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