diff mbox

[v2,4/4] kvm: vmx: fix VMfailValid when write vmcs02/vmcs01

Message ID 1417691470-5221-4-git-send-email-wanpeng.li@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Wanpeng Li Dec. 4, 2014, 11:11 a.m. UTC
SDM 30.3 VMWRITE

ELSIF secondary source operand does not correspond to any VMCS field
   THEN VMfailValid(VMREAD/VMWRITE from/to unsupported VMCS component);

We can't suppose L1 VMM expose MPX to L2 just if L0 support MPX. There
will be VMfailValid if L0 doesn't support MPX and L1 expose MPX to L2
when L0 writes vmcs02/vmcs01, in addition, there is no need to read
GUEST_BNDCFGS if L1 VMM doesn't expose it to L2. This patch fix it by
both check L0 support xsaves and L1 expose MPX to L2.

Signed-off-by: Wanpeng Li <wanpeng.li@linux.intel.com>
---
 arch/x86/kvm/vmx.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

Comments

Paolo Bonzini Dec. 4, 2014, 2:28 p.m. UTC | #1
On 04/12/2014 12:11, Wanpeng Li wrote:
> SDM 30.3 VMWRITE
> 
> ELSIF secondary source operand does not correspond to any VMCS field
>    THEN VMfailValid(VMREAD/VMWRITE from/to unsupported VMCS component);
> 
> We can't suppose L1 VMM expose MPX to L2 just if L0 support MPX. There
> will be VMfailValid if L0 doesn't support MPX and L1 expose MPX to L2
> when L0 writes vmcs02/vmcs01, in addition, there is no need to read
> GUEST_BNDCFGS if L1 VMM doesn't expose it to L2. This patch fix it by
> both check L0 support xsaves and L1 expose MPX to L2.

Did you have a reproducer for this?  It should not be needed, because
the bndcfgs entry/exit controls are hidden from
nested_vmx_exit_ctls_high and nested_vmx_entry_ctls_high if
!vmx_mpx_supported().

This hunk is also not correct:

> -	if (vmx_mpx_supported())
> +	if (vmx_mpx_supported() &&
> +		(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS))
>  		vmcs12->guest_bndcfgs = vmcs_read64(GUEST_BNDCFGS);
>  	if (nested_cpu_has_xsaves(vmcs12))
>  		vmcs12->xss_exit_bitmap = vmcs_read64(XSS_EXIT_BITMAP);

because there is no "save BNDCFGS" exit control; the guest BNDCFGS is
saved unconditionally into the vmcs.

Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index e5bc349..1233159 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -8496,7 +8496,8 @@  static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
 
 	set_cr4_guest_host_mask(vmx);
 
-	if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS)
+	if (vmx_mpx_supported() &&
+		(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS))
 		vmcs_write64(GUEST_BNDCFGS, vmcs12->guest_bndcfgs);
 
 	if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING)
@@ -8992,7 +8993,8 @@  static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
 	vmcs12->guest_sysenter_cs = vmcs_read32(GUEST_SYSENTER_CS);
 	vmcs12->guest_sysenter_esp = vmcs_readl(GUEST_SYSENTER_ESP);
 	vmcs12->guest_sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP);
-	if (vmx_mpx_supported())
+	if (vmx_mpx_supported() &&
+		(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS))
 		vmcs12->guest_bndcfgs = vmcs_read64(GUEST_BNDCFGS);
 	if (nested_cpu_has_xsaves(vmcs12))
 		vmcs12->xss_exit_bitmap = vmcs_read64(XSS_EXIT_BITMAP);
@@ -9106,7 +9108,8 @@  static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
 	vmcs_writel(GUEST_GDTR_BASE, vmcs12->host_gdtr_base);
 
 	/* If not VM_EXIT_CLEAR_BNDCFGS, the L2 value propagates to L1.  */
-	if (vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS)
+	if (vmx_mpx_supported() &&
+		(vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS))
 		vmcs_write64(GUEST_BNDCFGS, 0);
 
 	if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_PAT) {