Skip to content

Commit e2ffe85

Browse files
jsmattsonjrbonzini
authored andcommitted
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 6b1dd26 ("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: 095686e ("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>
1 parent b54e470 commit e2ffe85

4 files changed

Lines changed: 29 additions & 5 deletions

File tree

Documentation/virt/kvm/api.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8543,6 +8543,14 @@ KVM_X86_QUIRK_IGNORE_GUEST_PAT By default, on Intel platforms, KVM ignores
85438543
guest software, for example if it does not
85448544
expose a bochs graphics device (which is
85458545
known to have had a buggy driver).
8546+
8547+
KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM By default, KVM relaxes the consistency
8548+
check for GUEST_IA32_DEBUGCTL in vmcs12
8549+
to allow FREEZE_IN_SMM to be set. When
8550+
this quirk is disabled, KVM requires this
8551+
bit to be cleared. Note that the vmcs02
8552+
bit is still completely controlled by the
8553+
host, regardless of the quirk setting.
85468554
=================================== ============================================
85478555

85488556
7.32 KVM_CAP_MAX_VCPU_ID

arch/x86/include/asm/kvm_host.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2485,7 +2485,8 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages);
24852485
KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS | \
24862486
KVM_X86_QUIRK_SLOT_ZAP_ALL | \
24872487
KVM_X86_QUIRK_STUFF_FEATURE_MSRS | \
2488-
KVM_X86_QUIRK_IGNORE_GUEST_PAT)
2488+
KVM_X86_QUIRK_IGNORE_GUEST_PAT | \
2489+
KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM)
24892490

24902491
#define KVM_X86_CONDITIONAL_QUIRKS \
24912492
(KVM_X86_QUIRK_CD_NW_CLEARED | \

arch/x86/include/uapi/asm/kvm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ struct kvm_sync_regs {
476476
#define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7)
477477
#define KVM_X86_QUIRK_STUFF_FEATURE_MSRS (1 << 8)
478478
#define KVM_X86_QUIRK_IGNORE_GUEST_PAT (1 << 9)
479+
#define KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM (1 << 10)
479480

480481
#define KVM_STATE_NESTED_FORMAT_VMX 0
481482
#define KVM_STATE_NESTED_FORMAT_SVM 1

arch/x86/kvm/vmx/nested.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3300,10 +3300,24 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
33003300
if (CC(vmcs12->guest_cr4 & X86_CR4_CET && !(vmcs12->guest_cr0 & X86_CR0_WP)))
33013301
return -EINVAL;
33023302

3303-
if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS) &&
3304-
(CC(!kvm_dr7_valid(vmcs12->guest_dr7)) ||
3305-
CC(!vmx_is_valid_debugctl(vcpu, vmcs12->guest_ia32_debugctl, false))))
3306-
return -EINVAL;
3303+
if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS) {
3304+
u64 debugctl = vmcs12->guest_ia32_debugctl;
3305+
3306+
/*
3307+
* FREEZE_IN_SMM is not virtualized, but allow L1 to set it in
3308+
* vmcs12's DEBUGCTL under a quirk for backwards compatibility.
3309+
* Note that the quirk only relaxes the consistency check. The
3310+
* vmcc02 bit is still under the control of the host. In
3311+
* particular, if a host administrator decides to clear the bit,
3312+
* then L1 has no say in the matter.
3313+
*/
3314+
if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM))
3315+
debugctl &= ~DEBUGCTLMSR_FREEZE_IN_SMM;
3316+
3317+
if (CC(!kvm_dr7_valid(vmcs12->guest_dr7)) ||
3318+
CC(!vmx_is_valid_debugctl(vcpu, debugctl, false)))
3319+
return -EINVAL;
3320+
}
33073321

33083322
if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PAT) &&
33093323
CC(!kvm_pat_valid(vmcs12->guest_ia32_pat)))

0 commit comments

Comments
 (0)