aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/include/asm
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2015-04-03 18:27:48 -0400
committerRalf Baechle <ralf@linux-mips.org>2015-04-07 19:10:37 -0400
commit9b26616c8d9dae53fbac7f7cb2c6dd1308102976 (patch)
treed4249bd953d4fa955cecd1283cc0f518df83f8a2 /arch/mips/include/asm
parent232b6ec5df874236166fb0167cd473601a631715 (diff)
MIPS: Respect the ISA level in FCSR handling
Define the central place the default FCSR value is set from, initialised in `cpu_probe'. Determine the FCSR mask applied to values written to the register with CTC1 in the full emulation mode and via ptrace(2), according to the ISA level of processor hardware or the writability of bits 31:18 if actual FPU hardware is used. Software may rely on FCSR bits whose functions our emulator does not implement, so it should not allow them to be set or software may get confused. For ptrace(2) it's just sanity. [ralf@linux-mips.org: Fixed double inclusion of <asm/current.h>.] Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/9711/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/include/asm')
-rw-r--r--arch/mips/include/asm/cpu-info.h2
-rw-r--r--arch/mips/include/asm/elf.h7
-rw-r--r--arch/mips/include/asm/fpu.h7
-rw-r--r--arch/mips/include/asm/fpu_emulator.h2
4 files changed, 13 insertions, 5 deletions
diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index c3f4f2d2e108..e7dc785a91ca 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -49,6 +49,8 @@ struct cpuinfo_mips {
49 unsigned int udelay_val; 49 unsigned int udelay_val;
50 unsigned int processor_id; 50 unsigned int processor_id;
51 unsigned int fpu_id; 51 unsigned int fpu_id;
52 unsigned int fpu_csr31;
53 unsigned int fpu_msk31;
52 unsigned int msa_id; 54 unsigned int msa_id;
53 unsigned int cputype; 55 unsigned int cputype;
54 int isa_level; 56 int isa_level;
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index 535f196ffe02..612cf519bd88 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -11,6 +11,9 @@
11#include <linux/fs.h> 11#include <linux/fs.h>
12#include <uapi/linux/elf.h> 12#include <uapi/linux/elf.h>
13 13
14#include <asm/cpu-info.h>
15#include <asm/current.h>
16
14/* ELF header e_flags defines. */ 17/* ELF header e_flags defines. */
15/* MIPS architecture level. */ 18/* MIPS architecture level. */
16#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ 19#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
@@ -297,6 +300,8 @@ do { \
297 mips_set_personality_fp(state); \ 300 mips_set_personality_fp(state); \
298 \ 301 \
299 current->thread.abi = &mips_abi; \ 302 current->thread.abi = &mips_abi; \
303 \
304 current->thread.fpu.fcr31 = current_cpu_data.fpu_csr31; \
300} while (0) 305} while (0)
301 306
302#endif /* CONFIG_32BIT */ 307#endif /* CONFIG_32BIT */
@@ -356,6 +361,8 @@ do { \
356 else \ 361 else \
357 current->thread.abi = &mips_abi; \ 362 current->thread.abi = &mips_abi; \
358 \ 363 \
364 current->thread.fpu.fcr31 = current_cpu_data.fpu_csr31; \
365 \
359 p = personality(current->personality); \ 366 p = personality(current->personality); \
360 if (p != PER_LINUX32 && p != PER_LINUX) \ 367 if (p != PER_LINUX32 && p != PER_LINUX) \
361 set_personality(PER_LINUX); \ 368 set_personality(PER_LINUX); \
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
index dd083e999b08..83d50d563a0f 100644
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -30,7 +30,7 @@
30struct sigcontext; 30struct sigcontext;
31struct sigcontext32; 31struct sigcontext32;
32 32
33extern void _init_fpu(void); 33extern void _init_fpu(unsigned int);
34extern void _save_fp(struct task_struct *); 34extern void _save_fp(struct task_struct *);
35extern void _restore_fp(struct task_struct *); 35extern void _restore_fp(struct task_struct *);
36 36
@@ -182,6 +182,7 @@ static inline void lose_fpu(int save)
182 182
183static inline int init_fpu(void) 183static inline int init_fpu(void)
184{ 184{
185 unsigned int fcr31 = current->thread.fpu.fcr31;
185 int ret = 0; 186 int ret = 0;
186 187
187 if (cpu_has_fpu) { 188 if (cpu_has_fpu) {
@@ -192,7 +193,7 @@ static inline int init_fpu(void)
192 return ret; 193 return ret;
193 194
194 if (!cpu_has_fre) { 195 if (!cpu_has_fre) {
195 _init_fpu(); 196 _init_fpu(fcr31);
196 197
197 return 0; 198 return 0;
198 } 199 }
@@ -206,7 +207,7 @@ static inline int init_fpu(void)
206 config5 = clear_c0_config5(MIPS_CONF5_FRE); 207 config5 = clear_c0_config5(MIPS_CONF5_FRE);
207 enable_fpu_hazard(); 208 enable_fpu_hazard();
208 209
209 _init_fpu(); 210 _init_fpu(fcr31);
210 211
211 /* Restore FRE */ 212 /* Restore FRE */
212 write_c0_config5(config5); 213 write_c0_config5(config5);
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h
index bfcc5c64b7b0..2f021cdfba4f 100644
--- a/arch/mips/include/asm/fpu_emulator.h
+++ b/arch/mips/include/asm/fpu_emulator.h
@@ -88,8 +88,6 @@ static inline void fpu_emulator_init_fpu(void)
88 struct task_struct *t = current; 88 struct task_struct *t = current;
89 int i; 89 int i;
90 90
91 t->thread.fpu.fcr31 = 0;
92
93 for (i = 0; i < 32; i++) 91 for (i = 0; i < 32; i++)
94 set_fpr64(&t->thread.fpu.fpr[i], 0, SIGNALLING_NAN); 92 set_fpr64(&t->thread.fpu.fpr[i], 0, SIGNALLING_NAN);
95} 93}