Skip to content

Commit b5fa221

Browse files
committed
KVM: SEV: Synchronize MSR_IA32_XSS from the GHCB when it's valid
Synchronize XSS from the GHCB to KVM's internal tracking if the guest marks XSS as valid on a #VMGEXIT. Like XCR0, KVM needs an up-to-date copy of XSS in order to compute the required XSTATE size when emulating CPUID.0xD.0x1 for the guest. Treat the incoming XSS change as an emulated write, i.e. validatate the guest-provided value, to avoid letting the guest load garbage into KVM's tracking. Simply ignore bad values, as either the guest managed to get an unsupported value into hardware, or the guest is misbehaving and providing pure garbage. In either case, KVM can't fix the broken guest. Explicitly allow access to XSS at all times, as KVM needs to ensure its copy of XSS stays up-to-date. E.g. KVM supports migration of SEV-ES guests and so needs to allow the host to save/restore XSS, otherwise a guest that *knows* its XSS hasn't change could get stale/bad CPUID emulation if the guest doesn't provide XSS in the GHCB on every exit. This creates a hypothetical problem where a guest could request emulation of RDMSR or WRMSR on XSS, but arguably that's not even a problem, e.g. it would be entirely reasonable for a guest to request "emulation" as a way to inform the hypervisor that its XSS value has been modified. Note, emulating the change as an MSR write also takes care of side effects, e.g. marking dynamic CPUID bits as dirty. Suggested-by: John Allen <john.allen@amd.com> base-commit: 14298d819d5a6b7180a4089e7d2121ca3551dc6c Link: https://lore.kernel.org/r/20250919223258.1604852-40-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 38c46bd commit b5fa221

File tree

3 files changed

+6
-2
lines changed

3 files changed

+6
-2
lines changed

arch/x86/kvm/svm/sev.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3310,6 +3310,9 @@ static void sev_es_sync_from_ghcb(struct vcpu_svm *svm)
33103310
if (kvm_ghcb_xcr0_is_valid(svm))
33113311
__kvm_set_xcr(vcpu, 0, kvm_ghcb_get_xcr0(svm));
33123312

3313+
if (kvm_ghcb_xss_is_valid(svm))
3314+
__kvm_emulate_msr_write(vcpu, MSR_IA32_XSS, kvm_ghcb_get_xss(svm));
3315+
33133316
/* Copy the GHCB exit information into the VMCB fields */
33143317
exit_code = kvm_ghcb_get_sw_exit_code(svm);
33153318
control->exit_code = lower_32_bits(exit_code);

arch/x86/kvm/svm/svm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2721,8 +2721,8 @@ static int svm_get_feature_msr(u32 msr, u64 *data)
27212721
static bool sev_es_prevent_msr_access(struct kvm_vcpu *vcpu,
27222722
struct msr_data *msr_info)
27232723
{
2724-
return sev_es_guest(vcpu->kvm) &&
2725-
vcpu->arch.guest_state_protected &&
2724+
return sev_es_guest(vcpu->kvm) && vcpu->arch.guest_state_protected &&
2725+
msr_info->index != MSR_IA32_XSS &&
27262726
!msr_write_intercepted(vcpu, msr_info->index);
27272727
}
27282728

arch/x86/kvm/svm/svm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,5 +941,6 @@ DEFINE_KVM_GHCB_ACCESSORS(sw_exit_info_1)
941941
DEFINE_KVM_GHCB_ACCESSORS(sw_exit_info_2)
942942
DEFINE_KVM_GHCB_ACCESSORS(sw_scratch)
943943
DEFINE_KVM_GHCB_ACCESSORS(xcr0)
944+
DEFINE_KVM_GHCB_ACCESSORS(xss)
944945

945946
#endif

0 commit comments

Comments
 (0)