diff options
Diffstat (limited to 'arch/x86/include/asm')
-rw-r--r-- | arch/x86/include/asm/i387.h | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h index 262bea981aa..6e87fa43c35 100644 --- a/arch/x86/include/asm/i387.h +++ b/arch/x86/include/asm/i387.h | |||
@@ -400,6 +400,48 @@ static inline void irq_ts_restore(int TS_state) | |||
400 | } | 400 | } |
401 | 401 | ||
402 | /* | 402 | /* |
403 | * The question "does this thread have fpu access?" | ||
404 | * is slightly racy, since preemption could come in | ||
405 | * and revoke it immediately after the test. | ||
406 | * | ||
407 | * However, even in that very unlikely scenario, | ||
408 | * we can just assume we have FPU access - typically | ||
409 | * to save the FP state - we'll just take a #NM | ||
410 | * fault and get the FPU access back. | ||
411 | * | ||
412 | * The actual user_fpu_begin/end() functions | ||
413 | * need to be preemption-safe, though. | ||
414 | * | ||
415 | * NOTE! user_fpu_end() must be used only after you | ||
416 | * have saved the FP state, and user_fpu_begin() must | ||
417 | * be used only immediately before restoring it. | ||
418 | * These functions do not do any save/restore on | ||
419 | * their own. | ||
420 | */ | ||
421 | static inline int user_has_fpu(void) | ||
422 | { | ||
423 | return current_thread_info()->status & TS_USEDFPU; | ||
424 | } | ||
425 | |||
426 | static inline void user_fpu_end(void) | ||
427 | { | ||
428 | preempt_disable(); | ||
429 | current_thread_info()->status &= ~TS_USEDFPU; | ||
430 | stts(); | ||
431 | preempt_enable(); | ||
432 | } | ||
433 | |||
434 | static inline void user_fpu_begin(void) | ||
435 | { | ||
436 | preempt_disable(); | ||
437 | if (!user_has_fpu()) { | ||
438 | clts(); | ||
439 | current_thread_info()->status |= TS_USEDFPU; | ||
440 | } | ||
441 | preempt_enable(); | ||
442 | } | ||
443 | |||
444 | /* | ||
403 | * These disable preemption on their own and are safe | 445 | * These disable preemption on their own and are safe |
404 | */ | 446 | */ |
405 | static inline void save_init_fpu(struct task_struct *tsk) | 447 | static inline void save_init_fpu(struct task_struct *tsk) |