mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-30 06:02:14 -04:00
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 commit6b1dd26544("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:095686e6fc("KVM: nVMX: Check vmcs12->guest_ia32_debugctl on nested VM-Enter") Cc: stable@vger.kernel.org Signed-off-by: Jim 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: Sean Christopherson <seanjc@google.com> [Rename quirk. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
committed by
Paolo Bonzini
parent
b54e4707a6
commit
e2ffe85b6d
@@ -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
|
||||
|
||||
@@ -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 | \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)))
|
||||
|
||||
Reference in New Issue
Block a user