diff options
Diffstat (limited to 'arch/mips/include/asm/switch_to.h')
-rw-r--r-- | arch/mips/include/asm/switch_to.h | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h index ebb5c0f2f90d..c0ae27971e31 100644 --- a/arch/mips/include/asm/switch_to.h +++ b/arch/mips/include/asm/switch_to.h | |||
@@ -76,6 +76,22 @@ do { if (cpu_has_rw_llb) { \ | |||
76 | } while (0) | 76 | } while (0) |
77 | 77 | ||
78 | /* | 78 | /* |
79 | * Check FCSR for any unmasked exceptions pending set with `ptrace', | ||
80 | * clear them and send a signal. | ||
81 | */ | ||
82 | #define __sanitize_fcr31(next) \ | ||
83 | do { \ | ||
84 | unsigned long fcr31 = mask_fcr31_x(next->thread.fpu.fcr31); \ | ||
85 | void __user *pc; \ | ||
86 | \ | ||
87 | if (unlikely(fcr31)) { \ | ||
88 | pc = (void __user *)task_pt_regs(next)->cp0_epc; \ | ||
89 | next->thread.fpu.fcr31 &= ~fcr31; \ | ||
90 | force_fcr31_sig(fcr31, pc, next); \ | ||
91 | } \ | ||
92 | } while (0) | ||
93 | |||
94 | /* | ||
79 | * For newly created kernel threads switch_to() will return to | 95 | * For newly created kernel threads switch_to() will return to |
80 | * ret_from_kernel_thread, newly created user threads to ret_from_fork. | 96 | * ret_from_kernel_thread, newly created user threads to ret_from_fork. |
81 | * That is, everything following resume() will be skipped for new threads. | 97 | * That is, everything following resume() will be skipped for new threads. |
@@ -85,6 +101,8 @@ do { if (cpu_has_rw_llb) { \ | |||
85 | do { \ | 101 | do { \ |
86 | __mips_mt_fpaff_switch_to(prev); \ | 102 | __mips_mt_fpaff_switch_to(prev); \ |
87 | lose_fpu_inatomic(1, prev); \ | 103 | lose_fpu_inatomic(1, prev); \ |
104 | if (tsk_used_math(next)) \ | ||
105 | __sanitize_fcr31(next); \ | ||
88 | if (cpu_has_dsp) { \ | 106 | if (cpu_has_dsp) { \ |
89 | __save_dsp(prev); \ | 107 | __save_dsp(prev); \ |
90 | __restore_dsp(next); \ | 108 | __restore_dsp(next); \ |