diff options
author | Eugene Korenevsky <ekorenevsky@gmail.com> | 2015-03-29 16:56:27 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-04-08 04:46:57 -0400 |
commit | 9090422f1ca5270795738549cf91a4ae7cb47662 (patch) | |
tree | 2797188c1fb69e05f72c4cc8ebbd0fb695d466ad | |
parent | 5a4f55cde81f1633cb7ae9f0963b722e47acdc36 (diff) |
KVM: nVMX: checks for address bits beyond MAXPHYADDR on VM-entry
On each VM-entry CPU should check the following VMCS fields for zero bits
beyond physical address width:
- APIC-access address
- virtual-APIC address
- posted-interrupt descriptor address
This patch adds these checks required by Intel SDM.
Signed-off-by: Eugene Korenevsky <ekorenevsky@gmail.com>
Message-Id: <20150329205627.GA1244@gnote>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/vmx.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 9e4b12b5bff6..6f770e875936 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -8622,10 +8622,11 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu, | |||
8622 | struct vmcs12 *vmcs12) | 8622 | struct vmcs12 *vmcs12) |
8623 | { | 8623 | { |
8624 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 8624 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
8625 | int maxphyaddr = cpuid_maxphyaddr(vcpu); | ||
8625 | 8626 | ||
8626 | if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) { | 8627 | if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) { |
8627 | /* TODO: Also verify bits beyond physical address width are 0 */ | 8628 | if (!PAGE_ALIGNED(vmcs12->apic_access_addr) || |
8628 | if (!PAGE_ALIGNED(vmcs12->apic_access_addr)) | 8629 | vmcs12->apic_access_addr >> maxphyaddr) |
8629 | return false; | 8630 | return false; |
8630 | 8631 | ||
8631 | /* | 8632 | /* |
@@ -8641,8 +8642,8 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu, | |||
8641 | } | 8642 | } |
8642 | 8643 | ||
8643 | if (nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW)) { | 8644 | if (nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW)) { |
8644 | /* TODO: Also verify bits beyond physical address width are 0 */ | 8645 | if (!PAGE_ALIGNED(vmcs12->virtual_apic_page_addr) || |
8645 | if (!PAGE_ALIGNED(vmcs12->virtual_apic_page_addr)) | 8646 | vmcs12->virtual_apic_page_addr >> maxphyaddr) |
8646 | return false; | 8647 | return false; |
8647 | 8648 | ||
8648 | if (vmx->nested.virtual_apic_page) /* shouldn't happen */ | 8649 | if (vmx->nested.virtual_apic_page) /* shouldn't happen */ |
@@ -8665,7 +8666,8 @@ static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu, | |||
8665 | } | 8666 | } |
8666 | 8667 | ||
8667 | if (nested_cpu_has_posted_intr(vmcs12)) { | 8668 | if (nested_cpu_has_posted_intr(vmcs12)) { |
8668 | if (!IS_ALIGNED(vmcs12->posted_intr_desc_addr, 64)) | 8669 | if (!IS_ALIGNED(vmcs12->posted_intr_desc_addr, 64) || |
8670 | vmcs12->posted_intr_desc_addr >> maxphyaddr) | ||
8669 | return false; | 8671 | return false; |
8670 | 8672 | ||
8671 | if (vmx->nested.pi_desc_page) { /* shouldn't happen */ | 8673 | if (vmx->nested.pi_desc_page) { /* shouldn't happen */ |
@@ -9386,7 +9388,6 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) | |||
9386 | } | 9388 | } |
9387 | 9389 | ||
9388 | if (!nested_get_vmcs12_pages(vcpu, vmcs12)) { | 9390 | if (!nested_get_vmcs12_pages(vcpu, vmcs12)) { |
9389 | /*TODO: Also verify bits beyond physical address width are 0*/ | ||
9390 | nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD); | 9391 | nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD); |
9391 | return 1; | 9392 | return 1; |
9392 | } | 9393 | } |