@@ -250,10 +250,8 @@ sanitize_restored_user_xstate(union fpregs_state *state,
250
250
}
251
251
}
252
252
253
- /*
254
- * Restore the FPU state directly from the userspace signal frame.
255
- */
256
- static int restore_fpregs_from_user (void __user * buf , u64 xrestore , bool fx_only )
253
+ static int __restore_fpregs_from_user (void __user * buf , u64 xrestore ,
254
+ bool fx_only )
257
255
{
258
256
if (use_xsave ()) {
259
257
u64 init_bv = xfeatures_mask_uabi () & ~xrestore ;
@@ -274,6 +272,57 @@ static int restore_fpregs_from_user(void __user *buf, u64 xrestore, bool fx_only
274
272
}
275
273
}
276
274
275
+ static int restore_fpregs_from_user (void __user * buf , u64 xrestore , bool fx_only )
276
+ {
277
+ struct fpu * fpu = & current -> thread .fpu ;
278
+ int ret ;
279
+
280
+ fpregs_lock ();
281
+ pagefault_disable ();
282
+ ret = __restore_fpregs_from_user (buf , xrestore , fx_only );
283
+ pagefault_enable ();
284
+
285
+ if (unlikely (ret )) {
286
+ /*
287
+ * The above did an FPU restore operation, restricted to
288
+ * the user portion of the registers, and failed, but the
289
+ * microcode might have modified the FPU registers
290
+ * nevertheless.
291
+ *
292
+ * If the FPU registers do not belong to current, then
293
+ * invalidate the FPU register state otherwise the task
294
+ * might preempt current and return to user space with
295
+ * corrupted FPU registers.
296
+ *
297
+ * In case current owns the FPU registers then no further
298
+ * action is required. The fixup in the slow path will
299
+ * handle it correctly.
300
+ */
301
+ if (test_thread_flag (TIF_NEED_FPU_LOAD ))
302
+ __cpu_invalidate_fpregs_state ();
303
+ fpregs_unlock ();
304
+ return ret ;
305
+ }
306
+
307
+ /*
308
+ * Restore supervisor states: previous context switch etc has done
309
+ * XSAVES and saved the supervisor states in the kernel buffer from
310
+ * which they can be restored now.
311
+ *
312
+ * It would be optimal to handle this with a single XRSTORS, but
313
+ * this does not work because the rest of the FPU registers have
314
+ * been restored from a user buffer directly. The single XRSTORS
315
+ * happens below, when the user buffer has been copied to the
316
+ * kernel one.
317
+ */
318
+ if (test_thread_flag (TIF_NEED_FPU_LOAD ) && xfeatures_mask_supervisor ())
319
+ os_xrstor (& fpu -> state .xsave , xfeatures_mask_supervisor ());
320
+
321
+ fpregs_mark_activate ();
322
+ fpregs_unlock ();
323
+ return 0 ;
324
+ }
325
+
277
326
static int __fpu_restore_sig (void __user * buf , void __user * buf_fx ,
278
327
bool ia32_fxstate )
279
328
{
@@ -298,61 +347,16 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
298
347
user_xfeatures = fx_sw_user .xfeatures ;
299
348
}
300
349
301
- if (!ia32_fxstate ) {
350
+ if (likely ( !ia32_fxstate ) ) {
302
351
/*
303
352
* Attempt to restore the FPU registers directly from user
304
- * memory. For that to succeed, the user access cannot cause
305
- * page faults. If it does, fall back to the slow path below,
306
- * going through the kernel buffer with the enabled pagefault
307
- * handler.
353
+ * memory. For that to succeed, the user access cannot cause page
354
+ * faults. If it does, fall back to the slow path below, going
355
+ * through the kernel buffer with the enabled pagefault handler.
308
356
*/
309
- fpregs_lock ();
310
- pagefault_disable ();
311
357
ret = restore_fpregs_from_user (buf_fx , user_xfeatures , fx_only );
312
- pagefault_enable ();
313
- if (!ret ) {
314
-
315
- /*
316
- * Restore supervisor states: previous context switch
317
- * etc has done XSAVES and saved the supervisor states
318
- * in the kernel buffer from which they can be restored
319
- * now.
320
- *
321
- * We cannot do a single XRSTORS here - which would
322
- * be nice - because the rest of the FPU registers are
323
- * being restored from a user buffer directly. The
324
- * single XRSTORS happens below, when the user buffer
325
- * has been copied to the kernel one.
326
- */
327
- if (test_thread_flag (TIF_NEED_FPU_LOAD ) &&
328
- xfeatures_mask_supervisor ()) {
329
- os_xrstor (& fpu -> state .xsave ,
330
- xfeatures_mask_supervisor ());
331
- }
332
- fpregs_mark_activate ();
333
- fpregs_unlock ();
358
+ if (likely (!ret ))
334
359
return 0 ;
335
- }
336
-
337
- /*
338
- * The above did an FPU restore operation, restricted to
339
- * the user portion of the registers, and failed, but the
340
- * microcode might have modified the FPU registers
341
- * nevertheless.
342
- *
343
- * If the FPU registers do not belong to current, then
344
- * invalidate the FPU register state otherwise the task might
345
- * preempt current and return to user space with corrupted
346
- * FPU registers.
347
- *
348
- * In case current owns the FPU registers then no further
349
- * action is required. The fixup below will handle it
350
- * correctly.
351
- */
352
- if (test_thread_flag (TIF_NEED_FPU_LOAD ))
353
- __cpu_invalidate_fpregs_state ();
354
-
355
- fpregs_unlock ();
356
360
} else {
357
361
/*
358
362
* For 32-bit frames with fxstate, copy the fxstate so it can
0 commit comments