Skip to content

Commit a4dae7c

Browse files
committed
KVM: x86: Allow vendor code to disable quirks
In some cases, the handling of quirks is split between platform-specific code and generic code, or it is done entirely in generic code, but the relevant bug does not trigger on some platforms; for example, this will be the case for "ignore guest PAT". Allow unaffected vendor modules to disable handling of a quirk for all VMs via a new entry in kvm_caps. Such quirks remain available in KVM_CAP_DISABLE_QUIRKS2, because that API tells userspace that KVM *knows* that some of its past behavior was bogus or just undesirable. In other words, it's plausible for userspace to refuse to run if a quirk is not listed by KVM_CAP_DISABLE_QUIRKS2, so preserve that and make it part of the API. As an example, mark KVM_X86_QUIRK_CD_NW_CLEARED as auto-disabled on Intel systems. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 9966b78 commit a4dae7c

File tree

4 files changed

+7
-0
lines changed

4 files changed

+7
-0
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2422,6 +2422,9 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages);
24222422
KVM_X86_QUIRK_SLOT_ZAP_ALL | \
24232423
KVM_X86_QUIRK_STUFF_FEATURE_MSRS)
24242424

2425+
#define KVM_X86_CONDITIONAL_QUIRKS \
2426+
KVM_X86_QUIRK_CD_NW_CLEARED
2427+
24252428
/*
24262429
* KVM previously used a u32 field in kvm_run to indicate the hypercall was
24272430
* initiated from long mode. KVM now sets bit 0 to indicate long mode, but the

arch/x86/kvm/svm/svm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5472,6 +5472,7 @@ static __init int svm_hardware_setup(void)
54725472
*/
54735473
allow_smaller_maxphyaddr = !npt_enabled;
54745474

5475+
kvm_caps.inapplicable_quirks &= ~KVM_X86_QUIRK_CD_NW_CLEARED;
54755476
return 0;
54765477

54775478
err:

arch/x86/kvm/x86.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9783,6 +9783,7 @@ int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)
97839783
kvm_host.xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
97849784
kvm_caps.supported_xcr0 = kvm_host.xcr0 & KVM_SUPPORTED_XCR0;
97859785
}
9786+
kvm_caps.inapplicable_quirks = KVM_X86_CONDITIONAL_QUIRKS;
97869787

97879788
rdmsrl_safe(MSR_EFER, &kvm_host.efer);
97889789

@@ -12733,6 +12734,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
1273312734
/* Decided by the vendor code for other VM types. */
1273412735
kvm->arch.pre_fault_allowed =
1273512736
type == KVM_X86_DEFAULT_VM || type == KVM_X86_SW_PROTECTED_VM;
12737+
kvm->arch.disabled_quirks = kvm_caps.inapplicable_quirks;
1273612738

1273712739
ret = kvm_page_track_init(kvm);
1273812740
if (ret)

arch/x86/kvm/x86.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct kvm_caps {
3434
u64 supported_xcr0;
3535
u64 supported_xss;
3636
u64 supported_perf_cap;
37+
u64 inapplicable_quirks;
3738
};
3839

3940
struct kvm_host_values {

0 commit comments

Comments
 (0)