Commit b0237dad authored by Jing Liu's avatar Jing Liu Committed by Paolo Bonzini

x86/fpu: Make XFD initialization in __fpstate_reset() a function argument

vCPU threads are different from native tasks regarding to the initial XFD
value. While all native tasks follow a fixed value (init_fpstate::xfd)
established by the FPU core at boot, vCPU threads need to obey the reset
value (i.e. ZERO) defined by the specification, to meet the expectation of
the guest.

Let the caller supply an argument and adjust the host and guest related
invocations accordingly.
Signed-off-by: default avatarJing Liu <jing2.liu@intel.com>
Signed-off-by: default avatarYang Zhong <yang.zhong@intel.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarJing Liu <jing2.liu@intel.com>
Signed-off-by: default avatarYang Zhong <yang.zhong@intel.com>
Message-Id: <20220105123532.12586-6-yang.zhong@intel.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 445ecdf7
...@@ -199,7 +199,7 @@ void fpu_reset_from_exception_fixup(void) ...@@ -199,7 +199,7 @@ void fpu_reset_from_exception_fixup(void)
} }
#if IS_ENABLED(CONFIG_KVM) #if IS_ENABLED(CONFIG_KVM)
static void __fpstate_reset(struct fpstate *fpstate); static void __fpstate_reset(struct fpstate *fpstate, u64 xfd);
static void fpu_init_guest_permissions(struct fpu_guest *gfpu) static void fpu_init_guest_permissions(struct fpu_guest *gfpu)
{ {
...@@ -231,7 +231,8 @@ bool fpu_alloc_guest_fpstate(struct fpu_guest *gfpu) ...@@ -231,7 +231,8 @@ bool fpu_alloc_guest_fpstate(struct fpu_guest *gfpu)
if (!fpstate) if (!fpstate)
return false; return false;
__fpstate_reset(fpstate); /* Leave xfd to 0 (the reset value defined by spec) */
__fpstate_reset(fpstate, 0);
fpstate_init_user(fpstate); fpstate_init_user(fpstate);
fpstate->is_valloc = true; fpstate->is_valloc = true;
fpstate->is_guest = true; fpstate->is_guest = true;
...@@ -454,21 +455,21 @@ void fpstate_init_user(struct fpstate *fpstate) ...@@ -454,21 +455,21 @@ void fpstate_init_user(struct fpstate *fpstate)
fpstate_init_fstate(fpstate); fpstate_init_fstate(fpstate);
} }
static void __fpstate_reset(struct fpstate *fpstate) static void __fpstate_reset(struct fpstate *fpstate, u64 xfd)
{ {
/* Initialize sizes and feature masks */ /* Initialize sizes and feature masks */
fpstate->size = fpu_kernel_cfg.default_size; fpstate->size = fpu_kernel_cfg.default_size;
fpstate->user_size = fpu_user_cfg.default_size; fpstate->user_size = fpu_user_cfg.default_size;
fpstate->xfeatures = fpu_kernel_cfg.default_features; fpstate->xfeatures = fpu_kernel_cfg.default_features;
fpstate->user_xfeatures = fpu_user_cfg.default_features; fpstate->user_xfeatures = fpu_user_cfg.default_features;
fpstate->xfd = init_fpstate.xfd; fpstate->xfd = xfd;
} }
void fpstate_reset(struct fpu *fpu) void fpstate_reset(struct fpu *fpu)
{ {
/* Set the fpstate pointer to the default fpstate */ /* Set the fpstate pointer to the default fpstate */
fpu->fpstate = &fpu->__fpstate; fpu->fpstate = &fpu->__fpstate;
__fpstate_reset(fpu->fpstate); __fpstate_reset(fpu->fpstate, init_fpstate.xfd);
/* Initialize the permission related info in fpu */ /* Initialize the permission related info in fpu */
fpu->perm.__state_perm = fpu_kernel_cfg.default_features; fpu->perm.__state_perm = fpu_kernel_cfg.default_features;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment