On Wed, May 07, 2025, Chao Gao wrote: > From: Chao Gao <chao.gao@xxxxxxxxx> > Date: Fri, 31 May 2024 02:03:30 -0700 > Subject: [PATCH] x86/fpu: Initialize guest fpstate and FPU pseudo container > from guest defaults > > fpu_alloc_guest_fpstate() currently uses host defaults to initialize guest > fpstate and pseudo containers. Guest defaults were introduced to > differentiate the features and sizes of host and guest FPUs. Switch to > using guest defaults instead. > > Adjust __fpstate_reset() to handle different defaults for host and guest > FPUs. And to distinguish between the types of FPUs, move the initialization > of indicators (is_guest and is_valloc) before the reset. > > Suggested-by: Chang S. Bae <chang.seok.bae@xxxxxxxxx> > Signed-off-by: Chao Gao <chao.gao@xxxxxxxxx> > --- > arch/x86/kernel/fpu/core.c | 27 ++++++++++++++++++++------- > 1 file changed, 20 insertions(+), 7 deletions(-) > > diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c > index 444e517a8648..0d501bd25d79 100644 > --- a/arch/x86/kernel/fpu/core.c > +++ b/arch/x86/kernel/fpu/core.c > @@ -236,19 +236,22 @@ bool fpu_alloc_guest_fpstate(struct fpu_guest *gfpu) > struct fpstate *fpstate; > unsigned int size; > > - size = fpu_kernel_cfg.default_size + ALIGN(offsetof(struct fpstate, regs), 64); > + size = guest_default_cfg.size + ALIGN(offsetof(struct fpstate, regs), 64); > + > fpstate = vzalloc(size); > if (!fpstate) > return false; > > + /* Initialize indicators to reflect properties of the fpstate */ > + fpstate->is_valloc = true; > + fpstate->is_guest = true; > + > /* Leave xfd to 0 (the reset value defined by spec) */ > __fpstate_reset(fpstate, 0); > fpstate_init_user(fpstate); > - fpstate->is_valloc = true; > - fpstate->is_guest = true; > > gfpu->fpstate = fpstate; > - gfpu->xfeatures = fpu_kernel_cfg.default_features; > + gfpu->xfeatures = guest_default_cfg.features; > > /* > * KVM sets the FP+SSE bits in the XSAVE header when copying FPU state > @@ -535,10 +538,20 @@ void fpstate_init_user(struct fpstate *fpstate) > > static void __fpstate_reset(struct fpstate *fpstate, u64 xfd) > { > - /* Initialize sizes and feature masks */ > - fpstate->size = fpu_kernel_cfg.default_size; > + /* > + * Initialize sizes and feature masks. Supervisor features and > + * sizes may diverge between guest FPUs and host FPUs, whereas > + * user features and sizes are always identical the same. > + */ > + if (fpstate->is_guest) { > + fpstate->size = guest_default_cfg.size; > + fpstate->xfeatures = guest_default_cfg.features; > + } else { > + fpstate->size = fpu_kernel_cfg.default_size; > + fpstate->xfeatures = fpu_kernel_cfg.default_features; > + } Nice! I like this idea. > + > fpstate->user_size = fpu_user_cfg.default_size; > - fpstate->xfeatures = fpu_kernel_cfg.default_features; > fpstate->user_xfeatures = fpu_user_cfg.default_features; > fpstate->xfd = xfd; And then a follow-up patch (or same patch?) to do this? if (fpstate->is_guest) { fpstate->size = guest_default_cfg.size; fpstate->xfeatures = guest_default_cfg.features; fpstate->xfd = 0; } else { fpstate->size = fpu_kernel_cfg.default_size; fpstate->xfeatures = fpu_kernel_cfg.default_features; fpstate->xfd = init_fpstate.xfd; } > } > -- > 2.47.1