Skip to content

Commit

Permalink
x86/fpu: Fix copy_xstate_to_uabi() to copy init states correctly
Browse files Browse the repository at this point in the history
When an extended state component is not present in fpstate, but in init
state, the function copies from init_fpstate via copy_feature().

But, dynamic states are not present in init_fpstate because of all-zeros
init states. Then retrieving them from init_fpstate will explode like this:

 BUG: kernel NULL pointer dereference, address: 0000000000000000
 ...
 RIP: 0010:memcpy_erms+0x6/0x10
  ? __copy_xstate_to_uabi_buf+0x381/0x870
  fpu_copy_guest_fpstate_to_uabi+0x28/0x80
  kvm_arch_vcpu_ioctl+0x14c/0x1460 [kvm]
  ? __this_cpu_preempt_check+0x13/0x20
  ? vmx_vcpu_put+0x2e/0x260 [kvm_intel]
  kvm_vcpu_ioctl+0xea/0x6b0 [kvm]
  ? kvm_vcpu_ioctl+0xea/0x6b0 [kvm]
  ? __fget_light+0xd4/0x130
  __x64_sys_ioctl+0xe3/0x910
  ? debug_smp_processor_id+0x17/0x20
  ? fpregs_assert_state_consistent+0x27/0x50
  do_syscall_64+0x3f/0x90
  entry_SYSCALL_64_after_hwframe+0x63/0xcd

Adjust the 'mask' to zero out the userspace buffer for the features that
are not available both from fpstate and from init_fpstate.

The dynamic features depend on the compacted XSAVE format. Ensure it is
enabled before reading XCOMP_BV in init_fpstate.

Fixes: 2308ee5 ("x86/fpu/amx: Enable the AMX feature in 64-bit mode")
Reported-by: Yuan Yao <[email protected]>
Suggested-by: Dave Hansen <[email protected]>
Signed-off-by: Chang S. Bae <[email protected]>
Signed-off-by: Dave Hansen <[email protected]>
Tested-by: Yuan Yao <[email protected]>
Link: https://lore.kernel.org/lkml/BYAPR11MB3717EDEF2351C958F2C86EED95259@BYAPR11MB3717.namprd11.prod.outlook.com/
Link: https://lkml.kernel.org/r/[email protected]
  • Loading branch information
ChangSeokBae authored and hansendc committed Oct 21, 2022
1 parent b329f5d commit 471f0aa
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions arch/x86/kernel/fpu/xstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1125,6 +1125,15 @@ void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate,
*/
mask = fpstate->user_xfeatures;

/*
* Dynamic features are not present in init_fpstate. When they are
* in an all zeros init state, remove those from 'mask' to zero
* those features in the user buffer instead of retrieving them
* from init_fpstate.
*/
if (fpu_state_size_dynamic())
mask &= (header.xfeatures | xinit->header.xcomp_bv);

for_each_extended_xfeature(i, mask) {
/*
* If there was a feature or alignment gap, zero the space
Expand Down

0 comments on commit 471f0aa

Please sign in to comment.