Introduce supported_quirks in kvm_caps to store platform-specific valid quirks. Rename KVM_X86_VALID_QUIRKS to KVM_X86_VALID_QUIRKS_COMMON, representing valid quirks common to all x86 platforms. Initialize kvm_caps.supported_quirks to KVM_X86_VALID_QUIRKS_COMMON in the common vendor initializer kvm_x86_vendor_init(). Use kvm_caps.supported_quirks to respond to user queries about valid quirks and to mask out unsupported quirks provided by the user. In kvm_check_has_quirk(), in additional to check if a quirk is not explicitly disabled by the user, also verify if the quirk is supported by the platform. This ensures KVM does not treat a quirk as enabled if it's not explicitly disabled by the user but is outside the platform supported mask. This is a preparation for introducing quirks specific to certain platforms, e.g., quirks present only on Intel platforms and not on AMD. No functional changes intended. Signed-off-by: Yan Zhao <yan.y.zhao@xxxxxxxxx> --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/x86.c | 5 +++-- arch/x86/kvm/x86.h | 12 +++++++----- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 089cf2c82414..8d15e604613b 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -2409,7 +2409,7 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages); #define KVM_CLOCK_VALID_FLAGS \ (KVM_CLOCK_TSC_STABLE | KVM_CLOCK_REALTIME | KVM_CLOCK_HOST_TSC) -#define KVM_X86_VALID_QUIRKS \ +#define KVM_X86_VALID_QUIRKS_COMMON \ (KVM_X86_QUIRK_LINT0_REENABLED | \ KVM_X86_QUIRK_CD_NW_CLEARED | \ KVM_X86_QUIRK_LAPIC_MMIO_HOLE | \ diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 3078e09fc841..4f1b73620c6a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4782,7 +4782,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) r = enable_pmu ? KVM_CAP_PMU_VALID_MASK : 0; break; case KVM_CAP_DISABLE_QUIRKS2: - r = KVM_X86_VALID_QUIRKS; + r = kvm_caps.supported_quirks; break; case KVM_CAP_X86_NOTIFY_VMEXIT: r = kvm_caps.has_notify_vmexit; @@ -6521,7 +6521,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, switch (cap->cap) { case KVM_CAP_DISABLE_QUIRKS2: r = -EINVAL; - if (cap->args[0] & ~KVM_X86_VALID_QUIRKS) + if (cap->args[0] & ~kvm_caps.supported_quirks) break; fallthrough; case KVM_CAP_DISABLE_QUIRKS: @@ -9775,6 +9775,7 @@ int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops) kvm_host.xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK); kvm_caps.supported_xcr0 = kvm_host.xcr0 & KVM_SUPPORTED_XCR0; } + kvm_caps.supported_quirks = KVM_X86_VALID_QUIRKS_COMMON; rdmsrl_safe(MSR_EFER, &kvm_host.efer); diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 8ce6da98b5a2..772d5c320be1 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -34,6 +34,7 @@ struct kvm_caps { u64 supported_xcr0; u64 supported_xss; u64 supported_perf_cap; + u64 supported_quirks; }; struct kvm_host_values { @@ -354,11 +355,6 @@ static inline void kvm_register_write(struct kvm_vcpu *vcpu, return kvm_register_write_raw(vcpu, reg, val); } -static inline bool kvm_check_has_quirk(struct kvm *kvm, u64 quirk) -{ - return !(kvm->arch.disabled_quirks & quirk); -} - void kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip); u64 get_kvmclock_ns(struct kvm *kvm); @@ -394,6 +390,12 @@ extern struct kvm_host_values kvm_host; extern bool enable_pmu; +static inline bool kvm_check_has_quirk(struct kvm *kvm, u64 quirk) +{ + return (kvm_caps.supported_quirks & quirk) && + !(kvm->arch.disabled_quirks & quirk); +} + /* * Get a filtered version of KVM's supported XCR0 that strips out dynamic * features for which the current process doesn't (yet) have permission to use. -- 2.43.2