FAILED: patch "[PATCH] KVM: x86: Introduce KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM" failed to apply to 6.12-stable tree
Subsystems (5)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x e2ffe85b6d2bb7780174b87aa4468a39be17eb81
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026031659-scroll-setting-4687@gregkh' --subject-prefix 'PATCH 6.12.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From e2ffe85b6d2bb7780174b87aa4468a39be17eb81 Mon Sep 17 00:00:00 2001
From: Jim Mattson <[email protected]>
Date: Thu, 5 Feb 2026 15:15:26 -0800
Subject: [PATCH] KVM: x86: Introduce KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM
Add KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM to allow L1 to set FREEZE_IN_SMM in vmcs12's GUEST_IA32_DEBUGCTL field, as permitted prior to commit 6b1dd26544d0 ("KVM: VMX: Preserve host's DEBUGCTLMSR_FREEZE_IN_SMM while running the guest"). Enable the quirk by default for backwards compatibility (like all quirks); userspace can disable it via KVM_CAP_DISABLE_QUIRKS2 for consistency with the constraints on WRMSR(IA32_DEBUGCTL).
Note that the quirk only bypasses the consistency check. The vmcs02 bit is still owned by the host, and PMCs are not frozen during virtualized SMM. In particular, if a host administrator decides that PMCs should not be frozen during physical SMM, then L1 has no say in the matter.
Documentation/virt/kvm/api.rst +8 -0
@@ -8543,6 +8543,14 @@ KVM_X86_QUIRK_IGNORE_GUEST_PAT By default, on Intel platforms, KVM ignores guest software, for example if it does not expose a bochs graphics device (which is known to have had a buggy driver). + +KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM By default, KVM relaxes the consistency + check for GUEST_IA32_DEBUGCTL in vmcs12 + to allow FREEZE_IN_SMM to be set. When + this quirk is disabled, KVM requires this + bit to be cleared. Note that the vmcs02 + bit is still completely controlled by the + host, regardless of the quirk setting. =================================== ============================================ 7.32 KVM_CAP_MAX_VCPU_ID
arch/x86/include/asm/kvm_host.h +2 -1
@@ -2485,7 +2485,8 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages); KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS | \ KVM_X86_QUIRK_SLOT_ZAP_ALL | \ KVM_X86_QUIRK_STUFF_FEATURE_MSRS | \ - KVM_X86_QUIRK_IGNORE_GUEST_PAT) + KVM_X86_QUIRK_IGNORE_GUEST_PAT | \ + KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM)#define KVM_X86_CONDITIONAL_QUIRKS \ (KVM_X86_QUIRK_CD_NW_CLEARED | \
arch/x86/include/uapi/asm/kvm.h +1 -0
@@ -476,6 +476,7 @@ struct kvm_sync_regs {#define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7)#define KVM_X86_QUIRK_STUFF_FEATURE_MSRS (1 << 8)#define KVM_X86_QUIRK_IGNORE_GUEST_PAT (1 << 9) +#define KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM (1 << 10)#define KVM_STATE_NESTED_FORMAT_VMX 0#define KVM_STATE_NESTED_FORMAT_SVM 1
arch/x86/kvm/vmx/nested.c +18 -4
@@ -3300,10 +3300,24 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,if (CC (vmcs12->guest_cr4 &X86_CR4_CET && !(vmcs12->guest_cr0 &X86_CR0_WP )))return -EINVAL ; -if ((vmcs12->vm_entry_controls &VM_ENTRY_LOAD_DEBUG_CONTROLS ) && - (CC (!kvm_dr7_valid (vmcs12->guest_dr7)) || -CC (!vmx_is_valid_debugctl (vcpu, vmcs12->guest_ia32_debugctl, false)))) -return -EINVAL ; +if (vmcs12->vm_entry_controls &VM_ENTRY_LOAD_DEBUG_CONTROLS ) { +u64 debugctl = vmcs12->guest_ia32_debugctl; + +/* +* FREEZE_IN_SMM is not virtualized, but allow L1 to set it in +* vmcs12's DEBUGCTL under a quirk for backwards compatibility. +* Note that the quirk only relaxes the consistency check. The +* vmcc02 bit is still under the control of the host. In +* particular, if a host administrator decides to clear the bit, +* then L1 has no say in the matter. +*/ +if (kvm_check_has_quirk (vcpu->kvm,KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM )) + debugctl &= ~DEBUGCTLMSR_FREEZE_IN_SMM ; + +if (CC (!kvm_dr7_valid (vmcs12->guest_dr7)) || +CC (!vmx_is_valid_debugctl (vcpu, debugctl, false))) +return -EINVAL ; + }if ((vmcs12->vm_entry_controls &VM_ENTRY_LOAD_IA32_PAT ) &&CC (!kvm_pat_valid (vmcs12->guest_ia32_pat)))
Sasha Levin
maintainerPATCH 1/8 KVM: x86: Co-locate initialization of feature MSRs in kvm_arch_vcpu_create()
From: Sean Christopherson <[email protected]>
[ Upstream commit 2142ac663a6a72ac868d0768681b1355e3a703eb ]
Bunch all of the feature MSR initialization in kvm_arch_vcpu_create() so that it can be easily quirked in a future patch.
No functional change intended.
Stable-dep-of: e2ffe85b6d2b ("KVM: x86: Introduce KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM")
--- arch/x86/kvm/x86.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/x86.c +2 -2
@@ -12383,6 +12383,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)kvm_async_pf_hash_reset (vcpu); + vcpu->arch.arch_capabilities =kvm_get_arch_capabilities (); + vcpu->arch.msr_platform_info =MSR_PLATFORM_INFO_CPUID_FAULT ; vcpu->arch.perf_capabilities = kvm_caps.supported_perf_cap;kvm_pmu_init (vcpu);
@@ -12397,8 +12399,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)if (r) goto free_guest_fpu; - vcpu->arch.arch_capabilities =kvm_get_arch_capabilities (); - vcpu->arch.msr_platform_info =MSR_PLATFORM_INFO_CPUID_FAULT ;kvm_xen_init_vcpu (vcpu);vcpu_load (vcpu);kvm_set_tsc_khz (vcpu, vcpu->kvm->arch.default_tsc_khz);
Signature · 1 line
2.51.0
Sasha Levin
maintainerPATCH 2/8 KVM: x86: Quirk initialization of feature MSRs to KVM's max configuration
From: Sean Christopherson <[email protected]>
[ Upstream commit dcb988cdac85bad177de86fbf409524eda4f9467 ]
Add a quirk to control KVM's misguided initialization of select feature MSRs to KVM's max configuration, as enabling features by default violates KVM's approach of letting userspace own the vCPU model, and is actively problematic for MSRs that are conditionally supported, as the vCPU will end up with an MSR value that userspace can't restore. E.g. if the vCPU is configured with PDCM=0, userspace will save and attempt to restore a non-zero PERF_CAPABILITIES, thanks to KVM's meddling.
Stable-dep-of: e2ffe85b6d2b ("KVM: x86: Introduce KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM")
--- Documentation/virt/kvm/api.rst | 22 ++++++++++++++++++++++ arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/include/uapi/asm/kvm.h | 1 + arch/x86/kvm/svm/svm.c | 4 +++- arch/x86/kvm/vmx/vmx.c | 9 ++++++--- arch/x86/kvm/x86.c | 8 +++++--- 6 files changed, 39 insertions(+), 8 deletions(-)
Documentation/virt/kvm/api.rst +22 -0
@@ -8107,6 +8107,28 @@ KVM_X86_QUIRK_SLOT_ZAP_ALL By default, for KVM_X86_DEFAULT_VM VMs, KVM or moved memslot isn't reachable, i.e KVM _may_ invalidate only SPTEs related to the memslot. + +KVM_X86_QUIRK_STUFF_FEATURE_MSRS By default, at vCPU creation, KVM sets the + vCPU's MSR_IA32_PERF_CAPABILITIES (0x345), + MSR_IA32_ARCH_CAPABILITIES (0x10a), + MSR_PLATFORM_INFO (0xce), and all VMX MSRs + (0x480..0x492) to the maximal capabilities + supported by KVM. KVM also sets + MSR_IA32_UCODE_REV (0x8b) to an arbitrary + value (which is different for Intel vs. + AMD). Lastly, when guest CPUID is set (by + userspace), KVM modifies select VMX MSR + fields to force consistency between guest + CPUID and L2's effective ISA. When this + quirk is disabled, KVM zeroes the vCPU's MSR + values (with two exceptions, see below), + i.e. treats the feature MSRs like CPUID + leaves and gives userspace full control of + the vCPU model definition. This quirk does + not affect VMX MSRs CR0/CR4_FIXED1 (0x487 + and 0x489), as KVM does now allow them to + be set by userspace (KVM sets them based on + guest CPUID, for safety purposes). =================================== ============================================ 7.32 KVM_CAP_MAX_VCPU_ID
arch/x86/include/asm/kvm_host.h +2 -1
@@ -2385,7 +2385,8 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages);KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT | \KVM_X86_QUIRK_FIX_HYPERCALL_INSN | \KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS | \ - KVM_X86_QUIRK_SLOT_ZAP_ALL) +KVM_X86_QUIRK_SLOT_ZAP_ALL | \ + KVM_X86_QUIRK_STUFF_FEATURE_MSRS)/* * KVM previously used a u32 field in kvm_run to indicate the hypercall was
arch/x86/include/uapi/asm/kvm.h +1 -0
@@ -440,6 +440,7 @@ struct kvm_sync_regs {#define KVM_X86_QUIRK_FIX_HYPERCALL_INSN (1 << 5)#define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS (1 << 6)#define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7) +#define KVM_X86_QUIRK_STUFF_FEATURE_MSRS (1 << 8)#define KVM_STATE_NESTED_FORMAT_VMX 0#define KVM_STATE_NESTED_FORMAT_SVM 1
arch/x86/kvm/svm/svm.c +3 -1
@@ -1390,7 +1390,9 @@ static void __svm_vcpu_reset(struct kvm_vcpu *vcpu)svm_vcpu_init_msrpm (vcpu, svm->msrpm);svm_init_osvw (vcpu); - vcpu->arch.microcode_version =0x01000065 ; + +if (kvm_check_has_quirk (vcpu->kvm,KVM_X86_QUIRK_STUFF_FEATURE_MSRS )) + vcpu->arch.microcode_version =0x01000065 ; svm->tsc_ratio_msr = kvm_caps.default_tsc_scaling_ratio; svm->nmi_masked = false;
arch/x86/kvm/vmx/vmx.c +6 -3
@@ -4562,7 +4562,8 @@ vmx_adjust_secondary_exec_control(struct vcpu_vmx *vmx, u32 *exec_control,* Update the nested MSR settings so that a nested VMM can/can't set * controls for features that are/aren't exposed to the guest. */ -if (nested) { +if (nested && +kvm_check_has_quirk (vmx->vcpu.kvm,KVM_X86_QUIRK_STUFF_FEATURE_MSRS )) {/* * All features that can be added or removed to VMX MSRs must * be supported in the first place for nested virtualization.
@@ -4853,7 +4854,8 @@ static void __vmx_vcpu_reset(struct kvm_vcpu *vcpu)init_vmcs (vmx); -if (nested) +if (nested && +kvm_check_has_quirk (vcpu->kvm,KVM_X86_QUIRK_STUFF_FEATURE_MSRS ))memcpy (&vmx->nested.msrs, &vmcs_config.nested,sizeof (vmx->nested.msrs));vcpu_setup_sgx_lepubkeyhash (vcpu);
@@ -4866,7 +4868,8 @@ static void __vmx_vcpu_reset(struct kvm_vcpu *vcpu) vmx->nested.hv_evmcs_vmptr =EVMPTR_INVALID ;#endif - vcpu->arch.microcode_version =0x100000000ULL ; +if (kvm_check_has_quirk (vcpu->kvm,KVM_X86_QUIRK_STUFF_FEATURE_MSRS )) + vcpu->arch.microcode_version =0x100000000ULL ; vmx->msr_ia32_feature_control_valid_bits =FEAT_CTL_LOCKED ;/*
arch/x86/kvm/x86.c +5 -3
@@ -12383,9 +12383,11 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)kvm_async_pf_hash_reset (vcpu); - vcpu->arch.arch_capabilities =kvm_get_arch_capabilities (); - vcpu->arch.msr_platform_info =MSR_PLATFORM_INFO_CPUID_FAULT ; - vcpu->arch.perf_capabilities = kvm_caps.supported_perf_cap; +if (kvm_check_has_quirk (vcpu->kvm,KVM_X86_QUIRK_STUFF_FEATURE_MSRS )) { + vcpu->arch.arch_capabilities =kvm_get_arch_capabilities (); + vcpu->arch.msr_platform_info =MSR_PLATFORM_INFO_CPUID_FAULT ; + vcpu->arch.perf_capabilities = kvm_caps.supported_perf_cap; + }kvm_pmu_init (vcpu); vcpu->arch.pending_external_vector =-1 ;
Signature · 1 line
2.51.0
Sasha Levin
maintainerPATCH 3/8 KVM: x86: do not allow re-enabling quirks
In reply to Sasha LevinFrom: Paolo Bonzini <[email protected]>
[ Upstream commit 9966b7822b3f49b3aea5d926ece4bc92f1f0a700 ]
Allowing arbitrary re-enabling of quirks puts a limit on what the quirks themselves can do, since you cannot assume that the quirk prevents a particular state. More important, it also prevents KVM from disabling a quirk at VM creation time, because userspace can always go back and re-enable that.
Stable-dep-of: e2ffe85b6d2b ("KVM: x86: Introduce KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM")
--- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/x86.c +1 -1
@@ -6538,7 +6538,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,break ; fallthrough;case KVM_CAP_DISABLE_QUIRKS : - kvm->arch.disabled_quirks = cap->args[0 ]; + kvm->arch.disabled_quirks |= cap->args[0 ]; r =0 ;break ;case KVM_CAP_SPLIT_IRQCHIP : {
Signature · 1 line
2.51.0
Sasha Levin
maintainerPATCH 4/8 KVM: x86: Allow vendor code to disable quirks
In reply to Sasha LevinFrom: Paolo Bonzini <[email protected]>
[ Upstream commit a4dae7c7a41d803a05192015b2d47aca8aca4abf ]
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.
Stable-dep-of: e2ffe85b6d2b ("KVM: x86: Introduce KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM")
--- arch/x86/include/asm/kvm_host.h | 3 +++ arch/x86/kvm/svm/svm.c | 1 + arch/x86/kvm/x86.c | 2 ++ arch/x86/kvm/x86.h | 1 + 4 files changed, 7 insertions(+)
arch/x86/include/asm/kvm_host.h +3 -0
@@ -2388,6 +2388,9 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages); KVM_X86_QUIRK_SLOT_ZAP_ALL | \ KVM_X86_QUIRK_STUFF_FEATURE_MSRS) +#define KVM_X86_CONDITIONAL_QUIRKS \ + KVM_X86_QUIRK_CD_NW_CLEARED +/* * KVM previously used a u32 field in kvm_run to indicate the hypercall was * initiated from long mode. KVM now sets bit 0 to indicate long mode, but the
arch/x86/kvm/svm/svm.c +1 -0
@@ -5562,6 +5562,7 @@ static __init int svm_hardware_setup(void)*/ allow_smaller_maxphyaddr = !npt_enabled; + kvm_caps.inapplicable_quirks &= ~KVM_X86_QUIRK_CD_NW_CLEARED ;return 0 ; err:
arch/x86/kvm/x86.c +2 -0
@@ -9782,6 +9782,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.inapplicable_quirks =KVM_X86_CONDITIONAL_QUIRKS ;rdmsrl_safe (MSR_EFER , &kvm_host.efer);
@@ -12780,6 +12781,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)/* Decided by the vendor code for other VM types. */ kvm->arch.pre_fault_allowed = type ==KVM_X86_DEFAULT_VM || type ==KVM_X86_SW_PROTECTED_VM ; + kvm->arch.disabled_quirks = kvm_caps.inapplicable_quirks; ret =kvm_page_track_init (kvm);if (ret)
arch/x86/kvm/x86.h +1 -0
@@ -32,6 +32,7 @@ struct kvm_caps {u64 supported_xcr0;u64 supported_xss;u64 supported_perf_cap; +u64 inapplicable_quirks; };struct kvm_host_values {
Signature · 1 line
2.51.0
Sasha Levin
maintainerPATCH 5/8 KVM: x86: Introduce supported_quirks to block disabling quirks
In reply to Sasha LevinFrom: Yan Zhao <[email protected]>
[ Upstream commit bd7d5362b4c4ac8b951385867a0fadfae0ba3c07 ]
Introduce supported_quirks in kvm_caps to store platform-specific force-enabled quirks.
No functional changes intended.
Message-ID: <[email protected]>
Stable-dep-of: e2ffe85b6d2b ("KVM: x86: Introduce KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM")
--- arch/x86/kvm/x86.c | 9 +++++---- arch/x86/kvm/x86.h | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-)
arch/x86/kvm/x86.c +5 -4
@@ -4801,7 +4801,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;
@@ -6534,11 +6534,11 @@ 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 : - kvm->arch.disabled_quirks |= cap->args[0 ]; + kvm->arch.disabled_quirks |= cap->args[0 ] & kvm_caps.supported_quirks; r =0 ;break ;case KVM_CAP_SPLIT_IRQCHIP : {
@@ -9782,6 +9782,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 ; kvm_caps.inapplicable_quirks =KVM_X86_CONDITIONAL_QUIRKS ;rdmsrl_safe (MSR_EFER , &kvm_host.efer);
@@ -12781,7 +12782,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)/* Decided by the vendor code for other VM types. */ kvm->arch.pre_fault_allowed = type ==KVM_X86_DEFAULT_VM || type ==KVM_X86_SW_PROTECTED_VM ; - kvm->arch.disabled_quirks = kvm_caps.inapplicable_quirks; + kvm->arch.disabled_quirks = kvm_caps.inapplicable_quirks & kvm_caps.supported_quirks; ret =kvm_page_track_init (kvm);if (ret)
arch/x86/kvm/x86.h +2 -0
@@ -32,6 +32,8 @@ struct kvm_caps {u64 supported_xcr0;u64 supported_xss;u64 supported_perf_cap; + +u64 supported_quirks;u64 inapplicable_quirks; };
Signature · 1 line
2.51.0
Sasha Levin
maintainerPATCH 6/8 KVM: x86: Introduce Intel specific quirk KVM_X86_QUIRK_IGNORE_GUEST_PAT
In reply to Sasha LevinFrom: Yan Zhao <[email protected]>
[ Upstream commit c9c1e20b4c7d60fa084b3257525d21a49fe651a1 ]
Introduce an Intel specific quirk KVM_X86_QUIRK_IGNORE_GUEST_PAT to have KVM ignore guest PAT when this quirk is enabled.
On AMD platforms, KVM always honors guest PAT. On Intel however there are two issues. First, KVM *cannot* honor guest PAT if CPU feature self-snoop is not supported. Second, UC access on certain Intel platforms can be very slow[1] and honoring guest PAT on those platforms may break some old guests that accidentally specify video RAM as UC. Those old guests may never expect the slowness since KVM always forces WB previously. See [2].
So, introduce a quirk that KVM can enable by default on all Intel platforms to avoid breaking old unmodifiable guests. Newer userspace can disable this quirk if it wishes KVM to honor guest PAT; disabling the quirk will fail if self-snoop is not supported, i.e. if KVM cannot obey the wish.
The quirk is a no-op on AMD and also if any assigned devices have non-coherent DMA. This is not an issue, as KVM_X86_QUIRK_CD_NW_CLEARED is another example of a quirk that is sometimes automatically disabled.
Message-ID: <[email protected]> [Use supported_quirks/inapplicable_quirks to support both AMD and
no-self-snoop cases, as well as to remove the shadow_memtype_mask check from kvm_mmu_may_ignore_guest_pat(). - Paolo]
Stable-dep-of: e2ffe85b6d2b ("KVM: x86: Introduce KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM")
--- Documentation/virt/kvm/api.rst | 22 ++++++++++++++++++ arch/x86/include/asm/kvm_host.h | 6 +++-- arch/x86/include/uapi/asm/kvm.h | 1 + arch/x86/kvm/mmu.h | 2 +- arch/x86/kvm/mmu/mmu.c | 10 ++++---- arch/x86/kvm/vmx/vmx.c | 41 +++++++++++++++++++++++++++------ arch/x86/kvm/x86.c | 6 ++++- 7 files changed, 73 insertions(+), 15 deletions(-)
Documentation/virt/kvm/api.rst +22 -0
@@ -8129,6 +8129,28 @@ KVM_X86_QUIRK_STUFF_FEATURE_MSRS By default, at vCPU creation, KVM sets the and 0x489), as KVM does now allow them to be set by userspace (KVM sets them based on guest CPUID, for safety purposes). + +KVM_X86_QUIRK_IGNORE_GUEST_PAT By default, on Intel platforms, KVM ignores + guest PAT and forces the effective memory + type to WB in EPT. The quirk is not available + on Intel platforms which are incapable of + safely honoring guest PAT (i.e., without CPU + self-snoop, KVM always ignores guest PAT and + forces effective memory type to WB). It is + also ignored on AMD platforms or, on Intel, + when a VM has non-coherent DMA devices + assigned; KVM always honors guest PAT in + such case. The quirk is needed to avoid + slowdowns on certain Intel Xeon platforms + (e.g. ICX, SPR) where self-snoop feature is + supported but UC is slow enough to cause + issues with some older guests that use + UC instead of WC to map the video RAM. + Userspace can disable the quirk to honor + guest PAT if it knows that there is no such + guest software, for example if it does not + expose a bochs graphics device (which is + known to have had a buggy driver). =================================== ============================================ 7.32 KVM_CAP_MAX_VCPU_ID
arch/x86/include/asm/kvm_host.h +4 -2
@@ -2386,10 +2386,12 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages);KVM_X86_QUIRK_FIX_HYPERCALL_INSN | \KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS | \KVM_X86_QUIRK_SLOT_ZAP_ALL | \ - KVM_X86_QUIRK_STUFF_FEATURE_MSRS) +KVM_X86_QUIRK_STUFF_FEATURE_MSRS | \ + KVM_X86_QUIRK_IGNORE_GUEST_PAT) #define KVM_X86_CONDITIONAL_QUIRKS \ - KVM_X86_QUIRK_CD_NW_CLEARED + (KVM_X86_QUIRK_CD_NW_CLEARED | \ +KVM_X86_QUIRK_IGNORE_GUEST_PAT )/* * KVM previously used a u32 field in kvm_run to indicate the hypercall was
arch/x86/include/uapi/asm/kvm.h +1 -0
@@ -441,6 +441,7 @@ struct kvm_sync_regs {#define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS (1 << 6)#define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7)#define KVM_X86_QUIRK_STUFF_FEATURE_MSRS (1 << 8) +#define KVM_X86_QUIRK_IGNORE_GUEST_PAT (1 << 9)#define KVM_STATE_NESTED_FORMAT_VMX 0#define KVM_STATE_NESTED_FORMAT_SVM 1
arch/x86/kvm/mmu.h +1 -1
@@ -222,7 +222,7 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,return -(u32 )fault & errcode; } -bool kvm_mmu_may_ignore_guest_pat (void ); +bool kvm_mmu_may_ignore_guest_pat (struct kvm *kvm);int kvm_mmu_post_init_vm (struct kvm *kvm);void kvm_mmu_pre_destroy_vm (struct kvm *kvm);
arch/x86/kvm/mmu/mmu.c +6 -4
@@ -4713,17 +4713,19 @@ static int kvm_tdp_mmu_page_fault(struct kvm_vcpu *vcpu, }#endif -bool kvm_mmu_may_ignore_guest_pat (void ) +bool kvm_mmu_may_ignore_guest_pat (struct kvm *kvm) {/* * When EPT is enabled (shadow_memtype_mask is non-zero), and the VM * has non-coherent DMA (DMA doesn't snoop CPU caches), KVM's ABI is to * honor the memtype from the guest's PAT so that guest accesses to * memory that is DMA'd aren't cached against the guest's wishes. As a -* result, KVM _may_ ignore guest PAT, whereas without non-coherent DMA, -* KVM _always_ ignores guest PAT (when EPT is enabled). +* result, KVM _may_ ignore guest PAT, whereas without non-coherent DMA. +* KVM _always_ ignores guest PAT, when EPT is enabled and when quirk +* KVM_X86_QUIRK_IGNORE_GUEST_PAT is enabled or the CPU lacks the +* ability to safely honor guest PAT. */ -return shadow_memtype_mask; +return kvm_check_has_quirk (kvm,KVM_X86_QUIRK_IGNORE_GUEST_PAT ); }int kvm_tdp_page_fault (struct kvm_vcpu *vcpu,struct kvm_page_fault *fault)
arch/x86/kvm/vmx/vmx.c +34 -7
59 lines not on this page · raw message
arch/x86/kvm/x86.c +5 -1
@@ -9828,6 +9828,10 @@ int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)if (IS_ENABLED (CONFIG_KVM_SW_PROTECTED_VM ) && tdp_mmu_enabled) kvm_caps.supported_vm_types |=BIT (KVM_X86_SW_PROTECTED_VM ); +/* KVM always ignores guest PAT for shadow paging. */ +if (!tdp_enabled) + kvm_caps.supported_quirks &= ~KVM_X86_QUIRK_IGNORE_GUEST_PAT ; +if (!kvm_cpu_cap_has (X86_FEATURE_XSAVES )) kvm_caps.supported_xss =0 ;
@@ -13601,7 +13605,7 @@ static void kvm_noncoherent_dma_assignment_start_or_stop(struct kvm *kvm)* (or last) non-coherent device is (un)registered to so that new SPTEs * with the correct "ignore guest PAT" setting are created. */ -if (kvm_mmu_may_ignore_guest_pat ()) +if (kvm_mmu_may_ignore_guest_pat (kvm))kvm_zap_gfn_range (kvm,gpa_to_gfn (0 ),gpa_to_gfn (~0ULL )); }
Signature · 1 line
2.51.0
Sasha Levin
maintainerPATCH 7/8 KVM: nVMX: Add consistency checks for CR0.WP and CR4.CET
In reply to Sasha LevinFrom: Chao Gao <[email protected]>
[ Upstream commit 8060b2bd2dd05a19ad7ec248489d374f2bd2b057 ]
Add consistency checks for CR4.CET and CR0.WP in guest-state or host-state area in the VMCS12. This ensures that configurations with CR4.CET set and CR0.WP not set result in VM-entry failure, aligning with architectural behavior.
Stable-dep-of: e2ffe85b6d2b ("KVM: x86: Introduce KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM")
--- arch/x86/kvm/vmx/nested.c | 6 ++++++ 1 file changed, 6 insertions(+)
arch/x86/kvm/vmx/nested.c +6 -0
@@ -3022,6 +3022,9 @@ static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu, CC(!kvm_vcpu_is_legal_cr3(vcpu, vmcs12->host_cr3)))return -EINVAL ; +if (CC (vmcs12->host_cr4 &X86_CR4_CET && !(vmcs12->host_cr0 &X86_CR0_WP ))) +return -EINVAL ; +if (CC (is_noncanonical_msr_address (vmcs12->host_ia32_sysenter_esp, vcpu)) ||CC (is_noncanonical_msr_address (vmcs12->host_ia32_sysenter_eip, vcpu)))return -EINVAL ;
@@ -3136,6 +3139,9 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu, CC(!nested_guest_cr4_valid(vcpu, vmcs12->guest_cr4)))return -EINVAL ; +if (CC (vmcs12->guest_cr4 &X86_CR4_CET && !(vmcs12->guest_cr0 &X86_CR0_WP ))) +return -EINVAL ; +if ((vmcs12->vm_entry_controls &VM_ENTRY_LOAD_DEBUG_CONTROLS ) && (CC (!kvm_dr7_valid (vmcs12->guest_dr7)) ||CC (!vmx_is_valid_debugctl (vcpu, vmcs12->guest_ia32_debugctl, false))))
Signature · 1 line
2.51.0
Sasha Levin
maintainerPATCH 8/8 KVM: x86: Introduce KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM
In reply to Sasha LevinFrom: Jim Mattson <[email protected]>
[ Upstream commit e2ffe85b6d2bb7780174b87aa4468a39be17eb81 ]
Add KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM to allow L1 to set FREEZE_IN_SMM in vmcs12's GUEST_IA32_DEBUGCTL field, as permitted prior to commit 6b1dd26544d0 ("KVM: VMX: Preserve host's DEBUGCTLMSR_FREEZE_IN_SMM while running the guest"). Enable the quirk by default for backwards compatibility (like all quirks); userspace can disable it via KVM_CAP_DISABLE_QUIRKS2 for consistency with the constraints on WRMSR(IA32_DEBUGCTL).
Note that the quirk only bypasses the consistency check. The vmcs02 bit is still owned by the host, and PMCs are not frozen during virtualized SMM. In particular, if a host administrator decides that PMCs should not be frozen during physical SMM, then L1 has no say in the matter.
--- Documentation/virt/kvm/api.rst | 8 ++++++++ arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/include/uapi/asm/kvm.h | 1 + arch/x86/kvm/vmx/nested.c | 22 ++++++++++++++++++---- 4 files changed, 29 insertions(+), 5 deletions(-)
Documentation/virt/kvm/api.rst +8 -0
@@ -8151,6 +8151,14 @@ KVM_X86_QUIRK_IGNORE_GUEST_PAT By default, on Intel platforms, KVM ignores guest software, for example if it does not expose a bochs graphics device (which is known to have had a buggy driver). + +KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM By default, KVM relaxes the consistency + check for GUEST_IA32_DEBUGCTL in vmcs12 + to allow FREEZE_IN_SMM to be set. When + this quirk is disabled, KVM requires this + bit to be cleared. Note that the vmcs02 + bit is still completely controlled by the + host, regardless of the quirk setting. =================================== ============================================ 7.32 KVM_CAP_MAX_VCPU_ID
arch/x86/include/asm/kvm_host.h +2 -1
@@ -2387,7 +2387,8 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages); KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS | \ KVM_X86_QUIRK_SLOT_ZAP_ALL | \ KVM_X86_QUIRK_STUFF_FEATURE_MSRS | \ - KVM_X86_QUIRK_IGNORE_GUEST_PAT) + KVM_X86_QUIRK_IGNORE_GUEST_PAT | \ + KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM)#define KVM_X86_CONDITIONAL_QUIRKS \ (KVM_X86_QUIRK_CD_NW_CLEARED | \
arch/x86/include/uapi/asm/kvm.h +1 -0
@@ -442,6 +442,7 @@ struct kvm_sync_regs {#define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7)#define KVM_X86_QUIRK_STUFF_FEATURE_MSRS (1 << 8)#define KVM_X86_QUIRK_IGNORE_GUEST_PAT (1 << 9) +#define KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM (1 << 10)#define KVM_STATE_NESTED_FORMAT_VMX 0#define KVM_STATE_NESTED_FORMAT_SVM 1
arch/x86/kvm/vmx/nested.c +18 -4
@@ -3142,10 +3142,24 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,if (CC (vmcs12->guest_cr4 &X86_CR4_CET && !(vmcs12->guest_cr0 &X86_CR0_WP )))return -EINVAL ; -if ((vmcs12->vm_entry_controls &VM_ENTRY_LOAD_DEBUG_CONTROLS ) && - (CC (!kvm_dr7_valid (vmcs12->guest_dr7)) || -CC (!vmx_is_valid_debugctl (vcpu, vmcs12->guest_ia32_debugctl, false)))) -return -EINVAL ; +if (vmcs12->vm_entry_controls &VM_ENTRY_LOAD_DEBUG_CONTROLS ) { +u64 debugctl = vmcs12->guest_ia32_debugctl; + +/* +* FREEZE_IN_SMM is not virtualized, but allow L1 to set it in +* vmcs12's DEBUGCTL under a quirk for backwards compatibility. +* Note that the quirk only relaxes the consistency check. The +* vmcc02 bit is still under the control of the host. In +* particular, if a host administrator decides to clear the bit, +* then L1 has no say in the matter. +*/ +if (kvm_check_has_quirk (vcpu->kvm,KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM )) + debugctl &= ~DEBUGCTLMSR_FREEZE_IN_SMM ; + +if (CC (!kvm_dr7_valid (vmcs12->guest_dr7)) || +CC (!vmx_is_valid_debugctl (vcpu, debugctl, false))) +return -EINVAL ; + }if ((vmcs12->vm_entry_controls &VM_ENTRY_LOAD_IA32_PAT ) &&CC (!kvm_pat_valid (vmcs12->guest_ia32_pat)))
Signature · 1 line
2.51.0