diff options
| author | Jim Mattson <jmattson@google.com> | 2026-09-30 14:21:11 -0700 |
|---|---|---|
| committer | Sean Christopherson <seanjc@google.com> | 2026-09-30 14:22:38 -0700 |
| commit | 7358d13e1f1975bc8ddd2b02df70d2cdf638273a (patch) | |
| tree | 042ca6577616458f35874276a419606305bce339 /scripts/basic/split-include.c | |
| parent | 192dbad1bc0fb23460beef0c72b3590bfe613f35 (diff) | |
| download | linux-7358d13e1f1975bc8ddd2b02df70d2cdf638273a.tar.gz linux-7358d13e1f1975bc8ddd2b02df70d2cdf638273a.zip | |
KVM: x86: Honor the guest's EFER_LMSLE_MBZ
Reject guest attempts to set EFER.LMSLE if userspace enumerates
EFER_LMSLE_MBZ, CPUID.80000008H:EBX[bit 20], in guest CPUID, so that userspace
can hide long mode segment limits from the guest even on CPUs that support
LMSLE, e.g. for migration compatibility between Rome and Milan.
Enumerate the defeature as *partially* emulated, i.e. as supported by KVM but
never advertised, so that kvm_vcpu_after_set_cpuid() propagates userspace's bit
into vcpu->arch.cpu_caps. Checking guest_cpu_cap_has() in __kvm_valid_efer()
doesn't suffice on its own, because KVM clears the defeature in kvm_cpu_caps
precisely on the CPUs where it needs to be emulated, i.e. cpu_caps would never
hold the bit no matter what userspace puts in guest CPUID. Don't advertise the
defeature in KVM_GET_SUPPORTED_CPUID, as that would take EFER.LMSLE away from
userspace that blindly stuffs KVM's supported CPUID into KVM_SET_CPUID2.
MONITOR/MWAIT gets the same treatment.
Enforce the defeature only for guest-initiated writes, as it's a guest CPUID
consistency check, not a host capability. See commit 11988499e62b ("KVM: x86:
Skip EFER vs. guest CPUID checks for host-initiated writes"). Note,
KVM_SET_SREGS does reject EFER.LMSLE, as it runs the full set of guest CPUID
checks, as does nested VMRUN, i.e. L1 can't sneak EFER.LMSLE into L2 via
vmcb12.
Mask EFER_LMSLE out of the value consumed by efer_trap(), which handles
SVM_EXIT_EFER_WRITE_TRAP. EFER writes are *trapped*, not intercepted, i.e.
hardware has already committed the write by the time KVM gains control, and
the trap is enabled if and only if the guest is SEV-ES, whose EFER lives in
the encrypted VMSA and so can't be fixed up by KVM. Rejecting the write would
inject a #GP *and* leave EFER.LMSLE set in the guest, which is strictly worse
than honoring a write that hardware itself allowed. EFER_SVME is already
masked out for a similar "KVM can't enforce this here" reason.
Opportunistically fix the whitespace damage around __kvm_valid_efer().
Document the resulting two-level contract in api.rst, i.e. that userspace may
set the defeature even when KVM doesn't enumerate it.
Suggested-by: Sean Christopherson <seanjc@google.com>
Assisted-by: LLM
Signed-off-by: Jim Mattson <jmattson@google.com>
Link: https://patch.msgid.link/20260930212114.3500045-3-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Diffstat (limited to 'scripts/basic/split-include.c')
0 files changed, 0 insertions, 0 deletions
