aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-08-06 09:13:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-08-06 09:13:11 -0400
commit4305f42401b29e2e024bd064618faf25aef5cb69 (patch)
tree1bc924cfa60c9efbb21e07c1d834f495301cffc8 /arch/mips/kernel
parentdb8262787e82b5c0fa57bd9d676add187519a751 (diff)
parent4a89cf810130fde41e3fc729e770cb1a5a87d245 (diff)
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle: "This is the main pull request for MIPS for 4.8. Also includes is a minor SSB cleanup as SSB code traditionally is merged through the MIPS tree: ATH25: - MIPS: Add default configuration for ath25 Boot: - For zboot, copy appended dtb to the end of the kernel - store the appended dtb address in a variable BPF: - Fix off by one error in offset allocation Cobalt code: - Fix typos Core code: - debugfs_create_file returns NULL on error, so don't use IS_ERR for testing for errors. - Fix double locking issue in RM7000 S-cache code. This would only affect RM7000 ARC systems on reboot. - Fix page table corruption on THP permission changes. - Use compat_sys_keyctl for 32 bit userspace on 64 bit kernels. David says, there are no compatibility issues raised by this fix. - Move some signal code around. - Rewrite r4k count/compare clockevent device registration such that min_delta_ticks/max_delta_ticks files are guaranteed to be initialized. - Only register r4k count/compare as clockevent device if we can assume the clock to be constant. - Fix MSA asm warnings in control reg accessors - uasm and tlbex fixes and tweaking. - Print segment physical address when EU=1. - Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO. - CP: Allow booting by VP other than VP 0 - Cache handling fixes and optimizations for r4k class caches - Add hotplug support for R6 processors - Cleanup hotplug bits in kconfig - traps: return correct si code for accessing nonmapped addresses - Remove cpu_has_safe_index_cacheops Lantiq: - Register IRQ handler for virtual IRQ number - Fix EIU interrupt loading code - Use the real EXIN count - Fix build error. Loongson 3: - Increase HPET_MIN_PROG_DELTA and decrease HPET_MIN_CYCLES Octeon: - Delete built-in DTB pruning code for D-Link DSR-1000N. - Clean up GPIO definitions in dlink_dsr-1000n.dts. - Add more LEDs to the DSR-100n DTS - Fix off by one in octeon_irq_gpio_map() - Typo fixes - Enable SATA by default in cavium_octeon_defconfig - Support readq/writeq() - Remove forced mappings of USB interrupts. - Ensure DMA descriptors are always in the low 4GB - Improve USB reset code for OCTEON II. Pistachio: - Add maintainers entry for pistachio SoC Support - Remove plat_setup_iocoherency Ralink: - Fix pwm UART in spis group pinmux. SSB: - Change bare unsigned to unsigned int to suit coding style Tools: - Fix reloc tool compiler warnings. Other: - Delete use of ARCH_WANT_OPTIONAL_GPIOLIB" * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (61 commits) MIPS: mm: Fix definition of R6 cache instruction MIPS: tools: Fix relocs tool compiler warnings MIPS: Cobalt: Fix typo MIPS: Octeon: Fix typo MIPS: Lantiq: Fix build failure MIPS: Use CPHYSADDR to implement mips32 __pa MIPS: Octeon: Dlink_dsr-1000n.dts: add more leds. MIPS: Octeon: Clean up GPIO definitions in dlink_dsr-1000n.dts. MIPS: Octeon: Delete built-in DTB pruning code for D-Link DSR-1000N. MIPS: store the appended dtb address in a variable MIPS: ZBOOT: copy appended dtb to the end of the kernel MIPS: ralink: fix spis group pinmux MIPS: Factor o32 specific code into signal_o32.c MIPS: non-exec stack & heap when non-exec PT_GNU_STACK is present MIPS: Use per-mm page to execute branch delay slot instructions MIPS: Modify error handling MIPS: c-r4k: Use SMP calls for CM indexed cache ops MIPS: c-r4k: Avoid small flush_icache_range SMP calls MIPS: c-r4k: Local flush_icache_range cache op override MIPS: c-r4k: Split r4k_flush_kernel_vmap_range() ...
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/Makefile2
-rw-r--r--arch/mips/kernel/cevt-r4k.c7
-rw-r--r--arch/mips/kernel/csrc-r4k.c4
-rw-r--r--arch/mips/kernel/elf.c19
-rw-r--r--arch/mips/kernel/head.S21
-rw-r--r--arch/mips/kernel/mips-r2-to-r6-emul.c8
-rw-r--r--arch/mips/kernel/process.c14
-rw-r--r--arch/mips/kernel/scall64-n32.S2
-rw-r--r--arch/mips/kernel/scall64-o32.S2
-rw-r--r--arch/mips/kernel/segment.c13
-rw-r--r--arch/mips/kernel/setup.c4
-rw-r--r--arch/mips/kernel/signal.c8
-rw-r--r--arch/mips/kernel/signal32.c288
-rw-r--r--arch/mips/kernel/signal_o32.c285
-rw-r--r--arch/mips/kernel/smp-bmips.c1
-rw-r--r--arch/mips/kernel/smp-cps.c42
-rw-r--r--arch/mips/kernel/smp.c34
-rw-r--r--arch/mips/kernel/traps.c4
-rw-r--r--arch/mips/kernel/vdso.c10
19 files changed, 437 insertions, 331 deletions
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index e6053d07072f..4a603a3ea657 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -71,7 +71,7 @@ obj-$(CONFIG_32BIT) += scall32-o32.o
71obj-$(CONFIG_64BIT) += scall64-64.o 71obj-$(CONFIG_64BIT) += scall64-64.o
72obj-$(CONFIG_MIPS32_COMPAT) += linux32.o ptrace32.o signal32.o 72obj-$(CONFIG_MIPS32_COMPAT) += linux32.o ptrace32.o signal32.o
73obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o 73obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o
74obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o 74obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o signal_o32.o
75 75
76obj-$(CONFIG_KGDB) += kgdb.o 76obj-$(CONFIG_KGDB) += kgdb.o
77obj-$(CONFIG_PROC_FS) += proc.o 77obj-$(CONFIG_PROC_FS) += proc.o
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index e4c21bbf9422..804d2a2a19fe 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -276,12 +276,7 @@ int r4k_clockevent_init(void)
276 CLOCK_EVT_FEAT_C3STOP | 276 CLOCK_EVT_FEAT_C3STOP |
277 CLOCK_EVT_FEAT_PERCPU; 277 CLOCK_EVT_FEAT_PERCPU;
278 278
279 clockevent_set_clock(cd, mips_hpt_frequency);
280
281 /* Calculate the min / max delta */
282 cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
283 min_delta = calculate_min_delta(); 279 min_delta = calculate_min_delta();
284 cd->min_delta_ns = clockevent_delta2ns(min_delta, cd);
285 280
286 cd->rating = 300; 281 cd->rating = 300;
287 cd->irq = irq; 282 cd->irq = irq;
@@ -289,7 +284,7 @@ int r4k_clockevent_init(void)
289 cd->set_next_event = mips_next_event; 284 cd->set_next_event = mips_next_event;
290 cd->event_handler = mips_event_handler; 285 cd->event_handler = mips_event_handler;
291 286
292 clockevents_register_device(cd); 287 clockevents_config_and_register(cd, mips_hpt_frequency, min_delta, 0x7fffffff);
293 288
294 if (cp0_timer_irq_installed) 289 if (cp0_timer_irq_installed)
295 return 0; 290 return 0;
diff --git a/arch/mips/kernel/csrc-r4k.c b/arch/mips/kernel/csrc-r4k.c
index 1f910563fdf6..d76275da54cb 100644
--- a/arch/mips/kernel/csrc-r4k.c
+++ b/arch/mips/kernel/csrc-r4k.c
@@ -23,7 +23,7 @@ static struct clocksource clocksource_mips = {
23 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 23 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
24}; 24};
25 25
26static u64 notrace r4k_read_sched_clock(void) 26static u64 __maybe_unused notrace r4k_read_sched_clock(void)
27{ 27{
28 return read_c0_count(); 28 return read_c0_count();
29} 29}
@@ -82,7 +82,9 @@ int __init init_r4k_clocksource(void)
82 82
83 clocksource_register_hz(&clocksource_mips, mips_hpt_frequency); 83 clocksource_register_hz(&clocksource_mips, mips_hpt_frequency);
84 84
85#ifndef CONFIG_CPU_FREQ
85 sched_clock_register(r4k_read_sched_clock, 32, mips_hpt_frequency); 86 sched_clock_register(r4k_read_sched_clock, 32, mips_hpt_frequency);
87#endif
86 88
87 return 0; 89 return 0;
88} 90}
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c
index e6eb7f1f7723..6430bff21fff 100644
--- a/arch/mips/kernel/elf.c
+++ b/arch/mips/kernel/elf.c
@@ -8,9 +8,12 @@
8 * option) any later version. 8 * option) any later version.
9 */ 9 */
10 10
11#include <linux/binfmts.h>
11#include <linux/elf.h> 12#include <linux/elf.h>
13#include <linux/export.h>
12#include <linux/sched.h> 14#include <linux/sched.h>
13 15
16#include <asm/cpu-features.h>
14#include <asm/cpu-info.h> 17#include <asm/cpu-info.h>
15 18
16/* Whether to accept legacy-NaN and 2008-NaN user binaries. */ 19/* Whether to accept legacy-NaN and 2008-NaN user binaries. */
@@ -326,3 +329,19 @@ void mips_set_personality_nan(struct arch_elf_state *state)
326 BUG(); 329 BUG();
327 } 330 }
328} 331}
332
333int mips_elf_read_implies_exec(void *elf_ex, int exstack)
334{
335 if (exstack != EXSTACK_DISABLE_X) {
336 /* The binary doesn't request a non-executable stack */
337 return 1;
338 }
339
340 if (!cpu_has_rixi) {
341 /* The CPU doesn't support non-executable memory */
342 return 1;
343 }
344
345 return 0;
346}
347EXPORT_SYMBOL(mips_elf_read_implies_exec);
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 56e8fede3fd8..cf052204eb0a 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -93,21 +93,24 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
93 jr t0 93 jr t0
940: 940:
95 95
96#ifdef CONFIG_USE_OF
96#ifdef CONFIG_MIPS_RAW_APPENDED_DTB 97#ifdef CONFIG_MIPS_RAW_APPENDED_DTB
97 PTR_LA t0, __appended_dtb 98 PTR_LA t2, __appended_dtb
98 99
99#ifdef CONFIG_CPU_BIG_ENDIAN 100#ifdef CONFIG_CPU_BIG_ENDIAN
100 li t1, 0xd00dfeed 101 li t1, 0xd00dfeed
101#else 102#else
102 li t1, 0xedfe0dd0 103 li t1, 0xedfe0dd0
103#endif 104#endif
104 lw t2, (t0) 105 lw t0, (t2)
105 bne t1, t2, not_found 106 beq t0, t1, dtb_found
106 nop 107#endif
108 li t1, -2
109 beq a0, t1, dtb_found
110 move t2, a1
107 111
108 move a1, t0 112 li t2, 0
109 PTR_LI a0, -2 113dtb_found:
110not_found:
111#endif 114#endif
112 PTR_LA t0, __bss_start # clear .bss 115 PTR_LA t0, __bss_start # clear .bss
113 LONG_S zero, (t0) 116 LONG_S zero, (t0)
@@ -122,6 +125,10 @@ not_found:
122 LONG_S a2, fw_arg2 125 LONG_S a2, fw_arg2
123 LONG_S a3, fw_arg3 126 LONG_S a3, fw_arg3
124 127
128#ifdef CONFIG_USE_OF
129 LONG_S t2, fw_passed_dtb
130#endif
131
125 MTC0 zero, CP0_CONTEXT # clear context register 132 MTC0 zero, CP0_CONTEXT # clear context register
126 PTR_LA $28, init_thread_union 133 PTR_LA $28, init_thread_union
127 /* Set the SP after an empty pt_regs. */ 134 /* Set the SP after an empty pt_regs. */
diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c
index 43fbadc78d0a..c3372cac6db2 100644
--- a/arch/mips/kernel/mips-r2-to-r6-emul.c
+++ b/arch/mips/kernel/mips-r2-to-r6-emul.c
@@ -283,7 +283,7 @@ static int jr_func(struct pt_regs *regs, u32 ir)
283 err = mipsr6_emul(regs, nir); 283 err = mipsr6_emul(regs, nir);
284 if (err > 0) { 284 if (err > 0) {
285 regs->cp0_epc = nepc; 285 regs->cp0_epc = nepc;
286 err = mips_dsemul(regs, nir, cepc); 286 err = mips_dsemul(regs, nir, epc, cepc);
287 if (err == SIGILL) 287 if (err == SIGILL)
288 err = SIGEMT; 288 err = SIGEMT;
289 MIPS_R2_STATS(dsemul); 289 MIPS_R2_STATS(dsemul);
@@ -1033,7 +1033,7 @@ repeat:
1033 if (nir) { 1033 if (nir) {
1034 err = mipsr6_emul(regs, nir); 1034 err = mipsr6_emul(regs, nir);
1035 if (err > 0) { 1035 if (err > 0) {
1036 err = mips_dsemul(regs, nir, cpc); 1036 err = mips_dsemul(regs, nir, epc, cpc);
1037 if (err == SIGILL) 1037 if (err == SIGILL)
1038 err = SIGEMT; 1038 err = SIGEMT;
1039 MIPS_R2_STATS(dsemul); 1039 MIPS_R2_STATS(dsemul);
@@ -1082,7 +1082,7 @@ repeat:
1082 if (nir) { 1082 if (nir) {
1083 err = mipsr6_emul(regs, nir); 1083 err = mipsr6_emul(regs, nir);
1084 if (err > 0) { 1084 if (err > 0) {
1085 err = mips_dsemul(regs, nir, cpc); 1085 err = mips_dsemul(regs, nir, epc, cpc);
1086 if (err == SIGILL) 1086 if (err == SIGILL)
1087 err = SIGEMT; 1087 err = SIGEMT;
1088 MIPS_R2_STATS(dsemul); 1088 MIPS_R2_STATS(dsemul);
@@ -1149,7 +1149,7 @@ repeat:
1149 if (nir) { 1149 if (nir) {
1150 err = mipsr6_emul(regs, nir); 1150 err = mipsr6_emul(regs, nir);
1151 if (err > 0) { 1151 if (err > 0) {
1152 err = mips_dsemul(regs, nir, cpc); 1152 err = mips_dsemul(regs, nir, epc, cpc);
1153 if (err == SIGILL) 1153 if (err == SIGILL)
1154 err = SIGEMT; 1154 err = SIGEMT;
1155 MIPS_R2_STATS(dsemul); 1155 MIPS_R2_STATS(dsemul);
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 813ed7829c61..7429ad09fbe3 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -30,6 +30,7 @@
30#include <asm/asm.h> 30#include <asm/asm.h>
31#include <asm/bootinfo.h> 31#include <asm/bootinfo.h>
32#include <asm/cpu.h> 32#include <asm/cpu.h>
33#include <asm/dsemul.h>
33#include <asm/dsp.h> 34#include <asm/dsp.h>
34#include <asm/fpu.h> 35#include <asm/fpu.h>
35#include <asm/msa.h> 36#include <asm/msa.h>
@@ -68,11 +69,22 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
68 lose_fpu(0); 69 lose_fpu(0);
69 clear_thread_flag(TIF_MSA_CTX_LIVE); 70 clear_thread_flag(TIF_MSA_CTX_LIVE);
70 clear_used_math(); 71 clear_used_math();
72 atomic_set(&current->thread.bd_emu_frame, BD_EMUFRAME_NONE);
71 init_dsp(); 73 init_dsp();
72 regs->cp0_epc = pc; 74 regs->cp0_epc = pc;
73 regs->regs[29] = sp; 75 regs->regs[29] = sp;
74} 76}
75 77
78void exit_thread(struct task_struct *tsk)
79{
80 /*
81 * User threads may have allocated a delay slot emulation frame.
82 * If so, clean up that allocation.
83 */
84 if (!(current->flags & PF_KTHREAD))
85 dsemul_thread_cleanup(tsk);
86}
87
76int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) 88int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
77{ 89{
78 /* 90 /*
@@ -159,6 +171,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
159 clear_tsk_thread_flag(p, TIF_FPUBOUND); 171 clear_tsk_thread_flag(p, TIF_FPUBOUND);
160#endif /* CONFIG_MIPS_MT_FPAFF */ 172#endif /* CONFIG_MIPS_MT_FPAFF */
161 173
174 atomic_set(&p->thread.bd_emu_frame, BD_EMUFRAME_NONE);
175
162 if (clone_flags & CLONE_SETTLS) 176 if (clone_flags & CLONE_SETTLS)
163 ti->tp_value = regs->regs[7]; 177 ti->tp_value = regs->regs[7];
164 178
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 9c0b387d6427..51d3988933f8 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -348,7 +348,7 @@ EXPORT(sysn32_call_table)
348 PTR sys_ni_syscall /* available, was setaltroot */ 348 PTR sys_ni_syscall /* available, was setaltroot */
349 PTR sys_add_key 349 PTR sys_add_key
350 PTR sys_request_key 350 PTR sys_request_key
351 PTR sys_keyctl /* 6245 */ 351 PTR compat_sys_keyctl /* 6245 */
352 PTR sys_set_thread_area 352 PTR sys_set_thread_area
353 PTR sys_inotify_init 353 PTR sys_inotify_init
354 PTR sys_inotify_add_watch 354 PTR sys_inotify_add_watch
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index f4f28b1580de..6efa7136748f 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -504,7 +504,7 @@ EXPORT(sys32_call_table)
504 PTR sys_ni_syscall /* available, was setaltroot */ 504 PTR sys_ni_syscall /* available, was setaltroot */
505 PTR sys_add_key /* 4280 */ 505 PTR sys_add_key /* 4280 */
506 PTR sys_request_key 506 PTR sys_request_key
507 PTR sys_keyctl 507 PTR compat_sys_keyctl
508 PTR sys_set_thread_area 508 PTR sys_set_thread_area
509 PTR sys_inotify_init 509 PTR sys_inotify_init
510 PTR sys_inotify_add_watch /* 4285 */ 510 PTR sys_inotify_add_watch /* 4285 */
diff --git a/arch/mips/kernel/segment.c b/arch/mips/kernel/segment.c
index 87bc74a5a518..2703f218202e 100644
--- a/arch/mips/kernel/segment.c
+++ b/arch/mips/kernel/segment.c
@@ -26,17 +26,20 @@ static void build_segment_config(char *str, unsigned int cfg)
26 26
27 /* 27 /*
28 * Access modes MK, MSK and MUSK are mapped segments. Therefore 28 * Access modes MK, MSK and MUSK are mapped segments. Therefore
29 * there is no direct physical address mapping. 29 * there is no direct physical address mapping unless it becomes
30 * unmapped uncached at error level due to EU.
30 */ 31 */
31 if ((am == 0) || (am > 3)) { 32 if ((am == 0) || (am > 3) || (cfg & MIPS_SEGCFG_EU))
32 str += sprintf(str, " %03lx", 33 str += sprintf(str, " %03lx",
33 ((cfg & MIPS_SEGCFG_PA) >> MIPS_SEGCFG_PA_SHIFT)); 34 ((cfg & MIPS_SEGCFG_PA) >> MIPS_SEGCFG_PA_SHIFT));
35 else
36 str += sprintf(str, " UND");
37
38 if ((am == 0) || (am > 3))
34 str += sprintf(str, " %01ld", 39 str += sprintf(str, " %01ld",
35 ((cfg & MIPS_SEGCFG_C) >> MIPS_SEGCFG_C_SHIFT)); 40 ((cfg & MIPS_SEGCFG_C) >> MIPS_SEGCFG_C_SHIFT));
36 } else { 41 else
37 str += sprintf(str, " UND");
38 str += sprintf(str, " U"); 42 str += sprintf(str, " U");
39 }
40 43
41 /* Exception configuration. */ 44 /* Exception configuration. */
42 str += sprintf(str, " %01ld\n", 45 str += sprintf(str, " %01ld\n",
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index ef408a03e818..36cf8d65c47d 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -875,6 +875,10 @@ void __init setup_arch(char **cmdline_p)
875unsigned long kernelsp[NR_CPUS]; 875unsigned long kernelsp[NR_CPUS];
876unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3; 876unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3;
877 877
878#ifdef CONFIG_USE_OF
879unsigned long fw_passed_dtb;
880#endif
881
878#ifdef CONFIG_DEBUG_FS 882#ifdef CONFIG_DEBUG_FS
879struct dentry *mips_debugfs_dir; 883struct dentry *mips_debugfs_dir;
880static int __init debugfs_mips(void) 884static int __init debugfs_mips(void)
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 1975cd2f7de6..9e224469c788 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -772,6 +772,14 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
772 struct mips_abi *abi = current->thread.abi; 772 struct mips_abi *abi = current->thread.abi;
773 void *vdso = current->mm->context.vdso; 773 void *vdso = current->mm->context.vdso;
774 774
775 /*
776 * If we were emulating a delay slot instruction, exit that frame such
777 * that addresses in the sigframe are as expected for userland and we
778 * don't have a problem if we reuse the thread's frame for an
779 * instruction within the signal handler.
780 */
781 dsemul_thread_rollback(regs);
782
775 if (regs->regs[0]) { 783 if (regs->regs[0]) {
776 switch(regs->regs[2]) { 784 switch(regs->regs[2]) {
777 case ERESTART_RESTARTBLOCK: 785 case ERESTART_RESTARTBLOCK:
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 78c8349d151c..97b7c51b8251 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -6,129 +6,26 @@
6 * Copyright (C) 1991, 1992 Linus Torvalds 6 * Copyright (C) 1991, 1992 Linus Torvalds
7 * Copyright (C) 1994 - 2000, 2006 Ralf Baechle 7 * Copyright (C) 1994 - 2000, 2006 Ralf Baechle
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 * Copyright (C) 2016, Imagination Technologies Ltd.
9 */ 10 */
10#include <linux/cache.h> 11#include <linux/compiler.h>
11#include <linux/compat.h> 12#include <linux/errno.h>
12#include <linux/sched.h>
13#include <linux/mm.h>
14#include <linux/smp.h>
15#include <linux/kernel.h> 13#include <linux/kernel.h>
16#include <linux/signal.h> 14#include <linux/signal.h>
17#include <linux/syscalls.h> 15#include <linux/syscalls.h>
18#include <linux/errno.h>
19#include <linux/wait.h>
20#include <linux/ptrace.h>
21#include <linux/suspend.h>
22#include <linux/compiler.h>
23#include <linux/uaccess.h>
24 16
25#include <asm/abi.h> 17#include <asm/compat.h>
26#include <asm/asm.h>
27#include <asm/compat-signal.h> 18#include <asm/compat-signal.h>
28#include <linux/bitops.h> 19#include <asm/uaccess.h>
29#include <asm/cacheflush.h> 20#include <asm/unistd.h>
30#include <asm/sim.h>
31#include <asm/ucontext.h>
32#include <asm/fpu.h>
33#include <asm/war.h>
34#include <asm/dsp.h>
35 21
36#include "signal-common.h" 22#include "signal-common.h"
37 23
38/*
39 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
40 */
41#define __NR_O32_restart_syscall 4253
42
43/* 32-bit compatibility types */ 24/* 32-bit compatibility types */
44 25
45typedef unsigned int __sighandler32_t; 26typedef unsigned int __sighandler32_t;
46typedef void (*vfptr_t)(void); 27typedef void (*vfptr_t)(void);
47 28
48struct ucontext32 {
49 u32 uc_flags;
50 s32 uc_link;
51 compat_stack_t uc_stack;
52 struct sigcontext32 uc_mcontext;
53 compat_sigset_t uc_sigmask; /* mask last for extensibility */
54};
55
56struct sigframe32 {
57 u32 sf_ass[4]; /* argument save space for o32 */
58 u32 sf_pad[2]; /* Was: signal trampoline */
59 struct sigcontext32 sf_sc;
60 compat_sigset_t sf_mask;
61};
62
63struct rt_sigframe32 {
64 u32 rs_ass[4]; /* argument save space for o32 */
65 u32 rs_pad[2]; /* Was: signal trampoline */
66 compat_siginfo_t rs_info;
67 struct ucontext32 rs_uc;
68};
69
70static int setup_sigcontext32(struct pt_regs *regs,
71 struct sigcontext32 __user *sc)
72{
73 int err = 0;
74 int i;
75
76 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
77
78 err |= __put_user(0, &sc->sc_regs[0]);
79 for (i = 1; i < 32; i++)
80 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
81
82 err |= __put_user(regs->hi, &sc->sc_mdhi);
83 err |= __put_user(regs->lo, &sc->sc_mdlo);
84 if (cpu_has_dsp) {
85 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
86 err |= __put_user(mfhi1(), &sc->sc_hi1);
87 err |= __put_user(mflo1(), &sc->sc_lo1);
88 err |= __put_user(mfhi2(), &sc->sc_hi2);
89 err |= __put_user(mflo2(), &sc->sc_lo2);
90 err |= __put_user(mfhi3(), &sc->sc_hi3);
91 err |= __put_user(mflo3(), &sc->sc_lo3);
92 }
93
94 /*
95 * Save FPU state to signal context. Signal handler
96 * will "inherit" current FPU state.
97 */
98 err |= protected_save_fp_context(sc);
99
100 return err;
101}
102
103static int restore_sigcontext32(struct pt_regs *regs,
104 struct sigcontext32 __user *sc)
105{
106 int err = 0;
107 s32 treg;
108 int i;
109
110 /* Always make any pending restarted system calls return -EINTR */
111 current->restart_block.fn = do_no_restart_syscall;
112
113 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
114 err |= __get_user(regs->hi, &sc->sc_mdhi);
115 err |= __get_user(regs->lo, &sc->sc_mdlo);
116 if (cpu_has_dsp) {
117 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
118 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
119 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
120 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
121 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
122 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
123 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
124 }
125
126 for (i = 1; i < 32; i++)
127 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
128
129 return err ?: protected_restore_fp_context(sc);
130}
131
132/* 29/*
133 * Atomically swap in the new signal mask, and wait for a signal. 30 * Atomically swap in the new signal mask, and wait for a signal.
134 */ 31 */
@@ -247,176 +144,3 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
247 144
248 return 0; 145 return 0;
249} 146}
250
251asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
252{
253 struct sigframe32 __user *frame;
254 sigset_t blocked;
255 int sig;
256
257 frame = (struct sigframe32 __user *) regs.regs[29];
258 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
259 goto badframe;
260 if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
261 goto badframe;
262
263 set_current_blocked(&blocked);
264
265 sig = restore_sigcontext32(&regs, &frame->sf_sc);
266 if (sig < 0)
267 goto badframe;
268 else if (sig)
269 force_sig(sig, current);
270
271 /*
272 * Don't let your children do this ...
273 */
274 __asm__ __volatile__(
275 "move\t$29, %0\n\t"
276 "j\tsyscall_exit"
277 :/* no outputs */
278 :"r" (&regs));
279 /* Unreached */
280
281badframe:
282 force_sig(SIGSEGV, current);
283}
284
285asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
286{
287 struct rt_sigframe32 __user *frame;
288 sigset_t set;
289 int sig;
290
291 frame = (struct rt_sigframe32 __user *) regs.regs[29];
292 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
293 goto badframe;
294 if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
295 goto badframe;
296
297 set_current_blocked(&set);
298
299 sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
300 if (sig < 0)
301 goto badframe;
302 else if (sig)
303 force_sig(sig, current);
304
305 if (compat_restore_altstack(&frame->rs_uc.uc_stack))
306 goto badframe;
307
308 /*
309 * Don't let your children do this ...
310 */
311 __asm__ __volatile__(
312 "move\t$29, %0\n\t"
313 "j\tsyscall_exit"
314 :/* no outputs */
315 :"r" (&regs));
316 /* Unreached */
317
318badframe:
319 force_sig(SIGSEGV, current);
320}
321
322static int setup_frame_32(void *sig_return, struct ksignal *ksig,
323 struct pt_regs *regs, sigset_t *set)
324{
325 struct sigframe32 __user *frame;
326 int err = 0;
327
328 frame = get_sigframe(ksig, regs, sizeof(*frame));
329 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
330 return -EFAULT;
331
332 err |= setup_sigcontext32(regs, &frame->sf_sc);
333 err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
334
335 if (err)
336 return -EFAULT;
337
338 /*
339 * Arguments to signal handler:
340 *
341 * a0 = signal number
342 * a1 = 0 (should be cause)
343 * a2 = pointer to struct sigcontext
344 *
345 * $25 and c0_epc point to the signal handler, $29 points to the
346 * struct sigframe.
347 */
348 regs->regs[ 4] = ksig->sig;
349 regs->regs[ 5] = 0;
350 regs->regs[ 6] = (unsigned long) &frame->sf_sc;
351 regs->regs[29] = (unsigned long) frame;
352 regs->regs[31] = (unsigned long) sig_return;
353 regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
354
355 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
356 current->comm, current->pid,
357 frame, regs->cp0_epc, regs->regs[31]);
358
359 return 0;
360}
361
362static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig,
363 struct pt_regs *regs, sigset_t *set)
364{
365 struct rt_sigframe32 __user *frame;
366 int err = 0;
367
368 frame = get_sigframe(ksig, regs, sizeof(*frame));
369 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
370 return -EFAULT;
371
372 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
373 err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
374
375 /* Create the ucontext. */
376 err |= __put_user(0, &frame->rs_uc.uc_flags);
377 err |= __put_user(0, &frame->rs_uc.uc_link);
378 err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
379 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
380 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
381
382 if (err)
383 return -EFAULT;
384
385 /*
386 * Arguments to signal handler:
387 *
388 * a0 = signal number
389 * a1 = 0 (should be cause)
390 * a2 = pointer to ucontext
391 *
392 * $25 and c0_epc point to the signal handler, $29 points to
393 * the struct rt_sigframe32.
394 */
395 regs->regs[ 4] = ksig->sig;
396 regs->regs[ 5] = (unsigned long) &frame->rs_info;
397 regs->regs[ 6] = (unsigned long) &frame->rs_uc;
398 regs->regs[29] = (unsigned long) frame;
399 regs->regs[31] = (unsigned long) sig_return;
400 regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
401
402 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
403 current->comm, current->pid,
404 frame, regs->cp0_epc, regs->regs[31]);
405
406 return 0;
407}
408
409/*
410 * o32 compatibility on 64-bit kernels, without DSP ASE
411 */
412struct mips_abi mips_abi_32 = {
413 .setup_frame = setup_frame_32,
414 .setup_rt_frame = setup_rt_frame_32,
415 .restart = __NR_O32_restart_syscall,
416
417 .off_sc_fpregs = offsetof(struct sigcontext32, sc_fpregs),
418 .off_sc_fpc_csr = offsetof(struct sigcontext32, sc_fpc_csr),
419 .off_sc_used_math = offsetof(struct sigcontext32, sc_used_math),
420
421 .vdso = &vdso_image_o32,
422};
diff --git a/arch/mips/kernel/signal_o32.c b/arch/mips/kernel/signal_o32.c
new file mode 100644
index 000000000000..5e169fc5ca5c
--- /dev/null
+++ b/arch/mips/kernel/signal_o32.c
@@ -0,0 +1,285 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1991, 1992 Linus Torvalds
7 * Copyright (C) 1994 - 2000, 2006 Ralf Baechle
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 * Copyright (C) 2016, Imagination Technologies Ltd.
10 */
11#include <linux/compiler.h>
12#include <linux/errno.h>
13#include <linux/signal.h>
14#include <linux/uaccess.h>
15
16#include <asm/abi.h>
17#include <asm/compat-signal.h>
18#include <asm/dsp.h>
19#include <asm/sim.h>
20#include <asm/unistd.h>
21
22#include "signal-common.h"
23
24/*
25 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
26 */
27#define __NR_O32_restart_syscall 4253
28
29struct sigframe32 {
30 u32 sf_ass[4]; /* argument save space for o32 */
31 u32 sf_pad[2]; /* Was: signal trampoline */
32 struct sigcontext32 sf_sc;
33 compat_sigset_t sf_mask;
34};
35
36struct ucontext32 {
37 u32 uc_flags;
38 s32 uc_link;
39 compat_stack_t uc_stack;
40 struct sigcontext32 uc_mcontext;
41 compat_sigset_t uc_sigmask; /* mask last for extensibility */
42};
43
44struct rt_sigframe32 {
45 u32 rs_ass[4]; /* argument save space for o32 */
46 u32 rs_pad[2]; /* Was: signal trampoline */
47 compat_siginfo_t rs_info;
48 struct ucontext32 rs_uc;
49};
50
51static int setup_sigcontext32(struct pt_regs *regs,
52 struct sigcontext32 __user *sc)
53{
54 int err = 0;
55 int i;
56
57 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
58
59 err |= __put_user(0, &sc->sc_regs[0]);
60 for (i = 1; i < 32; i++)
61 err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
62
63 err |= __put_user(regs->hi, &sc->sc_mdhi);
64 err |= __put_user(regs->lo, &sc->sc_mdlo);
65 if (cpu_has_dsp) {
66 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
67 err |= __put_user(mfhi1(), &sc->sc_hi1);
68 err |= __put_user(mflo1(), &sc->sc_lo1);
69 err |= __put_user(mfhi2(), &sc->sc_hi2);
70 err |= __put_user(mflo2(), &sc->sc_lo2);
71 err |= __put_user(mfhi3(), &sc->sc_hi3);
72 err |= __put_user(mflo3(), &sc->sc_lo3);
73 }
74
75 /*
76 * Save FPU state to signal context. Signal handler
77 * will "inherit" current FPU state.
78 */
79 err |= protected_save_fp_context(sc);
80
81 return err;
82}
83
84static int restore_sigcontext32(struct pt_regs *regs,
85 struct sigcontext32 __user *sc)
86{
87 int err = 0;
88 s32 treg;
89 int i;
90
91 /* Always make any pending restarted system calls return -EINTR */
92 current->restart_block.fn = do_no_restart_syscall;
93
94 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
95 err |= __get_user(regs->hi, &sc->sc_mdhi);
96 err |= __get_user(regs->lo, &sc->sc_mdlo);
97 if (cpu_has_dsp) {
98 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
99 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
100 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
101 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
102 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
103 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
104 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
105 }
106
107 for (i = 1; i < 32; i++)
108 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
109
110 return err ?: protected_restore_fp_context(sc);
111}
112
113static int setup_frame_32(void *sig_return, struct ksignal *ksig,
114 struct pt_regs *regs, sigset_t *set)
115{
116 struct sigframe32 __user *frame;
117 int err = 0;
118
119 frame = get_sigframe(ksig, regs, sizeof(*frame));
120 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
121 return -EFAULT;
122
123 err |= setup_sigcontext32(regs, &frame->sf_sc);
124 err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
125
126 if (err)
127 return -EFAULT;
128
129 /*
130 * Arguments to signal handler:
131 *
132 * a0 = signal number
133 * a1 = 0 (should be cause)
134 * a2 = pointer to struct sigcontext
135 *
136 * $25 and c0_epc point to the signal handler, $29 points to the
137 * struct sigframe.
138 */
139 regs->regs[ 4] = ksig->sig;
140 regs->regs[ 5] = 0;
141 regs->regs[ 6] = (unsigned long) &frame->sf_sc;
142 regs->regs[29] = (unsigned long) frame;
143 regs->regs[31] = (unsigned long) sig_return;
144 regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
145
146 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
147 current->comm, current->pid,
148 frame, regs->cp0_epc, regs->regs[31]);
149
150 return 0;
151}
152
153asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
154{
155 struct rt_sigframe32 __user *frame;
156 sigset_t set;
157 int sig;
158
159 frame = (struct rt_sigframe32 __user *) regs.regs[29];
160 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
161 goto badframe;
162 if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
163 goto badframe;
164
165 set_current_blocked(&set);
166
167 sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
168 if (sig < 0)
169 goto badframe;
170 else if (sig)
171 force_sig(sig, current);
172
173 if (compat_restore_altstack(&frame->rs_uc.uc_stack))
174 goto badframe;
175
176 /*
177 * Don't let your children do this ...
178 */
179 __asm__ __volatile__(
180 "move\t$29, %0\n\t"
181 "j\tsyscall_exit"
182 :/* no outputs */
183 :"r" (&regs));
184 /* Unreached */
185
186badframe:
187 force_sig(SIGSEGV, current);
188}
189
190static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig,
191 struct pt_regs *regs, sigset_t *set)
192{
193 struct rt_sigframe32 __user *frame;
194 int err = 0;
195
196 frame = get_sigframe(ksig, regs, sizeof(*frame));
197 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
198 return -EFAULT;
199
200 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
201 err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
202
203 /* Create the ucontext. */
204 err |= __put_user(0, &frame->rs_uc.uc_flags);
205 err |= __put_user(0, &frame->rs_uc.uc_link);
206 err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
207 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
208 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
209
210 if (err)
211 return -EFAULT;
212
213 /*
214 * Arguments to signal handler:
215 *
216 * a0 = signal number
217 * a1 = 0 (should be cause)
218 * a2 = pointer to ucontext
219 *
220 * $25 and c0_epc point to the signal handler, $29 points to
221 * the struct rt_sigframe32.
222 */
223 regs->regs[ 4] = ksig->sig;
224 regs->regs[ 5] = (unsigned long) &frame->rs_info;
225 regs->regs[ 6] = (unsigned long) &frame->rs_uc;
226 regs->regs[29] = (unsigned long) frame;
227 regs->regs[31] = (unsigned long) sig_return;
228 regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
229
230 DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
231 current->comm, current->pid,
232 frame, regs->cp0_epc, regs->regs[31]);
233
234 return 0;
235}
236
237/*
238 * o32 compatibility on 64-bit kernels, without DSP ASE
239 */
240struct mips_abi mips_abi_32 = {
241 .setup_frame = setup_frame_32,
242 .setup_rt_frame = setup_rt_frame_32,
243 .restart = __NR_O32_restart_syscall,
244
245 .off_sc_fpregs = offsetof(struct sigcontext32, sc_fpregs),
246 .off_sc_fpc_csr = offsetof(struct sigcontext32, sc_fpc_csr),
247 .off_sc_used_math = offsetof(struct sigcontext32, sc_used_math),
248
249 .vdso = &vdso_image_o32,
250};
251
252
253asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
254{
255 struct sigframe32 __user *frame;
256 sigset_t blocked;
257 int sig;
258
259 frame = (struct sigframe32 __user *) regs.regs[29];
260 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
261 goto badframe;
262 if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
263 goto badframe;
264
265 set_current_blocked(&blocked);
266
267 sig = restore_sigcontext32(&regs, &frame->sf_sc);
268 if (sig < 0)
269 goto badframe;
270 else if (sig)
271 force_sig(sig, current);
272
273 /*
274 * Don't let your children do this ...
275 */
276 __asm__ __volatile__(
277 "move\t$29, %0\n\t"
278 "j\tsyscall_exit"
279 :/* no outputs */
280 :"r" (&regs));
281 /* Unreached */
282
283badframe:
284 force_sig(SIGSEGV, current);
285}
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index e02addc0307f..6d0f1321e084 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -363,6 +363,7 @@ static int bmips_cpu_disable(void)
363 pr_info("SMP: CPU%d is offline\n", cpu); 363 pr_info("SMP: CPU%d is offline\n", cpu);
364 364
365 set_cpu_online(cpu, false); 365 set_cpu_online(cpu, false);
366 calculate_cpu_foreign_map();
366 cpumask_clear_cpu(cpu, &cpu_callin_map); 367 cpumask_clear_cpu(cpu, &cpu_callin_map);
367 clear_c0_status(IE_IRQ5); 368 clear_c0_status(IE_IRQ5);
368 369
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 05b3201271b4..e9d9fc6c754c 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -206,7 +206,7 @@ err_out:
206 } 206 }
207} 207}
208 208
209static void boot_core(unsigned core) 209static void boot_core(unsigned int core, unsigned int vpe_id)
210{ 210{
211 u32 access, stat, seq_state; 211 u32 access, stat, seq_state;
212 unsigned timeout; 212 unsigned timeout;
@@ -233,8 +233,9 @@ static void boot_core(unsigned core)
233 mips_cpc_lock_other(core); 233 mips_cpc_lock_other(core);
234 234
235 if (mips_cm_revision() >= CM_REV_CM3) { 235 if (mips_cm_revision() >= CM_REV_CM3) {
236 /* Run VP0 following the reset */ 236 /* Run only the requested VP following the reset */
237 write_cpc_co_vp_run(0x1); 237 write_cpc_co_vp_stop(0xf);
238 write_cpc_co_vp_run(1 << vpe_id);
238 239
239 /* 240 /*
240 * Ensure that the VP_RUN register is written before the 241 * Ensure that the VP_RUN register is written before the
@@ -306,7 +307,7 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
306 307
307 if (!test_bit(core, core_power)) { 308 if (!test_bit(core, core_power)) {
308 /* Boot a VPE on a powered down core */ 309 /* Boot a VPE on a powered down core */
309 boot_core(core); 310 boot_core(core, vpe_id);
310 goto out; 311 goto out;
311 } 312 }
312 313
@@ -397,6 +398,7 @@ static int cps_cpu_disable(void)
397 atomic_sub(1 << cpu_vpe_id(&current_cpu_data), &core_cfg->vpe_mask); 398 atomic_sub(1 << cpu_vpe_id(&current_cpu_data), &core_cfg->vpe_mask);
398 smp_mb__after_atomic(); 399 smp_mb__after_atomic();
399 set_cpu_online(cpu, false); 400 set_cpu_online(cpu, false);
401 calculate_cpu_foreign_map();
400 cpumask_clear_cpu(cpu, &cpu_callin_map); 402 cpumask_clear_cpu(cpu, &cpu_callin_map);
401 403
402 return 0; 404 return 0;
@@ -411,14 +413,16 @@ static enum {
411 413
412void play_dead(void) 414void play_dead(void)
413{ 415{
414 unsigned cpu, core; 416 unsigned int cpu, core, vpe_id;
415 417
416 local_irq_disable(); 418 local_irq_disable();
417 idle_task_exit(); 419 idle_task_exit();
418 cpu = smp_processor_id(); 420 cpu = smp_processor_id();
419 cpu_death = CPU_DEATH_POWER; 421 cpu_death = CPU_DEATH_POWER;
420 422
421 if (cpu_has_mipsmt) { 423 pr_debug("CPU%d going offline\n", cpu);
424
425 if (cpu_has_mipsmt || cpu_has_vp) {
422 core = cpu_data[cpu].core; 426 core = cpu_data[cpu].core;
423 427
424 /* Look for another online VPE within the core */ 428 /* Look for another online VPE within the core */
@@ -439,10 +443,21 @@ void play_dead(void)
439 complete(&cpu_death_chosen); 443 complete(&cpu_death_chosen);
440 444
441 if (cpu_death == CPU_DEATH_HALT) { 445 if (cpu_death == CPU_DEATH_HALT) {
442 /* Halt this TC */ 446 vpe_id = cpu_vpe_id(&cpu_data[cpu]);
443 write_c0_tchalt(TCHALT_H); 447
444 instruction_hazard(); 448 pr_debug("Halting core %d VP%d\n", core, vpe_id);
449 if (cpu_has_mipsmt) {
450 /* Halt this TC */
451 write_c0_tchalt(TCHALT_H);
452 instruction_hazard();
453 } else if (cpu_has_vp) {
454 write_cpc_cl_vp_stop(1 << vpe_id);
455
456 /* Ensure that the VP_STOP register is written */
457 wmb();
458 }
445 } else { 459 } else {
460 pr_debug("Gating power to core %d\n", core);
446 /* Power down the core */ 461 /* Power down the core */
447 cps_pm_enter_state(CPS_PM_POWER_GATED); 462 cps_pm_enter_state(CPS_PM_POWER_GATED);
448 } 463 }
@@ -469,6 +484,7 @@ static void wait_for_sibling_halt(void *ptr_cpu)
469static void cps_cpu_die(unsigned int cpu) 484static void cps_cpu_die(unsigned int cpu)
470{ 485{
471 unsigned core = cpu_data[cpu].core; 486 unsigned core = cpu_data[cpu].core;
487 unsigned int vpe_id = cpu_vpe_id(&cpu_data[cpu]);
472 unsigned stat; 488 unsigned stat;
473 int err; 489 int err;
474 490
@@ -497,10 +513,12 @@ static void cps_cpu_die(unsigned int cpu)
497 * in which case the CPC will refuse to power down the core. 513 * in which case the CPC will refuse to power down the core.
498 */ 514 */
499 do { 515 do {
516 mips_cm_lock_other(core, vpe_id);
500 mips_cpc_lock_other(core); 517 mips_cpc_lock_other(core);
501 stat = read_cpc_co_stat_conf(); 518 stat = read_cpc_co_stat_conf();
502 stat &= CPC_Cx_STAT_CONF_SEQSTATE_MSK; 519 stat &= CPC_Cx_STAT_CONF_SEQSTATE_MSK;
503 mips_cpc_unlock_other(); 520 mips_cpc_unlock_other();
521 mips_cm_unlock_other();
504 } while (stat != CPC_Cx_STAT_CONF_SEQSTATE_D0 && 522 } while (stat != CPC_Cx_STAT_CONF_SEQSTATE_D0 &&
505 stat != CPC_Cx_STAT_CONF_SEQSTATE_D2 && 523 stat != CPC_Cx_STAT_CONF_SEQSTATE_D2 &&
506 stat != CPC_Cx_STAT_CONF_SEQSTATE_U2); 524 stat != CPC_Cx_STAT_CONF_SEQSTATE_U2);
@@ -517,6 +535,12 @@ static void cps_cpu_die(unsigned int cpu)
517 (void *)(unsigned long)cpu, 1); 535 (void *)(unsigned long)cpu, 1);
518 if (err) 536 if (err)
519 panic("Failed to call remote sibling CPU\n"); 537 panic("Failed to call remote sibling CPU\n");
538 } else if (cpu_has_vp) {
539 do {
540 mips_cm_lock_other(core, vpe_id);
541 stat = read_cpc_co_vp_running();
542 mips_cm_unlock_other();
543 } while (stat & (1 << vpe_id));
520 } 544 }
521} 545}
522 546
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index f9d01e953acb..f95f094f36e4 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -72,7 +72,7 @@ EXPORT_SYMBOL(cpu_core_map);
72 * A logcal cpu mask containing only one VPE per core to 72 * A logcal cpu mask containing only one VPE per core to
73 * reduce the number of IPIs on large MT systems. 73 * reduce the number of IPIs on large MT systems.
74 */ 74 */
75cpumask_t cpu_foreign_map __read_mostly; 75cpumask_t cpu_foreign_map[NR_CPUS] __read_mostly;
76EXPORT_SYMBOL(cpu_foreign_map); 76EXPORT_SYMBOL(cpu_foreign_map);
77 77
78/* representing cpus for which sibling maps can be computed */ 78/* representing cpus for which sibling maps can be computed */
@@ -124,7 +124,7 @@ static inline void set_cpu_core_map(int cpu)
124 * Calculate a new cpu_foreign_map mask whenever a 124 * Calculate a new cpu_foreign_map mask whenever a
125 * new cpu appears or disappears. 125 * new cpu appears or disappears.
126 */ 126 */
127static inline void calculate_cpu_foreign_map(void) 127void calculate_cpu_foreign_map(void)
128{ 128{
129 int i, k, core_present; 129 int i, k, core_present;
130 cpumask_t temp_foreign_map; 130 cpumask_t temp_foreign_map;
@@ -141,7 +141,9 @@ static inline void calculate_cpu_foreign_map(void)
141 cpumask_set_cpu(i, &temp_foreign_map); 141 cpumask_set_cpu(i, &temp_foreign_map);
142 } 142 }
143 143
144 cpumask_copy(&cpu_foreign_map, &temp_foreign_map); 144 for_each_online_cpu(i)
145 cpumask_andnot(&cpu_foreign_map[i],
146 &temp_foreign_map, &cpu_sibling_map[i]);
145} 147}
146 148
147struct plat_smp_ops *mp_ops; 149struct plat_smp_ops *mp_ops;
@@ -344,16 +346,9 @@ asmlinkage void start_secondary(void)
344static void stop_this_cpu(void *dummy) 346static void stop_this_cpu(void *dummy)
345{ 347{
346 /* 348 /*
347 * Remove this CPU. Be a bit slow here and 349 * Remove this CPU:
348 * set the bits for every online CPU so we don't miss
349 * any IPI whilst taking this VPE down.
350 */ 350 */
351 351
352 cpumask_copy(&cpu_foreign_map, cpu_online_mask);
353
354 /* Make it visible to every other CPU */
355 smp_mb();
356
357 set_cpu_online(smp_processor_id(), false); 352 set_cpu_online(smp_processor_id(), false);
358 calculate_cpu_foreign_map(); 353 calculate_cpu_foreign_map();
359 local_irq_disable(); 354 local_irq_disable();
@@ -512,10 +507,17 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned l
512 smp_on_other_tlbs(flush_tlb_range_ipi, &fd); 507 smp_on_other_tlbs(flush_tlb_range_ipi, &fd);
513 } else { 508 } else {
514 unsigned int cpu; 509 unsigned int cpu;
510 int exec = vma->vm_flags & VM_EXEC;
515 511
516 for_each_online_cpu(cpu) { 512 for_each_online_cpu(cpu) {
513 /*
514 * flush_cache_range() will only fully flush icache if
515 * the VMA is executable, otherwise we must invalidate
516 * ASID without it appearing to has_valid_asid() as if
517 * mm has been completely unused by that CPU.
518 */
517 if (cpu != smp_processor_id() && cpu_context(cpu, mm)) 519 if (cpu != smp_processor_id() && cpu_context(cpu, mm))
518 cpu_context(cpu, mm) = 0; 520 cpu_context(cpu, mm) = !exec;
519 } 521 }
520 } 522 }
521 local_flush_tlb_range(vma, start, end); 523 local_flush_tlb_range(vma, start, end);
@@ -560,8 +562,14 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
560 unsigned int cpu; 562 unsigned int cpu;
561 563
562 for_each_online_cpu(cpu) { 564 for_each_online_cpu(cpu) {
565 /*
566 * flush_cache_page() only does partial flushes, so
567 * invalidate ASID without it appearing to
568 * has_valid_asid() as if mm has been completely unused
569 * by that CPU.
570 */
563 if (cpu != smp_processor_id() && cpu_context(cpu, vma->vm_mm)) 571 if (cpu != smp_processor_id() && cpu_context(cpu, vma->vm_mm))
564 cpu_context(cpu, vma->vm_mm) = 0; 572 cpu_context(cpu, vma->vm_mm) = 1;
565 } 573 }
566 } 574 }
567 local_flush_tlb_page(vma, page); 575 local_flush_tlb_page(vma, page);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 6fb4704bd156..3de85be2486a 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -704,6 +704,7 @@ asmlinkage void do_ov(struct pt_regs *regs)
704int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31) 704int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
705{ 705{
706 struct siginfo si = { 0 }; 706 struct siginfo si = { 0 };
707 struct vm_area_struct *vma;
707 708
708 switch (sig) { 709 switch (sig) {
709 case 0: 710 case 0:
@@ -744,7 +745,8 @@ int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
744 si.si_addr = fault_addr; 745 si.si_addr = fault_addr;
745 si.si_signo = sig; 746 si.si_signo = sig;
746 down_read(&current->mm->mmap_sem); 747 down_read(&current->mm->mmap_sem);
747 if (find_vma(current->mm, (unsigned long)fault_addr)) 748 vma = find_vma(current->mm, (unsigned long)fault_addr);
749 if (vma && (vma->vm_start <= (unsigned long)fault_addr))
748 si.si_code = SEGV_ACCERR; 750 si.si_code = SEGV_ACCERR;
749 else 751 else
750 si.si_code = SEGV_MAPERR; 752 si.si_code = SEGV_MAPERR;
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 54e1663ce639..9abe447a4b48 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -107,6 +107,16 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
107 if (down_write_killable(&mm->mmap_sem)) 107 if (down_write_killable(&mm->mmap_sem))
108 return -EINTR; 108 return -EINTR;
109 109
110 /* Map delay slot emulation page */
111 base = mmap_region(NULL, STACK_TOP, PAGE_SIZE,
112 VM_READ|VM_WRITE|VM_EXEC|
113 VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
114 0);
115 if (IS_ERR_VALUE(base)) {
116 ret = base;
117 goto out;
118 }
119
110 /* 120 /*
111 * Determine total area size. This includes the VDSO data itself, the 121 * Determine total area size. This includes the VDSO data itself, the
112 * data page, and the GIC user page if present. Always create a mapping 122 * data page, and the GIC user page if present. Always create a mapping