aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2019-04-15 09:16:17 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2019-04-16 04:59:07 -0400
commit690908104e39d37947f89d76388c876ce4ec5fda (patch)
treec36cb58746423288987bdc08715c2c4fe4314ee0
parentcfd32acf7875d9dd83f82e1940098e88abeea439 (diff)
KVM: nVMX: allow tests to use bad virtual-APIC page address
As mentioned in the comment, there are some special cases where we can simply clear the TPR shadow bit from the CPU-based execution controls in the vmcs02. Handle them so that we can remove some XFAILs from vmx.flat. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/vmx/nested.c25
-rw-r--r--arch/x86/kvm/vmx/vmx.c2
-rw-r--r--arch/x86/kvm/vmx/vmx.h2
3 files changed, 19 insertions, 10 deletions
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 7ec9bb1dd723..a22af5a85540 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -2873,20 +2873,27 @@ static void nested_get_vmcs12_pages(struct kvm_vcpu *vcpu)
2873 /* 2873 /*
2874 * If translation failed, VM entry will fail because 2874 * If translation failed, VM entry will fail because
2875 * prepare_vmcs02 set VIRTUAL_APIC_PAGE_ADDR to -1ull. 2875 * prepare_vmcs02 set VIRTUAL_APIC_PAGE_ADDR to -1ull.
2876 * Failing the vm entry is _not_ what the processor
2877 * does but it's basically the only possibility we
2878 * have. We could still enter the guest if CR8 load
2879 * exits are enabled, CR8 store exits are enabled, and
2880 * virtualize APIC access is disabled; in this case
2881 * the processor would never use the TPR shadow and we
2882 * could simply clear the bit from the execution
2883 * control. But such a configuration is useless, so
2884 * let's keep the code simple.
2885 */ 2876 */
2886 if (!is_error_page(page)) { 2877 if (!is_error_page(page)) {
2887 vmx->nested.virtual_apic_page = page; 2878 vmx->nested.virtual_apic_page = page;
2888 hpa = page_to_phys(vmx->nested.virtual_apic_page); 2879 hpa = page_to_phys(vmx->nested.virtual_apic_page);
2889 vmcs_write64(VIRTUAL_APIC_PAGE_ADDR, hpa); 2880 vmcs_write64(VIRTUAL_APIC_PAGE_ADDR, hpa);
2881 } else if (nested_cpu_has(vmcs12, CPU_BASED_CR8_LOAD_EXITING) &&
2882 nested_cpu_has(vmcs12, CPU_BASED_CR8_STORE_EXITING) &&
2883 !nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
2884 /*
2885 * The processor will never use the TPR shadow, simply
2886 * clear the bit from the execution control. Such a
2887 * configuration is useless, but it happens in tests.
2888 * For any other configuration, failing the vm entry is
2889 * _not_ what the processor does but it's basically the
2890 * only possibility we have.
2891 */
2892 vmcs_clear_bits(CPU_BASED_VM_EXEC_CONTROL,
2893 CPU_BASED_TPR_SHADOW);
2894 } else {
2895 printk("bad virtual-APIC page address\n");
2896 dump_vmcs();
2890 } 2897 }
2891 } 2898 }
2892 2899
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index ab432a930ae8..7a8f75fc6b7e 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -5603,7 +5603,7 @@ static void vmx_dump_dtsel(char *name, uint32_t limit)
5603 vmcs_readl(limit + GUEST_GDTR_BASE - GUEST_GDTR_LIMIT)); 5603 vmcs_readl(limit + GUEST_GDTR_BASE - GUEST_GDTR_LIMIT));
5604} 5604}
5605 5605
5606static void dump_vmcs(void) 5606void dump_vmcs(void)
5607{ 5607{
5608 u32 vmentry_ctl = vmcs_read32(VM_ENTRY_CONTROLS); 5608 u32 vmentry_ctl = vmcs_read32(VM_ENTRY_CONTROLS);
5609 u32 vmexit_ctl = vmcs_read32(VM_EXIT_CONTROLS); 5609 u32 vmexit_ctl = vmcs_read32(VM_EXIT_CONTROLS);
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index a1e00d0a2482..f879529906b4 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -517,4 +517,6 @@ static inline void decache_tsc_multiplier(struct vcpu_vmx *vmx)
517 vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio); 517 vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio);
518} 518}
519 519
520void dump_vmcs(void);
521
520#endif /* __KVM_X86_VMX_H */ 522#endif /* __KVM_X86_VMX_H */