diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-26 10:45:33 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-26 10:45:33 -0800 |
commit | 89261c57021352045c4af24522c6854c9ee90139 (patch) | |
tree | ad7e2fd28eb7cc6700807b4c6cdc546959563bc8 /arch/mips/kernel/traps.c | |
parent | c2f1f3e0e17d94ab0c66d83e669492cb9e9a3698 (diff) | |
parent | adcc81f148d733b7e8e641300c5590a2cdc13bf3 (diff) |
Merge tag 'mips_4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
Pull MIPS updates from Paul Burton:
"Here's the main MIPS pull for Linux 4.21. Core architecture changes
include:
- Syscall tables & definitions for unistd.h are now generated by
scripts, providing greater consistency with other architectures &
making it easier to add new syscalls.
- Support for building kernels with no floating point support, upon
which any userland attempting to use floating point instructions
will receive a SIGILL. Mostly useful to shrink the kernel & as
preparation for nanoMIPS support which does not yet include FP.
- MIPS SIMD Architecture (MSA) vector register context is now exposed
by ptrace via a new NT_MIPS_MSA regset.
- ASIDs are now stored as 64b values even for MIPS32 kernels,
expanding the ASID version field sufficiently that we don't need to
worry about overflow & avoiding rare issues with reused ASIDs that
have been observed in the wild.
- The branch delay slot "emulation" page is now mapped without write
permission for the user, preventing its use as a nice location for
attacks to execute malicious code from.
- Support for ioremap_prot(), primarily to allow gdb or other ptrace
users the ability to view their tracee's memory using the same
cache coherency attribute.
- Optimizations to more cpu_has_* macros, allowing more to be
compile-time constant where possible.
- Enable building the whole kernel with UBSAN instrumentation.
- Enable building the kernel with link-time dead code & data
elimination.
Platform specific changes include:
- The Boston board gains a workaround for DMA prefetching issues with
the EG20T Platform Controller Hub that it uses.
- Cleanups to Cavium Octeon code removing about 20k lines of
redundant code, mostly unused or duplicate register definitions in
headers.
- defconfig updates for the DECstation machines, including new
defconfigs for r4k & 64b machines.
- Further work on Loongson 3 support.
- DMA fixes for SiByte machines"
* tag 'mips_4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: (95 commits)
MIPS: math-emu: Write-protect delay slot emulation pages
MIPS: Remove struct mm_context_t fp_mode_switching field
mips: generate uapi header and system call table files
mips: add system call table generation support
mips: remove syscall table entries
mips: add +1 to __NR_syscalls in uapi header
mips: rename scall64-64.S to scall64-n64.S
mips: remove unused macros
mips: add __NR_syscalls along with __NR_Linux_syscalls
MIPS: Expand MIPS32 ASIDs to 64 bits
MIPS: OCTEON: delete redundant register definitions
MIPS: OCTEON: cvmx_gmxx_inf_mode: use oldest forward compatible definition
MIPS: OCTEON: cvmx_mio_fus_dat3: use oldest forward compatible definition
MIPS: OCTEON: cvmx_pko_mem_debug8: use oldest forward compatible definition
MIPS: OCTEON: octeon-usb: use common gpio_bit definition
MIPS: OCTEON: enable all OCTEON drivers in defconfig
mips: annotate implicit fall throughs
MIPS: Hardcode cpu_has_mips* where target ISA allows
MIPS: MT: Remove norps command line parameter
MIPS: Only include mmzone.h when CONFIG_NEED_MULTIPLE_NODES=y
...
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r-- | arch/mips/kernel/traps.c | 124 |
1 files changed, 77 insertions, 47 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 15e103c6d799..c91097f7b32f 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -50,6 +50,7 @@ #include <asm/fpu.h> #include <asm/fpu_emulator.h> #include <asm/idle.h> +#include <asm/isa-rev.h> #include <asm/mips-cps.h> #include <asm/mips-r2-to-r6-emul.h> #include <asm/mipsregs.h> @@ -277,8 +278,10 @@ static void __show_regs(const struct pt_regs *regs) #ifdef CONFIG_CPU_HAS_SMARTMIPS printk("Acx : %0*lx\n", field, regs->acx); #endif - printk("Hi : %0*lx\n", field, regs->hi); - printk("Lo : %0*lx\n", field, regs->lo); + if (MIPS_ISA_REV < 6) { + printk("Hi : %0*lx\n", field, regs->hi); + printk("Lo : %0*lx\n", field, regs->lo); + } /* * Saved cp0 registers @@ -706,6 +709,8 @@ asmlinkage void do_ov(struct pt_regs *regs) exception_exit(prev_state); } +#ifdef CONFIG_MIPS_FP_SUPPORT + /* * Send SIGFPE according to FCSR Cause bits, which must have already * been masked against Enable bits. This is impotant as Inexact can @@ -794,9 +799,6 @@ static int simulate_fp(struct pt_regs *regs, unsigned int opcode, regs->cp0_epc = old_epc; regs->regs[31] = old_ra; - /* Save the FP context to struct thread_struct */ - lose_fpu(1); - /* Run the emulator */ sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, &fault_addr); @@ -848,8 +850,6 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) * register operands before invoking the emulator, which seems * a bit extreme for what should be an infrequent event. */ - /* Ensure 'resume' not overwrite saved fp context again. */ - lose_fpu(1); /* Run the emulator */ sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, @@ -876,6 +876,45 @@ out: exception_exit(prev_state); } +/* + * MIPS MT processors may have fewer FPU contexts than CPU threads. If we've + * emulated more than some threshold number of instructions, force migration to + * a "CPU" that has FP support. + */ +static void mt_ase_fp_affinity(void) +{ +#ifdef CONFIG_MIPS_MT_FPAFF + if (mt_fpemul_threshold > 0 && + ((current->thread.emulated_fp++ > mt_fpemul_threshold))) { + /* + * If there's no FPU present, or if the application has already + * restricted the allowed set to exclude any CPUs with FPUs, + * we'll skip the procedure. + */ + if (cpumask_intersects(¤t->cpus_allowed, &mt_fpu_cpumask)) { + cpumask_t tmask; + + current->thread.user_cpus_allowed + = current->cpus_allowed; + cpumask_and(&tmask, ¤t->cpus_allowed, + &mt_fpu_cpumask); + set_cpus_allowed_ptr(current, &tmask); + set_thread_flag(TIF_FPUBOUND); + } + } +#endif /* CONFIG_MIPS_MT_FPAFF */ +} + +#else /* !CONFIG_MIPS_FP_SUPPORT */ + +static int simulate_fp(struct pt_regs *regs, unsigned int opcode, + unsigned long old_epc, unsigned long old_ra) +{ + return -1; +} + +#endif /* !CONFIG_MIPS_FP_SUPPORT */ + void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code, const char *str) { @@ -1160,35 +1199,6 @@ out: } /* - * MIPS MT processors may have fewer FPU contexts than CPU threads. If we've - * emulated more than some threshold number of instructions, force migration to - * a "CPU" that has FP support. - */ -static void mt_ase_fp_affinity(void) -{ -#ifdef CONFIG_MIPS_MT_FPAFF - if (mt_fpemul_threshold > 0 && - ((current->thread.emulated_fp++ > mt_fpemul_threshold))) { - /* - * If there's no FPU present, or if the application has already - * restricted the allowed set to exclude any CPUs with FPUs, - * we'll skip the procedure. - */ - if (cpumask_intersects(¤t->cpus_allowed, &mt_fpu_cpumask)) { - cpumask_t tmask; - - current->thread.user_cpus_allowed - = current->cpus_allowed; - cpumask_and(&tmask, ¤t->cpus_allowed, - &mt_fpu_cpumask); - set_cpus_allowed_ptr(current, &tmask); - set_thread_flag(TIF_FPUBOUND); - } - } -#endif /* CONFIG_MIPS_MT_FPAFF */ -} - -/* * No lock; only written during early bootup by CPU 0. */ static RAW_NOTIFIER_HEAD(cu2_chain); @@ -1215,23 +1225,25 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action, return NOTIFY_OK; } +#ifdef CONFIG_MIPS_FP_SUPPORT + static int enable_restore_fp_context(int msa) { int err, was_fpu_owner, prior_msa; + bool first_fp; + + /* Initialize context if it hasn't been used already */ + first_fp = init_fp_ctx(current); - if (!used_math()) { - /* First time FP context user. */ + if (first_fp) { preempt_disable(); - err = init_fpu(); + err = own_fpu_inatomic(1); if (msa && !err) { enable_msa(); - init_msa_upper(); set_thread_flag(TIF_USEDMSA); set_thread_flag(TIF_MSA_CTX_LIVE); } preempt_enable(); - if (!err) - set_used_math(); return err; } @@ -1322,17 +1334,23 @@ out: return 0; } +#else /* !CONFIG_MIPS_FP_SUPPORT */ + +static int enable_restore_fp_context(int msa) +{ + return SIGILL; +} + +#endif /* CONFIG_MIPS_FP_SUPPORT */ + asmlinkage void do_cpu(struct pt_regs *regs) { enum ctx_state prev_state; unsigned int __user *epc; unsigned long old_epc, old31; - void __user *fault_addr; unsigned int opcode; - unsigned long fcr31; unsigned int cpid; - int status, err; - int sig; + int status; prev_state = exception_enter(); cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; @@ -1370,6 +1388,7 @@ asmlinkage void do_cpu(struct pt_regs *regs) break; +#ifdef CONFIG_MIPS_FP_SUPPORT case 3: /* * The COP3 opcode space and consequently the CP0.Status.CU3 @@ -1389,7 +1408,11 @@ asmlinkage void do_cpu(struct pt_regs *regs) } /* Fall through. */ - case 1: + case 1: { + void __user *fault_addr; + unsigned long fcr31; + int err, sig; + err = enable_restore_fp_context(0); if (raw_cpu_has_fpu && !err) @@ -1410,6 +1433,13 @@ asmlinkage void do_cpu(struct pt_regs *regs) mt_ase_fp_affinity(); break; + } +#else /* CONFIG_MIPS_FP_SUPPORT */ + case 1: + case 3: + force_sig(SIGILL, current); + break; +#endif /* CONFIG_MIPS_FP_SUPPORT */ case 2: raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs); |