Commit e2ffe85b authored by Jim Mattson's avatar Jim Mattson Committed by Paolo Bonzini
Browse files

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 6b1dd265 ("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.

Fixes: 095686e6 ("KVM: nVMX: Check vmcs12->guest_ia32_debugctl on nested VM-Enter")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarJim Mattson <jmattson@google.com>
Link: https://patch.msgid.link/20260205231537.1278753-1-jmattson@google.com


[sean: tag for stable@, clean-up and fix goofs in the comment and docs]
Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
[Rename quirk. - Paolo]
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent b54e4707
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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
+2 −1
Original line number Diff line number Diff line
@@ -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 |		\
+1 −0
Original line number Diff line number Diff line
@@ -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
+18 −4
Original line number Diff line number Diff line
@@ -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))))
	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)))