diff options
author | Jan Kiszka <jan.kiszka@siemens.com> | 2014-01-04 12:47:19 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-01-17 04:22:13 -0500 |
commit | 42124925c1f580068661bebd963d7c102175a8a9 (patch) | |
tree | 2176bdb36a414e2f3feb06d686bdb8d18b203f7b | |
parent | 8246bf52c75aa9b9b336a84f31ed2248754d0f71 (diff) |
KVM: nVMX: Leave VMX mode on clearing of feature control MSR
When userspace sets MSR_IA32_FEATURE_CONTROL to 0, make sure we leave
root and non-root mode, fully disabling VMX. The register state of the
VCPU is undefined after this step, so userspace has to set it to a
proper state afterward.
This enables to reboot a VM while it is running some hypervisor code.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/vmx.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index c8eb27ff1a2d..bff55554faec 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -2455,6 +2455,8 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) | |||
2455 | return 1; | 2455 | return 1; |
2456 | } | 2456 | } |
2457 | 2457 | ||
2458 | static void vmx_leave_nested(struct kvm_vcpu *vcpu); | ||
2459 | |||
2458 | static int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | 2460 | static int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) |
2459 | { | 2461 | { |
2460 | u32 msr_index = msr_info->index; | 2462 | u32 msr_index = msr_info->index; |
@@ -2470,6 +2472,8 @@ static int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
2470 | & FEATURE_CONTROL_LOCKED) | 2472 | & FEATURE_CONTROL_LOCKED) |
2471 | return 0; | 2473 | return 0; |
2472 | to_vmx(vcpu)->nested.msr_ia32_feature_control = data; | 2474 | to_vmx(vcpu)->nested.msr_ia32_feature_control = data; |
2475 | if (host_initialized && data == 0) | ||
2476 | vmx_leave_nested(vcpu); | ||
2473 | return 1; | 2477 | return 1; |
2474 | } | 2478 | } |
2475 | 2479 | ||
@@ -8504,6 +8508,16 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu) | |||
8504 | } | 8508 | } |
8505 | 8509 | ||
8506 | /* | 8510 | /* |
8511 | * Forcibly leave nested mode in order to be able to reset the VCPU later on. | ||
8512 | */ | ||
8513 | static void vmx_leave_nested(struct kvm_vcpu *vcpu) | ||
8514 | { | ||
8515 | if (is_guest_mode(vcpu)) | ||
8516 | nested_vmx_vmexit(vcpu); | ||
8517 | free_nested(to_vmx(vcpu)); | ||
8518 | } | ||
8519 | |||
8520 | /* | ||
8507 | * L1's failure to enter L2 is a subset of a normal exit, as explained in | 8521 | * L1's failure to enter L2 is a subset of a normal exit, as explained in |
8508 | * 23.7 "VM-entry failures during or after loading guest state" (this also | 8522 | * 23.7 "VM-entry failures during or after loading guest state" (this also |
8509 | * lists the acceptable exit-reason and exit-qualification parameters). | 8523 | * lists the acceptable exit-reason and exit-qualification parameters). |