diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2019-04-15 09:16:17 -0400 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2019-04-16 04:59:07 -0400 |
| commit | 690908104e39d37947f89d76388c876ce4ec5fda (patch) | |
| tree | c36cb58746423288987bdc08715c2c4fe4314ee0 | |
| parent | cfd32acf7875d9dd83f82e1940098e88abeea439 (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.c | 25 | ||||
| -rw-r--r-- | arch/x86/kvm/vmx/vmx.c | 2 | ||||
| -rw-r--r-- | arch/x86/kvm/vmx/vmx.h | 2 |
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 | ||
| 5606 | static void dump_vmcs(void) | 5606 | void 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 | ||
| 520 | void dump_vmcs(void); | ||
| 521 | |||
| 520 | #endif /* __KVM_X86_VMX_H */ | 522 | #endif /* __KVM_X86_VMX_H */ |
