aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2015-02-10 05:26:38 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2015-02-10 05:26:38 -0500
commitdf9ab9771c64f5229843bfe2a20fe0ee6ac59fc1 (patch)
treea091be1024bd76627f78e791e377126e47703b7b /arch
parented8f8ce38d0f7b505d7da2d79522972e962457c2 (diff)
parent4e1c0664de11e4b5861957ab4ddff2aeeffd042f (diff)
Merge branch 'devel-stable' into for-next
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/dts/armada-370-db.dts24
-rw-r--r--arch/arm/configs/multi_v7_defconfig1
-rw-r--r--arch/arm/include/asm/insn.h (renamed from arch/arm/kernel/insn.h)0
-rw-r--r--arch/arm/include/asm/kprobes.h33
-rw-r--r--arch/arm/include/asm/patch.h (renamed from arch/arm/kernel/patch.h)0
-rw-r--r--arch/arm/include/asm/probes.h15
-rw-r--r--arch/arm/kernel/Makefile16
-rw-r--r--arch/arm/kernel/entry-armv.S3
-rw-r--r--arch/arm/kernel/ftrace.c3
-rw-r--r--arch/arm/kernel/jump_label.c5
-rw-r--r--arch/arm/kernel/kgdb.c3
-rw-r--r--arch/arm/kernel/patch.c3
-rw-r--r--arch/arm/kernel/setup.c9
-rw-r--r--arch/arm/kernel/smp.c12
-rw-r--r--arch/arm/probes/Makefile7
-rw-r--r--arch/arm/probes/decode-arm.c (renamed from arch/arm/kernel/probes-arm.c)18
-rw-r--r--arch/arm/probes/decode-arm.h (renamed from arch/arm/kernel/probes-arm.h)9
-rw-r--r--arch/arm/probes/decode-thumb.c (renamed from arch/arm/kernel/probes-thumb.c)16
-rw-r--r--arch/arm/probes/decode-thumb.h (renamed from arch/arm/kernel/probes-thumb.h)10
-rw-r--r--arch/arm/probes/decode.c (renamed from arch/arm/kernel/probes.c)81
-rw-r--r--arch/arm/probes/decode.h (renamed from arch/arm/kernel/probes.h)13
-rw-r--r--arch/arm/probes/kprobes/Makefile12
-rw-r--r--arch/arm/probes/kprobes/actions-arm.c (renamed from arch/arm/kernel/kprobes-arm.c)11
-rw-r--r--arch/arm/probes/kprobes/actions-common.c (renamed from arch/arm/kernel/kprobes-common.c)4
-rw-r--r--arch/arm/probes/kprobes/actions-thumb.c (renamed from arch/arm/kernel/kprobes-thumb.c)10
-rw-r--r--arch/arm/probes/kprobes/checkers-arm.c192
-rw-r--r--arch/arm/probes/kprobes/checkers-common.c101
-rw-r--r--arch/arm/probes/kprobes/checkers-thumb.c110
-rw-r--r--arch/arm/probes/kprobes/checkers.h55
-rw-r--r--arch/arm/probes/kprobes/core.c (renamed from arch/arm/kernel/kprobes.c)49
-rw-r--r--arch/arm/probes/kprobes/core.h (renamed from arch/arm/kernel/kprobes.h)12
-rw-r--r--arch/arm/probes/kprobes/opt-arm.c370
-rw-r--r--arch/arm/probes/kprobes/test-arm.c (renamed from arch/arm/kernel/kprobes-test-arm.c)40
-rw-r--r--arch/arm/probes/kprobes/test-core.c (renamed from arch/arm/kernel/kprobes-test.c)46
-rw-r--r--arch/arm/probes/kprobes/test-core.h (renamed from arch/arm/kernel/kprobes-test.h)35
-rw-r--r--arch/arm/probes/kprobes/test-thumb.c (renamed from arch/arm/kernel/kprobes-test-thumb.c)20
-rw-r--r--arch/arm/probes/uprobes/Makefile1
-rw-r--r--arch/arm/probes/uprobes/actions-arm.c (renamed from arch/arm/kernel/uprobes-arm.c)8
-rw-r--r--arch/arm/probes/uprobes/core.c (renamed from arch/arm/kernel/uprobes.c)8
-rw-r--r--arch/arm/probes/uprobes/core.h (renamed from arch/arm/kernel/uprobes.h)0
-rw-r--r--arch/arm64/configs/defconfig9
-rw-r--r--arch/arm64/include/asm/dma-mapping.h11
-rw-r--r--arch/arm64/include/asm/pgtable.h5
-rw-r--r--arch/arm64/kernel/suspend.c14
-rw-r--r--arch/ia64/include/asm/unistd.h2
-rw-r--r--arch/ia64/include/uapi/asm/unistd.h1
-rw-r--r--arch/ia64/kernel/entry.S1
-rw-r--r--arch/nios2/kernel/cpuinfo.c1
-rw-r--r--arch/nios2/kernel/entry.S20
-rw-r--r--arch/parisc/include/asm/ldcw.h13
-rw-r--r--arch/powerpc/include/asm/kexec.h10
-rw-r--r--arch/powerpc/include/asm/systbl.h1
-rw-r--r--arch/powerpc/include/asm/unistd.h2
-rw-r--r--arch/powerpc/include/uapi/asm/unistd.h1
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c2
-rw-r--r--arch/powerpc/kernel/smp.c9
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c8
-rw-r--r--arch/um/Kconfig.common1
-rw-r--r--arch/x86/kernel/kprobes/opt.c3
-rw-r--r--arch/x86/kvm/mmu.c2
-rw-r--r--arch/x86/kvm/vmx.c88
-rw-r--r--arch/x86/um/sys_call_table_32.c2
-rw-r--r--arch/x86/um/sys_call_table_64.c2
65 files changed, 1331 insertions, 244 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c3a986d45125..1f5eb9aee750 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -61,6 +61,7 @@ config ARM
61 select HAVE_MEMBLOCK 61 select HAVE_MEMBLOCK
62 select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND 62 select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND
63 select HAVE_OPROFILE if (HAVE_PERF_EVENTS) 63 select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
64 select HAVE_OPTPROBES if !THUMB2_KERNEL
64 select HAVE_PERF_EVENTS 65 select HAVE_PERF_EVENTS
65 select HAVE_PERF_REGS 66 select HAVE_PERF_REGS
66 select HAVE_PERF_USER_STACK_DUMP 67 select HAVE_PERF_USER_STACK_DUMP
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c1785eec2cf7..7f99cd652203 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -266,6 +266,7 @@ core-$(CONFIG_KVM_ARM_HOST) += arch/arm/kvm/
266 266
267# If we have a machine-specific directory, then include it in the build. 267# If we have a machine-specific directory, then include it in the build.
268core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ 268core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
269core-y += arch/arm/probes/
269core-y += arch/arm/net/ 270core-y += arch/arm/net/
270core-y += arch/arm/crypto/ 271core-y += arch/arm/crypto/
271core-y += arch/arm/firmware/ 272core-y += arch/arm/firmware/
diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts
index 1466580be295..70b1943a86b1 100644
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -203,27 +203,3 @@
203 compatible = "linux,spdif-dir"; 203 compatible = "linux,spdif-dir";
204 }; 204 };
205}; 205};
206
207&pinctrl {
208 /*
209 * These pins might be muxed as I2S by
210 * the bootloader, but it conflicts
211 * with the real I2S pins that are
212 * muxed using i2s_pins. We must mux
213 * those pins to a function other than
214 * I2S.
215 */
216 pinctrl-0 = <&hog_pins1 &hog_pins2>;
217 pinctrl-names = "default";
218
219 hog_pins1: hog-pins1 {
220 marvell,pins = "mpp6", "mpp8", "mpp10",
221 "mpp12", "mpp13";
222 marvell,function = "gpio";
223 };
224
225 hog_pins2: hog-pins2 {
226 marvell,pins = "mpp5", "mpp7", "mpp9";
227 marvell,function = "gpo";
228 };
229};
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 2328fe752e9c..bc393b7e5ece 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -338,6 +338,7 @@ CONFIG_USB=y
338CONFIG_USB_XHCI_HCD=y 338CONFIG_USB_XHCI_HCD=y
339CONFIG_USB_XHCI_MVEBU=y 339CONFIG_USB_XHCI_MVEBU=y
340CONFIG_USB_EHCI_HCD=y 340CONFIG_USB_EHCI_HCD=y
341CONFIG_USB_EHCI_EXYNOS=y
341CONFIG_USB_EHCI_TEGRA=y 342CONFIG_USB_EHCI_TEGRA=y
342CONFIG_USB_EHCI_HCD_STI=y 343CONFIG_USB_EHCI_HCD_STI=y
343CONFIG_USB_EHCI_HCD_PLATFORM=y 344CONFIG_USB_EHCI_HCD_PLATFORM=y
diff --git a/arch/arm/kernel/insn.h b/arch/arm/include/asm/insn.h
index e96065da4dae..e96065da4dae 100644
--- a/arch/arm/kernel/insn.h
+++ b/arch/arm/include/asm/insn.h
diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h
index 49fa0dfaad33..3ea9be559726 100644
--- a/arch/arm/include/asm/kprobes.h
+++ b/arch/arm/include/asm/kprobes.h
@@ -22,7 +22,6 @@
22 22
23#define __ARCH_WANT_KPROBES_INSN_SLOT 23#define __ARCH_WANT_KPROBES_INSN_SLOT
24#define MAX_INSN_SIZE 2 24#define MAX_INSN_SIZE 2
25#define MAX_STACK_SIZE 64 /* 32 would probably be OK */
26 25
27#define flush_insn_slot(p) do { } while (0) 26#define flush_insn_slot(p) do { } while (0)
28#define kretprobe_blacklist_size 0 27#define kretprobe_blacklist_size 0
@@ -51,5 +50,37 @@ int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
51int kprobe_exceptions_notify(struct notifier_block *self, 50int kprobe_exceptions_notify(struct notifier_block *self,
52 unsigned long val, void *data); 51 unsigned long val, void *data);
53 52
53/* optinsn template addresses */
54extern __visible kprobe_opcode_t optprobe_template_entry;
55extern __visible kprobe_opcode_t optprobe_template_val;
56extern __visible kprobe_opcode_t optprobe_template_call;
57extern __visible kprobe_opcode_t optprobe_template_end;
58extern __visible kprobe_opcode_t optprobe_template_sub_sp;
59extern __visible kprobe_opcode_t optprobe_template_add_sp;
60extern __visible kprobe_opcode_t optprobe_template_restore_begin;
61extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn;
62extern __visible kprobe_opcode_t optprobe_template_restore_end;
63
64#define MAX_OPTIMIZED_LENGTH 4
65#define MAX_OPTINSN_SIZE \
66 ((unsigned long)&optprobe_template_end - \
67 (unsigned long)&optprobe_template_entry)
68#define RELATIVEJUMP_SIZE 4
69
70struct arch_optimized_insn {
71 /*
72 * copy of the original instructions.
73 * Different from x86, ARM kprobe_opcode_t is u32.
74 */
75#define MAX_COPIED_INSN DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t))
76 kprobe_opcode_t copied_insn[MAX_COPIED_INSN];
77 /* detour code buffer */
78 kprobe_opcode_t *insn;
79 /*
80 * We always copy one instruction on ARM,
81 * so size will always be 4, and unlike x86, there is no
82 * need for a size field.
83 */
84};
54 85
55#endif /* _ARM_KPROBES_H */ 86#endif /* _ARM_KPROBES_H */
diff --git a/arch/arm/kernel/patch.h b/arch/arm/include/asm/patch.h
index 77e054c2f6cd..77e054c2f6cd 100644
--- a/arch/arm/kernel/patch.h
+++ b/arch/arm/include/asm/patch.h
diff --git a/arch/arm/include/asm/probes.h b/arch/arm/include/asm/probes.h
index 806cfe622a9e..1e5b9bb92270 100644
--- a/arch/arm/include/asm/probes.h
+++ b/arch/arm/include/asm/probes.h
@@ -19,6 +19,8 @@
19#ifndef _ASM_PROBES_H 19#ifndef _ASM_PROBES_H
20#define _ASM_PROBES_H 20#define _ASM_PROBES_H
21 21
22#ifndef __ASSEMBLY__
23
22typedef u32 probes_opcode_t; 24typedef u32 probes_opcode_t;
23 25
24struct arch_probes_insn; 26struct arch_probes_insn;
@@ -38,6 +40,19 @@ struct arch_probes_insn {
38 probes_check_cc *insn_check_cc; 40 probes_check_cc *insn_check_cc;
39 probes_insn_singlestep_t *insn_singlestep; 41 probes_insn_singlestep_t *insn_singlestep;
40 probes_insn_fn_t *insn_fn; 42 probes_insn_fn_t *insn_fn;
43 int stack_space;
44 unsigned long register_usage_flags;
45 bool kprobe_direct_exec;
41}; 46};
42 47
48#endif /* __ASSEMBLY__ */
49
50/*
51 * We assume one instruction can consume at most 64 bytes stack, which is
52 * 'push {r0-r15}'. Instructions consume more or unknown stack space like
53 * 'str r0, [sp, #-80]' and 'str r0, [sp, r1]' should be prohibit to probe.
54 * Both kprobe and jprobe use this macro.
55 */
56#define MAX_STACK_SIZE 64
57
43#endif 58#endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index fb2b71ebe3f2..902397dd1000 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -51,20 +51,8 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o
51obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o 51obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o
52obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o 52obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o
53obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 53obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
54obj-$(CONFIG_UPROBES) += probes.o probes-arm.o uprobes.o uprobes-arm.o 54# Main staffs in KPROBES are in arch/arm/probes/ .
55obj-$(CONFIG_KPROBES) += probes.o kprobes.o kprobes-common.o patch.o 55obj-$(CONFIG_KPROBES) += patch.o insn.o
56ifdef CONFIG_THUMB2_KERNEL
57obj-$(CONFIG_KPROBES) += kprobes-thumb.o probes-thumb.o
58else
59obj-$(CONFIG_KPROBES) += kprobes-arm.o probes-arm.o
60endif
61obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o
62test-kprobes-objs := kprobes-test.o
63ifdef CONFIG_THUMB2_KERNEL
64test-kprobes-objs += kprobes-test-thumb.o
65else
66test-kprobes-objs += kprobes-test-arm.o
67endif
68obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o 56obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
69obj-$(CONFIG_ARM_THUMBEE) += thumbee.o 57obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
70obj-$(CONFIG_KGDB) += kgdb.o patch.o 58obj-$(CONFIG_KGDB) += kgdb.o patch.o
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 2f5555d307b3..672b21942fff 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -31,6 +31,7 @@
31 31
32#include "entry-header.S" 32#include "entry-header.S"
33#include <asm/entry-macro-multi.S> 33#include <asm/entry-macro-multi.S>
34#include <asm/probes.h>
34 35
35/* 36/*
36 * Interrupt handling. 37 * Interrupt handling.
@@ -249,7 +250,7 @@ __und_svc:
249 @ If a kprobe is about to simulate a "stmdb sp..." instruction, 250 @ If a kprobe is about to simulate a "stmdb sp..." instruction,
250 @ it obviously needs free stack space which then will belong to 251 @ it obviously needs free stack space which then will belong to
251 @ the saved context. 252 @ the saved context.
252 svc_entry 64 253 svc_entry MAX_STACK_SIZE
253#else 254#else
254 svc_entry 255 svc_entry
255#endif 256#endif
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index b8c75e45a950..709ee1d6d4df 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -20,8 +20,7 @@
20#include <asm/cacheflush.h> 20#include <asm/cacheflush.h>
21#include <asm/opcodes.h> 21#include <asm/opcodes.h>
22#include <asm/ftrace.h> 22#include <asm/ftrace.h>
23 23#include <asm/insn.h>
24#include "insn.h"
25 24
26#ifdef CONFIG_THUMB2_KERNEL 25#ifdef CONFIG_THUMB2_KERNEL
27#define NOP 0xf85deb04 /* pop.w {lr} */ 26#define NOP 0xf85deb04 /* pop.w {lr} */
diff --git a/arch/arm/kernel/jump_label.c b/arch/arm/kernel/jump_label.c
index afeeb9ea6f43..e39cbf488cfe 100644
--- a/arch/arm/kernel/jump_label.c
+++ b/arch/arm/kernel/jump_label.c
@@ -1,8 +1,7 @@
1#include <linux/kernel.h> 1#include <linux/kernel.h>
2#include <linux/jump_label.h> 2#include <linux/jump_label.h>
3 3#include <asm/patch.h>
4#include "insn.h" 4#include <asm/insn.h>
5#include "patch.h"
6 5
7#ifdef HAVE_JUMP_LABEL 6#ifdef HAVE_JUMP_LABEL
8 7
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
index 07db2f8a1b45..a6ad93c9bce3 100644
--- a/arch/arm/kernel/kgdb.c
+++ b/arch/arm/kernel/kgdb.c
@@ -14,10 +14,9 @@
14#include <linux/kgdb.h> 14#include <linux/kgdb.h>
15#include <linux/uaccess.h> 15#include <linux/uaccess.h>
16 16
17#include <asm/patch.h>
17#include <asm/traps.h> 18#include <asm/traps.h>
18 19
19#include "patch.h"
20
21struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = 20struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
22{ 21{
23 { "r0", 4, offsetof(struct pt_regs, ARM_r0)}, 22 { "r0", 4, offsetof(struct pt_regs, ARM_r0)},
diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
index 5038960e3c55..69bda1a5707e 100644
--- a/arch/arm/kernel/patch.c
+++ b/arch/arm/kernel/patch.c
@@ -8,8 +8,7 @@
8#include <asm/fixmap.h> 8#include <asm/fixmap.h>
9#include <asm/smp_plat.h> 9#include <asm/smp_plat.h>
10#include <asm/opcodes.h> 10#include <asm/opcodes.h>
11 11#include <asm/patch.h>
12#include "patch.h"
13 12
14struct patch { 13struct patch {
15 void *addr; 14 void *addr;
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index d13f185e7bd5..e55408e96559 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1049,6 +1049,15 @@ static int c_show(struct seq_file *m, void *v)
1049 seq_printf(m, "model name\t: %s rev %d (%s)\n", 1049 seq_printf(m, "model name\t: %s rev %d (%s)\n",
1050 cpu_name, cpuid & 15, elf_platform); 1050 cpu_name, cpuid & 15, elf_platform);
1051 1051
1052#if defined(CONFIG_SMP)
1053 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
1054 per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
1055 (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
1056#else
1057 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
1058 loops_per_jiffy / (500000/HZ),
1059 (loops_per_jiffy / (5000/HZ)) % 100);
1060#endif
1052 /* dump out the processor features */ 1061 /* dump out the processor features */
1053 seq_puts(m, "Features\t: "); 1062 seq_puts(m, "Features\t: ");
1054 1063
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 5e6052e18850..86ef244c5a24 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -387,6 +387,18 @@ asmlinkage void secondary_start_kernel(void)
387 387
388void __init smp_cpus_done(unsigned int max_cpus) 388void __init smp_cpus_done(unsigned int max_cpus)
389{ 389{
390 int cpu;
391 unsigned long bogosum = 0;
392
393 for_each_online_cpu(cpu)
394 bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy;
395
396 printk(KERN_INFO "SMP: Total of %d processors activated "
397 "(%lu.%02lu BogoMIPS).\n",
398 num_online_cpus(),
399 bogosum / (500000/HZ),
400 (bogosum / (5000/HZ)) % 100);
401
390 hyp_mode_check(); 402 hyp_mode_check();
391} 403}
392 404
diff --git a/arch/arm/probes/Makefile b/arch/arm/probes/Makefile
new file mode 100644
index 000000000000..aa1f8590dcdd
--- /dev/null
+++ b/arch/arm/probes/Makefile
@@ -0,0 +1,7 @@
1obj-$(CONFIG_UPROBES) += decode.o decode-arm.o uprobes/
2obj-$(CONFIG_KPROBES) += decode.o kprobes/
3ifdef CONFIG_THUMB2_KERNEL
4obj-$(CONFIG_KPROBES) += decode-thumb.o
5else
6obj-$(CONFIG_KPROBES) += decode-arm.o
7endif
diff --git a/arch/arm/kernel/probes-arm.c b/arch/arm/probes/decode-arm.c
index 8eaef81d8344..f72c33a2dcfb 100644
--- a/arch/arm/kernel/probes-arm.c
+++ b/arch/arm/probes/decode-arm.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * arch/arm/kernel/probes-arm.c 2 *
3 * arch/arm/probes/decode-arm.c
3 * 4 *
4 * Some code moved here from arch/arm/kernel/kprobes-arm.c 5 * Some code moved here from arch/arm/kernel/kprobes-arm.c
5 * 6 *
@@ -20,8 +21,8 @@
20#include <linux/stddef.h> 21#include <linux/stddef.h>
21#include <linux/ptrace.h> 22#include <linux/ptrace.h>
22 23
23#include "probes.h" 24#include "decode.h"
24#include "probes-arm.h" 25#include "decode-arm.h"
25 26
26#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit))))) 27#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
27 28
@@ -369,17 +370,17 @@ static const union decode_item arm_cccc_001x_table[] = {
369 370
370 /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */ 371 /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
371 /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */ 372 /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
372 DECODE_EMULATEX (0x0fb00000, 0x03000000, PROBES_DATA_PROCESSING_IMM, 373 DECODE_EMULATEX (0x0fb00000, 0x03000000, PROBES_MOV_HALFWORD,
373 REGS(0, NOPC, 0, 0, 0)), 374 REGS(0, NOPC, 0, 0, 0)),
374 375
375 /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */ 376 /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
376 DECODE_OR (0x0fff00ff, 0x03200001), 377 DECODE_OR (0x0fff00ff, 0x03200001),
377 /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */ 378 /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
378 DECODE_EMULATE (0x0fff00ff, 0x03200004, PROBES_EMULATE_NONE), 379 DECODE_EMULATE (0x0fff00ff, 0x03200004, PROBES_SEV),
379 /* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */ 380 /* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
380 /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */ 381 /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
381 /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */ 382 /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
382 DECODE_SIMULATE (0x0fff00fc, 0x03200000, PROBES_SIMULATE_NOP), 383 DECODE_SIMULATE (0x0fff00fc, 0x03200000, PROBES_WFE),
383 /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */ 384 /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */
384 /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */ 385 /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
385 /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */ 386 /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
@@ -725,10 +726,11 @@ static void __kprobes arm_singlestep(probes_opcode_t insn,
725 */ 726 */
726enum probes_insn __kprobes 727enum probes_insn __kprobes
727arm_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 728arm_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
728 bool emulate, const union decode_action *actions) 729 bool emulate, const union decode_action *actions,
730 const struct decode_checker *checkers[])
729{ 731{
730 asi->insn_singlestep = arm_singlestep; 732 asi->insn_singlestep = arm_singlestep;
731 asi->insn_check_cc = probes_condition_checks[insn>>28]; 733 asi->insn_check_cc = probes_condition_checks[insn>>28];
732 return probes_decode_insn(insn, asi, probes_decode_arm_table, false, 734 return probes_decode_insn(insn, asi, probes_decode_arm_table, false,
733 emulate, actions); 735 emulate, actions, checkers);
734} 736}
diff --git a/arch/arm/kernel/probes-arm.h b/arch/arm/probes/decode-arm.h
index ace6572f6e26..b3b80f6d414b 100644
--- a/arch/arm/kernel/probes-arm.h
+++ b/arch/arm/probes/decode-arm.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/probes-arm.h 2 * arch/arm/probes/decode-arm.h
3 * 3 *
4 * Copyright 2013 Linaro Ltd. 4 * Copyright 2013 Linaro Ltd.
5 * Written by: David A. Long 5 * Written by: David A. Long
@@ -15,9 +15,9 @@
15#ifndef _ARM_KERNEL_PROBES_ARM_H 15#ifndef _ARM_KERNEL_PROBES_ARM_H
16#define _ARM_KERNEL_PROBES_ARM_H 16#define _ARM_KERNEL_PROBES_ARM_H
17 17
18#include "decode.h"
19
18enum probes_arm_action { 20enum probes_arm_action {
19 PROBES_EMULATE_NONE,
20 PROBES_SIMULATE_NOP,
21 PROBES_PRELOAD_IMM, 21 PROBES_PRELOAD_IMM,
22 PROBES_PRELOAD_REG, 22 PROBES_PRELOAD_REG,
23 PROBES_BRANCH_IMM, 23 PROBES_BRANCH_IMM,
@@ -68,6 +68,7 @@ extern const union decode_item probes_decode_arm_table[];
68 68
69enum probes_insn arm_probes_decode_insn(probes_opcode_t, 69enum probes_insn arm_probes_decode_insn(probes_opcode_t,
70 struct arch_probes_insn *, bool emulate, 70 struct arch_probes_insn *, bool emulate,
71 const union decode_action *actions); 71 const union decode_action *actions,
72 const struct decode_checker *checkers[]);
72 73
73#endif 74#endif
diff --git a/arch/arm/kernel/probes-thumb.c b/arch/arm/probes/decode-thumb.c
index 4131351e812f..985e7dd4cac6 100644
--- a/arch/arm/kernel/probes-thumb.c
+++ b/arch/arm/probes/decode-thumb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/probes-thumb.c 2 * arch/arm/probes/decode-thumb.c
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -12,8 +12,8 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/module.h> 13#include <linux/module.h>
14 14
15#include "probes.h" 15#include "decode.h"
16#include "probes-thumb.h" 16#include "decode-thumb.h"
17 17
18 18
19static const union decode_item t32_table_1110_100x_x0xx[] = { 19static const union decode_item t32_table_1110_100x_x0xx[] = {
@@ -863,20 +863,22 @@ static void __kprobes thumb32_singlestep(probes_opcode_t opcode,
863 863
864enum probes_insn __kprobes 864enum probes_insn __kprobes
865thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 865thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
866 bool emulate, const union decode_action *actions) 866 bool emulate, const union decode_action *actions,
867 const struct decode_checker *checkers[])
867{ 868{
868 asi->insn_singlestep = thumb16_singlestep; 869 asi->insn_singlestep = thumb16_singlestep;
869 asi->insn_check_cc = thumb_check_cc; 870 asi->insn_check_cc = thumb_check_cc;
870 return probes_decode_insn(insn, asi, probes_decode_thumb16_table, true, 871 return probes_decode_insn(insn, asi, probes_decode_thumb16_table, true,
871 emulate, actions); 872 emulate, actions, checkers);
872} 873}
873 874
874enum probes_insn __kprobes 875enum probes_insn __kprobes
875thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 876thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
876 bool emulate, const union decode_action *actions) 877 bool emulate, const union decode_action *actions,
878 const struct decode_checker *checkers[])
877{ 879{
878 asi->insn_singlestep = thumb32_singlestep; 880 asi->insn_singlestep = thumb32_singlestep;
879 asi->insn_check_cc = thumb_check_cc; 881 asi->insn_check_cc = thumb_check_cc;
880 return probes_decode_insn(insn, asi, probes_decode_thumb32_table, true, 882 return probes_decode_insn(insn, asi, probes_decode_thumb32_table, true,
881 emulate, actions); 883 emulate, actions, checkers);
882} 884}
diff --git a/arch/arm/kernel/probes-thumb.h b/arch/arm/probes/decode-thumb.h
index 7c6f6ebe514f..8457add0a2d8 100644
--- a/arch/arm/kernel/probes-thumb.h
+++ b/arch/arm/probes/decode-thumb.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/probes-thumb.h 2 * arch/arm/probes/decode-thumb.h
3 * 3 *
4 * Copyright 2013 Linaro Ltd. 4 * Copyright 2013 Linaro Ltd.
5 * Written by: David A. Long 5 * Written by: David A. Long
@@ -15,6 +15,8 @@
15#ifndef _ARM_KERNEL_PROBES_THUMB_H 15#ifndef _ARM_KERNEL_PROBES_THUMB_H
16#define _ARM_KERNEL_PROBES_THUMB_H 16#define _ARM_KERNEL_PROBES_THUMB_H
17 17
18#include "decode.h"
19
18/* 20/*
19 * True if current instruction is in an IT block. 21 * True if current instruction is in an IT block.
20 */ 22 */
@@ -89,9 +91,11 @@ extern const union decode_item probes_decode_thumb16_table[];
89 91
90enum probes_insn __kprobes 92enum probes_insn __kprobes
91thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 93thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
92 bool emulate, const union decode_action *actions); 94 bool emulate, const union decode_action *actions,
95 const struct decode_checker *checkers[]);
93enum probes_insn __kprobes 96enum probes_insn __kprobes
94thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 97thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
95 bool emulate, const union decode_action *actions); 98 bool emulate, const union decode_action *actions,
99 const struct decode_checker *checkers[]);
96 100
97#endif 101#endif
diff --git a/arch/arm/kernel/probes.c b/arch/arm/probes/decode.c
index a8ab540d7e73..880ebe0cdf19 100644
--- a/arch/arm/kernel/probes.c
+++ b/arch/arm/probes/decode.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/probes.c 2 * arch/arm/probes/decode.c
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -17,7 +17,7 @@
17#include <asm/ptrace.h> 17#include <asm/ptrace.h>
18#include <linux/bug.h> 18#include <linux/bug.h>
19 19
20#include "probes.h" 20#include "decode.h"
21 21
22 22
23#ifndef find_str_pc_offset 23#ifndef find_str_pc_offset
@@ -342,6 +342,31 @@ static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
342 [DECODE_TYPE_REJECT] = sizeof(struct decode_reject) 342 [DECODE_TYPE_REJECT] = sizeof(struct decode_reject)
343}; 343};
344 344
345static int run_checkers(const struct decode_checker *checkers[],
346 int action, probes_opcode_t insn,
347 struct arch_probes_insn *asi,
348 const struct decode_header *h)
349{
350 const struct decode_checker **p;
351
352 if (!checkers)
353 return INSN_GOOD;
354
355 p = checkers;
356 while (*p != NULL) {
357 int retval;
358 probes_check_t *checker_func = (*p)[action].checker;
359
360 retval = INSN_GOOD;
361 if (checker_func)
362 retval = checker_func(insn, asi, h);
363 if (retval == INSN_REJECTED)
364 return retval;
365 p++;
366 }
367 return INSN_GOOD;
368}
369
345/* 370/*
346 * probes_decode_insn operates on data tables in order to decode an ARM 371 * probes_decode_insn operates on data tables in order to decode an ARM
347 * architecture instruction onto which a kprobe has been placed. 372 * architecture instruction onto which a kprobe has been placed.
@@ -388,11 +413,34 @@ static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
388int __kprobes 413int __kprobes
389probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 414probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
390 const union decode_item *table, bool thumb, 415 const union decode_item *table, bool thumb,
391 bool emulate, const union decode_action *actions) 416 bool emulate, const union decode_action *actions,
417 const struct decode_checker *checkers[])
392{ 418{
393 const struct decode_header *h = (struct decode_header *)table; 419 const struct decode_header *h = (struct decode_header *)table;
394 const struct decode_header *next; 420 const struct decode_header *next;
395 bool matched = false; 421 bool matched = false;
422 /*
423 * @insn can be modified by decode_regs. Save its original
424 * value for checkers.
425 */
426 probes_opcode_t origin_insn = insn;
427
428 /*
429 * stack_space is initialized to 0 here. Checker functions
430 * should update is value if they find this is a stack store
431 * instruction: positive value means bytes of stack usage,
432 * negitive value means unable to determine stack usage
433 * statically. For instruction doesn't store to stack, checker
434 * do nothing with it.
435 */
436 asi->stack_space = 0;
437
438 /*
439 * Similarly to stack_space, register_usage_flags is filled by
440 * checkers. Its default value is set to ~0, which is 'all
441 * registers are used', to prevent any potential optimization.
442 */
443 asi->register_usage_flags = ~0UL;
396 444
397 if (emulate) 445 if (emulate)
398 insn = prepare_emulated_insn(insn, asi, thumb); 446 insn = prepare_emulated_insn(insn, asi, thumb);
@@ -422,24 +470,41 @@ probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
422 } 470 }
423 471
424 case DECODE_TYPE_CUSTOM: { 472 case DECODE_TYPE_CUSTOM: {
473 int err;
425 struct decode_custom *d = (struct decode_custom *)h; 474 struct decode_custom *d = (struct decode_custom *)h;
426 return actions[d->decoder.action].decoder(insn, asi, h); 475 int action = d->decoder.action;
476
477 err = run_checkers(checkers, action, origin_insn, asi, h);
478 if (err == INSN_REJECTED)
479 return INSN_REJECTED;
480 return actions[action].decoder(insn, asi, h);
427 } 481 }
428 482
429 case DECODE_TYPE_SIMULATE: { 483 case DECODE_TYPE_SIMULATE: {
484 int err;
430 struct decode_simulate *d = (struct decode_simulate *)h; 485 struct decode_simulate *d = (struct decode_simulate *)h;
431 asi->insn_handler = actions[d->handler.action].handler; 486 int action = d->handler.action;
487
488 err = run_checkers(checkers, action, origin_insn, asi, h);
489 if (err == INSN_REJECTED)
490 return INSN_REJECTED;
491 asi->insn_handler = actions[action].handler;
432 return INSN_GOOD_NO_SLOT; 492 return INSN_GOOD_NO_SLOT;
433 } 493 }
434 494
435 case DECODE_TYPE_EMULATE: { 495 case DECODE_TYPE_EMULATE: {
496 int err;
436 struct decode_emulate *d = (struct decode_emulate *)h; 497 struct decode_emulate *d = (struct decode_emulate *)h;
498 int action = d->handler.action;
499
500 err = run_checkers(checkers, action, origin_insn, asi, h);
501 if (err == INSN_REJECTED)
502 return INSN_REJECTED;
437 503
438 if (!emulate) 504 if (!emulate)
439 return actions[d->handler.action].decoder(insn, 505 return actions[action].decoder(insn, asi, h);
440 asi, h);
441 506
442 asi->insn_handler = actions[d->handler.action].handler; 507 asi->insn_handler = actions[action].handler;
443 set_emulated_insn(insn, asi, thumb); 508 set_emulated_insn(insn, asi, thumb);
444 return INSN_GOOD; 509 return INSN_GOOD;
445 } 510 }
diff --git a/arch/arm/kernel/probes.h b/arch/arm/probes/decode.h
index dba9f2466a93..f9b08ba7fe73 100644
--- a/arch/arm/kernel/probes.h
+++ b/arch/arm/probes/decode.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/probes.h 2 * arch/arm/probes/decode.h
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -314,6 +314,14 @@ union decode_action {
314 probes_custom_decode_t *decoder; 314 probes_custom_decode_t *decoder;
315}; 315};
316 316
317typedef enum probes_insn (probes_check_t)(probes_opcode_t,
318 struct arch_probes_insn *,
319 const struct decode_header *);
320
321struct decode_checker {
322 probes_check_t *checker;
323};
324
317#define DECODE_END \ 325#define DECODE_END \
318 {.bits = DECODE_TYPE_END} 326 {.bits = DECODE_TYPE_END}
319 327
@@ -402,6 +410,7 @@ probes_insn_handler_t probes_emulate_none;
402int __kprobes 410int __kprobes
403probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 411probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
404 const union decode_item *table, bool thumb, bool emulate, 412 const union decode_item *table, bool thumb, bool emulate,
405 const union decode_action *actions); 413 const union decode_action *actions,
414 const struct decode_checker **checkers);
406 415
407#endif 416#endif
diff --git a/arch/arm/probes/kprobes/Makefile b/arch/arm/probes/kprobes/Makefile
new file mode 100644
index 000000000000..76a36bf102b7
--- /dev/null
+++ b/arch/arm/probes/kprobes/Makefile
@@ -0,0 +1,12 @@
1obj-$(CONFIG_KPROBES) += core.o actions-common.o checkers-common.o
2obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o
3test-kprobes-objs := test-core.o
4
5ifdef CONFIG_THUMB2_KERNEL
6obj-$(CONFIG_KPROBES) += actions-thumb.o checkers-thumb.o
7test-kprobes-objs += test-thumb.o
8else
9obj-$(CONFIG_KPROBES) += actions-arm.o checkers-arm.o
10obj-$(CONFIG_OPTPROBES) += opt-arm.o
11test-kprobes-objs += test-arm.o
12endif
diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/probes/kprobes/actions-arm.c
index ac300c60d656..b9056d649607 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/probes/kprobes/actions-arm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/kprobes-decode.c 2 * arch/arm/probes/kprobes/actions-arm.c
3 * 3 *
4 * Copyright (C) 2006, 2007 Motorola Inc. 4 * Copyright (C) 2006, 2007 Motorola Inc.
5 * 5 *
@@ -62,8 +62,9 @@
62#include <linux/kprobes.h> 62#include <linux/kprobes.h>
63#include <linux/ptrace.h> 63#include <linux/ptrace.h>
64 64
65#include "kprobes.h" 65#include "../decode-arm.h"
66#include "probes-arm.h" 66#include "core.h"
67#include "checkers.h"
67 68
68#if __LINUX_ARM_ARCH__ >= 6 69#if __LINUX_ARM_ARCH__ >= 6
69#define BLX(reg) "blx "reg" \n\t" 70#define BLX(reg) "blx "reg" \n\t"
@@ -302,8 +303,6 @@ emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(probes_opcode_t insn,
302} 303}
303 304
304const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = { 305const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
305 [PROBES_EMULATE_NONE] = {.handler = probes_emulate_none},
306 [PROBES_SIMULATE_NOP] = {.handler = probes_simulate_nop},
307 [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop}, 306 [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
308 [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop}, 307 [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
309 [PROBES_BRANCH_IMM] = {.handler = simulate_blx1}, 308 [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
@@ -341,3 +340,5 @@ const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
341 [PROBES_BRANCH] = {.handler = simulate_bbl}, 340 [PROBES_BRANCH] = {.handler = simulate_bbl},
342 [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm} 341 [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm}
343}; 342};
343
344const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker, arm_regs_checker, NULL};
diff --git a/arch/arm/kernel/kprobes-common.c b/arch/arm/probes/kprobes/actions-common.c
index 0bf5d64eba1d..bd20a71cd34a 100644
--- a/arch/arm/kernel/kprobes-common.c
+++ b/arch/arm/probes/kprobes/actions-common.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/kprobes-common.c 2 * arch/arm/probes/kprobes/actions-common.c
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -15,7 +15,7 @@
15#include <linux/kprobes.h> 15#include <linux/kprobes.h>
16#include <asm/opcodes.h> 16#include <asm/opcodes.h>
17 17
18#include "kprobes.h" 18#include "core.h"
19 19
20 20
21static void __kprobes simulate_ldm1stm1(probes_opcode_t insn, 21static void __kprobes simulate_ldm1stm1(probes_opcode_t insn,
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/probes/kprobes/actions-thumb.c
index 9495d7f3516f..07cfd9bef340 100644
--- a/arch/arm/kernel/kprobes-thumb.c
+++ b/arch/arm/probes/kprobes/actions-thumb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/kprobes-thumb.c 2 * arch/arm/probes/kprobes/actions-thumb.c
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -13,8 +13,9 @@
13#include <linux/ptrace.h> 13#include <linux/ptrace.h>
14#include <linux/kprobes.h> 14#include <linux/kprobes.h>
15 15
16#include "kprobes.h" 16#include "../decode-thumb.h"
17#include "probes-thumb.h" 17#include "core.h"
18#include "checkers.h"
18 19
19/* These emulation encodings are functionally equivalent... */ 20/* These emulation encodings are functionally equivalent... */
20#define t32_emulate_rd8rn16rm0ra12_noflags \ 21#define t32_emulate_rd8rn16rm0ra12_noflags \
@@ -664,3 +665,6 @@ const union decode_action kprobes_t32_actions[NUM_PROBES_T32_ACTIONS] = {
664 [PROBES_T32_MUL_ADD_LONG] = { 665 [PROBES_T32_MUL_ADD_LONG] = {
665 .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags}, 666 .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags},
666}; 667};
668
669const struct decode_checker *kprobes_t32_checkers[] = {t32_stack_checker, NULL};
670const struct decode_checker *kprobes_t16_checkers[] = {t16_stack_checker, NULL};
diff --git a/arch/arm/probes/kprobes/checkers-arm.c b/arch/arm/probes/kprobes/checkers-arm.c
new file mode 100644
index 000000000000..7b9817333b68
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers-arm.c
@@ -0,0 +1,192 @@
1/*
2 * arch/arm/probes/kprobes/checkers-arm.c
3 *
4 * Copyright (C) 2014 Huawei Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include "../decode.h"
18#include "../decode-arm.h"
19#include "checkers.h"
20
21static enum probes_insn __kprobes arm_check_stack(probes_opcode_t insn,
22 struct arch_probes_insn *asi,
23 const struct decode_header *h)
24{
25 /*
26 * PROBES_LDRSTRD, PROBES_LDMSTM, PROBES_STORE,
27 * PROBES_STORE_EXTRA may get here. Simply mark all normal
28 * insns as STACK_USE_NONE.
29 */
30 static const union decode_item table[] = {
31 /*
32 * 'STR{,D,B,H}, Rt, [Rn, Rm]' should be marked as UNKNOWN
33 * if Rn or Rm is SP.
34 * x
35 * STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx
36 * STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx
37 */
38 DECODE_OR (0x0e10000f, 0x0600000d),
39 DECODE_OR (0x0e1f0000, 0x060d0000),
40
41 /*
42 * x
43 * STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx
44 * STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx
45 */
46 DECODE_OR (0x0e5000bf, 0x000000bd),
47 DECODE_CUSTOM (0x0e5f00b0, 0x000d00b0, STACK_USE_UNKNOWN),
48
49 /*
50 * For PROBES_LDMSTM, only stmdx sp, [...] need to examine
51 *
52 * Bit B/A (bit 24) encodes arithmetic operation order. 1 means
53 * before, 0 means after.
54 * Bit I/D (bit 23) encodes arithmetic operation. 1 means
55 * increment, 0 means decrement.
56 *
57 * So:
58 * B I
59 * / /
60 * A D | Rn |
61 * STMDX SP, [...] cccc 100x 00x0 xxxx xxxx xxxx xxxx xxxx
62 */
63 DECODE_CUSTOM (0x0edf0000, 0x080d0000, STACK_USE_STMDX),
64
65 /* P U W | Rn | Rt | imm12 |*/
66 /* STR (immediate) cccc 010x x0x0 1101 xxxx xxxx xxxx xxxx */
67 /* STRB (immediate) cccc 010x x1x0 1101 xxxx xxxx xxxx xxxx */
68 /* P U W | Rn | Rt |imm4| |imm4|*/
69 /* STRD (immediate) cccc 000x x1x0 1101 xxxx xxxx 1111 xxxx */
70 /* STRH (immediate) cccc 000x x1x0 1101 xxxx xxxx 1011 xxxx */
71 /*
72 * index = (P == '1'); add = (U == '1').
73 * Above insns with:
74 * index == 0 (str{,d,h} rx, [sp], #+/-imm) or
75 * add == 1 (str{,d,h} rx, [sp, #+<imm>])
76 * should be STACK_USE_NONE.
77 * Only str{,b,d,h} rx,[sp,#-n] (P == 1 and U == 0) are
78 * required to be examined.
79 */
80 /* STR{,B} Rt,[SP,#-n] cccc 0101 0xx0 1101 xxxx xxxx xxxx xxxx */
81 DECODE_CUSTOM (0x0f9f0000, 0x050d0000, STACK_USE_FIXED_XXX),
82
83 /* STR{D,H} Rt,[SP,#-n] cccc 0001 01x0 1101 xxxx xxxx 1x11 xxxx */
84 DECODE_CUSTOM (0x0fdf00b0, 0x014d00b0, STACK_USE_FIXED_X0X),
85
86 /* fall through */
87 DECODE_CUSTOM (0, 0, STACK_USE_NONE),
88 DECODE_END
89 };
90
91 return probes_decode_insn(insn, asi, table, false, false, stack_check_actions, NULL);
92}
93
94const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = {
95 [PROBES_LDRSTRD] = {.checker = arm_check_stack},
96 [PROBES_STORE_EXTRA] = {.checker = arm_check_stack},
97 [PROBES_STORE] = {.checker = arm_check_stack},
98 [PROBES_LDMSTM] = {.checker = arm_check_stack},
99};
100
101static enum probes_insn __kprobes arm_check_regs_nouse(probes_opcode_t insn,
102 struct arch_probes_insn *asi,
103 const struct decode_header *h)
104{
105 asi->register_usage_flags = 0;
106 return INSN_GOOD;
107}
108
109static enum probes_insn arm_check_regs_normal(probes_opcode_t insn,
110 struct arch_probes_insn *asi,
111 const struct decode_header *h)
112{
113 u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS;
114 int i;
115
116 asi->register_usage_flags = 0;
117 for (i = 0; i < 5; regs >>= 4, insn >>= 4, i++)
118 if (regs & 0xf)
119 asi->register_usage_flags |= 1 << (insn & 0xf);
120
121 return INSN_GOOD;
122}
123
124
125static enum probes_insn arm_check_regs_ldmstm(probes_opcode_t insn,
126 struct arch_probes_insn *asi,
127 const struct decode_header *h)
128{
129 unsigned int reglist = insn & 0xffff;
130 unsigned int rn = (insn >> 16) & 0xf;
131 asi->register_usage_flags = reglist | (1 << rn);
132 return INSN_GOOD;
133}
134
135static enum probes_insn arm_check_regs_mov_ip_sp(probes_opcode_t insn,
136 struct arch_probes_insn *asi,
137 const struct decode_header *h)
138{
139 /* Instruction is 'mov ip, sp' i.e. 'mov r12, r13' */
140 asi->register_usage_flags = (1 << 12) | (1<< 13);
141 return INSN_GOOD;
142}
143
144/*
145 * | Rn |Rt/d| | Rm |
146 * LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx
147 * STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx
148 * | Rn |Rt/d| |imm4L|
149 * LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx
150 * STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx
151 *
152 * Such instructions access Rt/d and its next register, so different
153 * from others, a specific checker is required to handle this extra
154 * implicit register usage.
155 */
156static enum probes_insn arm_check_regs_ldrdstrd(probes_opcode_t insn,
157 struct arch_probes_insn *asi,
158 const struct decode_header *h)
159{
160 int rdt = (insn >> 12) & 0xf;
161 arm_check_regs_normal(insn, asi, h);
162 asi->register_usage_flags |= 1 << (rdt + 1);
163 return INSN_GOOD;
164}
165
166
167const struct decode_checker arm_regs_checker[NUM_PROBES_ARM_ACTIONS] = {
168 [PROBES_MRS] = {.checker = arm_check_regs_normal},
169 [PROBES_SATURATING_ARITHMETIC] = {.checker = arm_check_regs_normal},
170 [PROBES_MUL1] = {.checker = arm_check_regs_normal},
171 [PROBES_MUL2] = {.checker = arm_check_regs_normal},
172 [PROBES_MUL_ADD_LONG] = {.checker = arm_check_regs_normal},
173 [PROBES_MUL_ADD] = {.checker = arm_check_regs_normal},
174 [PROBES_LOAD] = {.checker = arm_check_regs_normal},
175 [PROBES_LOAD_EXTRA] = {.checker = arm_check_regs_normal},
176 [PROBES_STORE] = {.checker = arm_check_regs_normal},
177 [PROBES_STORE_EXTRA] = {.checker = arm_check_regs_normal},
178 [PROBES_DATA_PROCESSING_REG] = {.checker = arm_check_regs_normal},
179 [PROBES_DATA_PROCESSING_IMM] = {.checker = arm_check_regs_normal},
180 [PROBES_SEV] = {.checker = arm_check_regs_nouse},
181 [PROBES_WFE] = {.checker = arm_check_regs_nouse},
182 [PROBES_SATURATE] = {.checker = arm_check_regs_normal},
183 [PROBES_REV] = {.checker = arm_check_regs_normal},
184 [PROBES_MMI] = {.checker = arm_check_regs_normal},
185 [PROBES_PACK] = {.checker = arm_check_regs_normal},
186 [PROBES_EXTEND] = {.checker = arm_check_regs_normal},
187 [PROBES_EXTEND_ADD] = {.checker = arm_check_regs_normal},
188 [PROBES_BITFIELD] = {.checker = arm_check_regs_normal},
189 [PROBES_LDMSTM] = {.checker = arm_check_regs_ldmstm},
190 [PROBES_MOV_IP_SP] = {.checker = arm_check_regs_mov_ip_sp},
191 [PROBES_LDRSTRD] = {.checker = arm_check_regs_ldrdstrd},
192};
diff --git a/arch/arm/probes/kprobes/checkers-common.c b/arch/arm/probes/kprobes/checkers-common.c
new file mode 100644
index 000000000000..971119c29474
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers-common.c
@@ -0,0 +1,101 @@
1/*
2 * arch/arm/probes/kprobes/checkers-common.c
3 *
4 * Copyright (C) 2014 Huawei Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include "../decode.h"
18#include "../decode-arm.h"
19#include "checkers.h"
20
21enum probes_insn checker_stack_use_none(probes_opcode_t insn,
22 struct arch_probes_insn *asi,
23 const struct decode_header *h)
24{
25 asi->stack_space = 0;
26 return INSN_GOOD_NO_SLOT;
27}
28
29enum probes_insn checker_stack_use_unknown(probes_opcode_t insn,
30 struct arch_probes_insn *asi,
31 const struct decode_header *h)
32{
33 asi->stack_space = -1;
34 return INSN_GOOD_NO_SLOT;
35}
36
37#ifdef CONFIG_THUMB2_KERNEL
38enum probes_insn checker_stack_use_imm_0xx(probes_opcode_t insn,
39 struct arch_probes_insn *asi,
40 const struct decode_header *h)
41{
42 int imm = insn & 0xff;
43 asi->stack_space = imm;
44 return INSN_GOOD_NO_SLOT;
45}
46
47/*
48 * Different from other insn uses imm8, the real addressing offset of
49 * STRD in T32 encoding should be imm8 * 4. See ARMARM description.
50 */
51enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn,
52 struct arch_probes_insn *asi,
53 const struct decode_header *h)
54{
55 int imm = insn & 0xff;
56 asi->stack_space = imm << 2;
57 return INSN_GOOD_NO_SLOT;
58}
59#else
60enum probes_insn checker_stack_use_imm_x0x(probes_opcode_t insn,
61 struct arch_probes_insn *asi,
62 const struct decode_header *h)
63{
64 int imm = ((insn & 0xf00) >> 4) + (insn & 0xf);
65 asi->stack_space = imm;
66 return INSN_GOOD_NO_SLOT;
67}
68#endif
69
70enum probes_insn checker_stack_use_imm_xxx(probes_opcode_t insn,
71 struct arch_probes_insn *asi,
72 const struct decode_header *h)
73{
74 int imm = insn & 0xfff;
75 asi->stack_space = imm;
76 return INSN_GOOD_NO_SLOT;
77}
78
79enum probes_insn checker_stack_use_stmdx(probes_opcode_t insn,
80 struct arch_probes_insn *asi,
81 const struct decode_header *h)
82{
83 unsigned int reglist = insn & 0xffff;
84 int pbit = insn & (1 << 24);
85 asi->stack_space = (hweight32(reglist) - (!pbit ? 1 : 0)) * 4;
86
87 return INSN_GOOD_NO_SLOT;
88}
89
90const union decode_action stack_check_actions[] = {
91 [STACK_USE_NONE] = {.decoder = checker_stack_use_none},
92 [STACK_USE_UNKNOWN] = {.decoder = checker_stack_use_unknown},
93#ifdef CONFIG_THUMB2_KERNEL
94 [STACK_USE_FIXED_0XX] = {.decoder = checker_stack_use_imm_0xx},
95 [STACK_USE_T32STRD] = {.decoder = checker_stack_use_t32strd},
96#else
97 [STACK_USE_FIXED_X0X] = {.decoder = checker_stack_use_imm_x0x},
98#endif
99 [STACK_USE_FIXED_XXX] = {.decoder = checker_stack_use_imm_xxx},
100 [STACK_USE_STMDX] = {.decoder = checker_stack_use_stmdx},
101};
diff --git a/arch/arm/probes/kprobes/checkers-thumb.c b/arch/arm/probes/kprobes/checkers-thumb.c
new file mode 100644
index 000000000000..d608e3b9017a
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers-thumb.c
@@ -0,0 +1,110 @@
1/*
2 * arch/arm/probes/kprobes/checkers-thumb.c
3 *
4 * Copyright (C) 2014 Huawei Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include "../decode.h"
18#include "../decode-thumb.h"
19#include "checkers.h"
20
21static enum probes_insn __kprobes t32_check_stack(probes_opcode_t insn,
22 struct arch_probes_insn *asi,
23 const struct decode_header *h)
24{
25 /*
26 * PROBES_T32_LDMSTM, PROBES_T32_LDRDSTRD and PROBES_T32_LDRSTR
27 * may get here. Simply mark all normal insns as STACK_USE_NONE.
28 */
29 static const union decode_item table[] = {
30
31 /*
32 * First, filter out all ldr insns to make our life easier.
33 * Following load insns may come here:
34 * LDM, LDRD, LDR.
35 * In T32 encoding, bit 20 is enough for distinguishing
36 * load and store. All load insns have this bit set, when
37 * all store insns have this bit clear.
38 */
39 DECODE_CUSTOM (0x00100000, 0x00100000, STACK_USE_NONE),
40
41 /*
42 * Mark all 'STR{,B,H}, Rt, [Rn, Rm]' as STACK_USE_UNKNOWN
43 * if Rn or Rm is SP. T32 doesn't encode STRD.
44 */
45 /* xx | Rn | Rt | | Rm |*/
46 /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */
47 /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */
48 /* STRH (register) 1111 1000 0010 xxxx xxxx 0000 00xx xxxx */
49 /* INVALID INSN 1111 1000 0110 xxxx xxxx 0000 00xx xxxx */
50 /* By Introducing INVALID INSN, bit 21 and 22 can be ignored. */
51 DECODE_OR (0xff9f0fc0, 0xf80d0000),
52 DECODE_CUSTOM (0xff900fcf, 0xf800000d, STACK_USE_UNKNOWN),
53
54
55 /* xx | Rn | Rt | PUW| imm8 |*/
56 /* STR (imm 8) 1111 1000 0100 1101 xxxx 110x xxxx xxxx */
57 /* STRB (imm 8) 1111 1000 0000 1101 xxxx 110x xxxx xxxx */
58 /* STRH (imm 8) 1111 1000 0010 1101 xxxx 110x xxxx xxxx */
59 /* INVALID INSN 1111 1000 0110 1101 xxxx 110x xxxx xxxx */
60 /* Only consider U == 0 and P == 1: strx rx, [sp, #-<imm>] */
61 DECODE_CUSTOM (0xff9f0e00, 0xf80d0c00, STACK_USE_FIXED_0XX),
62
63 /* For STR{,B,H} (imm 12), offset is always positive, so ignore them. */
64
65 /* P U W | Rn | Rt | Rt2| imm8 |*/
66 /* STRD (immediate) 1110 1001 01x0 1101 xxxx xxxx xxxx xxxx */
67 /*
68 * Only consider U == 0 and P == 1.
69 * Also note that STRD in T32 encoding is special:
70 * imm = ZeroExtend(imm8:'00', 32)
71 */
72 DECODE_CUSTOM (0xffdf0000, 0xe94d0000, STACK_USE_T32STRD),
73
74 /* | Rn | */
75 /* STMDB 1110 1001 00x0 1101 xxxx xxxx xxxx xxxx */
76 DECODE_CUSTOM (0xffdf0000, 0xe90d0000, STACK_USE_STMDX),
77
78 /* fall through */
79 DECODE_CUSTOM (0, 0, STACK_USE_NONE),
80 DECODE_END
81 };
82
83 return probes_decode_insn(insn, asi, table, false, false, stack_check_actions, NULL);
84}
85
86const struct decode_checker t32_stack_checker[NUM_PROBES_T32_ACTIONS] = {
87 [PROBES_T32_LDMSTM] = {.checker = t32_check_stack},
88 [PROBES_T32_LDRDSTRD] = {.checker = t32_check_stack},
89 [PROBES_T32_LDRSTR] = {.checker = t32_check_stack},
90};
91
92/*
93 * See following comments. This insn must be 'push'.
94 */
95static enum probes_insn __kprobes t16_check_stack(probes_opcode_t insn,
96 struct arch_probes_insn *asi,
97 const struct decode_header *h)
98{
99 unsigned int reglist = insn & 0x1ff;
100 asi->stack_space = hweight32(reglist) * 4;
101 return INSN_GOOD;
102}
103
104/*
105 * T16 encoding is simple: only the 'push' insn can need extra stack space.
106 * Other insns, like str, can only use r0-r7 as Rn.
107 */
108const struct decode_checker t16_stack_checker[NUM_PROBES_T16_ACTIONS] = {
109 [PROBES_T16_PUSH] = {.checker = t16_check_stack},
110};
diff --git a/arch/arm/probes/kprobes/checkers.h b/arch/arm/probes/kprobes/checkers.h
new file mode 100644
index 000000000000..cf6c9e74d666
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers.h
@@ -0,0 +1,55 @@
1/*
2 * arch/arm/probes/kprobes/checkers.h
3 *
4 * Copyright (C) 2014 Huawei Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15#ifndef _ARM_KERNEL_PROBES_CHECKERS_H
16#define _ARM_KERNEL_PROBES_CHECKERS_H
17
18#include <linux/kernel.h>
19#include <linux/types.h>
20#include "../decode.h"
21
22extern probes_check_t checker_stack_use_none;
23extern probes_check_t checker_stack_use_unknown;
24#ifdef CONFIG_THUMB2_KERNEL
25extern probes_check_t checker_stack_use_imm_0xx;
26#else
27extern probes_check_t checker_stack_use_imm_x0x;
28#endif
29extern probes_check_t checker_stack_use_imm_xxx;
30extern probes_check_t checker_stack_use_stmdx;
31
32enum {
33 STACK_USE_NONE,
34 STACK_USE_UNKNOWN,
35#ifdef CONFIG_THUMB2_KERNEL
36 STACK_USE_FIXED_0XX,
37 STACK_USE_T32STRD,
38#else
39 STACK_USE_FIXED_X0X,
40#endif
41 STACK_USE_FIXED_XXX,
42 STACK_USE_STMDX,
43 NUM_STACK_USE_TYPES
44};
45
46extern const union decode_action stack_check_actions[];
47
48#ifndef CONFIG_THUMB2_KERNEL
49extern const struct decode_checker arm_stack_checker[];
50extern const struct decode_checker arm_regs_checker[];
51#else
52#endif
53extern const struct decode_checker t32_stack_checker[];
54extern const struct decode_checker t16_stack_checker[];
55#endif
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/probes/kprobes/core.c
index 6d644202c8dc..a4ec240ee7ba 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/probes/kprobes/core.c
@@ -30,11 +30,11 @@
30#include <asm/cacheflush.h> 30#include <asm/cacheflush.h>
31#include <linux/percpu.h> 31#include <linux/percpu.h>
32#include <linux/bug.h> 32#include <linux/bug.h>
33#include <asm/patch.h>
33 34
34#include "kprobes.h" 35#include "../decode-arm.h"
35#include "probes-arm.h" 36#include "../decode-thumb.h"
36#include "probes-thumb.h" 37#include "core.h"
37#include "patch.h"
38 38
39#define MIN_STACK_SIZE(addr) \ 39#define MIN_STACK_SIZE(addr) \
40 min((unsigned long)MAX_STACK_SIZE, \ 40 min((unsigned long)MAX_STACK_SIZE, \
@@ -61,6 +61,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
61 kprobe_decode_insn_t *decode_insn; 61 kprobe_decode_insn_t *decode_insn;
62 const union decode_action *actions; 62 const union decode_action *actions;
63 int is; 63 int is;
64 const struct decode_checker **checkers;
64 65
65 if (in_exception_text(addr)) 66 if (in_exception_text(addr))
66 return -EINVAL; 67 return -EINVAL;
@@ -74,9 +75,11 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
74 insn = __opcode_thumb32_compose(insn, inst2); 75 insn = __opcode_thumb32_compose(insn, inst2);
75 decode_insn = thumb32_probes_decode_insn; 76 decode_insn = thumb32_probes_decode_insn;
76 actions = kprobes_t32_actions; 77 actions = kprobes_t32_actions;
78 checkers = kprobes_t32_checkers;
77 } else { 79 } else {
78 decode_insn = thumb16_probes_decode_insn; 80 decode_insn = thumb16_probes_decode_insn;
79 actions = kprobes_t16_actions; 81 actions = kprobes_t16_actions;
82 checkers = kprobes_t16_checkers;
80 } 83 }
81#else /* !CONFIG_THUMB2_KERNEL */ 84#else /* !CONFIG_THUMB2_KERNEL */
82 thumb = false; 85 thumb = false;
@@ -85,12 +88,13 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
85 insn = __mem_to_opcode_arm(*p->addr); 88 insn = __mem_to_opcode_arm(*p->addr);
86 decode_insn = arm_probes_decode_insn; 89 decode_insn = arm_probes_decode_insn;
87 actions = kprobes_arm_actions; 90 actions = kprobes_arm_actions;
91 checkers = kprobes_arm_checkers;
88#endif 92#endif
89 93
90 p->opcode = insn; 94 p->opcode = insn;
91 p->ainsn.insn = tmp_insn; 95 p->ainsn.insn = tmp_insn;
92 96
93 switch ((*decode_insn)(insn, &p->ainsn, true, actions)) { 97 switch ((*decode_insn)(insn, &p->ainsn, true, actions, checkers)) {
94 case INSN_REJECTED: /* not supported */ 98 case INSN_REJECTED: /* not supported */
95 return -EINVAL; 99 return -EINVAL;
96 100
@@ -111,6 +115,15 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
111 break; 115 break;
112 } 116 }
113 117
118 /*
119 * Never instrument insn like 'str r0, [sp, +/-r1]'. Also, insn likes
120 * 'str r0, [sp, #-68]' should also be prohibited.
121 * See __und_svc.
122 */
123 if ((p->ainsn.stack_space < 0) ||
124 (p->ainsn.stack_space > MAX_STACK_SIZE))
125 return -EINVAL;
126
114 return 0; 127 return 0;
115} 128}
116 129
@@ -150,19 +163,31 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
150 * memory. It is also needed to atomically set the two half-words of a 32-bit 163 * memory. It is also needed to atomically set the two half-words of a 32-bit
151 * Thumb breakpoint. 164 * Thumb breakpoint.
152 */ 165 */
153int __kprobes __arch_disarm_kprobe(void *p) 166struct patch {
154{ 167 void *addr;
155 struct kprobe *kp = p; 168 unsigned int insn;
156 void *addr = (void *)((uintptr_t)kp->addr & ~1); 169};
157
158 __patch_text(addr, kp->opcode);
159 170
171static int __kprobes_remove_breakpoint(void *data)
172{
173 struct patch *p = data;
174 __patch_text(p->addr, p->insn);
160 return 0; 175 return 0;
161} 176}
162 177
178void __kprobes kprobes_remove_breakpoint(void *addr, unsigned int insn)
179{
180 struct patch p = {
181 .addr = addr,
182 .insn = insn,
183 };
184 stop_machine(__kprobes_remove_breakpoint, &p, cpu_online_mask);
185}
186
163void __kprobes arch_disarm_kprobe(struct kprobe *p) 187void __kprobes arch_disarm_kprobe(struct kprobe *p)
164{ 188{
165 stop_machine(__arch_disarm_kprobe, p, cpu_online_mask); 189 kprobes_remove_breakpoint((void *)((uintptr_t)p->addr & ~1),
190 p->opcode);
166} 191}
167 192
168void __kprobes arch_remove_kprobe(struct kprobe *p) 193void __kprobes arch_remove_kprobe(struct kprobe *p)
diff --git a/arch/arm/kernel/kprobes.h b/arch/arm/probes/kprobes/core.h
index 9a2712ecefc3..ec5d1f20a085 100644
--- a/arch/arm/kernel/kprobes.h
+++ b/arch/arm/probes/kprobes/core.h
@@ -19,7 +19,8 @@
19#ifndef _ARM_KERNEL_KPROBES_H 19#ifndef _ARM_KERNEL_KPROBES_H
20#define _ARM_KERNEL_KPROBES_H 20#define _ARM_KERNEL_KPROBES_H
21 21
22#include "probes.h" 22#include <asm/kprobes.h>
23#include "../decode.h"
23 24
24/* 25/*
25 * These undefined instructions must be unique and 26 * These undefined instructions must be unique and
@@ -29,6 +30,8 @@
29#define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18 30#define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18
30#define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018 31#define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018
31 32
33extern void kprobes_remove_breakpoint(void *addr, unsigned int insn);
34
32enum probes_insn __kprobes 35enum probes_insn __kprobes
33kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_probes_insn *asi, 36kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_probes_insn *asi,
34 const struct decode_header *h); 37 const struct decode_header *h);
@@ -36,16 +39,19 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_probes_insn *asi,
36typedef enum probes_insn (kprobe_decode_insn_t)(probes_opcode_t, 39typedef enum probes_insn (kprobe_decode_insn_t)(probes_opcode_t,
37 struct arch_probes_insn *, 40 struct arch_probes_insn *,
38 bool, 41 bool,
39 const union decode_action *); 42 const union decode_action *,
43 const struct decode_checker *[]);
40 44
41#ifdef CONFIG_THUMB2_KERNEL 45#ifdef CONFIG_THUMB2_KERNEL
42 46
43extern const union decode_action kprobes_t32_actions[]; 47extern const union decode_action kprobes_t32_actions[];
44extern const union decode_action kprobes_t16_actions[]; 48extern const union decode_action kprobes_t16_actions[];
45 49extern const struct decode_checker *kprobes_t32_checkers[];
50extern const struct decode_checker *kprobes_t16_checkers[];
46#else /* !CONFIG_THUMB2_KERNEL */ 51#else /* !CONFIG_THUMB2_KERNEL */
47 52
48extern const union decode_action kprobes_arm_actions[]; 53extern const union decode_action kprobes_arm_actions[];
54extern const struct decode_checker *kprobes_arm_checkers[];
49 55
50#endif 56#endif
51 57
diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c
new file mode 100644
index 000000000000..bcdecc25461b
--- /dev/null
+++ b/arch/arm/probes/kprobes/opt-arm.c
@@ -0,0 +1,370 @@
1/*
2 * Kernel Probes Jump Optimization (Optprobes)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * Copyright (C) IBM Corporation, 2002, 2004
19 * Copyright (C) Hitachi Ltd., 2012
20 * Copyright (C) Huawei Inc., 2014
21 */
22
23#include <linux/kprobes.h>
24#include <linux/jump_label.h>
25#include <asm/kprobes.h>
26#include <asm/cacheflush.h>
27/* for arm_gen_branch */
28#include <asm/insn.h>
29/* for patch_text */
30#include <asm/patch.h>
31
32#include "core.h"
33
34/*
35 * See register_usage_flags. If the probed instruction doesn't use PC,
36 * we can copy it into template and have it executed directly without
37 * simulation or emulation.
38 */
39#define ARM_REG_PC 15
40#define can_kprobe_direct_exec(m) (!test_bit(ARM_REG_PC, &(m)))
41
42/*
43 * NOTE: the first sub and add instruction will be modified according
44 * to the stack cost of the instruction.
45 */
46asm (
47 ".global optprobe_template_entry\n"
48 "optprobe_template_entry:\n"
49 ".global optprobe_template_sub_sp\n"
50 "optprobe_template_sub_sp:"
51 " sub sp, sp, #0xff\n"
52 " stmia sp, {r0 - r14} \n"
53 ".global optprobe_template_add_sp\n"
54 "optprobe_template_add_sp:"
55 " add r3, sp, #0xff\n"
56 " str r3, [sp, #52]\n"
57 " mrs r4, cpsr\n"
58 " str r4, [sp, #64]\n"
59 " mov r1, sp\n"
60 " ldr r0, 1f\n"
61 " ldr r2, 2f\n"
62 /*
63 * AEABI requires an 8-bytes alignment stack. If
64 * SP % 8 != 0 (SP % 4 == 0 should be ensured),
65 * alloc more bytes here.
66 */
67 " and r4, sp, #4\n"
68 " sub sp, sp, r4\n"
69#if __LINUX_ARM_ARCH__ >= 5
70 " blx r2\n"
71#else
72 " mov lr, pc\n"
73 " mov pc, r2\n"
74#endif
75 " add sp, sp, r4\n"
76 " ldr r1, [sp, #64]\n"
77 " tst r1, #"__stringify(PSR_T_BIT)"\n"
78 " ldrne r2, [sp, #60]\n"
79 " orrne r2, #1\n"
80 " strne r2, [sp, #60] @ set bit0 of PC for thumb\n"
81 " msr cpsr_cxsf, r1\n"
82 ".global optprobe_template_restore_begin\n"
83 "optprobe_template_restore_begin:\n"
84 " ldmia sp, {r0 - r15}\n"
85 ".global optprobe_template_restore_orig_insn\n"
86 "optprobe_template_restore_orig_insn:\n"
87 " nop\n"
88 ".global optprobe_template_restore_end\n"
89 "optprobe_template_restore_end:\n"
90 " nop\n"
91 ".global optprobe_template_val\n"
92 "optprobe_template_val:\n"
93 "1: .long 0\n"
94 ".global optprobe_template_call\n"
95 "optprobe_template_call:\n"
96 "2: .long 0\n"
97 ".global optprobe_template_end\n"
98 "optprobe_template_end:\n");
99
100#define TMPL_VAL_IDX \
101 ((unsigned long *)&optprobe_template_val - (unsigned long *)&optprobe_template_entry)
102#define TMPL_CALL_IDX \
103 ((unsigned long *)&optprobe_template_call - (unsigned long *)&optprobe_template_entry)
104#define TMPL_END_IDX \
105 ((unsigned long *)&optprobe_template_end - (unsigned long *)&optprobe_template_entry)
106#define TMPL_ADD_SP \
107 ((unsigned long *)&optprobe_template_add_sp - (unsigned long *)&optprobe_template_entry)
108#define TMPL_SUB_SP \
109 ((unsigned long *)&optprobe_template_sub_sp - (unsigned long *)&optprobe_template_entry)
110#define TMPL_RESTORE_BEGIN \
111 ((unsigned long *)&optprobe_template_restore_begin - (unsigned long *)&optprobe_template_entry)
112#define TMPL_RESTORE_ORIGN_INSN \
113 ((unsigned long *)&optprobe_template_restore_orig_insn - (unsigned long *)&optprobe_template_entry)
114#define TMPL_RESTORE_END \
115 ((unsigned long *)&optprobe_template_restore_end - (unsigned long *)&optprobe_template_entry)
116
117/*
118 * ARM can always optimize an instruction when using ARM ISA, except
119 * instructions like 'str r0, [sp, r1]' which store to stack and unable
120 * to determine stack space consumption statically.
121 */
122int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
123{
124 return optinsn->insn != NULL;
125}
126
127/*
128 * In ARM ISA, kprobe opt always replace one instruction (4 bytes
129 * aligned and 4 bytes long). It is impossible to encounter another
130 * kprobe in the address range. So always return 0.
131 */
132int arch_check_optimized_kprobe(struct optimized_kprobe *op)
133{
134 return 0;
135}
136
137/* Caller must ensure addr & 3 == 0 */
138static int can_optimize(struct kprobe *kp)
139{
140 if (kp->ainsn.stack_space < 0)
141 return 0;
142 /*
143 * 255 is the biggest imm can be used in 'sub r0, r0, #<imm>'.
144 * Number larger than 255 needs special encoding.
145 */
146 if (kp->ainsn.stack_space > 255 - sizeof(struct pt_regs))
147 return 0;
148 return 1;
149}
150
151/* Free optimized instruction slot */
152static void
153__arch_remove_optimized_kprobe(struct optimized_kprobe *op, int dirty)
154{
155 if (op->optinsn.insn) {
156 free_optinsn_slot(op->optinsn.insn, dirty);
157 op->optinsn.insn = NULL;
158 }
159}
160
161extern void kprobe_handler(struct pt_regs *regs);
162
163static void
164optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
165{
166 unsigned long flags;
167 struct kprobe *p = &op->kp;
168 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
169
170 /* Save skipped registers */
171 regs->ARM_pc = (unsigned long)op->kp.addr;
172 regs->ARM_ORIG_r0 = ~0UL;
173
174 local_irq_save(flags);
175
176 if (kprobe_running()) {
177 kprobes_inc_nmissed_count(&op->kp);
178 } else {
179 __this_cpu_write(current_kprobe, &op->kp);
180 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
181 opt_pre_handler(&op->kp, regs);
182 __this_cpu_write(current_kprobe, NULL);
183 }
184
185 /*
186 * We singlestep the replaced instruction only when it can't be
187 * executed directly during restore.
188 */
189 if (!p->ainsn.kprobe_direct_exec)
190 op->kp.ainsn.insn_singlestep(p->opcode, &p->ainsn, regs);
191
192 local_irq_restore(flags);
193}
194
195int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
196{
197 kprobe_opcode_t *code;
198 unsigned long rel_chk;
199 unsigned long val;
200 unsigned long stack_protect = sizeof(struct pt_regs);
201
202 if (!can_optimize(orig))
203 return -EILSEQ;
204
205 code = get_optinsn_slot();
206 if (!code)
207 return -ENOMEM;
208
209 /*
210 * Verify if the address gap is in 32MiB range, because this uses
211 * a relative jump.
212 *
213 * kprobe opt use a 'b' instruction to branch to optinsn.insn.
214 * According to ARM manual, branch instruction is:
215 *
216 * 31 28 27 24 23 0
217 * +------+---+---+---+---+----------------+
218 * | cond | 1 | 0 | 1 | 0 | imm24 |
219 * +------+---+---+---+---+----------------+
220 *
221 * imm24 is a signed 24 bits integer. The real branch offset is computed
222 * by: imm32 = SignExtend(imm24:'00', 32);
223 *
224 * So the maximum forward branch should be:
225 * (0x007fffff << 2) = 0x01fffffc = 0x1fffffc
226 * The maximum backword branch should be:
227 * (0xff800000 << 2) = 0xfe000000 = -0x2000000
228 *
229 * We can simply check (rel & 0xfe000003):
230 * if rel is positive, (rel & 0xfe000000) shoule be 0
231 * if rel is negitive, (rel & 0xfe000000) should be 0xfe000000
232 * the last '3' is used for alignment checking.
233 */
234 rel_chk = (unsigned long)((long)code -
235 (long)orig->addr + 8) & 0xfe000003;
236
237 if ((rel_chk != 0) && (rel_chk != 0xfe000000)) {
238 /*
239 * Different from x86, we free code buf directly instead of
240 * calling __arch_remove_optimized_kprobe() because
241 * we have not fill any field in op.
242 */
243 free_optinsn_slot(code, 0);
244 return -ERANGE;
245 }
246
247 /* Copy arch-dep-instance from template. */
248 memcpy(code, &optprobe_template_entry,
249 TMPL_END_IDX * sizeof(kprobe_opcode_t));
250
251 /* Adjust buffer according to instruction. */
252 BUG_ON(orig->ainsn.stack_space < 0);
253
254 stack_protect += orig->ainsn.stack_space;
255
256 /* Should have been filtered by can_optimize(). */
257 BUG_ON(stack_protect > 255);
258
259 /* Create a 'sub sp, sp, #<stack_protect>' */
260 code[TMPL_SUB_SP] = __opcode_to_mem_arm(0xe24dd000 | stack_protect);
261 /* Create a 'add r3, sp, #<stack_protect>' */
262 code[TMPL_ADD_SP] = __opcode_to_mem_arm(0xe28d3000 | stack_protect);
263
264 /* Set probe information */
265 val = (unsigned long)op;
266 code[TMPL_VAL_IDX] = val;
267
268 /* Set probe function call */
269 val = (unsigned long)optimized_callback;
270 code[TMPL_CALL_IDX] = val;
271
272 /* If possible, copy insn and have it executed during restore */
273 orig->ainsn.kprobe_direct_exec = false;
274 if (can_kprobe_direct_exec(orig->ainsn.register_usage_flags)) {
275 kprobe_opcode_t final_branch = arm_gen_branch(
276 (unsigned long)(&code[TMPL_RESTORE_END]),
277 (unsigned long)(op->kp.addr) + 4);
278 if (final_branch != 0) {
279 /*
280 * Replace original 'ldmia sp, {r0 - r15}' with
281 * 'ldmia {r0 - r14}', restore all registers except pc.
282 */
283 code[TMPL_RESTORE_BEGIN] = __opcode_to_mem_arm(0xe89d7fff);
284
285 /* The original probed instruction */
286 code[TMPL_RESTORE_ORIGN_INSN] = __opcode_to_mem_arm(orig->opcode);
287
288 /* Jump back to next instruction */
289 code[TMPL_RESTORE_END] = __opcode_to_mem_arm(final_branch);
290 orig->ainsn.kprobe_direct_exec = true;
291 }
292 }
293
294 flush_icache_range((unsigned long)code,
295 (unsigned long)(&code[TMPL_END_IDX]));
296
297 /* Set op->optinsn.insn means prepared. */
298 op->optinsn.insn = code;
299 return 0;
300}
301
302void __kprobes arch_optimize_kprobes(struct list_head *oplist)
303{
304 struct optimized_kprobe *op, *tmp;
305
306 list_for_each_entry_safe(op, tmp, oplist, list) {
307 unsigned long insn;
308 WARN_ON(kprobe_disabled(&op->kp));
309
310 /*
311 * Backup instructions which will be replaced
312 * by jump address
313 */
314 memcpy(op->optinsn.copied_insn, op->kp.addr,
315 RELATIVEJUMP_SIZE);
316
317 insn = arm_gen_branch((unsigned long)op->kp.addr,
318 (unsigned long)op->optinsn.insn);
319 BUG_ON(insn == 0);
320
321 /*
322 * Make it a conditional branch if replaced insn
323 * is consitional
324 */
325 insn = (__mem_to_opcode_arm(
326 op->optinsn.copied_insn[0]) & 0xf0000000) |
327 (insn & 0x0fffffff);
328
329 /*
330 * Similar to __arch_disarm_kprobe, operations which
331 * removing breakpoints must be wrapped by stop_machine
332 * to avoid racing.
333 */
334 kprobes_remove_breakpoint(op->kp.addr, insn);
335
336 list_del_init(&op->list);
337 }
338}
339
340void arch_unoptimize_kprobe(struct optimized_kprobe *op)
341{
342 arch_arm_kprobe(&op->kp);
343}
344
345/*
346 * Recover original instructions and breakpoints from relative jumps.
347 * Caller must call with locking kprobe_mutex.
348 */
349void arch_unoptimize_kprobes(struct list_head *oplist,
350 struct list_head *done_list)
351{
352 struct optimized_kprobe *op, *tmp;
353
354 list_for_each_entry_safe(op, tmp, oplist, list) {
355 arch_unoptimize_kprobe(op);
356 list_move(&op->list, done_list);
357 }
358}
359
360int arch_within_optimized_kprobe(struct optimized_kprobe *op,
361 unsigned long addr)
362{
363 return ((unsigned long)op->kp.addr <= addr &&
364 (unsigned long)op->kp.addr + RELATIVEJUMP_SIZE > addr);
365}
366
367void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
368{
369 __arch_remove_optimized_kprobe(op, 1);
370}
diff --git a/arch/arm/kernel/kprobes-test-arm.c b/arch/arm/probes/kprobes/test-arm.c
index cb1424240ff6..8866aedfdea2 100644
--- a/arch/arm/kernel/kprobes-test-arm.c
+++ b/arch/arm/probes/kprobes/test-arm.c
@@ -12,8 +12,9 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <asm/system_info.h> 13#include <asm/system_info.h>
14#include <asm/opcodes.h> 14#include <asm/opcodes.h>
15#include <asm/probes.h>
15 16
16#include "kprobes-test.h" 17#include "test-core.h"
17 18
18 19
19#define TEST_ISA "32" 20#define TEST_ISA "32"
@@ -203,9 +204,9 @@ void kprobe_arm_test_cases(void)
203#endif 204#endif
204 TEST_GROUP("Miscellaneous instructions") 205 TEST_GROUP("Miscellaneous instructions")
205 206
206 TEST("mrs r0, cpsr") 207 TEST_RMASKED("mrs r",0,~PSR_IGNORE_BITS,", cpsr")
207 TEST("mrspl r7, cpsr") 208 TEST_RMASKED("mrspl r",7,~PSR_IGNORE_BITS,", cpsr")
208 TEST("mrs r14, cpsr") 209 TEST_RMASKED("mrs r",14,~PSR_IGNORE_BITS,", cpsr")
209 TEST_UNSUPPORTED(__inst_arm(0xe10ff000) " @ mrs r15, cpsr") 210 TEST_UNSUPPORTED(__inst_arm(0xe10ff000) " @ mrs r15, cpsr")
210 TEST_UNSUPPORTED("mrs r0, spsr") 211 TEST_UNSUPPORTED("mrs r0, spsr")
211 TEST_UNSUPPORTED("mrs lr, spsr") 212 TEST_UNSUPPORTED("mrs lr, spsr")
@@ -214,9 +215,12 @@ void kprobe_arm_test_cases(void)
214 TEST_UNSUPPORTED("msr cpsr_f, lr") 215 TEST_UNSUPPORTED("msr cpsr_f, lr")
215 TEST_UNSUPPORTED("msr spsr, r0") 216 TEST_UNSUPPORTED("msr spsr, r0")
216 217
218#if __LINUX_ARM_ARCH__ >= 5 || \
219 (__LINUX_ARM_ARCH__ == 4 && !defined(CONFIG_CPU_32v4))
217 TEST_BF_R("bx r",0,2f,"") 220 TEST_BF_R("bx r",0,2f,"")
218 TEST_BB_R("bx r",7,2f,"") 221 TEST_BB_R("bx r",7,2f,"")
219 TEST_BF_R("bxeq r",14,2f,"") 222 TEST_BF_R("bxeq r",14,2f,"")
223#endif
220 224
221#if __LINUX_ARM_ARCH__ >= 5 225#if __LINUX_ARM_ARCH__ >= 5
222 TEST_R("clz r0, r",0, 0x0,"") 226 TEST_R("clz r0, r",0, 0x0,"")
@@ -476,7 +480,9 @@ void kprobe_arm_test_cases(void)
476 TEST_GROUP("Extra load/store instructions") 480 TEST_GROUP("Extra load/store instructions")
477 481
478 TEST_RPR( "strh r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") 482 TEST_RPR( "strh r",0, VAL1,", [r",1, 48,", -r",2, 24,"]")
479 TEST_RPR( "streqh r",14,VAL2,", [r",13,0, ", r",12, 48,"]") 483 TEST_RPR( "streqh r",14,VAL2,", [r",11,0, ", r",12, 48,"]")
484 TEST_UNSUPPORTED( "streqh r14, [r13, r12]")
485 TEST_UNSUPPORTED( "streqh r14, [r12, r13]")
480 TEST_RPR( "strh r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") 486 TEST_RPR( "strh r",1, VAL1,", [r",2, 24,", r",3, 48,"]!")
481 TEST_RPR( "strneh r",12,VAL2,", [r",11,48,", -r",10,24,"]!") 487 TEST_RPR( "strneh r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
482 TEST_RPR( "strh r",2, VAL1,", [r",3, 24,"], r",4, 48,"") 488 TEST_RPR( "strh r",2, VAL1,", [r",3, 24,"], r",4, 48,"")
@@ -501,6 +507,9 @@ void kprobe_arm_test_cases(void)
501 TEST_RP( "strplh r",12,VAL2,", [r",11,24,", #-4]!") 507 TEST_RP( "strplh r",12,VAL2,", [r",11,24,", #-4]!")
502 TEST_RP( "strh r",2, VAL1,", [r",3, 24,"], #48") 508 TEST_RP( "strh r",2, VAL1,", [r",3, 24,"], #48")
503 TEST_RP( "strh r",10,VAL2,", [r",9, 64,"], #-48") 509 TEST_RP( "strh r",10,VAL2,", [r",9, 64,"], #-48")
510 TEST_RP( "strh r",3, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!")
511 TEST_UNSUPPORTED("strh r3, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!")
512 TEST_RP( "strh r",4, VAL1,", [r",14,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!")
504 TEST_UNSUPPORTED(__inst_arm(0xe1efc3b0) " @ strh r12, [pc, #48]!") 513 TEST_UNSUPPORTED(__inst_arm(0xe1efc3b0) " @ strh r12, [pc, #48]!")
505 TEST_UNSUPPORTED(__inst_arm(0xe0c9f3b0) " @ strh pc, [r9], #48") 514 TEST_UNSUPPORTED(__inst_arm(0xe0c9f3b0) " @ strh pc, [r9], #48")
506 515
@@ -565,7 +574,9 @@ void kprobe_arm_test_cases(void)
565 574
566#if __LINUX_ARM_ARCH__ >= 5 575#if __LINUX_ARM_ARCH__ >= 5
567 TEST_RPR( "strd r",0, VAL1,", [r",1, 48,", -r",2,24,"]") 576 TEST_RPR( "strd r",0, VAL1,", [r",1, 48,", -r",2,24,"]")
568 TEST_RPR( "strccd r",8, VAL2,", [r",13,0, ", r",12,48,"]") 577 TEST_RPR( "strccd r",8, VAL2,", [r",11,0, ", r",12,48,"]")
578 TEST_UNSUPPORTED( "strccd r8, [r13, r12]")
579 TEST_UNSUPPORTED( "strccd r8, [r12, r13]")
569 TEST_RPR( "strd r",4, VAL1,", [r",2, 24,", r",3, 48,"]!") 580 TEST_RPR( "strd r",4, VAL1,", [r",2, 24,", r",3, 48,"]!")
570 TEST_RPR( "strcsd r",12,VAL2,", [r",11,48,", -r",10,24,"]!") 581 TEST_RPR( "strcsd r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
571 TEST_RPR( "strd r",2, VAL1,", [r",5, 24,"], r",4,48,"") 582 TEST_RPR( "strd r",2, VAL1,", [r",5, 24,"], r",4,48,"")
@@ -589,6 +600,9 @@ void kprobe_arm_test_cases(void)
589 TEST_RP( "strvcd r",12,VAL2,", [r",11,24,", #-16]!") 600 TEST_RP( "strvcd r",12,VAL2,", [r",11,24,", #-16]!")
590 TEST_RP( "strd r",2, VAL1,", [r",4, 24,"], #48") 601 TEST_RP( "strd r",2, VAL1,", [r",4, 24,"], #48")
591 TEST_RP( "strd r",10,VAL2,", [r",9, 64,"], #-48") 602 TEST_RP( "strd r",10,VAL2,", [r",9, 64,"], #-48")
603 TEST_RP( "strd r",6, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!")
604 TEST_UNSUPPORTED("strd r6, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!")
605 TEST_RP( "strd r",4, VAL1,", [r",12,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!")
592 TEST_UNSUPPORTED(__inst_arm(0xe1efc3f0) " @ strd r12, [pc, #48]!") 606 TEST_UNSUPPORTED(__inst_arm(0xe1efc3f0) " @ strd r12, [pc, #48]!")
593 607
594 TEST_P( "ldrd r0, [r",0, 24,", #-8]") 608 TEST_P( "ldrd r0, [r",0, 24,", #-8]")
@@ -637,14 +651,20 @@ void kprobe_arm_test_cases(void)
637 TEST_RP( "str"byte" r",12,VAL2,", [r",11,24,", #-4]!") \ 651 TEST_RP( "str"byte" r",12,VAL2,", [r",11,24,", #-4]!") \
638 TEST_RP( "str"byte" r",2, VAL1,", [r",3, 24,"], #48") \ 652 TEST_RP( "str"byte" r",2, VAL1,", [r",3, 24,"], #48") \
639 TEST_RP( "str"byte" r",10,VAL2,", [r",9, 64,"], #-48") \ 653 TEST_RP( "str"byte" r",10,VAL2,", [r",9, 64,"], #-48") \
654 TEST_RP( "str"byte" r",3, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!") \
655 TEST_UNSUPPORTED("str"byte" r3, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!") \
656 TEST_RP( "str"byte" r",4, VAL1,", [r",10,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!") \
640 TEST_RPR("str"byte" r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") \ 657 TEST_RPR("str"byte" r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") \
641 TEST_RPR("str"byte" r",14,VAL2,", [r",13,0, ", r",12, 48,"]") \ 658 TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 48,"]") \
659 TEST_UNSUPPORTED("str"byte" r14, [r13, r12]") \
660 TEST_UNSUPPORTED("str"byte" r14, [r12, r13]") \
642 TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") \ 661 TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") \
643 TEST_RPR("str"byte" r",12,VAL2,", [r",11,48,", -r",10,24,"]!") \ 662 TEST_RPR("str"byte" r",12,VAL2,", [r",11,48,", -r",10,24,"]!") \
644 TEST_RPR("str"byte" r",2, VAL1,", [r",3, 24,"], r",4, 48,"") \ 663 TEST_RPR("str"byte" r",2, VAL1,", [r",3, 24,"], r",4, 48,"") \
645 TEST_RPR("str"byte" r",10,VAL2,", [r",9, 48,"], -r",11,24,"") \ 664 TEST_RPR("str"byte" r",10,VAL2,", [r",9, 48,"], -r",11,24,"") \
646 TEST_RPR("str"byte" r",0, VAL1,", [r",1, 24,", r",2, 32,", asl #1]")\ 665 TEST_RPR("str"byte" r",0, VAL1,", [r",1, 24,", r",2, 32,", asl #1]")\
647 TEST_RPR("str"byte" r",14,VAL2,", [r",13,0, ", r",12, 32,", lsr #2]")\ 666 TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 32,", lsr #2]")\
667 TEST_UNSUPPORTED("str"byte" r14, [r13, r12, lsr #2]") \
648 TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 32,", asr #3]!")\ 668 TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 32,", asr #3]!")\
649 TEST_RPR("str"byte" r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\ 669 TEST_RPR("str"byte" r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\
650 TEST_P( "ldr"byte" r0, [r",0, 24,", #-2]") \ 670 TEST_P( "ldr"byte" r0, [r",0, 24,", #-2]") \
@@ -668,12 +688,12 @@ void kprobe_arm_test_cases(void)
668 688
669 LOAD_STORE("") 689 LOAD_STORE("")
670 TEST_P( "str pc, [r",0,0,", #15*4]") 690 TEST_P( "str pc, [r",0,0,", #15*4]")
671 TEST_R( "str pc, [sp, r",2,15*4,"]") 691 TEST_UNSUPPORTED( "str pc, [sp, r2]")
672 TEST_BF( "ldr pc, [sp, #15*4]") 692 TEST_BF( "ldr pc, [sp, #15*4]")
673 TEST_BF_R("ldr pc, [sp, r",2,15*4,"]") 693 TEST_BF_R("ldr pc, [sp, r",2,15*4,"]")
674 694
675 TEST_P( "str sp, [r",0,0,", #13*4]") 695 TEST_P( "str sp, [r",0,0,", #13*4]")
676 TEST_R( "str sp, [sp, r",2,13*4,"]") 696 TEST_UNSUPPORTED( "str sp, [sp, r2]")
677 TEST_BF( "ldr sp, [sp, #13*4]") 697 TEST_BF( "ldr sp, [sp, #13*4]")
678 TEST_BF_R("ldr sp, [sp, r",2,13*4,"]") 698 TEST_BF_R("ldr sp, [sp, r",2,13*4,"]")
679 699
diff --git a/arch/arm/kernel/kprobes-test.c b/arch/arm/probes/kprobes/test-core.c
index b206d7790c77..9775de22e2ff 100644
--- a/arch/arm/kernel/kprobes-test.c
+++ b/arch/arm/probes/kprobes/test-core.c
@@ -209,10 +209,10 @@
209#include <linux/bug.h> 209#include <linux/bug.h>
210#include <asm/opcodes.h> 210#include <asm/opcodes.h>
211 211
212#include "kprobes.h" 212#include "core.h"
213#include "probes-arm.h" 213#include "test-core.h"
214#include "probes-thumb.h" 214#include "../decode-arm.h"
215#include "kprobes-test.h" 215#include "../decode-thumb.h"
216 216
217 217
218#define BENCHMARKING 1 218#define BENCHMARKING 1
@@ -236,6 +236,8 @@ static int tests_failed;
236 236
237#ifndef CONFIG_THUMB2_KERNEL 237#ifndef CONFIG_THUMB2_KERNEL
238 238
239#define RET(reg) "mov pc, "#reg
240
239long arm_func(long r0, long r1); 241long arm_func(long r0, long r1);
240 242
241static void __used __naked __arm_kprobes_test_func(void) 243static void __used __naked __arm_kprobes_test_func(void)
@@ -245,7 +247,7 @@ static void __used __naked __arm_kprobes_test_func(void)
245 ".type arm_func, %%function \n\t" 247 ".type arm_func, %%function \n\t"
246 "arm_func: \n\t" 248 "arm_func: \n\t"
247 "adds r0, r0, r1 \n\t" 249 "adds r0, r0, r1 \n\t"
248 "bx lr \n\t" 250 "mov pc, lr \n\t"
249 ".code "NORMAL_ISA /* Back to Thumb if necessary */ 251 ".code "NORMAL_ISA /* Back to Thumb if necessary */
250 : : : "r0", "r1", "cc" 252 : : : "r0", "r1", "cc"
251 ); 253 );
@@ -253,6 +255,8 @@ static void __used __naked __arm_kprobes_test_func(void)
253 255
254#else /* CONFIG_THUMB2_KERNEL */ 256#else /* CONFIG_THUMB2_KERNEL */
255 257
258#define RET(reg) "bx "#reg
259
256long thumb16_func(long r0, long r1); 260long thumb16_func(long r0, long r1);
257long thumb32even_func(long r0, long r1); 261long thumb32even_func(long r0, long r1);
258long thumb32odd_func(long r0, long r1); 262long thumb32odd_func(long r0, long r1);
@@ -494,7 +498,7 @@ static void __naked benchmark_nop(void)
494{ 498{
495 __asm__ __volatile__ ( 499 __asm__ __volatile__ (
496 "nop \n\t" 500 "nop \n\t"
497 "bx lr" 501 RET(lr)" \n\t"
498 ); 502 );
499} 503}
500 504
@@ -977,7 +981,7 @@ void __naked __kprobes_test_case_start(void)
977 "bic r0, lr, #1 @ r0 = inline data \n\t" 981 "bic r0, lr, #1 @ r0 = inline data \n\t"
978 "mov r1, sp \n\t" 982 "mov r1, sp \n\t"
979 "bl kprobes_test_case_start \n\t" 983 "bl kprobes_test_case_start \n\t"
980 "bx r0 \n\t" 984 RET(r0)" \n\t"
981 ); 985 );
982} 986}
983 987
@@ -1056,15 +1060,6 @@ static int test_case_run_count;
1056static bool test_case_is_thumb; 1060static bool test_case_is_thumb;
1057static int test_instance; 1061static int test_instance;
1058 1062
1059/*
1060 * We ignore the state of the imprecise abort disable flag (CPSR.A) because this
1061 * can change randomly as the kernel doesn't take care to preserve or initialise
1062 * this across context switches. Also, with Security Extentions, the flag may
1063 * not be under control of the kernel; for this reason we ignore the state of
1064 * the FIQ disable flag CPSR.F as well.
1065 */
1066#define PSR_IGNORE_BITS (PSR_A_BIT | PSR_F_BIT)
1067
1068static unsigned long test_check_cc(int cc, unsigned long cpsr) 1063static unsigned long test_check_cc(int cc, unsigned long cpsr)
1069{ 1064{
1070 int ret = arm_check_condition(cc << 28, cpsr); 1065 int ret = arm_check_condition(cc << 28, cpsr);
@@ -1196,6 +1191,13 @@ static void setup_test_context(struct pt_regs *regs)
1196 regs->uregs[arg->reg] = 1191 regs->uregs[arg->reg] =
1197 (unsigned long)current_stack + arg->val; 1192 (unsigned long)current_stack + arg->val;
1198 memory_needs_checking = true; 1193 memory_needs_checking = true;
1194 /*
1195 * Test memory at an address below SP is in danger of
1196 * being altered by an interrupt occurring and pushing
1197 * data onto the stack. Disable interrupts to stop this.
1198 */
1199 if (arg->reg == 13)
1200 regs->ARM_cpsr |= PSR_I_BIT;
1199 break; 1201 break;
1200 } 1202 }
1201 case ARG_TYPE_MEM: { 1203 case ARG_TYPE_MEM: {
@@ -1264,14 +1266,26 @@ test_case_pre_handler(struct kprobe *p, struct pt_regs *regs)
1264static int __kprobes 1266static int __kprobes
1265test_after_pre_handler(struct kprobe *p, struct pt_regs *regs) 1267test_after_pre_handler(struct kprobe *p, struct pt_regs *regs)
1266{ 1268{
1269 struct test_arg *args;
1270
1267 if (container_of(p, struct test_probe, kprobe)->hit == test_instance) 1271 if (container_of(p, struct test_probe, kprobe)->hit == test_instance)
1268 return 0; /* Already run for this test instance */ 1272 return 0; /* Already run for this test instance */
1269 1273
1270 result_regs = *regs; 1274 result_regs = *regs;
1275
1276 /* Mask out results which are indeterminate */
1271 result_regs.ARM_cpsr &= ~PSR_IGNORE_BITS; 1277 result_regs.ARM_cpsr &= ~PSR_IGNORE_BITS;
1278 for (args = current_args; args[0].type != ARG_TYPE_END; ++args)
1279 if (args[0].type == ARG_TYPE_REG_MASKED) {
1280 struct test_arg_regptr *arg =
1281 (struct test_arg_regptr *)args;
1282 result_regs.uregs[arg->reg] &= arg->val;
1283 }
1272 1284
1273 /* Undo any changes done to SP by the test case */ 1285 /* Undo any changes done to SP by the test case */
1274 regs->ARM_sp = (unsigned long)current_stack; 1286 regs->ARM_sp = (unsigned long)current_stack;
1287 /* Enable interrupts in case setup_test_context disabled them */
1288 regs->ARM_cpsr &= ~PSR_I_BIT;
1275 1289
1276 container_of(p, struct test_probe, kprobe)->hit = test_instance; 1290 container_of(p, struct test_probe, kprobe)->hit = test_instance;
1277 return 0; 1291 return 0;
diff --git a/arch/arm/kernel/kprobes-test.h b/arch/arm/probes/kprobes/test-core.h
index 4430990e90e7..94285203e9f7 100644
--- a/arch/arm/kernel/kprobes-test.h
+++ b/arch/arm/probes/kprobes/test-core.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/kprobes-test.h 2 * arch/arm/probes/kprobes/test-core.h
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -45,10 +45,11 @@ extern int kprobe_test_cc_position;
45 * 45 *
46 */ 46 */
47 47
48#define ARG_TYPE_END 0 48#define ARG_TYPE_END 0
49#define ARG_TYPE_REG 1 49#define ARG_TYPE_REG 1
50#define ARG_TYPE_PTR 2 50#define ARG_TYPE_PTR 2
51#define ARG_TYPE_MEM 3 51#define ARG_TYPE_MEM 3
52#define ARG_TYPE_REG_MASKED 4
52 53
53#define ARG_FLAG_UNSUPPORTED 0x01 54#define ARG_FLAG_UNSUPPORTED 0x01
54#define ARG_FLAG_SUPPORTED 0x02 55#define ARG_FLAG_SUPPORTED 0x02
@@ -61,7 +62,7 @@ struct test_arg {
61}; 62};
62 63
63struct test_arg_regptr { 64struct test_arg_regptr {
64 u8 type; /* ARG_TYPE_REG or ARG_TYPE_PTR */ 65 u8 type; /* ARG_TYPE_REG or ARG_TYPE_PTR or ARG_TYPE_REG_MASKED */
65 u8 reg; 66 u8 reg;
66 u8 _padding[2]; 67 u8 _padding[2];
67 u32 val; 68 u32 val;
@@ -138,6 +139,12 @@ struct test_arg_end {
138 ".short 0 \n\t" \ 139 ".short 0 \n\t" \
139 ".word "#val" \n\t" 140 ".word "#val" \n\t"
140 141
142#define TEST_ARG_REG_MASKED(reg, val) \
143 ".byte "__stringify(ARG_TYPE_REG_MASKED)" \n\t" \
144 ".byte "#reg" \n\t" \
145 ".short 0 \n\t" \
146 ".word "#val" \n\t"
147
141#define TEST_ARG_END(flags) \ 148#define TEST_ARG_END(flags) \
142 ".byte "__stringify(ARG_TYPE_END)" \n\t" \ 149 ".byte "__stringify(ARG_TYPE_END)" \n\t" \
143 ".byte "TEST_ISA flags" \n\t" \ 150 ".byte "TEST_ISA flags" \n\t" \
@@ -395,6 +402,22 @@ struct test_arg_end {
395 " "codex" \n\t" \ 402 " "codex" \n\t" \
396 TESTCASE_END 403 TESTCASE_END
397 404
405#define TEST_RMASKED(code1, reg, mask, code2) \
406 TESTCASE_START(code1 #reg code2) \
407 TEST_ARG_REG_MASKED(reg, mask) \
408 TEST_ARG_END("") \
409 TEST_INSTRUCTION(code1 #reg code2) \
410 TESTCASE_END
411
412/*
413 * We ignore the state of the imprecise abort disable flag (CPSR.A) because this
414 * can change randomly as the kernel doesn't take care to preserve or initialise
415 * this across context switches. Also, with Security Extensions, the flag may
416 * not be under control of the kernel; for this reason we ignore the state of
417 * the FIQ disable flag CPSR.F as well.
418 */
419#define PSR_IGNORE_BITS (PSR_A_BIT | PSR_F_BIT)
420
398 421
399/* 422/*
400 * Macros for defining space directives spread over multiple lines. 423 * Macros for defining space directives spread over multiple lines.
diff --git a/arch/arm/kernel/kprobes-test-thumb.c b/arch/arm/probes/kprobes/test-thumb.c
index 844dd10d8593..b683b4517458 100644
--- a/arch/arm/kernel/kprobes-test-thumb.c
+++ b/arch/arm/probes/kprobes/test-thumb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/kprobes-test-thumb.c 2 * arch/arm/probes/kprobes/test-thumb.c
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -11,8 +11,9 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <asm/opcodes.h> 13#include <asm/opcodes.h>
14#include <asm/probes.h>
14 15
15#include "kprobes-test.h" 16#include "test-core.h"
16 17
17 18
18#define TEST_ISA "16" 19#define TEST_ISA "16"
@@ -416,6 +417,9 @@ void kprobe_thumb32_test_cases(void)
416 TEST_RR( "strd r",14,VAL2,", r",12,VAL1,", [sp, #16]!") 417 TEST_RR( "strd r",14,VAL2,", r",12,VAL1,", [sp, #16]!")
417 TEST_RRP("strd r",1, VAL1,", r",0, VAL2,", [r",7, 24,"], #16") 418 TEST_RRP("strd r",1, VAL1,", r",0, VAL2,", [r",7, 24,"], #16")
418 TEST_RR( "strd r",7, VAL2,", r",8, VAL1,", [sp], #-16") 419 TEST_RR( "strd r",7, VAL2,", r",8, VAL1,", [sp], #-16")
420 TEST_RRP("strd r",6, VAL1,", r",7, VAL2,", [r",13, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!")
421 TEST_UNSUPPORTED("strd r6, r7, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!")
422 TEST_RRP("strd r",4, VAL1,", r",5, VAL2,", [r",14, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!")
419 TEST_UNSUPPORTED(__inst_thumb32(0xe9efec04) " @ strd r14, r12, [pc, #16]!") 423 TEST_UNSUPPORTED(__inst_thumb32(0xe9efec04) " @ strd r14, r12, [pc, #16]!")
420 TEST_UNSUPPORTED(__inst_thumb32(0xe8efec04) " @ strd r14, r12, [pc], #16") 424 TEST_UNSUPPORTED(__inst_thumb32(0xe8efec04) " @ strd r14, r12, [pc], #16")
421 425
@@ -774,8 +778,8 @@ CONDITION_INSTRUCTIONS(22,
774 778
775 TEST_UNSUPPORTED("subs pc, lr, #4") 779 TEST_UNSUPPORTED("subs pc, lr, #4")
776 780
777 TEST("mrs r0, cpsr") 781 TEST_RMASKED("mrs r",0,~PSR_IGNORE_BITS,", cpsr")
778 TEST("mrs r14, cpsr") 782 TEST_RMASKED("mrs r",14,~PSR_IGNORE_BITS,", cpsr")
779 TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8d00) " @ mrs sp, spsr") 783 TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8d00) " @ mrs sp, spsr")
780 TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8f00) " @ mrs pc, spsr") 784 TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8f00) " @ mrs pc, spsr")
781 TEST_UNSUPPORTED("mrs r0, spsr") 785 TEST_UNSUPPORTED("mrs r0, spsr")
@@ -821,14 +825,22 @@ CONDITION_INSTRUCTIONS(22,
821 TEST_RP( "str"size" r",14,VAL2,", [r",1, 256, ", #-128]!") \ 825 TEST_RP( "str"size" r",14,VAL2,", [r",1, 256, ", #-128]!") \
822 TEST_RPR("str"size".w r",0, VAL1,", [r",1, 0,", r",2, 4,"]") \ 826 TEST_RPR("str"size".w r",0, VAL1,", [r",1, 0,", r",2, 4,"]") \
823 TEST_RPR("str"size" r",14,VAL2,", [r",10,0,", r",11,4,", lsl #1]") \ 827 TEST_RPR("str"size" r",14,VAL2,", [r",10,0,", r",11,4,", lsl #1]") \
828 TEST_UNSUPPORTED("str"size" r0, [r13, r1]") \
824 TEST_R( "str"size".w r",7, VAL1,", [sp, #24]") \ 829 TEST_R( "str"size".w r",7, VAL1,", [sp, #24]") \
825 TEST_RP( "str"size".w r",0, VAL2,", [r",0,0, "]") \ 830 TEST_RP( "str"size".w r",0, VAL2,", [r",0,0, "]") \
831 TEST_RP( "str"size" r",6, VAL1,", [r",13, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!") \
832 TEST_UNSUPPORTED("str"size" r6, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!") \
833 TEST_RP( "str"size" r",4, VAL2,", [r",12, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!") \
826 TEST_UNSUPPORTED("str"size"t r0, [r1, #4]") 834 TEST_UNSUPPORTED("str"size"t r0, [r1, #4]")
827 835
828 SINGLE_STORE("b") 836 SINGLE_STORE("b")
829 SINGLE_STORE("h") 837 SINGLE_STORE("h")
830 SINGLE_STORE("") 838 SINGLE_STORE("")
831 839
840 TEST_UNSUPPORTED(__inst_thumb32(0xf801000d) " @ strb r0, [r1, r13]")
841 TEST_UNSUPPORTED(__inst_thumb32(0xf821000d) " @ strh r0, [r1, r13]")
842 TEST_UNSUPPORTED(__inst_thumb32(0xf841000d) " @ str r0, [r1, r13]")
843
832 TEST("str sp, [sp]") 844 TEST("str sp, [sp]")
833 TEST_UNSUPPORTED(__inst_thumb32(0xf8cfe000) " @ str r14, [pc]") 845 TEST_UNSUPPORTED(__inst_thumb32(0xf8cfe000) " @ str r14, [pc]")
834 TEST_UNSUPPORTED(__inst_thumb32(0xf8cef000) " @ str pc, [r14]") 846 TEST_UNSUPPORTED(__inst_thumb32(0xf8cef000) " @ str pc, [r14]")
diff --git a/arch/arm/probes/uprobes/Makefile b/arch/arm/probes/uprobes/Makefile
new file mode 100644
index 000000000000..e1dc3d0f6d5a
--- /dev/null
+++ b/arch/arm/probes/uprobes/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_UPROBES) += core.o actions-arm.o
diff --git a/arch/arm/kernel/uprobes-arm.c b/arch/arm/probes/uprobes/actions-arm.c
index d3b655ff17da..76eb44972ebe 100644
--- a/arch/arm/kernel/uprobes-arm.c
+++ b/arch/arm/probes/uprobes/actions-arm.c
@@ -13,9 +13,9 @@
13#include <linux/uprobes.h> 13#include <linux/uprobes.h>
14#include <linux/module.h> 14#include <linux/module.h>
15 15
16#include "probes.h" 16#include "../decode.h"
17#include "probes-arm.h" 17#include "../decode-arm.h"
18#include "uprobes.h" 18#include "core.h"
19 19
20static int uprobes_substitute_pc(unsigned long *pinsn, u32 oregs) 20static int uprobes_substitute_pc(unsigned long *pinsn, u32 oregs)
21{ 21{
@@ -195,8 +195,6 @@ uprobe_decode_ldmstm(probes_opcode_t insn,
195} 195}
196 196
197const union decode_action uprobes_probes_actions[] = { 197const union decode_action uprobes_probes_actions[] = {
198 [PROBES_EMULATE_NONE] = {.handler = probes_simulate_nop},
199 [PROBES_SIMULATE_NOP] = {.handler = probes_simulate_nop},
200 [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop}, 198 [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
201 [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop}, 199 [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
202 [PROBES_BRANCH_IMM] = {.handler = simulate_blx1}, 200 [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
diff --git a/arch/arm/kernel/uprobes.c b/arch/arm/probes/uprobes/core.c
index 56adf9c1fde0..d1329f1ba4e4 100644
--- a/arch/arm/kernel/uprobes.c
+++ b/arch/arm/probes/uprobes/core.c
@@ -17,9 +17,9 @@
17#include <asm/opcodes.h> 17#include <asm/opcodes.h>
18#include <asm/traps.h> 18#include <asm/traps.h>
19 19
20#include "probes.h" 20#include "../decode.h"
21#include "probes-arm.h" 21#include "../decode-arm.h"
22#include "uprobes.h" 22#include "core.h"
23 23
24#define UPROBE_TRAP_NR UINT_MAX 24#define UPROBE_TRAP_NR UINT_MAX
25 25
@@ -88,7 +88,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
88 auprobe->ixol[1] = __opcode_to_mem_arm(UPROBE_SS_ARM_INSN); 88 auprobe->ixol[1] = __opcode_to_mem_arm(UPROBE_SS_ARM_INSN);
89 89
90 ret = arm_probes_decode_insn(insn, &auprobe->asi, false, 90 ret = arm_probes_decode_insn(insn, &auprobe->asi, false,
91 uprobes_probes_actions); 91 uprobes_probes_actions, NULL);
92 switch (ret) { 92 switch (ret) {
93 case INSN_REJECTED: 93 case INSN_REJECTED:
94 return -EINVAL; 94 return -EINVAL;
diff --git a/arch/arm/kernel/uprobes.h b/arch/arm/probes/uprobes/core.h
index 1d0c12dfbd03..1d0c12dfbd03 100644
--- a/arch/arm/kernel/uprobes.h
+++ b/arch/arm/probes/uprobes/core.h
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index dd301be89ecc..5376d908eabe 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1,6 +1,7 @@
1# CONFIG_LOCALVERSION_AUTO is not set 1# CONFIG_LOCALVERSION_AUTO is not set
2CONFIG_SYSVIPC=y 2CONFIG_SYSVIPC=y
3CONFIG_POSIX_MQUEUE=y 3CONFIG_POSIX_MQUEUE=y
4CONFIG_FHANDLE=y
4CONFIG_AUDIT=y 5CONFIG_AUDIT=y
5CONFIG_NO_HZ_IDLE=y 6CONFIG_NO_HZ_IDLE=y
6CONFIG_HIGH_RES_TIMERS=y 7CONFIG_HIGH_RES_TIMERS=y
@@ -13,14 +14,12 @@ CONFIG_TASK_IO_ACCOUNTING=y
13CONFIG_IKCONFIG=y 14CONFIG_IKCONFIG=y
14CONFIG_IKCONFIG_PROC=y 15CONFIG_IKCONFIG_PROC=y
15CONFIG_LOG_BUF_SHIFT=14 16CONFIG_LOG_BUF_SHIFT=14
16CONFIG_RESOURCE_COUNTERS=y
17CONFIG_MEMCG=y 17CONFIG_MEMCG=y
18CONFIG_MEMCG_SWAP=y 18CONFIG_MEMCG_SWAP=y
19CONFIG_MEMCG_KMEM=y 19CONFIG_MEMCG_KMEM=y
20CONFIG_CGROUP_HUGETLB=y 20CONFIG_CGROUP_HUGETLB=y
21# CONFIG_UTS_NS is not set 21# CONFIG_UTS_NS is not set
22# CONFIG_IPC_NS is not set 22# CONFIG_IPC_NS is not set
23# CONFIG_PID_NS is not set
24# CONFIG_NET_NS is not set 23# CONFIG_NET_NS is not set
25CONFIG_SCHED_AUTOGROUP=y 24CONFIG_SCHED_AUTOGROUP=y
26CONFIG_BLK_DEV_INITRD=y 25CONFIG_BLK_DEV_INITRD=y
@@ -92,7 +91,6 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
92CONFIG_SERIAL_OF_PLATFORM=y 91CONFIG_SERIAL_OF_PLATFORM=y
93CONFIG_VIRTIO_CONSOLE=y 92CONFIG_VIRTIO_CONSOLE=y
94# CONFIG_HW_RANDOM is not set 93# CONFIG_HW_RANDOM is not set
95# CONFIG_HMC_DRV is not set
96CONFIG_SPI=y 94CONFIG_SPI=y
97CONFIG_SPI_PL022=y 95CONFIG_SPI_PL022=y
98CONFIG_GPIO_PL061=y 96CONFIG_GPIO_PL061=y
@@ -133,6 +131,8 @@ CONFIG_EXT3_FS=y
133CONFIG_EXT4_FS=y 131CONFIG_EXT4_FS=y
134CONFIG_FANOTIFY=y 132CONFIG_FANOTIFY=y
135CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y 133CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
134CONFIG_QUOTA=y
135CONFIG_AUTOFS4_FS=y
136CONFIG_FUSE_FS=y 136CONFIG_FUSE_FS=y
137CONFIG_CUSE=y 137CONFIG_CUSE=y
138CONFIG_VFAT_FS=y 138CONFIG_VFAT_FS=y
@@ -152,14 +152,15 @@ CONFIG_MAGIC_SYSRQ=y
152CONFIG_DEBUG_KERNEL=y 152CONFIG_DEBUG_KERNEL=y
153CONFIG_LOCKUP_DETECTOR=y 153CONFIG_LOCKUP_DETECTOR=y
154# CONFIG_SCHED_DEBUG is not set 154# CONFIG_SCHED_DEBUG is not set
155# CONFIG_DEBUG_PREEMPT is not set
155# CONFIG_FTRACE is not set 156# CONFIG_FTRACE is not set
157CONFIG_KEYS=y
156CONFIG_SECURITY=y 158CONFIG_SECURITY=y
157CONFIG_CRYPTO_ANSI_CPRNG=y 159CONFIG_CRYPTO_ANSI_CPRNG=y
158CONFIG_ARM64_CRYPTO=y 160CONFIG_ARM64_CRYPTO=y
159CONFIG_CRYPTO_SHA1_ARM64_CE=y 161CONFIG_CRYPTO_SHA1_ARM64_CE=y
160CONFIG_CRYPTO_SHA2_ARM64_CE=y 162CONFIG_CRYPTO_SHA2_ARM64_CE=y
161CONFIG_CRYPTO_GHASH_ARM64_CE=y 163CONFIG_CRYPTO_GHASH_ARM64_CE=y
162CONFIG_CRYPTO_AES_ARM64_CE=y
163CONFIG_CRYPTO_AES_ARM64_CE_CCM=y 164CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
164CONFIG_CRYPTO_AES_ARM64_CE_BLK=y 165CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
165CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y 166CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
index d34189bceff7..9ce3e680ae1c 100644
--- a/arch/arm64/include/asm/dma-mapping.h
+++ b/arch/arm64/include/asm/dma-mapping.h
@@ -52,13 +52,14 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
52 dev->archdata.dma_ops = ops; 52 dev->archdata.dma_ops = ops;
53} 53}
54 54
55static inline int set_arch_dma_coherent_ops(struct device *dev) 55static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
56 struct iommu_ops *iommu, bool coherent)
56{ 57{
57 dev->archdata.dma_coherent = true; 58 dev->archdata.dma_coherent = coherent;
58 set_dma_ops(dev, &coherent_swiotlb_dma_ops); 59 if (coherent)
59 return 0; 60 set_dma_ops(dev, &coherent_swiotlb_dma_ops);
60} 61}
61#define set_arch_dma_coherent_ops set_arch_dma_coherent_ops 62#define arch_setup_dma_ops arch_setup_dma_ops
62 63
63/* do not use this function in a driver */ 64/* do not use this function in a driver */
64static inline bool is_device_dma_coherent(struct device *dev) 65static inline bool is_device_dma_coherent(struct device *dev)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index df22314f57cf..210d632aa5ad 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -298,7 +298,6 @@ void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
298#define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))) 298#define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
299#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot) 299#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot)
300 300
301#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
302#define pud_write(pud) pte_write(pud_pte(pud)) 301#define pud_write(pud) pte_write(pud_pte(pud))
303#define pud_pfn(pud) (((pud_val(pud) & PUD_MASK) & PHYS_MASK) >> PAGE_SHIFT) 302#define pud_pfn(pud) (((pud_val(pud) & PUD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
304 303
@@ -401,7 +400,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
401 return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr); 400 return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
402} 401}
403 402
404#define pud_page(pud) pmd_page(pud_pmd(pud)) 403#define pud_page(pud) pfn_to_page(__phys_to_pfn(pud_val(pud) & PHYS_MASK))
405 404
406#endif /* CONFIG_ARM64_PGTABLE_LEVELS > 2 */ 405#endif /* CONFIG_ARM64_PGTABLE_LEVELS > 2 */
407 406
@@ -437,6 +436,8 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long addr)
437 return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(addr); 436 return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(addr);
438} 437}
439 438
439#define pgd_page(pgd) pfn_to_page(__phys_to_pfn(pgd_val(pgd) & PHYS_MASK))
440
440#endif /* CONFIG_ARM64_PGTABLE_LEVELS > 3 */ 441#endif /* CONFIG_ARM64_PGTABLE_LEVELS > 3 */
441 442
442#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd)) 443#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index 3771b72b6569..2d6b6065fe7f 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -5,6 +5,7 @@
5#include <asm/debug-monitors.h> 5#include <asm/debug-monitors.h>
6#include <asm/pgtable.h> 6#include <asm/pgtable.h>
7#include <asm/memory.h> 7#include <asm/memory.h>
8#include <asm/mmu_context.h>
8#include <asm/smp_plat.h> 9#include <asm/smp_plat.h>
9#include <asm/suspend.h> 10#include <asm/suspend.h>
10#include <asm/tlbflush.h> 11#include <asm/tlbflush.h>
@@ -98,7 +99,18 @@ int __cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
98 */ 99 */
99 ret = __cpu_suspend_enter(arg, fn); 100 ret = __cpu_suspend_enter(arg, fn);
100 if (ret == 0) { 101 if (ret == 0) {
101 cpu_switch_mm(mm->pgd, mm); 102 /*
103 * We are resuming from reset with TTBR0_EL1 set to the
104 * idmap to enable the MMU; restore the active_mm mappings in
105 * TTBR0_EL1 unless the active_mm == &init_mm, in which case
106 * the thread entered __cpu_suspend with TTBR0_EL1 set to
107 * reserved TTBR0 page tables and should be restored as such.
108 */
109 if (mm == &init_mm)
110 cpu_set_reserved_ttbr0();
111 else
112 cpu_switch_mm(mm->pgd, mm);
113
102 flush_tlb_all(); 114 flush_tlb_all();
103 115
104 /* 116 /*
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
index f3b51b57740a..95c39b95e97e 100644
--- a/arch/ia64/include/asm/unistd.h
+++ b/arch/ia64/include/asm/unistd.h
@@ -11,7 +11,7 @@
11 11
12 12
13 13
14#define NR_syscalls 318 /* length of syscall table */ 14#define NR_syscalls 319 /* length of syscall table */
15 15
16/* 16/*
17 * The following defines stop scripts/checksyscalls.sh from complaining about 17 * The following defines stop scripts/checksyscalls.sh from complaining about
diff --git a/arch/ia64/include/uapi/asm/unistd.h b/arch/ia64/include/uapi/asm/unistd.h
index 4c2240c1b0cb..461079560c78 100644
--- a/arch/ia64/include/uapi/asm/unistd.h
+++ b/arch/ia64/include/uapi/asm/unistd.h
@@ -331,5 +331,6 @@
331#define __NR_getrandom 1339 331#define __NR_getrandom 1339
332#define __NR_memfd_create 1340 332#define __NR_memfd_create 1340
333#define __NR_bpf 1341 333#define __NR_bpf 1341
334#define __NR_execveat 1342
334 335
335#endif /* _UAPI_ASM_IA64_UNISTD_H */ 336#endif /* _UAPI_ASM_IA64_UNISTD_H */
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index f5e96dffc63c..fcf8b8cbca0b 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1779,6 +1779,7 @@ sys_call_table:
1779 data8 sys_getrandom 1779 data8 sys_getrandom
1780 data8 sys_memfd_create // 1340 1780 data8 sys_memfd_create // 1340
1781 data8 sys_bpf 1781 data8 sys_bpf
1782 data8 sys_execveat
1782 1783
1783 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls 1784 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
1784#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ 1785#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
diff --git a/arch/nios2/kernel/cpuinfo.c b/arch/nios2/kernel/cpuinfo.c
index 51d5bb90d3e5..a223691dff4f 100644
--- a/arch/nios2/kernel/cpuinfo.c
+++ b/arch/nios2/kernel/cpuinfo.c
@@ -72,6 +72,7 @@ void __init setup_cpuinfo(void)
72 cpuinfo.has_div = fcpu_has(cpu, "altr,has-div"); 72 cpuinfo.has_div = fcpu_has(cpu, "altr,has-div");
73 cpuinfo.has_mul = fcpu_has(cpu, "altr,has-mul"); 73 cpuinfo.has_mul = fcpu_has(cpu, "altr,has-mul");
74 cpuinfo.has_mulx = fcpu_has(cpu, "altr,has-mulx"); 74 cpuinfo.has_mulx = fcpu_has(cpu, "altr,has-mulx");
75 cpuinfo.mmu = fcpu_has(cpu, "altr,has-mmu");
75 76
76 if (IS_ENABLED(CONFIG_NIOS2_HW_DIV_SUPPORT) && !cpuinfo.has_div) 77 if (IS_ENABLED(CONFIG_NIOS2_HW_DIV_SUPPORT) && !cpuinfo.has_div)
77 err_cpu("DIV"); 78 err_cpu("DIV");
diff --git a/arch/nios2/kernel/entry.S b/arch/nios2/kernel/entry.S
index 83bca17d1008..0bdfd13ff98b 100644
--- a/arch/nios2/kernel/entry.S
+++ b/arch/nios2/kernel/entry.S
@@ -365,30 +365,14 @@ ENTRY(ret_from_interrupt)
365 GET_THREAD_INFO r1 365 GET_THREAD_INFO r1
366 ldw r4, TI_PREEMPT_COUNT(r1) 366 ldw r4, TI_PREEMPT_COUNT(r1)
367 bne r4, r0, restore_all 367 bne r4, r0, restore_all
368
369need_resched:
370 ldw r4, TI_FLAGS(r1) /* ? Need resched set */ 368 ldw r4, TI_FLAGS(r1) /* ? Need resched set */
371 BTBZ r10, r4, TIF_NEED_RESCHED, restore_all 369 BTBZ r10, r4, TIF_NEED_RESCHED, restore_all
372 ldw r4, PT_ESTATUS(sp) /* ? Interrupts off */ 370 ldw r4, PT_ESTATUS(sp) /* ? Interrupts off */
373 andi r10, r4, ESTATUS_EPIE 371 andi r10, r4, ESTATUS_EPIE
374 beq r10, r0, restore_all 372 beq r10, r0, restore_all
375 movia r4, PREEMPT_ACTIVE 373 call preempt_schedule_irq
376 stw r4, TI_PREEMPT_COUNT(r1)
377 rdctl r10, status /* enable intrs again */
378 ori r10, r10 ,STATUS_PIE
379 wrctl status, r10
380 PUSH r1
381 call schedule
382 POP r1
383 mov r4, r0
384 stw r4, TI_PREEMPT_COUNT(r1)
385 rdctl r10, status /* disable intrs */
386 andi r10, r10, %lo(~STATUS_PIE)
387 wrctl status, r10
388 br need_resched
389#else
390 br restore_all
391#endif 374#endif
375 br restore_all
392 376
393/*********************************************************************** 377/***********************************************************************
394 * A few syscall wrappers 378 * A few syscall wrappers
diff --git a/arch/parisc/include/asm/ldcw.h b/arch/parisc/include/asm/ldcw.h
index d2d11b7055ba..8121aa6db2ff 100644
--- a/arch/parisc/include/asm/ldcw.h
+++ b/arch/parisc/include/asm/ldcw.h
@@ -33,11 +33,18 @@
33 33
34#endif /*!CONFIG_PA20*/ 34#endif /*!CONFIG_PA20*/
35 35
36/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ 36/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*.
37 We don't explicitly expose that "*a" may be written as reload
38 fails to find a register in class R1_REGS when "a" needs to be
39 reloaded when generating 64-bit PIC code. Instead, we clobber
40 memory to indicate to the compiler that the assembly code reads
41 or writes to items other than those listed in the input and output
42 operands. This may pessimize the code somewhat but __ldcw is
43 usually used within code blocks surrounded by memory barriors. */
37#define __ldcw(a) ({ \ 44#define __ldcw(a) ({ \
38 unsigned __ret; \ 45 unsigned __ret; \
39 __asm__ __volatile__(__LDCW " 0(%2),%0" \ 46 __asm__ __volatile__(__LDCW " 0(%1),%0" \
40 : "=r" (__ret), "+m" (*(a)) : "r" (a)); \ 47 : "=r" (__ret) : "r" (a) : "memory"); \
41 __ret; \ 48 __ret; \
42}) 49})
43 50
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index 19c36cba37c4..a46f5f45570c 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -86,6 +86,11 @@ extern int overlaps_crashkernel(unsigned long start, unsigned long size);
86extern void reserve_crashkernel(void); 86extern void reserve_crashkernel(void);
87extern void machine_kexec_mask_interrupts(void); 87extern void machine_kexec_mask_interrupts(void);
88 88
89static inline bool kdump_in_progress(void)
90{
91 return crashing_cpu >= 0;
92}
93
89#else /* !CONFIG_KEXEC */ 94#else /* !CONFIG_KEXEC */
90static inline void crash_kexec_secondary(struct pt_regs *regs) { } 95static inline void crash_kexec_secondary(struct pt_regs *regs) { }
91 96
@@ -106,6 +111,11 @@ static inline int crash_shutdown_unregister(crash_shutdown_t handler)
106 return 0; 111 return 0;
107} 112}
108 113
114static inline bool kdump_in_progress(void)
115{
116 return false;
117}
118
109#endif /* CONFIG_KEXEC */ 119#endif /* CONFIG_KEXEC */
110#endif /* ! __ASSEMBLY__ */ 120#endif /* ! __ASSEMBLY__ */
111#endif /* __KERNEL__ */ 121#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index ce9577d693be..91062eef582f 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -366,3 +366,4 @@ SYSCALL_SPU(seccomp)
366SYSCALL_SPU(getrandom) 366SYSCALL_SPU(getrandom)
367SYSCALL_SPU(memfd_create) 367SYSCALL_SPU(memfd_create)
368SYSCALL_SPU(bpf) 368SYSCALL_SPU(bpf)
369COMPAT_SYS(execveat)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index e0da021caa00..36b79c31eedd 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -12,7 +12,7 @@
12#include <uapi/asm/unistd.h> 12#include <uapi/asm/unistd.h>
13 13
14 14
15#define __NR_syscalls 362 15#define __NR_syscalls 363
16 16
17#define __NR__exit __NR_exit 17#define __NR__exit __NR_exit
18#define NR_syscalls __NR_syscalls 18#define NR_syscalls __NR_syscalls
diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h
index f55351f2e66e..ef5b5b1f3123 100644
--- a/arch/powerpc/include/uapi/asm/unistd.h
+++ b/arch/powerpc/include/uapi/asm/unistd.h
@@ -384,5 +384,6 @@
384#define __NR_getrandom 359 384#define __NR_getrandom 359
385#define __NR_memfd_create 360 385#define __NR_memfd_create 360
386#define __NR_bpf 361 386#define __NR_bpf 361
387#define __NR_execveat 362
387 388
388#endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ 389#endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 879b3aacac32..f96d1ec24189 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -330,7 +330,7 @@ void default_machine_kexec(struct kimage *image)
330 * using debugger IPI. 330 * using debugger IPI.
331 */ 331 */
332 332
333 if (crashing_cpu == -1) 333 if (!kdump_in_progress())
334 kexec_prepare_cpus(); 334 kexec_prepare_cpus();
335 335
336 pr_debug("kexec: Starting switchover sequence.\n"); 336 pr_debug("kexec: Starting switchover sequence.\n");
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 8ec017cb4446..8b2d2dc8ef10 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -700,6 +700,7 @@ void start_secondary(void *unused)
700 smp_store_cpu_info(cpu); 700 smp_store_cpu_info(cpu);
701 set_dec(tb_ticks_per_jiffy); 701 set_dec(tb_ticks_per_jiffy);
702 preempt_disable(); 702 preempt_disable();
703 cpu_callin_map[cpu] = 1;
703 704
704 if (smp_ops->setup_cpu) 705 if (smp_ops->setup_cpu)
705 smp_ops->setup_cpu(cpu); 706 smp_ops->setup_cpu(cpu);
@@ -738,14 +739,6 @@ void start_secondary(void *unused)
738 notify_cpu_starting(cpu); 739 notify_cpu_starting(cpu);
739 set_cpu_online(cpu, true); 740 set_cpu_online(cpu, true);
740 741
741 /*
742 * CPU must be marked active and online before we signal back to the
743 * master, because the scheduler needs to see the cpu_online and
744 * cpu_active bits set.
745 */
746 smp_wmb();
747 cpu_callin_map[cpu] = 1;
748
749 local_irq_enable(); 742 local_irq_enable();
750 743
751 cpu_startup_entry(CPUHP_ONLINE); 744 cpu_startup_entry(CPUHP_ONLINE);
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 469751d92004..b5682fd6c984 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -43,6 +43,7 @@
43#include <asm/trace.h> 43#include <asm/trace.h>
44#include <asm/firmware.h> 44#include <asm/firmware.h>
45#include <asm/plpar_wrappers.h> 45#include <asm/plpar_wrappers.h>
46#include <asm/kexec.h>
46#include <asm/fadump.h> 47#include <asm/fadump.h>
47 48
48#include "pseries.h" 49#include "pseries.h"
@@ -267,8 +268,13 @@ static void pSeries_lpar_hptab_clear(void)
267 * out to the user, but at least this will stop us from 268 * out to the user, but at least this will stop us from
268 * continuing on further and creating an even more 269 * continuing on further and creating an even more
269 * difficult to debug situation. 270 * difficult to debug situation.
271 *
272 * There is a known problem when kdump'ing, if cpus are offline
273 * the above call will fail. Rather than panicking again, keep
274 * going and hope the kdump kernel is also little endian, which
275 * it usually is.
270 */ 276 */
271 if (rc) 277 if (rc && !kdump_in_progress())
272 panic("Could not enable big endian exceptions"); 278 panic("Could not enable big endian exceptions");
273 } 279 }
274#endif 280#endif
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index 87bc86821bc9..d195a87ca542 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -3,6 +3,7 @@ config UML
3 default y 3 default y
4 select HAVE_ARCH_AUDITSYSCALL 4 select HAVE_ARCH_AUDITSYSCALL
5 select HAVE_UID16 5 select HAVE_UID16
6 select HAVE_FUTEX_CMPXCHG if FUTEX
6 select GENERIC_IRQ_SHOW 7 select GENERIC_IRQ_SHOW
7 select GENERIC_CPU_DEVICES 8 select GENERIC_CPU_DEVICES
8 select GENERIC_IO 9 select GENERIC_IO
diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
index 7c523bbf3dc8..0dd8d089c315 100644
--- a/arch/x86/kernel/kprobes/opt.c
+++ b/arch/x86/kernel/kprobes/opt.c
@@ -322,7 +322,8 @@ void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
322 * Target instructions MUST be relocatable (checked inside) 322 * Target instructions MUST be relocatable (checked inside)
323 * This is called when new aggr(opt)probe is allocated or reused. 323 * This is called when new aggr(opt)probe is allocated or reused.
324 */ 324 */
325int arch_prepare_optimized_kprobe(struct optimized_kprobe *op) 325int arch_prepare_optimized_kprobe(struct optimized_kprobe *op,
326 struct kprobe *__unused)
326{ 327{
327 u8 *buf; 328 u8 *buf;
328 int ret; 329 int ret;
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 10fbed126b11..f83fc6c5e0ba 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -4448,7 +4448,7 @@ void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm)
4448 * zap all shadow pages. 4448 * zap all shadow pages.
4449 */ 4449 */
4450 if (unlikely(kvm_current_mmio_generation(kvm) == 0)) { 4450 if (unlikely(kvm_current_mmio_generation(kvm) == 0)) {
4451 printk_ratelimited(KERN_INFO "kvm: zapping shadow pages for mmio generation wraparound\n"); 4451 printk_ratelimited(KERN_DEBUG "kvm: zapping shadow pages for mmio generation wraparound\n");
4452 kvm_mmu_invalidate_zap_all_pages(kvm); 4452 kvm_mmu_invalidate_zap_all_pages(kvm);
4453 } 4453 }
4454} 4454}
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index feb852b04598..d4c58d884838 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5840,53 +5840,10 @@ static __init int hardware_setup(void)
5840 memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE); 5840 memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE);
5841 memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE); 5841 memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE);
5842 5842
5843 vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
5844 vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
5845 vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
5846 vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
5847 vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
5848 vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
5849 vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true);
5850
5851 memcpy(vmx_msr_bitmap_legacy_x2apic,
5852 vmx_msr_bitmap_legacy, PAGE_SIZE);
5853 memcpy(vmx_msr_bitmap_longmode_x2apic,
5854 vmx_msr_bitmap_longmode, PAGE_SIZE);
5855
5856 if (enable_apicv) {
5857 for (msr = 0x800; msr <= 0x8ff; msr++)
5858 vmx_disable_intercept_msr_read_x2apic(msr);
5859
5860 /* According SDM, in x2apic mode, the whole id reg is used.
5861 * But in KVM, it only use the highest eight bits. Need to
5862 * intercept it */
5863 vmx_enable_intercept_msr_read_x2apic(0x802);
5864 /* TMCCT */
5865 vmx_enable_intercept_msr_read_x2apic(0x839);
5866 /* TPR */
5867 vmx_disable_intercept_msr_write_x2apic(0x808);
5868 /* EOI */
5869 vmx_disable_intercept_msr_write_x2apic(0x80b);
5870 /* SELF-IPI */
5871 vmx_disable_intercept_msr_write_x2apic(0x83f);
5872 }
5873
5874 if (enable_ept) {
5875 kvm_mmu_set_mask_ptes(0ull,
5876 (enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull,
5877 (enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull,
5878 0ull, VMX_EPT_EXECUTABLE_MASK);
5879 ept_set_mmio_spte_mask();
5880 kvm_enable_tdp();
5881 } else
5882 kvm_disable_tdp();
5883
5884 update_ple_window_actual_max();
5885
5886 if (setup_vmcs_config(&vmcs_config) < 0) { 5843 if (setup_vmcs_config(&vmcs_config) < 0) {
5887 r = -EIO; 5844 r = -EIO;
5888 goto out7; 5845 goto out7;
5889 } 5846 }
5890 5847
5891 if (boot_cpu_has(X86_FEATURE_NX)) 5848 if (boot_cpu_has(X86_FEATURE_NX))
5892 kvm_enable_efer_bits(EFER_NX); 5849 kvm_enable_efer_bits(EFER_NX);
@@ -5945,6 +5902,49 @@ static __init int hardware_setup(void)
5945 if (nested) 5902 if (nested)
5946 nested_vmx_setup_ctls_msrs(); 5903 nested_vmx_setup_ctls_msrs();
5947 5904
5905 vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
5906 vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
5907 vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
5908 vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
5909 vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
5910 vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
5911 vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true);
5912
5913 memcpy(vmx_msr_bitmap_legacy_x2apic,
5914 vmx_msr_bitmap_legacy, PAGE_SIZE);
5915 memcpy(vmx_msr_bitmap_longmode_x2apic,
5916 vmx_msr_bitmap_longmode, PAGE_SIZE);
5917
5918 if (enable_apicv) {
5919 for (msr = 0x800; msr <= 0x8ff; msr++)
5920 vmx_disable_intercept_msr_read_x2apic(msr);
5921
5922 /* According SDM, in x2apic mode, the whole id reg is used.
5923 * But in KVM, it only use the highest eight bits. Need to
5924 * intercept it */
5925 vmx_enable_intercept_msr_read_x2apic(0x802);
5926 /* TMCCT */
5927 vmx_enable_intercept_msr_read_x2apic(0x839);
5928 /* TPR */
5929 vmx_disable_intercept_msr_write_x2apic(0x808);
5930 /* EOI */
5931 vmx_disable_intercept_msr_write_x2apic(0x80b);
5932 /* SELF-IPI */
5933 vmx_disable_intercept_msr_write_x2apic(0x83f);
5934 }
5935
5936 if (enable_ept) {
5937 kvm_mmu_set_mask_ptes(0ull,
5938 (enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull,
5939 (enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull,
5940 0ull, VMX_EPT_EXECUTABLE_MASK);
5941 ept_set_mmio_spte_mask();
5942 kvm_enable_tdp();
5943 } else
5944 kvm_disable_tdp();
5945
5946 update_ple_window_actual_max();
5947
5948 return alloc_kvm_area(); 5948 return alloc_kvm_area();
5949 5949
5950out7: 5950out7:
diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c
index 531d4269e2e3..bd16d6c370ec 100644
--- a/arch/x86/um/sys_call_table_32.c
+++ b/arch/x86/um/sys_call_table_32.c
@@ -34,7 +34,7 @@ typedef asmlinkage void (*sys_call_ptr_t)(void);
34 34
35extern asmlinkage void sys_ni_syscall(void); 35extern asmlinkage void sys_ni_syscall(void);
36 36
37const sys_call_ptr_t sys_call_table[] __cacheline_aligned = { 37const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
38 /* 38 /*
39 * Smells like a compiler bug -- it doesn't work 39 * Smells like a compiler bug -- it doesn't work
40 * when the & below is removed. 40 * when the & below is removed.
diff --git a/arch/x86/um/sys_call_table_64.c b/arch/x86/um/sys_call_table_64.c
index 20c3649d0691..5cdfa9db2217 100644
--- a/arch/x86/um/sys_call_table_64.c
+++ b/arch/x86/um/sys_call_table_64.c
@@ -47,7 +47,7 @@ typedef void (*sys_call_ptr_t)(void);
47 47
48extern void sys_ni_syscall(void); 48extern void sys_ni_syscall(void);
49 49
50const sys_call_ptr_t sys_call_table[] __cacheline_aligned = { 50const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
51 /* 51 /*
52 * Smells like a compiler bug -- it doesn't work 52 * Smells like a compiler bug -- it doesn't work
53 * when the & below is removed. 53 * when the & below is removed.