diff options
author | Maciej W. Rozycki <macro@linux-mips.org> | 2015-04-03 18:27:15 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2015-04-07 19:10:19 -0400 |
commit | 304acb717e5b67cf56f05bc5b21123758e1f7ea0 (patch) | |
tree | 031d9969f99864c02701d9df056f92c894a56116 /arch/mips/include/asm | |
parent | 443c44032a54f9acf027a8e688380fddc809bc19 (diff) |
MIPS: Set `si_code' for SIGFPE signals sent from emulation too
Rework `process_fpemu_return' and move IEEE 754 exception interpretation
there, from `do_fpe'. Record the cause bits set in FCSR before they are
cleared and pass them through to `process_fpemu_return' so as to set
`si_code' correctly too for SIGFPE signals sent from emulation rather
than those issued by hardware with the FPE processor exception only.
For simplicity `mipsr2_decoder' assumes `*fcr31' has been preinitialised
and only sets it to anything if an FPU instruction has been emulated,
which in turn is the only case SIGFPE can be issued for here.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/9705/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/include/asm')
-rw-r--r-- | arch/mips/include/asm/fpu_emulator.h | 3 | ||||
-rw-r--r-- | arch/mips/include/asm/mips-r2-to-r6-emul.h | 9 |
2 files changed, 9 insertions, 3 deletions
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h index 6370c82eb5e1..bfcc5c64b7b0 100644 --- a/arch/mips/include/asm/fpu_emulator.h +++ b/arch/mips/include/asm/fpu_emulator.h | |||
@@ -66,7 +66,8 @@ extern int do_dsemulret(struct pt_regs *xcp); | |||
66 | extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, | 66 | extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, |
67 | struct mips_fpu_struct *ctx, int has_fpu, | 67 | struct mips_fpu_struct *ctx, int has_fpu, |
68 | void *__user *fault_addr); | 68 | void *__user *fault_addr); |
69 | int process_fpemu_return(int sig, void __user *fault_addr); | 69 | int process_fpemu_return(int sig, void __user *fault_addr, |
70 | unsigned long fcr31); | ||
70 | int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, | 71 | int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, |
71 | unsigned long *contpc); | 72 | unsigned long *contpc); |
72 | 73 | ||
diff --git a/arch/mips/include/asm/mips-r2-to-r6-emul.h b/arch/mips/include/asm/mips-r2-to-r6-emul.h index dd6f1de5b621..4b89f28047f7 100644 --- a/arch/mips/include/asm/mips-r2-to-r6-emul.h +++ b/arch/mips/include/asm/mips-r2-to-r6-emul.h | |||
@@ -84,11 +84,16 @@ extern void do_trap_or_bp(struct pt_regs *regs, unsigned int code, | |||
84 | 84 | ||
85 | #ifndef CONFIG_MIPSR2_TO_R6_EMULATOR | 85 | #ifndef CONFIG_MIPSR2_TO_R6_EMULATOR |
86 | static int mipsr2_emulation; | 86 | static int mipsr2_emulation; |
87 | static inline int mipsr2_decoder(struct pt_regs *regs, u32 inst) { return 0; }; | 87 | static inline int mipsr2_decoder(struct pt_regs *regs, u32 inst, |
88 | unsigned long *fcr31) | ||
89 | { | ||
90 | return 0; | ||
91 | }; | ||
88 | #else | 92 | #else |
89 | /* MIPS R2 Emulator ON/OFF */ | 93 | /* MIPS R2 Emulator ON/OFF */ |
90 | extern int mipsr2_emulation; | 94 | extern int mipsr2_emulation; |
91 | extern int mipsr2_decoder(struct pt_regs *regs, u32 inst); | 95 | extern int mipsr2_decoder(struct pt_regs *regs, u32 inst, |
96 | unsigned long *fcr31); | ||
92 | #endif /* CONFIG_MIPSR2_TO_R6_EMULATOR */ | 97 | #endif /* CONFIG_MIPSR2_TO_R6_EMULATOR */ |
93 | 98 | ||
94 | #define NO_R6EMU (cpu_has_mips_r6 && !mipsr2_emulation) | 99 | #define NO_R6EMU (cpu_has_mips_r6 && !mipsr2_emulation) |