Skip to content

Commit 41f6710

Browse files
committed
KVM: x86: Manually clear MPX state only on INIT
Don't manually clear/zero MPX state on RESET, as the guest FPU state is zero allocated and KVM only does RESET during vCPU creation, i.e. the relevant state is guaranteed to be all zeroes. Opportunistically move the relevant code into a helper in anticipation of adding support for CET shadow stacks, which also has state that is zeroed on INIT. Signed-off-by: Yang Weijiang <weijiang.yang@intel.com> Tested-by: Mathias Krause <minipli@grsecurity.net> Tested-by: John Allen <john.allen@amd.com> Signed-off-by: Chao Gao <chao.gao@intel.com> Tested-by: Rick Edgecombe <rick.p.edgecombe@intel.com> Link: https://lore.kernel.org/r/20250812025606.74625-5-chao.gao@intel.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent c2aa58b commit 41f6710

File tree

1 file changed

+30
-16
lines changed

1 file changed

+30
-16
lines changed

arch/x86/kvm/x86.c

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12398,6 +12398,35 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
1239812398
kvfree(vcpu->arch.cpuid_entries);
1239912399
}
1240012400

12401+
static void kvm_xstate_reset(struct kvm_vcpu *vcpu, bool init_event)
12402+
{
12403+
struct fpstate *fpstate = vcpu->arch.guest_fpu.fpstate;
12404+
12405+
/*
12406+
* Guest FPU state is zero allocated and so doesn't need to be manually
12407+
* cleared on RESET, i.e. during vCPU creation.
12408+
*/
12409+
if (!init_event || !fpstate)
12410+
return;
12411+
12412+
/*
12413+
* On INIT, only select XSTATE components are zeroed, most components
12414+
* are unchanged. Currently, the only components that are zeroed and
12415+
* supported by KVM are MPX related.
12416+
*/
12417+
if (!kvm_mpx_supported())
12418+
return;
12419+
12420+
/*
12421+
* All paths that lead to INIT are required to load the guest's FPU
12422+
* state (because most paths are buried in KVM_RUN).
12423+
*/
12424+
kvm_put_guest_fpu(vcpu);
12425+
fpstate_clear_xstate_component(fpstate, XFEATURE_BNDREGS);
12426+
fpstate_clear_xstate_component(fpstate, XFEATURE_BNDCSR);
12427+
kvm_load_guest_fpu(vcpu);
12428+
}
12429+
1240112430
void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
1240212431
{
1240312432
struct kvm_cpuid_entry2 *cpuid_0x1;
@@ -12455,22 +12484,7 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
1245512484
kvm_async_pf_hash_reset(vcpu);
1245612485
vcpu->arch.apf.halted = false;
1245712486

12458-
if (vcpu->arch.guest_fpu.fpstate && kvm_mpx_supported()) {
12459-
struct fpstate *fpstate = vcpu->arch.guest_fpu.fpstate;
12460-
12461-
/*
12462-
* All paths that lead to INIT are required to load the guest's
12463-
* FPU state (because most paths are buried in KVM_RUN).
12464-
*/
12465-
if (init_event)
12466-
kvm_put_guest_fpu(vcpu);
12467-
12468-
fpstate_clear_xstate_component(fpstate, XFEATURE_BNDREGS);
12469-
fpstate_clear_xstate_component(fpstate, XFEATURE_BNDCSR);
12470-
12471-
if (init_event)
12472-
kvm_load_guest_fpu(vcpu);
12473-
}
12487+
kvm_xstate_reset(vcpu, init_event);
1247412488

1247512489
if (!init_event) {
1247612490
vcpu->arch.smbase = 0x30000;

0 commit comments

Comments
 (0)