aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-05-20 14:50:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-05-20 14:50:27 -0400
commit132ce5d43adfd9b5da27ad17cc28a01cd2310f0a (patch)
tree20c16a85244277cb2d7c7e122d5cca4094c78379
parent8a6bd2f40e96fb4d96749ab029c61f0df218b003 (diff)
parent92d44a42af81e850a038c38278ff4f434b2871df (diff)
Merge branch 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM fixes from Russell King: - Ɓukasz Stelmach spotted a couple of issues with the decompressor. - a couple of kdump fixes found while testing kdump - replace some perl with shell code - resolve SIGFPE breakage - kprobes fixes * 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm: ARM: fix kill( ,SIGFPE) breakage ARM: 8772/1: kprobes: Prohibit kprobes on get_user functions ARM: 8771/1: kprobes: Prohibit kprobes on do_undefinstr ARM: 8770/1: kprobes: Prohibit probing on optimized_callback ARM: 8769/1: kprobes: Fix to use get_kprobe_ctlblk after irq-disabed ARM: replace unnecessary perl with sed and the shell $(( )) operator ARM: kexec: record parent context registers for non-crash CPUs ARM: kexec: fix kdump register saving on panic() ARM: 8758/1: decompressor: restore r1 and r2 just before jumping to the kernel ARM: 8753/1: decompressor: add a missing parameter to the addruart macro
-rw-r--r--arch/arm/boot/compressed/Makefile8
-rw-r--r--arch/arm/boot/compressed/head.S20
-rw-r--r--arch/arm/include/asm/assembler.h10
-rw-r--r--arch/arm/include/uapi/asm/siginfo.h13
-rw-r--r--arch/arm/kernel/machine_kexec.c36
-rw-r--r--arch/arm/kernel/traps.c5
-rw-r--r--arch/arm/lib/getuser.S10
-rw-r--r--arch/arm/probes/kprobes/opt-arm.c4
-rw-r--r--arch/arm/vfp/vfpmodule.c2
9 files changed, 64 insertions, 44 deletions
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 45a6b9b7af2a..6a4e7341ecd3 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -117,11 +117,9 @@ ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
117asflags-y := -DZIMAGE 117asflags-y := -DZIMAGE
118 118
119# Supply kernel BSS size to the decompressor via a linker symbol. 119# Supply kernel BSS size to the decompressor via a linker symbol.
120KBSS_SZ = $(shell $(CROSS_COMPILE)nm $(obj)/../../../../vmlinux | \ 120KBSS_SZ = $(shell echo $$(($$($(CROSS_COMPILE)nm $(obj)/../../../../vmlinux | \
121 perl -e 'while (<>) { \ 121 sed -n -e 's/^\([^ ]*\) [AB] __bss_start$$/-0x\1/p' \
122 $$bss_start=hex($$1) if /^([[:xdigit:]]+) B __bss_start$$/; \ 122 -e 's/^\([^ ]*\) [AB] __bss_stop$$/+0x\1/p') )) )
123 $$bss_end=hex($$1) if /^([[:xdigit:]]+) B __bss_stop$$/; \
124 }; printf "%d\n", $$bss_end - $$bss_start;')
125LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ) 123LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
126# Supply ZRELADDR to the decompressor via a linker symbol. 124# Supply ZRELADDR to the decompressor via a linker symbol.
127ifneq ($(CONFIG_AUTO_ZRELADDR),y) 125ifneq ($(CONFIG_AUTO_ZRELADDR),y)
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 45c8823c3750..517e0e18f0b8 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -29,19 +29,19 @@
29#if defined(CONFIG_DEBUG_ICEDCC) 29#if defined(CONFIG_DEBUG_ICEDCC)
30 30
31#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7) 31#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
32 .macro loadsp, rb, tmp 32 .macro loadsp, rb, tmp1, tmp2
33 .endm 33 .endm
34 .macro writeb, ch, rb 34 .macro writeb, ch, rb
35 mcr p14, 0, \ch, c0, c5, 0 35 mcr p14, 0, \ch, c0, c5, 0
36 .endm 36 .endm
37#elif defined(CONFIG_CPU_XSCALE) 37#elif defined(CONFIG_CPU_XSCALE)
38 .macro loadsp, rb, tmp 38 .macro loadsp, rb, tmp1, tmp2
39 .endm 39 .endm
40 .macro writeb, ch, rb 40 .macro writeb, ch, rb
41 mcr p14, 0, \ch, c8, c0, 0 41 mcr p14, 0, \ch, c8, c0, 0
42 .endm 42 .endm
43#else 43#else
44 .macro loadsp, rb, tmp 44 .macro loadsp, rb, tmp1, tmp2
45 .endm 45 .endm
46 .macro writeb, ch, rb 46 .macro writeb, ch, rb
47 mcr p14, 0, \ch, c1, c0, 0 47 mcr p14, 0, \ch, c1, c0, 0
@@ -57,7 +57,7 @@
57 .endm 57 .endm
58 58
59#if defined(CONFIG_ARCH_SA1100) 59#if defined(CONFIG_ARCH_SA1100)
60 .macro loadsp, rb, tmp 60 .macro loadsp, rb, tmp1, tmp2
61 mov \rb, #0x80000000 @ physical base address 61 mov \rb, #0x80000000 @ physical base address
62#ifdef CONFIG_DEBUG_LL_SER3 62#ifdef CONFIG_DEBUG_LL_SER3
63 add \rb, \rb, #0x00050000 @ Ser3 63 add \rb, \rb, #0x00050000 @ Ser3
@@ -66,8 +66,8 @@
66#endif 66#endif
67 .endm 67 .endm
68#else 68#else
69 .macro loadsp, rb, tmp 69 .macro loadsp, rb, tmp1, tmp2
70 addruart \rb, \tmp 70 addruart \rb, \tmp1, \tmp2
71 .endm 71 .endm
72#endif 72#endif
73#endif 73#endif
@@ -561,8 +561,6 @@ not_relocated: mov r0, #0
561 bl decompress_kernel 561 bl decompress_kernel
562 bl cache_clean_flush 562 bl cache_clean_flush
563 bl cache_off 563 bl cache_off
564 mov r1, r7 @ restore architecture number
565 mov r2, r8 @ restore atags pointer
566 564
567#ifdef CONFIG_ARM_VIRT_EXT 565#ifdef CONFIG_ARM_VIRT_EXT
568 mrs r0, spsr @ Get saved CPU boot mode 566 mrs r0, spsr @ Get saved CPU boot mode
@@ -1297,7 +1295,7 @@ phex: adr r3, phexbuf
1297 b 1b 1295 b 1b
1298 1296
1299@ puts corrupts {r0, r1, r2, r3} 1297@ puts corrupts {r0, r1, r2, r3}
1300puts: loadsp r3, r1 1298puts: loadsp r3, r2, r1
13011: ldrb r2, [r0], #1 12991: ldrb r2, [r0], #1
1302 teq r2, #0 1300 teq r2, #0
1303 moveq pc, lr 1301 moveq pc, lr
@@ -1314,8 +1312,8 @@ puts: loadsp r3, r1
1314@ putc corrupts {r0, r1, r2, r3} 1312@ putc corrupts {r0, r1, r2, r3}
1315putc: 1313putc:
1316 mov r2, r0 1314 mov r2, r0
1315 loadsp r3, r1, r0
1317 mov r0, #0 1316 mov r0, #0
1318 loadsp r3, r1
1319 b 2b 1317 b 2b
1320 1318
1321@ memdump corrupts {r0, r1, r2, r3, r10, r11, r12, lr} 1319@ memdump corrupts {r0, r1, r2, r3, r10, r11, r12, lr}
@@ -1365,6 +1363,8 @@ __hyp_reentry_vectors:
1365 1363
1366__enter_kernel: 1364__enter_kernel:
1367 mov r0, #0 @ must be 0 1365 mov r0, #0 @ must be 0
1366 mov r1, r7 @ restore architecture number
1367 mov r2, r8 @ restore atags pointer
1368 ARM( mov pc, r4 ) @ call kernel 1368 ARM( mov pc, r4 ) @ call kernel
1369 M_CLASS( add r4, r4, #1 ) @ enter in Thumb mode for M class 1369 M_CLASS( add r4, r4, #1 ) @ enter in Thumb mode for M class
1370 THUMB( bx r4 ) @ entry point is always ARM for A/R classes 1370 THUMB( bx r4 ) @ entry point is always ARM for A/R classes
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index bc8d4bbd82e2..9342904cccca 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -536,4 +536,14 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
536#endif 536#endif
537 .endm 537 .endm
538 538
539#ifdef CONFIG_KPROBES
540#define _ASM_NOKPROBE(entry) \
541 .pushsection "_kprobe_blacklist", "aw" ; \
542 .balign 4 ; \
543 .long entry; \
544 .popsection
545#else
546#define _ASM_NOKPROBE(entry)
547#endif
548
539#endif /* __ASM_ASSEMBLER_H__ */ 549#endif /* __ASM_ASSEMBLER_H__ */
diff --git a/arch/arm/include/uapi/asm/siginfo.h b/arch/arm/include/uapi/asm/siginfo.h
deleted file mode 100644
index d0513880be21..000000000000
--- a/arch/arm/include/uapi/asm/siginfo.h
+++ /dev/null
@@ -1,13 +0,0 @@
1#ifndef __ASM_SIGINFO_H
2#define __ASM_SIGINFO_H
3
4#include <asm-generic/siginfo.h>
5
6/*
7 * SIGFPE si_codes
8 */
9#ifdef __KERNEL__
10#define FPE_FIXME 0 /* Broken dup of SI_USER */
11#endif /* __KERNEL__ */
12
13#endif
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 6b38d7a634c1..dd2eb5f76b9f 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -83,7 +83,7 @@ void machine_crash_nonpanic_core(void *unused)
83{ 83{
84 struct pt_regs regs; 84 struct pt_regs regs;
85 85
86 crash_setup_regs(&regs, NULL); 86 crash_setup_regs(&regs, get_irq_regs());
87 printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n", 87 printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n",
88 smp_processor_id()); 88 smp_processor_id());
89 crash_save_cpu(&regs, smp_processor_id()); 89 crash_save_cpu(&regs, smp_processor_id());
@@ -95,6 +95,27 @@ void machine_crash_nonpanic_core(void *unused)
95 cpu_relax(); 95 cpu_relax();
96} 96}
97 97
98void crash_smp_send_stop(void)
99{
100 static int cpus_stopped;
101 unsigned long msecs;
102
103 if (cpus_stopped)
104 return;
105
106 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
107 smp_call_function(machine_crash_nonpanic_core, NULL, false);
108 msecs = 1000; /* Wait at most a second for the other cpus to stop */
109 while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
110 mdelay(1);
111 msecs--;
112 }
113 if (atomic_read(&waiting_for_crash_ipi) > 0)
114 pr_warn("Non-crashing CPUs did not react to IPI\n");
115
116 cpus_stopped = 1;
117}
118
98static void machine_kexec_mask_interrupts(void) 119static void machine_kexec_mask_interrupts(void)
99{ 120{
100 unsigned int i; 121 unsigned int i;
@@ -120,19 +141,8 @@ static void machine_kexec_mask_interrupts(void)
120 141
121void machine_crash_shutdown(struct pt_regs *regs) 142void machine_crash_shutdown(struct pt_regs *regs)
122{ 143{
123 unsigned long msecs;
124
125 local_irq_disable(); 144 local_irq_disable();
126 145 crash_smp_send_stop();
127 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
128 smp_call_function(machine_crash_nonpanic_core, NULL, false);
129 msecs = 1000; /* Wait at most a second for the other cpus to stop */
130 while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
131 mdelay(1);
132 msecs--;
133 }
134 if (atomic_read(&waiting_for_crash_ipi) > 0)
135 pr_warn("Non-crashing CPUs did not react to IPI\n");
136 146
137 crash_save_cpu(regs, smp_processor_id()); 147 crash_save_cpu(regs, smp_processor_id());
138 machine_kexec_mask_interrupts(); 148 machine_kexec_mask_interrupts();
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 5e3633c24e63..2fe87109ae46 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -19,6 +19,7 @@
19#include <linux/uaccess.h> 19#include <linux/uaccess.h>
20#include <linux/hardirq.h> 20#include <linux/hardirq.h>
21#include <linux/kdebug.h> 21#include <linux/kdebug.h>
22#include <linux/kprobes.h>
22#include <linux/module.h> 23#include <linux/module.h>
23#include <linux/kexec.h> 24#include <linux/kexec.h>
24#include <linux/bug.h> 25#include <linux/bug.h>
@@ -417,7 +418,8 @@ void unregister_undef_hook(struct undef_hook *hook)
417 raw_spin_unlock_irqrestore(&undef_lock, flags); 418 raw_spin_unlock_irqrestore(&undef_lock, flags);
418} 419}
419 420
420static int call_undef_hook(struct pt_regs *regs, unsigned int instr) 421static nokprobe_inline
422int call_undef_hook(struct pt_regs *regs, unsigned int instr)
421{ 423{
422 struct undef_hook *hook; 424 struct undef_hook *hook;
423 unsigned long flags; 425 unsigned long flags;
@@ -490,6 +492,7 @@ die_sig:
490 492
491 arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6); 493 arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
492} 494}
495NOKPROBE_SYMBOL(do_undefinstr)
493 496
494/* 497/*
495 * Handle FIQ similarly to NMI on x86 systems. 498 * Handle FIQ similarly to NMI on x86 systems.
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index df73914e81c8..746e7801dcdf 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -38,6 +38,7 @@ ENTRY(__get_user_1)
38 mov r0, #0 38 mov r0, #0
39 ret lr 39 ret lr
40ENDPROC(__get_user_1) 40ENDPROC(__get_user_1)
41_ASM_NOKPROBE(__get_user_1)
41 42
42ENTRY(__get_user_2) 43ENTRY(__get_user_2)
43 check_uaccess r0, 2, r1, r2, __get_user_bad 44 check_uaccess r0, 2, r1, r2, __get_user_bad
@@ -58,6 +59,7 @@ rb .req r0
58 mov r0, #0 59 mov r0, #0
59 ret lr 60 ret lr
60ENDPROC(__get_user_2) 61ENDPROC(__get_user_2)
62_ASM_NOKPROBE(__get_user_2)
61 63
62ENTRY(__get_user_4) 64ENTRY(__get_user_4)
63 check_uaccess r0, 4, r1, r2, __get_user_bad 65 check_uaccess r0, 4, r1, r2, __get_user_bad
@@ -65,6 +67,7 @@ ENTRY(__get_user_4)
65 mov r0, #0 67 mov r0, #0
66 ret lr 68 ret lr
67ENDPROC(__get_user_4) 69ENDPROC(__get_user_4)
70_ASM_NOKPROBE(__get_user_4)
68 71
69ENTRY(__get_user_8) 72ENTRY(__get_user_8)
70 check_uaccess r0, 8, r1, r2, __get_user_bad8 73 check_uaccess r0, 8, r1, r2, __get_user_bad8
@@ -78,6 +81,7 @@ ENTRY(__get_user_8)
78 mov r0, #0 81 mov r0, #0
79 ret lr 82 ret lr
80ENDPROC(__get_user_8) 83ENDPROC(__get_user_8)
84_ASM_NOKPROBE(__get_user_8)
81 85
82#ifdef __ARMEB__ 86#ifdef __ARMEB__
83ENTRY(__get_user_32t_8) 87ENTRY(__get_user_32t_8)
@@ -91,6 +95,7 @@ ENTRY(__get_user_32t_8)
91 mov r0, #0 95 mov r0, #0
92 ret lr 96 ret lr
93ENDPROC(__get_user_32t_8) 97ENDPROC(__get_user_32t_8)
98_ASM_NOKPROBE(__get_user_32t_8)
94 99
95ENTRY(__get_user_64t_1) 100ENTRY(__get_user_64t_1)
96 check_uaccess r0, 1, r1, r2, __get_user_bad8 101 check_uaccess r0, 1, r1, r2, __get_user_bad8
@@ -98,6 +103,7 @@ ENTRY(__get_user_64t_1)
98 mov r0, #0 103 mov r0, #0
99 ret lr 104 ret lr
100ENDPROC(__get_user_64t_1) 105ENDPROC(__get_user_64t_1)
106_ASM_NOKPROBE(__get_user_64t_1)
101 107
102ENTRY(__get_user_64t_2) 108ENTRY(__get_user_64t_2)
103 check_uaccess r0, 2, r1, r2, __get_user_bad8 109 check_uaccess r0, 2, r1, r2, __get_user_bad8
@@ -114,6 +120,7 @@ rb .req r0
114 mov r0, #0 120 mov r0, #0
115 ret lr 121 ret lr
116ENDPROC(__get_user_64t_2) 122ENDPROC(__get_user_64t_2)
123_ASM_NOKPROBE(__get_user_64t_2)
117 124
118ENTRY(__get_user_64t_4) 125ENTRY(__get_user_64t_4)
119 check_uaccess r0, 4, r1, r2, __get_user_bad8 126 check_uaccess r0, 4, r1, r2, __get_user_bad8
@@ -121,6 +128,7 @@ ENTRY(__get_user_64t_4)
121 mov r0, #0 128 mov r0, #0
122 ret lr 129 ret lr
123ENDPROC(__get_user_64t_4) 130ENDPROC(__get_user_64t_4)
131_ASM_NOKPROBE(__get_user_64t_4)
124#endif 132#endif
125 133
126__get_user_bad8: 134__get_user_bad8:
@@ -131,6 +139,8 @@ __get_user_bad:
131 ret lr 139 ret lr
132ENDPROC(__get_user_bad) 140ENDPROC(__get_user_bad)
133ENDPROC(__get_user_bad8) 141ENDPROC(__get_user_bad8)
142_ASM_NOKPROBE(__get_user_bad)
143_ASM_NOKPROBE(__get_user_bad8)
134 144
135.pushsection __ex_table, "a" 145.pushsection __ex_table, "a"
136 .long 1b, __get_user_bad 146 .long 1b, __get_user_bad
diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c
index bcdecc25461b..b2aa9b32bff2 100644
--- a/arch/arm/probes/kprobes/opt-arm.c
+++ b/arch/arm/probes/kprobes/opt-arm.c
@@ -165,13 +165,14 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
165{ 165{
166 unsigned long flags; 166 unsigned long flags;
167 struct kprobe *p = &op->kp; 167 struct kprobe *p = &op->kp;
168 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 168 struct kprobe_ctlblk *kcb;
169 169
170 /* Save skipped registers */ 170 /* Save skipped registers */
171 regs->ARM_pc = (unsigned long)op->kp.addr; 171 regs->ARM_pc = (unsigned long)op->kp.addr;
172 regs->ARM_ORIG_r0 = ~0UL; 172 regs->ARM_ORIG_r0 = ~0UL;
173 173
174 local_irq_save(flags); 174 local_irq_save(flags);
175 kcb = get_kprobe_ctlblk();
175 176
176 if (kprobe_running()) { 177 if (kprobe_running()) {
177 kprobes_inc_nmissed_count(&op->kp); 178 kprobes_inc_nmissed_count(&op->kp);
@@ -191,6 +192,7 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
191 192
192 local_irq_restore(flags); 193 local_irq_restore(flags);
193} 194}
195NOKPROBE_SYMBOL(optimized_callback)
194 196
195int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig) 197int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
196{ 198{
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 4c375e11ae95..af4ee2cef2f9 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -257,7 +257,7 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_
257 257
258 if (exceptions == VFP_EXCEPTION_ERROR) { 258 if (exceptions == VFP_EXCEPTION_ERROR) {
259 vfp_panic("unhandled bounce", inst); 259 vfp_panic("unhandled bounce", inst);
260 vfp_raise_sigfpe(FPE_FIXME, regs); 260 vfp_raise_sigfpe(FPE_FLTINV, regs);
261 return; 261 return;
262 } 262 }
263 263