Skip to content

Commit 509e880

Browse files
gaochaointelhansendc
authored andcommitted
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 <[email protected]> Signed-off-by: Chao Gao <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Reviewed-by: Rick Edgecombe <[email protected]> Reviewed-by: John Allen <[email protected]> Link: https://lore.kernel.org/all/20250522151031.426788-4-chao.gao%40intel.com
1 parent 7c2c893 commit 509e880

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

arch/x86/kernel/fpu/core.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -243,19 +243,22 @@ bool fpu_alloc_guest_fpstate(struct fpu_guest *gfpu)
243243
struct fpstate *fpstate;
244244
unsigned int size;
245245

246-
size = fpu_kernel_cfg.default_size + ALIGN(offsetof(struct fpstate, regs), 64);
246+
size = guest_default_cfg.size + ALIGN(offsetof(struct fpstate, regs), 64);
247+
247248
fpstate = vzalloc(size);
248249
if (!fpstate)
249250
return false;
250251

252+
/* Initialize indicators to reflect properties of the fpstate */
253+
fpstate->is_valloc = true;
254+
fpstate->is_guest = true;
255+
251256
/* Leave xfd to 0 (the reset value defined by spec) */
252257
__fpstate_reset(fpstate, 0);
253258
fpstate_init_user(fpstate);
254-
fpstate->is_valloc = true;
255-
fpstate->is_guest = true;
256259

257260
gfpu->fpstate = fpstate;
258-
gfpu->xfeatures = fpu_kernel_cfg.default_features;
261+
gfpu->xfeatures = guest_default_cfg.features;
259262

260263
/*
261264
* KVM sets the FP+SSE bits in the XSAVE header when copying FPU state
@@ -544,10 +547,22 @@ void fpstate_init_user(struct fpstate *fpstate)
544547

545548
static void __fpstate_reset(struct fpstate *fpstate, u64 xfd)
546549
{
547-
/* Initialize sizes and feature masks */
548-
fpstate->size = fpu_kernel_cfg.default_size;
550+
/*
551+
* Supervisor features (and thus sizes) may diverge between guest
552+
* FPUs and host FPUs, as some supervisor features are supported
553+
* for guests despite not being utilized by the host. User
554+
* features and sizes are always identical, which allows for
555+
* common guest and userspace ABI.
556+
*/
557+
if (fpstate->is_guest) {
558+
fpstate->size = guest_default_cfg.size;
559+
fpstate->xfeatures = guest_default_cfg.features;
560+
} else {
561+
fpstate->size = fpu_kernel_cfg.default_size;
562+
fpstate->xfeatures = fpu_kernel_cfg.default_features;
563+
}
564+
549565
fpstate->user_size = fpu_user_cfg.default_size;
550-
fpstate->xfeatures = fpu_kernel_cfg.default_features;
551566
fpstate->user_xfeatures = fpu_user_cfg.default_features;
552567
fpstate->xfd = xfd;
553568
}

0 commit comments

Comments
 (0)