diff mbox series

[05/15] KVM: VMX: Add document to state that write to uret msr should always be intercepted

Message ID 20211118110814.2568-6-jiangshanlai@gmail.com (mailing list archive)
State New, archived
Headers show
Series KVM: X86: Miscellaneous cleanups | expand

Commit Message

Lai Jiangshan Nov. 18, 2021, 11:08 a.m. UTC
From: Lai Jiangshan <laijs@linux.alibaba.com>

And adds a corresponding sanity check code.

Signed-off-by: Lai Jiangshan <laijs@linux.alibaba.com>
---
 arch/x86/kvm/vmx/vmx.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

Comments

Paolo Bonzini Nov. 18, 2021, 4:05 p.m. UTC | #1
On 11/18/21 12:08, Lai Jiangshan wrote:
> From: Lai Jiangshan <laijs@linux.alibaba.com>
> 
> And adds a corresponding sanity check code.
> 
> Signed-off-by: Lai Jiangshan <laijs@linux.alibaba.com>
> ---
>   arch/x86/kvm/vmx/vmx.c | 10 +++++++++-
>   1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index e8a41fdc3c4d..cd081219b668 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -3703,13 +3703,21 @@ void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type)
>   	if (!cpu_has_vmx_msr_bitmap())
>   		return;
>   
> +	/*
> +	 * Write to uret msr should always be intercepted due to the mechanism
> +	 * must know the current value.  Santity check to avoid any inadvertent
> +	 * mistake in coding.
> +	 */
> +	if (WARN_ON_ONCE(vmx_find_uret_msr(vmx, msr) && (type & MSR_TYPE_W)))
> +		return;
> +

I'm not sure about this one, it's relatively expensive to call 
vmx_find_uret_msr.

User-return MSRs and disable-intercept MSRs are almost the opposite: 
uret is for MSRs that the host (not even the processor) never uses, 
disable-intercept is for MSRs that the guest reads/writes often.  As 
such it seems almost impossible that they overlap.

Paolo
Sean Christopherson Dec. 7, 2021, 8:38 p.m. UTC | #2
On Thu, Nov 18, 2021, Paolo Bonzini wrote:
> On 11/18/21 12:08, Lai Jiangshan wrote:
> > From: Lai Jiangshan <laijs@linux.alibaba.com>
> > 
> > And adds a corresponding sanity check code.
> > 
> > Signed-off-by: Lai Jiangshan <laijs@linux.alibaba.com>
> > ---
> >   arch/x86/kvm/vmx/vmx.c | 10 +++++++++-
> >   1 file changed, 9 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> > index e8a41fdc3c4d..cd081219b668 100644
> > --- a/arch/x86/kvm/vmx/vmx.c
> > +++ b/arch/x86/kvm/vmx/vmx.c
> > @@ -3703,13 +3703,21 @@ void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type)
> >   	if (!cpu_has_vmx_msr_bitmap())
> >   		return;
> > +	/*
> > +	 * Write to uret msr should always be intercepted due to the mechanism
> > +	 * must know the current value.  Santity check to avoid any inadvertent
> > +	 * mistake in coding.
> > +	 */
> > +	if (WARN_ON_ONCE(vmx_find_uret_msr(vmx, msr) && (type & MSR_TYPE_W)))
> > +		return;
> > +
> 
> I'm not sure about this one, it's relatively expensive to call
> vmx_find_uret_msr.
> 
> User-return MSRs and disable-intercept MSRs are almost the opposite: uret is
> for MSRs that the host (not even the processor) never uses,
> disable-intercept is for MSRs that the guest reads/writes often.  As such it
> seems almost impossible that they overlap.

And they aren't fundamentally mutually exclusive, e.g. KVM could pass-through an
MSR and then do RDMSR in vmx_prepare_switch_to_host() to refresh the uret data
with the current (guest) value.  It'd be silly, but it would work.
diff mbox series

Patch

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index e8a41fdc3c4d..cd081219b668 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -3703,13 +3703,21 @@  void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type)
 	if (!cpu_has_vmx_msr_bitmap())
 		return;
 
+	/*
+	 * Write to uret msr should always be intercepted due to the mechanism
+	 * must know the current value.  Santity check to avoid any inadvertent
+	 * mistake in coding.
+	 */
+	if (WARN_ON_ONCE(vmx_find_uret_msr(vmx, msr) && (type & MSR_TYPE_W)))
+		return;
+
 	if (static_branch_unlikely(&enable_evmcs))
 		evmcs_touch_msr_bitmap();
 
 	/*
 	 * Mark the desired intercept state in shadow bitmap, this is needed
 	 * for resync when the MSR filters change.
-	*/
+	 */
 	if (is_valid_passthrough_msr(msr)) {
 		int idx = possible_passthrough_msr_slot(msr);