Re: [PATCH 2/2] KVM: x86: Add kvm_x86_ops callback to allow VMX to stash away CR4.VMXE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 27/03/19 21:34, Sean Christopherson wrote:
> Ah fudge.  KVM_{GET,SET}_NESTED_STATE, i.e. vmx_{get,set}_nested_state().
> This patch would also need to add and handle KVM_STATE_NESTED_SMM_CR4_VMXE.

Like this:

diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
index dabfcf7c3941..88bdff7b866c 100644
--- a/arch/x86/include/uapi/asm/kvm.h
+++ b/arch/x86/include/uapi/asm/kvm.h
@@ -388,6 +388,7 @@ struct kvm_sync_regs {
 
 #define KVM_STATE_NESTED_SMM_GUEST_MODE	0x00000001
 #define KVM_STATE_NESTED_SMM_VMXON	0x00000002
+#define KVM_STATE_NESTED_SMM_CR4_VMXE	0x00000004
 
 struct kvm_vmx_nested_state {
 	__u64 vmxon_pa;
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 153e539c29c9..cbd5f2ddf7f7 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -5245,6 +5245,9 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu,
 	if (nested_vmx_allowed(vcpu) && vmx->nested.enlightened_vmcs_enabled)
 		kvm_state.flags |= KVM_STATE_NESTED_EVMCS;
 
+	if (vmx->nested.smm.cr4_vmxe)
+		kvm_state.vmx.smm.flags |= KVM_STATE_NESTED_SMM_CR4_VMXE;
+
 	if (nested_vmx_allowed(vcpu) &&
 	    (vmx->nested.vmxon || vmx->nested.smm.vmxon)) {
 		kvm_state.vmx.vmxon_pa = vmx->nested.vmxon_ptr;
@@ -5365,7 +5368,8 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
 		return -EINVAL;
 
 	if (kvm_state->vmx.smm.flags &
-	    ~(KVM_STATE_NESTED_SMM_GUEST_MODE | KVM_STATE_NESTED_SMM_VMXON))
+	    ~(KVM_STATE_NESTED_SMM_GUEST_MODE | KVM_STATE_NESTED_SMM_VMXON |
+	      KVM_STATE_NESTED_SMM_CR4_VMXE))
 		return -EINVAL;
 
 	/*
@@ -5380,6 +5384,10 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
 	    !(kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_VMXON))
 		return -EINVAL;
 
+	if ((kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_VMXON) &&
+	    !(kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_CR4_VMXE))
+		return -EINVAL;
+
 	vmx_leave_nested(vcpu);
 	if (kvm_state->vmx.vmxon_pa == -1ull)
 		return 0;
@@ -5409,6 +5417,9 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
 		return -EINVAL;
 	}
 
+	vmx->nested.smm.cr4_vmxe =
+		!!(kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_CR4_VMXE);
+
 	if (kvm_state->vmx.smm.flags & KVM_STATE_NESTED_SMM_VMXON) {
 		vmx->nested.smm.vmxon = true;
 		vmx->nested.vmxon = false;

I'll try to put together a testcase.

Paolo



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux