aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLadi Prosek <lprosek@redhat.com>2016-11-30 10:03:11 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2016-12-08 09:31:10 -0500
commit1dc35dacc16b4f13547125c5df2d026d9e46ea01 (patch)
treeb65c2fffe3be59f812ab38da97b73e249657ce8f
parent9ed38ffad47316dbdc16de0de275868c7771754d (diff)
KVM: nVMX: check host CR3 on vmentry and vmexit
This commit adds missing host CR3 checks. Before entering guest mode, the value of CR3 is checked for reserved bits. After returning, nested_vmx_load_cr3 is called to set the new CR3 value and check and load PDPTRs. Signed-off-by: Ladi Prosek <lprosek@redhat.com> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
-rw-r--r--arch/x86/include/uapi/asm/vmx.h1
-rw-r--r--arch/x86/kvm/vmx.c25
2 files changed, 19 insertions, 7 deletions
diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h
index f9dea4fd4107..14458658e988 100644
--- a/arch/x86/include/uapi/asm/vmx.h
+++ b/arch/x86/include/uapi/asm/vmx.h
@@ -133,6 +133,7 @@
133 { EXIT_REASON_XRSTORS, "XRSTORS" } 133 { EXIT_REASON_XRSTORS, "XRSTORS" }
134 134
135#define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1 135#define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1
136#define VMX_ABORT_LOAD_HOST_PDPTE_FAIL 2
136#define VMX_ABORT_LOAD_HOST_MSR_FAIL 4 137#define VMX_ABORT_LOAD_HOST_MSR_FAIL 4
137 138
138#endif /* _UAPIVMX_H */ 139#endif /* _UAPIVMX_H */
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index a0d6e59f4f34..7280a355737e 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -9968,6 +9968,14 @@ static int nested_vmx_store_msr(struct kvm_vcpu *vcpu, u64 gpa, u32 count)
9968 return 0; 9968 return 0;
9969} 9969}
9970 9970
9971static bool nested_cr3_valid(struct kvm_vcpu *vcpu, unsigned long val)
9972{
9973 unsigned long invalid_mask;
9974
9975 invalid_mask = (~0ULL) << cpuid_maxphyaddr(vcpu);
9976 return (val & invalid_mask) == 0;
9977}
9978
9971/* 9979/*
9972 * Load guest's/host's cr3 at nested entry/exit. nested_ept is true if we are 9980 * Load guest's/host's cr3 at nested entry/exit. nested_ept is true if we are
9973 * emulating VM entry into a guest with EPT enabled. 9981 * emulating VM entry into a guest with EPT enabled.
@@ -9977,11 +9985,8 @@ static int nested_vmx_store_msr(struct kvm_vcpu *vcpu, u64 gpa, u32 count)
9977static int nested_vmx_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3, bool nested_ept, 9985static int nested_vmx_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3, bool nested_ept,
9978 unsigned long *entry_failure_code) 9986 unsigned long *entry_failure_code)
9979{ 9987{
9980 unsigned long invalid_mask;
9981
9982 if (cr3 != kvm_read_cr3(vcpu) || (!nested_ept && pdptrs_changed(vcpu))) { 9988 if (cr3 != kvm_read_cr3(vcpu) || (!nested_ept && pdptrs_changed(vcpu))) {
9983 invalid_mask = (~0ULL) << cpuid_maxphyaddr(vcpu); 9989 if (!nested_cr3_valid(vcpu, cr3)) {
9984 if (cr3 & invalid_mask) {
9985 *entry_failure_code = ENTRY_FAIL_DEFAULT; 9990 *entry_failure_code = ENTRY_FAIL_DEFAULT;
9986 return 1; 9991 return 1;
9987 } 9992 }
@@ -10452,7 +10457,8 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
10452 } 10457 }
10453 10458
10454 if (!nested_host_cr0_valid(vcpu, vmcs12->host_cr0) || 10459 if (!nested_host_cr0_valid(vcpu, vmcs12->host_cr0) ||
10455 !nested_host_cr4_valid(vcpu, vmcs12->host_cr4)) { 10460 !nested_host_cr4_valid(vcpu, vmcs12->host_cr4) ||
10461 !nested_cr3_valid(vcpu, vmcs12->host_cr3)) {
10456 nested_vmx_failValid(vcpu, 10462 nested_vmx_failValid(vcpu,
10457 VMXERR_ENTRY_INVALID_HOST_STATE_FIELD); 10463 VMXERR_ENTRY_INVALID_HOST_STATE_FIELD);
10458 goto out; 10464 goto out;
@@ -10879,6 +10885,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
10879 struct vmcs12 *vmcs12) 10885 struct vmcs12 *vmcs12)
10880{ 10886{
10881 struct kvm_segment seg; 10887 struct kvm_segment seg;
10888 unsigned long entry_failure_code;
10882 10889
10883 if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_EFER) 10890 if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_EFER)
10884 vcpu->arch.efer = vmcs12->host_ia32_efer; 10891 vcpu->arch.efer = vmcs12->host_ia32_efer;
@@ -10916,8 +10923,12 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
10916 10923
10917 nested_ept_uninit_mmu_context(vcpu); 10924 nested_ept_uninit_mmu_context(vcpu);
10918 10925
10919 kvm_set_cr3(vcpu, vmcs12->host_cr3); 10926 /*
10920 kvm_mmu_reset_context(vcpu); 10927 * Only PDPTE load can fail as the value of cr3 was checked on entry and
10928 * couldn't have changed.
10929 */
10930 if (nested_vmx_load_cr3(vcpu, vmcs12->host_cr3, false, &entry_failure_code))
10931 nested_vmx_abort(vcpu, VMX_ABORT_LOAD_HOST_PDPTE_FAIL);
10921 10932
10922 if (!enable_ept) 10933 if (!enable_ept)
10923 vcpu->arch.walk_mmu->inject_page_fault = kvm_inject_page_fault; 10934 vcpu->arch.walk_mmu->inject_page_fault = kvm_inject_page_fault;