aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-05 16:20:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-05 16:20:43 -0400
commit2d1eb87ae1e6f3999e77989fd2f831b134270787 (patch)
treeadf505adb17c96929c797920613afa3dc5731650 /arch
parent2f997759dffe5458446075a58734df39d8035e6e (diff)
parentbce5669be3a8946952258a064ef26defeb887138 (diff)
Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm
Pull ARM changes from Russell King: - Perf updates from Will Deacon: - Support for Qualcomm Krait processors (run perf on your phone!) - Support for Cortex-A12 (run perf stat on your FPGA!) - Support for perf_sample_event_took, allowing us to automatically decrease the sample rate if we can't handle the PMU interrupts quickly enough (run perf record on your FPGA!). - Basic uprobes support from David Long: This patch series adds basic uprobes support to ARM. It is based on patches developed earlier by Rabin Vincent. That approach of adding hooks into the kprobes instruction parsing code was not well received. This approach separates the ARM instruction parsing code in kprobes out into a separate set of functions which can be used by both kprobes and uprobes. Both kprobes and uprobes then provide their own semantic action tables to process the results of the parsing. - ARMv7M (microcontroller) updates from Uwe Kleine-König - OMAP DMA updates (recently added Vinod's Ack even though they've been sitting in linux-next for a few months) to reduce the reliance of omap-dma on the code in arch/arm. - SA11x0 changes from Dmitry Eremin-Solenikov and Alexander Shiyan - Support for Cortex-A12 CPU - Align support for ARMv6 with ARMv7 so they can cooperate better in a single zImage. - Addition of first AT_HWCAP2 feature bits for ARMv8 crypto support. - Removal of IRQ_DISABLED from various ARM files - Improved efficiency of virt_to_page() for single zImage - Patch from Ulf Hansson to permit runtime PM callbacks to be available for AMBA devices for suspend/resume as well. - Finally kill asm/system.h on ARM. * 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm: (89 commits) dmaengine: omap-dma: more consolidation of CCR register setup dmaengine: omap-dma: move IRQ handling to omap-dma dmaengine: omap-dma: move register read/writes into omap-dma.c ARM: omap: dma: get rid of 'p' allocation and clean up ARM: omap: move dma channel allocation into plat-omap code ARM: omap: dma: get rid of errata global ARM: omap: clean up DMA register accesses ARM: omap: remove almost-const variables ARM: omap: remove references to disable_irq_lch dmaengine: omap-dma: cleanup errata 3.3 handling dmaengine: omap-dma: provide register read/write functions dmaengine: omap-dma: use cached CCR value when enabling DMA dmaengine: omap-dma: move barrier to omap_dma_start_desc() dmaengine: omap-dma: move clnk_ctrl setting to preparation functions dmaengine: omap-dma: improve efficiency loading C.SA/C.EI/C.FI registers dmaengine: omap-dma: consolidate clearing channel status register dmaengine: omap-dma: move CCR buffering disable errata out of the fast path dmaengine: omap-dma: provide register definitions dmaengine: omap-dma: consolidate setup of CCR dmaengine: omap-dma: consolidate setup of CSDP ...
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig6
-rw-r--r--arch/arm/Kconfig5
-rw-r--r--arch/arm/common/Makefile1
-rw-r--r--arch/arm/common/scoop.c2
-rw-r--r--arch/arm/include/asm/assembler.h8
-rw-r--r--arch/arm/include/asm/atomic.h44
-rw-r--r--arch/arm/include/asm/cmpxchg.h6
-rw-r--r--arch/arm/include/asm/cputype.h1
-rw-r--r--arch/arm/include/asm/floppy.h2
-rw-r--r--arch/arm/include/asm/futex.h9
-rw-r--r--arch/arm/include/asm/hw_breakpoint.h1
-rw-r--r--arch/arm/include/asm/hwcap.h3
-rw-r--r--arch/arm/include/asm/jump_label.h1
-rw-r--r--arch/arm/include/asm/kprobes.h17
-rw-r--r--arch/arm/include/asm/memory.h41
-rw-r--r--arch/arm/include/asm/pgtable-2level.h1
-rw-r--r--arch/arm/include/asm/pgtable.h7
-rw-r--r--arch/arm/include/asm/pmu.h2
-rw-r--r--arch/arm/include/asm/probes.h43
-rw-r--r--arch/arm/include/asm/ptrace.h14
-rw-r--r--arch/arm/include/asm/sync_bitops.h1
-rw-r--r--arch/arm/include/asm/system.h7
-rw-r--r--arch/arm/include/asm/thread_info.h5
-rw-r--r--arch/arm/include/asm/uaccess.h2
-rw-r--r--arch/arm/include/asm/unistd.h1
-rw-r--r--arch/arm/include/asm/uprobes.h45
-rw-r--r--arch/arm/include/uapi/asm/hwcap.h9
-rw-r--r--arch/arm/kernel/Makefile7
-rw-r--r--arch/arm/kernel/armksyms.c2
-rw-r--r--arch/arm/kernel/bios32.c37
-rw-r--r--arch/arm/kernel/head.S17
-rw-r--r--arch/arm/kernel/hw_breakpoint.c3
-rw-r--r--arch/arm/kernel/kprobes-arm.c806
-rw-r--r--arch/arm/kernel/kprobes-common.c469
-rw-r--r--arch/arm/kernel/kprobes-test-arm.c1
-rw-r--r--arch/arm/kernel/kprobes-test.c12
-rw-r--r--arch/arm/kernel/kprobes-thumb.c1145
-rw-r--r--arch/arm/kernel/kprobes.c25
-rw-r--r--arch/arm/kernel/kprobes.h400
-rw-r--r--arch/arm/kernel/perf_event.c27
-rw-r--r--arch/arm/kernel/perf_event_cpu.c113
-rw-r--r--arch/arm/kernel/perf_event_v7.c717
-rw-r--r--arch/arm/kernel/probes-arm.c734
-rw-r--r--arch/arm/kernel/probes-arm.h73
-rw-r--r--arch/arm/kernel/probes-thumb.c882
-rw-r--r--arch/arm/kernel/probes-thumb.h97
-rw-r--r--arch/arm/kernel/probes.c455
-rw-r--r--arch/arm/kernel/probes.h407
-rw-r--r--arch/arm/kernel/process.c9
-rw-r--r--arch/arm/kernel/setup.c16
-rw-r--r--arch/arm/kernel/signal.c4
-rw-r--r--arch/arm/kernel/unwind.c137
-rw-r--r--arch/arm/kernel/uprobes-arm.c234
-rw-r--r--arch/arm/kernel/uprobes.c210
-rw-r--r--arch/arm/kernel/uprobes.h35
-rw-r--r--arch/arm/lib/bitops.h5
-rw-r--r--arch/arm/lib/copy_template.S36
-rw-r--r--arch/arm/lib/csumpartialcopygeneric.S96
-rw-r--r--arch/arm/lib/io-readsl.S12
-rw-r--r--arch/arm/lib/io-writesl.S12
-rw-r--r--arch/arm/lib/memmove.S36
-rw-r--r--arch/arm/lib/uaccess.S192
-rw-r--r--arch/arm/mach-cns3xxx/core.c2
-rw-r--r--arch/arm/mach-ebsa110/core.c2
-rw-r--r--arch/arm/mach-footbridge/dc21285-timer.c6
-rw-r--r--arch/arm/mach-footbridge/dc21285.c10
-rw-r--r--arch/arm/mach-footbridge/isa-timer.c2
-rw-r--r--arch/arm/mach-gemini/idle.c2
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c2
-rw-r--r--arch/arm/mach-ixp4xx/common.c2
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-setup.c3
-rw-r--r--arch/arm/mach-ixp4xx/fsg-setup.c6
-rw-r--r--arch/arm/mach-ixp4xx/nas100d-setup.c3
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-setup.c6
-rw-r--r--arch/arm/mach-ks8695/time.c2
-rw-r--r--arch/arm/mach-lpc32xx/timer.c2
-rw-r--r--arch/arm/mach-mmp/time.c2
-rw-r--r--arch/arm/mach-netx/time.c2
-rw-r--r--arch/arm/mach-omap1/dma.c191
-rw-r--r--arch/arm/mach-omap2/am35xx-emac.c1
-rw-r--r--arch/arm/mach-omap2/dma.c183
-rw-r--r--arch/arm/mach-rpc/dma.c2
-rw-r--r--arch/arm/mach-rpc/time.c1
-rw-r--r--arch/arm/mach-sa1100/collie.c33
-rw-r--r--arch/arm/mach-sa1100/h3100.c7
-rw-r--r--arch/arm/mach-sa1100/h3600.c7
-rw-r--r--arch/arm/mach-sa1100/h3xxx.c58
-rw-r--r--arch/arm/mach-sa1100/include/mach/collie.h2
-rw-r--r--arch/arm/mach-sa1100/include/mach/h3xxx.h11
-rw-r--r--arch/arm/mach-sa1100/time.c2
-rw-r--r--arch/arm/mach-spear/time.c2
-rw-r--r--arch/arm/mach-vexpress/Makefile3
-rw-r--r--arch/arm/mach-w90x900/time.c2
-rw-r--r--arch/arm/mm/Kconfig3
-rw-r--r--arch/arm/mm/cache-feroceon-l2.c4
-rw-r--r--arch/arm/mm/dma-mapping.c3
-rw-r--r--arch/arm/mm/mmu.c10
-rw-r--r--arch/arm/mm/proc-macros.S19
-rw-r--r--arch/arm/mm/proc-v7-2level.S7
-rw-r--r--arch/arm/mm/proc-v7.S11
-rw-r--r--arch/arm/plat-iop/time.c2
-rw-r--r--arch/arm/plat-omap/dma.c17
102 files changed, 5100 insertions, 3282 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 80bbb8ccd0d1..97ff872c7acc 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -86,9 +86,7 @@ config KPROBES_ON_FTRACE
86 optimize on top of function tracing. 86 optimize on top of function tracing.
87 87
88config UPROBES 88config UPROBES
89 bool "Transparent user-space probes (EXPERIMENTAL)" 89 def_bool n
90 depends on UPROBE_EVENT && PERF_EVENTS
91 default n
92 select PERCPU_RWSEM 90 select PERCPU_RWSEM
93 help 91 help
94 Uprobes is the user-space counterpart to kprobes: they 92 Uprobes is the user-space counterpart to kprobes: they
@@ -101,8 +99,6 @@ config UPROBES
101 managed by the kernel and kept transparent to the probed 99 managed by the kernel and kept transparent to the probed
102 application. ) 100 application. )
103 101
104 If in doubt, say "N".
105
106config HAVE_64BIT_ALIGNED_ACCESS 102config HAVE_64BIT_ALIGNED_ACCESS
107 def_bool 64BIT && !HAVE_EFFICIENT_UNALIGNED_ACCESS 103 def_bool 64BIT && !HAVE_EFFICIENT_UNALIGNED_ACCESS
108 help 104 help
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 503da0a2a8ea..6b4ac5de6dec 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -207,6 +207,9 @@ config ZONE_DMA
207config NEED_DMA_MAP_STATE 207config NEED_DMA_MAP_STATE
208 def_bool y 208 def_bool y
209 209
210config ARCH_SUPPORTS_UPROBES
211 def_bool y
212
210config ARCH_HAS_DMA_SET_COHERENT_MASK 213config ARCH_HAS_DMA_SET_COHERENT_MASK
211 bool 214 bool
212 215
@@ -2271,7 +2274,7 @@ source "kernel/power/Kconfig"
2271config ARCH_SUSPEND_POSSIBLE 2274config ARCH_SUSPEND_POSSIBLE
2272 depends on !ARCH_S5PC100 2275 depends on !ARCH_S5PC100
2273 depends on CPU_ARM920T || CPU_ARM926T || CPU_FEROCEON || CPU_SA1100 || \ 2276 depends on CPU_ARM920T || CPU_ARM926T || CPU_FEROCEON || CPU_SA1100 || \
2274 CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE || CPU_MOHAWK 2277 CPU_V6 || CPU_V6K || CPU_V7 || CPU_V7M || CPU_XSC3 || CPU_XSCALE || CPU_MOHAWK
2275 def_bool y 2278 def_bool y
2276 2279
2277config ARM_CPU_SUSPEND 2280config ARM_CPU_SUSPEND
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 4bdc41622c36..70b1eff477b3 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_SHARP_SCOOP) += scoop.o
13obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o 13obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
14obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o 14obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
15obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o 15obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o
16CFLAGS_REMOVE_mcpm_entry.o = -pg
16AFLAGS_mcpm_head.o := -march=armv7-a 17AFLAGS_mcpm_head.o := -march=armv7-a
17AFLAGS_vlock.o := -march=armv7-a 18AFLAGS_vlock.o := -march=armv7-a
18obj-$(CONFIG_TI_PRIV_EDMA) += edma.o 19obj-$(CONFIG_TI_PRIV_EDMA) += edma.o
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index a5c3dc38aa18..6ef146edd0cd 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -232,8 +232,6 @@ static int scoop_probe(struct platform_device *pdev)
232 232
233 return 0; 233 return 0;
234 234
235 if (devptr->gpio.base != -1)
236 temp = gpiochip_remove(&devptr->gpio);
237err_gpio: 235err_gpio:
238 platform_set_drvdata(pdev, NULL); 236 platform_set_drvdata(pdev, NULL);
239err_ioremap: 237err_ioremap:
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 5c2285160575..380ac4f20000 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -30,8 +30,8 @@
30 * Endian independent macros for shifting bytes within registers. 30 * Endian independent macros for shifting bytes within registers.
31 */ 31 */
32#ifndef __ARMEB__ 32#ifndef __ARMEB__
33#define pull lsr 33#define lspull lsr
34#define push lsl 34#define lspush lsl
35#define get_byte_0 lsl #0 35#define get_byte_0 lsl #0
36#define get_byte_1 lsr #8 36#define get_byte_1 lsr #8
37#define get_byte_2 lsr #16 37#define get_byte_2 lsr #16
@@ -41,8 +41,8 @@
41#define put_byte_2 lsl #16 41#define put_byte_2 lsl #16
42#define put_byte_3 lsl #24 42#define put_byte_3 lsl #24
43#else 43#else
44#define pull lsl 44#define lspull lsl
45#define push lsr 45#define lspush lsr
46#define get_byte_0 lsr #24 46#define get_byte_0 lsr #24
47#define get_byte_1 lsr #16 47#define get_byte_1 lsr #16
48#define get_byte_2 lsr #8 48#define get_byte_2 lsr #8
diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
index 62d2cb53b069..9a92fd7864a8 100644
--- a/arch/arm/include/asm/atomic.h
+++ b/arch/arm/include/asm/atomic.h
@@ -60,6 +60,7 @@ static inline int atomic_add_return(int i, atomic_t *v)
60 int result; 60 int result;
61 61
62 smp_mb(); 62 smp_mb();
63 prefetchw(&v->counter);
63 64
64 __asm__ __volatile__("@ atomic_add_return\n" 65 __asm__ __volatile__("@ atomic_add_return\n"
65"1: ldrex %0, [%3]\n" 66"1: ldrex %0, [%3]\n"
@@ -99,6 +100,7 @@ static inline int atomic_sub_return(int i, atomic_t *v)
99 int result; 100 int result;
100 101
101 smp_mb(); 102 smp_mb();
103 prefetchw(&v->counter);
102 104
103 __asm__ __volatile__("@ atomic_sub_return\n" 105 __asm__ __volatile__("@ atomic_sub_return\n"
104"1: ldrex %0, [%3]\n" 106"1: ldrex %0, [%3]\n"
@@ -121,6 +123,7 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
121 unsigned long res; 123 unsigned long res;
122 124
123 smp_mb(); 125 smp_mb();
126 prefetchw(&ptr->counter);
124 127
125 do { 128 do {
126 __asm__ __volatile__("@ atomic_cmpxchg\n" 129 __asm__ __volatile__("@ atomic_cmpxchg\n"
@@ -138,6 +141,33 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
138 return oldval; 141 return oldval;
139} 142}
140 143
144static inline int __atomic_add_unless(atomic_t *v, int a, int u)
145{
146 int oldval, newval;
147 unsigned long tmp;
148
149 smp_mb();
150 prefetchw(&v->counter);
151
152 __asm__ __volatile__ ("@ atomic_add_unless\n"
153"1: ldrex %0, [%4]\n"
154" teq %0, %5\n"
155" beq 2f\n"
156" add %1, %0, %6\n"
157" strex %2, %1, [%4]\n"
158" teq %2, #0\n"
159" bne 1b\n"
160"2:"
161 : "=&r" (oldval), "=&r" (newval), "=&r" (tmp), "+Qo" (v->counter)
162 : "r" (&v->counter), "r" (u), "r" (a)
163 : "cc");
164
165 if (oldval != u)
166 smp_mb();
167
168 return oldval;
169}
170
141#else /* ARM_ARCH_6 */ 171#else /* ARM_ARCH_6 */
142 172
143#ifdef CONFIG_SMP 173#ifdef CONFIG_SMP
@@ -186,10 +216,6 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
186 return ret; 216 return ret;
187} 217}
188 218
189#endif /* __LINUX_ARM_ARCH__ */
190
191#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
192
193static inline int __atomic_add_unless(atomic_t *v, int a, int u) 219static inline int __atomic_add_unless(atomic_t *v, int a, int u)
194{ 220{
195 int c, old; 221 int c, old;
@@ -200,6 +226,10 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
200 return c; 226 return c;
201} 227}
202 228
229#endif /* __LINUX_ARM_ARCH__ */
230
231#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
232
203#define atomic_inc(v) atomic_add(1, v) 233#define atomic_inc(v) atomic_add(1, v)
204#define atomic_dec(v) atomic_sub(1, v) 234#define atomic_dec(v) atomic_sub(1, v)
205 235
@@ -299,6 +329,7 @@ static inline long long atomic64_add_return(long long i, atomic64_t *v)
299 unsigned long tmp; 329 unsigned long tmp;
300 330
301 smp_mb(); 331 smp_mb();
332 prefetchw(&v->counter);
302 333
303 __asm__ __volatile__("@ atomic64_add_return\n" 334 __asm__ __volatile__("@ atomic64_add_return\n"
304"1: ldrexd %0, %H0, [%3]\n" 335"1: ldrexd %0, %H0, [%3]\n"
@@ -340,6 +371,7 @@ static inline long long atomic64_sub_return(long long i, atomic64_t *v)
340 unsigned long tmp; 371 unsigned long tmp;
341 372
342 smp_mb(); 373 smp_mb();
374 prefetchw(&v->counter);
343 375
344 __asm__ __volatile__("@ atomic64_sub_return\n" 376 __asm__ __volatile__("@ atomic64_sub_return\n"
345"1: ldrexd %0, %H0, [%3]\n" 377"1: ldrexd %0, %H0, [%3]\n"
@@ -364,6 +396,7 @@ static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old,
364 unsigned long res; 396 unsigned long res;
365 397
366 smp_mb(); 398 smp_mb();
399 prefetchw(&ptr->counter);
367 400
368 do { 401 do {
369 __asm__ __volatile__("@ atomic64_cmpxchg\n" 402 __asm__ __volatile__("@ atomic64_cmpxchg\n"
@@ -388,6 +421,7 @@ static inline long long atomic64_xchg(atomic64_t *ptr, long long new)
388 unsigned long tmp; 421 unsigned long tmp;
389 422
390 smp_mb(); 423 smp_mb();
424 prefetchw(&ptr->counter);
391 425
392 __asm__ __volatile__("@ atomic64_xchg\n" 426 __asm__ __volatile__("@ atomic64_xchg\n"
393"1: ldrexd %0, %H0, [%3]\n" 427"1: ldrexd %0, %H0, [%3]\n"
@@ -409,6 +443,7 @@ static inline long long atomic64_dec_if_positive(atomic64_t *v)
409 unsigned long tmp; 443 unsigned long tmp;
410 444
411 smp_mb(); 445 smp_mb();
446 prefetchw(&v->counter);
412 447
413 __asm__ __volatile__("@ atomic64_dec_if_positive\n" 448 __asm__ __volatile__("@ atomic64_dec_if_positive\n"
414"1: ldrexd %0, %H0, [%3]\n" 449"1: ldrexd %0, %H0, [%3]\n"
@@ -436,6 +471,7 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
436 int ret = 1; 471 int ret = 1;
437 472
438 smp_mb(); 473 smp_mb();
474 prefetchw(&v->counter);
439 475
440 __asm__ __volatile__("@ atomic64_add_unless\n" 476 __asm__ __volatile__("@ atomic64_add_unless\n"
441"1: ldrexd %0, %H0, [%4]\n" 477"1: ldrexd %0, %H0, [%4]\n"
diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
index df2fbba7efc8..abb2c3769b01 100644
--- a/arch/arm/include/asm/cmpxchg.h
+++ b/arch/arm/include/asm/cmpxchg.h
@@ -2,6 +2,7 @@
2#define __ASM_ARM_CMPXCHG_H 2#define __ASM_ARM_CMPXCHG_H
3 3
4#include <linux/irqflags.h> 4#include <linux/irqflags.h>
5#include <linux/prefetch.h>
5#include <asm/barrier.h> 6#include <asm/barrier.h>
6 7
7#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) 8#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
@@ -35,6 +36,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
35#endif 36#endif
36 37
37 smp_mb(); 38 smp_mb();
39 prefetchw((const void *)ptr);
38 40
39 switch (size) { 41 switch (size) {
40#if __LINUX_ARM_ARCH__ >= 6 42#if __LINUX_ARM_ARCH__ >= 6
@@ -138,6 +140,8 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
138{ 140{
139 unsigned long oldval, res; 141 unsigned long oldval, res;
140 142
143 prefetchw((const void *)ptr);
144
141 switch (size) { 145 switch (size) {
142#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */ 146#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
143 case 1: 147 case 1:
@@ -230,6 +234,8 @@ static inline unsigned long long __cmpxchg64(unsigned long long *ptr,
230 unsigned long long oldval; 234 unsigned long long oldval;
231 unsigned long res; 235 unsigned long res;
232 236
237 prefetchw(ptr);
238
233 __asm__ __volatile__( 239 __asm__ __volatile__(
234"1: ldrexd %1, %H1, [%3]\n" 240"1: ldrexd %1, %H1, [%3]\n"
235" teq %1, %4\n" 241" teq %1, %4\n"
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index acdde76b39bb..42f0889f0584 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -71,6 +71,7 @@
71#define ARM_CPU_PART_CORTEX_A5 0xC050 71#define ARM_CPU_PART_CORTEX_A5 0xC050
72#define ARM_CPU_PART_CORTEX_A15 0xC0F0 72#define ARM_CPU_PART_CORTEX_A15 0xC0F0
73#define ARM_CPU_PART_CORTEX_A7 0xC070 73#define ARM_CPU_PART_CORTEX_A7 0xC070
74#define ARM_CPU_PART_CORTEX_A12 0xC0D0
74 75
75#define ARM_CPU_XSCALE_ARCH_MASK 0xe000 76#define ARM_CPU_XSCALE_ARCH_MASK 0xe000
76#define ARM_CPU_XSCALE_ARCH_V1 0x2000 77#define ARM_CPU_XSCALE_ARCH_V1 0x2000
diff --git a/arch/arm/include/asm/floppy.h b/arch/arm/include/asm/floppy.h
index c9f03eccc9d8..f4882553fbb0 100644
--- a/arch/arm/include/asm/floppy.h
+++ b/arch/arm/include/asm/floppy.h
@@ -25,7 +25,7 @@
25 25
26#define fd_inb(port) inb((port)) 26#define fd_inb(port) inb((port))
27#define fd_request_irq() request_irq(IRQ_FLOPPYDISK,floppy_interrupt,\ 27#define fd_request_irq() request_irq(IRQ_FLOPPYDISK,floppy_interrupt,\
28 IRQF_DISABLED,"floppy",NULL) 28 0,"floppy",NULL)
29#define fd_free_irq() free_irq(IRQ_FLOPPYDISK,NULL) 29#define fd_free_irq() free_irq(IRQ_FLOPPYDISK,NULL)
30#define fd_disable_irq() disable_irq(IRQ_FLOPPYDISK) 30#define fd_disable_irq() disable_irq(IRQ_FLOPPYDISK)
31#define fd_enable_irq() enable_irq(IRQ_FLOPPYDISK) 31#define fd_enable_irq() enable_irq(IRQ_FLOPPYDISK)
diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
index e42cf597f6e6..53e69dae796f 100644
--- a/arch/arm/include/asm/futex.h
+++ b/arch/arm/include/asm/futex.h
@@ -3,11 +3,6 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#if defined(CONFIG_CPU_USE_DOMAINS) && defined(CONFIG_SMP)
7/* ARM doesn't provide unprivileged exclusive memory accessors */
8#include <asm-generic/futex.h>
9#else
10
11#include <linux/futex.h> 6#include <linux/futex.h>
12#include <linux/uaccess.h> 7#include <linux/uaccess.h>
13#include <asm/errno.h> 8#include <asm/errno.h>
@@ -28,6 +23,7 @@
28 23
29#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \ 24#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \
30 smp_mb(); \ 25 smp_mb(); \
26 prefetchw(uaddr); \
31 __asm__ __volatile__( \ 27 __asm__ __volatile__( \
32 "1: ldrex %1, [%3]\n" \ 28 "1: ldrex %1, [%3]\n" \
33 " " insn "\n" \ 29 " " insn "\n" \
@@ -51,6 +47,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
51 return -EFAULT; 47 return -EFAULT;
52 48
53 smp_mb(); 49 smp_mb();
50 /* Prefetching cannot fault */
51 prefetchw(uaddr);
54 __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" 52 __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
55 "1: ldrex %1, [%4]\n" 53 "1: ldrex %1, [%4]\n"
56 " teq %1, %2\n" 54 " teq %1, %2\n"
@@ -164,6 +162,5 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
164 return ret; 162 return ret;
165} 163}
166 164
167#endif /* !(CPU_USE_DOMAINS && SMP) */
168#endif /* __KERNEL__ */ 165#endif /* __KERNEL__ */
169#endif /* _ASM_ARM_FUTEX_H */ 166#endif /* _ASM_ARM_FUTEX_H */
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h
index eef55ea9ef00..8e427c7b4425 100644
--- a/arch/arm/include/asm/hw_breakpoint.h
+++ b/arch/arm/include/asm/hw_breakpoint.h
@@ -51,6 +51,7 @@ static inline void decode_ctrl_reg(u32 reg,
51#define ARM_DEBUG_ARCH_V7_ECP14 3 51#define ARM_DEBUG_ARCH_V7_ECP14 3
52#define ARM_DEBUG_ARCH_V7_MM 4 52#define ARM_DEBUG_ARCH_V7_MM 4
53#define ARM_DEBUG_ARCH_V7_1 5 53#define ARM_DEBUG_ARCH_V7_1 5
54#define ARM_DEBUG_ARCH_V8 6
54 55
55/* Breakpoint */ 56/* Breakpoint */
56#define ARM_BREAKPOINT_EXECUTE 0 57#define ARM_BREAKPOINT_EXECUTE 0
diff --git a/arch/arm/include/asm/hwcap.h b/arch/arm/include/asm/hwcap.h
index 6ff56eca3f1f..6e183fd269fb 100644
--- a/arch/arm/include/asm/hwcap.h
+++ b/arch/arm/include/asm/hwcap.h
@@ -9,6 +9,7 @@
9 * instruction set this cpu supports. 9 * instruction set this cpu supports.
10 */ 10 */
11#define ELF_HWCAP (elf_hwcap) 11#define ELF_HWCAP (elf_hwcap)
12extern unsigned int elf_hwcap; 12#define ELF_HWCAP2 (elf_hwcap2)
13extern unsigned int elf_hwcap, elf_hwcap2;
13#endif 14#endif
14#endif 15#endif
diff --git a/arch/arm/include/asm/jump_label.h b/arch/arm/include/asm/jump_label.h
index 863c892b4aaa..70f9b9bfb1f9 100644
--- a/arch/arm/include/asm/jump_label.h
+++ b/arch/arm/include/asm/jump_label.h
@@ -4,7 +4,6 @@
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/types.h> 6#include <linux/types.h>
7#include <asm/system.h>
8 7
9#define JUMP_LABEL_NOP_SIZE 4 8#define JUMP_LABEL_NOP_SIZE 4
10 9
diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h
index f82ec22eeb11..49fa0dfaad33 100644
--- a/arch/arm/include/asm/kprobes.h
+++ b/arch/arm/include/asm/kprobes.h
@@ -18,7 +18,7 @@
18 18
19#include <linux/types.h> 19#include <linux/types.h>
20#include <linux/ptrace.h> 20#include <linux/ptrace.h>
21#include <linux/percpu.h> 21#include <linux/notifier.h>
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
@@ -28,21 +28,10 @@
28#define kretprobe_blacklist_size 0 28#define kretprobe_blacklist_size 0
29 29
30typedef u32 kprobe_opcode_t; 30typedef u32 kprobe_opcode_t;
31
32struct kprobe; 31struct kprobe;
33typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *); 32#include <asm/probes.h>
34typedef unsigned long (kprobe_check_cc)(unsigned long);
35typedef void (kprobe_insn_singlestep_t)(struct kprobe *, struct pt_regs *);
36typedef void (kprobe_insn_fn_t)(void);
37 33
38/* Architecture specific copy of original instruction. */ 34#define arch_specific_insn arch_probes_insn
39struct arch_specific_insn {
40 kprobe_opcode_t *insn;
41 kprobe_insn_handler_t *insn_handler;
42 kprobe_check_cc *insn_check_cc;
43 kprobe_insn_singlestep_t *insn_singlestep;
44 kprobe_insn_fn_t *insn_fn;
45};
46 35
47struct prev_kprobe { 36struct prev_kprobe {
48 struct kprobe *kp; 37 struct kprobe *kp;
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 4afb376d9c7c..02fa2558f662 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -166,9 +166,17 @@
166 * Physical vs virtual RAM address space conversion. These are 166 * Physical vs virtual RAM address space conversion. These are
167 * private definitions which should NOT be used outside memory.h 167 * private definitions which should NOT be used outside memory.h
168 * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. 168 * files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
169 *
170 * PFNs are used to describe any physical page; this means
171 * PFN 0 == physical address 0.
169 */ 172 */
170#ifndef __virt_to_phys 173#if defined(__virt_to_phys)
171#ifdef CONFIG_ARM_PATCH_PHYS_VIRT 174#define PHYS_OFFSET PLAT_PHYS_OFFSET
175#define PHYS_PFN_OFFSET ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT))
176
177#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
178
179#elif defined(CONFIG_ARM_PATCH_PHYS_VIRT)
172 180
173/* 181/*
174 * Constants used to force the right instruction encodings and shifts 182 * Constants used to force the right instruction encodings and shifts
@@ -177,12 +185,17 @@
177#define __PV_BITS_31_24 0x81000000 185#define __PV_BITS_31_24 0x81000000
178#define __PV_BITS_7_0 0x81 186#define __PV_BITS_7_0 0x81
179 187
180extern u64 __pv_phys_offset; 188extern unsigned long __pv_phys_pfn_offset;
181extern u64 __pv_offset; 189extern u64 __pv_offset;
182extern void fixup_pv_table(const void *, unsigned long); 190extern void fixup_pv_table(const void *, unsigned long);
183extern const void *__pv_table_begin, *__pv_table_end; 191extern const void *__pv_table_begin, *__pv_table_end;
184 192
185#define PHYS_OFFSET __pv_phys_offset 193#define PHYS_OFFSET ((phys_addr_t)__pv_phys_pfn_offset << PAGE_SHIFT)
194#define PHYS_PFN_OFFSET (__pv_phys_pfn_offset)
195
196#define virt_to_pfn(kaddr) \
197 ((((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT) + \
198 PHYS_PFN_OFFSET)
186 199
187#define __pv_stub(from,to,instr,type) \ 200#define __pv_stub(from,to,instr,type) \
188 __asm__("@ __pv_stub\n" \ 201 __asm__("@ __pv_stub\n" \
@@ -243,6 +256,7 @@ static inline unsigned long __phys_to_virt(phys_addr_t x)
243#else 256#else
244 257
245#define PHYS_OFFSET PLAT_PHYS_OFFSET 258#define PHYS_OFFSET PLAT_PHYS_OFFSET
259#define PHYS_PFN_OFFSET ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT))
246 260
247static inline phys_addr_t __virt_to_phys(unsigned long x) 261static inline phys_addr_t __virt_to_phys(unsigned long x)
248{ 262{
@@ -254,18 +268,11 @@ static inline unsigned long __phys_to_virt(phys_addr_t x)
254 return x - PHYS_OFFSET + PAGE_OFFSET; 268 return x - PHYS_OFFSET + PAGE_OFFSET;
255} 269}
256 270
257#endif 271#define virt_to_pfn(kaddr) \
258#endif 272 ((((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT) + \
273 PHYS_PFN_OFFSET)
259 274
260/* 275#endif
261 * PFNs are used to describe any physical page; this means
262 * PFN 0 == physical address 0.
263 *
264 * This is the PFN of the first RAM page in the kernel
265 * direct-mapped view. We assume this is the first page
266 * of RAM in the mem_map as well.
267 */
268#define PHYS_PFN_OFFSET ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT))
269 276
270/* 277/*
271 * These are *only* valid on the kernel direct mapped RAM memory. 278 * These are *only* valid on the kernel direct mapped RAM memory.
@@ -343,9 +350,9 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
343 */ 350 */
344#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET 351#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET
345 352
346#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 353#define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr))
347#define virt_addr_valid(kaddr) (((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) \ 354#define virt_addr_valid(kaddr) (((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) \
348 && pfn_valid(__pa(kaddr) >> PAGE_SHIFT) ) 355 && pfn_valid(virt_to_pfn(kaddr)))
349 356
350#endif 357#endif
351 358
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index dfff709fda3c..219ac88a9542 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -140,6 +140,7 @@
140#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */ 140#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */
141#define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */ 141#define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */
142#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */ 142#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */
143#define L_PTE_MT_VECTORS (_AT(pteval_t, 0x0f) << 2) /* 1111 */
143#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2) 144#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2)
144 145
145#ifndef __ASSEMBLY__ 146#ifndef __ASSEMBLY__
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 7d59b524f2af..5478e5d6ad89 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -216,13 +216,16 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
216 216
217#define pte_none(pte) (!pte_val(pte)) 217#define pte_none(pte) (!pte_val(pte))
218#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) 218#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
219#define pte_valid(pte) (pte_val(pte) & L_PTE_VALID)
220#define pte_accessible(mm, pte) (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid(pte))
219#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY)) 221#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY))
220#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) 222#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
221#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) 223#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
222#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN)) 224#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN))
223#define pte_special(pte) (0) 225#define pte_special(pte) (0)
224 226
225#define pte_present_user(pte) (pte_present(pte) && (pte_val(pte) & L_PTE_USER)) 227#define pte_valid_user(pte) \
228 (pte_valid(pte) && (pte_val(pte) & L_PTE_USER) && pte_young(pte))
226 229
227#if __LINUX_ARM_ARCH__ < 6 230#if __LINUX_ARM_ARCH__ < 6
228static inline void __sync_icache_dcache(pte_t pteval) 231static inline void __sync_icache_dcache(pte_t pteval)
@@ -237,7 +240,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
237{ 240{
238 unsigned long ext = 0; 241 unsigned long ext = 0;
239 242
240 if (addr < TASK_SIZE && pte_present_user(pteval)) { 243 if (addr < TASK_SIZE && pte_valid_user(pteval)) {
241 __sync_icache_dcache(pteval); 244 __sync_icache_dcache(pteval);
242 ext |= PTE_EXT_NG; 245 ext |= PTE_EXT_NG;
243 } 246 }
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index f24edad26c70..ae1919be8f98 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -71,6 +71,8 @@ struct arm_pmu {
71 void (*disable)(struct perf_event *event); 71 void (*disable)(struct perf_event *event);
72 int (*get_event_idx)(struct pmu_hw_events *hw_events, 72 int (*get_event_idx)(struct pmu_hw_events *hw_events,
73 struct perf_event *event); 73 struct perf_event *event);
74 void (*clear_event_idx)(struct pmu_hw_events *hw_events,
75 struct perf_event *event);
74 int (*set_event_filter)(struct hw_perf_event *evt, 76 int (*set_event_filter)(struct hw_perf_event *evt,
75 struct perf_event_attr *attr); 77 struct perf_event_attr *attr);
76 u32 (*read_counter)(struct perf_event *event); 78 u32 (*read_counter)(struct perf_event *event);
diff --git a/arch/arm/include/asm/probes.h b/arch/arm/include/asm/probes.h
new file mode 100644
index 000000000000..806cfe622a9e
--- /dev/null
+++ b/arch/arm/include/asm/probes.h
@@ -0,0 +1,43 @@
1/*
2 * arch/arm/include/asm/probes.h
3 *
4 * Original contents copied from arch/arm/include/asm/kprobes.h
5 * which contains the following notice...
6 *
7 * Copyright (C) 2006, 2007 Motorola Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 */
18
19#ifndef _ASM_PROBES_H
20#define _ASM_PROBES_H
21
22typedef u32 probes_opcode_t;
23
24struct arch_probes_insn;
25typedef void (probes_insn_handler_t)(probes_opcode_t,
26 struct arch_probes_insn *,
27 struct pt_regs *);
28typedef unsigned long (probes_check_cc)(unsigned long);
29typedef void (probes_insn_singlestep_t)(probes_opcode_t,
30 struct arch_probes_insn *,
31 struct pt_regs *);
32typedef void (probes_insn_fn_t)(void);
33
34/* Architecture specific copy of original instruction. */
35struct arch_probes_insn {
36 probes_opcode_t *insn;
37 probes_insn_handler_t *insn_handler;
38 probes_check_cc *insn_check_cc;
39 probes_insn_singlestep_t *insn_singlestep;
40 probes_insn_fn_t *insn_fn;
41};
42
43#endif
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 04c99f36ff7f..c877654fe3bf 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -27,9 +27,13 @@ struct pt_regs {
27#define thumb_mode(regs) (0) 27#define thumb_mode(regs) (0)
28#endif 28#endif
29 29
30#ifndef CONFIG_CPU_V7M
30#define isa_mode(regs) \ 31#define isa_mode(regs) \
31 ((((regs)->ARM_cpsr & PSR_J_BIT) >> 23) | \ 32 ((((regs)->ARM_cpsr & PSR_J_BIT) >> (__ffs(PSR_J_BIT) - 1)) | \
32 (((regs)->ARM_cpsr & PSR_T_BIT) >> 5)) 33 (((regs)->ARM_cpsr & PSR_T_BIT) >> (__ffs(PSR_T_BIT))))
34#else
35#define isa_mode(regs) 1 /* Thumb */
36#endif
33 37
34#define processor_mode(regs) \ 38#define processor_mode(regs) \
35 ((regs)->ARM_cpsr & MODE_MASK) 39 ((regs)->ARM_cpsr & MODE_MASK)
@@ -80,6 +84,12 @@ static inline long regs_return_value(struct pt_regs *regs)
80 84
81#define instruction_pointer(regs) (regs)->ARM_pc 85#define instruction_pointer(regs) (regs)->ARM_pc
82 86
87static inline void instruction_pointer_set(struct pt_regs *regs,
88 unsigned long val)
89{
90 instruction_pointer(regs) = val;
91}
92
83#ifdef CONFIG_SMP 93#ifdef CONFIG_SMP
84extern unsigned long profile_pc(struct pt_regs *regs); 94extern unsigned long profile_pc(struct pt_regs *regs);
85#else 95#else
diff --git a/arch/arm/include/asm/sync_bitops.h b/arch/arm/include/asm/sync_bitops.h
index 63479eecbf76..9732b8e11e63 100644
--- a/arch/arm/include/asm/sync_bitops.h
+++ b/arch/arm/include/asm/sync_bitops.h
@@ -2,7 +2,6 @@
2#define __ASM_SYNC_BITOPS_H__ 2#define __ASM_SYNC_BITOPS_H__
3 3
4#include <asm/bitops.h> 4#include <asm/bitops.h>
5#include <asm/system.h>
6 5
7/* sync_bitops functions are equivalent to the SMP implementation of the 6/* sync_bitops functions are equivalent to the SMP implementation of the
8 * original functions, independently from CONFIG_SMP being defined. 7 * original functions, independently from CONFIG_SMP being defined.
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
deleted file mode 100644
index 368165e33c1c..000000000000
--- a/arch/arm/include/asm/system.h
+++ /dev/null
@@ -1,7 +0,0 @@
1/* FILE TO BE DELETED. DO NOT ADD STUFF HERE! */
2#include <asm/barrier.h>
3#include <asm/compiler.h>
4#include <asm/cmpxchg.h>
5#include <asm/switch_to.h>
6#include <asm/system_info.h>
7#include <asm/system_misc.h>
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 71a06b293489..f989d7c22dc5 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -153,6 +153,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
153#define TIF_SIGPENDING 0 153#define TIF_SIGPENDING 0
154#define TIF_NEED_RESCHED 1 154#define TIF_NEED_RESCHED 1
155#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ 155#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
156#define TIF_UPROBE 7
156#define TIF_SYSCALL_TRACE 8 157#define TIF_SYSCALL_TRACE 8
157#define TIF_SYSCALL_AUDIT 9 158#define TIF_SYSCALL_AUDIT 9
158#define TIF_SYSCALL_TRACEPOINT 10 159#define TIF_SYSCALL_TRACEPOINT 10
@@ -165,6 +166,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
165#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 166#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
166#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 167#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
167#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) 168#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
169#define _TIF_UPROBE (1 << TIF_UPROBE)
168#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 170#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
169#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) 171#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
170#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) 172#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
@@ -178,7 +180,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
178/* 180/*
179 * Change these and you break ASM code in entry-common.S 181 * Change these and you break ASM code in entry-common.S
180 */ 182 */
181#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_RESUME) 183#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
184 _TIF_NOTIFY_RESUME | _TIF_UPROBE)
182 185
183#endif /* __KERNEL__ */ 186#endif /* __KERNEL__ */
184#endif /* __ASM_ARM_THREAD_INFO_H */ 187#endif /* __ASM_ARM_THREAD_INFO_H */
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 72abdc541f38..12c3a5decc60 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -19,7 +19,7 @@
19#include <asm/unified.h> 19#include <asm/unified.h>
20#include <asm/compiler.h> 20#include <asm/compiler.h>
21 21
22#if __LINUX_ARM_ARCH__ < 6 22#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
23#include <asm-generic/uaccess-unaligned.h> 23#include <asm-generic/uaccess-unaligned.h>
24#else 24#else
25#define __get_user_unaligned __get_user 25#define __get_user_unaligned __get_user
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index acabef1a75df..43876245fc57 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -48,6 +48,5 @@
48 */ 48 */
49#define __IGNORE_fadvise64_64 49#define __IGNORE_fadvise64_64
50#define __IGNORE_migrate_pages 50#define __IGNORE_migrate_pages
51#define __IGNORE_kcmp
52 51
53#endif /* __ASM_ARM_UNISTD_H */ 52#endif /* __ASM_ARM_UNISTD_H */
diff --git a/arch/arm/include/asm/uprobes.h b/arch/arm/include/asm/uprobes.h
new file mode 100644
index 000000000000..9472c20b7d49
--- /dev/null
+++ b/arch/arm/include/asm/uprobes.h
@@ -0,0 +1,45 @@
1/*
2 * Copyright (C) 2012 Rabin Vincent <rabin at rab.in>
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 version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _ASM_UPROBES_H
10#define _ASM_UPROBES_H
11
12#include <asm/probes.h>
13#include <asm/opcodes.h>
14
15typedef u32 uprobe_opcode_t;
16
17#define MAX_UINSN_BYTES 4
18#define UPROBE_XOL_SLOT_BYTES 64
19
20#define UPROBE_SWBP_ARM_INSN 0xe7f001f9
21#define UPROBE_SS_ARM_INSN 0xe7f001fa
22#define UPROBE_SWBP_INSN __opcode_to_mem_arm(UPROBE_SWBP_ARM_INSN)
23#define UPROBE_SWBP_INSN_SIZE 4
24
25struct arch_uprobe_task {
26 u32 backup;
27 unsigned long saved_trap_no;
28};
29
30struct arch_uprobe {
31 u8 insn[MAX_UINSN_BYTES];
32 unsigned long ixol[2];
33 uprobe_opcode_t bpinsn;
34 bool simulate;
35 u32 pcreg;
36 void (*prehandler)(struct arch_uprobe *auprobe,
37 struct arch_uprobe_task *autask,
38 struct pt_regs *regs);
39 void (*posthandler)(struct arch_uprobe *auprobe,
40 struct arch_uprobe_task *autask,
41 struct pt_regs *regs);
42 struct arch_probes_insn asi;
43};
44
45#endif
diff --git a/arch/arm/include/uapi/asm/hwcap.h b/arch/arm/include/uapi/asm/hwcap.h
index 7dcc10d67253..20d12f230a2f 100644
--- a/arch/arm/include/uapi/asm/hwcap.h
+++ b/arch/arm/include/uapi/asm/hwcap.h
@@ -28,4 +28,13 @@
28#define HWCAP_LPAE (1 << 20) 28#define HWCAP_LPAE (1 << 20)
29#define HWCAP_EVTSTRM (1 << 21) 29#define HWCAP_EVTSTRM (1 << 21)
30 30
31/*
32 * HWCAP2 flags - for elf_hwcap2 (in kernel) and AT_HWCAP2
33 */
34#define HWCAP2_AES (1 << 0)
35#define HWCAP2_PMULL (1 << 1)
36#define HWCAP2_SHA1 (1 << 2)
37#define HWCAP2_SHA2 (1 << 3)
38#define HWCAP2_CRC32 (1 << 4)
39
31#endif /* _UAPI__ASMARM_HWCAP_H */ 40#endif /* _UAPI__ASMARM_HWCAP_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index a30fc9be9e9e..a766bcbaf8ad 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -50,11 +50,12 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o
50obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o 50obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o
51obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o 51obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o
52obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 52obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
53obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o patch.o 53obj-$(CONFIG_UPROBES) += probes.o probes-arm.o uprobes.o uprobes-arm.o
54obj-$(CONFIG_KPROBES) += probes.o kprobes.o kprobes-common.o patch.o
54ifdef CONFIG_THUMB2_KERNEL 55ifdef CONFIG_THUMB2_KERNEL
55obj-$(CONFIG_KPROBES) += kprobes-thumb.o 56obj-$(CONFIG_KPROBES) += kprobes-thumb.o probes-thumb.o
56else 57else
57obj-$(CONFIG_KPROBES) += kprobes-arm.o 58obj-$(CONFIG_KPROBES) += kprobes-arm.o probes-arm.o
58endif 59endif
59obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o 60obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o
60test-kprobes-objs := kprobes-test.o 61test-kprobes-objs := kprobes-test.o
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 85e664b6a5f1..f7b450f97e68 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -158,6 +158,6 @@ EXPORT_SYMBOL(__gnu_mcount_nc);
158#endif 158#endif
159 159
160#ifdef CONFIG_ARM_PATCH_PHYS_VIRT 160#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
161EXPORT_SYMBOL(__pv_phys_offset); 161EXPORT_SYMBOL(__pv_phys_pfn_offset);
162EXPORT_SYMBOL(__pv_offset); 162EXPORT_SYMBOL(__pv_offset);
163#endif 163#endif
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index d0d46786892c..16d43cd45619 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -605,41 +605,10 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
605 */ 605 */
606int pcibios_enable_device(struct pci_dev *dev, int mask) 606int pcibios_enable_device(struct pci_dev *dev, int mask)
607{ 607{
608 u16 cmd, old_cmd; 608 if (pci_has_flag(PCI_PROBE_ONLY))
609 int idx; 609 return 0;
610 struct resource *r;
611
612 pci_read_config_word(dev, PCI_COMMAND, &cmd);
613 old_cmd = cmd;
614 for (idx = 0; idx < 6; idx++) {
615 /* Only set up the requested stuff */
616 if (!(mask & (1 << idx)))
617 continue;
618
619 r = dev->resource + idx;
620 if (!r->start && r->end) {
621 printk(KERN_ERR "PCI: Device %s not available because"
622 " of resource collisions\n", pci_name(dev));
623 return -EINVAL;
624 }
625 if (r->flags & IORESOURCE_IO)
626 cmd |= PCI_COMMAND_IO;
627 if (r->flags & IORESOURCE_MEM)
628 cmd |= PCI_COMMAND_MEMORY;
629 }
630 610
631 /* 611 return pci_enable_resources(dev, mask);
632 * Bridges (eg, cardbus bridges) need to be fully enabled
633 */
634 if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
635 cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
636
637 if (cmd != old_cmd) {
638 printk("PCI: enabling device %s (%04x -> %04x)\n",
639 pci_name(dev), old_cmd, cmd);
640 pci_write_config_word(dev, PCI_COMMAND, cmd);
641 }
642 return 0;
643} 612}
644 613
645int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, 614int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index f5f381d91556..f8c08839edf3 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -584,9 +584,10 @@ __fixup_pv_table:
584 subs r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET 584 subs r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET
585 add r4, r4, r3 @ adjust table start address 585 add r4, r4, r3 @ adjust table start address
586 add r5, r5, r3 @ adjust table end address 586 add r5, r5, r3 @ adjust table end address
587 add r6, r6, r3 @ adjust __pv_phys_offset address 587 add r6, r6, r3 @ adjust __pv_phys_pfn_offset address
588 add r7, r7, r3 @ adjust __pv_offset address 588 add r7, r7, r3 @ adjust __pv_offset address
589 str r8, [r6, #LOW_OFFSET] @ save computed PHYS_OFFSET to __pv_phys_offset 589 mov r0, r8, lsr #12 @ convert to PFN
590 str r0, [r6, #LOW_OFFSET] @ save computed PHYS_OFFSET to __pv_phys_pfn_offset
590 strcc ip, [r7, #HIGH_OFFSET] @ save to __pv_offset high bits 591 strcc ip, [r7, #HIGH_OFFSET] @ save to __pv_offset high bits
591 mov r6, r3, lsr #24 @ constant for add/sub instructions 592 mov r6, r3, lsr #24 @ constant for add/sub instructions
592 teq r3, r6, lsl #24 @ must be 16MiB aligned 593 teq r3, r6, lsl #24 @ must be 16MiB aligned
@@ -600,7 +601,7 @@ ENDPROC(__fixup_pv_table)
6001: .long . 6011: .long .
601 .long __pv_table_begin 602 .long __pv_table_begin
602 .long __pv_table_end 603 .long __pv_table_end
6032: .long __pv_phys_offset 6042: .long __pv_phys_pfn_offset
604 .long __pv_offset 605 .long __pv_offset
605 606
606 .text 607 .text
@@ -688,11 +689,11 @@ ENTRY(fixup_pv_table)
688ENDPROC(fixup_pv_table) 689ENDPROC(fixup_pv_table)
689 690
690 .data 691 .data
691 .globl __pv_phys_offset 692 .globl __pv_phys_pfn_offset
692 .type __pv_phys_offset, %object 693 .type __pv_phys_pfn_offset, %object
693__pv_phys_offset: 694__pv_phys_pfn_offset:
694 .quad 0 695 .word 0
695 .size __pv_phys_offset, . -__pv_phys_offset 696 .size __pv_phys_pfn_offset, . -__pv_phys_pfn_offset
696 697
697 .globl __pv_offset 698 .globl __pv_offset
698 .type __pv_offset, %object 699 .type __pv_offset, %object
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 3d446605cbf8..9da35c6d3411 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -167,7 +167,7 @@ static int debug_arch_supported(void)
167/* Can we determine the watchpoint access type from the fsr? */ 167/* Can we determine the watchpoint access type from the fsr? */
168static int debug_exception_updates_fsr(void) 168static int debug_exception_updates_fsr(void)
169{ 169{
170 return 0; 170 return get_debug_arch() >= ARM_DEBUG_ARCH_V8;
171} 171}
172 172
173/* Determine number of WRP registers available. */ 173/* Determine number of WRP registers available. */
@@ -257,6 +257,7 @@ static int enable_monitor_mode(void)
257 break; 257 break;
258 case ARM_DEBUG_ARCH_V7_ECP14: 258 case ARM_DEBUG_ARCH_V7_ECP14:
259 case ARM_DEBUG_ARCH_V7_1: 259 case ARM_DEBUG_ARCH_V7_1:
260 case ARM_DEBUG_ARCH_V8:
260 ARM_DBG_WRITE(c0, c2, 2, (dscr | ARM_DSCR_MDBGEN)); 261 ARM_DBG_WRITE(c0, c2, 2, (dscr | ARM_DSCR_MDBGEN));
261 isb(); 262 isb();
262 break; 263 break;
diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 8a30c89da70e..ac300c60d656 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -60,13 +60,10 @@
60 60
61#include <linux/kernel.h> 61#include <linux/kernel.h>
62#include <linux/kprobes.h> 62#include <linux/kprobes.h>
63#include <linux/module.h> 63#include <linux/ptrace.h>
64 64
65#include "kprobes.h" 65#include "kprobes.h"
66 66#include "probes-arm.h"
67#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
68
69#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
70 67
71#if __LINUX_ARM_ARCH__ >= 6 68#if __LINUX_ARM_ARCH__ >= 6
72#define BLX(reg) "blx "reg" \n\t" 69#define BLX(reg) "blx "reg" \n\t"
@@ -75,92 +72,11 @@
75 "mov pc, "reg" \n\t" 72 "mov pc, "reg" \n\t"
76#endif 73#endif
77 74
78/*
79 * To avoid the complications of mimicing single-stepping on a
80 * processor without a Next-PC or a single-step mode, and to
81 * avoid having to deal with the side-effects of boosting, we
82 * simulate or emulate (almost) all ARM instructions.
83 *
84 * "Simulation" is where the instruction's behavior is duplicated in
85 * C code. "Emulation" is where the original instruction is rewritten
86 * and executed, often by altering its registers.
87 *
88 * By having all behavior of the kprobe'd instruction completed before
89 * returning from the kprobe_handler(), all locks (scheduler and
90 * interrupt) can safely be released. There is no need for secondary
91 * breakpoints, no race with MP or preemptable kernels, nor having to
92 * clean up resources counts at a later time impacting overall system
93 * performance. By rewriting the instruction, only the minimum registers
94 * need to be loaded and saved back optimizing performance.
95 *
96 * Calling the insnslot_*_rwflags version of a function doesn't hurt
97 * anything even when the CPSR flags aren't updated by the
98 * instruction. It's just a little slower in return for saving
99 * a little space by not having a duplicate function that doesn't
100 * update the flags. (The same optimization can be said for
101 * instructions that do or don't perform register writeback)
102 * Also, instructions can either read the flags, only write the
103 * flags, or read and write the flags. To save combinations
104 * rather than for sheer performance, flag functions just assume
105 * read and write of flags.
106 */
107
108static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
109{
110 kprobe_opcode_t insn = p->opcode;
111 long iaddr = (long)p->addr;
112 int disp = branch_displacement(insn);
113
114 if (insn & (1 << 24))
115 regs->ARM_lr = iaddr + 4;
116
117 regs->ARM_pc = iaddr + 8 + disp;
118}
119
120static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)
121{
122 kprobe_opcode_t insn = p->opcode;
123 long iaddr = (long)p->addr;
124 int disp = branch_displacement(insn);
125
126 regs->ARM_lr = iaddr + 4;
127 regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2);
128 regs->ARM_cpsr |= PSR_T_BIT;
129}
130
131static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
132{
133 kprobe_opcode_t insn = p->opcode;
134 int rm = insn & 0xf;
135 long rmv = regs->uregs[rm];
136
137 if (insn & (1 << 5))
138 regs->ARM_lr = (long)p->addr + 4;
139
140 regs->ARM_pc = rmv & ~0x1;
141 regs->ARM_cpsr &= ~PSR_T_BIT;
142 if (rmv & 0x1)
143 regs->ARM_cpsr |= PSR_T_BIT;
144}
145
146static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs)
147{
148 kprobe_opcode_t insn = p->opcode;
149 int rd = (insn >> 12) & 0xf;
150 unsigned long mask = 0xf8ff03df; /* Mask out execution state */
151 regs->uregs[rd] = regs->ARM_cpsr & mask;
152}
153
154static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
155{
156 regs->uregs[12] = regs->uregs[13];
157}
158
159static void __kprobes 75static void __kprobes
160emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) 76emulate_ldrdstrd(probes_opcode_t insn,
77 struct arch_probes_insn *asi, struct pt_regs *regs)
161{ 78{
162 kprobe_opcode_t insn = p->opcode; 79 unsigned long pc = regs->ARM_pc + 4;
163 unsigned long pc = (unsigned long)p->addr + 8;
164 int rt = (insn >> 12) & 0xf; 80 int rt = (insn >> 12) & 0xf;
165 int rn = (insn >> 16) & 0xf; 81 int rn = (insn >> 16) & 0xf;
166 int rm = insn & 0xf; 82 int rm = insn & 0xf;
@@ -175,7 +91,7 @@ emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
175 BLX("%[fn]") 91 BLX("%[fn]")
176 : "=r" (rtv), "=r" (rt2v), "=r" (rnv) 92 : "=r" (rtv), "=r" (rt2v), "=r" (rnv)
177 : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv), 93 : "0" (rtv), "1" (rt2v), "2" (rnv), "r" (rmv),
178 [fn] "r" (p->ainsn.insn_fn) 94 [fn] "r" (asi->insn_fn)
179 : "lr", "memory", "cc" 95 : "lr", "memory", "cc"
180 ); 96 );
181 97
@@ -186,10 +102,10 @@ emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
186} 102}
187 103
188static void __kprobes 104static void __kprobes
189emulate_ldr(struct kprobe *p, struct pt_regs *regs) 105emulate_ldr(probes_opcode_t insn,
106 struct arch_probes_insn *asi, struct pt_regs *regs)
190{ 107{
191 kprobe_opcode_t insn = p->opcode; 108 unsigned long pc = regs->ARM_pc + 4;
192 unsigned long pc = (unsigned long)p->addr + 8;
193 int rt = (insn >> 12) & 0xf; 109 int rt = (insn >> 12) & 0xf;
194 int rn = (insn >> 16) & 0xf; 110 int rn = (insn >> 16) & 0xf;
195 int rm = insn & 0xf; 111 int rm = insn & 0xf;
@@ -202,7 +118,7 @@ emulate_ldr(struct kprobe *p, struct pt_regs *regs)
202 __asm__ __volatile__ ( 118 __asm__ __volatile__ (
203 BLX("%[fn]") 119 BLX("%[fn]")
204 : "=r" (rtv), "=r" (rnv) 120 : "=r" (rtv), "=r" (rnv)
205 : "1" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn) 121 : "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
206 : "lr", "memory", "cc" 122 : "lr", "memory", "cc"
207 ); 123 );
208 124
@@ -216,11 +132,11 @@ emulate_ldr(struct kprobe *p, struct pt_regs *regs)
216} 132}
217 133
218static void __kprobes 134static void __kprobes
219emulate_str(struct kprobe *p, struct pt_regs *regs) 135emulate_str(probes_opcode_t insn,
136 struct arch_probes_insn *asi, struct pt_regs *regs)
220{ 137{
221 kprobe_opcode_t insn = p->opcode; 138 unsigned long rtpc = regs->ARM_pc - 4 + str_pc_offset;
222 unsigned long rtpc = (unsigned long)p->addr + str_pc_offset; 139 unsigned long rnpc = regs->ARM_pc + 4;
223 unsigned long rnpc = (unsigned long)p->addr + 8;
224 int rt = (insn >> 12) & 0xf; 140 int rt = (insn >> 12) & 0xf;
225 int rn = (insn >> 16) & 0xf; 141 int rn = (insn >> 16) & 0xf;
226 int rm = insn & 0xf; 142 int rm = insn & 0xf;
@@ -234,7 +150,7 @@ emulate_str(struct kprobe *p, struct pt_regs *regs)
234 __asm__ __volatile__ ( 150 __asm__ __volatile__ (
235 BLX("%[fn]") 151 BLX("%[fn]")
236 : "=r" (rnv) 152 : "=r" (rnv)
237 : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn) 153 : "r" (rtv), "0" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
238 : "lr", "memory", "cc" 154 : "lr", "memory", "cc"
239 ); 155 );
240 156
@@ -243,10 +159,10 @@ emulate_str(struct kprobe *p, struct pt_regs *regs)
243} 159}
244 160
245static void __kprobes 161static void __kprobes
246emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs) 162emulate_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
163 struct arch_probes_insn *asi, struct pt_regs *regs)
247{ 164{
248 kprobe_opcode_t insn = p->opcode; 165 unsigned long pc = regs->ARM_pc + 4;
249 unsigned long pc = (unsigned long)p->addr + 8;
250 int rd = (insn >> 12) & 0xf; 166 int rd = (insn >> 12) & 0xf;
251 int rn = (insn >> 16) & 0xf; 167 int rn = (insn >> 16) & 0xf;
252 int rm = insn & 0xf; 168 int rm = insn & 0xf;
@@ -266,7 +182,7 @@ emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
266 "mrs %[cpsr], cpsr \n\t" 182 "mrs %[cpsr], cpsr \n\t"
267 : "=r" (rdv), [cpsr] "=r" (cpsr) 183 : "=r" (rdv), [cpsr] "=r" (cpsr)
268 : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv), 184 : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
269 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) 185 "1" (cpsr), [fn] "r" (asi->insn_fn)
270 : "lr", "memory", "cc" 186 : "lr", "memory", "cc"
271 ); 187 );
272 188
@@ -278,9 +194,9 @@ emulate_rd12rn16rm0rs8_rwflags(struct kprobe *p, struct pt_regs *regs)
278} 194}
279 195
280static void __kprobes 196static void __kprobes
281emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) 197emulate_rd12rn16rm0_rwflags_nopc(probes_opcode_t insn,
198 struct arch_probes_insn *asi, struct pt_regs *regs)
282{ 199{
283 kprobe_opcode_t insn = p->opcode;
284 int rd = (insn >> 12) & 0xf; 200 int rd = (insn >> 12) & 0xf;
285 int rn = (insn >> 16) & 0xf; 201 int rn = (insn >> 16) & 0xf;
286 int rm = insn & 0xf; 202 int rm = insn & 0xf;
@@ -296,7 +212,7 @@ emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
296 "mrs %[cpsr], cpsr \n\t" 212 "mrs %[cpsr], cpsr \n\t"
297 : "=r" (rdv), [cpsr] "=r" (cpsr) 213 : "=r" (rdv), [cpsr] "=r" (cpsr)
298 : "0" (rdv), "r" (rnv), "r" (rmv), 214 : "0" (rdv), "r" (rnv), "r" (rmv),
299 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) 215 "1" (cpsr), [fn] "r" (asi->insn_fn)
300 : "lr", "memory", "cc" 216 : "lr", "memory", "cc"
301 ); 217 );
302 218
@@ -305,9 +221,10 @@ emulate_rd12rn16rm0_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
305} 221}
306 222
307static void __kprobes 223static void __kprobes
308emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) 224emulate_rd16rn12rm0rs8_rwflags_nopc(probes_opcode_t insn,
225 struct arch_probes_insn *asi,
226 struct pt_regs *regs)
309{ 227{
310 kprobe_opcode_t insn = p->opcode;
311 int rd = (insn >> 16) & 0xf; 228 int rd = (insn >> 16) & 0xf;
312 int rn = (insn >> 12) & 0xf; 229 int rn = (insn >> 12) & 0xf;
313 int rm = insn & 0xf; 230 int rm = insn & 0xf;
@@ -325,7 +242,7 @@ emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
325 "mrs %[cpsr], cpsr \n\t" 242 "mrs %[cpsr], cpsr \n\t"
326 : "=r" (rdv), [cpsr] "=r" (cpsr) 243 : "=r" (rdv), [cpsr] "=r" (cpsr)
327 : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv), 244 : "0" (rdv), "r" (rnv), "r" (rmv), "r" (rsv),
328 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) 245 "1" (cpsr), [fn] "r" (asi->insn_fn)
329 : "lr", "memory", "cc" 246 : "lr", "memory", "cc"
330 ); 247 );
331 248
@@ -334,9 +251,9 @@ emulate_rd16rn12rm0rs8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
334} 251}
335 252
336static void __kprobes 253static void __kprobes
337emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs) 254emulate_rd12rm0_noflags_nopc(probes_opcode_t insn,
255 struct arch_probes_insn *asi, struct pt_regs *regs)
338{ 256{
339 kprobe_opcode_t insn = p->opcode;
340 int rd = (insn >> 12) & 0xf; 257 int rd = (insn >> 12) & 0xf;
341 int rm = insn & 0xf; 258 int rm = insn & 0xf;
342 259
@@ -346,7 +263,7 @@ emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs)
346 __asm__ __volatile__ ( 263 __asm__ __volatile__ (
347 BLX("%[fn]") 264 BLX("%[fn]")
348 : "=r" (rdv) 265 : "=r" (rdv)
349 : "0" (rdv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn) 266 : "0" (rdv), "r" (rmv), [fn] "r" (asi->insn_fn)
350 : "lr", "memory", "cc" 267 : "lr", "memory", "cc"
351 ); 268 );
352 269
@@ -354,9 +271,10 @@ emulate_rd12rm0_noflags_nopc(struct kprobe *p, struct pt_regs *regs)
354} 271}
355 272
356static void __kprobes 273static void __kprobes
357emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs) 274emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(probes_opcode_t insn,
275 struct arch_probes_insn *asi,
276 struct pt_regs *regs)
358{ 277{
359 kprobe_opcode_t insn = p->opcode;
360 int rdlo = (insn >> 12) & 0xf; 278 int rdlo = (insn >> 12) & 0xf;
361 int rdhi = (insn >> 16) & 0xf; 279 int rdhi = (insn >> 16) & 0xf;
362 int rn = insn & 0xf; 280 int rn = insn & 0xf;
@@ -374,7 +292,7 @@ emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
374 "mrs %[cpsr], cpsr \n\t" 292 "mrs %[cpsr], cpsr \n\t"
375 : "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr) 293 : "=r" (rdlov), "=r" (rdhiv), [cpsr] "=r" (cpsr)
376 : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv), 294 : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
377 "2" (cpsr), [fn] "r" (p->ainsn.insn_fn) 295 "2" (cpsr), [fn] "r" (asi->insn_fn)
378 : "lr", "memory", "cc" 296 : "lr", "memory", "cc"
379 ); 297 );
380 298
@@ -383,623 +301,43 @@ emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(struct kprobe *p, struct pt_regs *regs)
383 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 301 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
384} 302}
385 303
386/* 304const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
387 * For the instruction masking and comparisons in all the "space_*" 305 [PROBES_EMULATE_NONE] = {.handler = probes_emulate_none},
388 * functions below, Do _not_ rearrange the order of tests unless 306 [PROBES_SIMULATE_NOP] = {.handler = probes_simulate_nop},
389 * you're very, very sure of what you are doing. For the sake of 307 [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
390 * efficiency, the masks for some tests sometimes assume other test 308 [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
391 * have been done prior to them so the number of patterns to test 309 [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
392 * for an instruction set can be as broad as possible to reduce the 310 [PROBES_MRS] = {.handler = simulate_mrs},
393 * number of tests needed. 311 [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx},
394 */ 312 [PROBES_CLZ] = {.handler = emulate_rd12rm0_noflags_nopc},
395 313 [PROBES_SATURATING_ARITHMETIC] = {
396static const union decode_item arm_1111_table[] = { 314 .handler = emulate_rd12rn16rm0_rwflags_nopc},
397 /* Unconditional instructions */ 315 [PROBES_MUL1] = {.handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
398 316 [PROBES_MUL2] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
399 /* memory hint 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx */ 317 [PROBES_SWP] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
400 /* PLDI (immediate) 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx */ 318 [PROBES_LDRSTRD] = {.handler = emulate_ldrdstrd},
401 /* PLDW (immediate) 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx */ 319 [PROBES_LOAD_EXTRA] = {.handler = emulate_ldr},
402 /* PLD (immediate) 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx */ 320 [PROBES_LOAD] = {.handler = emulate_ldr},
403 DECODE_SIMULATE (0xfe300000, 0xf4100000, kprobe_simulate_nop), 321 [PROBES_STORE_EXTRA] = {.handler = emulate_str},
404 322 [PROBES_STORE] = {.handler = emulate_str},
405 /* memory hint 1111 0110 x001 xxxx xxxx xxxx xxx0 xxxx */ 323 [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp},
406 /* PLDI (register) 1111 0110 x101 xxxx xxxx xxxx xxx0 xxxx */ 324 [PROBES_DATA_PROCESSING_REG] = {
407 /* PLDW (register) 1111 0111 x001 xxxx xxxx xxxx xxx0 xxxx */ 325 .handler = emulate_rd12rn16rm0rs8_rwflags},
408 /* PLD (register) 1111 0111 x101 xxxx xxxx xxxx xxx0 xxxx */ 326 [PROBES_DATA_PROCESSING_IMM] = {
409 DECODE_SIMULATE (0xfe300010, 0xf6100000, kprobe_simulate_nop), 327 .handler = emulate_rd12rn16rm0rs8_rwflags},
410 328 [PROBES_MOV_HALFWORD] = {.handler = emulate_rd12rm0_noflags_nopc},
411 /* BLX (immediate) 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx */ 329 [PROBES_SEV] = {.handler = probes_emulate_none},
412 DECODE_SIMULATE (0xfe000000, 0xfa000000, simulate_blx1), 330 [PROBES_WFE] = {.handler = probes_simulate_nop},
413 331 [PROBES_SATURATE] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
414 /* CPS 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */ 332 [PROBES_REV] = {.handler = emulate_rd12rm0_noflags_nopc},
415 /* SETEND 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */ 333 [PROBES_MMI] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
416 /* SRS 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */ 334 [PROBES_PACK] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
417 /* RFE 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ 335 [PROBES_EXTEND] = {.handler = emulate_rd12rm0_noflags_nopc},
418 336 [PROBES_EXTEND_ADD] = {.handler = emulate_rd12rn16rm0_rwflags_nopc},
419 /* Coprocessor instructions... */ 337 [PROBES_MUL_ADD_LONG] = {
420 /* MCRR2 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx */ 338 .handler = emulate_rdlo12rdhi16rn0rm8_rwflags_nopc},
421 /* MRRC2 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx */ 339 [PROBES_MUL_ADD] = {.handler = emulate_rd16rn12rm0rs8_rwflags_nopc},
422 /* LDC2 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ 340 [PROBES_BITFIELD] = {.handler = emulate_rd12rm0_noflags_nopc},
423 /* STC2 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ 341 [PROBES_BRANCH] = {.handler = simulate_bbl},
424 /* CDP2 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ 342 [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm}
425 /* MCR2 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
426 /* MRC2 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
427
428 /* Other unallocated instructions... */
429 DECODE_END
430};
431
432static const union decode_item arm_cccc_0001_0xx0____0xxx_table[] = {
433 /* Miscellaneous instructions */
434
435 /* MRS cpsr cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
436 DECODE_SIMULATEX(0x0ff000f0, 0x01000000, simulate_mrs,
437 REGS(0, NOPC, 0, 0, 0)),
438
439 /* BX cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
440 DECODE_SIMULATE (0x0ff000f0, 0x01200010, simulate_blx2bx),
441
442 /* BLX (register) cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
443 DECODE_SIMULATEX(0x0ff000f0, 0x01200030, simulate_blx2bx,
444 REGS(0, 0, 0, 0, NOPC)),
445
446 /* CLZ cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
447 DECODE_EMULATEX (0x0ff000f0, 0x01600010, emulate_rd12rm0_noflags_nopc,
448 REGS(0, NOPC, 0, 0, NOPC)),
449
450 /* QADD cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx */
451 /* QSUB cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */
452 /* QDADD cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx */
453 /* QDSUB cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx */
454 DECODE_EMULATEX (0x0f9000f0, 0x01000050, emulate_rd12rn16rm0_rwflags_nopc,
455 REGS(NOPC, NOPC, 0, 0, NOPC)),
456
457 /* BXJ cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
458 /* MSR cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
459 /* MRS spsr cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */
460 /* BKPT 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
461 /* SMC cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
462 /* And unallocated instructions... */
463 DECODE_END
464};
465
466static const union decode_item arm_cccc_0001_0xx0____1xx0_table[] = {
467 /* Halfword multiply and multiply-accumulate */
468
469 /* SMLALxy cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
470 DECODE_EMULATEX (0x0ff00090, 0x01400080, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
471 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
472
473 /* SMULWy cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
474 DECODE_OR (0x0ff000b0, 0x012000a0),
475 /* SMULxy cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
476 DECODE_EMULATEX (0x0ff00090, 0x01600080, emulate_rd16rn12rm0rs8_rwflags_nopc,
477 REGS(NOPC, 0, NOPC, 0, NOPC)),
478
479 /* SMLAxy cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx */
480 DECODE_OR (0x0ff00090, 0x01000080),
481 /* SMLAWy cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx */
482 DECODE_EMULATEX (0x0ff000b0, 0x01200080, emulate_rd16rn12rm0rs8_rwflags_nopc,
483 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
484
485 DECODE_END
486}; 343};
487
488static const union decode_item arm_cccc_0000_____1001_table[] = {
489 /* Multiply and multiply-accumulate */
490
491 /* MUL cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx */
492 /* MULS cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx */
493 DECODE_EMULATEX (0x0fe000f0, 0x00000090, emulate_rd16rn12rm0rs8_rwflags_nopc,
494 REGS(NOPC, 0, NOPC, 0, NOPC)),
495
496 /* MLA cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx */
497 /* MLAS cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx */
498 DECODE_OR (0x0fe000f0, 0x00200090),
499 /* MLS cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx */
500 DECODE_EMULATEX (0x0ff000f0, 0x00600090, emulate_rd16rn12rm0rs8_rwflags_nopc,
501 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
502
503 /* UMAAL cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx */
504 DECODE_OR (0x0ff000f0, 0x00400090),
505 /* UMULL cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx */
506 /* UMULLS cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx */
507 /* UMLAL cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx */
508 /* UMLALS cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx */
509 /* SMULL cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx */
510 /* SMULLS cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx */
511 /* SMLAL cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx */
512 /* SMLALS cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx */
513 DECODE_EMULATEX (0x0f8000f0, 0x00800090, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
514 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
515
516 DECODE_END
517};
518
519static const union decode_item arm_cccc_0001_____1001_table[] = {
520 /* Synchronization primitives */
521
522#if __LINUX_ARM_ARCH__ < 6
523 /* Deprecated on ARMv6 and may be UNDEFINED on v7 */
524 /* SMP/SWPB cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
525 DECODE_EMULATEX (0x0fb000f0, 0x01000090, emulate_rd12rn16rm0_rwflags_nopc,
526 REGS(NOPC, NOPC, 0, 0, NOPC)),
527#endif
528 /* LDREX/STREX{,D,B,H} cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
529 /* And unallocated instructions... */
530 DECODE_END
531};
532
533static const union decode_item arm_cccc_000x_____1xx1_table[] = {
534 /* Extra load/store instructions */
535
536 /* STRHT cccc 0000 xx10 xxxx xxxx xxxx 1011 xxxx */
537 /* ??? cccc 0000 xx10 xxxx xxxx xxxx 11x1 xxxx */
538 /* LDRHT cccc 0000 xx11 xxxx xxxx xxxx 1011 xxxx */
539 /* LDRSBT cccc 0000 xx11 xxxx xxxx xxxx 1101 xxxx */
540 /* LDRSHT cccc 0000 xx11 xxxx xxxx xxxx 1111 xxxx */
541 DECODE_REJECT (0x0f200090, 0x00200090),
542
543 /* LDRD/STRD lr,pc,{... cccc 000x x0x0 xxxx 111x xxxx 1101 xxxx */
544 DECODE_REJECT (0x0e10e0d0, 0x0000e0d0),
545
546 /* LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx */
547 /* STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx */
548 DECODE_EMULATEX (0x0e5000d0, 0x000000d0, emulate_ldrdstrd,
549 REGS(NOPCWB, NOPCX, 0, 0, NOPC)),
550
551 /* LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx */
552 /* STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx */
553 DECODE_EMULATEX (0x0e5000d0, 0x004000d0, emulate_ldrdstrd,
554 REGS(NOPCWB, NOPCX, 0, 0, 0)),
555
556 /* STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx */
557 DECODE_EMULATEX (0x0e5000f0, 0x000000b0, emulate_str,
558 REGS(NOPCWB, NOPC, 0, 0, NOPC)),
559
560 /* LDRH (register) cccc 000x x0x1 xxxx xxxx xxxx 1011 xxxx */
561 /* LDRSB (register) cccc 000x x0x1 xxxx xxxx xxxx 1101 xxxx */
562 /* LDRSH (register) cccc 000x x0x1 xxxx xxxx xxxx 1111 xxxx */
563 DECODE_EMULATEX (0x0e500090, 0x00100090, emulate_ldr,
564 REGS(NOPCWB, NOPC, 0, 0, NOPC)),
565
566 /* STRH (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1011 xxxx */
567 DECODE_EMULATEX (0x0e5000f0, 0x004000b0, emulate_str,
568 REGS(NOPCWB, NOPC, 0, 0, 0)),
569
570 /* LDRH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1011 xxxx */
571 /* LDRSB (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1101 xxxx */
572 /* LDRSH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1111 xxxx */
573 DECODE_EMULATEX (0x0e500090, 0x00500090, emulate_ldr,
574 REGS(NOPCWB, NOPC, 0, 0, 0)),
575
576 DECODE_END
577};
578
579static const union decode_item arm_cccc_000x_table[] = {
580 /* Data-processing (register) */
581
582 /* <op>S PC, ... cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx */
583 DECODE_REJECT (0x0e10f000, 0x0010f000),
584
585 /* MOV IP, SP 1110 0001 1010 0000 1100 0000 0000 1101 */
586 DECODE_SIMULATE (0xffffffff, 0xe1a0c00d, simulate_mov_ipsp),
587
588 /* TST (register) cccc 0001 0001 xxxx xxxx xxxx xxx0 xxxx */
589 /* TEQ (register) cccc 0001 0011 xxxx xxxx xxxx xxx0 xxxx */
590 /* CMP (register) cccc 0001 0101 xxxx xxxx xxxx xxx0 xxxx */
591 /* CMN (register) cccc 0001 0111 xxxx xxxx xxxx xxx0 xxxx */
592 DECODE_EMULATEX (0x0f900010, 0x01100000, emulate_rd12rn16rm0rs8_rwflags,
593 REGS(ANY, 0, 0, 0, ANY)),
594
595 /* MOV (register) cccc 0001 101x xxxx xxxx xxxx xxx0 xxxx */
596 /* MVN (register) cccc 0001 111x xxxx xxxx xxxx xxx0 xxxx */
597 DECODE_EMULATEX (0x0fa00010, 0x01a00000, emulate_rd12rn16rm0rs8_rwflags,
598 REGS(0, ANY, 0, 0, ANY)),
599
600 /* AND (register) cccc 0000 000x xxxx xxxx xxxx xxx0 xxxx */
601 /* EOR (register) cccc 0000 001x xxxx xxxx xxxx xxx0 xxxx */
602 /* SUB (register) cccc 0000 010x xxxx xxxx xxxx xxx0 xxxx */
603 /* RSB (register) cccc 0000 011x xxxx xxxx xxxx xxx0 xxxx */
604 /* ADD (register) cccc 0000 100x xxxx xxxx xxxx xxx0 xxxx */
605 /* ADC (register) cccc 0000 101x xxxx xxxx xxxx xxx0 xxxx */
606 /* SBC (register) cccc 0000 110x xxxx xxxx xxxx xxx0 xxxx */
607 /* RSC (register) cccc 0000 111x xxxx xxxx xxxx xxx0 xxxx */
608 /* ORR (register) cccc 0001 100x xxxx xxxx xxxx xxx0 xxxx */
609 /* BIC (register) cccc 0001 110x xxxx xxxx xxxx xxx0 xxxx */
610 DECODE_EMULATEX (0x0e000010, 0x00000000, emulate_rd12rn16rm0rs8_rwflags,
611 REGS(ANY, ANY, 0, 0, ANY)),
612
613 /* TST (reg-shift reg) cccc 0001 0001 xxxx xxxx xxxx 0xx1 xxxx */
614 /* TEQ (reg-shift reg) cccc 0001 0011 xxxx xxxx xxxx 0xx1 xxxx */
615 /* CMP (reg-shift reg) cccc 0001 0101 xxxx xxxx xxxx 0xx1 xxxx */
616 /* CMN (reg-shift reg) cccc 0001 0111 xxxx xxxx xxxx 0xx1 xxxx */
617 DECODE_EMULATEX (0x0f900090, 0x01100010, emulate_rd12rn16rm0rs8_rwflags,
618 REGS(ANY, 0, NOPC, 0, ANY)),
619
620 /* MOV (reg-shift reg) cccc 0001 101x xxxx xxxx xxxx 0xx1 xxxx */
621 /* MVN (reg-shift reg) cccc 0001 111x xxxx xxxx xxxx 0xx1 xxxx */
622 DECODE_EMULATEX (0x0fa00090, 0x01a00010, emulate_rd12rn16rm0rs8_rwflags,
623 REGS(0, ANY, NOPC, 0, ANY)),
624
625 /* AND (reg-shift reg) cccc 0000 000x xxxx xxxx xxxx 0xx1 xxxx */
626 /* EOR (reg-shift reg) cccc 0000 001x xxxx xxxx xxxx 0xx1 xxxx */
627 /* SUB (reg-shift reg) cccc 0000 010x xxxx xxxx xxxx 0xx1 xxxx */
628 /* RSB (reg-shift reg) cccc 0000 011x xxxx xxxx xxxx 0xx1 xxxx */
629 /* ADD (reg-shift reg) cccc 0000 100x xxxx xxxx xxxx 0xx1 xxxx */
630 /* ADC (reg-shift reg) cccc 0000 101x xxxx xxxx xxxx 0xx1 xxxx */
631 /* SBC (reg-shift reg) cccc 0000 110x xxxx xxxx xxxx 0xx1 xxxx */
632 /* RSC (reg-shift reg) cccc 0000 111x xxxx xxxx xxxx 0xx1 xxxx */
633 /* ORR (reg-shift reg) cccc 0001 100x xxxx xxxx xxxx 0xx1 xxxx */
634 /* BIC (reg-shift reg) cccc 0001 110x xxxx xxxx xxxx 0xx1 xxxx */
635 DECODE_EMULATEX (0x0e000090, 0x00000010, emulate_rd12rn16rm0rs8_rwflags,
636 REGS(ANY, ANY, NOPC, 0, ANY)),
637
638 DECODE_END
639};
640
641static const union decode_item arm_cccc_001x_table[] = {
642 /* Data-processing (immediate) */
643
644 /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
645 /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
646 DECODE_EMULATEX (0x0fb00000, 0x03000000, emulate_rd12rm0_noflags_nopc,
647 REGS(0, NOPC, 0, 0, 0)),
648
649 /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
650 DECODE_OR (0x0fff00ff, 0x03200001),
651 /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
652 DECODE_EMULATE (0x0fff00ff, 0x03200004, kprobe_emulate_none),
653 /* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
654 /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
655 /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
656 DECODE_SIMULATE (0x0fff00fc, 0x03200000, kprobe_simulate_nop),
657 /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */
658 /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
659 /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
660 DECODE_REJECT (0x0fb00000, 0x03200000),
661
662 /* <op>S PC, ... cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */
663 DECODE_REJECT (0x0e10f000, 0x0210f000),
664
665 /* TST (immediate) cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx */
666 /* TEQ (immediate) cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx */
667 /* CMP (immediate) cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx */
668 /* CMN (immediate) cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx */
669 DECODE_EMULATEX (0x0f900000, 0x03100000, emulate_rd12rn16rm0rs8_rwflags,
670 REGS(ANY, 0, 0, 0, 0)),
671
672 /* MOV (immediate) cccc 0011 101x xxxx xxxx xxxx xxxx xxxx */
673 /* MVN (immediate) cccc 0011 111x xxxx xxxx xxxx xxxx xxxx */
674 DECODE_EMULATEX (0x0fa00000, 0x03a00000, emulate_rd12rn16rm0rs8_rwflags,
675 REGS(0, ANY, 0, 0, 0)),
676
677 /* AND (immediate) cccc 0010 000x xxxx xxxx xxxx xxxx xxxx */
678 /* EOR (immediate) cccc 0010 001x xxxx xxxx xxxx xxxx xxxx */
679 /* SUB (immediate) cccc 0010 010x xxxx xxxx xxxx xxxx xxxx */
680 /* RSB (immediate) cccc 0010 011x xxxx xxxx xxxx xxxx xxxx */
681 /* ADD (immediate) cccc 0010 100x xxxx xxxx xxxx xxxx xxxx */
682 /* ADC (immediate) cccc 0010 101x xxxx xxxx xxxx xxxx xxxx */
683 /* SBC (immediate) cccc 0010 110x xxxx xxxx xxxx xxxx xxxx */
684 /* RSC (immediate) cccc 0010 111x xxxx xxxx xxxx xxxx xxxx */
685 /* ORR (immediate) cccc 0011 100x xxxx xxxx xxxx xxxx xxxx */
686 /* BIC (immediate) cccc 0011 110x xxxx xxxx xxxx xxxx xxxx */
687 DECODE_EMULATEX (0x0e000000, 0x02000000, emulate_rd12rn16rm0rs8_rwflags,
688 REGS(ANY, ANY, 0, 0, 0)),
689
690 DECODE_END
691};
692
693static const union decode_item arm_cccc_0110_____xxx1_table[] = {
694 /* Media instructions */
695
696 /* SEL cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx */
697 DECODE_EMULATEX (0x0ff000f0, 0x068000b0, emulate_rd12rn16rm0_rwflags_nopc,
698 REGS(NOPC, NOPC, 0, 0, NOPC)),
699
700 /* SSAT cccc 0110 101x xxxx xxxx xxxx xx01 xxxx */
701 /* USAT cccc 0110 111x xxxx xxxx xxxx xx01 xxxx */
702 DECODE_OR(0x0fa00030, 0x06a00010),
703 /* SSAT16 cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx */
704 /* USAT16 cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx */
705 DECODE_EMULATEX (0x0fb000f0, 0x06a00030, emulate_rd12rn16rm0_rwflags_nopc,
706 REGS(0, NOPC, 0, 0, NOPC)),
707
708 /* REV cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
709 /* REV16 cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
710 /* RBIT cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
711 /* REVSH cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
712 DECODE_EMULATEX (0x0fb00070, 0x06b00030, emulate_rd12rm0_noflags_nopc,
713 REGS(0, NOPC, 0, 0, NOPC)),
714
715 /* ??? cccc 0110 0x00 xxxx xxxx xxxx xxx1 xxxx */
716 DECODE_REJECT (0x0fb00010, 0x06000010),
717 /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1011 xxxx */
718 DECODE_REJECT (0x0f8000f0, 0x060000b0),
719 /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1101 xxxx */
720 DECODE_REJECT (0x0f8000f0, 0x060000d0),
721 /* SADD16 cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx */
722 /* SADDSUBX cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx */
723 /* SSUBADDX cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx */
724 /* SSUB16 cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx */
725 /* SADD8 cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx */
726 /* SSUB8 cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx */
727 /* QADD16 cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx */
728 /* QADDSUBX cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx */
729 /* QSUBADDX cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx */
730 /* QSUB16 cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx */
731 /* QADD8 cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx */
732 /* QSUB8 cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx */
733 /* SHADD16 cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx */
734 /* SHADDSUBX cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx */
735 /* SHSUBADDX cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx */
736 /* SHSUB16 cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx */
737 /* SHADD8 cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx */
738 /* SHSUB8 cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx */
739 /* UADD16 cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx */
740 /* UADDSUBX cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx */
741 /* USUBADDX cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx */
742 /* USUB16 cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx */
743 /* UADD8 cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx */
744 /* USUB8 cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx */
745 /* UQADD16 cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx */
746 /* UQADDSUBX cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx */
747 /* UQSUBADDX cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx */
748 /* UQSUB16 cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx */
749 /* UQADD8 cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx */
750 /* UQSUB8 cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx */
751 /* UHADD16 cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx */
752 /* UHADDSUBX cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx */
753 /* UHSUBADDX cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx */
754 /* UHSUB16 cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx */
755 /* UHADD8 cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx */
756 /* UHSUB8 cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx */
757 DECODE_EMULATEX (0x0f800010, 0x06000010, emulate_rd12rn16rm0_rwflags_nopc,
758 REGS(NOPC, NOPC, 0, 0, NOPC)),
759
760 /* PKHBT cccc 0110 1000 xxxx xxxx xxxx x001 xxxx */
761 /* PKHTB cccc 0110 1000 xxxx xxxx xxxx x101 xxxx */
762 DECODE_EMULATEX (0x0ff00030, 0x06800010, emulate_rd12rn16rm0_rwflags_nopc,
763 REGS(NOPC, NOPC, 0, 0, NOPC)),
764
765 /* ??? cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx */
766 /* ??? cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx */
767 DECODE_REJECT (0x0fb000f0, 0x06900070),
768
769 /* SXTB16 cccc 0110 1000 1111 xxxx xxxx 0111 xxxx */
770 /* SXTB cccc 0110 1010 1111 xxxx xxxx 0111 xxxx */
771 /* SXTH cccc 0110 1011 1111 xxxx xxxx 0111 xxxx */
772 /* UXTB16 cccc 0110 1100 1111 xxxx xxxx 0111 xxxx */
773 /* UXTB cccc 0110 1110 1111 xxxx xxxx 0111 xxxx */
774 /* UXTH cccc 0110 1111 1111 xxxx xxxx 0111 xxxx */
775 DECODE_EMULATEX (0x0f8f00f0, 0x068f0070, emulate_rd12rm0_noflags_nopc,
776 REGS(0, NOPC, 0, 0, NOPC)),
777
778 /* SXTAB16 cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx */
779 /* SXTAB cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx */
780 /* SXTAH cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx */
781 /* UXTAB16 cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx */
782 /* UXTAB cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx */
783 /* UXTAH cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx */
784 DECODE_EMULATEX (0x0f8000f0, 0x06800070, emulate_rd12rn16rm0_rwflags_nopc,
785 REGS(NOPCX, NOPC, 0, 0, NOPC)),
786
787 DECODE_END
788};
789
790static const union decode_item arm_cccc_0111_____xxx1_table[] = {
791 /* Media instructions */
792
793 /* UNDEFINED cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
794 DECODE_REJECT (0x0ff000f0, 0x07f000f0),
795
796 /* SMLALD cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
797 /* SMLSLD cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
798 DECODE_EMULATEX (0x0ff00090, 0x07400010, emulate_rdlo12rdhi16rn0rm8_rwflags_nopc,
799 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
800
801 /* SMUAD cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx */
802 /* SMUSD cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx */
803 DECODE_OR (0x0ff0f090, 0x0700f010),
804 /* SMMUL cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx */
805 DECODE_OR (0x0ff0f0d0, 0x0750f010),
806 /* USAD8 cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
807 DECODE_EMULATEX (0x0ff0f0f0, 0x0780f010, emulate_rd16rn12rm0rs8_rwflags_nopc,
808 REGS(NOPC, 0, NOPC, 0, NOPC)),
809
810 /* SMLAD cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx */
811 /* SMLSD cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx */
812 DECODE_OR (0x0ff00090, 0x07000010),
813 /* SMMLA cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx */
814 DECODE_OR (0x0ff000d0, 0x07500010),
815 /* USADA8 cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
816 DECODE_EMULATEX (0x0ff000f0, 0x07800010, emulate_rd16rn12rm0rs8_rwflags_nopc,
817 REGS(NOPC, NOPCX, NOPC, 0, NOPC)),
818
819 /* SMMLS cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx */
820 DECODE_EMULATEX (0x0ff000d0, 0x075000d0, emulate_rd16rn12rm0rs8_rwflags_nopc,
821 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
822
823 /* SBFX cccc 0111 101x xxxx xxxx xxxx x101 xxxx */
824 /* UBFX cccc 0111 111x xxxx xxxx xxxx x101 xxxx */
825 DECODE_EMULATEX (0x0fa00070, 0x07a00050, emulate_rd12rm0_noflags_nopc,
826 REGS(0, NOPC, 0, 0, NOPC)),
827
828 /* BFC cccc 0111 110x xxxx xxxx xxxx x001 1111 */
829 DECODE_EMULATEX (0x0fe0007f, 0x07c0001f, emulate_rd12rm0_noflags_nopc,
830 REGS(0, NOPC, 0, 0, 0)),
831
832 /* BFI cccc 0111 110x xxxx xxxx xxxx x001 xxxx */
833 DECODE_EMULATEX (0x0fe00070, 0x07c00010, emulate_rd12rm0_noflags_nopc,
834 REGS(0, NOPC, 0, 0, NOPCX)),
835
836 DECODE_END
837};
838
839static const union decode_item arm_cccc_01xx_table[] = {
840 /* Load/store word and unsigned byte */
841
842 /* LDRB/STRB pc,[...] cccc 01xx x0xx xxxx xxxx xxxx xxxx xxxx */
843 DECODE_REJECT (0x0c40f000, 0x0440f000),
844
845 /* STRT cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
846 /* LDRT cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
847 /* STRBT cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
848 /* LDRBT cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
849 DECODE_REJECT (0x0d200000, 0x04200000),
850
851 /* STR (immediate) cccc 010x x0x0 xxxx xxxx xxxx xxxx xxxx */
852 /* STRB (immediate) cccc 010x x1x0 xxxx xxxx xxxx xxxx xxxx */
853 DECODE_EMULATEX (0x0e100000, 0x04000000, emulate_str,
854 REGS(NOPCWB, ANY, 0, 0, 0)),
855
856 /* LDR (immediate) cccc 010x x0x1 xxxx xxxx xxxx xxxx xxxx */
857 /* LDRB (immediate) cccc 010x x1x1 xxxx xxxx xxxx xxxx xxxx */
858 DECODE_EMULATEX (0x0e100000, 0x04100000, emulate_ldr,
859 REGS(NOPCWB, ANY, 0, 0, 0)),
860
861 /* STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx */
862 /* STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx */
863 DECODE_EMULATEX (0x0e100000, 0x06000000, emulate_str,
864 REGS(NOPCWB, ANY, 0, 0, NOPC)),
865
866 /* LDR (register) cccc 011x x0x1 xxxx xxxx xxxx xxxx xxxx */
867 /* LDRB (register) cccc 011x x1x1 xxxx xxxx xxxx xxxx xxxx */
868 DECODE_EMULATEX (0x0e100000, 0x06100000, emulate_ldr,
869 REGS(NOPCWB, ANY, 0, 0, NOPC)),
870
871 DECODE_END
872};
873
874static const union decode_item arm_cccc_100x_table[] = {
875 /* Block data transfer instructions */
876
877 /* LDM cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
878 /* STM cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
879 DECODE_CUSTOM (0x0e400000, 0x08000000, kprobe_decode_ldmstm),
880
881 /* STM (user registers) cccc 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
882 /* LDM (user registers) cccc 100x x1x1 xxxx 0xxx xxxx xxxx xxxx */
883 /* LDM (exception ret) cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
884 DECODE_END
885};
886
887const union decode_item kprobe_decode_arm_table[] = {
888 /*
889 * Unconditional instructions
890 * 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx
891 */
892 DECODE_TABLE (0xf0000000, 0xf0000000, arm_1111_table),
893
894 /*
895 * Miscellaneous instructions
896 * cccc 0001 0xx0 xxxx xxxx xxxx 0xxx xxxx
897 */
898 DECODE_TABLE (0x0f900080, 0x01000000, arm_cccc_0001_0xx0____0xxx_table),
899
900 /*
901 * Halfword multiply and multiply-accumulate
902 * cccc 0001 0xx0 xxxx xxxx xxxx 1xx0 xxxx
903 */
904 DECODE_TABLE (0x0f900090, 0x01000080, arm_cccc_0001_0xx0____1xx0_table),
905
906 /*
907 * Multiply and multiply-accumulate
908 * cccc 0000 xxxx xxxx xxxx xxxx 1001 xxxx
909 */
910 DECODE_TABLE (0x0f0000f0, 0x00000090, arm_cccc_0000_____1001_table),
911
912 /*
913 * Synchronization primitives
914 * cccc 0001 xxxx xxxx xxxx xxxx 1001 xxxx
915 */
916 DECODE_TABLE (0x0f0000f0, 0x01000090, arm_cccc_0001_____1001_table),
917
918 /*
919 * Extra load/store instructions
920 * cccc 000x xxxx xxxx xxxx xxxx 1xx1 xxxx
921 */
922 DECODE_TABLE (0x0e000090, 0x00000090, arm_cccc_000x_____1xx1_table),
923
924 /*
925 * Data-processing (register)
926 * cccc 000x xxxx xxxx xxxx xxxx xxx0 xxxx
927 * Data-processing (register-shifted register)
928 * cccc 000x xxxx xxxx xxxx xxxx 0xx1 xxxx
929 */
930 DECODE_TABLE (0x0e000000, 0x00000000, arm_cccc_000x_table),
931
932 /*
933 * Data-processing (immediate)
934 * cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
935 */
936 DECODE_TABLE (0x0e000000, 0x02000000, arm_cccc_001x_table),
937
938 /*
939 * Media instructions
940 * cccc 011x xxxx xxxx xxxx xxxx xxx1 xxxx
941 */
942 DECODE_TABLE (0x0f000010, 0x06000010, arm_cccc_0110_____xxx1_table),
943 DECODE_TABLE (0x0f000010, 0x07000010, arm_cccc_0111_____xxx1_table),
944
945 /*
946 * Load/store word and unsigned byte
947 * cccc 01xx xxxx xxxx xxxx xxxx xxxx xxxx
948 */
949 DECODE_TABLE (0x0c000000, 0x04000000, arm_cccc_01xx_table),
950
951 /*
952 * Block data transfer instructions
953 * cccc 100x xxxx xxxx xxxx xxxx xxxx xxxx
954 */
955 DECODE_TABLE (0x0e000000, 0x08000000, arm_cccc_100x_table),
956
957 /* B cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
958 /* BL cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
959 DECODE_SIMULATE (0x0e000000, 0x0a000000, simulate_bbl),
960
961 /*
962 * Supervisor Call, and coprocessor instructions
963 */
964
965 /* MCRR cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx */
966 /* MRRC cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx */
967 /* LDC cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
968 /* STC cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
969 /* CDP cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
970 /* MCR cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
971 /* MRC cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
972 /* SVC cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
973 DECODE_REJECT (0x0c000000, 0x0c000000),
974
975 DECODE_END
976};
977#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
978EXPORT_SYMBOL_GPL(kprobe_decode_arm_table);
979#endif
980
981static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs)
982{
983 regs->ARM_pc += 4;
984 p->ainsn.insn_handler(p, regs);
985}
986
987/* Return:
988 * INSN_REJECTED If instruction is one not allowed to kprobe,
989 * INSN_GOOD If instruction is supported and uses instruction slot,
990 * INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot.
991 *
992 * For instructions we don't want to kprobe (INSN_REJECTED return result):
993 * These are generally ones that modify the processor state making
994 * them "hard" to simulate such as switches processor modes or
995 * make accesses in alternate modes. Any of these could be simulated
996 * if the work was put into it, but low return considering they
997 * should also be very rare.
998 */
999enum kprobe_insn __kprobes
1000arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1001{
1002 asi->insn_singlestep = arm_singlestep;
1003 asi->insn_check_cc = kprobe_condition_checks[insn>>28];
1004 return kprobe_decode_insn(insn, asi, kprobe_decode_arm_table, false);
1005}
diff --git a/arch/arm/kernel/kprobes-common.c b/arch/arm/kernel/kprobes-common.c
index 18a76282970e..c311ed94ff1c 100644
--- a/arch/arm/kernel/kprobes-common.c
+++ b/arch/arm/kernel/kprobes-common.c
@@ -13,178 +13,14 @@
13 13
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/kprobes.h> 15#include <linux/kprobes.h>
16#include <asm/system_info.h>
17 16
18#include "kprobes.h" 17#include "kprobes.h"
19 18
20 19
21#ifndef find_str_pc_offset 20static void __kprobes simulate_ldm1stm1(probes_opcode_t insn,
22 21 struct arch_probes_insn *asi,
23/* 22 struct pt_regs *regs)
24 * For STR and STM instructions, an ARM core may choose to use either
25 * a +8 or a +12 displacement from the current instruction's address.
26 * Whichever value is chosen for a given core, it must be the same for
27 * both instructions and may not change. This function measures it.
28 */
29
30int str_pc_offset;
31
32void __init find_str_pc_offset(void)
33{
34 int addr, scratch, ret;
35
36 __asm__ (
37 "sub %[ret], pc, #4 \n\t"
38 "str pc, %[addr] \n\t"
39 "ldr %[scr], %[addr] \n\t"
40 "sub %[ret], %[scr], %[ret] \n\t"
41 : [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr));
42
43 str_pc_offset = ret;
44}
45
46#endif /* !find_str_pc_offset */
47
48
49#ifndef test_load_write_pc_interworking
50
51bool load_write_pc_interworks;
52
53void __init test_load_write_pc_interworking(void)
54{
55 int arch = cpu_architecture();
56 BUG_ON(arch == CPU_ARCH_UNKNOWN);
57 load_write_pc_interworks = arch >= CPU_ARCH_ARMv5T;
58}
59
60#endif /* !test_load_write_pc_interworking */
61
62
63#ifndef test_alu_write_pc_interworking
64
65bool alu_write_pc_interworks;
66
67void __init test_alu_write_pc_interworking(void)
68{
69 int arch = cpu_architecture();
70 BUG_ON(arch == CPU_ARCH_UNKNOWN);
71 alu_write_pc_interworks = arch >= CPU_ARCH_ARMv7;
72}
73
74#endif /* !test_alu_write_pc_interworking */
75
76
77void __init arm_kprobe_decode_init(void)
78{
79 find_str_pc_offset();
80 test_load_write_pc_interworking();
81 test_alu_write_pc_interworking();
82}
83
84
85static unsigned long __kprobes __check_eq(unsigned long cpsr)
86{
87 return cpsr & PSR_Z_BIT;
88}
89
90static unsigned long __kprobes __check_ne(unsigned long cpsr)
91{
92 return (~cpsr) & PSR_Z_BIT;
93}
94
95static unsigned long __kprobes __check_cs(unsigned long cpsr)
96{
97 return cpsr & PSR_C_BIT;
98}
99
100static unsigned long __kprobes __check_cc(unsigned long cpsr)
101{
102 return (~cpsr) & PSR_C_BIT;
103}
104
105static unsigned long __kprobes __check_mi(unsigned long cpsr)
106{
107 return cpsr & PSR_N_BIT;
108}
109
110static unsigned long __kprobes __check_pl(unsigned long cpsr)
111{
112 return (~cpsr) & PSR_N_BIT;
113}
114
115static unsigned long __kprobes __check_vs(unsigned long cpsr)
116{
117 return cpsr & PSR_V_BIT;
118}
119
120static unsigned long __kprobes __check_vc(unsigned long cpsr)
121{
122 return (~cpsr) & PSR_V_BIT;
123}
124
125static unsigned long __kprobes __check_hi(unsigned long cpsr)
126{
127 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
128 return cpsr & PSR_C_BIT;
129}
130
131static unsigned long __kprobes __check_ls(unsigned long cpsr)
132{
133 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
134 return (~cpsr) & PSR_C_BIT;
135}
136
137static unsigned long __kprobes __check_ge(unsigned long cpsr)
138{
139 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
140 return (~cpsr) & PSR_N_BIT;
141}
142
143static unsigned long __kprobes __check_lt(unsigned long cpsr)
144{
145 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
146 return cpsr & PSR_N_BIT;
147}
148
149static unsigned long __kprobes __check_gt(unsigned long cpsr)
150{
151 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
152 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
153 return (~temp) & PSR_N_BIT;
154}
155
156static unsigned long __kprobes __check_le(unsigned long cpsr)
157{
158 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
159 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
160 return temp & PSR_N_BIT;
161}
162
163static unsigned long __kprobes __check_al(unsigned long cpsr)
164{
165 return true;
166}
167
168kprobe_check_cc * const kprobe_condition_checks[16] = {
169 &__check_eq, &__check_ne, &__check_cs, &__check_cc,
170 &__check_mi, &__check_pl, &__check_vs, &__check_vc,
171 &__check_hi, &__check_ls, &__check_ge, &__check_lt,
172 &__check_gt, &__check_le, &__check_al, &__check_al
173};
174
175
176void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs)
177{
178}
179
180void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs)
181{
182 p->ainsn.insn_fn();
183}
184
185static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
186{ 23{
187 kprobe_opcode_t insn = p->opcode;
188 int rn = (insn >> 16) & 0xf; 24 int rn = (insn >> 16) & 0xf;
189 int lbit = insn & (1 << 20); 25 int lbit = insn & (1 << 20);
190 int wbit = insn & (1 << 21); 26 int wbit = insn & (1 << 21);
@@ -223,24 +59,31 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
223 } 59 }
224} 60}
225 61
226static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs) 62static void __kprobes simulate_stm1_pc(probes_opcode_t insn,
63 struct arch_probes_insn *asi,
64 struct pt_regs *regs)
227{ 65{
228 regs->ARM_pc = (long)p->addr + str_pc_offset; 66 unsigned long addr = regs->ARM_pc - 4;
229 simulate_ldm1stm1(p, regs); 67
230 regs->ARM_pc = (long)p->addr + 4; 68 regs->ARM_pc = (long)addr + str_pc_offset;
69 simulate_ldm1stm1(insn, asi, regs);
70 regs->ARM_pc = (long)addr + 4;
231} 71}
232 72
233static void __kprobes simulate_ldm1_pc(struct kprobe *p, struct pt_regs *regs) 73static void __kprobes simulate_ldm1_pc(probes_opcode_t insn,
74 struct arch_probes_insn *asi,
75 struct pt_regs *regs)
234{ 76{
235 simulate_ldm1stm1(p, regs); 77 simulate_ldm1stm1(insn, asi, regs);
236 load_write_pc(regs->ARM_pc, regs); 78 load_write_pc(regs->ARM_pc, regs);
237} 79}
238 80
239static void __kprobes 81static void __kprobes
240emulate_generic_r0_12_noflags(struct kprobe *p, struct pt_regs *regs) 82emulate_generic_r0_12_noflags(probes_opcode_t insn,
83 struct arch_probes_insn *asi, struct pt_regs *regs)
241{ 84{
242 register void *rregs asm("r1") = regs; 85 register void *rregs asm("r1") = regs;
243 register void *rfn asm("lr") = p->ainsn.insn_fn; 86 register void *rfn asm("lr") = asi->insn_fn;
244 87
245 __asm__ __volatile__ ( 88 __asm__ __volatile__ (
246 "stmdb sp!, {%[regs], r11} \n\t" 89 "stmdb sp!, {%[regs], r11} \n\t"
@@ -264,22 +107,27 @@ emulate_generic_r0_12_noflags(struct kprobe *p, struct pt_regs *regs)
264} 107}
265 108
266static void __kprobes 109static void __kprobes
267emulate_generic_r2_14_noflags(struct kprobe *p, struct pt_regs *regs) 110emulate_generic_r2_14_noflags(probes_opcode_t insn,
111 struct arch_probes_insn *asi, struct pt_regs *regs)
268{ 112{
269 emulate_generic_r0_12_noflags(p, (struct pt_regs *)(regs->uregs+2)); 113 emulate_generic_r0_12_noflags(insn, asi,
114 (struct pt_regs *)(regs->uregs+2));
270} 115}
271 116
272static void __kprobes 117static void __kprobes
273emulate_ldm_r3_15(struct kprobe *p, struct pt_regs *regs) 118emulate_ldm_r3_15(probes_opcode_t insn,
119 struct arch_probes_insn *asi, struct pt_regs *regs)
274{ 120{
275 emulate_generic_r0_12_noflags(p, (struct pt_regs *)(regs->uregs+3)); 121 emulate_generic_r0_12_noflags(insn, asi,
122 (struct pt_regs *)(regs->uregs+3));
276 load_write_pc(regs->ARM_pc, regs); 123 load_write_pc(regs->ARM_pc, regs);
277} 124}
278 125
279enum kprobe_insn __kprobes 126enum probes_insn __kprobes
280kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi) 127kprobe_decode_ldmstm(probes_opcode_t insn, struct arch_probes_insn *asi,
128 const struct decode_header *h)
281{ 129{
282 kprobe_insn_handler_t *handler = 0; 130 probes_insn_handler_t *handler = 0;
283 unsigned reglist = insn & 0xffff; 131 unsigned reglist = insn & 0xffff;
284 int is_ldm = insn & 0x100000; 132 int is_ldm = insn & 0x100000;
285 int rn = (insn >> 16) & 0xf; 133 int rn = (insn >> 16) & 0xf;
@@ -319,260 +167,3 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
319 return INSN_GOOD_NO_SLOT; 167 return INSN_GOOD_NO_SLOT;
320} 168}
321 169
322
323/*
324 * Prepare an instruction slot to receive an instruction for emulating.
325 * This is done by placing a subroutine return after the location where the
326 * instruction will be placed. We also modify ARM instructions to be
327 * unconditional as the condition code will already be checked before any
328 * emulation handler is called.
329 */
330static kprobe_opcode_t __kprobes
331prepare_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
332 bool thumb)
333{
334#ifdef CONFIG_THUMB2_KERNEL
335 if (thumb) {
336 u16 *thumb_insn = (u16 *)asi->insn;
337 thumb_insn[1] = 0x4770; /* Thumb bx lr */
338 thumb_insn[2] = 0x4770; /* Thumb bx lr */
339 return insn;
340 }
341 asi->insn[1] = 0xe12fff1e; /* ARM bx lr */
342#else
343 asi->insn[1] = 0xe1a0f00e; /* mov pc, lr */
344#endif
345 /* Make an ARM instruction unconditional */
346 if (insn < 0xe0000000)
347 insn = (insn | 0xe0000000) & ~0x10000000;
348 return insn;
349}
350
351/*
352 * Write a (probably modified) instruction into the slot previously prepared by
353 * prepare_emulated_insn
354 */
355static void __kprobes
356set_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
357 bool thumb)
358{
359#ifdef CONFIG_THUMB2_KERNEL
360 if (thumb) {
361 u16 *ip = (u16 *)asi->insn;
362 if (is_wide_instruction(insn))
363 *ip++ = insn >> 16;
364 *ip++ = insn;
365 return;
366 }
367#endif
368 asi->insn[0] = insn;
369}
370
371/*
372 * When we modify the register numbers encoded in an instruction to be emulated,
373 * the new values come from this define. For ARM and 32-bit Thumb instructions
374 * this gives...
375 *
376 * bit position 16 12 8 4 0
377 * ---------------+---+---+---+---+---+
378 * register r2 r0 r1 -- r3
379 */
380#define INSN_NEW_BITS 0x00020103
381
382/* Each nibble has same value as that at INSN_NEW_BITS bit 16 */
383#define INSN_SAMEAS16_BITS 0x22222222
384
385/*
386 * Validate and modify each of the registers encoded in an instruction.
387 *
388 * Each nibble in regs contains a value from enum decode_reg_type. For each
389 * non-zero value, the corresponding nibble in pinsn is validated and modified
390 * according to the type.
391 */
392static bool __kprobes decode_regs(kprobe_opcode_t* pinsn, u32 regs)
393{
394 kprobe_opcode_t insn = *pinsn;
395 kprobe_opcode_t mask = 0xf; /* Start at least significant nibble */
396
397 for (; regs != 0; regs >>= 4, mask <<= 4) {
398
399 kprobe_opcode_t new_bits = INSN_NEW_BITS;
400
401 switch (regs & 0xf) {
402
403 case REG_TYPE_NONE:
404 /* Nibble not a register, skip to next */
405 continue;
406
407 case REG_TYPE_ANY:
408 /* Any register is allowed */
409 break;
410
411 case REG_TYPE_SAMEAS16:
412 /* Replace register with same as at bit position 16 */
413 new_bits = INSN_SAMEAS16_BITS;
414 break;
415
416 case REG_TYPE_SP:
417 /* Only allow SP (R13) */
418 if ((insn ^ 0xdddddddd) & mask)
419 goto reject;
420 break;
421
422 case REG_TYPE_PC:
423 /* Only allow PC (R15) */
424 if ((insn ^ 0xffffffff) & mask)
425 goto reject;
426 break;
427
428 case REG_TYPE_NOSP:
429 /* Reject SP (R13) */
430 if (((insn ^ 0xdddddddd) & mask) == 0)
431 goto reject;
432 break;
433
434 case REG_TYPE_NOSPPC:
435 case REG_TYPE_NOSPPCX:
436 /* Reject SP and PC (R13 and R15) */
437 if (((insn ^ 0xdddddddd) & 0xdddddddd & mask) == 0)
438 goto reject;
439 break;
440
441 case REG_TYPE_NOPCWB:
442 if (!is_writeback(insn))
443 break; /* No writeback, so any register is OK */
444 /* fall through... */
445 case REG_TYPE_NOPC:
446 case REG_TYPE_NOPCX:
447 /* Reject PC (R15) */
448 if (((insn ^ 0xffffffff) & mask) == 0)
449 goto reject;
450 break;
451 }
452
453 /* Replace value of nibble with new register number... */
454 insn &= ~mask;
455 insn |= new_bits & mask;
456 }
457
458 *pinsn = insn;
459 return true;
460
461reject:
462 return false;
463}
464
465static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
466 [DECODE_TYPE_TABLE] = sizeof(struct decode_table),
467 [DECODE_TYPE_CUSTOM] = sizeof(struct decode_custom),
468 [DECODE_TYPE_SIMULATE] = sizeof(struct decode_simulate),
469 [DECODE_TYPE_EMULATE] = sizeof(struct decode_emulate),
470 [DECODE_TYPE_OR] = sizeof(struct decode_or),
471 [DECODE_TYPE_REJECT] = sizeof(struct decode_reject)
472};
473
474/*
475 * kprobe_decode_insn operates on data tables in order to decode an ARM
476 * architecture instruction onto which a kprobe has been placed.
477 *
478 * These instruction decoding tables are a concatenation of entries each
479 * of which consist of one of the following structs:
480 *
481 * decode_table
482 * decode_custom
483 * decode_simulate
484 * decode_emulate
485 * decode_or
486 * decode_reject
487 *
488 * Each of these starts with a struct decode_header which has the following
489 * fields:
490 *
491 * type_regs
492 * mask
493 * value
494 *
495 * The least significant DECODE_TYPE_BITS of type_regs contains a value
496 * from enum decode_type, this indicates which of the decode_* structs
497 * the entry contains. The value DECODE_TYPE_END indicates the end of the
498 * table.
499 *
500 * When the table is parsed, each entry is checked in turn to see if it
501 * matches the instruction to be decoded using the test:
502 *
503 * (insn & mask) == value
504 *
505 * If no match is found before the end of the table is reached then decoding
506 * fails with INSN_REJECTED.
507 *
508 * When a match is found, decode_regs() is called to validate and modify each
509 * of the registers encoded in the instruction; the data it uses to do this
510 * is (type_regs >> DECODE_TYPE_BITS). A validation failure will cause decoding
511 * to fail with INSN_REJECTED.
512 *
513 * Once the instruction has passed the above tests, further processing
514 * depends on the type of the table entry's decode struct.
515 *
516 */
517int __kprobes
518kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
519 const union decode_item *table, bool thumb)
520{
521 const struct decode_header *h = (struct decode_header *)table;
522 const struct decode_header *next;
523 bool matched = false;
524
525 insn = prepare_emulated_insn(insn, asi, thumb);
526
527 for (;; h = next) {
528 enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK;
529 u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS;
530
531 if (type == DECODE_TYPE_END)
532 return INSN_REJECTED;
533
534 next = (struct decode_header *)
535 ((uintptr_t)h + decode_struct_sizes[type]);
536
537 if (!matched && (insn & h->mask.bits) != h->value.bits)
538 continue;
539
540 if (!decode_regs(&insn, regs))
541 return INSN_REJECTED;
542
543 switch (type) {
544
545 case DECODE_TYPE_TABLE: {
546 struct decode_table *d = (struct decode_table *)h;
547 next = (struct decode_header *)d->table.table;
548 break;
549 }
550
551 case DECODE_TYPE_CUSTOM: {
552 struct decode_custom *d = (struct decode_custom *)h;
553 return (*d->decoder.decoder)(insn, asi);
554 }
555
556 case DECODE_TYPE_SIMULATE: {
557 struct decode_simulate *d = (struct decode_simulate *)h;
558 asi->insn_handler = d->handler.handler;
559 return INSN_GOOD_NO_SLOT;
560 }
561
562 case DECODE_TYPE_EMULATE: {
563 struct decode_emulate *d = (struct decode_emulate *)h;
564 asi->insn_handler = d->handler.handler;
565 set_emulated_insn(insn, asi, thumb);
566 return INSN_GOOD;
567 }
568
569 case DECODE_TYPE_OR:
570 matched = true;
571 break;
572
573 case DECODE_TYPE_REJECT:
574 default:
575 return INSN_REJECTED;
576 }
577 }
578 }
diff --git a/arch/arm/kernel/kprobes-test-arm.c b/arch/arm/kernel/kprobes-test-arm.c
index 839312905067..87839de77e5f 100644
--- a/arch/arm/kernel/kprobes-test-arm.c
+++ b/arch/arm/kernel/kprobes-test-arm.c
@@ -10,6 +10,7 @@
10 10
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <asm/system_info.h>
13 14
14#include "kprobes-test.h" 15#include "kprobes-test.h"
15 16
diff --git a/arch/arm/kernel/kprobes-test.c b/arch/arm/kernel/kprobes-test.c
index 0cd63d080c7b..c2fd06b4c389 100644
--- a/arch/arm/kernel/kprobes-test.c
+++ b/arch/arm/kernel/kprobes-test.c
@@ -201,10 +201,14 @@
201#include <linux/module.h> 201#include <linux/module.h>
202#include <linux/slab.h> 202#include <linux/slab.h>
203#include <linux/kprobes.h> 203#include <linux/kprobes.h>
204 204#include <linux/errno.h>
205#include <linux/stddef.h>
206#include <linux/bug.h>
205#include <asm/opcodes.h> 207#include <asm/opcodes.h>
206 208
207#include "kprobes.h" 209#include "kprobes.h"
210#include "probes-arm.h"
211#include "probes-thumb.h"
208#include "kprobes-test.h" 212#include "kprobes-test.h"
209 213
210 214
@@ -1608,7 +1612,7 @@ static int __init run_all_tests(void)
1608 goto out; 1612 goto out;
1609 1613
1610 pr_info("ARM instruction simulation\n"); 1614 pr_info("ARM instruction simulation\n");
1611 ret = run_test_cases(kprobe_arm_test_cases, kprobe_decode_arm_table); 1615 ret = run_test_cases(kprobe_arm_test_cases, probes_decode_arm_table);
1612 if (ret) 1616 if (ret)
1613 goto out; 1617 goto out;
1614 1618
@@ -1631,13 +1635,13 @@ static int __init run_all_tests(void)
1631 1635
1632 pr_info("16-bit Thumb instruction simulation\n"); 1636 pr_info("16-bit Thumb instruction simulation\n");
1633 ret = run_test_cases(kprobe_thumb16_test_cases, 1637 ret = run_test_cases(kprobe_thumb16_test_cases,
1634 kprobe_decode_thumb16_table); 1638 probes_decode_thumb16_table);
1635 if (ret) 1639 if (ret)
1636 goto out; 1640 goto out;
1637 1641
1638 pr_info("32-bit Thumb instruction simulation\n"); 1642 pr_info("32-bit Thumb instruction simulation\n");
1639 ret = run_test_cases(kprobe_thumb32_test_cases, 1643 ret = run_test_cases(kprobe_thumb32_test_cases,
1640 kprobe_decode_thumb32_table); 1644 probes_decode_thumb32_table);
1641 if (ret) 1645 if (ret)
1642 goto out; 1646 goto out;
1643#endif 1647#endif
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c
index 6123daf397a7..6619188619ae 100644
--- a/arch/arm/kernel/kprobes-thumb.c
+++ b/arch/arm/kernel/kprobes-thumb.c
@@ -8,41 +8,25 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11#include <linux/types.h>
11#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/ptrace.h>
12#include <linux/kprobes.h> 14#include <linux/kprobes.h>
13#include <linux/module.h>
14 15
15#include "kprobes.h" 16#include "kprobes.h"
17#include "probes-thumb.h"
16 18
19/* These emulation encodings are functionally equivalent... */
20#define t32_emulate_rd8rn16rm0ra12_noflags \
21 t32_emulate_rdlo12rdhi8rn16rm0_noflags
17 22
18/* 23/* t32 thumb actions */
19 * True if current instruction is in an IT block.
20 */
21#define in_it_block(cpsr) ((cpsr & 0x06000c00) != 0x00000000)
22
23/*
24 * Return the condition code to check for the currently executing instruction.
25 * This is in ITSTATE<7:4> which is in CPSR<15:12> but is only valid if
26 * in_it_block returns true.
27 */
28#define current_cond(cpsr) ((cpsr >> 12) & 0xf)
29
30/*
31 * Return the PC value for a probe in thumb code.
32 * This is the address of the probed instruction plus 4.
33 * We subtract one because the address will have bit zero set to indicate
34 * a pointer to thumb code.
35 */
36static inline unsigned long __kprobes thumb_probe_pc(struct kprobe *p)
37{
38 return (unsigned long)p->addr - 1 + 4;
39}
40 24
41static void __kprobes 25static void __kprobes
42t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs) 26t32_simulate_table_branch(probes_opcode_t insn,
27 struct arch_probes_insn *asi, struct pt_regs *regs)
43{ 28{
44 kprobe_opcode_t insn = p->opcode; 29 unsigned long pc = regs->ARM_pc;
45 unsigned long pc = thumb_probe_pc(p);
46 int rn = (insn >> 16) & 0xf; 30 int rn = (insn >> 16) & 0xf;
47 int rm = insn & 0xf; 31 int rm = insn & 0xf;
48 32
@@ -59,19 +43,19 @@ t32_simulate_table_branch(struct kprobe *p, struct pt_regs *regs)
59} 43}
60 44
61static void __kprobes 45static void __kprobes
62t32_simulate_mrs(struct kprobe *p, struct pt_regs *regs) 46t32_simulate_mrs(probes_opcode_t insn,
47 struct arch_probes_insn *asi, struct pt_regs *regs)
63{ 48{
64 kprobe_opcode_t insn = p->opcode;
65 int rd = (insn >> 8) & 0xf; 49 int rd = (insn >> 8) & 0xf;
66 unsigned long mask = 0xf8ff03df; /* Mask out execution state */ 50 unsigned long mask = 0xf8ff03df; /* Mask out execution state */
67 regs->uregs[rd] = regs->ARM_cpsr & mask; 51 regs->uregs[rd] = regs->ARM_cpsr & mask;
68} 52}
69 53
70static void __kprobes 54static void __kprobes
71t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs) 55t32_simulate_cond_branch(probes_opcode_t insn,
56 struct arch_probes_insn *asi, struct pt_regs *regs)
72{ 57{
73 kprobe_opcode_t insn = p->opcode; 58 unsigned long pc = regs->ARM_pc;
74 unsigned long pc = thumb_probe_pc(p);
75 59
76 long offset = insn & 0x7ff; /* imm11 */ 60 long offset = insn & 0x7ff; /* imm11 */
77 offset += (insn & 0x003f0000) >> 5; /* imm6 */ 61 offset += (insn & 0x003f0000) >> 5; /* imm6 */
@@ -82,20 +66,21 @@ t32_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs)
82 regs->ARM_pc = pc + (offset * 2); 66 regs->ARM_pc = pc + (offset * 2);
83} 67}
84 68
85static enum kprobe_insn __kprobes 69static enum probes_insn __kprobes
86t32_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi) 70t32_decode_cond_branch(probes_opcode_t insn, struct arch_probes_insn *asi,
71 const struct decode_header *d)
87{ 72{
88 int cc = (insn >> 22) & 0xf; 73 int cc = (insn >> 22) & 0xf;
89 asi->insn_check_cc = kprobe_condition_checks[cc]; 74 asi->insn_check_cc = probes_condition_checks[cc];
90 asi->insn_handler = t32_simulate_cond_branch; 75 asi->insn_handler = t32_simulate_cond_branch;
91 return INSN_GOOD_NO_SLOT; 76 return INSN_GOOD_NO_SLOT;
92} 77}
93 78
94static void __kprobes 79static void __kprobes
95t32_simulate_branch(struct kprobe *p, struct pt_regs *regs) 80t32_simulate_branch(probes_opcode_t insn,
81 struct arch_probes_insn *asi, struct pt_regs *regs)
96{ 82{
97 kprobe_opcode_t insn = p->opcode; 83 unsigned long pc = regs->ARM_pc;
98 unsigned long pc = thumb_probe_pc(p);
99 84
100 long offset = insn & 0x7ff; /* imm11 */ 85 long offset = insn & 0x7ff; /* imm11 */
101 offset += (insn & 0x03ff0000) >> 5; /* imm10 */ 86 offset += (insn & 0x03ff0000) >> 5; /* imm10 */
@@ -108,7 +93,7 @@ t32_simulate_branch(struct kprobe *p, struct pt_regs *regs)
108 93
109 if (insn & (1 << 14)) { 94 if (insn & (1 << 14)) {
110 /* BL or BLX */ 95 /* BL or BLX */
111 regs->ARM_lr = (unsigned long)p->addr + 4; 96 regs->ARM_lr = regs->ARM_pc | 1;
112 if (!(insn & (1 << 12))) { 97 if (!(insn & (1 << 12))) {
113 /* BLX so switch to ARM mode */ 98 /* BLX so switch to ARM mode */
114 regs->ARM_cpsr &= ~PSR_T_BIT; 99 regs->ARM_cpsr &= ~PSR_T_BIT;
@@ -120,10 +105,10 @@ t32_simulate_branch(struct kprobe *p, struct pt_regs *regs)
120} 105}
121 106
122static void __kprobes 107static void __kprobes
123t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs) 108t32_simulate_ldr_literal(probes_opcode_t insn,
109 struct arch_probes_insn *asi, struct pt_regs *regs)
124{ 110{
125 kprobe_opcode_t insn = p->opcode; 111 unsigned long addr = regs->ARM_pc & ~3;
126 unsigned long addr = thumb_probe_pc(p) & ~3;
127 int rt = (insn >> 12) & 0xf; 112 int rt = (insn >> 12) & 0xf;
128 unsigned long rtv; 113 unsigned long rtv;
129 114
@@ -157,10 +142,11 @@ t32_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs)
157 regs->uregs[rt] = rtv; 142 regs->uregs[rt] = rtv;
158} 143}
159 144
160static enum kprobe_insn __kprobes 145static enum probes_insn __kprobes
161t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi) 146t32_decode_ldmstm(probes_opcode_t insn, struct arch_probes_insn *asi,
147 const struct decode_header *d)
162{ 148{
163 enum kprobe_insn ret = kprobe_decode_ldmstm(insn, asi); 149 enum probes_insn ret = kprobe_decode_ldmstm(insn, asi, d);
164 150
165 /* Fixup modified instruction to have halfwords in correct order...*/ 151 /* Fixup modified instruction to have halfwords in correct order...*/
166 insn = asi->insn[0]; 152 insn = asi->insn[0];
@@ -171,10 +157,10 @@ t32_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
171} 157}
172 158
173static void __kprobes 159static void __kprobes
174t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs) 160t32_emulate_ldrdstrd(probes_opcode_t insn,
161 struct arch_probes_insn *asi, struct pt_regs *regs)
175{ 162{
176 kprobe_opcode_t insn = p->opcode; 163 unsigned long pc = regs->ARM_pc & ~3;
177 unsigned long pc = thumb_probe_pc(p) & ~3;
178 int rt1 = (insn >> 12) & 0xf; 164 int rt1 = (insn >> 12) & 0xf;
179 int rt2 = (insn >> 8) & 0xf; 165 int rt2 = (insn >> 8) & 0xf;
180 int rn = (insn >> 16) & 0xf; 166 int rn = (insn >> 16) & 0xf;
@@ -187,7 +173,7 @@ t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
187 __asm__ __volatile__ ( 173 __asm__ __volatile__ (
188 "blx %[fn]" 174 "blx %[fn]"
189 : "=r" (rt1v), "=r" (rt2v), "=r" (rnv) 175 : "=r" (rt1v), "=r" (rt2v), "=r" (rnv)
190 : "0" (rt1v), "1" (rt2v), "2" (rnv), [fn] "r" (p->ainsn.insn_fn) 176 : "0" (rt1v), "1" (rt2v), "2" (rnv), [fn] "r" (asi->insn_fn)
191 : "lr", "memory", "cc" 177 : "lr", "memory", "cc"
192 ); 178 );
193 179
@@ -198,9 +184,9 @@ t32_emulate_ldrdstrd(struct kprobe *p, struct pt_regs *regs)
198} 184}
199 185
200static void __kprobes 186static void __kprobes
201t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs) 187t32_emulate_ldrstr(probes_opcode_t insn,
188 struct arch_probes_insn *asi, struct pt_regs *regs)
202{ 189{
203 kprobe_opcode_t insn = p->opcode;
204 int rt = (insn >> 12) & 0xf; 190 int rt = (insn >> 12) & 0xf;
205 int rn = (insn >> 16) & 0xf; 191 int rn = (insn >> 16) & 0xf;
206 int rm = insn & 0xf; 192 int rm = insn & 0xf;
@@ -212,7 +198,7 @@ t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs)
212 __asm__ __volatile__ ( 198 __asm__ __volatile__ (
213 "blx %[fn]" 199 "blx %[fn]"
214 : "=r" (rtv), "=r" (rnv) 200 : "=r" (rtv), "=r" (rnv)
215 : "0" (rtv), "1" (rnv), "r" (rmv), [fn] "r" (p->ainsn.insn_fn) 201 : "0" (rtv), "1" (rnv), "r" (rmv), [fn] "r" (asi->insn_fn)
216 : "lr", "memory", "cc" 202 : "lr", "memory", "cc"
217 ); 203 );
218 204
@@ -224,9 +210,9 @@ t32_emulate_ldrstr(struct kprobe *p, struct pt_regs *regs)
224} 210}
225 211
226static void __kprobes 212static void __kprobes
227t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs) 213t32_emulate_rd8rn16rm0_rwflags(probes_opcode_t insn,
214 struct arch_probes_insn *asi, struct pt_regs *regs)
228{ 215{
229 kprobe_opcode_t insn = p->opcode;
230 int rd = (insn >> 8) & 0xf; 216 int rd = (insn >> 8) & 0xf;
231 int rn = (insn >> 16) & 0xf; 217 int rn = (insn >> 16) & 0xf;
232 int rm = insn & 0xf; 218 int rm = insn & 0xf;
@@ -242,7 +228,7 @@ t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
242 "mrs %[cpsr], cpsr \n\t" 228 "mrs %[cpsr], cpsr \n\t"
243 : "=r" (rdv), [cpsr] "=r" (cpsr) 229 : "=r" (rdv), [cpsr] "=r" (cpsr)
244 : "0" (rdv), "r" (rnv), "r" (rmv), 230 : "0" (rdv), "r" (rnv), "r" (rmv),
245 "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) 231 "1" (cpsr), [fn] "r" (asi->insn_fn)
246 : "lr", "memory", "cc" 232 : "lr", "memory", "cc"
247 ); 233 );
248 234
@@ -251,10 +237,10 @@ t32_emulate_rd8rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
251} 237}
252 238
253static void __kprobes 239static void __kprobes
254t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs) 240t32_emulate_rd8pc16_noflags(probes_opcode_t insn,
241 struct arch_probes_insn *asi, struct pt_regs *regs)
255{ 242{
256 kprobe_opcode_t insn = p->opcode; 243 unsigned long pc = regs->ARM_pc;
257 unsigned long pc = thumb_probe_pc(p);
258 int rd = (insn >> 8) & 0xf; 244 int rd = (insn >> 8) & 0xf;
259 245
260 register unsigned long rdv asm("r1") = regs->uregs[rd]; 246 register unsigned long rdv asm("r1") = regs->uregs[rd];
@@ -263,7 +249,7 @@ t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs)
263 __asm__ __volatile__ ( 249 __asm__ __volatile__ (
264 "blx %[fn]" 250 "blx %[fn]"
265 : "=r" (rdv) 251 : "=r" (rdv)
266 : "0" (rdv), "r" (rnv), [fn] "r" (p->ainsn.insn_fn) 252 : "0" (rdv), "r" (rnv), [fn] "r" (asi->insn_fn)
267 : "lr", "memory", "cc" 253 : "lr", "memory", "cc"
268 ); 254 );
269 255
@@ -271,9 +257,9 @@ t32_emulate_rd8pc16_noflags(struct kprobe *p, struct pt_regs *regs)
271} 257}
272 258
273static void __kprobes 259static void __kprobes
274t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs) 260t32_emulate_rd8rn16_noflags(probes_opcode_t insn,
261 struct arch_probes_insn *asi, struct pt_regs *regs)
275{ 262{
276 kprobe_opcode_t insn = p->opcode;
277 int rd = (insn >> 8) & 0xf; 263 int rd = (insn >> 8) & 0xf;
278 int rn = (insn >> 16) & 0xf; 264 int rn = (insn >> 16) & 0xf;
279 265
@@ -283,7 +269,7 @@ t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs)
283 __asm__ __volatile__ ( 269 __asm__ __volatile__ (
284 "blx %[fn]" 270 "blx %[fn]"
285 : "=r" (rdv) 271 : "=r" (rdv)
286 : "0" (rdv), "r" (rnv), [fn] "r" (p->ainsn.insn_fn) 272 : "0" (rdv), "r" (rnv), [fn] "r" (asi->insn_fn)
287 : "lr", "memory", "cc" 273 : "lr", "memory", "cc"
288 ); 274 );
289 275
@@ -291,9 +277,10 @@ t32_emulate_rd8rn16_noflags(struct kprobe *p, struct pt_regs *regs)
291} 277}
292 278
293static void __kprobes 279static void __kprobes
294t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs) 280t32_emulate_rdlo12rdhi8rn16rm0_noflags(probes_opcode_t insn,
281 struct arch_probes_insn *asi,
282 struct pt_regs *regs)
295{ 283{
296 kprobe_opcode_t insn = p->opcode;
297 int rdlo = (insn >> 12) & 0xf; 284 int rdlo = (insn >> 12) & 0xf;
298 int rdhi = (insn >> 8) & 0xf; 285 int rdhi = (insn >> 8) & 0xf;
299 int rn = (insn >> 16) & 0xf; 286 int rn = (insn >> 16) & 0xf;
@@ -308,674 +295,43 @@ t32_emulate_rdlo12rdhi8rn16rm0_noflags(struct kprobe *p, struct pt_regs *regs)
308 "blx %[fn]" 295 "blx %[fn]"
309 : "=r" (rdlov), "=r" (rdhiv) 296 : "=r" (rdlov), "=r" (rdhiv)
310 : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv), 297 : "0" (rdlov), "1" (rdhiv), "r" (rnv), "r" (rmv),
311 [fn] "r" (p->ainsn.insn_fn) 298 [fn] "r" (asi->insn_fn)
312 : "lr", "memory", "cc" 299 : "lr", "memory", "cc"
313 ); 300 );
314 301
315 regs->uregs[rdlo] = rdlov; 302 regs->uregs[rdlo] = rdlov;
316 regs->uregs[rdhi] = rdhiv; 303 regs->uregs[rdhi] = rdhiv;
317} 304}
318 305/* t16 thumb actions */
319/* These emulation encodings are functionally equivalent... */
320#define t32_emulate_rd8rn16rm0ra12_noflags \
321 t32_emulate_rdlo12rdhi8rn16rm0_noflags
322
323static const union decode_item t32_table_1110_100x_x0xx[] = {
324 /* Load/store multiple instructions */
325
326 /* Rn is PC 1110 100x x0xx 1111 xxxx xxxx xxxx xxxx */
327 DECODE_REJECT (0xfe4f0000, 0xe80f0000),
328
329 /* SRS 1110 1000 00x0 xxxx xxxx xxxx xxxx xxxx */
330 /* RFE 1110 1000 00x1 xxxx xxxx xxxx xxxx xxxx */
331 DECODE_REJECT (0xffc00000, 0xe8000000),
332 /* SRS 1110 1001 10x0 xxxx xxxx xxxx xxxx xxxx */
333 /* RFE 1110 1001 10x1 xxxx xxxx xxxx xxxx xxxx */
334 DECODE_REJECT (0xffc00000, 0xe9800000),
335
336 /* STM Rn, {...pc} 1110 100x x0x0 xxxx 1xxx xxxx xxxx xxxx */
337 DECODE_REJECT (0xfe508000, 0xe8008000),
338 /* LDM Rn, {...lr,pc} 1110 100x x0x1 xxxx 11xx xxxx xxxx xxxx */
339 DECODE_REJECT (0xfe50c000, 0xe810c000),
340 /* LDM/STM Rn, {...sp} 1110 100x x0xx xxxx xx1x xxxx xxxx xxxx */
341 DECODE_REJECT (0xfe402000, 0xe8002000),
342
343 /* STMIA 1110 1000 10x0 xxxx xxxx xxxx xxxx xxxx */
344 /* LDMIA 1110 1000 10x1 xxxx xxxx xxxx xxxx xxxx */
345 /* STMDB 1110 1001 00x0 xxxx xxxx xxxx xxxx xxxx */
346 /* LDMDB 1110 1001 00x1 xxxx xxxx xxxx xxxx xxxx */
347 DECODE_CUSTOM (0xfe400000, 0xe8000000, t32_decode_ldmstm),
348
349 DECODE_END
350};
351
352static const union decode_item t32_table_1110_100x_x1xx[] = {
353 /* Load/store dual, load/store exclusive, table branch */
354
355 /* STRD (immediate) 1110 1000 x110 xxxx xxxx xxxx xxxx xxxx */
356 /* LDRD (immediate) 1110 1000 x111 xxxx xxxx xxxx xxxx xxxx */
357 DECODE_OR (0xff600000, 0xe8600000),
358 /* STRD (immediate) 1110 1001 x1x0 xxxx xxxx xxxx xxxx xxxx */
359 /* LDRD (immediate) 1110 1001 x1x1 xxxx xxxx xxxx xxxx xxxx */
360 DECODE_EMULATEX (0xff400000, 0xe9400000, t32_emulate_ldrdstrd,
361 REGS(NOPCWB, NOSPPC, NOSPPC, 0, 0)),
362
363 /* TBB 1110 1000 1101 xxxx xxxx xxxx 0000 xxxx */
364 /* TBH 1110 1000 1101 xxxx xxxx xxxx 0001 xxxx */
365 DECODE_SIMULATEX(0xfff000e0, 0xe8d00000, t32_simulate_table_branch,
366 REGS(NOSP, 0, 0, 0, NOSPPC)),
367
368 /* STREX 1110 1000 0100 xxxx xxxx xxxx xxxx xxxx */
369 /* LDREX 1110 1000 0101 xxxx xxxx xxxx xxxx xxxx */
370 /* STREXB 1110 1000 1100 xxxx xxxx xxxx 0100 xxxx */
371 /* STREXH 1110 1000 1100 xxxx xxxx xxxx 0101 xxxx */
372 /* STREXD 1110 1000 1100 xxxx xxxx xxxx 0111 xxxx */
373 /* LDREXB 1110 1000 1101 xxxx xxxx xxxx 0100 xxxx */
374 /* LDREXH 1110 1000 1101 xxxx xxxx xxxx 0101 xxxx */
375 /* LDREXD 1110 1000 1101 xxxx xxxx xxxx 0111 xxxx */
376 /* And unallocated instructions... */
377 DECODE_END
378};
379
380static const union decode_item t32_table_1110_101x[] = {
381 /* Data-processing (shifted register) */
382
383 /* TST 1110 1010 0001 xxxx xxxx 1111 xxxx xxxx */
384 /* TEQ 1110 1010 1001 xxxx xxxx 1111 xxxx xxxx */
385 DECODE_EMULATEX (0xff700f00, 0xea100f00, t32_emulate_rd8rn16rm0_rwflags,
386 REGS(NOSPPC, 0, 0, 0, NOSPPC)),
387
388 /* CMN 1110 1011 0001 xxxx xxxx 1111 xxxx xxxx */
389 DECODE_OR (0xfff00f00, 0xeb100f00),
390 /* CMP 1110 1011 1011 xxxx xxxx 1111 xxxx xxxx */
391 DECODE_EMULATEX (0xfff00f00, 0xebb00f00, t32_emulate_rd8rn16rm0_rwflags,
392 REGS(NOPC, 0, 0, 0, NOSPPC)),
393
394 /* MOV 1110 1010 010x 1111 xxxx xxxx xxxx xxxx */
395 /* MVN 1110 1010 011x 1111 xxxx xxxx xxxx xxxx */
396 DECODE_EMULATEX (0xffcf0000, 0xea4f0000, t32_emulate_rd8rn16rm0_rwflags,
397 REGS(0, 0, NOSPPC, 0, NOSPPC)),
398
399 /* ??? 1110 1010 101x xxxx xxxx xxxx xxxx xxxx */
400 /* ??? 1110 1010 111x xxxx xxxx xxxx xxxx xxxx */
401 DECODE_REJECT (0xffa00000, 0xeaa00000),
402 /* ??? 1110 1011 001x xxxx xxxx xxxx xxxx xxxx */
403 DECODE_REJECT (0xffe00000, 0xeb200000),
404 /* ??? 1110 1011 100x xxxx xxxx xxxx xxxx xxxx */
405 DECODE_REJECT (0xffe00000, 0xeb800000),
406 /* ??? 1110 1011 111x xxxx xxxx xxxx xxxx xxxx */
407 DECODE_REJECT (0xffe00000, 0xebe00000),
408
409 /* ADD/SUB SP, SP, Rm, LSL #0..3 */
410 /* 1110 1011 x0xx 1101 x000 1101 xx00 xxxx */
411 DECODE_EMULATEX (0xff4f7f30, 0xeb0d0d00, t32_emulate_rd8rn16rm0_rwflags,
412 REGS(SP, 0, SP, 0, NOSPPC)),
413
414 /* ADD/SUB SP, SP, Rm, shift */
415 /* 1110 1011 x0xx 1101 xxxx 1101 xxxx xxxx */
416 DECODE_REJECT (0xff4f0f00, 0xeb0d0d00),
417
418 /* ADD/SUB Rd, SP, Rm, shift */
419 /* 1110 1011 x0xx 1101 xxxx xxxx xxxx xxxx */
420 DECODE_EMULATEX (0xff4f0000, 0xeb0d0000, t32_emulate_rd8rn16rm0_rwflags,
421 REGS(SP, 0, NOPC, 0, NOSPPC)),
422
423 /* AND 1110 1010 000x xxxx xxxx xxxx xxxx xxxx */
424 /* BIC 1110 1010 001x xxxx xxxx xxxx xxxx xxxx */
425 /* ORR 1110 1010 010x xxxx xxxx xxxx xxxx xxxx */
426 /* ORN 1110 1010 011x xxxx xxxx xxxx xxxx xxxx */
427 /* EOR 1110 1010 100x xxxx xxxx xxxx xxxx xxxx */
428 /* PKH 1110 1010 110x xxxx xxxx xxxx xxxx xxxx */
429 /* ADD 1110 1011 000x xxxx xxxx xxxx xxxx xxxx */
430 /* ADC 1110 1011 010x xxxx xxxx xxxx xxxx xxxx */
431 /* SBC 1110 1011 011x xxxx xxxx xxxx xxxx xxxx */
432 /* SUB 1110 1011 101x xxxx xxxx xxxx xxxx xxxx */
433 /* RSB 1110 1011 110x xxxx xxxx xxxx xxxx xxxx */
434 DECODE_EMULATEX (0xfe000000, 0xea000000, t32_emulate_rd8rn16rm0_rwflags,
435 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
436
437 DECODE_END
438};
439
440static const union decode_item t32_table_1111_0x0x___0[] = {
441 /* Data-processing (modified immediate) */
442
443 /* TST 1111 0x00 0001 xxxx 0xxx 1111 xxxx xxxx */
444 /* TEQ 1111 0x00 1001 xxxx 0xxx 1111 xxxx xxxx */
445 DECODE_EMULATEX (0xfb708f00, 0xf0100f00, t32_emulate_rd8rn16rm0_rwflags,
446 REGS(NOSPPC, 0, 0, 0, 0)),
447
448 /* CMN 1111 0x01 0001 xxxx 0xxx 1111 xxxx xxxx */
449 DECODE_OR (0xfbf08f00, 0xf1100f00),
450 /* CMP 1111 0x01 1011 xxxx 0xxx 1111 xxxx xxxx */
451 DECODE_EMULATEX (0xfbf08f00, 0xf1b00f00, t32_emulate_rd8rn16rm0_rwflags,
452 REGS(NOPC, 0, 0, 0, 0)),
453
454 /* MOV 1111 0x00 010x 1111 0xxx xxxx xxxx xxxx */
455 /* MVN 1111 0x00 011x 1111 0xxx xxxx xxxx xxxx */
456 DECODE_EMULATEX (0xfbcf8000, 0xf04f0000, t32_emulate_rd8rn16rm0_rwflags,
457 REGS(0, 0, NOSPPC, 0, 0)),
458
459 /* ??? 1111 0x00 101x xxxx 0xxx xxxx xxxx xxxx */
460 DECODE_REJECT (0xfbe08000, 0xf0a00000),
461 /* ??? 1111 0x00 110x xxxx 0xxx xxxx xxxx xxxx */
462 /* ??? 1111 0x00 111x xxxx 0xxx xxxx xxxx xxxx */
463 DECODE_REJECT (0xfbc08000, 0xf0c00000),
464 /* ??? 1111 0x01 001x xxxx 0xxx xxxx xxxx xxxx */
465 DECODE_REJECT (0xfbe08000, 0xf1200000),
466 /* ??? 1111 0x01 100x xxxx 0xxx xxxx xxxx xxxx */
467 DECODE_REJECT (0xfbe08000, 0xf1800000),
468 /* ??? 1111 0x01 111x xxxx 0xxx xxxx xxxx xxxx */
469 DECODE_REJECT (0xfbe08000, 0xf1e00000),
470
471 /* ADD Rd, SP, #imm 1111 0x01 000x 1101 0xxx xxxx xxxx xxxx */
472 /* SUB Rd, SP, #imm 1111 0x01 101x 1101 0xxx xxxx xxxx xxxx */
473 DECODE_EMULATEX (0xfb4f8000, 0xf10d0000, t32_emulate_rd8rn16rm0_rwflags,
474 REGS(SP, 0, NOPC, 0, 0)),
475
476 /* AND 1111 0x00 000x xxxx 0xxx xxxx xxxx xxxx */
477 /* BIC 1111 0x00 001x xxxx 0xxx xxxx xxxx xxxx */
478 /* ORR 1111 0x00 010x xxxx 0xxx xxxx xxxx xxxx */
479 /* ORN 1111 0x00 011x xxxx 0xxx xxxx xxxx xxxx */
480 /* EOR 1111 0x00 100x xxxx 0xxx xxxx xxxx xxxx */
481 /* ADD 1111 0x01 000x xxxx 0xxx xxxx xxxx xxxx */
482 /* ADC 1111 0x01 010x xxxx 0xxx xxxx xxxx xxxx */
483 /* SBC 1111 0x01 011x xxxx 0xxx xxxx xxxx xxxx */
484 /* SUB 1111 0x01 101x xxxx 0xxx xxxx xxxx xxxx */
485 /* RSB 1111 0x01 110x xxxx 0xxx xxxx xxxx xxxx */
486 DECODE_EMULATEX (0xfa008000, 0xf0000000, t32_emulate_rd8rn16rm0_rwflags,
487 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
488
489 DECODE_END
490};
491
492static const union decode_item t32_table_1111_0x1x___0[] = {
493 /* Data-processing (plain binary immediate) */
494
495 /* ADDW Rd, PC, #imm 1111 0x10 0000 1111 0xxx xxxx xxxx xxxx */
496 DECODE_OR (0xfbff8000, 0xf20f0000),
497 /* SUBW Rd, PC, #imm 1111 0x10 1010 1111 0xxx xxxx xxxx xxxx */
498 DECODE_EMULATEX (0xfbff8000, 0xf2af0000, t32_emulate_rd8pc16_noflags,
499 REGS(PC, 0, NOSPPC, 0, 0)),
500
501 /* ADDW SP, SP, #imm 1111 0x10 0000 1101 0xxx 1101 xxxx xxxx */
502 DECODE_OR (0xfbff8f00, 0xf20d0d00),
503 /* SUBW SP, SP, #imm 1111 0x10 1010 1101 0xxx 1101 xxxx xxxx */
504 DECODE_EMULATEX (0xfbff8f00, 0xf2ad0d00, t32_emulate_rd8rn16_noflags,
505 REGS(SP, 0, SP, 0, 0)),
506
507 /* ADDW 1111 0x10 0000 xxxx 0xxx xxxx xxxx xxxx */
508 DECODE_OR (0xfbf08000, 0xf2000000),
509 /* SUBW 1111 0x10 1010 xxxx 0xxx xxxx xxxx xxxx */
510 DECODE_EMULATEX (0xfbf08000, 0xf2a00000, t32_emulate_rd8rn16_noflags,
511 REGS(NOPCX, 0, NOSPPC, 0, 0)),
512
513 /* MOVW 1111 0x10 0100 xxxx 0xxx xxxx xxxx xxxx */
514 /* MOVT 1111 0x10 1100 xxxx 0xxx xxxx xxxx xxxx */
515 DECODE_EMULATEX (0xfb708000, 0xf2400000, t32_emulate_rd8rn16_noflags,
516 REGS(0, 0, NOSPPC, 0, 0)),
517
518 /* SSAT16 1111 0x11 0010 xxxx 0000 xxxx 00xx xxxx */
519 /* SSAT 1111 0x11 00x0 xxxx 0xxx xxxx xxxx xxxx */
520 /* USAT16 1111 0x11 1010 xxxx 0000 xxxx 00xx xxxx */
521 /* USAT 1111 0x11 10x0 xxxx 0xxx xxxx xxxx xxxx */
522 DECODE_EMULATEX (0xfb508000, 0xf3000000, t32_emulate_rd8rn16rm0_rwflags,
523 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
524
525 /* SFBX 1111 0x11 0100 xxxx 0xxx xxxx xxxx xxxx */
526 /* UFBX 1111 0x11 1100 xxxx 0xxx xxxx xxxx xxxx */
527 DECODE_EMULATEX (0xfb708000, 0xf3400000, t32_emulate_rd8rn16_noflags,
528 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
529
530 /* BFC 1111 0x11 0110 1111 0xxx xxxx xxxx xxxx */
531 DECODE_EMULATEX (0xfbff8000, 0xf36f0000, t32_emulate_rd8rn16_noflags,
532 REGS(0, 0, NOSPPC, 0, 0)),
533
534 /* BFI 1111 0x11 0110 xxxx 0xxx xxxx xxxx xxxx */
535 DECODE_EMULATEX (0xfbf08000, 0xf3600000, t32_emulate_rd8rn16_noflags,
536 REGS(NOSPPCX, 0, NOSPPC, 0, 0)),
537
538 DECODE_END
539};
540
541static const union decode_item t32_table_1111_0xxx___1[] = {
542 /* Branches and miscellaneous control */
543
544 /* YIELD 1111 0011 1010 xxxx 10x0 x000 0000 0001 */
545 DECODE_OR (0xfff0d7ff, 0xf3a08001),
546 /* SEV 1111 0011 1010 xxxx 10x0 x000 0000 0100 */
547 DECODE_EMULATE (0xfff0d7ff, 0xf3a08004, kprobe_emulate_none),
548 /* NOP 1111 0011 1010 xxxx 10x0 x000 0000 0000 */
549 /* WFE 1111 0011 1010 xxxx 10x0 x000 0000 0010 */
550 /* WFI 1111 0011 1010 xxxx 10x0 x000 0000 0011 */
551 DECODE_SIMULATE (0xfff0d7fc, 0xf3a08000, kprobe_simulate_nop),
552
553 /* MRS Rd, CPSR 1111 0011 1110 xxxx 10x0 xxxx xxxx xxxx */
554 DECODE_SIMULATEX(0xfff0d000, 0xf3e08000, t32_simulate_mrs,
555 REGS(0, 0, NOSPPC, 0, 0)),
556
557 /*
558 * Unsupported instructions
559 * 1111 0x11 1xxx xxxx 10x0 xxxx xxxx xxxx
560 *
561 * MSR 1111 0011 100x xxxx 10x0 xxxx xxxx xxxx
562 * DBG hint 1111 0011 1010 xxxx 10x0 x000 1111 xxxx
563 * Unallocated hints 1111 0011 1010 xxxx 10x0 x000 xxxx xxxx
564 * CPS 1111 0011 1010 xxxx 10x0 xxxx xxxx xxxx
565 * CLREX/DSB/DMB/ISB 1111 0011 1011 xxxx 10x0 xxxx xxxx xxxx
566 * BXJ 1111 0011 1100 xxxx 10x0 xxxx xxxx xxxx
567 * SUBS PC,LR,#<imm8> 1111 0011 1101 xxxx 10x0 xxxx xxxx xxxx
568 * MRS Rd, SPSR 1111 0011 1111 xxxx 10x0 xxxx xxxx xxxx
569 * SMC 1111 0111 1111 xxxx 1000 xxxx xxxx xxxx
570 * UNDEFINED 1111 0111 1111 xxxx 1010 xxxx xxxx xxxx
571 * ??? 1111 0111 1xxx xxxx 1010 xxxx xxxx xxxx
572 */
573 DECODE_REJECT (0xfb80d000, 0xf3808000),
574
575 /* Bcc 1111 0xxx xxxx xxxx 10x0 xxxx xxxx xxxx */
576 DECODE_CUSTOM (0xf800d000, 0xf0008000, t32_decode_cond_branch),
577
578 /* BLX 1111 0xxx xxxx xxxx 11x0 xxxx xxxx xxx0 */
579 DECODE_OR (0xf800d001, 0xf000c000),
580 /* B 1111 0xxx xxxx xxxx 10x1 xxxx xxxx xxxx */
581 /* BL 1111 0xxx xxxx xxxx 11x1 xxxx xxxx xxxx */
582 DECODE_SIMULATE (0xf8009000, 0xf0009000, t32_simulate_branch),
583
584 DECODE_END
585};
586
587static const union decode_item t32_table_1111_100x_x0x1__1111[] = {
588 /* Memory hints */
589
590 /* PLD (literal) 1111 1000 x001 1111 1111 xxxx xxxx xxxx */
591 /* PLI (literal) 1111 1001 x001 1111 1111 xxxx xxxx xxxx */
592 DECODE_SIMULATE (0xfe7ff000, 0xf81ff000, kprobe_simulate_nop),
593
594 /* PLD{W} (immediate) 1111 1000 10x1 xxxx 1111 xxxx xxxx xxxx */
595 DECODE_OR (0xffd0f000, 0xf890f000),
596 /* PLD{W} (immediate) 1111 1000 00x1 xxxx 1111 1100 xxxx xxxx */
597 DECODE_OR (0xffd0ff00, 0xf810fc00),
598 /* PLI (immediate) 1111 1001 1001 xxxx 1111 xxxx xxxx xxxx */
599 DECODE_OR (0xfff0f000, 0xf990f000),
600 /* PLI (immediate) 1111 1001 0001 xxxx 1111 1100 xxxx xxxx */
601 DECODE_SIMULATEX(0xfff0ff00, 0xf910fc00, kprobe_simulate_nop,
602 REGS(NOPCX, 0, 0, 0, 0)),
603
604 /* PLD{W} (register) 1111 1000 00x1 xxxx 1111 0000 00xx xxxx */
605 DECODE_OR (0xffd0ffc0, 0xf810f000),
606 /* PLI (register) 1111 1001 0001 xxxx 1111 0000 00xx xxxx */
607 DECODE_SIMULATEX(0xfff0ffc0, 0xf910f000, kprobe_simulate_nop,
608 REGS(NOPCX, 0, 0, 0, NOSPPC)),
609
610 /* Other unallocated instructions... */
611 DECODE_END
612};
613
614static const union decode_item t32_table_1111_100x[] = {
615 /* Store/Load single data item */
616
617 /* ??? 1111 100x x11x xxxx xxxx xxxx xxxx xxxx */
618 DECODE_REJECT (0xfe600000, 0xf8600000),
619
620 /* ??? 1111 1001 0101 xxxx xxxx xxxx xxxx xxxx */
621 DECODE_REJECT (0xfff00000, 0xf9500000),
622
623 /* ??? 1111 100x 0xxx xxxx xxxx 10x0 xxxx xxxx */
624 DECODE_REJECT (0xfe800d00, 0xf8000800),
625
626 /* STRBT 1111 1000 0000 xxxx xxxx 1110 xxxx xxxx */
627 /* STRHT 1111 1000 0010 xxxx xxxx 1110 xxxx xxxx */
628 /* STRT 1111 1000 0100 xxxx xxxx 1110 xxxx xxxx */
629 /* LDRBT 1111 1000 0001 xxxx xxxx 1110 xxxx xxxx */
630 /* LDRSBT 1111 1001 0001 xxxx xxxx 1110 xxxx xxxx */
631 /* LDRHT 1111 1000 0011 xxxx xxxx 1110 xxxx xxxx */
632 /* LDRSHT 1111 1001 0011 xxxx xxxx 1110 xxxx xxxx */
633 /* LDRT 1111 1000 0101 xxxx xxxx 1110 xxxx xxxx */
634 DECODE_REJECT (0xfe800f00, 0xf8000e00),
635
636 /* STR{,B,H} Rn,[PC...] 1111 1000 xxx0 1111 xxxx xxxx xxxx xxxx */
637 DECODE_REJECT (0xff1f0000, 0xf80f0000),
638
639 /* STR{,B,H} PC,[Rn...] 1111 1000 xxx0 xxxx 1111 xxxx xxxx xxxx */
640 DECODE_REJECT (0xff10f000, 0xf800f000),
641
642 /* LDR (literal) 1111 1000 x101 1111 xxxx xxxx xxxx xxxx */
643 DECODE_SIMULATEX(0xff7f0000, 0xf85f0000, t32_simulate_ldr_literal,
644 REGS(PC, ANY, 0, 0, 0)),
645
646 /* STR (immediate) 1111 1000 0100 xxxx xxxx 1xxx xxxx xxxx */
647 /* LDR (immediate) 1111 1000 0101 xxxx xxxx 1xxx xxxx xxxx */
648 DECODE_OR (0xffe00800, 0xf8400800),
649 /* STR (immediate) 1111 1000 1100 xxxx xxxx xxxx xxxx xxxx */
650 /* LDR (immediate) 1111 1000 1101 xxxx xxxx xxxx xxxx xxxx */
651 DECODE_EMULATEX (0xffe00000, 0xf8c00000, t32_emulate_ldrstr,
652 REGS(NOPCX, ANY, 0, 0, 0)),
653
654 /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */
655 /* LDR (register) 1111 1000 0101 xxxx xxxx 0000 00xx xxxx */
656 DECODE_EMULATEX (0xffe00fc0, 0xf8400000, t32_emulate_ldrstr,
657 REGS(NOPCX, ANY, 0, 0, NOSPPC)),
658
659 /* LDRB (literal) 1111 1000 x001 1111 xxxx xxxx xxxx xxxx */
660 /* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */
661 /* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */
662 /* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */
663 DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal,
664 REGS(PC, NOSPPCX, 0, 0, 0)),
665
666 /* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */
667 /* STRH (immediate) 1111 1000 0010 xxxx xxxx 1xxx xxxx xxxx */
668 /* LDRB (immediate) 1111 1000 0001 xxxx xxxx 1xxx xxxx xxxx */
669 /* LDRSB (immediate) 1111 1001 0001 xxxx xxxx 1xxx xxxx xxxx */
670 /* LDRH (immediate) 1111 1000 0011 xxxx xxxx 1xxx xxxx xxxx */
671 /* LDRSH (immediate) 1111 1001 0011 xxxx xxxx 1xxx xxxx xxxx */
672 DECODE_OR (0xfec00800, 0xf8000800),
673 /* STRB (immediate) 1111 1000 1000 xxxx xxxx xxxx xxxx xxxx */
674 /* STRH (immediate) 1111 1000 1010 xxxx xxxx xxxx xxxx xxxx */
675 /* LDRB (immediate) 1111 1000 1001 xxxx xxxx xxxx xxxx xxxx */
676 /* LDRSB (immediate) 1111 1001 1001 xxxx xxxx xxxx xxxx xxxx */
677 /* LDRH (immediate) 1111 1000 1011 xxxx xxxx xxxx xxxx xxxx */
678 /* LDRSH (immediate) 1111 1001 1011 xxxx xxxx xxxx xxxx xxxx */
679 DECODE_EMULATEX (0xfec00000, 0xf8800000, t32_emulate_ldrstr,
680 REGS(NOPCX, NOSPPCX, 0, 0, 0)),
681
682 /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */
683 /* STRH (register) 1111 1000 0010 xxxx xxxx 0000 00xx xxxx */
684 /* LDRB (register) 1111 1000 0001 xxxx xxxx 0000 00xx xxxx */
685 /* LDRSB (register) 1111 1001 0001 xxxx xxxx 0000 00xx xxxx */
686 /* LDRH (register) 1111 1000 0011 xxxx xxxx 0000 00xx xxxx */
687 /* LDRSH (register) 1111 1001 0011 xxxx xxxx 0000 00xx xxxx */
688 DECODE_EMULATEX (0xfe800fc0, 0xf8000000, t32_emulate_ldrstr,
689 REGS(NOPCX, NOSPPCX, 0, 0, NOSPPC)),
690
691 /* Other unallocated instructions... */
692 DECODE_END
693};
694
695static const union decode_item t32_table_1111_1010___1111[] = {
696 /* Data-processing (register) */
697
698 /* ??? 1111 1010 011x xxxx 1111 xxxx 1xxx xxxx */
699 DECODE_REJECT (0xffe0f080, 0xfa60f080),
700
701 /* SXTH 1111 1010 0000 1111 1111 xxxx 1xxx xxxx */
702 /* UXTH 1111 1010 0001 1111 1111 xxxx 1xxx xxxx */
703 /* SXTB16 1111 1010 0010 1111 1111 xxxx 1xxx xxxx */
704 /* UXTB16 1111 1010 0011 1111 1111 xxxx 1xxx xxxx */
705 /* SXTB 1111 1010 0100 1111 1111 xxxx 1xxx xxxx */
706 /* UXTB 1111 1010 0101 1111 1111 xxxx 1xxx xxxx */
707 DECODE_EMULATEX (0xff8ff080, 0xfa0ff080, t32_emulate_rd8rn16rm0_rwflags,
708 REGS(0, 0, NOSPPC, 0, NOSPPC)),
709
710
711 /* ??? 1111 1010 1xxx xxxx 1111 xxxx 0x11 xxxx */
712 DECODE_REJECT (0xff80f0b0, 0xfa80f030),
713 /* ??? 1111 1010 1x11 xxxx 1111 xxxx 0xxx xxxx */
714 DECODE_REJECT (0xffb0f080, 0xfab0f000),
715
716 /* SADD16 1111 1010 1001 xxxx 1111 xxxx 0000 xxxx */
717 /* SASX 1111 1010 1010 xxxx 1111 xxxx 0000 xxxx */
718 /* SSAX 1111 1010 1110 xxxx 1111 xxxx 0000 xxxx */
719 /* SSUB16 1111 1010 1101 xxxx 1111 xxxx 0000 xxxx */
720 /* SADD8 1111 1010 1000 xxxx 1111 xxxx 0000 xxxx */
721 /* SSUB8 1111 1010 1100 xxxx 1111 xxxx 0000 xxxx */
722
723 /* QADD16 1111 1010 1001 xxxx 1111 xxxx 0001 xxxx */
724 /* QASX 1111 1010 1010 xxxx 1111 xxxx 0001 xxxx */
725 /* QSAX 1111 1010 1110 xxxx 1111 xxxx 0001 xxxx */
726 /* QSUB16 1111 1010 1101 xxxx 1111 xxxx 0001 xxxx */
727 /* QADD8 1111 1010 1000 xxxx 1111 xxxx 0001 xxxx */
728 /* QSUB8 1111 1010 1100 xxxx 1111 xxxx 0001 xxxx */
729
730 /* SHADD16 1111 1010 1001 xxxx 1111 xxxx 0010 xxxx */
731 /* SHASX 1111 1010 1010 xxxx 1111 xxxx 0010 xxxx */
732 /* SHSAX 1111 1010 1110 xxxx 1111 xxxx 0010 xxxx */
733 /* SHSUB16 1111 1010 1101 xxxx 1111 xxxx 0010 xxxx */
734 /* SHADD8 1111 1010 1000 xxxx 1111 xxxx 0010 xxxx */
735 /* SHSUB8 1111 1010 1100 xxxx 1111 xxxx 0010 xxxx */
736
737 /* UADD16 1111 1010 1001 xxxx 1111 xxxx 0100 xxxx */
738 /* UASX 1111 1010 1010 xxxx 1111 xxxx 0100 xxxx */
739 /* USAX 1111 1010 1110 xxxx 1111 xxxx 0100 xxxx */
740 /* USUB16 1111 1010 1101 xxxx 1111 xxxx 0100 xxxx */
741 /* UADD8 1111 1010 1000 xxxx 1111 xxxx 0100 xxxx */
742 /* USUB8 1111 1010 1100 xxxx 1111 xxxx 0100 xxxx */
743
744 /* UQADD16 1111 1010 1001 xxxx 1111 xxxx 0101 xxxx */
745 /* UQASX 1111 1010 1010 xxxx 1111 xxxx 0101 xxxx */
746 /* UQSAX 1111 1010 1110 xxxx 1111 xxxx 0101 xxxx */
747 /* UQSUB16 1111 1010 1101 xxxx 1111 xxxx 0101 xxxx */
748 /* UQADD8 1111 1010 1000 xxxx 1111 xxxx 0101 xxxx */
749 /* UQSUB8 1111 1010 1100 xxxx 1111 xxxx 0101 xxxx */
750
751 /* UHADD16 1111 1010 1001 xxxx 1111 xxxx 0110 xxxx */
752 /* UHASX 1111 1010 1010 xxxx 1111 xxxx 0110 xxxx */
753 /* UHSAX 1111 1010 1110 xxxx 1111 xxxx 0110 xxxx */
754 /* UHSUB16 1111 1010 1101 xxxx 1111 xxxx 0110 xxxx */
755 /* UHADD8 1111 1010 1000 xxxx 1111 xxxx 0110 xxxx */
756 /* UHSUB8 1111 1010 1100 xxxx 1111 xxxx 0110 xxxx */
757 DECODE_OR (0xff80f080, 0xfa80f000),
758
759 /* SXTAH 1111 1010 0000 xxxx 1111 xxxx 1xxx xxxx */
760 /* UXTAH 1111 1010 0001 xxxx 1111 xxxx 1xxx xxxx */
761 /* SXTAB16 1111 1010 0010 xxxx 1111 xxxx 1xxx xxxx */
762 /* UXTAB16 1111 1010 0011 xxxx 1111 xxxx 1xxx xxxx */
763 /* SXTAB 1111 1010 0100 xxxx 1111 xxxx 1xxx xxxx */
764 /* UXTAB 1111 1010 0101 xxxx 1111 xxxx 1xxx xxxx */
765 DECODE_OR (0xff80f080, 0xfa00f080),
766
767 /* QADD 1111 1010 1000 xxxx 1111 xxxx 1000 xxxx */
768 /* QDADD 1111 1010 1000 xxxx 1111 xxxx 1001 xxxx */
769 /* QSUB 1111 1010 1000 xxxx 1111 xxxx 1010 xxxx */
770 /* QDSUB 1111 1010 1000 xxxx 1111 xxxx 1011 xxxx */
771 DECODE_OR (0xfff0f0c0, 0xfa80f080),
772
773 /* SEL 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
774 DECODE_OR (0xfff0f0f0, 0xfaa0f080),
775
776 /* LSL 1111 1010 000x xxxx 1111 xxxx 0000 xxxx */
777 /* LSR 1111 1010 001x xxxx 1111 xxxx 0000 xxxx */
778 /* ASR 1111 1010 010x xxxx 1111 xxxx 0000 xxxx */
779 /* ROR 1111 1010 011x xxxx 1111 xxxx 0000 xxxx */
780 DECODE_EMULATEX (0xff80f0f0, 0xfa00f000, t32_emulate_rd8rn16rm0_rwflags,
781 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
782
783 /* CLZ 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
784 DECODE_OR (0xfff0f0f0, 0xfab0f080),
785
786 /* REV 1111 1010 1001 xxxx 1111 xxxx 1000 xxxx */
787 /* REV16 1111 1010 1001 xxxx 1111 xxxx 1001 xxxx */
788 /* RBIT 1111 1010 1001 xxxx 1111 xxxx 1010 xxxx */
789 /* REVSH 1111 1010 1001 xxxx 1111 xxxx 1011 xxxx */
790 DECODE_EMULATEX (0xfff0f0c0, 0xfa90f080, t32_emulate_rd8rn16_noflags,
791 REGS(NOSPPC, 0, NOSPPC, 0, SAMEAS16)),
792
793 /* Other unallocated instructions... */
794 DECODE_END
795};
796
797static const union decode_item t32_table_1111_1011_0[] = {
798 /* Multiply, multiply accumulate, and absolute difference */
799
800 /* ??? 1111 1011 0000 xxxx 1111 xxxx 0001 xxxx */
801 DECODE_REJECT (0xfff0f0f0, 0xfb00f010),
802 /* ??? 1111 1011 0111 xxxx 1111 xxxx 0001 xxxx */
803 DECODE_REJECT (0xfff0f0f0, 0xfb70f010),
804
805 /* SMULxy 1111 1011 0001 xxxx 1111 xxxx 00xx xxxx */
806 DECODE_OR (0xfff0f0c0, 0xfb10f000),
807 /* MUL 1111 1011 0000 xxxx 1111 xxxx 0000 xxxx */
808 /* SMUAD{X} 1111 1011 0010 xxxx 1111 xxxx 000x xxxx */
809 /* SMULWy 1111 1011 0011 xxxx 1111 xxxx 000x xxxx */
810 /* SMUSD{X} 1111 1011 0100 xxxx 1111 xxxx 000x xxxx */
811 /* SMMUL{R} 1111 1011 0101 xxxx 1111 xxxx 000x xxxx */
812 /* USAD8 1111 1011 0111 xxxx 1111 xxxx 0000 xxxx */
813 DECODE_EMULATEX (0xff80f0e0, 0xfb00f000, t32_emulate_rd8rn16rm0_rwflags,
814 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
815
816 /* ??? 1111 1011 0111 xxxx xxxx xxxx 0001 xxxx */
817 DECODE_REJECT (0xfff000f0, 0xfb700010),
818
819 /* SMLAxy 1111 1011 0001 xxxx xxxx xxxx 00xx xxxx */
820 DECODE_OR (0xfff000c0, 0xfb100000),
821 /* MLA 1111 1011 0000 xxxx xxxx xxxx 0000 xxxx */
822 /* MLS 1111 1011 0000 xxxx xxxx xxxx 0001 xxxx */
823 /* SMLAD{X} 1111 1011 0010 xxxx xxxx xxxx 000x xxxx */
824 /* SMLAWy 1111 1011 0011 xxxx xxxx xxxx 000x xxxx */
825 /* SMLSD{X} 1111 1011 0100 xxxx xxxx xxxx 000x xxxx */
826 /* SMMLA{R} 1111 1011 0101 xxxx xxxx xxxx 000x xxxx */
827 /* SMMLS{R} 1111 1011 0110 xxxx xxxx xxxx 000x xxxx */
828 /* USADA8 1111 1011 0111 xxxx xxxx xxxx 0000 xxxx */
829 DECODE_EMULATEX (0xff8000c0, 0xfb000000, t32_emulate_rd8rn16rm0ra12_noflags,
830 REGS(NOSPPC, NOSPPCX, NOSPPC, 0, NOSPPC)),
831
832 /* Other unallocated instructions... */
833 DECODE_END
834};
835
836static const union decode_item t32_table_1111_1011_1[] = {
837 /* Long multiply, long multiply accumulate, and divide */
838
839 /* UMAAL 1111 1011 1110 xxxx xxxx xxxx 0110 xxxx */
840 DECODE_OR (0xfff000f0, 0xfbe00060),
841 /* SMLALxy 1111 1011 1100 xxxx xxxx xxxx 10xx xxxx */
842 DECODE_OR (0xfff000c0, 0xfbc00080),
843 /* SMLALD{X} 1111 1011 1100 xxxx xxxx xxxx 110x xxxx */
844 /* SMLSLD{X} 1111 1011 1101 xxxx xxxx xxxx 110x xxxx */
845 DECODE_OR (0xffe000e0, 0xfbc000c0),
846 /* SMULL 1111 1011 1000 xxxx xxxx xxxx 0000 xxxx */
847 /* UMULL 1111 1011 1010 xxxx xxxx xxxx 0000 xxxx */
848 /* SMLAL 1111 1011 1100 xxxx xxxx xxxx 0000 xxxx */
849 /* UMLAL 1111 1011 1110 xxxx xxxx xxxx 0000 xxxx */
850 DECODE_EMULATEX (0xff9000f0, 0xfb800000, t32_emulate_rdlo12rdhi8rn16rm0_noflags,
851 REGS(NOSPPC, NOSPPC, NOSPPC, 0, NOSPPC)),
852
853 /* SDIV 1111 1011 1001 xxxx xxxx xxxx 1111 xxxx */
854 /* UDIV 1111 1011 1011 xxxx xxxx xxxx 1111 xxxx */
855 /* Other unallocated instructions... */
856 DECODE_END
857};
858
859const union decode_item kprobe_decode_thumb32_table[] = {
860
861 /*
862 * Load/store multiple instructions
863 * 1110 100x x0xx xxxx xxxx xxxx xxxx xxxx
864 */
865 DECODE_TABLE (0xfe400000, 0xe8000000, t32_table_1110_100x_x0xx),
866
867 /*
868 * Load/store dual, load/store exclusive, table branch
869 * 1110 100x x1xx xxxx xxxx xxxx xxxx xxxx
870 */
871 DECODE_TABLE (0xfe400000, 0xe8400000, t32_table_1110_100x_x1xx),
872
873 /*
874 * Data-processing (shifted register)
875 * 1110 101x xxxx xxxx xxxx xxxx xxxx xxxx
876 */
877 DECODE_TABLE (0xfe000000, 0xea000000, t32_table_1110_101x),
878
879 /*
880 * Coprocessor instructions
881 * 1110 11xx xxxx xxxx xxxx xxxx xxxx xxxx
882 */
883 DECODE_REJECT (0xfc000000, 0xec000000),
884
885 /*
886 * Data-processing (modified immediate)
887 * 1111 0x0x xxxx xxxx 0xxx xxxx xxxx xxxx
888 */
889 DECODE_TABLE (0xfa008000, 0xf0000000, t32_table_1111_0x0x___0),
890
891 /*
892 * Data-processing (plain binary immediate)
893 * 1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx
894 */
895 DECODE_TABLE (0xfa008000, 0xf2000000, t32_table_1111_0x1x___0),
896
897 /*
898 * Branches and miscellaneous control
899 * 1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx
900 */
901 DECODE_TABLE (0xf8008000, 0xf0008000, t32_table_1111_0xxx___1),
902
903 /*
904 * Advanced SIMD element or structure load/store instructions
905 * 1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx
906 */
907 DECODE_REJECT (0xff100000, 0xf9000000),
908
909 /*
910 * Memory hints
911 * 1111 100x x0x1 xxxx 1111 xxxx xxxx xxxx
912 */
913 DECODE_TABLE (0xfe50f000, 0xf810f000, t32_table_1111_100x_x0x1__1111),
914
915 /*
916 * Store single data item
917 * 1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx
918 * Load single data items
919 * 1111 100x xxx1 xxxx xxxx xxxx xxxx xxxx
920 */
921 DECODE_TABLE (0xfe000000, 0xf8000000, t32_table_1111_100x),
922
923 /*
924 * Data-processing (register)
925 * 1111 1010 xxxx xxxx 1111 xxxx xxxx xxxx
926 */
927 DECODE_TABLE (0xff00f000, 0xfa00f000, t32_table_1111_1010___1111),
928
929 /*
930 * Multiply, multiply accumulate, and absolute difference
931 * 1111 1011 0xxx xxxx xxxx xxxx xxxx xxxx
932 */
933 DECODE_TABLE (0xff800000, 0xfb000000, t32_table_1111_1011_0),
934
935 /*
936 * Long multiply, long multiply accumulate, and divide
937 * 1111 1011 1xxx xxxx xxxx xxxx xxxx xxxx
938 */
939 DECODE_TABLE (0xff800000, 0xfb800000, t32_table_1111_1011_1),
940
941 /*
942 * Coprocessor instructions
943 * 1111 11xx xxxx xxxx xxxx xxxx xxxx xxxx
944 */
945 DECODE_END
946};
947#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
948EXPORT_SYMBOL_GPL(kprobe_decode_thumb32_table);
949#endif
950 306
951static void __kprobes 307static void __kprobes
952t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs) 308t16_simulate_bxblx(probes_opcode_t insn,
309 struct arch_probes_insn *asi, struct pt_regs *regs)
953{ 310{
954 kprobe_opcode_t insn = p->opcode; 311 unsigned long pc = regs->ARM_pc + 2;
955 unsigned long pc = thumb_probe_pc(p);
956 int rm = (insn >> 3) & 0xf; 312 int rm = (insn >> 3) & 0xf;
957 unsigned long rmv = (rm == 15) ? pc : regs->uregs[rm]; 313 unsigned long rmv = (rm == 15) ? pc : regs->uregs[rm];
958 314
959 if (insn & (1 << 7)) /* BLX ? */ 315 if (insn & (1 << 7)) /* BLX ? */
960 regs->ARM_lr = (unsigned long)p->addr + 2; 316 regs->ARM_lr = regs->ARM_pc | 1;
961 317
962 bx_write_pc(rmv, regs); 318 bx_write_pc(rmv, regs);
963} 319}
964 320
965static void __kprobes 321static void __kprobes
966t16_simulate_ldr_literal(struct kprobe *p, struct pt_regs *regs) 322t16_simulate_ldr_literal(probes_opcode_t insn,
323 struct arch_probes_insn *asi, struct pt_regs *regs)
967{ 324{
968 kprobe_opcode_t insn = p->opcode; 325 unsigned long *base = (unsigned long *)((regs->ARM_pc + 2) & ~3);
969 unsigned long* base = (unsigned long *)(thumb_probe_pc(p) & ~3);
970 long index = insn & 0xff; 326 long index = insn & 0xff;
971 int rt = (insn >> 8) & 0x7; 327 int rt = (insn >> 8) & 0x7;
972 regs->uregs[rt] = base[index]; 328 regs->uregs[rt] = base[index];
973} 329}
974 330
975static void __kprobes 331static void __kprobes
976t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs) 332t16_simulate_ldrstr_sp_relative(probes_opcode_t insn,
333 struct arch_probes_insn *asi, struct pt_regs *regs)
977{ 334{
978 kprobe_opcode_t insn = p->opcode;
979 unsigned long* base = (unsigned long *)regs->ARM_sp; 335 unsigned long* base = (unsigned long *)regs->ARM_sp;
980 long index = insn & 0xff; 336 long index = insn & 0xff;
981 int rt = (insn >> 8) & 0x7; 337 int rt = (insn >> 8) & 0x7;
@@ -986,20 +342,20 @@ t16_simulate_ldrstr_sp_relative(struct kprobe *p, struct pt_regs *regs)
986} 342}
987 343
988static void __kprobes 344static void __kprobes
989t16_simulate_reladr(struct kprobe *p, struct pt_regs *regs) 345t16_simulate_reladr(probes_opcode_t insn,
346 struct arch_probes_insn *asi, struct pt_regs *regs)
990{ 347{
991 kprobe_opcode_t insn = p->opcode;
992 unsigned long base = (insn & 0x800) ? regs->ARM_sp 348 unsigned long base = (insn & 0x800) ? regs->ARM_sp
993 : (thumb_probe_pc(p) & ~3); 349 : ((regs->ARM_pc + 2) & ~3);
994 long offset = insn & 0xff; 350 long offset = insn & 0xff;
995 int rt = (insn >> 8) & 0x7; 351 int rt = (insn >> 8) & 0x7;
996 regs->uregs[rt] = base + offset * 4; 352 regs->uregs[rt] = base + offset * 4;
997} 353}
998 354
999static void __kprobes 355static void __kprobes
1000t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs) 356t16_simulate_add_sp_imm(probes_opcode_t insn,
357 struct arch_probes_insn *asi, struct pt_regs *regs)
1001{ 358{
1002 kprobe_opcode_t insn = p->opcode;
1003 long imm = insn & 0x7f; 359 long imm = insn & 0x7f;
1004 if (insn & 0x80) /* SUB */ 360 if (insn & 0x80) /* SUB */
1005 regs->ARM_sp -= imm * 4; 361 regs->ARM_sp -= imm * 4;
@@ -1008,21 +364,22 @@ t16_simulate_add_sp_imm(struct kprobe *p, struct pt_regs *regs)
1008} 364}
1009 365
1010static void __kprobes 366static void __kprobes
1011t16_simulate_cbz(struct kprobe *p, struct pt_regs *regs) 367t16_simulate_cbz(probes_opcode_t insn,
368 struct arch_probes_insn *asi, struct pt_regs *regs)
1012{ 369{
1013 kprobe_opcode_t insn = p->opcode;
1014 int rn = insn & 0x7; 370 int rn = insn & 0x7;
1015 kprobe_opcode_t nonzero = regs->uregs[rn] ? insn : ~insn; 371 probes_opcode_t nonzero = regs->uregs[rn] ? insn : ~insn;
1016 if (nonzero & 0x800) { 372 if (nonzero & 0x800) {
1017 long i = insn & 0x200; 373 long i = insn & 0x200;
1018 long imm5 = insn & 0xf8; 374 long imm5 = insn & 0xf8;
1019 unsigned long pc = thumb_probe_pc(p); 375 unsigned long pc = regs->ARM_pc + 2;
1020 regs->ARM_pc = pc + (i >> 3) + (imm5 >> 2); 376 regs->ARM_pc = pc + (i >> 3) + (imm5 >> 2);
1021 } 377 }
1022} 378}
1023 379
1024static void __kprobes 380static void __kprobes
1025t16_simulate_it(struct kprobe *p, struct pt_regs *regs) 381t16_simulate_it(probes_opcode_t insn,
382 struct arch_probes_insn *asi, struct pt_regs *regs)
1026{ 383{
1027 /* 384 /*
1028 * The 8 IT state bits are split into two parts in CPSR: 385 * The 8 IT state bits are split into two parts in CPSR:
@@ -1030,7 +387,6 @@ t16_simulate_it(struct kprobe *p, struct pt_regs *regs)
1030 * ITSTATE<7:2> are in CPSR<15:10> 387 * ITSTATE<7:2> are in CPSR<15:10>
1031 * The new IT state is in the lower byte of insn. 388 * The new IT state is in the lower byte of insn.
1032 */ 389 */
1033 kprobe_opcode_t insn = p->opcode;
1034 unsigned long cpsr = regs->ARM_cpsr; 390 unsigned long cpsr = regs->ARM_cpsr;
1035 cpsr &= ~PSR_IT_MASK; 391 cpsr &= ~PSR_IT_MASK;
1036 cpsr |= (insn & 0xfc) << 8; 392 cpsr |= (insn & 0xfc) << 8;
@@ -1039,50 +395,54 @@ t16_simulate_it(struct kprobe *p, struct pt_regs *regs)
1039} 395}
1040 396
1041static void __kprobes 397static void __kprobes
1042t16_singlestep_it(struct kprobe *p, struct pt_regs *regs) 398t16_singlestep_it(probes_opcode_t insn,
399 struct arch_probes_insn *asi, struct pt_regs *regs)
1043{ 400{
1044 regs->ARM_pc += 2; 401 regs->ARM_pc += 2;
1045 t16_simulate_it(p, regs); 402 t16_simulate_it(insn, asi, regs);
1046} 403}
1047 404
1048static enum kprobe_insn __kprobes 405static enum probes_insn __kprobes
1049t16_decode_it(kprobe_opcode_t insn, struct arch_specific_insn *asi) 406t16_decode_it(probes_opcode_t insn, struct arch_probes_insn *asi,
407 const struct decode_header *d)
1050{ 408{
1051 asi->insn_singlestep = t16_singlestep_it; 409 asi->insn_singlestep = t16_singlestep_it;
1052 return INSN_GOOD_NO_SLOT; 410 return INSN_GOOD_NO_SLOT;
1053} 411}
1054 412
1055static void __kprobes 413static void __kprobes
1056t16_simulate_cond_branch(struct kprobe *p, struct pt_regs *regs) 414t16_simulate_cond_branch(probes_opcode_t insn,
415 struct arch_probes_insn *asi, struct pt_regs *regs)
1057{ 416{
1058 kprobe_opcode_t insn = p->opcode; 417 unsigned long pc = regs->ARM_pc + 2;
1059 unsigned long pc = thumb_probe_pc(p);
1060 long offset = insn & 0x7f; 418 long offset = insn & 0x7f;
1061 offset -= insn & 0x80; /* Apply sign bit */ 419 offset -= insn & 0x80; /* Apply sign bit */
1062 regs->ARM_pc = pc + (offset * 2); 420 regs->ARM_pc = pc + (offset * 2);
1063} 421}
1064 422
1065static enum kprobe_insn __kprobes 423static enum probes_insn __kprobes
1066t16_decode_cond_branch(kprobe_opcode_t insn, struct arch_specific_insn *asi) 424t16_decode_cond_branch(probes_opcode_t insn, struct arch_probes_insn *asi,
425 const struct decode_header *d)
1067{ 426{
1068 int cc = (insn >> 8) & 0xf; 427 int cc = (insn >> 8) & 0xf;
1069 asi->insn_check_cc = kprobe_condition_checks[cc]; 428 asi->insn_check_cc = probes_condition_checks[cc];
1070 asi->insn_handler = t16_simulate_cond_branch; 429 asi->insn_handler = t16_simulate_cond_branch;
1071 return INSN_GOOD_NO_SLOT; 430 return INSN_GOOD_NO_SLOT;
1072} 431}
1073 432
1074static void __kprobes 433static void __kprobes
1075t16_simulate_branch(struct kprobe *p, struct pt_regs *regs) 434t16_simulate_branch(probes_opcode_t insn,
435 struct arch_probes_insn *asi, struct pt_regs *regs)
1076{ 436{
1077 kprobe_opcode_t insn = p->opcode; 437 unsigned long pc = regs->ARM_pc + 2;
1078 unsigned long pc = thumb_probe_pc(p);
1079 long offset = insn & 0x3ff; 438 long offset = insn & 0x3ff;
1080 offset -= insn & 0x400; /* Apply sign bit */ 439 offset -= insn & 0x400; /* Apply sign bit */
1081 regs->ARM_pc = pc + (offset * 2); 440 regs->ARM_pc = pc + (offset * 2);
1082} 441}
1083 442
1084static unsigned long __kprobes 443static unsigned long __kprobes
1085t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs) 444t16_emulate_loregs(probes_opcode_t insn,
445 struct arch_probes_insn *asi, struct pt_regs *regs)
1086{ 446{
1087 unsigned long oldcpsr = regs->ARM_cpsr; 447 unsigned long oldcpsr = regs->ARM_cpsr;
1088 unsigned long newcpsr; 448 unsigned long newcpsr;
@@ -1095,7 +455,7 @@ t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs)
1095 "mrs %[newcpsr], cpsr \n\t" 455 "mrs %[newcpsr], cpsr \n\t"
1096 : [newcpsr] "=r" (newcpsr) 456 : [newcpsr] "=r" (newcpsr)
1097 : [oldcpsr] "r" (oldcpsr), [regs] "r" (regs), 457 : [oldcpsr] "r" (oldcpsr), [regs] "r" (regs),
1098 [fn] "r" (p->ainsn.insn_fn) 458 [fn] "r" (asi->insn_fn)
1099 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 459 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1100 "lr", "memory", "cc" 460 "lr", "memory", "cc"
1101 ); 461 );
@@ -1104,24 +464,26 @@ t16_emulate_loregs(struct kprobe *p, struct pt_regs *regs)
1104} 464}
1105 465
1106static void __kprobes 466static void __kprobes
1107t16_emulate_loregs_rwflags(struct kprobe *p, struct pt_regs *regs) 467t16_emulate_loregs_rwflags(probes_opcode_t insn,
468 struct arch_probes_insn *asi, struct pt_regs *regs)
1108{ 469{
1109 regs->ARM_cpsr = t16_emulate_loregs(p, regs); 470 regs->ARM_cpsr = t16_emulate_loregs(insn, asi, regs);
1110} 471}
1111 472
1112static void __kprobes 473static void __kprobes
1113t16_emulate_loregs_noitrwflags(struct kprobe *p, struct pt_regs *regs) 474t16_emulate_loregs_noitrwflags(probes_opcode_t insn,
475 struct arch_probes_insn *asi, struct pt_regs *regs)
1114{ 476{
1115 unsigned long cpsr = t16_emulate_loregs(p, regs); 477 unsigned long cpsr = t16_emulate_loregs(insn, asi, regs);
1116 if (!in_it_block(cpsr)) 478 if (!in_it_block(cpsr))
1117 regs->ARM_cpsr = cpsr; 479 regs->ARM_cpsr = cpsr;
1118} 480}
1119 481
1120static void __kprobes 482static void __kprobes
1121t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs) 483t16_emulate_hiregs(probes_opcode_t insn,
484 struct arch_probes_insn *asi, struct pt_regs *regs)
1122{ 485{
1123 kprobe_opcode_t insn = p->opcode; 486 unsigned long pc = regs->ARM_pc + 2;
1124 unsigned long pc = thumb_probe_pc(p);
1125 int rdn = (insn & 0x7) | ((insn & 0x80) >> 4); 487 int rdn = (insn & 0x7) | ((insn & 0x80) >> 4);
1126 int rm = (insn >> 3) & 0xf; 488 int rm = (insn >> 3) & 0xf;
1127 489
@@ -1137,7 +499,7 @@ t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs)
1137 "blx %[fn] \n\t" 499 "blx %[fn] \n\t"
1138 "mrs %[cpsr], cpsr \n\t" 500 "mrs %[cpsr], cpsr \n\t"
1139 : "=r" (rdnv), [cpsr] "=r" (cpsr) 501 : "=r" (rdnv), [cpsr] "=r" (cpsr)
1140 : "0" (rdnv), "r" (rmv), "1" (cpsr), [fn] "r" (p->ainsn.insn_fn) 502 : "0" (rdnv), "r" (rmv), "1" (cpsr), [fn] "r" (asi->insn_fn)
1141 : "lr", "memory", "cc" 503 : "lr", "memory", "cc"
1142 ); 504 );
1143 505
@@ -1148,8 +510,9 @@ t16_emulate_hiregs(struct kprobe *p, struct pt_regs *regs)
1148 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK); 510 regs->ARM_cpsr = (regs->ARM_cpsr & ~APSR_MASK) | (cpsr & APSR_MASK);
1149} 511}
1150 512
1151static enum kprobe_insn __kprobes 513static enum probes_insn __kprobes
1152t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi) 514t16_decode_hiregs(probes_opcode_t insn, struct arch_probes_insn *asi,
515 const struct decode_header *d)
1153{ 516{
1154 insn &= ~0x00ff; 517 insn &= ~0x00ff;
1155 insn |= 0x001; /* Set Rdn = R1 and Rm = R0 */ 518 insn |= 0x001; /* Set Rdn = R1 and Rm = R0 */
@@ -1159,7 +522,8 @@ t16_decode_hiregs(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1159} 522}
1160 523
1161static void __kprobes 524static void __kprobes
1162t16_emulate_push(struct kprobe *p, struct pt_regs *regs) 525t16_emulate_push(probes_opcode_t insn,
526 struct arch_probes_insn *asi, struct pt_regs *regs)
1163{ 527{
1164 __asm__ __volatile__ ( 528 __asm__ __volatile__ (
1165 "ldr r9, [%[regs], #13*4] \n\t" 529 "ldr r9, [%[regs], #13*4] \n\t"
@@ -1168,14 +532,15 @@ t16_emulate_push(struct kprobe *p, struct pt_regs *regs)
1168 "blx %[fn] \n\t" 532 "blx %[fn] \n\t"
1169 "str r9, [%[regs], #13*4] \n\t" 533 "str r9, [%[regs], #13*4] \n\t"
1170 : 534 :
1171 : [regs] "r" (regs), [fn] "r" (p->ainsn.insn_fn) 535 : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
1172 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", 536 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
1173 "lr", "memory", "cc" 537 "lr", "memory", "cc"
1174 ); 538 );
1175} 539}
1176 540
1177static enum kprobe_insn __kprobes 541static enum probes_insn __kprobes
1178t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi) 542t16_decode_push(probes_opcode_t insn, struct arch_probes_insn *asi,
543 const struct decode_header *d)
1179{ 544{
1180 /* 545 /*
1181 * To simulate a PUSH we use a Thumb-2 "STMDB R9!, {registers}" 546 * To simulate a PUSH we use a Thumb-2 "STMDB R9!, {registers}"
@@ -1189,7 +554,8 @@ t16_decode_push(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1189} 554}
1190 555
1191static void __kprobes 556static void __kprobes
1192t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs) 557t16_emulate_pop_nopc(probes_opcode_t insn,
558 struct arch_probes_insn *asi, struct pt_regs *regs)
1193{ 559{
1194 __asm__ __volatile__ ( 560 __asm__ __volatile__ (
1195 "ldr r9, [%[regs], #13*4] \n\t" 561 "ldr r9, [%[regs], #13*4] \n\t"
@@ -1198,14 +564,15 @@ t16_emulate_pop_nopc(struct kprobe *p, struct pt_regs *regs)
1198 "stmia %[regs], {r0-r7} \n\t" 564 "stmia %[regs], {r0-r7} \n\t"
1199 "str r9, [%[regs], #13*4] \n\t" 565 "str r9, [%[regs], #13*4] \n\t"
1200 : 566 :
1201 : [regs] "r" (regs), [fn] "r" (p->ainsn.insn_fn) 567 : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
1202 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9", 568 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
1203 "lr", "memory", "cc" 569 "lr", "memory", "cc"
1204 ); 570 );
1205} 571}
1206 572
1207static void __kprobes 573static void __kprobes
1208t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs) 574t16_emulate_pop_pc(probes_opcode_t insn,
575 struct arch_probes_insn *asi, struct pt_regs *regs)
1209{ 576{
1210 register unsigned long pc asm("r8"); 577 register unsigned long pc asm("r8");
1211 578
@@ -1216,7 +583,7 @@ t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs)
1216 "stmia %[regs], {r0-r7} \n\t" 583 "stmia %[regs], {r0-r7} \n\t"
1217 "str r9, [%[regs], #13*4] \n\t" 584 "str r9, [%[regs], #13*4] \n\t"
1218 : "=r" (pc) 585 : "=r" (pc)
1219 : [regs] "r" (regs), [fn] "r" (p->ainsn.insn_fn) 586 : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
1220 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9", 587 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
1221 "lr", "memory", "cc" 588 "lr", "memory", "cc"
1222 ); 589 );
@@ -1224,8 +591,9 @@ t16_emulate_pop_pc(struct kprobe *p, struct pt_regs *regs)
1224 bx_write_pc(pc, regs); 591 bx_write_pc(pc, regs);
1225} 592}
1226 593
1227static enum kprobe_insn __kprobes 594static enum probes_insn __kprobes
1228t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi) 595t16_decode_pop(probes_opcode_t insn, struct arch_probes_insn *asi,
596 const struct decode_header *d)
1229{ 597{
1230 /* 598 /*
1231 * To simulate a POP we use a Thumb-2 "LDMDB R9!, {registers}" 599 * To simulate a POP we use a Thumb-2 "LDMDB R9!, {registers}"
@@ -1239,231 +607,56 @@ t16_decode_pop(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1239 return INSN_GOOD; 607 return INSN_GOOD;
1240} 608}
1241 609
1242static const union decode_item t16_table_1011[] = { 610const union decode_action kprobes_t16_actions[NUM_PROBES_T16_ACTIONS] = {
1243 /* Miscellaneous 16-bit instructions */ 611 [PROBES_T16_ADD_SP] = {.handler = t16_simulate_add_sp_imm},
1244 612 [PROBES_T16_CBZ] = {.handler = t16_simulate_cbz},
1245 /* ADD (SP plus immediate) 1011 0000 0xxx xxxx */ 613 [PROBES_T16_SIGN_EXTEND] = {.handler = t16_emulate_loregs_rwflags},
1246 /* SUB (SP minus immediate) 1011 0000 1xxx xxxx */ 614 [PROBES_T16_PUSH] = {.decoder = t16_decode_push},
1247 DECODE_SIMULATE (0xff00, 0xb000, t16_simulate_add_sp_imm), 615 [PROBES_T16_POP] = {.decoder = t16_decode_pop},
1248 616 [PROBES_T16_SEV] = {.handler = probes_emulate_none},
1249 /* CBZ 1011 00x1 xxxx xxxx */ 617 [PROBES_T16_WFE] = {.handler = probes_simulate_nop},
1250 /* CBNZ 1011 10x1 xxxx xxxx */ 618 [PROBES_T16_IT] = {.decoder = t16_decode_it},
1251 DECODE_SIMULATE (0xf500, 0xb100, t16_simulate_cbz), 619 [PROBES_T16_CMP] = {.handler = t16_emulate_loregs_rwflags},
1252 620 [PROBES_T16_ADDSUB] = {.handler = t16_emulate_loregs_noitrwflags},
1253 /* SXTH 1011 0010 00xx xxxx */ 621 [PROBES_T16_LOGICAL] = {.handler = t16_emulate_loregs_noitrwflags},
1254 /* SXTB 1011 0010 01xx xxxx */ 622 [PROBES_T16_LDR_LIT] = {.handler = t16_simulate_ldr_literal},
1255 /* UXTH 1011 0010 10xx xxxx */ 623 [PROBES_T16_BLX] = {.handler = t16_simulate_bxblx},
1256 /* UXTB 1011 0010 11xx xxxx */ 624 [PROBES_T16_HIREGOPS] = {.decoder = t16_decode_hiregs},
1257 /* REV 1011 1010 00xx xxxx */ 625 [PROBES_T16_LDRHSTRH] = {.handler = t16_emulate_loregs_rwflags},
1258 /* REV16 1011 1010 01xx xxxx */ 626 [PROBES_T16_LDRSTR] = {.handler = t16_simulate_ldrstr_sp_relative},
1259 /* ??? 1011 1010 10xx xxxx */ 627 [PROBES_T16_ADR] = {.handler = t16_simulate_reladr},
1260 /* REVSH 1011 1010 11xx xxxx */ 628 [PROBES_T16_LDMSTM] = {.handler = t16_emulate_loregs_rwflags},
1261 DECODE_REJECT (0xffc0, 0xba80), 629 [PROBES_T16_BRANCH_COND] = {.decoder = t16_decode_cond_branch},
1262 DECODE_EMULATE (0xf500, 0xb000, t16_emulate_loregs_rwflags), 630 [PROBES_T16_BRANCH] = {.handler = t16_simulate_branch},
1263
1264 /* PUSH 1011 010x xxxx xxxx */
1265 DECODE_CUSTOM (0xfe00, 0xb400, t16_decode_push),
1266 /* POP 1011 110x xxxx xxxx */
1267 DECODE_CUSTOM (0xfe00, 0xbc00, t16_decode_pop),
1268
1269 /*
1270 * If-Then, and hints
1271 * 1011 1111 xxxx xxxx
1272 */
1273
1274 /* YIELD 1011 1111 0001 0000 */
1275 DECODE_OR (0xffff, 0xbf10),
1276 /* SEV 1011 1111 0100 0000 */
1277 DECODE_EMULATE (0xffff, 0xbf40, kprobe_emulate_none),
1278 /* NOP 1011 1111 0000 0000 */
1279 /* WFE 1011 1111 0010 0000 */
1280 /* WFI 1011 1111 0011 0000 */
1281 DECODE_SIMULATE (0xffcf, 0xbf00, kprobe_simulate_nop),
1282 /* Unassigned hints 1011 1111 xxxx 0000 */
1283 DECODE_REJECT (0xff0f, 0xbf00),
1284 /* IT 1011 1111 xxxx xxxx */
1285 DECODE_CUSTOM (0xff00, 0xbf00, t16_decode_it),
1286
1287 /* SETEND 1011 0110 010x xxxx */
1288 /* CPS 1011 0110 011x xxxx */
1289 /* BKPT 1011 1110 xxxx xxxx */
1290 /* And unallocated instructions... */
1291 DECODE_END
1292}; 631};
1293 632
1294const union decode_item kprobe_decode_thumb16_table[] = { 633const union decode_action kprobes_t32_actions[NUM_PROBES_T32_ACTIONS] = {
1295 634 [PROBES_T32_LDMSTM] = {.decoder = t32_decode_ldmstm},
1296 /* 635 [PROBES_T32_LDRDSTRD] = {.handler = t32_emulate_ldrdstrd},
1297 * Shift (immediate), add, subtract, move, and compare 636 [PROBES_T32_TABLE_BRANCH] = {.handler = t32_simulate_table_branch},
1298 * 00xx xxxx xxxx xxxx 637 [PROBES_T32_TST] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1299 */ 638 [PROBES_T32_MOV] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1300 639 [PROBES_T32_ADDSUB] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1301 /* CMP (immediate) 0010 1xxx xxxx xxxx */ 640 [PROBES_T32_LOGICAL] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1302 DECODE_EMULATE (0xf800, 0x2800, t16_emulate_loregs_rwflags), 641 [PROBES_T32_CMP] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1303 642 [PROBES_T32_ADDWSUBW_PC] = {.handler = t32_emulate_rd8pc16_noflags,},
1304 /* ADD (register) 0001 100x xxxx xxxx */ 643 [PROBES_T32_ADDWSUBW] = {.handler = t32_emulate_rd8rn16_noflags},
1305 /* SUB (register) 0001 101x xxxx xxxx */ 644 [PROBES_T32_MOVW] = {.handler = t32_emulate_rd8rn16_noflags},
1306 /* LSL (immediate) 0000 0xxx xxxx xxxx */ 645 [PROBES_T32_SAT] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1307 /* LSR (immediate) 0000 1xxx xxxx xxxx */ 646 [PROBES_T32_BITFIELD] = {.handler = t32_emulate_rd8rn16_noflags},
1308 /* ASR (immediate) 0001 0xxx xxxx xxxx */ 647 [PROBES_T32_SEV] = {.handler = probes_emulate_none},
1309 /* ADD (immediate, Thumb) 0001 110x xxxx xxxx */ 648 [PROBES_T32_WFE] = {.handler = probes_simulate_nop},
1310 /* SUB (immediate, Thumb) 0001 111x xxxx xxxx */ 649 [PROBES_T32_MRS] = {.handler = t32_simulate_mrs},
1311 /* MOV (immediate) 0010 0xxx xxxx xxxx */ 650 [PROBES_T32_BRANCH_COND] = {.decoder = t32_decode_cond_branch},
1312 /* ADD (immediate, Thumb) 0011 0xxx xxxx xxxx */ 651 [PROBES_T32_BRANCH] = {.handler = t32_simulate_branch},
1313 /* SUB (immediate, Thumb) 0011 1xxx xxxx xxxx */ 652 [PROBES_T32_PLDI] = {.handler = probes_simulate_nop},
1314 DECODE_EMULATE (0xc000, 0x0000, t16_emulate_loregs_noitrwflags), 653 [PROBES_T32_LDR_LIT] = {.handler = t32_simulate_ldr_literal},
1315 654 [PROBES_T32_LDRSTR] = {.handler = t32_emulate_ldrstr},
1316 /* 655 [PROBES_T32_SIGN_EXTEND] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1317 * 16-bit Thumb data-processing instructions 656 [PROBES_T32_MEDIA] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1318 * 0100 00xx xxxx xxxx 657 [PROBES_T32_REVERSE] = {.handler = t32_emulate_rd8rn16_noflags},
1319 */ 658 [PROBES_T32_MUL_ADD] = {.handler = t32_emulate_rd8rn16rm0_rwflags},
1320 659 [PROBES_T32_MUL_ADD2] = {.handler = t32_emulate_rd8rn16rm0ra12_noflags},
1321 /* TST (register) 0100 0010 00xx xxxx */ 660 [PROBES_T32_MUL_ADD_LONG] = {
1322 DECODE_EMULATE (0xffc0, 0x4200, t16_emulate_loregs_rwflags), 661 .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags},
1323 /* CMP (register) 0100 0010 10xx xxxx */
1324 /* CMN (register) 0100 0010 11xx xxxx */
1325 DECODE_EMULATE (0xff80, 0x4280, t16_emulate_loregs_rwflags),
1326 /* AND (register) 0100 0000 00xx xxxx */
1327 /* EOR (register) 0100 0000 01xx xxxx */
1328 /* LSL (register) 0100 0000 10xx xxxx */
1329 /* LSR (register) 0100 0000 11xx xxxx */
1330 /* ASR (register) 0100 0001 00xx xxxx */
1331 /* ADC (register) 0100 0001 01xx xxxx */
1332 /* SBC (register) 0100 0001 10xx xxxx */
1333 /* ROR (register) 0100 0001 11xx xxxx */
1334 /* RSB (immediate) 0100 0010 01xx xxxx */
1335 /* ORR (register) 0100 0011 00xx xxxx */
1336 /* MUL 0100 0011 00xx xxxx */
1337 /* BIC (register) 0100 0011 10xx xxxx */
1338 /* MVN (register) 0100 0011 10xx xxxx */
1339 DECODE_EMULATE (0xfc00, 0x4000, t16_emulate_loregs_noitrwflags),
1340
1341 /*
1342 * Special data instructions and branch and exchange
1343 * 0100 01xx xxxx xxxx
1344 */
1345
1346 /* BLX pc 0100 0111 1111 1xxx */
1347 DECODE_REJECT (0xfff8, 0x47f8),
1348
1349 /* BX (register) 0100 0111 0xxx xxxx */
1350 /* BLX (register) 0100 0111 1xxx xxxx */
1351 DECODE_SIMULATE (0xff00, 0x4700, t16_simulate_bxblx),
1352
1353 /* ADD pc, pc 0100 0100 1111 1111 */
1354 DECODE_REJECT (0xffff, 0x44ff),
1355
1356 /* ADD (register) 0100 0100 xxxx xxxx */
1357 /* CMP (register) 0100 0101 xxxx xxxx */
1358 /* MOV (register) 0100 0110 xxxx xxxx */
1359 DECODE_CUSTOM (0xfc00, 0x4400, t16_decode_hiregs),
1360
1361 /*
1362 * Load from Literal Pool
1363 * LDR (literal) 0100 1xxx xxxx xxxx
1364 */
1365 DECODE_SIMULATE (0xf800, 0x4800, t16_simulate_ldr_literal),
1366
1367 /*
1368 * 16-bit Thumb Load/store instructions
1369 * 0101 xxxx xxxx xxxx
1370 * 011x xxxx xxxx xxxx
1371 * 100x xxxx xxxx xxxx
1372 */
1373
1374 /* STR (register) 0101 000x xxxx xxxx */
1375 /* STRH (register) 0101 001x xxxx xxxx */
1376 /* STRB (register) 0101 010x xxxx xxxx */
1377 /* LDRSB (register) 0101 011x xxxx xxxx */
1378 /* LDR (register) 0101 100x xxxx xxxx */
1379 /* LDRH (register) 0101 101x xxxx xxxx */
1380 /* LDRB (register) 0101 110x xxxx xxxx */
1381 /* LDRSH (register) 0101 111x xxxx xxxx */
1382 /* STR (immediate, Thumb) 0110 0xxx xxxx xxxx */
1383 /* LDR (immediate, Thumb) 0110 1xxx xxxx xxxx */
1384 /* STRB (immediate, Thumb) 0111 0xxx xxxx xxxx */
1385 /* LDRB (immediate, Thumb) 0111 1xxx xxxx xxxx */
1386 DECODE_EMULATE (0xc000, 0x4000, t16_emulate_loregs_rwflags),
1387 /* STRH (immediate, Thumb) 1000 0xxx xxxx xxxx */
1388 /* LDRH (immediate, Thumb) 1000 1xxx xxxx xxxx */
1389 DECODE_EMULATE (0xf000, 0x8000, t16_emulate_loregs_rwflags),
1390 /* STR (immediate, Thumb) 1001 0xxx xxxx xxxx */
1391 /* LDR (immediate, Thumb) 1001 1xxx xxxx xxxx */
1392 DECODE_SIMULATE (0xf000, 0x9000, t16_simulate_ldrstr_sp_relative),
1393
1394 /*
1395 * Generate PC-/SP-relative address
1396 * ADR (literal) 1010 0xxx xxxx xxxx
1397 * ADD (SP plus immediate) 1010 1xxx xxxx xxxx
1398 */
1399 DECODE_SIMULATE (0xf000, 0xa000, t16_simulate_reladr),
1400
1401 /*
1402 * Miscellaneous 16-bit instructions
1403 * 1011 xxxx xxxx xxxx
1404 */
1405 DECODE_TABLE (0xf000, 0xb000, t16_table_1011),
1406
1407 /* STM 1100 0xxx xxxx xxxx */
1408 /* LDM 1100 1xxx xxxx xxxx */
1409 DECODE_EMULATE (0xf000, 0xc000, t16_emulate_loregs_rwflags),
1410
1411 /*
1412 * Conditional branch, and Supervisor Call
1413 */
1414
1415 /* Permanently UNDEFINED 1101 1110 xxxx xxxx */
1416 /* SVC 1101 1111 xxxx xxxx */
1417 DECODE_REJECT (0xfe00, 0xde00),
1418
1419 /* Conditional branch 1101 xxxx xxxx xxxx */
1420 DECODE_CUSTOM (0xf000, 0xd000, t16_decode_cond_branch),
1421
1422 /*
1423 * Unconditional branch
1424 * B 1110 0xxx xxxx xxxx
1425 */
1426 DECODE_SIMULATE (0xf800, 0xe000, t16_simulate_branch),
1427
1428 DECODE_END
1429}; 662};
1430#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
1431EXPORT_SYMBOL_GPL(kprobe_decode_thumb16_table);
1432#endif
1433
1434static unsigned long __kprobes thumb_check_cc(unsigned long cpsr)
1435{
1436 if (unlikely(in_it_block(cpsr)))
1437 return kprobe_condition_checks[current_cond(cpsr)](cpsr);
1438 return true;
1439}
1440
1441static void __kprobes thumb16_singlestep(struct kprobe *p, struct pt_regs *regs)
1442{
1443 regs->ARM_pc += 2;
1444 p->ainsn.insn_handler(p, regs);
1445 regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
1446}
1447
1448static void __kprobes thumb32_singlestep(struct kprobe *p, struct pt_regs *regs)
1449{
1450 regs->ARM_pc += 4;
1451 p->ainsn.insn_handler(p, regs);
1452 regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
1453}
1454
1455enum kprobe_insn __kprobes
1456thumb16_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1457{
1458 asi->insn_singlestep = thumb16_singlestep;
1459 asi->insn_check_cc = thumb_check_cc;
1460 return kprobe_decode_insn(insn, asi, kprobe_decode_thumb16_table, true);
1461}
1462
1463enum kprobe_insn __kprobes
1464thumb32_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1465{
1466 asi->insn_singlestep = thumb32_singlestep;
1467 asi->insn_check_cc = thumb_check_cc;
1468 return kprobe_decode_insn(insn, asi, kprobe_decode_thumb32_table, true);
1469}
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index a7b621ece23d..8795f9f819d5 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/kernel/kprobes.c
@@ -27,8 +27,12 @@
27#include <linux/stringify.h> 27#include <linux/stringify.h>
28#include <asm/traps.h> 28#include <asm/traps.h>
29#include <asm/cacheflush.h> 29#include <asm/cacheflush.h>
30#include <linux/percpu.h>
31#include <linux/bug.h>
30 32
31#include "kprobes.h" 33#include "kprobes.h"
34#include "probes-arm.h"
35#include "probes-thumb.h"
32#include "patch.h" 36#include "patch.h"
33 37
34#define MIN_STACK_SIZE(addr) \ 38#define MIN_STACK_SIZE(addr) \
@@ -54,6 +58,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
54 unsigned long addr = (unsigned long)p->addr; 58 unsigned long addr = (unsigned long)p->addr;
55 bool thumb; 59 bool thumb;
56 kprobe_decode_insn_t *decode_insn; 60 kprobe_decode_insn_t *decode_insn;
61 const union decode_action *actions;
57 int is; 62 int is;
58 63
59 if (in_exception_text(addr)) 64 if (in_exception_text(addr))
@@ -66,21 +71,25 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
66 if (is_wide_instruction(insn)) { 71 if (is_wide_instruction(insn)) {
67 insn <<= 16; 72 insn <<= 16;
68 insn |= ((u16 *)addr)[1]; 73 insn |= ((u16 *)addr)[1];
69 decode_insn = thumb32_kprobe_decode_insn; 74 decode_insn = thumb32_probes_decode_insn;
70 } else 75 actions = kprobes_t32_actions;
71 decode_insn = thumb16_kprobe_decode_insn; 76 } else {
77 decode_insn = thumb16_probes_decode_insn;
78 actions = kprobes_t16_actions;
79 }
72#else /* !CONFIG_THUMB2_KERNEL */ 80#else /* !CONFIG_THUMB2_KERNEL */
73 thumb = false; 81 thumb = false;
74 if (addr & 0x3) 82 if (addr & 0x3)
75 return -EINVAL; 83 return -EINVAL;
76 insn = *p->addr; 84 insn = *p->addr;
77 decode_insn = arm_kprobe_decode_insn; 85 decode_insn = arm_probes_decode_insn;
86 actions = kprobes_arm_actions;
78#endif 87#endif
79 88
80 p->opcode = insn; 89 p->opcode = insn;
81 p->ainsn.insn = tmp_insn; 90 p->ainsn.insn = tmp_insn;
82 91
83 switch ((*decode_insn)(insn, &p->ainsn)) { 92 switch ((*decode_insn)(insn, &p->ainsn, true, actions)) {
84 case INSN_REJECTED: /* not supported */ 93 case INSN_REJECTED: /* not supported */
85 return -EINVAL; 94 return -EINVAL;
86 95
@@ -92,7 +101,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
92 p->ainsn.insn[is] = tmp_insn[is]; 101 p->ainsn.insn[is] = tmp_insn[is];
93 flush_insns(p->ainsn.insn, 102 flush_insns(p->ainsn.insn,
94 sizeof(p->ainsn.insn[0]) * MAX_INSN_SIZE); 103 sizeof(p->ainsn.insn[0]) * MAX_INSN_SIZE);
95 p->ainsn.insn_fn = (kprobe_insn_fn_t *) 104 p->ainsn.insn_fn = (probes_insn_fn_t *)
96 ((uintptr_t)p->ainsn.insn | thumb); 105 ((uintptr_t)p->ainsn.insn | thumb);
97 break; 106 break;
98 107
@@ -197,7 +206,7 @@ singlestep_skip(struct kprobe *p, struct pt_regs *regs)
197static inline void __kprobes 206static inline void __kprobes
198singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) 207singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb)
199{ 208{
200 p->ainsn.insn_singlestep(p, regs); 209 p->ainsn.insn_singlestep(p->opcode, &p->ainsn, regs);
201} 210}
202 211
203/* 212/*
@@ -607,7 +616,7 @@ static struct undef_hook kprobes_arm_break_hook = {
607 616
608int __init arch_init_kprobes() 617int __init arch_init_kprobes()
609{ 618{
610 arm_kprobe_decode_init(); 619 arm_probes_decode_init();
611#ifdef CONFIG_THUMB2_KERNEL 620#ifdef CONFIG_THUMB2_KERNEL
612 register_undef_hook(&kprobes_thumb16_break_hook); 621 register_undef_hook(&kprobes_thumb16_break_hook);
613 register_undef_hook(&kprobes_thumb32_break_hook); 622 register_undef_hook(&kprobes_thumb32_break_hook);
diff --git a/arch/arm/kernel/kprobes.h b/arch/arm/kernel/kprobes.h
index 38945f78f9f1..9a2712ecefc3 100644
--- a/arch/arm/kernel/kprobes.h
+++ b/arch/arm/kernel/kprobes.h
@@ -19,6 +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"
23
22/* 24/*
23 * These undefined instructions must be unique and 25 * These undefined instructions must be unique and
24 * reserved solely for kprobes' use. 26 * reserved solely for kprobes' use.
@@ -27,402 +29,24 @@
27#define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18 29#define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18
28#define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018 30#define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018
29 31
32enum probes_insn __kprobes
33kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_probes_insn *asi,
34 const struct decode_header *h);
30 35
31enum kprobe_insn { 36typedef enum probes_insn (kprobe_decode_insn_t)(probes_opcode_t,
32 INSN_REJECTED, 37 struct arch_probes_insn *,
33 INSN_GOOD, 38 bool,
34 INSN_GOOD_NO_SLOT 39 const union decode_action *);
35};
36
37typedef enum kprobe_insn (kprobe_decode_insn_t)(kprobe_opcode_t,
38 struct arch_specific_insn *);
39 40
40#ifdef CONFIG_THUMB2_KERNEL 41#ifdef CONFIG_THUMB2_KERNEL
41 42
42enum kprobe_insn thumb16_kprobe_decode_insn(kprobe_opcode_t, 43extern const union decode_action kprobes_t32_actions[];
43 struct arch_specific_insn *); 44extern const union decode_action kprobes_t16_actions[];
44enum kprobe_insn thumb32_kprobe_decode_insn(kprobe_opcode_t,
45 struct arch_specific_insn *);
46 45
47#else /* !CONFIG_THUMB2_KERNEL */ 46#else /* !CONFIG_THUMB2_KERNEL */
48 47
49enum kprobe_insn arm_kprobe_decode_insn(kprobe_opcode_t, 48extern const union decode_action kprobes_arm_actions[];
50 struct arch_specific_insn *);
51#endif
52
53void __init arm_kprobe_decode_init(void);
54
55extern kprobe_check_cc * const kprobe_condition_checks[16];
56
57
58#if __LINUX_ARM_ARCH__ >= 7
59
60/* str_pc_offset is architecturally defined from ARMv7 onwards */
61#define str_pc_offset 8
62#define find_str_pc_offset()
63
64#else /* __LINUX_ARM_ARCH__ < 7 */
65
66/* We need a run-time check to determine str_pc_offset */
67extern int str_pc_offset;
68void __init find_str_pc_offset(void);
69 49
70#endif 50#endif
71 51
72
73/*
74 * Update ITSTATE after normal execution of an IT block instruction.
75 *
76 * The 8 IT state bits are split into two parts in CPSR:
77 * ITSTATE<1:0> are in CPSR<26:25>
78 * ITSTATE<7:2> are in CPSR<15:10>
79 */
80static inline unsigned long it_advance(unsigned long cpsr)
81 {
82 if ((cpsr & 0x06000400) == 0) {
83 /* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */
84 cpsr &= ~PSR_IT_MASK;
85 } else {
86 /* We need to shift left ITSTATE<4:0> */
87 const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */
88 unsigned long it = cpsr & mask;
89 it <<= 1;
90 it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */
91 it &= mask;
92 cpsr &= ~mask;
93 cpsr |= it;
94 }
95 return cpsr;
96}
97
98static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs)
99{
100 long cpsr = regs->ARM_cpsr;
101 if (pcv & 0x1) {
102 cpsr |= PSR_T_BIT;
103 pcv &= ~0x1;
104 } else {
105 cpsr &= ~PSR_T_BIT;
106 pcv &= ~0x2; /* Avoid UNPREDICTABLE address allignment */
107 }
108 regs->ARM_cpsr = cpsr;
109 regs->ARM_pc = pcv;
110}
111
112
113#if __LINUX_ARM_ARCH__ >= 6
114
115/* Kernels built for >= ARMv6 should never run on <= ARMv5 hardware, so... */
116#define load_write_pc_interworks true
117#define test_load_write_pc_interworking()
118
119#else /* __LINUX_ARM_ARCH__ < 6 */
120
121/* We need run-time testing to determine if load_write_pc() should interwork. */
122extern bool load_write_pc_interworks;
123void __init test_load_write_pc_interworking(void);
124
125#endif
126
127static inline void __kprobes load_write_pc(long pcv, struct pt_regs *regs)
128{
129 if (load_write_pc_interworks)
130 bx_write_pc(pcv, regs);
131 else
132 regs->ARM_pc = pcv;
133}
134
135
136#if __LINUX_ARM_ARCH__ >= 7
137
138#define alu_write_pc_interworks true
139#define test_alu_write_pc_interworking()
140
141#elif __LINUX_ARM_ARCH__ <= 5
142
143/* Kernels built for <= ARMv5 should never run on >= ARMv6 hardware, so... */
144#define alu_write_pc_interworks false
145#define test_alu_write_pc_interworking()
146
147#else /* __LINUX_ARM_ARCH__ == 6 */
148
149/* We could be an ARMv6 binary on ARMv7 hardware so we need a run-time check. */
150extern bool alu_write_pc_interworks;
151void __init test_alu_write_pc_interworking(void);
152
153#endif /* __LINUX_ARM_ARCH__ == 6 */
154
155static inline void __kprobes alu_write_pc(long pcv, struct pt_regs *regs)
156{
157 if (alu_write_pc_interworks)
158 bx_write_pc(pcv, regs);
159 else
160 regs->ARM_pc = pcv;
161}
162
163
164void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs);
165void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs);
166
167enum kprobe_insn __kprobes
168kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi);
169
170/*
171 * Test if load/store instructions writeback the address register.
172 * if P (bit 24) == 0 or W (bit 21) == 1
173 */
174#define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000)
175
176/*
177 * The following definitions and macros are used to build instruction
178 * decoding tables for use by kprobe_decode_insn.
179 *
180 * These tables are a concatenation of entries each of which consist of one of
181 * the decode_* structs. All of the fields in every type of decode structure
182 * are of the union type decode_item, therefore the entire decode table can be
183 * viewed as an array of these and declared like:
184 *
185 * static const union decode_item table_name[] = {};
186 *
187 * In order to construct each entry in the table, macros are used to
188 * initialise a number of sequential decode_item values in a layout which
189 * matches the relevant struct. E.g. DECODE_SIMULATE initialise a struct
190 * decode_simulate by initialising four decode_item objects like this...
191 *
192 * {.bits = _type},
193 * {.bits = _mask},
194 * {.bits = _value},
195 * {.handler = _handler},
196 *
197 * Initialising a specified member of the union means that the compiler
198 * will produce a warning if the argument is of an incorrect type.
199 *
200 * Below is a list of each of the macros used to initialise entries and a
201 * description of the action performed when that entry is matched to an
202 * instruction. A match is found when (instruction & mask) == value.
203 *
204 * DECODE_TABLE(mask, value, table)
205 * Instruction decoding jumps to parsing the new sub-table 'table'.
206 *
207 * DECODE_CUSTOM(mask, value, decoder)
208 * The custom function 'decoder' is called to the complete decoding
209 * of an instruction.
210 *
211 * DECODE_SIMULATE(mask, value, handler)
212 * Set the probes instruction handler to 'handler', this will be used
213 * to simulate the instruction when the probe is hit. Decoding returns
214 * with INSN_GOOD_NO_SLOT.
215 *
216 * DECODE_EMULATE(mask, value, handler)
217 * Set the probes instruction handler to 'handler', this will be used
218 * to emulate the instruction when the probe is hit. The modified
219 * instruction (see below) is placed in the probes instruction slot so it
220 * may be called by the emulation code. Decoding returns with INSN_GOOD.
221 *
222 * DECODE_REJECT(mask, value)
223 * Instruction decoding fails with INSN_REJECTED
224 *
225 * DECODE_OR(mask, value)
226 * This allows the mask/value test of multiple table entries to be
227 * logically ORed. Once an 'or' entry is matched the decoding action to
228 * be performed is that of the next entry which isn't an 'or'. E.g.
229 *
230 * DECODE_OR (mask1, value1)
231 * DECODE_OR (mask2, value2)
232 * DECODE_SIMULATE (mask3, value3, simulation_handler)
233 *
234 * This means that if any of the three mask/value pairs match the
235 * instruction being decoded, then 'simulation_handler' will be used
236 * for it.
237 *
238 * Both the SIMULATE and EMULATE macros have a second form which take an
239 * additional 'regs' argument.
240 *
241 * DECODE_SIMULATEX(mask, value, handler, regs)
242 * DECODE_EMULATEX (mask, value, handler, regs)
243 *
244 * These are used to specify what kind of CPU register is encoded in each of the
245 * least significant 5 nibbles of the instruction being decoded. The regs value
246 * is specified using the REGS macro, this takes any of the REG_TYPE_* values
247 * from enum decode_reg_type as arguments; only the '*' part of the name is
248 * given. E.g.
249 *
250 * REGS(0, ANY, NOPC, 0, ANY)
251 *
252 * This indicates an instruction is encoded like:
253 *
254 * bits 19..16 ignore
255 * bits 15..12 any register allowed here
256 * bits 11.. 8 any register except PC allowed here
257 * bits 7.. 4 ignore
258 * bits 3.. 0 any register allowed here
259 *
260 * This register specification is checked after a decode table entry is found to
261 * match an instruction (through the mask/value test). Any invalid register then
262 * found in the instruction will cause decoding to fail with INSN_REJECTED. In
263 * the above example this would happen if bits 11..8 of the instruction were
264 * 1111, indicating R15 or PC.
265 *
266 * As well as checking for legal combinations of registers, this data is also
267 * used to modify the registers encoded in the instructions so that an
268 * emulation routines can use it. (See decode_regs() and INSN_NEW_BITS.)
269 *
270 * Here is a real example which matches ARM instructions of the form
271 * "AND <Rd>,<Rn>,<Rm>,<shift> <Rs>"
272 *
273 * DECODE_EMULATEX (0x0e000090, 0x00000010, emulate_rd12rn16rm0rs8_rwflags,
274 * REGS(ANY, ANY, NOPC, 0, ANY)),
275 * ^ ^ ^ ^
276 * Rn Rd Rs Rm
277 *
278 * Decoding the instruction "AND R4, R5, R6, ASL R15" will be rejected because
279 * Rs == R15
280 *
281 * Decoding the instruction "AND R4, R5, R6, ASL R7" will be accepted and the
282 * instruction will be modified to "AND R0, R2, R3, ASL R1" and then placed into
283 * the kprobes instruction slot. This can then be called later by the handler
284 * function emulate_rd12rn16rm0rs8_rwflags in order to simulate the instruction.
285 */
286
287enum decode_type {
288 DECODE_TYPE_END,
289 DECODE_TYPE_TABLE,
290 DECODE_TYPE_CUSTOM,
291 DECODE_TYPE_SIMULATE,
292 DECODE_TYPE_EMULATE,
293 DECODE_TYPE_OR,
294 DECODE_TYPE_REJECT,
295 NUM_DECODE_TYPES /* Must be last enum */
296};
297
298#define DECODE_TYPE_BITS 4
299#define DECODE_TYPE_MASK ((1 << DECODE_TYPE_BITS) - 1)
300
301enum decode_reg_type {
302 REG_TYPE_NONE = 0, /* Not a register, ignore */
303 REG_TYPE_ANY, /* Any register allowed */
304 REG_TYPE_SAMEAS16, /* Register should be same as that at bits 19..16 */
305 REG_TYPE_SP, /* Register must be SP */
306 REG_TYPE_PC, /* Register must be PC */
307 REG_TYPE_NOSP, /* Register must not be SP */
308 REG_TYPE_NOSPPC, /* Register must not be SP or PC */
309 REG_TYPE_NOPC, /* Register must not be PC */
310 REG_TYPE_NOPCWB, /* No PC if load/store write-back flag also set */
311
312 /* The following types are used when the encoding for PC indicates
313 * another instruction form. This distiction only matters for test
314 * case coverage checks.
315 */
316 REG_TYPE_NOPCX, /* Register must not be PC */
317 REG_TYPE_NOSPPCX, /* Register must not be SP or PC */
318
319 /* Alias to allow '0' arg to be used in REGS macro. */
320 REG_TYPE_0 = REG_TYPE_NONE
321};
322
323#define REGS(r16, r12, r8, r4, r0) \
324 ((REG_TYPE_##r16) << 16) + \
325 ((REG_TYPE_##r12) << 12) + \
326 ((REG_TYPE_##r8) << 8) + \
327 ((REG_TYPE_##r4) << 4) + \
328 (REG_TYPE_##r0)
329
330union decode_item {
331 u32 bits;
332 const union decode_item *table;
333 kprobe_insn_handler_t *handler;
334 kprobe_decode_insn_t *decoder;
335};
336
337
338#define DECODE_END \
339 {.bits = DECODE_TYPE_END}
340
341
342struct decode_header {
343 union decode_item type_regs;
344 union decode_item mask;
345 union decode_item value;
346};
347
348#define DECODE_HEADER(_type, _mask, _value, _regs) \
349 {.bits = (_type) | ((_regs) << DECODE_TYPE_BITS)}, \
350 {.bits = (_mask)}, \
351 {.bits = (_value)}
352
353
354struct decode_table {
355 struct decode_header header;
356 union decode_item table;
357};
358
359#define DECODE_TABLE(_mask, _value, _table) \
360 DECODE_HEADER(DECODE_TYPE_TABLE, _mask, _value, 0), \
361 {.table = (_table)}
362
363
364struct decode_custom {
365 struct decode_header header;
366 union decode_item decoder;
367};
368
369#define DECODE_CUSTOM(_mask, _value, _decoder) \
370 DECODE_HEADER(DECODE_TYPE_CUSTOM, _mask, _value, 0), \
371 {.decoder = (_decoder)}
372
373
374struct decode_simulate {
375 struct decode_header header;
376 union decode_item handler;
377};
378
379#define DECODE_SIMULATEX(_mask, _value, _handler, _regs) \
380 DECODE_HEADER(DECODE_TYPE_SIMULATE, _mask, _value, _regs), \
381 {.handler = (_handler)}
382
383#define DECODE_SIMULATE(_mask, _value, _handler) \
384 DECODE_SIMULATEX(_mask, _value, _handler, 0)
385
386
387struct decode_emulate {
388 struct decode_header header;
389 union decode_item handler;
390};
391
392#define DECODE_EMULATEX(_mask, _value, _handler, _regs) \
393 DECODE_HEADER(DECODE_TYPE_EMULATE, _mask, _value, _regs), \
394 {.handler = (_handler)}
395
396#define DECODE_EMULATE(_mask, _value, _handler) \
397 DECODE_EMULATEX(_mask, _value, _handler, 0)
398
399
400struct decode_or {
401 struct decode_header header;
402};
403
404#define DECODE_OR(_mask, _value) \
405 DECODE_HEADER(DECODE_TYPE_OR, _mask, _value, 0)
406
407
408struct decode_reject {
409 struct decode_header header;
410};
411
412#define DECODE_REJECT(_mask, _value) \
413 DECODE_HEADER(DECODE_TYPE_REJECT, _mask, _value, 0)
414
415
416#ifdef CONFIG_THUMB2_KERNEL
417extern const union decode_item kprobe_decode_thumb16_table[];
418extern const union decode_item kprobe_decode_thumb32_table[];
419#else
420extern const union decode_item kprobe_decode_arm_table[];
421#endif
422
423
424int kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
425 const union decode_item *table, bool thumb16);
426
427
428#endif /* _ARM_KERNEL_KPROBES_H */ 52#endif /* _ARM_KERNEL_KPROBES_H */
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 789d846a9184..a6bc431cde70 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -16,6 +16,8 @@
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/pm_runtime.h> 17#include <linux/pm_runtime.h>
18#include <linux/uaccess.h> 18#include <linux/uaccess.h>
19#include <linux/irq.h>
20#include <linux/irqdesc.h>
19 21
20#include <asm/irq_regs.h> 22#include <asm/irq_regs.h>
21#include <asm/pmu.h> 23#include <asm/pmu.h>
@@ -205,6 +207,8 @@ armpmu_del(struct perf_event *event, int flags)
205 armpmu_stop(event, PERF_EF_UPDATE); 207 armpmu_stop(event, PERF_EF_UPDATE);
206 hw_events->events[idx] = NULL; 208 hw_events->events[idx] = NULL;
207 clear_bit(idx, hw_events->used_mask); 209 clear_bit(idx, hw_events->used_mask);
210 if (armpmu->clear_event_idx)
211 armpmu->clear_event_idx(hw_events, event);
208 212
209 perf_event_update_userpage(event); 213 perf_event_update_userpage(event);
210} 214}
@@ -295,14 +299,27 @@ validate_group(struct perf_event *event)
295 299
296static irqreturn_t armpmu_dispatch_irq(int irq, void *dev) 300static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
297{ 301{
298 struct arm_pmu *armpmu = (struct arm_pmu *) dev; 302 struct arm_pmu *armpmu;
299 struct platform_device *plat_device = armpmu->plat_device; 303 struct platform_device *plat_device;
300 struct arm_pmu_platdata *plat = dev_get_platdata(&plat_device->dev); 304 struct arm_pmu_platdata *plat;
305 int ret;
306 u64 start_clock, finish_clock;
301 307
308 if (irq_is_percpu(irq))
309 dev = *(void **)dev;
310 armpmu = dev;
311 plat_device = armpmu->plat_device;
312 plat = dev_get_platdata(&plat_device->dev);
313
314 start_clock = sched_clock();
302 if (plat && plat->handle_irq) 315 if (plat && plat->handle_irq)
303 return plat->handle_irq(irq, dev, armpmu->handle_irq); 316 ret = plat->handle_irq(irq, dev, armpmu->handle_irq);
304 else 317 else
305 return armpmu->handle_irq(irq, dev); 318 ret = armpmu->handle_irq(irq, dev);
319 finish_clock = sched_clock();
320
321 perf_sample_event_took(finish_clock - start_clock);
322 return ret;
306} 323}
307 324
308static void 325static void
diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c
index 20d553c9f5e2..51798d7854ac 100644
--- a/arch/arm/kernel/perf_event_cpu.c
+++ b/arch/arm/kernel/perf_event_cpu.c
@@ -25,6 +25,8 @@
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/irq.h>
29#include <linux/irqdesc.h>
28 30
29#include <asm/cputype.h> 31#include <asm/cputype.h>
30#include <asm/irq_regs.h> 32#include <asm/irq_regs.h>
@@ -33,6 +35,7 @@
33/* Set at runtime when we know what CPU type we are. */ 35/* Set at runtime when we know what CPU type we are. */
34static struct arm_pmu *cpu_pmu; 36static struct arm_pmu *cpu_pmu;
35 37
38static DEFINE_PER_CPU(struct arm_pmu *, percpu_pmu);
36static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events); 39static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events);
37static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask); 40static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask);
38static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events); 41static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
@@ -71,6 +74,26 @@ static struct pmu_hw_events *cpu_pmu_get_cpu_events(void)
71 return this_cpu_ptr(&cpu_hw_events); 74 return this_cpu_ptr(&cpu_hw_events);
72} 75}
73 76
77static void cpu_pmu_enable_percpu_irq(void *data)
78{
79 struct arm_pmu *cpu_pmu = data;
80 struct platform_device *pmu_device = cpu_pmu->plat_device;
81 int irq = platform_get_irq(pmu_device, 0);
82
83 enable_percpu_irq(irq, IRQ_TYPE_NONE);
84 cpumask_set_cpu(smp_processor_id(), &cpu_pmu->active_irqs);
85}
86
87static void cpu_pmu_disable_percpu_irq(void *data)
88{
89 struct arm_pmu *cpu_pmu = data;
90 struct platform_device *pmu_device = cpu_pmu->plat_device;
91 int irq = platform_get_irq(pmu_device, 0);
92
93 cpumask_clear_cpu(smp_processor_id(), &cpu_pmu->active_irqs);
94 disable_percpu_irq(irq);
95}
96
74static void cpu_pmu_free_irq(struct arm_pmu *cpu_pmu) 97static void cpu_pmu_free_irq(struct arm_pmu *cpu_pmu)
75{ 98{
76 int i, irq, irqs; 99 int i, irq, irqs;
@@ -78,12 +101,18 @@ static void cpu_pmu_free_irq(struct arm_pmu *cpu_pmu)
78 101
79 irqs = min(pmu_device->num_resources, num_possible_cpus()); 102 irqs = min(pmu_device->num_resources, num_possible_cpus());
80 103
81 for (i = 0; i < irqs; ++i) { 104 irq = platform_get_irq(pmu_device, 0);
82 if (!cpumask_test_and_clear_cpu(i, &cpu_pmu->active_irqs)) 105 if (irq >= 0 && irq_is_percpu(irq)) {
83 continue; 106 on_each_cpu(cpu_pmu_disable_percpu_irq, cpu_pmu, 1);
84 irq = platform_get_irq(pmu_device, i); 107 free_percpu_irq(irq, &percpu_pmu);
85 if (irq >= 0) 108 } else {
86 free_irq(irq, cpu_pmu); 109 for (i = 0; i < irqs; ++i) {
110 if (!cpumask_test_and_clear_cpu(i, &cpu_pmu->active_irqs))
111 continue;
112 irq = platform_get_irq(pmu_device, i);
113 if (irq >= 0)
114 free_irq(irq, cpu_pmu);
115 }
87 } 116 }
88} 117}
89 118
@@ -101,33 +130,44 @@ static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler)
101 return -ENODEV; 130 return -ENODEV;
102 } 131 }
103 132
104 for (i = 0; i < irqs; ++i) { 133 irq = platform_get_irq(pmu_device, 0);
105 err = 0; 134 if (irq >= 0 && irq_is_percpu(irq)) {
106 irq = platform_get_irq(pmu_device, i); 135 err = request_percpu_irq(irq, handler, "arm-pmu", &percpu_pmu);
107 if (irq < 0)
108 continue;
109
110 /*
111 * If we have a single PMU interrupt that we can't shift,
112 * assume that we're running on a uniprocessor machine and
113 * continue. Otherwise, continue without this interrupt.
114 */
115 if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) {
116 pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
117 irq, i);
118 continue;
119 }
120
121 err = request_irq(irq, handler,
122 IRQF_NOBALANCING | IRQF_NO_THREAD, "arm-pmu",
123 cpu_pmu);
124 if (err) { 136 if (err) {
125 pr_err("unable to request IRQ%d for ARM PMU counters\n", 137 pr_err("unable to request IRQ%d for ARM PMU counters\n",
126 irq); 138 irq);
127 return err; 139 return err;
128 } 140 }
129 141 on_each_cpu(cpu_pmu_enable_percpu_irq, cpu_pmu, 1);
130 cpumask_set_cpu(i, &cpu_pmu->active_irqs); 142 } else {
143 for (i = 0; i < irqs; ++i) {
144 err = 0;
145 irq = platform_get_irq(pmu_device, i);
146 if (irq < 0)
147 continue;
148
149 /*
150 * If we have a single PMU interrupt that we can't shift,
151 * assume that we're running on a uniprocessor machine and
152 * continue. Otherwise, continue without this interrupt.
153 */
154 if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) {
155 pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
156 irq, i);
157 continue;
158 }
159
160 err = request_irq(irq, handler,
161 IRQF_NOBALANCING | IRQF_NO_THREAD, "arm-pmu",
162 cpu_pmu);
163 if (err) {
164 pr_err("unable to request IRQ%d for ARM PMU counters\n",
165 irq);
166 return err;
167 }
168
169 cpumask_set_cpu(i, &cpu_pmu->active_irqs);
170 }
131 } 171 }
132 172
133 return 0; 173 return 0;
@@ -141,6 +181,7 @@ static void cpu_pmu_init(struct arm_pmu *cpu_pmu)
141 events->events = per_cpu(hw_events, cpu); 181 events->events = per_cpu(hw_events, cpu);
142 events->used_mask = per_cpu(used_mask, cpu); 182 events->used_mask = per_cpu(used_mask, cpu);
143 raw_spin_lock_init(&events->pmu_lock); 183 raw_spin_lock_init(&events->pmu_lock);
184 per_cpu(percpu_pmu, cpu) = cpu_pmu;
144 } 185 }
145 186
146 cpu_pmu->get_hw_events = cpu_pmu_get_cpu_events; 187 cpu_pmu->get_hw_events = cpu_pmu_get_cpu_events;
@@ -181,6 +222,7 @@ static struct notifier_block cpu_pmu_hotplug_notifier = {
181 */ 222 */
182static struct of_device_id cpu_pmu_of_device_ids[] = { 223static struct of_device_id cpu_pmu_of_device_ids[] = {
183 {.compatible = "arm,cortex-a15-pmu", .data = armv7_a15_pmu_init}, 224 {.compatible = "arm,cortex-a15-pmu", .data = armv7_a15_pmu_init},
225 {.compatible = "arm,cortex-a12-pmu", .data = armv7_a12_pmu_init},
184 {.compatible = "arm,cortex-a9-pmu", .data = armv7_a9_pmu_init}, 226 {.compatible = "arm,cortex-a9-pmu", .data = armv7_a9_pmu_init},
185 {.compatible = "arm,cortex-a8-pmu", .data = armv7_a8_pmu_init}, 227 {.compatible = "arm,cortex-a8-pmu", .data = armv7_a8_pmu_init},
186 {.compatible = "arm,cortex-a7-pmu", .data = armv7_a7_pmu_init}, 228 {.compatible = "arm,cortex-a7-pmu", .data = armv7_a7_pmu_init},
@@ -188,6 +230,7 @@ static struct of_device_id cpu_pmu_of_device_ids[] = {
188 {.compatible = "arm,arm11mpcore-pmu", .data = armv6mpcore_pmu_init}, 230 {.compatible = "arm,arm11mpcore-pmu", .data = armv6mpcore_pmu_init},
189 {.compatible = "arm,arm1176-pmu", .data = armv6pmu_init}, 231 {.compatible = "arm,arm1176-pmu", .data = armv6pmu_init},
190 {.compatible = "arm,arm1136-pmu", .data = armv6pmu_init}, 232 {.compatible = "arm,arm1136-pmu", .data = armv6pmu_init},
233 {.compatible = "qcom,krait-pmu", .data = krait_pmu_init},
191 {}, 234 {},
192}; 235};
193 236
@@ -225,15 +268,6 @@ static int probe_current_pmu(struct arm_pmu *pmu)
225 case ARM_CPU_PART_CORTEX_A9: 268 case ARM_CPU_PART_CORTEX_A9:
226 ret = armv7_a9_pmu_init(pmu); 269 ret = armv7_a9_pmu_init(pmu);
227 break; 270 break;
228 case ARM_CPU_PART_CORTEX_A5:
229 ret = armv7_a5_pmu_init(pmu);
230 break;
231 case ARM_CPU_PART_CORTEX_A15:
232 ret = armv7_a15_pmu_init(pmu);
233 break;
234 case ARM_CPU_PART_CORTEX_A7:
235 ret = armv7_a7_pmu_init(pmu);
236 break;
237 } 271 }
238 /* Intel CPUs [xscale]. */ 272 /* Intel CPUs [xscale]. */
239 } else if (implementor == ARM_CPU_IMP_INTEL) { 273 } else if (implementor == ARM_CPU_IMP_INTEL) {
@@ -270,6 +304,9 @@ static int cpu_pmu_device_probe(struct platform_device *pdev)
270 return -ENOMEM; 304 return -ENOMEM;
271 } 305 }
272 306
307 cpu_pmu = pmu;
308 cpu_pmu->plat_device = pdev;
309
273 if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) { 310 if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) {
274 init_fn = of_id->data; 311 init_fn = of_id->data;
275 ret = init_fn(pmu); 312 ret = init_fn(pmu);
@@ -282,8 +319,6 @@ static int cpu_pmu_device_probe(struct platform_device *pdev)
282 goto out_free; 319 goto out_free;
283 } 320 }
284 321
285 cpu_pmu = pmu;
286 cpu_pmu->plat_device = pdev;
287 cpu_pmu_init(cpu_pmu); 322 cpu_pmu_init(cpu_pmu);
288 ret = armpmu_register(cpu_pmu, PERF_TYPE_RAW); 323 ret = armpmu_register(cpu_pmu, PERF_TYPE_RAW);
289 324
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 039cffb053a7..f4ef3981ed02 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -18,6 +18,10 @@
18 18
19#ifdef CONFIG_CPU_V7 19#ifdef CONFIG_CPU_V7
20 20
21#include <asm/cp15.h>
22#include <asm/vfp.h>
23#include "../vfp/vfpinstr.h"
24
21/* 25/*
22 * Common ARMv7 event types 26 * Common ARMv7 event types
23 * 27 *
@@ -109,6 +113,33 @@ enum armv7_a15_perf_types {
109 ARMV7_A15_PERFCTR_PC_WRITE_SPEC = 0x76, 113 ARMV7_A15_PERFCTR_PC_WRITE_SPEC = 0x76,
110}; 114};
111 115
116/* ARMv7 Cortex-A12 specific event types */
117enum armv7_a12_perf_types {
118 ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40,
119 ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41,
120
121 ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
122 ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
123
124 ARMV7_A12_PERFCTR_PC_WRITE_SPEC = 0x76,
125
126 ARMV7_A12_PERFCTR_PF_TLB_REFILL = 0xe7,
127};
128
129/* ARMv7 Krait specific event types */
130enum krait_perf_types {
131 KRAIT_PMRESR0_GROUP0 = 0xcc,
132 KRAIT_PMRESR1_GROUP0 = 0xd0,
133 KRAIT_PMRESR2_GROUP0 = 0xd4,
134 KRAIT_VPMRESR0_GROUP0 = 0xd8,
135
136 KRAIT_PERFCTR_L1_ICACHE_ACCESS = 0x10011,
137 KRAIT_PERFCTR_L1_ICACHE_MISS = 0x10010,
138
139 KRAIT_PERFCTR_L1_ITLB_ACCESS = 0x12222,
140 KRAIT_PERFCTR_L1_DTLB_ACCESS = 0x12210,
141};
142
112/* 143/*
113 * Cortex-A8 HW events mapping 144 * Cortex-A8 HW events mapping
114 * 145 *
@@ -732,6 +763,262 @@ static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
732}; 763};
733 764
734/* 765/*
766 * Cortex-A12 HW events mapping
767 */
768static const unsigned armv7_a12_perf_map[PERF_COUNT_HW_MAX] = {
769 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
770 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
771 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
772 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
773 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A12_PERFCTR_PC_WRITE_SPEC,
774 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
775 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
776 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
777 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
778};
779
780static const unsigned armv7_a12_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
781 [PERF_COUNT_HW_CACHE_OP_MAX]
782 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
783 [C(L1D)] = {
784 [C(OP_READ)] = {
785 [C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ,
786 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
787 },
788 [C(OP_WRITE)] = {
789 [C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE,
790 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
791 },
792 [C(OP_PREFETCH)] = {
793 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
794 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
795 },
796 },
797 [C(L1I)] = {
798 /*
799 * Not all performance counters differentiate between read
800 * and write accesses/misses so we're not always strictly
801 * correct, but it's the best we can do. Writes and reads get
802 * combined in these cases.
803 */
804 [C(OP_READ)] = {
805 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
806 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
807 },
808 [C(OP_WRITE)] = {
809 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
810 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
811 },
812 [C(OP_PREFETCH)] = {
813 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
814 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
815 },
816 },
817 [C(LL)] = {
818 [C(OP_READ)] = {
819 [C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ,
820 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
821 },
822 [C(OP_WRITE)] = {
823 [C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE,
824 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
825 },
826 [C(OP_PREFETCH)] = {
827 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
828 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
829 },
830 },
831 [C(DTLB)] = {
832 [C(OP_READ)] = {
833 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
834 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
835 },
836 [C(OP_WRITE)] = {
837 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
838 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
839 },
840 [C(OP_PREFETCH)] = {
841 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
842 [C(RESULT_MISS)] = ARMV7_A12_PERFCTR_PF_TLB_REFILL,
843 },
844 },
845 [C(ITLB)] = {
846 [C(OP_READ)] = {
847 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
848 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
849 },
850 [C(OP_WRITE)] = {
851 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
852 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
853 },
854 [C(OP_PREFETCH)] = {
855 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
856 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
857 },
858 },
859 [C(BPU)] = {
860 [C(OP_READ)] = {
861 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
862 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
863 },
864 [C(OP_WRITE)] = {
865 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
866 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
867 },
868 [C(OP_PREFETCH)] = {
869 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
870 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
871 },
872 },
873 [C(NODE)] = {
874 [C(OP_READ)] = {
875 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
876 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
877 },
878 [C(OP_WRITE)] = {
879 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
880 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
881 },
882 [C(OP_PREFETCH)] = {
883 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
884 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
885 },
886 },
887};
888
889/*
890 * Krait HW events mapping
891 */
892static const unsigned krait_perf_map[PERF_COUNT_HW_MAX] = {
893 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
894 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
895 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
896 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
897 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
898 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
899 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
900};
901
902static const unsigned krait_perf_map_no_branch[PERF_COUNT_HW_MAX] = {
903 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
904 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
905 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
906 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
907 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = HW_OP_UNSUPPORTED,
908 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
909 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
910};
911
912static const unsigned krait_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
913 [PERF_COUNT_HW_CACHE_OP_MAX]
914 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
915 [C(L1D)] = {
916 /*
917 * The performance counters don't differentiate between read
918 * and write accesses/misses so this isn't strictly correct,
919 * but it's the best we can do. Writes and reads get
920 * combined.
921 */
922 [C(OP_READ)] = {
923 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
924 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
925 },
926 [C(OP_WRITE)] = {
927 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
928 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
929 },
930 [C(OP_PREFETCH)] = {
931 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
932 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
933 },
934 },
935 [C(L1I)] = {
936 [C(OP_READ)] = {
937 [C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ICACHE_ACCESS,
938 [C(RESULT_MISS)] = KRAIT_PERFCTR_L1_ICACHE_MISS,
939 },
940 [C(OP_WRITE)] = {
941 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
942 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
943 },
944 [C(OP_PREFETCH)] = {
945 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
946 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
947 },
948 },
949 [C(LL)] = {
950 [C(OP_READ)] = {
951 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
952 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
953 },
954 [C(OP_WRITE)] = {
955 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
956 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
957 },
958 [C(OP_PREFETCH)] = {
959 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
960 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
961 },
962 },
963 [C(DTLB)] = {
964 [C(OP_READ)] = {
965 [C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_DTLB_ACCESS,
966 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
967 },
968 [C(OP_WRITE)] = {
969 [C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_DTLB_ACCESS,
970 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
971 },
972 [C(OP_PREFETCH)] = {
973 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
974 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
975 },
976 },
977 [C(ITLB)] = {
978 [C(OP_READ)] = {
979 [C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ITLB_ACCESS,
980 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
981 },
982 [C(OP_WRITE)] = {
983 [C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ITLB_ACCESS,
984 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
985 },
986 [C(OP_PREFETCH)] = {
987 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
988 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
989 },
990 },
991 [C(BPU)] = {
992 [C(OP_READ)] = {
993 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
994 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
995 },
996 [C(OP_WRITE)] = {
997 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
998 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
999 },
1000 [C(OP_PREFETCH)] = {
1001 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1002 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1003 },
1004 },
1005 [C(NODE)] = {
1006 [C(OP_READ)] = {
1007 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1008 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1009 },
1010 [C(OP_WRITE)] = {
1011 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1012 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1013 },
1014 [C(OP_PREFETCH)] = {
1015 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1016 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1017 },
1018 },
1019};
1020
1021/*
735 * Perf Events' indices 1022 * Perf Events' indices
736 */ 1023 */
737#define ARMV7_IDX_CYCLE_COUNTER 0 1024#define ARMV7_IDX_CYCLE_COUNTER 0
@@ -1212,6 +1499,24 @@ static int armv7_a7_map_event(struct perf_event *event)
1212 &armv7_a7_perf_cache_map, 0xFF); 1499 &armv7_a7_perf_cache_map, 0xFF);
1213} 1500}
1214 1501
1502static int armv7_a12_map_event(struct perf_event *event)
1503{
1504 return armpmu_map_event(event, &armv7_a12_perf_map,
1505 &armv7_a12_perf_cache_map, 0xFF);
1506}
1507
1508static int krait_map_event(struct perf_event *event)
1509{
1510 return armpmu_map_event(event, &krait_perf_map,
1511 &krait_perf_cache_map, 0xFFFFF);
1512}
1513
1514static int krait_map_event_no_branch(struct perf_event *event)
1515{
1516 return armpmu_map_event(event, &krait_perf_map_no_branch,
1517 &krait_perf_cache_map, 0xFFFFF);
1518}
1519
1215static void armv7pmu_init(struct arm_pmu *cpu_pmu) 1520static void armv7pmu_init(struct arm_pmu *cpu_pmu)
1216{ 1521{
1217 cpu_pmu->handle_irq = armv7pmu_handle_irq; 1522 cpu_pmu->handle_irq = armv7pmu_handle_irq;
@@ -1283,6 +1588,408 @@ static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
1283 cpu_pmu->set_event_filter = armv7pmu_set_event_filter; 1588 cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
1284 return 0; 1589 return 0;
1285} 1590}
1591
1592static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
1593{
1594 armv7pmu_init(cpu_pmu);
1595 cpu_pmu->name = "ARMv7 Cortex-A12";
1596 cpu_pmu->map_event = armv7_a12_map_event;
1597 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1598 cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
1599 return 0;
1600}
1601
1602/*
1603 * Krait Performance Monitor Region Event Selection Register (PMRESRn)
1604 *
1605 * 31 30 24 16 8 0
1606 * +--------------------------------+
1607 * PMRESR0 | EN | CC | CC | CC | CC | N = 1, R = 0
1608 * +--------------------------------+
1609 * PMRESR1 | EN | CC | CC | CC | CC | N = 1, R = 1
1610 * +--------------------------------+
1611 * PMRESR2 | EN | CC | CC | CC | CC | N = 1, R = 2
1612 * +--------------------------------+
1613 * VPMRESR0 | EN | CC | CC | CC | CC | N = 2, R = ?
1614 * +--------------------------------+
1615 * EN | G=3 | G=2 | G=1 | G=0
1616 *
1617 * Event Encoding:
1618 *
1619 * hwc->config_base = 0xNRCCG
1620 *
1621 * N = prefix, 1 for Krait CPU (PMRESRn), 2 for Venum VFP (VPMRESR)
1622 * R = region register
1623 * CC = class of events the group G is choosing from
1624 * G = group or particular event
1625 *
1626 * Example: 0x12021 is a Krait CPU event in PMRESR2's group 1 with code 2
1627 *
1628 * A region (R) corresponds to a piece of the CPU (execution unit, instruction
1629 * unit, etc.) while the event code (CC) corresponds to a particular class of
1630 * events (interrupts for example). An event code is broken down into
1631 * groups (G) that can be mapped into the PMU (irq, fiqs, and irq+fiqs for
1632 * example).
1633 */
1634
1635#define KRAIT_EVENT (1 << 16)
1636#define VENUM_EVENT (2 << 16)
1637#define KRAIT_EVENT_MASK (KRAIT_EVENT | VENUM_EVENT)
1638#define PMRESRn_EN BIT(31)
1639
1640static u32 krait_read_pmresrn(int n)
1641{
1642 u32 val;
1643
1644 switch (n) {
1645 case 0:
1646 asm volatile("mrc p15, 1, %0, c9, c15, 0" : "=r" (val));
1647 break;
1648 case 1:
1649 asm volatile("mrc p15, 1, %0, c9, c15, 1" : "=r" (val));
1650 break;
1651 case 2:
1652 asm volatile("mrc p15, 1, %0, c9, c15, 2" : "=r" (val));
1653 break;
1654 default:
1655 BUG(); /* Should be validated in krait_pmu_get_event_idx() */
1656 }
1657
1658 return val;
1659}
1660
1661static void krait_write_pmresrn(int n, u32 val)
1662{
1663 switch (n) {
1664 case 0:
1665 asm volatile("mcr p15, 1, %0, c9, c15, 0" : : "r" (val));
1666 break;
1667 case 1:
1668 asm volatile("mcr p15, 1, %0, c9, c15, 1" : : "r" (val));
1669 break;
1670 case 2:
1671 asm volatile("mcr p15, 1, %0, c9, c15, 2" : : "r" (val));
1672 break;
1673 default:
1674 BUG(); /* Should be validated in krait_pmu_get_event_idx() */
1675 }
1676}
1677
1678static u32 krait_read_vpmresr0(void)
1679{
1680 u32 val;
1681 asm volatile("mrc p10, 7, %0, c11, c0, 0" : "=r" (val));
1682 return val;
1683}
1684
1685static void krait_write_vpmresr0(u32 val)
1686{
1687 asm volatile("mcr p10, 7, %0, c11, c0, 0" : : "r" (val));
1688}
1689
1690static void krait_pre_vpmresr0(u32 *venum_orig_val, u32 *fp_orig_val)
1691{
1692 u32 venum_new_val;
1693 u32 fp_new_val;
1694
1695 BUG_ON(preemptible());
1696 /* CPACR Enable CP10 and CP11 access */
1697 *venum_orig_val = get_copro_access();
1698 venum_new_val = *venum_orig_val | CPACC_SVC(10) | CPACC_SVC(11);
1699 set_copro_access(venum_new_val);
1700
1701 /* Enable FPEXC */
1702 *fp_orig_val = fmrx(FPEXC);
1703 fp_new_val = *fp_orig_val | FPEXC_EN;
1704 fmxr(FPEXC, fp_new_val);
1705}
1706
1707static void krait_post_vpmresr0(u32 venum_orig_val, u32 fp_orig_val)
1708{
1709 BUG_ON(preemptible());
1710 /* Restore FPEXC */
1711 fmxr(FPEXC, fp_orig_val);
1712 isb();
1713 /* Restore CPACR */
1714 set_copro_access(venum_orig_val);
1715}
1716
1717static u32 krait_get_pmresrn_event(unsigned int region)
1718{
1719 static const u32 pmresrn_table[] = { KRAIT_PMRESR0_GROUP0,
1720 KRAIT_PMRESR1_GROUP0,
1721 KRAIT_PMRESR2_GROUP0 };
1722 return pmresrn_table[region];
1723}
1724
1725static void krait_evt_setup(int idx, u32 config_base)
1726{
1727 u32 val;
1728 u32 mask;
1729 u32 vval, fval;
1730 unsigned int region;
1731 unsigned int group;
1732 unsigned int code;
1733 unsigned int group_shift;
1734 bool venum_event;
1735
1736 venum_event = !!(config_base & VENUM_EVENT);
1737 region = (config_base >> 12) & 0xf;
1738 code = (config_base >> 4) & 0xff;
1739 group = (config_base >> 0) & 0xf;
1740
1741 group_shift = group * 8;
1742 mask = 0xff << group_shift;
1743
1744 /* Configure evtsel for the region and group */
1745 if (venum_event)
1746 val = KRAIT_VPMRESR0_GROUP0;
1747 else
1748 val = krait_get_pmresrn_event(region);
1749 val += group;
1750 /* Mix in mode-exclusion bits */
1751 val |= config_base & (ARMV7_EXCLUDE_USER | ARMV7_EXCLUDE_PL1);
1752 armv7_pmnc_write_evtsel(idx, val);
1753
1754 asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
1755
1756 if (venum_event) {
1757 krait_pre_vpmresr0(&vval, &fval);
1758 val = krait_read_vpmresr0();
1759 val &= ~mask;
1760 val |= code << group_shift;
1761 val |= PMRESRn_EN;
1762 krait_write_vpmresr0(val);
1763 krait_post_vpmresr0(vval, fval);
1764 } else {
1765 val = krait_read_pmresrn(region);
1766 val &= ~mask;
1767 val |= code << group_shift;
1768 val |= PMRESRn_EN;
1769 krait_write_pmresrn(region, val);
1770 }
1771}
1772
1773static u32 krait_clear_pmresrn_group(u32 val, int group)
1774{
1775 u32 mask;
1776 int group_shift;
1777
1778 group_shift = group * 8;
1779 mask = 0xff << group_shift;
1780 val &= ~mask;
1781
1782 /* Don't clear enable bit if entire region isn't disabled */
1783 if (val & ~PMRESRn_EN)
1784 return val |= PMRESRn_EN;
1785
1786 return 0;
1787}
1788
1789static void krait_clearpmu(u32 config_base)
1790{
1791 u32 val;
1792 u32 vval, fval;
1793 unsigned int region;
1794 unsigned int group;
1795 bool venum_event;
1796
1797 venum_event = !!(config_base & VENUM_EVENT);
1798 region = (config_base >> 12) & 0xf;
1799 group = (config_base >> 0) & 0xf;
1800
1801 if (venum_event) {
1802 krait_pre_vpmresr0(&vval, &fval);
1803 val = krait_read_vpmresr0();
1804 val = krait_clear_pmresrn_group(val, group);
1805 krait_write_vpmresr0(val);
1806 krait_post_vpmresr0(vval, fval);
1807 } else {
1808 val = krait_read_pmresrn(region);
1809 val = krait_clear_pmresrn_group(val, group);
1810 krait_write_pmresrn(region, val);
1811 }
1812}
1813
1814static void krait_pmu_disable_event(struct perf_event *event)
1815{
1816 unsigned long flags;
1817 struct hw_perf_event *hwc = &event->hw;
1818 int idx = hwc->idx;
1819 struct pmu_hw_events *events = cpu_pmu->get_hw_events();
1820
1821 /* Disable counter and interrupt */
1822 raw_spin_lock_irqsave(&events->pmu_lock, flags);
1823
1824 /* Disable counter */
1825 armv7_pmnc_disable_counter(idx);
1826
1827 /*
1828 * Clear pmresr code (if destined for PMNx counters)
1829 */
1830 if (hwc->config_base & KRAIT_EVENT_MASK)
1831 krait_clearpmu(hwc->config_base);
1832
1833 /* Disable interrupt for this counter */
1834 armv7_pmnc_disable_intens(idx);
1835
1836 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1837}
1838
1839static void krait_pmu_enable_event(struct perf_event *event)
1840{
1841 unsigned long flags;
1842 struct hw_perf_event *hwc = &event->hw;
1843 int idx = hwc->idx;
1844 struct pmu_hw_events *events = cpu_pmu->get_hw_events();
1845
1846 /*
1847 * Enable counter and interrupt, and set the counter to count
1848 * the event that we're interested in.
1849 */
1850 raw_spin_lock_irqsave(&events->pmu_lock, flags);
1851
1852 /* Disable counter */
1853 armv7_pmnc_disable_counter(idx);
1854
1855 /*
1856 * Set event (if destined for PMNx counters)
1857 * We set the event for the cycle counter because we
1858 * have the ability to perform event filtering.
1859 */
1860 if (hwc->config_base & KRAIT_EVENT_MASK)
1861 krait_evt_setup(idx, hwc->config_base);
1862 else
1863 armv7_pmnc_write_evtsel(idx, hwc->config_base);
1864
1865 /* Enable interrupt for this counter */
1866 armv7_pmnc_enable_intens(idx);
1867
1868 /* Enable counter */
1869 armv7_pmnc_enable_counter(idx);
1870
1871 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
1872}
1873
1874static void krait_pmu_reset(void *info)
1875{
1876 u32 vval, fval;
1877
1878 armv7pmu_reset(info);
1879
1880 /* Clear all pmresrs */
1881 krait_write_pmresrn(0, 0);
1882 krait_write_pmresrn(1, 0);
1883 krait_write_pmresrn(2, 0);
1884
1885 krait_pre_vpmresr0(&vval, &fval);
1886 krait_write_vpmresr0(0);
1887 krait_post_vpmresr0(vval, fval);
1888}
1889
1890static int krait_event_to_bit(struct perf_event *event, unsigned int region,
1891 unsigned int group)
1892{
1893 int bit;
1894 struct hw_perf_event *hwc = &event->hw;
1895 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
1896
1897 if (hwc->config_base & VENUM_EVENT)
1898 bit = KRAIT_VPMRESR0_GROUP0;
1899 else
1900 bit = krait_get_pmresrn_event(region);
1901 bit -= krait_get_pmresrn_event(0);
1902 bit += group;
1903 /*
1904 * Lower bits are reserved for use by the counters (see
1905 * armv7pmu_get_event_idx() for more info)
1906 */
1907 bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1;
1908
1909 return bit;
1910}
1911
1912/*
1913 * We check for column exclusion constraints here.
1914 * Two events cant use the same group within a pmresr register.
1915 */
1916static int krait_pmu_get_event_idx(struct pmu_hw_events *cpuc,
1917 struct perf_event *event)
1918{
1919 int idx;
1920 int bit;
1921 unsigned int prefix;
1922 unsigned int region;
1923 unsigned int code;
1924 unsigned int group;
1925 bool krait_event;
1926 struct hw_perf_event *hwc = &event->hw;
1927
1928 region = (hwc->config_base >> 12) & 0xf;
1929 code = (hwc->config_base >> 4) & 0xff;
1930 group = (hwc->config_base >> 0) & 0xf;
1931 krait_event = !!(hwc->config_base & KRAIT_EVENT_MASK);
1932
1933 if (krait_event) {
1934 /* Ignore invalid events */
1935 if (group > 3 || region > 2)
1936 return -EINVAL;
1937 prefix = hwc->config_base & KRAIT_EVENT_MASK;
1938 if (prefix != KRAIT_EVENT && prefix != VENUM_EVENT)
1939 return -EINVAL;
1940 if (prefix == VENUM_EVENT && (code & 0xe0))
1941 return -EINVAL;
1942
1943 bit = krait_event_to_bit(event, region, group);
1944 if (test_and_set_bit(bit, cpuc->used_mask))
1945 return -EAGAIN;
1946 }
1947
1948 idx = armv7pmu_get_event_idx(cpuc, event);
1949 if (idx < 0 && krait_event)
1950 clear_bit(bit, cpuc->used_mask);
1951
1952 return idx;
1953}
1954
1955static void krait_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
1956 struct perf_event *event)
1957{
1958 int bit;
1959 struct hw_perf_event *hwc = &event->hw;
1960 unsigned int region;
1961 unsigned int group;
1962 bool krait_event;
1963
1964 region = (hwc->config_base >> 12) & 0xf;
1965 group = (hwc->config_base >> 0) & 0xf;
1966 krait_event = !!(hwc->config_base & KRAIT_EVENT_MASK);
1967
1968 if (krait_event) {
1969 bit = krait_event_to_bit(event, region, group);
1970 clear_bit(bit, cpuc->used_mask);
1971 }
1972}
1973
1974static int krait_pmu_init(struct arm_pmu *cpu_pmu)
1975{
1976 armv7pmu_init(cpu_pmu);
1977 cpu_pmu->name = "ARMv7 Krait";
1978 /* Some early versions of Krait don't support PC write events */
1979 if (of_property_read_bool(cpu_pmu->plat_device->dev.of_node,
1980 "qcom,no-pc-write"))
1981 cpu_pmu->map_event = krait_map_event_no_branch;
1982 else
1983 cpu_pmu->map_event = krait_map_event;
1984 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1985 cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
1986 cpu_pmu->reset = krait_pmu_reset;
1987 cpu_pmu->enable = krait_pmu_enable_event;
1988 cpu_pmu->disable = krait_pmu_disable_event;
1989 cpu_pmu->get_event_idx = krait_pmu_get_event_idx;
1990 cpu_pmu->clear_event_idx = krait_pmu_clear_event_idx;
1991 return 0;
1992}
1286#else 1993#else
1287static inline int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu) 1994static inline int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
1288{ 1995{
@@ -1308,4 +2015,14 @@ static inline int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
1308{ 2015{
1309 return -ENODEV; 2016 return -ENODEV;
1310} 2017}
2018
2019static inline int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
2020{
2021 return -ENODEV;
2022}
2023
2024static inline int krait_pmu_init(struct arm_pmu *cpu_pmu)
2025{
2026 return -ENODEV;
2027}
1311#endif /* CONFIG_CPU_V7 */ 2028#endif /* CONFIG_CPU_V7 */
diff --git a/arch/arm/kernel/probes-arm.c b/arch/arm/kernel/probes-arm.c
new file mode 100644
index 000000000000..51a13a027989
--- /dev/null
+++ b/arch/arm/kernel/probes-arm.c
@@ -0,0 +1,734 @@
1/*
2 * arch/arm/kernel/probes-arm.c
3 *
4 * Some code moved here from arch/arm/kernel/kprobes-arm.c
5 *
6 * Copyright (C) 2006, 2007 Motorola Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/stddef.h>
21#include <linux/ptrace.h>
22
23#include "probes.h"
24#include "probes-arm.h"
25
26#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
27
28#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
29
30/*
31 * To avoid the complications of mimicing single-stepping on a
32 * processor without a Next-PC or a single-step mode, and to
33 * avoid having to deal with the side-effects of boosting, we
34 * simulate or emulate (almost) all ARM instructions.
35 *
36 * "Simulation" is where the instruction's behavior is duplicated in
37 * C code. "Emulation" is where the original instruction is rewritten
38 * and executed, often by altering its registers.
39 *
40 * By having all behavior of the kprobe'd instruction completed before
41 * returning from the kprobe_handler(), all locks (scheduler and
42 * interrupt) can safely be released. There is no need for secondary
43 * breakpoints, no race with MP or preemptable kernels, nor having to
44 * clean up resources counts at a later time impacting overall system
45 * performance. By rewriting the instruction, only the minimum registers
46 * need to be loaded and saved back optimizing performance.
47 *
48 * Calling the insnslot_*_rwflags version of a function doesn't hurt
49 * anything even when the CPSR flags aren't updated by the
50 * instruction. It's just a little slower in return for saving
51 * a little space by not having a duplicate function that doesn't
52 * update the flags. (The same optimization can be said for
53 * instructions that do or don't perform register writeback)
54 * Also, instructions can either read the flags, only write the
55 * flags, or read and write the flags. To save combinations
56 * rather than for sheer performance, flag functions just assume
57 * read and write of flags.
58 */
59
60void __kprobes simulate_bbl(probes_opcode_t insn,
61 struct arch_probes_insn *asi, struct pt_regs *regs)
62{
63 long iaddr = (long) regs->ARM_pc - 4;
64 int disp = branch_displacement(insn);
65
66 if (insn & (1 << 24))
67 regs->ARM_lr = iaddr + 4;
68
69 regs->ARM_pc = iaddr + 8 + disp;
70}
71
72void __kprobes simulate_blx1(probes_opcode_t insn,
73 struct arch_probes_insn *asi, struct pt_regs *regs)
74{
75 long iaddr = (long) regs->ARM_pc - 4;
76 int disp = branch_displacement(insn);
77
78 regs->ARM_lr = iaddr + 4;
79 regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2);
80 regs->ARM_cpsr |= PSR_T_BIT;
81}
82
83void __kprobes simulate_blx2bx(probes_opcode_t insn,
84 struct arch_probes_insn *asi, struct pt_regs *regs)
85{
86 int rm = insn & 0xf;
87 long rmv = regs->uregs[rm];
88
89 if (insn & (1 << 5))
90 regs->ARM_lr = (long) regs->ARM_pc;
91
92 regs->ARM_pc = rmv & ~0x1;
93 regs->ARM_cpsr &= ~PSR_T_BIT;
94 if (rmv & 0x1)
95 regs->ARM_cpsr |= PSR_T_BIT;
96}
97
98void __kprobes simulate_mrs(probes_opcode_t insn,
99 struct arch_probes_insn *asi, struct pt_regs *regs)
100{
101 int rd = (insn >> 12) & 0xf;
102 unsigned long mask = 0xf8ff03df; /* Mask out execution state */
103 regs->uregs[rd] = regs->ARM_cpsr & mask;
104}
105
106void __kprobes simulate_mov_ipsp(probes_opcode_t insn,
107 struct arch_probes_insn *asi, struct pt_regs *regs)
108{
109 regs->uregs[12] = regs->uregs[13];
110}
111
112/*
113 * For the instruction masking and comparisons in all the "space_*"
114 * functions below, Do _not_ rearrange the order of tests unless
115 * you're very, very sure of what you are doing. For the sake of
116 * efficiency, the masks for some tests sometimes assume other test
117 * have been done prior to them so the number of patterns to test
118 * for an instruction set can be as broad as possible to reduce the
119 * number of tests needed.
120 */
121
122static const union decode_item arm_1111_table[] = {
123 /* Unconditional instructions */
124
125 /* memory hint 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx */
126 /* PLDI (immediate) 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx */
127 /* PLDW (immediate) 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx */
128 /* PLD (immediate) 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx */
129 DECODE_SIMULATE (0xfe300000, 0xf4100000, PROBES_PRELOAD_IMM),
130
131 /* memory hint 1111 0110 x001 xxxx xxxx xxxx xxx0 xxxx */
132 /* PLDI (register) 1111 0110 x101 xxxx xxxx xxxx xxx0 xxxx */
133 /* PLDW (register) 1111 0111 x001 xxxx xxxx xxxx xxx0 xxxx */
134 /* PLD (register) 1111 0111 x101 xxxx xxxx xxxx xxx0 xxxx */
135 DECODE_SIMULATE (0xfe300010, 0xf6100000, PROBES_PRELOAD_REG),
136
137 /* BLX (immediate) 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx */
138 DECODE_SIMULATE (0xfe000000, 0xfa000000, PROBES_BRANCH_IMM),
139
140 /* CPS 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */
141 /* SETEND 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
142 /* SRS 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
143 /* RFE 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
144
145 /* Coprocessor instructions... */
146 /* MCRR2 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx */
147 /* MRRC2 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx */
148 /* LDC2 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
149 /* STC2 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
150 /* CDP2 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
151 /* MCR2 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
152 /* MRC2 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
153
154 /* Other unallocated instructions... */
155 DECODE_END
156};
157
158static const union decode_item arm_cccc_0001_0xx0____0xxx_table[] = {
159 /* Miscellaneous instructions */
160
161 /* MRS cpsr cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
162 DECODE_SIMULATEX(0x0ff000f0, 0x01000000, PROBES_MRS,
163 REGS(0, NOPC, 0, 0, 0)),
164
165 /* BX cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
166 DECODE_SIMULATE (0x0ff000f0, 0x01200010, PROBES_BRANCH_REG),
167
168 /* BLX (register) cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
169 DECODE_SIMULATEX(0x0ff000f0, 0x01200030, PROBES_BRANCH_REG,
170 REGS(0, 0, 0, 0, NOPC)),
171
172 /* CLZ cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
173 DECODE_EMULATEX (0x0ff000f0, 0x01600010, PROBES_CLZ,
174 REGS(0, NOPC, 0, 0, NOPC)),
175
176 /* QADD cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx */
177 /* QSUB cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx */
178 /* QDADD cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx */
179 /* QDSUB cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx */
180 DECODE_EMULATEX (0x0f9000f0, 0x01000050, PROBES_SATURATING_ARITHMETIC,
181 REGS(NOPC, NOPC, 0, 0, NOPC)),
182
183 /* BXJ cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
184 /* MSR cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
185 /* MRS spsr cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */
186 /* BKPT 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
187 /* SMC cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
188 /* And unallocated instructions... */
189 DECODE_END
190};
191
192static const union decode_item arm_cccc_0001_0xx0____1xx0_table[] = {
193 /* Halfword multiply and multiply-accumulate */
194
195 /* SMLALxy cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
196 DECODE_EMULATEX (0x0ff00090, 0x01400080, PROBES_MUL1,
197 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
198
199 /* SMULWy cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
200 DECODE_OR (0x0ff000b0, 0x012000a0),
201 /* SMULxy cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
202 DECODE_EMULATEX (0x0ff00090, 0x01600080, PROBES_MUL2,
203 REGS(NOPC, 0, NOPC, 0, NOPC)),
204
205 /* SMLAxy cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx */
206 DECODE_OR (0x0ff00090, 0x01000080),
207 /* SMLAWy cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx */
208 DECODE_EMULATEX (0x0ff000b0, 0x01200080, PROBES_MUL2,
209 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
210
211 DECODE_END
212};
213
214static const union decode_item arm_cccc_0000_____1001_table[] = {
215 /* Multiply and multiply-accumulate */
216
217 /* MUL cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx */
218 /* MULS cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx */
219 DECODE_EMULATEX (0x0fe000f0, 0x00000090, PROBES_MUL2,
220 REGS(NOPC, 0, NOPC, 0, NOPC)),
221
222 /* MLA cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx */
223 /* MLAS cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx */
224 DECODE_OR (0x0fe000f0, 0x00200090),
225 /* MLS cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx */
226 DECODE_EMULATEX (0x0ff000f0, 0x00600090, PROBES_MUL2,
227 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
228
229 /* UMAAL cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx */
230 DECODE_OR (0x0ff000f0, 0x00400090),
231 /* UMULL cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx */
232 /* UMULLS cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx */
233 /* UMLAL cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx */
234 /* UMLALS cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx */
235 /* SMULL cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx */
236 /* SMULLS cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx */
237 /* SMLAL cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx */
238 /* SMLALS cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx */
239 DECODE_EMULATEX (0x0f8000f0, 0x00800090, PROBES_MUL1,
240 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
241
242 DECODE_END
243};
244
245static const union decode_item arm_cccc_0001_____1001_table[] = {
246 /* Synchronization primitives */
247
248#if __LINUX_ARM_ARCH__ < 6
249 /* Deprecated on ARMv6 and may be UNDEFINED on v7 */
250 /* SMP/SWPB cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
251 DECODE_EMULATEX (0x0fb000f0, 0x01000090, PROBES_SWP,
252 REGS(NOPC, NOPC, 0, 0, NOPC)),
253#endif
254 /* LDREX/STREX{,D,B,H} cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
255 /* And unallocated instructions... */
256 DECODE_END
257};
258
259static const union decode_item arm_cccc_000x_____1xx1_table[] = {
260 /* Extra load/store instructions */
261
262 /* STRHT cccc 0000 xx10 xxxx xxxx xxxx 1011 xxxx */
263 /* ??? cccc 0000 xx10 xxxx xxxx xxxx 11x1 xxxx */
264 /* LDRHT cccc 0000 xx11 xxxx xxxx xxxx 1011 xxxx */
265 /* LDRSBT cccc 0000 xx11 xxxx xxxx xxxx 1101 xxxx */
266 /* LDRSHT cccc 0000 xx11 xxxx xxxx xxxx 1111 xxxx */
267 DECODE_REJECT (0x0f200090, 0x00200090),
268
269 /* LDRD/STRD lr,pc,{... cccc 000x x0x0 xxxx 111x xxxx 1101 xxxx */
270 DECODE_REJECT (0x0e10e0d0, 0x0000e0d0),
271
272 /* LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx */
273 /* STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx */
274 DECODE_EMULATEX (0x0e5000d0, 0x000000d0, PROBES_LDRSTRD,
275 REGS(NOPCWB, NOPCX, 0, 0, NOPC)),
276
277 /* LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx */
278 /* STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx */
279 DECODE_EMULATEX (0x0e5000d0, 0x004000d0, PROBES_LDRSTRD,
280 REGS(NOPCWB, NOPCX, 0, 0, 0)),
281
282 /* STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx */
283 DECODE_EMULATEX (0x0e5000f0, 0x000000b0, PROBES_STORE_EXTRA,
284 REGS(NOPCWB, NOPC, 0, 0, NOPC)),
285
286 /* LDRH (register) cccc 000x x0x1 xxxx xxxx xxxx 1011 xxxx */
287 /* LDRSB (register) cccc 000x x0x1 xxxx xxxx xxxx 1101 xxxx */
288 /* LDRSH (register) cccc 000x x0x1 xxxx xxxx xxxx 1111 xxxx */
289 DECODE_EMULATEX (0x0e500090, 0x00100090, PROBES_LOAD_EXTRA,
290 REGS(NOPCWB, NOPC, 0, 0, NOPC)),
291
292 /* STRH (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1011 xxxx */
293 DECODE_EMULATEX (0x0e5000f0, 0x004000b0, PROBES_STORE_EXTRA,
294 REGS(NOPCWB, NOPC, 0, 0, 0)),
295
296 /* LDRH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1011 xxxx */
297 /* LDRSB (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1101 xxxx */
298 /* LDRSH (immediate) cccc 000x x1x1 xxxx xxxx xxxx 1111 xxxx */
299 DECODE_EMULATEX (0x0e500090, 0x00500090, PROBES_LOAD_EXTRA,
300 REGS(NOPCWB, NOPC, 0, 0, 0)),
301
302 DECODE_END
303};
304
305static const union decode_item arm_cccc_000x_table[] = {
306 /* Data-processing (register) */
307
308 /* <op>S PC, ... cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx */
309 DECODE_REJECT (0x0e10f000, 0x0010f000),
310
311 /* MOV IP, SP 1110 0001 1010 0000 1100 0000 0000 1101 */
312 DECODE_SIMULATE (0xffffffff, 0xe1a0c00d, PROBES_MOV_IP_SP),
313
314 /* TST (register) cccc 0001 0001 xxxx xxxx xxxx xxx0 xxxx */
315 /* TEQ (register) cccc 0001 0011 xxxx xxxx xxxx xxx0 xxxx */
316 /* CMP (register) cccc 0001 0101 xxxx xxxx xxxx xxx0 xxxx */
317 /* CMN (register) cccc 0001 0111 xxxx xxxx xxxx xxx0 xxxx */
318 DECODE_EMULATEX (0x0f900010, 0x01100000, PROBES_DATA_PROCESSING_REG,
319 REGS(ANY, 0, 0, 0, ANY)),
320
321 /* MOV (register) cccc 0001 101x xxxx xxxx xxxx xxx0 xxxx */
322 /* MVN (register) cccc 0001 111x xxxx xxxx xxxx xxx0 xxxx */
323 DECODE_EMULATEX (0x0fa00010, 0x01a00000, PROBES_DATA_PROCESSING_REG,
324 REGS(0, ANY, 0, 0, ANY)),
325
326 /* AND (register) cccc 0000 000x xxxx xxxx xxxx xxx0 xxxx */
327 /* EOR (register) cccc 0000 001x xxxx xxxx xxxx xxx0 xxxx */
328 /* SUB (register) cccc 0000 010x xxxx xxxx xxxx xxx0 xxxx */
329 /* RSB (register) cccc 0000 011x xxxx xxxx xxxx xxx0 xxxx */
330 /* ADD (register) cccc 0000 100x xxxx xxxx xxxx xxx0 xxxx */
331 /* ADC (register) cccc 0000 101x xxxx xxxx xxxx xxx0 xxxx */
332 /* SBC (register) cccc 0000 110x xxxx xxxx xxxx xxx0 xxxx */
333 /* RSC (register) cccc 0000 111x xxxx xxxx xxxx xxx0 xxxx */
334 /* ORR (register) cccc 0001 100x xxxx xxxx xxxx xxx0 xxxx */
335 /* BIC (register) cccc 0001 110x xxxx xxxx xxxx xxx0 xxxx */
336 DECODE_EMULATEX (0x0e000010, 0x00000000, PROBES_DATA_PROCESSING_REG,
337 REGS(ANY, ANY, 0, 0, ANY)),
338
339 /* TST (reg-shift reg) cccc 0001 0001 xxxx xxxx xxxx 0xx1 xxxx */
340 /* TEQ (reg-shift reg) cccc 0001 0011 xxxx xxxx xxxx 0xx1 xxxx */
341 /* CMP (reg-shift reg) cccc 0001 0101 xxxx xxxx xxxx 0xx1 xxxx */
342 /* CMN (reg-shift reg) cccc 0001 0111 xxxx xxxx xxxx 0xx1 xxxx */
343 DECODE_EMULATEX (0x0f900090, 0x01100010, PROBES_DATA_PROCESSING_REG,
344 REGS(ANY, 0, NOPC, 0, ANY)),
345
346 /* MOV (reg-shift reg) cccc 0001 101x xxxx xxxx xxxx 0xx1 xxxx */
347 /* MVN (reg-shift reg) cccc 0001 111x xxxx xxxx xxxx 0xx1 xxxx */
348 DECODE_EMULATEX (0x0fa00090, 0x01a00010, PROBES_DATA_PROCESSING_REG,
349 REGS(0, ANY, NOPC, 0, ANY)),
350
351 /* AND (reg-shift reg) cccc 0000 000x xxxx xxxx xxxx 0xx1 xxxx */
352 /* EOR (reg-shift reg) cccc 0000 001x xxxx xxxx xxxx 0xx1 xxxx */
353 /* SUB (reg-shift reg) cccc 0000 010x xxxx xxxx xxxx 0xx1 xxxx */
354 /* RSB (reg-shift reg) cccc 0000 011x xxxx xxxx xxxx 0xx1 xxxx */
355 /* ADD (reg-shift reg) cccc 0000 100x xxxx xxxx xxxx 0xx1 xxxx */
356 /* ADC (reg-shift reg) cccc 0000 101x xxxx xxxx xxxx 0xx1 xxxx */
357 /* SBC (reg-shift reg) cccc 0000 110x xxxx xxxx xxxx 0xx1 xxxx */
358 /* RSC (reg-shift reg) cccc 0000 111x xxxx xxxx xxxx 0xx1 xxxx */
359 /* ORR (reg-shift reg) cccc 0001 100x xxxx xxxx xxxx 0xx1 xxxx */
360 /* BIC (reg-shift reg) cccc 0001 110x xxxx xxxx xxxx 0xx1 xxxx */
361 DECODE_EMULATEX (0x0e000090, 0x00000010, PROBES_DATA_PROCESSING_REG,
362 REGS(ANY, ANY, NOPC, 0, ANY)),
363
364 DECODE_END
365};
366
367static const union decode_item arm_cccc_001x_table[] = {
368 /* Data-processing (immediate) */
369
370 /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
371 /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
372 DECODE_EMULATEX (0x0fb00000, 0x03000000, PROBES_DATA_PROCESSING_IMM,
373 REGS(0, NOPC, 0, 0, 0)),
374
375 /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
376 DECODE_OR (0x0fff00ff, 0x03200001),
377 /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
378 DECODE_EMULATE (0x0fff00ff, 0x03200004, PROBES_EMULATE_NONE),
379 /* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
380 /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
381 /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
382 DECODE_SIMULATE (0x0fff00fc, 0x03200000, PROBES_SIMULATE_NOP),
383 /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */
384 /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
385 /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
386 DECODE_REJECT (0x0fb00000, 0x03200000),
387
388 /* <op>S PC, ... cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */
389 DECODE_REJECT (0x0e10f000, 0x0210f000),
390
391 /* TST (immediate) cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx */
392 /* TEQ (immediate) cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx */
393 /* CMP (immediate) cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx */
394 /* CMN (immediate) cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx */
395 DECODE_EMULATEX (0x0f900000, 0x03100000, PROBES_DATA_PROCESSING_IMM,
396 REGS(ANY, 0, 0, 0, 0)),
397
398 /* MOV (immediate) cccc 0011 101x xxxx xxxx xxxx xxxx xxxx */
399 /* MVN (immediate) cccc 0011 111x xxxx xxxx xxxx xxxx xxxx */
400 DECODE_EMULATEX (0x0fa00000, 0x03a00000, PROBES_DATA_PROCESSING_IMM,
401 REGS(0, ANY, 0, 0, 0)),
402
403 /* AND (immediate) cccc 0010 000x xxxx xxxx xxxx xxxx xxxx */
404 /* EOR (immediate) cccc 0010 001x xxxx xxxx xxxx xxxx xxxx */
405 /* SUB (immediate) cccc 0010 010x xxxx xxxx xxxx xxxx xxxx */
406 /* RSB (immediate) cccc 0010 011x xxxx xxxx xxxx xxxx xxxx */
407 /* ADD (immediate) cccc 0010 100x xxxx xxxx xxxx xxxx xxxx */
408 /* ADC (immediate) cccc 0010 101x xxxx xxxx xxxx xxxx xxxx */
409 /* SBC (immediate) cccc 0010 110x xxxx xxxx xxxx xxxx xxxx */
410 /* RSC (immediate) cccc 0010 111x xxxx xxxx xxxx xxxx xxxx */
411 /* ORR (immediate) cccc 0011 100x xxxx xxxx xxxx xxxx xxxx */
412 /* BIC (immediate) cccc 0011 110x xxxx xxxx xxxx xxxx xxxx */
413 DECODE_EMULATEX (0x0e000000, 0x02000000, PROBES_DATA_PROCESSING_IMM,
414 REGS(ANY, ANY, 0, 0, 0)),
415
416 DECODE_END
417};
418
419static const union decode_item arm_cccc_0110_____xxx1_table[] = {
420 /* Media instructions */
421
422 /* SEL cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx */
423 DECODE_EMULATEX (0x0ff000f0, 0x068000b0, PROBES_SATURATE,
424 REGS(NOPC, NOPC, 0, 0, NOPC)),
425
426 /* SSAT cccc 0110 101x xxxx xxxx xxxx xx01 xxxx */
427 /* USAT cccc 0110 111x xxxx xxxx xxxx xx01 xxxx */
428 DECODE_OR(0x0fa00030, 0x06a00010),
429 /* SSAT16 cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx */
430 /* USAT16 cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx */
431 DECODE_EMULATEX (0x0fb000f0, 0x06a00030, PROBES_SATURATE,
432 REGS(0, NOPC, 0, 0, NOPC)),
433
434 /* REV cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
435 /* REV16 cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
436 /* RBIT cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
437 /* REVSH cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
438 DECODE_EMULATEX (0x0fb00070, 0x06b00030, PROBES_REV,
439 REGS(0, NOPC, 0, 0, NOPC)),
440
441 /* ??? cccc 0110 0x00 xxxx xxxx xxxx xxx1 xxxx */
442 DECODE_REJECT (0x0fb00010, 0x06000010),
443 /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1011 xxxx */
444 DECODE_REJECT (0x0f8000f0, 0x060000b0),
445 /* ??? cccc 0110 0xxx xxxx xxxx xxxx 1101 xxxx */
446 DECODE_REJECT (0x0f8000f0, 0x060000d0),
447 /* SADD16 cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx */
448 /* SADDSUBX cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx */
449 /* SSUBADDX cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx */
450 /* SSUB16 cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx */
451 /* SADD8 cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx */
452 /* SSUB8 cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx */
453 /* QADD16 cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx */
454 /* QADDSUBX cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx */
455 /* QSUBADDX cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx */
456 /* QSUB16 cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx */
457 /* QADD8 cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx */
458 /* QSUB8 cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx */
459 /* SHADD16 cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx */
460 /* SHADDSUBX cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx */
461 /* SHSUBADDX cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx */
462 /* SHSUB16 cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx */
463 /* SHADD8 cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx */
464 /* SHSUB8 cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx */
465 /* UADD16 cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx */
466 /* UADDSUBX cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx */
467 /* USUBADDX cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx */
468 /* USUB16 cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx */
469 /* UADD8 cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx */
470 /* USUB8 cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx */
471 /* UQADD16 cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx */
472 /* UQADDSUBX cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx */
473 /* UQSUBADDX cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx */
474 /* UQSUB16 cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx */
475 /* UQADD8 cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx */
476 /* UQSUB8 cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx */
477 /* UHADD16 cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx */
478 /* UHADDSUBX cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx */
479 /* UHSUBADDX cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx */
480 /* UHSUB16 cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx */
481 /* UHADD8 cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx */
482 /* UHSUB8 cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx */
483 DECODE_EMULATEX (0x0f800010, 0x06000010, PROBES_MMI,
484 REGS(NOPC, NOPC, 0, 0, NOPC)),
485
486 /* PKHBT cccc 0110 1000 xxxx xxxx xxxx x001 xxxx */
487 /* PKHTB cccc 0110 1000 xxxx xxxx xxxx x101 xxxx */
488 DECODE_EMULATEX (0x0ff00030, 0x06800010, PROBES_PACK,
489 REGS(NOPC, NOPC, 0, 0, NOPC)),
490
491 /* ??? cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx */
492 /* ??? cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx */
493 DECODE_REJECT (0x0fb000f0, 0x06900070),
494
495 /* SXTB16 cccc 0110 1000 1111 xxxx xxxx 0111 xxxx */
496 /* SXTB cccc 0110 1010 1111 xxxx xxxx 0111 xxxx */
497 /* SXTH cccc 0110 1011 1111 xxxx xxxx 0111 xxxx */
498 /* UXTB16 cccc 0110 1100 1111 xxxx xxxx 0111 xxxx */
499 /* UXTB cccc 0110 1110 1111 xxxx xxxx 0111 xxxx */
500 /* UXTH cccc 0110 1111 1111 xxxx xxxx 0111 xxxx */
501 DECODE_EMULATEX (0x0f8f00f0, 0x068f0070, PROBES_EXTEND,
502 REGS(0, NOPC, 0, 0, NOPC)),
503
504 /* SXTAB16 cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx */
505 /* SXTAB cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx */
506 /* SXTAH cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx */
507 /* UXTAB16 cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx */
508 /* UXTAB cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx */
509 /* UXTAH cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx */
510 DECODE_EMULATEX (0x0f8000f0, 0x06800070, PROBES_EXTEND_ADD,
511 REGS(NOPCX, NOPC, 0, 0, NOPC)),
512
513 DECODE_END
514};
515
516static const union decode_item arm_cccc_0111_____xxx1_table[] = {
517 /* Media instructions */
518
519 /* UNDEFINED cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
520 DECODE_REJECT (0x0ff000f0, 0x07f000f0),
521
522 /* SMLALD cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
523 /* SMLSLD cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
524 DECODE_EMULATEX (0x0ff00090, 0x07400010, PROBES_MUL_ADD_LONG,
525 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
526
527 /* SMUAD cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx */
528 /* SMUSD cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx */
529 DECODE_OR (0x0ff0f090, 0x0700f010),
530 /* SMMUL cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx */
531 DECODE_OR (0x0ff0f0d0, 0x0750f010),
532 /* USAD8 cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
533 DECODE_EMULATEX (0x0ff0f0f0, 0x0780f010, PROBES_MUL_ADD,
534 REGS(NOPC, 0, NOPC, 0, NOPC)),
535
536 /* SMLAD cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx */
537 /* SMLSD cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx */
538 DECODE_OR (0x0ff00090, 0x07000010),
539 /* SMMLA cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx */
540 DECODE_OR (0x0ff000d0, 0x07500010),
541 /* USADA8 cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
542 DECODE_EMULATEX (0x0ff000f0, 0x07800010, PROBES_MUL_ADD,
543 REGS(NOPC, NOPCX, NOPC, 0, NOPC)),
544
545 /* SMMLS cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx */
546 DECODE_EMULATEX (0x0ff000d0, 0x075000d0, PROBES_MUL_ADD,
547 REGS(NOPC, NOPC, NOPC, 0, NOPC)),
548
549 /* SBFX cccc 0111 101x xxxx xxxx xxxx x101 xxxx */
550 /* UBFX cccc 0111 111x xxxx xxxx xxxx x101 xxxx */
551 DECODE_EMULATEX (0x0fa00070, 0x07a00050, PROBES_BITFIELD,
552 REGS(0, NOPC, 0, 0, NOPC)),
553
554 /* BFC cccc 0111 110x xxxx xxxx xxxx x001 1111 */
555 DECODE_EMULATEX (0x0fe0007f, 0x07c0001f, PROBES_BITFIELD,
556 REGS(0, NOPC, 0, 0, 0)),
557
558 /* BFI cccc 0111 110x xxxx xxxx xxxx x001 xxxx */
559 DECODE_EMULATEX (0x0fe00070, 0x07c00010, PROBES_BITFIELD,
560 REGS(0, NOPC, 0, 0, NOPCX)),
561
562 DECODE_END
563};
564
565static const union decode_item arm_cccc_01xx_table[] = {
566 /* Load/store word and unsigned byte */
567
568 /* LDRB/STRB pc,[...] cccc 01xx x0xx xxxx xxxx xxxx xxxx xxxx */
569 DECODE_REJECT (0x0c40f000, 0x0440f000),
570
571 /* STRT cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
572 /* LDRT cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
573 /* STRBT cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
574 /* LDRBT cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
575 DECODE_REJECT (0x0d200000, 0x04200000),
576
577 /* STR (immediate) cccc 010x x0x0 xxxx xxxx xxxx xxxx xxxx */
578 /* STRB (immediate) cccc 010x x1x0 xxxx xxxx xxxx xxxx xxxx */
579 DECODE_EMULATEX (0x0e100000, 0x04000000, PROBES_STORE,
580 REGS(NOPCWB, ANY, 0, 0, 0)),
581
582 /* LDR (immediate) cccc 010x x0x1 xxxx xxxx xxxx xxxx xxxx */
583 /* LDRB (immediate) cccc 010x x1x1 xxxx xxxx xxxx xxxx xxxx */
584 DECODE_EMULATEX (0x0e100000, 0x04100000, PROBES_LOAD,
585 REGS(NOPCWB, ANY, 0, 0, 0)),
586
587 /* STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx */
588 /* STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx */
589 DECODE_EMULATEX (0x0e100000, 0x06000000, PROBES_STORE,
590 REGS(NOPCWB, ANY, 0, 0, NOPC)),
591
592 /* LDR (register) cccc 011x x0x1 xxxx xxxx xxxx xxxx xxxx */
593 /* LDRB (register) cccc 011x x1x1 xxxx xxxx xxxx xxxx xxxx */
594 DECODE_EMULATEX (0x0e100000, 0x06100000, PROBES_LOAD,
595 REGS(NOPCWB, ANY, 0, 0, NOPC)),
596
597 DECODE_END
598};
599
600static const union decode_item arm_cccc_100x_table[] = {
601 /* Block data transfer instructions */
602
603 /* LDM cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
604 /* STM cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
605 DECODE_CUSTOM (0x0e400000, 0x08000000, PROBES_LDMSTM),
606
607 /* STM (user registers) cccc 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
608 /* LDM (user registers) cccc 100x x1x1 xxxx 0xxx xxxx xxxx xxxx */
609 /* LDM (exception ret) cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
610 DECODE_END
611};
612
613const union decode_item probes_decode_arm_table[] = {
614 /*
615 * Unconditional instructions
616 * 1111 xxxx xxxx xxxx xxxx xxxx xxxx xxxx
617 */
618 DECODE_TABLE (0xf0000000, 0xf0000000, arm_1111_table),
619
620 /*
621 * Miscellaneous instructions
622 * cccc 0001 0xx0 xxxx xxxx xxxx 0xxx xxxx
623 */
624 DECODE_TABLE (0x0f900080, 0x01000000, arm_cccc_0001_0xx0____0xxx_table),
625
626 /*
627 * Halfword multiply and multiply-accumulate
628 * cccc 0001 0xx0 xxxx xxxx xxxx 1xx0 xxxx
629 */
630 DECODE_TABLE (0x0f900090, 0x01000080, arm_cccc_0001_0xx0____1xx0_table),
631
632 /*
633 * Multiply and multiply-accumulate
634 * cccc 0000 xxxx xxxx xxxx xxxx 1001 xxxx
635 */
636 DECODE_TABLE (0x0f0000f0, 0x00000090, arm_cccc_0000_____1001_table),
637
638 /*
639 * Synchronization primitives
640 * cccc 0001 xxxx xxxx xxxx xxxx 1001 xxxx
641 */
642 DECODE_TABLE (0x0f0000f0, 0x01000090, arm_cccc_0001_____1001_table),
643
644 /*
645 * Extra load/store instructions
646 * cccc 000x xxxx xxxx xxxx xxxx 1xx1 xxxx
647 */
648 DECODE_TABLE (0x0e000090, 0x00000090, arm_cccc_000x_____1xx1_table),
649
650 /*
651 * Data-processing (register)
652 * cccc 000x xxxx xxxx xxxx xxxx xxx0 xxxx
653 * Data-processing (register-shifted register)
654 * cccc 000x xxxx xxxx xxxx xxxx 0xx1 xxxx
655 */
656 DECODE_TABLE (0x0e000000, 0x00000000, arm_cccc_000x_table),
657
658 /*
659 * Data-processing (immediate)
660 * cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
661 */
662 DECODE_TABLE (0x0e000000, 0x02000000, arm_cccc_001x_table),
663
664 /*
665 * Media instructions
666 * cccc 011x xxxx xxxx xxxx xxxx xxx1 xxxx
667 */
668 DECODE_TABLE (0x0f000010, 0x06000010, arm_cccc_0110_____xxx1_table),
669 DECODE_TABLE (0x0f000010, 0x07000010, arm_cccc_0111_____xxx1_table),
670
671 /*
672 * Load/store word and unsigned byte
673 * cccc 01xx xxxx xxxx xxxx xxxx xxxx xxxx
674 */
675 DECODE_TABLE (0x0c000000, 0x04000000, arm_cccc_01xx_table),
676
677 /*
678 * Block data transfer instructions
679 * cccc 100x xxxx xxxx xxxx xxxx xxxx xxxx
680 */
681 DECODE_TABLE (0x0e000000, 0x08000000, arm_cccc_100x_table),
682
683 /* B cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
684 /* BL cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
685 DECODE_SIMULATE (0x0e000000, 0x0a000000, PROBES_BRANCH),
686
687 /*
688 * Supervisor Call, and coprocessor instructions
689 */
690
691 /* MCRR cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx */
692 /* MRRC cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx */
693 /* LDC cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
694 /* STC cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
695 /* CDP cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
696 /* MCR cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
697 /* MRC cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
698 /* SVC cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
699 DECODE_REJECT (0x0c000000, 0x0c000000),
700
701 DECODE_END
702};
703#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
704EXPORT_SYMBOL_GPL(probes_decode_arm_table);
705#endif
706
707static void __kprobes arm_singlestep(probes_opcode_t insn,
708 struct arch_probes_insn *asi, struct pt_regs *regs)
709{
710 regs->ARM_pc += 4;
711 asi->insn_handler(insn, asi, regs);
712}
713
714/* Return:
715 * INSN_REJECTED If instruction is one not allowed to kprobe,
716 * INSN_GOOD If instruction is supported and uses instruction slot,
717 * INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot.
718 *
719 * For instructions we don't want to kprobe (INSN_REJECTED return result):
720 * These are generally ones that modify the processor state making
721 * them "hard" to simulate such as switches processor modes or
722 * make accesses in alternate modes. Any of these could be simulated
723 * if the work was put into it, but low return considering they
724 * should also be very rare.
725 */
726enum probes_insn __kprobes
727arm_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
728 bool emulate, const union decode_action *actions)
729{
730 asi->insn_singlestep = arm_singlestep;
731 asi->insn_check_cc = probes_condition_checks[insn>>28];
732 return probes_decode_insn(insn, asi, probes_decode_arm_table, false,
733 emulate, actions);
734}
diff --git a/arch/arm/kernel/probes-arm.h b/arch/arm/kernel/probes-arm.h
new file mode 100644
index 000000000000..ace6572f6e26
--- /dev/null
+++ b/arch/arm/kernel/probes-arm.h
@@ -0,0 +1,73 @@
1/*
2 * arch/arm/kernel/probes-arm.h
3 *
4 * Copyright 2013 Linaro Ltd.
5 * Written by: David A. Long
6 *
7 * The code contained herein is licensed under the GNU General Public
8 * License. You may obtain a copy of the GNU General Public License
9 * Version 2 or later at the following locations:
10 *
11 * http://www.opensource.org/licenses/gpl-license.html
12 * http://www.gnu.org/copyleft/gpl.html
13 */
14
15#ifndef _ARM_KERNEL_PROBES_ARM_H
16#define _ARM_KERNEL_PROBES_ARM_H
17
18enum probes_arm_action {
19 PROBES_EMULATE_NONE,
20 PROBES_SIMULATE_NOP,
21 PROBES_PRELOAD_IMM,
22 PROBES_PRELOAD_REG,
23 PROBES_BRANCH_IMM,
24 PROBES_BRANCH_REG,
25 PROBES_MRS,
26 PROBES_CLZ,
27 PROBES_SATURATING_ARITHMETIC,
28 PROBES_MUL1,
29 PROBES_MUL2,
30 PROBES_SWP,
31 PROBES_LDRSTRD,
32 PROBES_LOAD,
33 PROBES_STORE,
34 PROBES_LOAD_EXTRA,
35 PROBES_STORE_EXTRA,
36 PROBES_MOV_IP_SP,
37 PROBES_DATA_PROCESSING_REG,
38 PROBES_DATA_PROCESSING_IMM,
39 PROBES_MOV_HALFWORD,
40 PROBES_SEV,
41 PROBES_WFE,
42 PROBES_SATURATE,
43 PROBES_REV,
44 PROBES_MMI,
45 PROBES_PACK,
46 PROBES_EXTEND,
47 PROBES_EXTEND_ADD,
48 PROBES_MUL_ADD_LONG,
49 PROBES_MUL_ADD,
50 PROBES_BITFIELD,
51 PROBES_BRANCH,
52 PROBES_LDMSTM,
53 NUM_PROBES_ARM_ACTIONS
54};
55
56void __kprobes simulate_bbl(probes_opcode_t opcode,
57 struct arch_probes_insn *asi, struct pt_regs *regs);
58void __kprobes simulate_blx1(probes_opcode_t opcode,
59 struct arch_probes_insn *asi, struct pt_regs *regs);
60void __kprobes simulate_blx2bx(probes_opcode_t opcode,
61 struct arch_probes_insn *asi, struct pt_regs *regs);
62void __kprobes simulate_mrs(probes_opcode_t opcode,
63 struct arch_probes_insn *asi, struct pt_regs *regs);
64void __kprobes simulate_mov_ipsp(probes_opcode_t opcode,
65 struct arch_probes_insn *asi, struct pt_regs *regs);
66
67extern const union decode_item probes_decode_arm_table[];
68
69enum probes_insn arm_probes_decode_insn(probes_opcode_t,
70 struct arch_probes_insn *, bool emulate,
71 const union decode_action *actions);
72
73#endif
diff --git a/arch/arm/kernel/probes-thumb.c b/arch/arm/kernel/probes-thumb.c
new file mode 100644
index 000000000000..4131351e812f
--- /dev/null
+++ b/arch/arm/kernel/probes-thumb.c
@@ -0,0 +1,882 @@
1/*
2 * arch/arm/kernel/probes-thumb.c
3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
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
11#include <linux/stddef.h>
12#include <linux/kernel.h>
13#include <linux/module.h>
14
15#include "probes.h"
16#include "probes-thumb.h"
17
18
19static const union decode_item t32_table_1110_100x_x0xx[] = {
20 /* Load/store multiple instructions */
21
22 /* Rn is PC 1110 100x x0xx 1111 xxxx xxxx xxxx xxxx */
23 DECODE_REJECT (0xfe4f0000, 0xe80f0000),
24
25 /* SRS 1110 1000 00x0 xxxx xxxx xxxx xxxx xxxx */
26 /* RFE 1110 1000 00x1 xxxx xxxx xxxx xxxx xxxx */
27 DECODE_REJECT (0xffc00000, 0xe8000000),
28 /* SRS 1110 1001 10x0 xxxx xxxx xxxx xxxx xxxx */
29 /* RFE 1110 1001 10x1 xxxx xxxx xxxx xxxx xxxx */
30 DECODE_REJECT (0xffc00000, 0xe9800000),
31
32 /* STM Rn, {...pc} 1110 100x x0x0 xxxx 1xxx xxxx xxxx xxxx */
33 DECODE_REJECT (0xfe508000, 0xe8008000),
34 /* LDM Rn, {...lr,pc} 1110 100x x0x1 xxxx 11xx xxxx xxxx xxxx */
35 DECODE_REJECT (0xfe50c000, 0xe810c000),
36 /* LDM/STM Rn, {...sp} 1110 100x x0xx xxxx xx1x xxxx xxxx xxxx */
37 DECODE_REJECT (0xfe402000, 0xe8002000),
38
39 /* STMIA 1110 1000 10x0 xxxx xxxx xxxx xxxx xxxx */
40 /* LDMIA 1110 1000 10x1 xxxx xxxx xxxx xxxx xxxx */
41 /* STMDB 1110 1001 00x0 xxxx xxxx xxxx xxxx xxxx */
42 /* LDMDB 1110 1001 00x1 xxxx xxxx xxxx xxxx xxxx */
43 DECODE_CUSTOM (0xfe400000, 0xe8000000, PROBES_T32_LDMSTM),
44
45 DECODE_END
46};
47
48static const union decode_item t32_table_1110_100x_x1xx[] = {
49 /* Load/store dual, load/store exclusive, table branch */
50
51 /* STRD (immediate) 1110 1000 x110 xxxx xxxx xxxx xxxx xxxx */
52 /* LDRD (immediate) 1110 1000 x111 xxxx xxxx xxxx xxxx xxxx */
53 DECODE_OR (0xff600000, 0xe8600000),
54 /* STRD (immediate) 1110 1001 x1x0 xxxx xxxx xxxx xxxx xxxx */
55 /* LDRD (immediate) 1110 1001 x1x1 xxxx xxxx xxxx xxxx xxxx */
56 DECODE_EMULATEX (0xff400000, 0xe9400000, PROBES_T32_LDRDSTRD,
57 REGS(NOPCWB, NOSPPC, NOSPPC, 0, 0)),
58
59 /* TBB 1110 1000 1101 xxxx xxxx xxxx 0000 xxxx */
60 /* TBH 1110 1000 1101 xxxx xxxx xxxx 0001 xxxx */
61 DECODE_SIMULATEX(0xfff000e0, 0xe8d00000, PROBES_T32_TABLE_BRANCH,
62 REGS(NOSP, 0, 0, 0, NOSPPC)),
63
64 /* STREX 1110 1000 0100 xxxx xxxx xxxx xxxx xxxx */
65 /* LDREX 1110 1000 0101 xxxx xxxx xxxx xxxx xxxx */
66 /* STREXB 1110 1000 1100 xxxx xxxx xxxx 0100 xxxx */
67 /* STREXH 1110 1000 1100 xxxx xxxx xxxx 0101 xxxx */
68 /* STREXD 1110 1000 1100 xxxx xxxx xxxx 0111 xxxx */
69 /* LDREXB 1110 1000 1101 xxxx xxxx xxxx 0100 xxxx */
70 /* LDREXH 1110 1000 1101 xxxx xxxx xxxx 0101 xxxx */
71 /* LDREXD 1110 1000 1101 xxxx xxxx xxxx 0111 xxxx */
72 /* And unallocated instructions... */
73 DECODE_END
74};
75
76static const union decode_item t32_table_1110_101x[] = {
77 /* Data-processing (shifted register) */
78
79 /* TST 1110 1010 0001 xxxx xxxx 1111 xxxx xxxx */
80 /* TEQ 1110 1010 1001 xxxx xxxx 1111 xxxx xxxx */
81 DECODE_EMULATEX (0xff700f00, 0xea100f00, PROBES_T32_TST,
82 REGS(NOSPPC, 0, 0, 0, NOSPPC)),
83
84 /* CMN 1110 1011 0001 xxxx xxxx 1111 xxxx xxxx */
85 DECODE_OR (0xfff00f00, 0xeb100f00),
86 /* CMP 1110 1011 1011 xxxx xxxx 1111 xxxx xxxx */
87 DECODE_EMULATEX (0xfff00f00, 0xebb00f00, PROBES_T32_TST,
88 REGS(NOPC, 0, 0, 0, NOSPPC)),
89
90 /* MOV 1110 1010 010x 1111 xxxx xxxx xxxx xxxx */
91 /* MVN 1110 1010 011x 1111 xxxx xxxx xxxx xxxx */
92 DECODE_EMULATEX (0xffcf0000, 0xea4f0000, PROBES_T32_MOV,
93 REGS(0, 0, NOSPPC, 0, NOSPPC)),
94
95 /* ??? 1110 1010 101x xxxx xxxx xxxx xxxx xxxx */
96 /* ??? 1110 1010 111x xxxx xxxx xxxx xxxx xxxx */
97 DECODE_REJECT (0xffa00000, 0xeaa00000),
98 /* ??? 1110 1011 001x xxxx xxxx xxxx xxxx xxxx */
99 DECODE_REJECT (0xffe00000, 0xeb200000),
100 /* ??? 1110 1011 100x xxxx xxxx xxxx xxxx xxxx */
101 DECODE_REJECT (0xffe00000, 0xeb800000),
102 /* ??? 1110 1011 111x xxxx xxxx xxxx xxxx xxxx */
103 DECODE_REJECT (0xffe00000, 0xebe00000),
104
105 /* ADD/SUB SP, SP, Rm, LSL #0..3 */
106 /* 1110 1011 x0xx 1101 x000 1101 xx00 xxxx */
107 DECODE_EMULATEX (0xff4f7f30, 0xeb0d0d00, PROBES_T32_ADDSUB,
108 REGS(SP, 0, SP, 0, NOSPPC)),
109
110 /* ADD/SUB SP, SP, Rm, shift */
111 /* 1110 1011 x0xx 1101 xxxx 1101 xxxx xxxx */
112 DECODE_REJECT (0xff4f0f00, 0xeb0d0d00),
113
114 /* ADD/SUB Rd, SP, Rm, shift */
115 /* 1110 1011 x0xx 1101 xxxx xxxx xxxx xxxx */
116 DECODE_EMULATEX (0xff4f0000, 0xeb0d0000, PROBES_T32_ADDSUB,
117 REGS(SP, 0, NOPC, 0, NOSPPC)),
118
119 /* AND 1110 1010 000x xxxx xxxx xxxx xxxx xxxx */
120 /* BIC 1110 1010 001x xxxx xxxx xxxx xxxx xxxx */
121 /* ORR 1110 1010 010x xxxx xxxx xxxx xxxx xxxx */
122 /* ORN 1110 1010 011x xxxx xxxx xxxx xxxx xxxx */
123 /* EOR 1110 1010 100x xxxx xxxx xxxx xxxx xxxx */
124 /* PKH 1110 1010 110x xxxx xxxx xxxx xxxx xxxx */
125 /* ADD 1110 1011 000x xxxx xxxx xxxx xxxx xxxx */
126 /* ADC 1110 1011 010x xxxx xxxx xxxx xxxx xxxx */
127 /* SBC 1110 1011 011x xxxx xxxx xxxx xxxx xxxx */
128 /* SUB 1110 1011 101x xxxx xxxx xxxx xxxx xxxx */
129 /* RSB 1110 1011 110x xxxx xxxx xxxx xxxx xxxx */
130 DECODE_EMULATEX (0xfe000000, 0xea000000, PROBES_T32_LOGICAL,
131 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
132
133 DECODE_END
134};
135
136static const union decode_item t32_table_1111_0x0x___0[] = {
137 /* Data-processing (modified immediate) */
138
139 /* TST 1111 0x00 0001 xxxx 0xxx 1111 xxxx xxxx */
140 /* TEQ 1111 0x00 1001 xxxx 0xxx 1111 xxxx xxxx */
141 DECODE_EMULATEX (0xfb708f00, 0xf0100f00, PROBES_T32_TST,
142 REGS(NOSPPC, 0, 0, 0, 0)),
143
144 /* CMN 1111 0x01 0001 xxxx 0xxx 1111 xxxx xxxx */
145 DECODE_OR (0xfbf08f00, 0xf1100f00),
146 /* CMP 1111 0x01 1011 xxxx 0xxx 1111 xxxx xxxx */
147 DECODE_EMULATEX (0xfbf08f00, 0xf1b00f00, PROBES_T32_CMP,
148 REGS(NOPC, 0, 0, 0, 0)),
149
150 /* MOV 1111 0x00 010x 1111 0xxx xxxx xxxx xxxx */
151 /* MVN 1111 0x00 011x 1111 0xxx xxxx xxxx xxxx */
152 DECODE_EMULATEX (0xfbcf8000, 0xf04f0000, PROBES_T32_MOV,
153 REGS(0, 0, NOSPPC, 0, 0)),
154
155 /* ??? 1111 0x00 101x xxxx 0xxx xxxx xxxx xxxx */
156 DECODE_REJECT (0xfbe08000, 0xf0a00000),
157 /* ??? 1111 0x00 110x xxxx 0xxx xxxx xxxx xxxx */
158 /* ??? 1111 0x00 111x xxxx 0xxx xxxx xxxx xxxx */
159 DECODE_REJECT (0xfbc08000, 0xf0c00000),
160 /* ??? 1111 0x01 001x xxxx 0xxx xxxx xxxx xxxx */
161 DECODE_REJECT (0xfbe08000, 0xf1200000),
162 /* ??? 1111 0x01 100x xxxx 0xxx xxxx xxxx xxxx */
163 DECODE_REJECT (0xfbe08000, 0xf1800000),
164 /* ??? 1111 0x01 111x xxxx 0xxx xxxx xxxx xxxx */
165 DECODE_REJECT (0xfbe08000, 0xf1e00000),
166
167 /* ADD Rd, SP, #imm 1111 0x01 000x 1101 0xxx xxxx xxxx xxxx */
168 /* SUB Rd, SP, #imm 1111 0x01 101x 1101 0xxx xxxx xxxx xxxx */
169 DECODE_EMULATEX (0xfb4f8000, 0xf10d0000, PROBES_T32_ADDSUB,
170 REGS(SP, 0, NOPC, 0, 0)),
171
172 /* AND 1111 0x00 000x xxxx 0xxx xxxx xxxx xxxx */
173 /* BIC 1111 0x00 001x xxxx 0xxx xxxx xxxx xxxx */
174 /* ORR 1111 0x00 010x xxxx 0xxx xxxx xxxx xxxx */
175 /* ORN 1111 0x00 011x xxxx 0xxx xxxx xxxx xxxx */
176 /* EOR 1111 0x00 100x xxxx 0xxx xxxx xxxx xxxx */
177 /* ADD 1111 0x01 000x xxxx 0xxx xxxx xxxx xxxx */
178 /* ADC 1111 0x01 010x xxxx 0xxx xxxx xxxx xxxx */
179 /* SBC 1111 0x01 011x xxxx 0xxx xxxx xxxx xxxx */
180 /* SUB 1111 0x01 101x xxxx 0xxx xxxx xxxx xxxx */
181 /* RSB 1111 0x01 110x xxxx 0xxx xxxx xxxx xxxx */
182 DECODE_EMULATEX (0xfa008000, 0xf0000000, PROBES_T32_LOGICAL,
183 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
184
185 DECODE_END
186};
187
188static const union decode_item t32_table_1111_0x1x___0[] = {
189 /* Data-processing (plain binary immediate) */
190
191 /* ADDW Rd, PC, #imm 1111 0x10 0000 1111 0xxx xxxx xxxx xxxx */
192 DECODE_OR (0xfbff8000, 0xf20f0000),
193 /* SUBW Rd, PC, #imm 1111 0x10 1010 1111 0xxx xxxx xxxx xxxx */
194 DECODE_EMULATEX (0xfbff8000, 0xf2af0000, PROBES_T32_ADDWSUBW_PC,
195 REGS(PC, 0, NOSPPC, 0, 0)),
196
197 /* ADDW SP, SP, #imm 1111 0x10 0000 1101 0xxx 1101 xxxx xxxx */
198 DECODE_OR (0xfbff8f00, 0xf20d0d00),
199 /* SUBW SP, SP, #imm 1111 0x10 1010 1101 0xxx 1101 xxxx xxxx */
200 DECODE_EMULATEX (0xfbff8f00, 0xf2ad0d00, PROBES_T32_ADDWSUBW,
201 REGS(SP, 0, SP, 0, 0)),
202
203 /* ADDW 1111 0x10 0000 xxxx 0xxx xxxx xxxx xxxx */
204 DECODE_OR (0xfbf08000, 0xf2000000),
205 /* SUBW 1111 0x10 1010 xxxx 0xxx xxxx xxxx xxxx */
206 DECODE_EMULATEX (0xfbf08000, 0xf2a00000, PROBES_T32_ADDWSUBW,
207 REGS(NOPCX, 0, NOSPPC, 0, 0)),
208
209 /* MOVW 1111 0x10 0100 xxxx 0xxx xxxx xxxx xxxx */
210 /* MOVT 1111 0x10 1100 xxxx 0xxx xxxx xxxx xxxx */
211 DECODE_EMULATEX (0xfb708000, 0xf2400000, PROBES_T32_MOVW,
212 REGS(0, 0, NOSPPC, 0, 0)),
213
214 /* SSAT16 1111 0x11 0010 xxxx 0000 xxxx 00xx xxxx */
215 /* SSAT 1111 0x11 00x0 xxxx 0xxx xxxx xxxx xxxx */
216 /* USAT16 1111 0x11 1010 xxxx 0000 xxxx 00xx xxxx */
217 /* USAT 1111 0x11 10x0 xxxx 0xxx xxxx xxxx xxxx */
218 DECODE_EMULATEX (0xfb508000, 0xf3000000, PROBES_T32_SAT,
219 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
220
221 /* SFBX 1111 0x11 0100 xxxx 0xxx xxxx xxxx xxxx */
222 /* UFBX 1111 0x11 1100 xxxx 0xxx xxxx xxxx xxxx */
223 DECODE_EMULATEX (0xfb708000, 0xf3400000, PROBES_T32_BITFIELD,
224 REGS(NOSPPC, 0, NOSPPC, 0, 0)),
225
226 /* BFC 1111 0x11 0110 1111 0xxx xxxx xxxx xxxx */
227 DECODE_EMULATEX (0xfbff8000, 0xf36f0000, PROBES_T32_BITFIELD,
228 REGS(0, 0, NOSPPC, 0, 0)),
229
230 /* BFI 1111 0x11 0110 xxxx 0xxx xxxx xxxx xxxx */
231 DECODE_EMULATEX (0xfbf08000, 0xf3600000, PROBES_T32_BITFIELD,
232 REGS(NOSPPCX, 0, NOSPPC, 0, 0)),
233
234 DECODE_END
235};
236
237static const union decode_item t32_table_1111_0xxx___1[] = {
238 /* Branches and miscellaneous control */
239
240 /* YIELD 1111 0011 1010 xxxx 10x0 x000 0000 0001 */
241 DECODE_OR (0xfff0d7ff, 0xf3a08001),
242 /* SEV 1111 0011 1010 xxxx 10x0 x000 0000 0100 */
243 DECODE_EMULATE (0xfff0d7ff, 0xf3a08004, PROBES_T32_SEV),
244 /* NOP 1111 0011 1010 xxxx 10x0 x000 0000 0000 */
245 /* WFE 1111 0011 1010 xxxx 10x0 x000 0000 0010 */
246 /* WFI 1111 0011 1010 xxxx 10x0 x000 0000 0011 */
247 DECODE_SIMULATE (0xfff0d7fc, 0xf3a08000, PROBES_T32_WFE),
248
249 /* MRS Rd, CPSR 1111 0011 1110 xxxx 10x0 xxxx xxxx xxxx */
250 DECODE_SIMULATEX(0xfff0d000, 0xf3e08000, PROBES_T32_MRS,
251 REGS(0, 0, NOSPPC, 0, 0)),
252
253 /*
254 * Unsupported instructions
255 * 1111 0x11 1xxx xxxx 10x0 xxxx xxxx xxxx
256 *
257 * MSR 1111 0011 100x xxxx 10x0 xxxx xxxx xxxx
258 * DBG hint 1111 0011 1010 xxxx 10x0 x000 1111 xxxx
259 * Unallocated hints 1111 0011 1010 xxxx 10x0 x000 xxxx xxxx
260 * CPS 1111 0011 1010 xxxx 10x0 xxxx xxxx xxxx
261 * CLREX/DSB/DMB/ISB 1111 0011 1011 xxxx 10x0 xxxx xxxx xxxx
262 * BXJ 1111 0011 1100 xxxx 10x0 xxxx xxxx xxxx
263 * SUBS PC,LR,#<imm8> 1111 0011 1101 xxxx 10x0 xxxx xxxx xxxx
264 * MRS Rd, SPSR 1111 0011 1111 xxxx 10x0 xxxx xxxx xxxx
265 * SMC 1111 0111 1111 xxxx 1000 xxxx xxxx xxxx
266 * UNDEFINED 1111 0111 1111 xxxx 1010 xxxx xxxx xxxx
267 * ??? 1111 0111 1xxx xxxx 1010 xxxx xxxx xxxx
268 */
269 DECODE_REJECT (0xfb80d000, 0xf3808000),
270
271 /* Bcc 1111 0xxx xxxx xxxx 10x0 xxxx xxxx xxxx */
272 DECODE_CUSTOM (0xf800d000, 0xf0008000, PROBES_T32_BRANCH_COND),
273
274 /* BLX 1111 0xxx xxxx xxxx 11x0 xxxx xxxx xxx0 */
275 DECODE_OR (0xf800d001, 0xf000c000),
276 /* B 1111 0xxx xxxx xxxx 10x1 xxxx xxxx xxxx */
277 /* BL 1111 0xxx xxxx xxxx 11x1 xxxx xxxx xxxx */
278 DECODE_SIMULATE (0xf8009000, 0xf0009000, PROBES_T32_BRANCH),
279
280 DECODE_END
281};
282
283static const union decode_item t32_table_1111_100x_x0x1__1111[] = {
284 /* Memory hints */
285
286 /* PLD (literal) 1111 1000 x001 1111 1111 xxxx xxxx xxxx */
287 /* PLI (literal) 1111 1001 x001 1111 1111 xxxx xxxx xxxx */
288 DECODE_SIMULATE (0xfe7ff000, 0xf81ff000, PROBES_T32_PLDI),
289
290 /* PLD{W} (immediate) 1111 1000 10x1 xxxx 1111 xxxx xxxx xxxx */
291 DECODE_OR (0xffd0f000, 0xf890f000),
292 /* PLD{W} (immediate) 1111 1000 00x1 xxxx 1111 1100 xxxx xxxx */
293 DECODE_OR (0xffd0ff00, 0xf810fc00),
294 /* PLI (immediate) 1111 1001 1001 xxxx 1111 xxxx xxxx xxxx */
295 DECODE_OR (0xfff0f000, 0xf990f000),
296 /* PLI (immediate) 1111 1001 0001 xxxx 1111 1100 xxxx xxxx */
297 DECODE_SIMULATEX(0xfff0ff00, 0xf910fc00, PROBES_T32_PLDI,
298 REGS(NOPCX, 0, 0, 0, 0)),
299
300 /* PLD{W} (register) 1111 1000 00x1 xxxx 1111 0000 00xx xxxx */
301 DECODE_OR (0xffd0ffc0, 0xf810f000),
302 /* PLI (register) 1111 1001 0001 xxxx 1111 0000 00xx xxxx */
303 DECODE_SIMULATEX(0xfff0ffc0, 0xf910f000, PROBES_T32_PLDI,
304 REGS(NOPCX, 0, 0, 0, NOSPPC)),
305
306 /* Other unallocated instructions... */
307 DECODE_END
308};
309
310static const union decode_item t32_table_1111_100x[] = {
311 /* Store/Load single data item */
312
313 /* ??? 1111 100x x11x xxxx xxxx xxxx xxxx xxxx */
314 DECODE_REJECT (0xfe600000, 0xf8600000),
315
316 /* ??? 1111 1001 0101 xxxx xxxx xxxx xxxx xxxx */
317 DECODE_REJECT (0xfff00000, 0xf9500000),
318
319 /* ??? 1111 100x 0xxx xxxx xxxx 10x0 xxxx xxxx */
320 DECODE_REJECT (0xfe800d00, 0xf8000800),
321
322 /* STRBT 1111 1000 0000 xxxx xxxx 1110 xxxx xxxx */
323 /* STRHT 1111 1000 0010 xxxx xxxx 1110 xxxx xxxx */
324 /* STRT 1111 1000 0100 xxxx xxxx 1110 xxxx xxxx */
325 /* LDRBT 1111 1000 0001 xxxx xxxx 1110 xxxx xxxx */
326 /* LDRSBT 1111 1001 0001 xxxx xxxx 1110 xxxx xxxx */
327 /* LDRHT 1111 1000 0011 xxxx xxxx 1110 xxxx xxxx */
328 /* LDRSHT 1111 1001 0011 xxxx xxxx 1110 xxxx xxxx */
329 /* LDRT 1111 1000 0101 xxxx xxxx 1110 xxxx xxxx */
330 DECODE_REJECT (0xfe800f00, 0xf8000e00),
331
332 /* STR{,B,H} Rn,[PC...] 1111 1000 xxx0 1111 xxxx xxxx xxxx xxxx */
333 DECODE_REJECT (0xff1f0000, 0xf80f0000),
334
335 /* STR{,B,H} PC,[Rn...] 1111 1000 xxx0 xxxx 1111 xxxx xxxx xxxx */
336 DECODE_REJECT (0xff10f000, 0xf800f000),
337
338 /* LDR (literal) 1111 1000 x101 1111 xxxx xxxx xxxx xxxx */
339 DECODE_SIMULATEX(0xff7f0000, 0xf85f0000, PROBES_T32_LDR_LIT,
340 REGS(PC, ANY, 0, 0, 0)),
341
342 /* STR (immediate) 1111 1000 0100 xxxx xxxx 1xxx xxxx xxxx */
343 /* LDR (immediate) 1111 1000 0101 xxxx xxxx 1xxx xxxx xxxx */
344 DECODE_OR (0xffe00800, 0xf8400800),
345 /* STR (immediate) 1111 1000 1100 xxxx xxxx xxxx xxxx xxxx */
346 /* LDR (immediate) 1111 1000 1101 xxxx xxxx xxxx xxxx xxxx */
347 DECODE_EMULATEX (0xffe00000, 0xf8c00000, PROBES_T32_LDRSTR,
348 REGS(NOPCX, ANY, 0, 0, 0)),
349
350 /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */
351 /* LDR (register) 1111 1000 0101 xxxx xxxx 0000 00xx xxxx */
352 DECODE_EMULATEX (0xffe00fc0, 0xf8400000, PROBES_T32_LDRSTR,
353 REGS(NOPCX, ANY, 0, 0, NOSPPC)),
354
355 /* LDRB (literal) 1111 1000 x001 1111 xxxx xxxx xxxx xxxx */
356 /* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */
357 /* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */
358 /* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */
359 DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, PROBES_T32_LDR_LIT,
360 REGS(PC, NOSPPCX, 0, 0, 0)),
361
362 /* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */
363 /* STRH (immediate) 1111 1000 0010 xxxx xxxx 1xxx xxxx xxxx */
364 /* LDRB (immediate) 1111 1000 0001 xxxx xxxx 1xxx xxxx xxxx */
365 /* LDRSB (immediate) 1111 1001 0001 xxxx xxxx 1xxx xxxx xxxx */
366 /* LDRH (immediate) 1111 1000 0011 xxxx xxxx 1xxx xxxx xxxx */
367 /* LDRSH (immediate) 1111 1001 0011 xxxx xxxx 1xxx xxxx xxxx */
368 DECODE_OR (0xfec00800, 0xf8000800),
369 /* STRB (immediate) 1111 1000 1000 xxxx xxxx xxxx xxxx xxxx */
370 /* STRH (immediate) 1111 1000 1010 xxxx xxxx xxxx xxxx xxxx */
371 /* LDRB (immediate) 1111 1000 1001 xxxx xxxx xxxx xxxx xxxx */
372 /* LDRSB (immediate) 1111 1001 1001 xxxx xxxx xxxx xxxx xxxx */
373 /* LDRH (immediate) 1111 1000 1011 xxxx xxxx xxxx xxxx xxxx */
374 /* LDRSH (immediate) 1111 1001 1011 xxxx xxxx xxxx xxxx xxxx */
375 DECODE_EMULATEX (0xfec00000, 0xf8800000, PROBES_T32_LDRSTR,
376 REGS(NOPCX, NOSPPCX, 0, 0, 0)),
377
378 /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */
379 /* STRH (register) 1111 1000 0010 xxxx xxxx 0000 00xx xxxx */
380 /* LDRB (register) 1111 1000 0001 xxxx xxxx 0000 00xx xxxx */
381 /* LDRSB (register) 1111 1001 0001 xxxx xxxx 0000 00xx xxxx */
382 /* LDRH (register) 1111 1000 0011 xxxx xxxx 0000 00xx xxxx */
383 /* LDRSH (register) 1111 1001 0011 xxxx xxxx 0000 00xx xxxx */
384 DECODE_EMULATEX (0xfe800fc0, 0xf8000000, PROBES_T32_LDRSTR,
385 REGS(NOPCX, NOSPPCX, 0, 0, NOSPPC)),
386
387 /* Other unallocated instructions... */
388 DECODE_END
389};
390
391static const union decode_item t32_table_1111_1010___1111[] = {
392 /* Data-processing (register) */
393
394 /* ??? 1111 1010 011x xxxx 1111 xxxx 1xxx xxxx */
395 DECODE_REJECT (0xffe0f080, 0xfa60f080),
396
397 /* SXTH 1111 1010 0000 1111 1111 xxxx 1xxx xxxx */
398 /* UXTH 1111 1010 0001 1111 1111 xxxx 1xxx xxxx */
399 /* SXTB16 1111 1010 0010 1111 1111 xxxx 1xxx xxxx */
400 /* UXTB16 1111 1010 0011 1111 1111 xxxx 1xxx xxxx */
401 /* SXTB 1111 1010 0100 1111 1111 xxxx 1xxx xxxx */
402 /* UXTB 1111 1010 0101 1111 1111 xxxx 1xxx xxxx */
403 DECODE_EMULATEX (0xff8ff080, 0xfa0ff080, PROBES_T32_SIGN_EXTEND,
404 REGS(0, 0, NOSPPC, 0, NOSPPC)),
405
406
407 /* ??? 1111 1010 1xxx xxxx 1111 xxxx 0x11 xxxx */
408 DECODE_REJECT (0xff80f0b0, 0xfa80f030),
409 /* ??? 1111 1010 1x11 xxxx 1111 xxxx 0xxx xxxx */
410 DECODE_REJECT (0xffb0f080, 0xfab0f000),
411
412 /* SADD16 1111 1010 1001 xxxx 1111 xxxx 0000 xxxx */
413 /* SASX 1111 1010 1010 xxxx 1111 xxxx 0000 xxxx */
414 /* SSAX 1111 1010 1110 xxxx 1111 xxxx 0000 xxxx */
415 /* SSUB16 1111 1010 1101 xxxx 1111 xxxx 0000 xxxx */
416 /* SADD8 1111 1010 1000 xxxx 1111 xxxx 0000 xxxx */
417 /* SSUB8 1111 1010 1100 xxxx 1111 xxxx 0000 xxxx */
418
419 /* QADD16 1111 1010 1001 xxxx 1111 xxxx 0001 xxxx */
420 /* QASX 1111 1010 1010 xxxx 1111 xxxx 0001 xxxx */
421 /* QSAX 1111 1010 1110 xxxx 1111 xxxx 0001 xxxx */
422 /* QSUB16 1111 1010 1101 xxxx 1111 xxxx 0001 xxxx */
423 /* QADD8 1111 1010 1000 xxxx 1111 xxxx 0001 xxxx */
424 /* QSUB8 1111 1010 1100 xxxx 1111 xxxx 0001 xxxx */
425
426 /* SHADD16 1111 1010 1001 xxxx 1111 xxxx 0010 xxxx */
427 /* SHASX 1111 1010 1010 xxxx 1111 xxxx 0010 xxxx */
428 /* SHSAX 1111 1010 1110 xxxx 1111 xxxx 0010 xxxx */
429 /* SHSUB16 1111 1010 1101 xxxx 1111 xxxx 0010 xxxx */
430 /* SHADD8 1111 1010 1000 xxxx 1111 xxxx 0010 xxxx */
431 /* SHSUB8 1111 1010 1100 xxxx 1111 xxxx 0010 xxxx */
432
433 /* UADD16 1111 1010 1001 xxxx 1111 xxxx 0100 xxxx */
434 /* UASX 1111 1010 1010 xxxx 1111 xxxx 0100 xxxx */
435 /* USAX 1111 1010 1110 xxxx 1111 xxxx 0100 xxxx */
436 /* USUB16 1111 1010 1101 xxxx 1111 xxxx 0100 xxxx */
437 /* UADD8 1111 1010 1000 xxxx 1111 xxxx 0100 xxxx */
438 /* USUB8 1111 1010 1100 xxxx 1111 xxxx 0100 xxxx */
439
440 /* UQADD16 1111 1010 1001 xxxx 1111 xxxx 0101 xxxx */
441 /* UQASX 1111 1010 1010 xxxx 1111 xxxx 0101 xxxx */
442 /* UQSAX 1111 1010 1110 xxxx 1111 xxxx 0101 xxxx */
443 /* UQSUB16 1111 1010 1101 xxxx 1111 xxxx 0101 xxxx */
444 /* UQADD8 1111 1010 1000 xxxx 1111 xxxx 0101 xxxx */
445 /* UQSUB8 1111 1010 1100 xxxx 1111 xxxx 0101 xxxx */
446
447 /* UHADD16 1111 1010 1001 xxxx 1111 xxxx 0110 xxxx */
448 /* UHASX 1111 1010 1010 xxxx 1111 xxxx 0110 xxxx */
449 /* UHSAX 1111 1010 1110 xxxx 1111 xxxx 0110 xxxx */
450 /* UHSUB16 1111 1010 1101 xxxx 1111 xxxx 0110 xxxx */
451 /* UHADD8 1111 1010 1000 xxxx 1111 xxxx 0110 xxxx */
452 /* UHSUB8 1111 1010 1100 xxxx 1111 xxxx 0110 xxxx */
453 DECODE_OR (0xff80f080, 0xfa80f000),
454
455 /* SXTAH 1111 1010 0000 xxxx 1111 xxxx 1xxx xxxx */
456 /* UXTAH 1111 1010 0001 xxxx 1111 xxxx 1xxx xxxx */
457 /* SXTAB16 1111 1010 0010 xxxx 1111 xxxx 1xxx xxxx */
458 /* UXTAB16 1111 1010 0011 xxxx 1111 xxxx 1xxx xxxx */
459 /* SXTAB 1111 1010 0100 xxxx 1111 xxxx 1xxx xxxx */
460 /* UXTAB 1111 1010 0101 xxxx 1111 xxxx 1xxx xxxx */
461 DECODE_OR (0xff80f080, 0xfa00f080),
462
463 /* QADD 1111 1010 1000 xxxx 1111 xxxx 1000 xxxx */
464 /* QDADD 1111 1010 1000 xxxx 1111 xxxx 1001 xxxx */
465 /* QSUB 1111 1010 1000 xxxx 1111 xxxx 1010 xxxx */
466 /* QDSUB 1111 1010 1000 xxxx 1111 xxxx 1011 xxxx */
467 DECODE_OR (0xfff0f0c0, 0xfa80f080),
468
469 /* SEL 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
470 DECODE_OR (0xfff0f0f0, 0xfaa0f080),
471
472 /* LSL 1111 1010 000x xxxx 1111 xxxx 0000 xxxx */
473 /* LSR 1111 1010 001x xxxx 1111 xxxx 0000 xxxx */
474 /* ASR 1111 1010 010x xxxx 1111 xxxx 0000 xxxx */
475 /* ROR 1111 1010 011x xxxx 1111 xxxx 0000 xxxx */
476 DECODE_EMULATEX (0xff80f0f0, 0xfa00f000, PROBES_T32_MEDIA,
477 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
478
479 /* CLZ 1111 1010 1010 xxxx 1111 xxxx 1000 xxxx */
480 DECODE_OR (0xfff0f0f0, 0xfab0f080),
481
482 /* REV 1111 1010 1001 xxxx 1111 xxxx 1000 xxxx */
483 /* REV16 1111 1010 1001 xxxx 1111 xxxx 1001 xxxx */
484 /* RBIT 1111 1010 1001 xxxx 1111 xxxx 1010 xxxx */
485 /* REVSH 1111 1010 1001 xxxx 1111 xxxx 1011 xxxx */
486 DECODE_EMULATEX (0xfff0f0c0, 0xfa90f080, PROBES_T32_REVERSE,
487 REGS(NOSPPC, 0, NOSPPC, 0, SAMEAS16)),
488
489 /* Other unallocated instructions... */
490 DECODE_END
491};
492
493static const union decode_item t32_table_1111_1011_0[] = {
494 /* Multiply, multiply accumulate, and absolute difference */
495
496 /* ??? 1111 1011 0000 xxxx 1111 xxxx 0001 xxxx */
497 DECODE_REJECT (0xfff0f0f0, 0xfb00f010),
498 /* ??? 1111 1011 0111 xxxx 1111 xxxx 0001 xxxx */
499 DECODE_REJECT (0xfff0f0f0, 0xfb70f010),
500
501 /* SMULxy 1111 1011 0001 xxxx 1111 xxxx 00xx xxxx */
502 DECODE_OR (0xfff0f0c0, 0xfb10f000),
503 /* MUL 1111 1011 0000 xxxx 1111 xxxx 0000 xxxx */
504 /* SMUAD{X} 1111 1011 0010 xxxx 1111 xxxx 000x xxxx */
505 /* SMULWy 1111 1011 0011 xxxx 1111 xxxx 000x xxxx */
506 /* SMUSD{X} 1111 1011 0100 xxxx 1111 xxxx 000x xxxx */
507 /* SMMUL{R} 1111 1011 0101 xxxx 1111 xxxx 000x xxxx */
508 /* USAD8 1111 1011 0111 xxxx 1111 xxxx 0000 xxxx */
509 DECODE_EMULATEX (0xff80f0e0, 0xfb00f000, PROBES_T32_MUL_ADD,
510 REGS(NOSPPC, 0, NOSPPC, 0, NOSPPC)),
511
512 /* ??? 1111 1011 0111 xxxx xxxx xxxx 0001 xxxx */
513 DECODE_REJECT (0xfff000f0, 0xfb700010),
514
515 /* SMLAxy 1111 1011 0001 xxxx xxxx xxxx 00xx xxxx */
516 DECODE_OR (0xfff000c0, 0xfb100000),
517 /* MLA 1111 1011 0000 xxxx xxxx xxxx 0000 xxxx */
518 /* MLS 1111 1011 0000 xxxx xxxx xxxx 0001 xxxx */
519 /* SMLAD{X} 1111 1011 0010 xxxx xxxx xxxx 000x xxxx */
520 /* SMLAWy 1111 1011 0011 xxxx xxxx xxxx 000x xxxx */
521 /* SMLSD{X} 1111 1011 0100 xxxx xxxx xxxx 000x xxxx */
522 /* SMMLA{R} 1111 1011 0101 xxxx xxxx xxxx 000x xxxx */
523 /* SMMLS{R} 1111 1011 0110 xxxx xxxx xxxx 000x xxxx */
524 /* USADA8 1111 1011 0111 xxxx xxxx xxxx 0000 xxxx */
525 DECODE_EMULATEX (0xff8000c0, 0xfb000000, PROBES_T32_MUL_ADD2,
526 REGS(NOSPPC, NOSPPCX, NOSPPC, 0, NOSPPC)),
527
528 /* Other unallocated instructions... */
529 DECODE_END
530};
531
532static const union decode_item t32_table_1111_1011_1[] = {
533 /* Long multiply, long multiply accumulate, and divide */
534
535 /* UMAAL 1111 1011 1110 xxxx xxxx xxxx 0110 xxxx */
536 DECODE_OR (0xfff000f0, 0xfbe00060),
537 /* SMLALxy 1111 1011 1100 xxxx xxxx xxxx 10xx xxxx */
538 DECODE_OR (0xfff000c0, 0xfbc00080),
539 /* SMLALD{X} 1111 1011 1100 xxxx xxxx xxxx 110x xxxx */
540 /* SMLSLD{X} 1111 1011 1101 xxxx xxxx xxxx 110x xxxx */
541 DECODE_OR (0xffe000e0, 0xfbc000c0),
542 /* SMULL 1111 1011 1000 xxxx xxxx xxxx 0000 xxxx */
543 /* UMULL 1111 1011 1010 xxxx xxxx xxxx 0000 xxxx */
544 /* SMLAL 1111 1011 1100 xxxx xxxx xxxx 0000 xxxx */
545 /* UMLAL 1111 1011 1110 xxxx xxxx xxxx 0000 xxxx */
546 DECODE_EMULATEX (0xff9000f0, 0xfb800000, PROBES_T32_MUL_ADD_LONG,
547 REGS(NOSPPC, NOSPPC, NOSPPC, 0, NOSPPC)),
548
549 /* SDIV 1111 1011 1001 xxxx xxxx xxxx 1111 xxxx */
550 /* UDIV 1111 1011 1011 xxxx xxxx xxxx 1111 xxxx */
551 /* Other unallocated instructions... */
552 DECODE_END
553};
554
555const union decode_item probes_decode_thumb32_table[] = {
556
557 /*
558 * Load/store multiple instructions
559 * 1110 100x x0xx xxxx xxxx xxxx xxxx xxxx
560 */
561 DECODE_TABLE (0xfe400000, 0xe8000000, t32_table_1110_100x_x0xx),
562
563 /*
564 * Load/store dual, load/store exclusive, table branch
565 * 1110 100x x1xx xxxx xxxx xxxx xxxx xxxx
566 */
567 DECODE_TABLE (0xfe400000, 0xe8400000, t32_table_1110_100x_x1xx),
568
569 /*
570 * Data-processing (shifted register)
571 * 1110 101x xxxx xxxx xxxx xxxx xxxx xxxx
572 */
573 DECODE_TABLE (0xfe000000, 0xea000000, t32_table_1110_101x),
574
575 /*
576 * Coprocessor instructions
577 * 1110 11xx xxxx xxxx xxxx xxxx xxxx xxxx
578 */
579 DECODE_REJECT (0xfc000000, 0xec000000),
580
581 /*
582 * Data-processing (modified immediate)
583 * 1111 0x0x xxxx xxxx 0xxx xxxx xxxx xxxx
584 */
585 DECODE_TABLE (0xfa008000, 0xf0000000, t32_table_1111_0x0x___0),
586
587 /*
588 * Data-processing (plain binary immediate)
589 * 1111 0x1x xxxx xxxx 0xxx xxxx xxxx xxxx
590 */
591 DECODE_TABLE (0xfa008000, 0xf2000000, t32_table_1111_0x1x___0),
592
593 /*
594 * Branches and miscellaneous control
595 * 1111 0xxx xxxx xxxx 1xxx xxxx xxxx xxxx
596 */
597 DECODE_TABLE (0xf8008000, 0xf0008000, t32_table_1111_0xxx___1),
598
599 /*
600 * Advanced SIMD element or structure load/store instructions
601 * 1111 1001 xxx0 xxxx xxxx xxxx xxxx xxxx
602 */
603 DECODE_REJECT (0xff100000, 0xf9000000),
604
605 /*
606 * Memory hints
607 * 1111 100x x0x1 xxxx 1111 xxxx xxxx xxxx
608 */
609 DECODE_TABLE (0xfe50f000, 0xf810f000, t32_table_1111_100x_x0x1__1111),
610
611 /*
612 * Store single data item
613 * 1111 1000 xxx0 xxxx xxxx xxxx xxxx xxxx
614 * Load single data items
615 * 1111 100x xxx1 xxxx xxxx xxxx xxxx xxxx
616 */
617 DECODE_TABLE (0xfe000000, 0xf8000000, t32_table_1111_100x),
618
619 /*
620 * Data-processing (register)
621 * 1111 1010 xxxx xxxx 1111 xxxx xxxx xxxx
622 */
623 DECODE_TABLE (0xff00f000, 0xfa00f000, t32_table_1111_1010___1111),
624
625 /*
626 * Multiply, multiply accumulate, and absolute difference
627 * 1111 1011 0xxx xxxx xxxx xxxx xxxx xxxx
628 */
629 DECODE_TABLE (0xff800000, 0xfb000000, t32_table_1111_1011_0),
630
631 /*
632 * Long multiply, long multiply accumulate, and divide
633 * 1111 1011 1xxx xxxx xxxx xxxx xxxx xxxx
634 */
635 DECODE_TABLE (0xff800000, 0xfb800000, t32_table_1111_1011_1),
636
637 /*
638 * Coprocessor instructions
639 * 1111 11xx xxxx xxxx xxxx xxxx xxxx xxxx
640 */
641 DECODE_END
642};
643#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
644EXPORT_SYMBOL_GPL(probes_decode_thumb32_table);
645#endif
646
647static const union decode_item t16_table_1011[] = {
648 /* Miscellaneous 16-bit instructions */
649
650 /* ADD (SP plus immediate) 1011 0000 0xxx xxxx */
651 /* SUB (SP minus immediate) 1011 0000 1xxx xxxx */
652 DECODE_SIMULATE (0xff00, 0xb000, PROBES_T16_ADD_SP),
653
654 /* CBZ 1011 00x1 xxxx xxxx */
655 /* CBNZ 1011 10x1 xxxx xxxx */
656 DECODE_SIMULATE (0xf500, 0xb100, PROBES_T16_CBZ),
657
658 /* SXTH 1011 0010 00xx xxxx */
659 /* SXTB 1011 0010 01xx xxxx */
660 /* UXTH 1011 0010 10xx xxxx */
661 /* UXTB 1011 0010 11xx xxxx */
662 /* REV 1011 1010 00xx xxxx */
663 /* REV16 1011 1010 01xx xxxx */
664 /* ??? 1011 1010 10xx xxxx */
665 /* REVSH 1011 1010 11xx xxxx */
666 DECODE_REJECT (0xffc0, 0xba80),
667 DECODE_EMULATE (0xf500, 0xb000, PROBES_T16_SIGN_EXTEND),
668
669 /* PUSH 1011 010x xxxx xxxx */
670 DECODE_CUSTOM (0xfe00, 0xb400, PROBES_T16_PUSH),
671 /* POP 1011 110x xxxx xxxx */
672 DECODE_CUSTOM (0xfe00, 0xbc00, PROBES_T16_POP),
673
674 /*
675 * If-Then, and hints
676 * 1011 1111 xxxx xxxx
677 */
678
679 /* YIELD 1011 1111 0001 0000 */
680 DECODE_OR (0xffff, 0xbf10),
681 /* SEV 1011 1111 0100 0000 */
682 DECODE_EMULATE (0xffff, 0xbf40, PROBES_T16_SEV),
683 /* NOP 1011 1111 0000 0000 */
684 /* WFE 1011 1111 0010 0000 */
685 /* WFI 1011 1111 0011 0000 */
686 DECODE_SIMULATE (0xffcf, 0xbf00, PROBES_T16_WFE),
687 /* Unassigned hints 1011 1111 xxxx 0000 */
688 DECODE_REJECT (0xff0f, 0xbf00),
689 /* IT 1011 1111 xxxx xxxx */
690 DECODE_CUSTOM (0xff00, 0xbf00, PROBES_T16_IT),
691
692 /* SETEND 1011 0110 010x xxxx */
693 /* CPS 1011 0110 011x xxxx */
694 /* BKPT 1011 1110 xxxx xxxx */
695 /* And unallocated instructions... */
696 DECODE_END
697};
698
699const union decode_item probes_decode_thumb16_table[] = {
700
701 /*
702 * Shift (immediate), add, subtract, move, and compare
703 * 00xx xxxx xxxx xxxx
704 */
705
706 /* CMP (immediate) 0010 1xxx xxxx xxxx */
707 DECODE_EMULATE (0xf800, 0x2800, PROBES_T16_CMP),
708
709 /* ADD (register) 0001 100x xxxx xxxx */
710 /* SUB (register) 0001 101x xxxx xxxx */
711 /* LSL (immediate) 0000 0xxx xxxx xxxx */
712 /* LSR (immediate) 0000 1xxx xxxx xxxx */
713 /* ASR (immediate) 0001 0xxx xxxx xxxx */
714 /* ADD (immediate, Thumb) 0001 110x xxxx xxxx */
715 /* SUB (immediate, Thumb) 0001 111x xxxx xxxx */
716 /* MOV (immediate) 0010 0xxx xxxx xxxx */
717 /* ADD (immediate, Thumb) 0011 0xxx xxxx xxxx */
718 /* SUB (immediate, Thumb) 0011 1xxx xxxx xxxx */
719 DECODE_EMULATE (0xc000, 0x0000, PROBES_T16_ADDSUB),
720
721 /*
722 * 16-bit Thumb data-processing instructions
723 * 0100 00xx xxxx xxxx
724 */
725
726 /* TST (register) 0100 0010 00xx xxxx */
727 DECODE_EMULATE (0xffc0, 0x4200, PROBES_T16_CMP),
728 /* CMP (register) 0100 0010 10xx xxxx */
729 /* CMN (register) 0100 0010 11xx xxxx */
730 DECODE_EMULATE (0xff80, 0x4280, PROBES_T16_CMP),
731 /* AND (register) 0100 0000 00xx xxxx */
732 /* EOR (register) 0100 0000 01xx xxxx */
733 /* LSL (register) 0100 0000 10xx xxxx */
734 /* LSR (register) 0100 0000 11xx xxxx */
735 /* ASR (register) 0100 0001 00xx xxxx */
736 /* ADC (register) 0100 0001 01xx xxxx */
737 /* SBC (register) 0100 0001 10xx xxxx */
738 /* ROR (register) 0100 0001 11xx xxxx */
739 /* RSB (immediate) 0100 0010 01xx xxxx */
740 /* ORR (register) 0100 0011 00xx xxxx */
741 /* MUL 0100 0011 00xx xxxx */
742 /* BIC (register) 0100 0011 10xx xxxx */
743 /* MVN (register) 0100 0011 10xx xxxx */
744 DECODE_EMULATE (0xfc00, 0x4000, PROBES_T16_LOGICAL),
745
746 /*
747 * Special data instructions and branch and exchange
748 * 0100 01xx xxxx xxxx
749 */
750
751 /* BLX pc 0100 0111 1111 1xxx */
752 DECODE_REJECT (0xfff8, 0x47f8),
753
754 /* BX (register) 0100 0111 0xxx xxxx */
755 /* BLX (register) 0100 0111 1xxx xxxx */
756 DECODE_SIMULATE (0xff00, 0x4700, PROBES_T16_BLX),
757
758 /* ADD pc, pc 0100 0100 1111 1111 */
759 DECODE_REJECT (0xffff, 0x44ff),
760
761 /* ADD (register) 0100 0100 xxxx xxxx */
762 /* CMP (register) 0100 0101 xxxx xxxx */
763 /* MOV (register) 0100 0110 xxxx xxxx */
764 DECODE_CUSTOM (0xfc00, 0x4400, PROBES_T16_HIREGOPS),
765
766 /*
767 * Load from Literal Pool
768 * LDR (literal) 0100 1xxx xxxx xxxx
769 */
770 DECODE_SIMULATE (0xf800, 0x4800, PROBES_T16_LDR_LIT),
771
772 /*
773 * 16-bit Thumb Load/store instructions
774 * 0101 xxxx xxxx xxxx
775 * 011x xxxx xxxx xxxx
776 * 100x xxxx xxxx xxxx
777 */
778
779 /* STR (register) 0101 000x xxxx xxxx */
780 /* STRH (register) 0101 001x xxxx xxxx */
781 /* STRB (register) 0101 010x xxxx xxxx */
782 /* LDRSB (register) 0101 011x xxxx xxxx */
783 /* LDR (register) 0101 100x xxxx xxxx */
784 /* LDRH (register) 0101 101x xxxx xxxx */
785 /* LDRB (register) 0101 110x xxxx xxxx */
786 /* LDRSH (register) 0101 111x xxxx xxxx */
787 /* STR (immediate, Thumb) 0110 0xxx xxxx xxxx */
788 /* LDR (immediate, Thumb) 0110 1xxx xxxx xxxx */
789 /* STRB (immediate, Thumb) 0111 0xxx xxxx xxxx */
790 /* LDRB (immediate, Thumb) 0111 1xxx xxxx xxxx */
791 DECODE_EMULATE (0xc000, 0x4000, PROBES_T16_LDRHSTRH),
792 /* STRH (immediate, Thumb) 1000 0xxx xxxx xxxx */
793 /* LDRH (immediate, Thumb) 1000 1xxx xxxx xxxx */
794 DECODE_EMULATE (0xf000, 0x8000, PROBES_T16_LDRHSTRH),
795 /* STR (immediate, Thumb) 1001 0xxx xxxx xxxx */
796 /* LDR (immediate, Thumb) 1001 1xxx xxxx xxxx */
797 DECODE_SIMULATE (0xf000, 0x9000, PROBES_T16_LDRSTR),
798
799 /*
800 * Generate PC-/SP-relative address
801 * ADR (literal) 1010 0xxx xxxx xxxx
802 * ADD (SP plus immediate) 1010 1xxx xxxx xxxx
803 */
804 DECODE_SIMULATE (0xf000, 0xa000, PROBES_T16_ADR),
805
806 /*
807 * Miscellaneous 16-bit instructions
808 * 1011 xxxx xxxx xxxx
809 */
810 DECODE_TABLE (0xf000, 0xb000, t16_table_1011),
811
812 /* STM 1100 0xxx xxxx xxxx */
813 /* LDM 1100 1xxx xxxx xxxx */
814 DECODE_EMULATE (0xf000, 0xc000, PROBES_T16_LDMSTM),
815
816 /*
817 * Conditional branch, and Supervisor Call
818 */
819
820 /* Permanently UNDEFINED 1101 1110 xxxx xxxx */
821 /* SVC 1101 1111 xxxx xxxx */
822 DECODE_REJECT (0xfe00, 0xde00),
823
824 /* Conditional branch 1101 xxxx xxxx xxxx */
825 DECODE_CUSTOM (0xf000, 0xd000, PROBES_T16_BRANCH_COND),
826
827 /*
828 * Unconditional branch
829 * B 1110 0xxx xxxx xxxx
830 */
831 DECODE_SIMULATE (0xf800, 0xe000, PROBES_T16_BRANCH),
832
833 DECODE_END
834};
835#ifdef CONFIG_ARM_KPROBES_TEST_MODULE
836EXPORT_SYMBOL_GPL(probes_decode_thumb16_table);
837#endif
838
839static unsigned long __kprobes thumb_check_cc(unsigned long cpsr)
840{
841 if (unlikely(in_it_block(cpsr)))
842 return probes_condition_checks[current_cond(cpsr)](cpsr);
843 return true;
844}
845
846static void __kprobes thumb16_singlestep(probes_opcode_t opcode,
847 struct arch_probes_insn *asi,
848 struct pt_regs *regs)
849{
850 regs->ARM_pc += 2;
851 asi->insn_handler(opcode, asi, regs);
852 regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
853}
854
855static void __kprobes thumb32_singlestep(probes_opcode_t opcode,
856 struct arch_probes_insn *asi,
857 struct pt_regs *regs)
858{
859 regs->ARM_pc += 4;
860 asi->insn_handler(opcode, asi, regs);
861 regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
862}
863
864enum probes_insn __kprobes
865thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
866 bool emulate, const union decode_action *actions)
867{
868 asi->insn_singlestep = thumb16_singlestep;
869 asi->insn_check_cc = thumb_check_cc;
870 return probes_decode_insn(insn, asi, probes_decode_thumb16_table, true,
871 emulate, actions);
872}
873
874enum probes_insn __kprobes
875thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
876 bool emulate, const union decode_action *actions)
877{
878 asi->insn_singlestep = thumb32_singlestep;
879 asi->insn_check_cc = thumb_check_cc;
880 return probes_decode_insn(insn, asi, probes_decode_thumb32_table, true,
881 emulate, actions);
882}
diff --git a/arch/arm/kernel/probes-thumb.h b/arch/arm/kernel/probes-thumb.h
new file mode 100644
index 000000000000..7c6f6ebe514f
--- /dev/null
+++ b/arch/arm/kernel/probes-thumb.h
@@ -0,0 +1,97 @@
1/*
2 * arch/arm/kernel/probes-thumb.h
3 *
4 * Copyright 2013 Linaro Ltd.
5 * Written by: David A. Long
6 *
7 * The code contained herein is licensed under the GNU General Public
8 * License. You may obtain a copy of the GNU General Public License
9 * Version 2 or later at the following locations:
10 *
11 * http://www.opensource.org/licenses/gpl-license.html
12 * http://www.gnu.org/copyleft/gpl.html
13 */
14
15#ifndef _ARM_KERNEL_PROBES_THUMB_H
16#define _ARM_KERNEL_PROBES_THUMB_H
17
18/*
19 * True if current instruction is in an IT block.
20 */
21#define in_it_block(cpsr) ((cpsr & 0x06000c00) != 0x00000000)
22
23/*
24 * Return the condition code to check for the currently executing instruction.
25 * This is in ITSTATE<7:4> which is in CPSR<15:12> but is only valid if
26 * in_it_block returns true.
27 */
28#define current_cond(cpsr) ((cpsr >> 12) & 0xf)
29
30enum probes_t32_action {
31 PROBES_T32_EMULATE_NONE,
32 PROBES_T32_SIMULATE_NOP,
33 PROBES_T32_LDMSTM,
34 PROBES_T32_LDRDSTRD,
35 PROBES_T32_TABLE_BRANCH,
36 PROBES_T32_TST,
37 PROBES_T32_CMP,
38 PROBES_T32_MOV,
39 PROBES_T32_ADDSUB,
40 PROBES_T32_LOGICAL,
41 PROBES_T32_ADDWSUBW_PC,
42 PROBES_T32_ADDWSUBW,
43 PROBES_T32_MOVW,
44 PROBES_T32_SAT,
45 PROBES_T32_BITFIELD,
46 PROBES_T32_SEV,
47 PROBES_T32_WFE,
48 PROBES_T32_MRS,
49 PROBES_T32_BRANCH_COND,
50 PROBES_T32_BRANCH,
51 PROBES_T32_PLDI,
52 PROBES_T32_LDR_LIT,
53 PROBES_T32_LDRSTR,
54 PROBES_T32_SIGN_EXTEND,
55 PROBES_T32_MEDIA,
56 PROBES_T32_REVERSE,
57 PROBES_T32_MUL_ADD,
58 PROBES_T32_MUL_ADD2,
59 PROBES_T32_MUL_ADD_LONG,
60 NUM_PROBES_T32_ACTIONS
61};
62
63enum probes_t16_action {
64 PROBES_T16_ADD_SP,
65 PROBES_T16_CBZ,
66 PROBES_T16_SIGN_EXTEND,
67 PROBES_T16_PUSH,
68 PROBES_T16_POP,
69 PROBES_T16_SEV,
70 PROBES_T16_WFE,
71 PROBES_T16_IT,
72 PROBES_T16_CMP,
73 PROBES_T16_ADDSUB,
74 PROBES_T16_LOGICAL,
75 PROBES_T16_BLX,
76 PROBES_T16_HIREGOPS,
77 PROBES_T16_LDR_LIT,
78 PROBES_T16_LDRHSTRH,
79 PROBES_T16_LDRSTR,
80 PROBES_T16_ADR,
81 PROBES_T16_LDMSTM,
82 PROBES_T16_BRANCH_COND,
83 PROBES_T16_BRANCH,
84 NUM_PROBES_T16_ACTIONS
85};
86
87extern const union decode_item probes_decode_thumb32_table[];
88extern const union decode_item probes_decode_thumb16_table[];
89
90enum probes_insn __kprobes
91thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
92 bool emulate, const union decode_action *actions);
93enum probes_insn __kprobes
94thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
95 bool emulate, const union decode_action *actions);
96
97#endif
diff --git a/arch/arm/kernel/probes.c b/arch/arm/kernel/probes.c
new file mode 100644
index 000000000000..b41873f33e69
--- /dev/null
+++ b/arch/arm/kernel/probes.c
@@ -0,0 +1,455 @@
1/*
2 * arch/arm/kernel/probes.c
3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 *
6 * Some contents moved here from arch/arm/include/asm/kprobes-arm.c which is
7 * Copyright (C) 2006, 2007 Motorola Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <asm/system_info.h>
17#include <asm/ptrace.h>
18#include <linux/bug.h>
19
20#include "probes.h"
21
22
23#ifndef find_str_pc_offset
24
25/*
26 * For STR and STM instructions, an ARM core may choose to use either
27 * a +8 or a +12 displacement from the current instruction's address.
28 * Whichever value is chosen for a given core, it must be the same for
29 * both instructions and may not change. This function measures it.
30 */
31
32int str_pc_offset;
33
34void __init find_str_pc_offset(void)
35{
36 int addr, scratch, ret;
37
38 __asm__ (
39 "sub %[ret], pc, #4 \n\t"
40 "str pc, %[addr] \n\t"
41 "ldr %[scr], %[addr] \n\t"
42 "sub %[ret], %[scr], %[ret] \n\t"
43 : [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr));
44
45 str_pc_offset = ret;
46}
47
48#endif /* !find_str_pc_offset */
49
50
51#ifndef test_load_write_pc_interworking
52
53bool load_write_pc_interworks;
54
55void __init test_load_write_pc_interworking(void)
56{
57 int arch = cpu_architecture();
58 BUG_ON(arch == CPU_ARCH_UNKNOWN);
59 load_write_pc_interworks = arch >= CPU_ARCH_ARMv5T;
60}
61
62#endif /* !test_load_write_pc_interworking */
63
64
65#ifndef test_alu_write_pc_interworking
66
67bool alu_write_pc_interworks;
68
69void __init test_alu_write_pc_interworking(void)
70{
71 int arch = cpu_architecture();
72 BUG_ON(arch == CPU_ARCH_UNKNOWN);
73 alu_write_pc_interworks = arch >= CPU_ARCH_ARMv7;
74}
75
76#endif /* !test_alu_write_pc_interworking */
77
78
79void __init arm_probes_decode_init(void)
80{
81 find_str_pc_offset();
82 test_load_write_pc_interworking();
83 test_alu_write_pc_interworking();
84}
85
86
87static unsigned long __kprobes __check_eq(unsigned long cpsr)
88{
89 return cpsr & PSR_Z_BIT;
90}
91
92static unsigned long __kprobes __check_ne(unsigned long cpsr)
93{
94 return (~cpsr) & PSR_Z_BIT;
95}
96
97static unsigned long __kprobes __check_cs(unsigned long cpsr)
98{
99 return cpsr & PSR_C_BIT;
100}
101
102static unsigned long __kprobes __check_cc(unsigned long cpsr)
103{
104 return (~cpsr) & PSR_C_BIT;
105}
106
107static unsigned long __kprobes __check_mi(unsigned long cpsr)
108{
109 return cpsr & PSR_N_BIT;
110}
111
112static unsigned long __kprobes __check_pl(unsigned long cpsr)
113{
114 return (~cpsr) & PSR_N_BIT;
115}
116
117static unsigned long __kprobes __check_vs(unsigned long cpsr)
118{
119 return cpsr & PSR_V_BIT;
120}
121
122static unsigned long __kprobes __check_vc(unsigned long cpsr)
123{
124 return (~cpsr) & PSR_V_BIT;
125}
126
127static unsigned long __kprobes __check_hi(unsigned long cpsr)
128{
129 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
130 return cpsr & PSR_C_BIT;
131}
132
133static unsigned long __kprobes __check_ls(unsigned long cpsr)
134{
135 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
136 return (~cpsr) & PSR_C_BIT;
137}
138
139static unsigned long __kprobes __check_ge(unsigned long cpsr)
140{
141 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
142 return (~cpsr) & PSR_N_BIT;
143}
144
145static unsigned long __kprobes __check_lt(unsigned long cpsr)
146{
147 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
148 return cpsr & PSR_N_BIT;
149}
150
151static unsigned long __kprobes __check_gt(unsigned long cpsr)
152{
153 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
154 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
155 return (~temp) & PSR_N_BIT;
156}
157
158static unsigned long __kprobes __check_le(unsigned long cpsr)
159{
160 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
161 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
162 return temp & PSR_N_BIT;
163}
164
165static unsigned long __kprobes __check_al(unsigned long cpsr)
166{
167 return true;
168}
169
170probes_check_cc * const probes_condition_checks[16] = {
171 &__check_eq, &__check_ne, &__check_cs, &__check_cc,
172 &__check_mi, &__check_pl, &__check_vs, &__check_vc,
173 &__check_hi, &__check_ls, &__check_ge, &__check_lt,
174 &__check_gt, &__check_le, &__check_al, &__check_al
175};
176
177
178void __kprobes probes_simulate_nop(probes_opcode_t opcode,
179 struct arch_probes_insn *asi,
180 struct pt_regs *regs)
181{
182}
183
184void __kprobes probes_emulate_none(probes_opcode_t opcode,
185 struct arch_probes_insn *asi,
186 struct pt_regs *regs)
187{
188 asi->insn_fn();
189}
190
191/*
192 * Prepare an instruction slot to receive an instruction for emulating.
193 * This is done by placing a subroutine return after the location where the
194 * instruction will be placed. We also modify ARM instructions to be
195 * unconditional as the condition code will already be checked before any
196 * emulation handler is called.
197 */
198static probes_opcode_t __kprobes
199prepare_emulated_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
200 bool thumb)
201{
202#ifdef CONFIG_THUMB2_KERNEL
203 if (thumb) {
204 u16 *thumb_insn = (u16 *)asi->insn;
205 thumb_insn[1] = 0x4770; /* Thumb bx lr */
206 thumb_insn[2] = 0x4770; /* Thumb bx lr */
207 return insn;
208 }
209 asi->insn[1] = 0xe12fff1e; /* ARM bx lr */
210#else
211 asi->insn[1] = 0xe1a0f00e; /* mov pc, lr */
212#endif
213 /* Make an ARM instruction unconditional */
214 if (insn < 0xe0000000)
215 insn = (insn | 0xe0000000) & ~0x10000000;
216 return insn;
217}
218
219/*
220 * Write a (probably modified) instruction into the slot previously prepared by
221 * prepare_emulated_insn
222 */
223static void __kprobes
224set_emulated_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
225 bool thumb)
226{
227#ifdef CONFIG_THUMB2_KERNEL
228 if (thumb) {
229 u16 *ip = (u16 *)asi->insn;
230 if (is_wide_instruction(insn))
231 *ip++ = insn >> 16;
232 *ip++ = insn;
233 return;
234 }
235#endif
236 asi->insn[0] = insn;
237}
238
239/*
240 * When we modify the register numbers encoded in an instruction to be emulated,
241 * the new values come from this define. For ARM and 32-bit Thumb instructions
242 * this gives...
243 *
244 * bit position 16 12 8 4 0
245 * ---------------+---+---+---+---+---+
246 * register r2 r0 r1 -- r3
247 */
248#define INSN_NEW_BITS 0x00020103
249
250/* Each nibble has same value as that at INSN_NEW_BITS bit 16 */
251#define INSN_SAMEAS16_BITS 0x22222222
252
253/*
254 * Validate and modify each of the registers encoded in an instruction.
255 *
256 * Each nibble in regs contains a value from enum decode_reg_type. For each
257 * non-zero value, the corresponding nibble in pinsn is validated and modified
258 * according to the type.
259 */
260static bool __kprobes decode_regs(probes_opcode_t *pinsn, u32 regs, bool modify)
261{
262 probes_opcode_t insn = *pinsn;
263 probes_opcode_t mask = 0xf; /* Start at least significant nibble */
264
265 for (; regs != 0; regs >>= 4, mask <<= 4) {
266
267 probes_opcode_t new_bits = INSN_NEW_BITS;
268
269 switch (regs & 0xf) {
270
271 case REG_TYPE_NONE:
272 /* Nibble not a register, skip to next */
273 continue;
274
275 case REG_TYPE_ANY:
276 /* Any register is allowed */
277 break;
278
279 case REG_TYPE_SAMEAS16:
280 /* Replace register with same as at bit position 16 */
281 new_bits = INSN_SAMEAS16_BITS;
282 break;
283
284 case REG_TYPE_SP:
285 /* Only allow SP (R13) */
286 if ((insn ^ 0xdddddddd) & mask)
287 goto reject;
288 break;
289
290 case REG_TYPE_PC:
291 /* Only allow PC (R15) */
292 if ((insn ^ 0xffffffff) & mask)
293 goto reject;
294 break;
295
296 case REG_TYPE_NOSP:
297 /* Reject SP (R13) */
298 if (((insn ^ 0xdddddddd) & mask) == 0)
299 goto reject;
300 break;
301
302 case REG_TYPE_NOSPPC:
303 case REG_TYPE_NOSPPCX:
304 /* Reject SP and PC (R13 and R15) */
305 if (((insn ^ 0xdddddddd) & 0xdddddddd & mask) == 0)
306 goto reject;
307 break;
308
309 case REG_TYPE_NOPCWB:
310 if (!is_writeback(insn))
311 break; /* No writeback, so any register is OK */
312 /* fall through... */
313 case REG_TYPE_NOPC:
314 case REG_TYPE_NOPCX:
315 /* Reject PC (R15) */
316 if (((insn ^ 0xffffffff) & mask) == 0)
317 goto reject;
318 break;
319 }
320
321 /* Replace value of nibble with new register number... */
322 insn &= ~mask;
323 insn |= new_bits & mask;
324 }
325
326 if (modify)
327 *pinsn = insn;
328
329 return true;
330
331reject:
332 return false;
333}
334
335static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
336 [DECODE_TYPE_TABLE] = sizeof(struct decode_table),
337 [DECODE_TYPE_CUSTOM] = sizeof(struct decode_custom),
338 [DECODE_TYPE_SIMULATE] = sizeof(struct decode_simulate),
339 [DECODE_TYPE_EMULATE] = sizeof(struct decode_emulate),
340 [DECODE_TYPE_OR] = sizeof(struct decode_or),
341 [DECODE_TYPE_REJECT] = sizeof(struct decode_reject)
342};
343
344/*
345 * probes_decode_insn operates on data tables in order to decode an ARM
346 * architecture instruction onto which a kprobe has been placed.
347 *
348 * These instruction decoding tables are a concatenation of entries each
349 * of which consist of one of the following structs:
350 *
351 * decode_table
352 * decode_custom
353 * decode_simulate
354 * decode_emulate
355 * decode_or
356 * decode_reject
357 *
358 * Each of these starts with a struct decode_header which has the following
359 * fields:
360 *
361 * type_regs
362 * mask
363 * value
364 *
365 * The least significant DECODE_TYPE_BITS of type_regs contains a value
366 * from enum decode_type, this indicates which of the decode_* structs
367 * the entry contains. The value DECODE_TYPE_END indicates the end of the
368 * table.
369 *
370 * When the table is parsed, each entry is checked in turn to see if it
371 * matches the instruction to be decoded using the test:
372 *
373 * (insn & mask) == value
374 *
375 * If no match is found before the end of the table is reached then decoding
376 * fails with INSN_REJECTED.
377 *
378 * When a match is found, decode_regs() is called to validate and modify each
379 * of the registers encoded in the instruction; the data it uses to do this
380 * is (type_regs >> DECODE_TYPE_BITS). A validation failure will cause decoding
381 * to fail with INSN_REJECTED.
382 *
383 * Once the instruction has passed the above tests, further processing
384 * depends on the type of the table entry's decode struct.
385 *
386 */
387int __kprobes
388probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
389 const union decode_item *table, bool thumb,
390 bool emulate, const union decode_action *actions)
391{
392 const struct decode_header *h = (struct decode_header *)table;
393 const struct decode_header *next;
394 bool matched = false;
395
396 if (emulate)
397 insn = prepare_emulated_insn(insn, asi, thumb);
398
399 for (;; h = next) {
400 enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK;
401 u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS;
402
403 if (type == DECODE_TYPE_END)
404 return INSN_REJECTED;
405
406 next = (struct decode_header *)
407 ((uintptr_t)h + decode_struct_sizes[type]);
408
409 if (!matched && (insn & h->mask.bits) != h->value.bits)
410 continue;
411
412 if (!decode_regs(&insn, regs, emulate))
413 return INSN_REJECTED;
414
415 switch (type) {
416
417 case DECODE_TYPE_TABLE: {
418 struct decode_table *d = (struct decode_table *)h;
419 next = (struct decode_header *)d->table.table;
420 break;
421 }
422
423 case DECODE_TYPE_CUSTOM: {
424 struct decode_custom *d = (struct decode_custom *)h;
425 return actions[d->decoder.action].decoder(insn, asi, h);
426 }
427
428 case DECODE_TYPE_SIMULATE: {
429 struct decode_simulate *d = (struct decode_simulate *)h;
430 asi->insn_handler = actions[d->handler.action].handler;
431 return INSN_GOOD_NO_SLOT;
432 }
433
434 case DECODE_TYPE_EMULATE: {
435 struct decode_emulate *d = (struct decode_emulate *)h;
436
437 if (!emulate)
438 return actions[d->handler.action].decoder(insn,
439 asi, h);
440
441 asi->insn_handler = actions[d->handler.action].handler;
442 set_emulated_insn(insn, asi, thumb);
443 return INSN_GOOD;
444 }
445
446 case DECODE_TYPE_OR:
447 matched = true;
448 break;
449
450 case DECODE_TYPE_REJECT:
451 default:
452 return INSN_REJECTED;
453 }
454 }
455}
diff --git a/arch/arm/kernel/probes.h b/arch/arm/kernel/probes.h
new file mode 100644
index 000000000000..dba9f2466a93
--- /dev/null
+++ b/arch/arm/kernel/probes.h
@@ -0,0 +1,407 @@
1/*
2 * arch/arm/kernel/probes.h
3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 *
6 * Some contents moved here from arch/arm/include/asm/kprobes.h which is
7 * Copyright (C) 2006, 2007 Motorola Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 */
18
19#ifndef _ARM_KERNEL_PROBES_H
20#define _ARM_KERNEL_PROBES_H
21
22#include <linux/types.h>
23#include <linux/stddef.h>
24#include <asm/probes.h>
25
26void __init arm_probes_decode_init(void);
27
28extern probes_check_cc * const probes_condition_checks[16];
29
30#if __LINUX_ARM_ARCH__ >= 7
31
32/* str_pc_offset is architecturally defined from ARMv7 onwards */
33#define str_pc_offset 8
34#define find_str_pc_offset()
35
36#else /* __LINUX_ARM_ARCH__ < 7 */
37
38/* We need a run-time check to determine str_pc_offset */
39extern int str_pc_offset;
40void __init find_str_pc_offset(void);
41
42#endif
43
44
45/*
46 * Update ITSTATE after normal execution of an IT block instruction.
47 *
48 * The 8 IT state bits are split into two parts in CPSR:
49 * ITSTATE<1:0> are in CPSR<26:25>
50 * ITSTATE<7:2> are in CPSR<15:10>
51 */
52static inline unsigned long it_advance(unsigned long cpsr)
53 {
54 if ((cpsr & 0x06000400) == 0) {
55 /* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */
56 cpsr &= ~PSR_IT_MASK;
57 } else {
58 /* We need to shift left ITSTATE<4:0> */
59 const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */
60 unsigned long it = cpsr & mask;
61 it <<= 1;
62 it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */
63 it &= mask;
64 cpsr &= ~mask;
65 cpsr |= it;
66 }
67 return cpsr;
68}
69
70static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs)
71{
72 long cpsr = regs->ARM_cpsr;
73 if (pcv & 0x1) {
74 cpsr |= PSR_T_BIT;
75 pcv &= ~0x1;
76 } else {
77 cpsr &= ~PSR_T_BIT;
78 pcv &= ~0x2; /* Avoid UNPREDICTABLE address allignment */
79 }
80 regs->ARM_cpsr = cpsr;
81 regs->ARM_pc = pcv;
82}
83
84
85#if __LINUX_ARM_ARCH__ >= 6
86
87/* Kernels built for >= ARMv6 should never run on <= ARMv5 hardware, so... */
88#define load_write_pc_interworks true
89#define test_load_write_pc_interworking()
90
91#else /* __LINUX_ARM_ARCH__ < 6 */
92
93/* We need run-time testing to determine if load_write_pc() should interwork. */
94extern bool load_write_pc_interworks;
95void __init test_load_write_pc_interworking(void);
96
97#endif
98
99static inline void __kprobes load_write_pc(long pcv, struct pt_regs *regs)
100{
101 if (load_write_pc_interworks)
102 bx_write_pc(pcv, regs);
103 else
104 regs->ARM_pc = pcv;
105}
106
107
108#if __LINUX_ARM_ARCH__ >= 7
109
110#define alu_write_pc_interworks true
111#define test_alu_write_pc_interworking()
112
113#elif __LINUX_ARM_ARCH__ <= 5
114
115/* Kernels built for <= ARMv5 should never run on >= ARMv6 hardware, so... */
116#define alu_write_pc_interworks false
117#define test_alu_write_pc_interworking()
118
119#else /* __LINUX_ARM_ARCH__ == 6 */
120
121/* We could be an ARMv6 binary on ARMv7 hardware so we need a run-time check. */
122extern bool alu_write_pc_interworks;
123void __init test_alu_write_pc_interworking(void);
124
125#endif /* __LINUX_ARM_ARCH__ == 6 */
126
127static inline void __kprobes alu_write_pc(long pcv, struct pt_regs *regs)
128{
129 if (alu_write_pc_interworks)
130 bx_write_pc(pcv, regs);
131 else
132 regs->ARM_pc = pcv;
133}
134
135
136/*
137 * Test if load/store instructions writeback the address register.
138 * if P (bit 24) == 0 or W (bit 21) == 1
139 */
140#define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000)
141
142/*
143 * The following definitions and macros are used to build instruction
144 * decoding tables for use by probes_decode_insn.
145 *
146 * These tables are a concatenation of entries each of which consist of one of
147 * the decode_* structs. All of the fields in every type of decode structure
148 * are of the union type decode_item, therefore the entire decode table can be
149 * viewed as an array of these and declared like:
150 *
151 * static const union decode_item table_name[] = {};
152 *
153 * In order to construct each entry in the table, macros are used to
154 * initialise a number of sequential decode_item values in a layout which
155 * matches the relevant struct. E.g. DECODE_SIMULATE initialise a struct
156 * decode_simulate by initialising four decode_item objects like this...
157 *
158 * {.bits = _type},
159 * {.bits = _mask},
160 * {.bits = _value},
161 * {.action = _handler},
162 *
163 * Initialising a specified member of the union means that the compiler
164 * will produce a warning if the argument is of an incorrect type.
165 *
166 * Below is a list of each of the macros used to initialise entries and a
167 * description of the action performed when that entry is matched to an
168 * instruction. A match is found when (instruction & mask) == value.
169 *
170 * DECODE_TABLE(mask, value, table)
171 * Instruction decoding jumps to parsing the new sub-table 'table'.
172 *
173 * DECODE_CUSTOM(mask, value, decoder)
174 * The value of 'decoder' is used as an index into the array of
175 * action functions, and the retrieved decoder function is invoked
176 * to complete decoding of the instruction.
177 *
178 * DECODE_SIMULATE(mask, value, handler)
179 * The probes instruction handler is set to the value found by
180 * indexing into the action array using the value of 'handler'. This
181 * will be used to simulate the instruction when the probe is hit.
182 * Decoding returns with INSN_GOOD_NO_SLOT.
183 *
184 * DECODE_EMULATE(mask, value, handler)
185 * The probes instruction handler is set to the value found by
186 * indexing into the action array using the value of 'handler'. This
187 * will be used to emulate the instruction when the probe is hit. The
188 * modified instruction (see below) is placed in the probes instruction
189 * slot so it may be called by the emulation code. Decoding returns
190 * with INSN_GOOD.
191 *
192 * DECODE_REJECT(mask, value)
193 * Instruction decoding fails with INSN_REJECTED
194 *
195 * DECODE_OR(mask, value)
196 * This allows the mask/value test of multiple table entries to be
197 * logically ORed. Once an 'or' entry is matched the decoding action to
198 * be performed is that of the next entry which isn't an 'or'. E.g.
199 *
200 * DECODE_OR (mask1, value1)
201 * DECODE_OR (mask2, value2)
202 * DECODE_SIMULATE (mask3, value3, simulation_handler)
203 *
204 * This means that if any of the three mask/value pairs match the
205 * instruction being decoded, then 'simulation_handler' will be used
206 * for it.
207 *
208 * Both the SIMULATE and EMULATE macros have a second form which take an
209 * additional 'regs' argument.
210 *
211 * DECODE_SIMULATEX(mask, value, handler, regs)
212 * DECODE_EMULATEX (mask, value, handler, regs)
213 *
214 * These are used to specify what kind of CPU register is encoded in each of the
215 * least significant 5 nibbles of the instruction being decoded. The regs value
216 * is specified using the REGS macro, this takes any of the REG_TYPE_* values
217 * from enum decode_reg_type as arguments; only the '*' part of the name is
218 * given. E.g.
219 *
220 * REGS(0, ANY, NOPC, 0, ANY)
221 *
222 * This indicates an instruction is encoded like:
223 *
224 * bits 19..16 ignore
225 * bits 15..12 any register allowed here
226 * bits 11.. 8 any register except PC allowed here
227 * bits 7.. 4 ignore
228 * bits 3.. 0 any register allowed here
229 *
230 * This register specification is checked after a decode table entry is found to
231 * match an instruction (through the mask/value test). Any invalid register then
232 * found in the instruction will cause decoding to fail with INSN_REJECTED. In
233 * the above example this would happen if bits 11..8 of the instruction were
234 * 1111, indicating R15 or PC.
235 *
236 * As well as checking for legal combinations of registers, this data is also
237 * used to modify the registers encoded in the instructions so that an
238 * emulation routines can use it. (See decode_regs() and INSN_NEW_BITS.)
239 *
240 * Here is a real example which matches ARM instructions of the form
241 * "AND <Rd>,<Rn>,<Rm>,<shift> <Rs>"
242 *
243 * DECODE_EMULATEX (0x0e000090, 0x00000010, PROBES_DATA_PROCESSING_REG,
244 * REGS(ANY, ANY, NOPC, 0, ANY)),
245 * ^ ^ ^ ^
246 * Rn Rd Rs Rm
247 *
248 * Decoding the instruction "AND R4, R5, R6, ASL R15" will be rejected because
249 * Rs == R15
250 *
251 * Decoding the instruction "AND R4, R5, R6, ASL R7" will be accepted and the
252 * instruction will be modified to "AND R0, R2, R3, ASL R1" and then placed into
253 * the kprobes instruction slot. This can then be called later by the handler
254 * function emulate_rd12rn16rm0rs8_rwflags (a pointer to which is retrieved from
255 * the indicated slot in the action array), in order to simulate the instruction.
256 */
257
258enum decode_type {
259 DECODE_TYPE_END,
260 DECODE_TYPE_TABLE,
261 DECODE_TYPE_CUSTOM,
262 DECODE_TYPE_SIMULATE,
263 DECODE_TYPE_EMULATE,
264 DECODE_TYPE_OR,
265 DECODE_TYPE_REJECT,
266 NUM_DECODE_TYPES /* Must be last enum */
267};
268
269#define DECODE_TYPE_BITS 4
270#define DECODE_TYPE_MASK ((1 << DECODE_TYPE_BITS) - 1)
271
272enum decode_reg_type {
273 REG_TYPE_NONE = 0, /* Not a register, ignore */
274 REG_TYPE_ANY, /* Any register allowed */
275 REG_TYPE_SAMEAS16, /* Register should be same as that at bits 19..16 */
276 REG_TYPE_SP, /* Register must be SP */
277 REG_TYPE_PC, /* Register must be PC */
278 REG_TYPE_NOSP, /* Register must not be SP */
279 REG_TYPE_NOSPPC, /* Register must not be SP or PC */
280 REG_TYPE_NOPC, /* Register must not be PC */
281 REG_TYPE_NOPCWB, /* No PC if load/store write-back flag also set */
282
283 /* The following types are used when the encoding for PC indicates
284 * another instruction form. This distiction only matters for test
285 * case coverage checks.
286 */
287 REG_TYPE_NOPCX, /* Register must not be PC */
288 REG_TYPE_NOSPPCX, /* Register must not be SP or PC */
289
290 /* Alias to allow '0' arg to be used in REGS macro. */
291 REG_TYPE_0 = REG_TYPE_NONE
292};
293
294#define REGS(r16, r12, r8, r4, r0) \
295 (((REG_TYPE_##r16) << 16) + \
296 ((REG_TYPE_##r12) << 12) + \
297 ((REG_TYPE_##r8) << 8) + \
298 ((REG_TYPE_##r4) << 4) + \
299 (REG_TYPE_##r0))
300
301union decode_item {
302 u32 bits;
303 const union decode_item *table;
304 int action;
305};
306
307struct decode_header;
308typedef enum probes_insn (probes_custom_decode_t)(probes_opcode_t,
309 struct arch_probes_insn *,
310 const struct decode_header *);
311
312union decode_action {
313 probes_insn_handler_t *handler;
314 probes_custom_decode_t *decoder;
315};
316
317#define DECODE_END \
318 {.bits = DECODE_TYPE_END}
319
320
321struct decode_header {
322 union decode_item type_regs;
323 union decode_item mask;
324 union decode_item value;
325};
326
327#define DECODE_HEADER(_type, _mask, _value, _regs) \
328 {.bits = (_type) | ((_regs) << DECODE_TYPE_BITS)}, \
329 {.bits = (_mask)}, \
330 {.bits = (_value)}
331
332
333struct decode_table {
334 struct decode_header header;
335 union decode_item table;
336};
337
338#define DECODE_TABLE(_mask, _value, _table) \
339 DECODE_HEADER(DECODE_TYPE_TABLE, _mask, _value, 0), \
340 {.table = (_table)}
341
342
343struct decode_custom {
344 struct decode_header header;
345 union decode_item decoder;
346};
347
348#define DECODE_CUSTOM(_mask, _value, _decoder) \
349 DECODE_HEADER(DECODE_TYPE_CUSTOM, _mask, _value, 0), \
350 {.action = (_decoder)}
351
352
353struct decode_simulate {
354 struct decode_header header;
355 union decode_item handler;
356};
357
358#define DECODE_SIMULATEX(_mask, _value, _handler, _regs) \
359 DECODE_HEADER(DECODE_TYPE_SIMULATE, _mask, _value, _regs), \
360 {.action = (_handler)}
361
362#define DECODE_SIMULATE(_mask, _value, _handler) \
363 DECODE_SIMULATEX(_mask, _value, _handler, 0)
364
365
366struct decode_emulate {
367 struct decode_header header;
368 union decode_item handler;
369};
370
371#define DECODE_EMULATEX(_mask, _value, _handler, _regs) \
372 DECODE_HEADER(DECODE_TYPE_EMULATE, _mask, _value, _regs), \
373 {.action = (_handler)}
374
375#define DECODE_EMULATE(_mask, _value, _handler) \
376 DECODE_EMULATEX(_mask, _value, _handler, 0)
377
378
379struct decode_or {
380 struct decode_header header;
381};
382
383#define DECODE_OR(_mask, _value) \
384 DECODE_HEADER(DECODE_TYPE_OR, _mask, _value, 0)
385
386enum probes_insn {
387 INSN_REJECTED,
388 INSN_GOOD,
389 INSN_GOOD_NO_SLOT
390};
391
392struct decode_reject {
393 struct decode_header header;
394};
395
396#define DECODE_REJECT(_mask, _value) \
397 DECODE_HEADER(DECODE_TYPE_REJECT, _mask, _value, 0)
398
399probes_insn_handler_t probes_simulate_nop;
400probes_insn_handler_t probes_emulate_none;
401
402int __kprobes
403probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
404 const union decode_item *table, bool thumb, bool emulate,
405 const union decode_action *actions);
406
407#endif
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index adabeababeb0..806d287e3e53 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -47,14 +47,14 @@ unsigned long __stack_chk_guard __read_mostly;
47EXPORT_SYMBOL(__stack_chk_guard); 47EXPORT_SYMBOL(__stack_chk_guard);
48#endif 48#endif
49 49
50static const char *processor_modes[] = { 50static const char *processor_modes[] __maybe_unused = {
51 "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" , 51 "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
52 "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26", 52 "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
53 "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" , 53 "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
54 "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32" 54 "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
55}; 55};
56 56
57static const char *isa_modes[] = { 57static const char *isa_modes[] __maybe_unused = {
58 "ARM" , "Thumb" , "Jazelle", "ThumbEE" 58 "ARM" , "Thumb" , "Jazelle", "ThumbEE"
59}; 59};
60 60
@@ -270,12 +270,17 @@ void __show_regs(struct pt_regs *regs)
270 buf[3] = flags & PSR_V_BIT ? 'V' : 'v'; 270 buf[3] = flags & PSR_V_BIT ? 'V' : 'v';
271 buf[4] = '\0'; 271 buf[4] = '\0';
272 272
273#ifndef CONFIG_CPU_V7M
273 printk("Flags: %s IRQs o%s FIQs o%s Mode %s ISA %s Segment %s\n", 274 printk("Flags: %s IRQs o%s FIQs o%s Mode %s ISA %s Segment %s\n",
274 buf, interrupts_enabled(regs) ? "n" : "ff", 275 buf, interrupts_enabled(regs) ? "n" : "ff",
275 fast_interrupts_enabled(regs) ? "n" : "ff", 276 fast_interrupts_enabled(regs) ? "n" : "ff",
276 processor_modes[processor_mode(regs)], 277 processor_modes[processor_mode(regs)],
277 isa_modes[isa_mode(regs)], 278 isa_modes[isa_mode(regs)],
278 get_fs() == get_ds() ? "kernel" : "user"); 279 get_fs() == get_ds() ? "kernel" : "user");
280#else
281 printk("xPSR: %08lx\n", regs->ARM_cpsr);
282#endif
283
279#ifdef CONFIG_CPU_CP15 284#ifdef CONFIG_CPU_CP15
280 { 285 {
281 unsigned int ctrl; 286 unsigned int ctrl;
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 1e8b030dbefd..50e198c1e9c8 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -100,6 +100,9 @@ EXPORT_SYMBOL(system_serial_high);
100unsigned int elf_hwcap __read_mostly; 100unsigned int elf_hwcap __read_mostly;
101EXPORT_SYMBOL(elf_hwcap); 101EXPORT_SYMBOL(elf_hwcap);
102 102
103unsigned int elf_hwcap2 __read_mostly;
104EXPORT_SYMBOL(elf_hwcap2);
105
103 106
104#ifdef MULTI_CPU 107#ifdef MULTI_CPU
105struct processor processor __read_mostly; 108struct processor processor __read_mostly;
@@ -1005,6 +1008,15 @@ static const char *hwcap_str[] = {
1005 NULL 1008 NULL
1006}; 1009};
1007 1010
1011static const char *hwcap2_str[] = {
1012 "aes",
1013 "pmull",
1014 "sha1",
1015 "sha2",
1016 "crc32",
1017 NULL
1018};
1019
1008static int c_show(struct seq_file *m, void *v) 1020static int c_show(struct seq_file *m, void *v)
1009{ 1021{
1010 int i, j; 1022 int i, j;
@@ -1028,6 +1040,10 @@ static int c_show(struct seq_file *m, void *v)
1028 if (elf_hwcap & (1 << j)) 1040 if (elf_hwcap & (1 << j))
1029 seq_printf(m, "%s ", hwcap_str[j]); 1041 seq_printf(m, "%s ", hwcap_str[j]);
1030 1042
1043 for (j = 0; hwcap2_str[j]; j++)
1044 if (elf_hwcap2 & (1 << j))
1045 seq_printf(m, "%s ", hwcap2_str[j]);
1046
1031 seq_printf(m, "\nCPU implementer\t: 0x%02x\n", cpuid >> 24); 1047 seq_printf(m, "\nCPU implementer\t: 0x%02x\n", cpuid >> 24);
1032 seq_printf(m, "CPU architecture: %s\n", 1048 seq_printf(m, "CPU architecture: %s\n",
1033 proc_arch[cpu_architecture()]); 1049 proc_arch[cpu_architecture()]);
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 04d63880037f..bd1983437205 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -13,6 +13,7 @@
13#include <linux/personality.h> 13#include <linux/personality.h>
14#include <linux/uaccess.h> 14#include <linux/uaccess.h>
15#include <linux/tracehook.h> 15#include <linux/tracehook.h>
16#include <linux/uprobes.h>
16 17
17#include <asm/elf.h> 18#include <asm/elf.h>
18#include <asm/cacheflush.h> 19#include <asm/cacheflush.h>
@@ -590,6 +591,9 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
590 return restart; 591 return restart;
591 } 592 }
592 syscall = 0; 593 syscall = 0;
594 } else if (thread_flags & _TIF_UPROBE) {
595 clear_thread_flag(TIF_UPROBE);
596 uprobe_notify_resume(regs);
593 } else { 597 } else {
594 clear_thread_flag(TIF_NOTIFY_RESUME); 598 clear_thread_flag(TIF_NOTIFY_RESUME);
595 tracehook_notify_resume(regs); 599 tracehook_notify_resume(regs);
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 00df012c4678..3c217694ebec 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -68,6 +68,12 @@ EXPORT_SYMBOL(__aeabi_unwind_cpp_pr2);
68struct unwind_ctrl_block { 68struct unwind_ctrl_block {
69 unsigned long vrs[16]; /* virtual register set */ 69 unsigned long vrs[16]; /* virtual register set */
70 const unsigned long *insn; /* pointer to the current instructions word */ 70 const unsigned long *insn; /* pointer to the current instructions word */
71 unsigned long sp_high; /* highest value of sp allowed */
72 /*
73 * 1 : check for stack overflow for each register pop.
74 * 0 : save overhead if there is plenty of stack remaining.
75 */
76 int check_each_pop;
71 int entries; /* number of entries left to interpret */ 77 int entries; /* number of entries left to interpret */
72 int byte; /* current byte number in the instructions word */ 78 int byte; /* current byte number in the instructions word */
73}; 79};
@@ -235,12 +241,85 @@ static unsigned long unwind_get_byte(struct unwind_ctrl_block *ctrl)
235 return ret; 241 return ret;
236} 242}
237 243
244/* Before poping a register check whether it is feasible or not */
245static int unwind_pop_register(struct unwind_ctrl_block *ctrl,
246 unsigned long **vsp, unsigned int reg)
247{
248 if (unlikely(ctrl->check_each_pop))
249 if (*vsp >= (unsigned long *)ctrl->sp_high)
250 return -URC_FAILURE;
251
252 ctrl->vrs[reg] = *(*vsp)++;
253 return URC_OK;
254}
255
256/* Helper functions to execute the instructions */
257static int unwind_exec_pop_subset_r4_to_r13(struct unwind_ctrl_block *ctrl,
258 unsigned long mask)
259{
260 unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
261 int load_sp, reg = 4;
262
263 load_sp = mask & (1 << (13 - 4));
264 while (mask) {
265 if (mask & 1)
266 if (unwind_pop_register(ctrl, &vsp, reg))
267 return -URC_FAILURE;
268 mask >>= 1;
269 reg++;
270 }
271 if (!load_sp)
272 ctrl->vrs[SP] = (unsigned long)vsp;
273
274 return URC_OK;
275}
276
277static int unwind_exec_pop_r4_to_rN(struct unwind_ctrl_block *ctrl,
278 unsigned long insn)
279{
280 unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
281 int reg;
282
283 /* pop R4-R[4+bbb] */
284 for (reg = 4; reg <= 4 + (insn & 7); reg++)
285 if (unwind_pop_register(ctrl, &vsp, reg))
286 return -URC_FAILURE;
287
288 if (insn & 0x80)
289 if (unwind_pop_register(ctrl, &vsp, 14))
290 return -URC_FAILURE;
291
292 ctrl->vrs[SP] = (unsigned long)vsp;
293
294 return URC_OK;
295}
296
297static int unwind_exec_pop_subset_r0_to_r3(struct unwind_ctrl_block *ctrl,
298 unsigned long mask)
299{
300 unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
301 int reg = 0;
302
303 /* pop R0-R3 according to mask */
304 while (mask) {
305 if (mask & 1)
306 if (unwind_pop_register(ctrl, &vsp, reg))
307 return -URC_FAILURE;
308 mask >>= 1;
309 reg++;
310 }
311 ctrl->vrs[SP] = (unsigned long)vsp;
312
313 return URC_OK;
314}
315
238/* 316/*
239 * Execute the current unwind instruction. 317 * Execute the current unwind instruction.
240 */ 318 */
241static int unwind_exec_insn(struct unwind_ctrl_block *ctrl) 319static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
242{ 320{
243 unsigned long insn = unwind_get_byte(ctrl); 321 unsigned long insn = unwind_get_byte(ctrl);
322 int ret = URC_OK;
244 323
245 pr_debug("%s: insn = %08lx\n", __func__, insn); 324 pr_debug("%s: insn = %08lx\n", __func__, insn);
246 325
@@ -250,8 +329,6 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
250 ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4; 329 ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4;
251 else if ((insn & 0xf0) == 0x80) { 330 else if ((insn & 0xf0) == 0x80) {
252 unsigned long mask; 331 unsigned long mask;
253 unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
254 int load_sp, reg = 4;
255 332
256 insn = (insn << 8) | unwind_get_byte(ctrl); 333 insn = (insn << 8) | unwind_get_byte(ctrl);
257 mask = insn & 0x0fff; 334 mask = insn & 0x0fff;
@@ -261,29 +338,16 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
261 return -URC_FAILURE; 338 return -URC_FAILURE;
262 } 339 }
263 340
264 /* pop R4-R15 according to mask */ 341 ret = unwind_exec_pop_subset_r4_to_r13(ctrl, mask);
265 load_sp = mask & (1 << (13 - 4)); 342 if (ret)
266 while (mask) { 343 goto error;
267 if (mask & 1)
268 ctrl->vrs[reg] = *vsp++;
269 mask >>= 1;
270 reg++;
271 }
272 if (!load_sp)
273 ctrl->vrs[SP] = (unsigned long)vsp;
274 } else if ((insn & 0xf0) == 0x90 && 344 } else if ((insn & 0xf0) == 0x90 &&
275 (insn & 0x0d) != 0x0d) 345 (insn & 0x0d) != 0x0d)
276 ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f]; 346 ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f];
277 else if ((insn & 0xf0) == 0xa0) { 347 else if ((insn & 0xf0) == 0xa0) {
278 unsigned long *vsp = (unsigned long *)ctrl->vrs[SP]; 348 ret = unwind_exec_pop_r4_to_rN(ctrl, insn);
279 int reg; 349 if (ret)
280 350 goto error;
281 /* pop R4-R[4+bbb] */
282 for (reg = 4; reg <= 4 + (insn & 7); reg++)
283 ctrl->vrs[reg] = *vsp++;
284 if (insn & 0x80)
285 ctrl->vrs[14] = *vsp++;
286 ctrl->vrs[SP] = (unsigned long)vsp;
287 } else if (insn == 0xb0) { 351 } else if (insn == 0xb0) {
288 if (ctrl->vrs[PC] == 0) 352 if (ctrl->vrs[PC] == 0)
289 ctrl->vrs[PC] = ctrl->vrs[LR]; 353 ctrl->vrs[PC] = ctrl->vrs[LR];
@@ -291,8 +355,6 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
291 ctrl->entries = 0; 355 ctrl->entries = 0;
292 } else if (insn == 0xb1) { 356 } else if (insn == 0xb1) {
293 unsigned long mask = unwind_get_byte(ctrl); 357 unsigned long mask = unwind_get_byte(ctrl);
294 unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
295 int reg = 0;
296 358
297 if (mask == 0 || mask & 0xf0) { 359 if (mask == 0 || mask & 0xf0) {
298 pr_warning("unwind: Spare encoding %04lx\n", 360 pr_warning("unwind: Spare encoding %04lx\n",
@@ -300,14 +362,9 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
300 return -URC_FAILURE; 362 return -URC_FAILURE;
301 } 363 }
302 364
303 /* pop R0-R3 according to mask */ 365 ret = unwind_exec_pop_subset_r0_to_r3(ctrl, mask);
304 while (mask) { 366 if (ret)
305 if (mask & 1) 367 goto error;
306 ctrl->vrs[reg] = *vsp++;
307 mask >>= 1;
308 reg++;
309 }
310 ctrl->vrs[SP] = (unsigned long)vsp;
311 } else if (insn == 0xb2) { 368 } else if (insn == 0xb2) {
312 unsigned long uleb128 = unwind_get_byte(ctrl); 369 unsigned long uleb128 = unwind_get_byte(ctrl);
313 370
@@ -320,7 +377,8 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
320 pr_debug("%s: fp = %08lx sp = %08lx lr = %08lx pc = %08lx\n", __func__, 377 pr_debug("%s: fp = %08lx sp = %08lx lr = %08lx pc = %08lx\n", __func__,
321 ctrl->vrs[FP], ctrl->vrs[SP], ctrl->vrs[LR], ctrl->vrs[PC]); 378 ctrl->vrs[FP], ctrl->vrs[SP], ctrl->vrs[LR], ctrl->vrs[PC]);
322 379
323 return URC_OK; 380error:
381 return ret;
324} 382}
325 383
326/* 384/*
@@ -329,13 +387,13 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
329 */ 387 */
330int unwind_frame(struct stackframe *frame) 388int unwind_frame(struct stackframe *frame)
331{ 389{
332 unsigned long high, low; 390 unsigned long low;
333 const struct unwind_idx *idx; 391 const struct unwind_idx *idx;
334 struct unwind_ctrl_block ctrl; 392 struct unwind_ctrl_block ctrl;
335 393
336 /* only go to a higher address on the stack */ 394 /* store the highest address on the stack to avoid crossing it*/
337 low = frame->sp; 395 low = frame->sp;
338 high = ALIGN(low, THREAD_SIZE); 396 ctrl.sp_high = ALIGN(low, THREAD_SIZE);
339 397
340 pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__, 398 pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
341 frame->pc, frame->lr, frame->sp); 399 frame->pc, frame->lr, frame->sp);
@@ -382,11 +440,16 @@ int unwind_frame(struct stackframe *frame)
382 return -URC_FAILURE; 440 return -URC_FAILURE;
383 } 441 }
384 442
443 ctrl.check_each_pop = 0;
444
385 while (ctrl.entries > 0) { 445 while (ctrl.entries > 0) {
386 int urc = unwind_exec_insn(&ctrl); 446 int urc;
447 if ((ctrl.sp_high - ctrl.vrs[SP]) < sizeof(ctrl.vrs))
448 ctrl.check_each_pop = 1;
449 urc = unwind_exec_insn(&ctrl);
387 if (urc < 0) 450 if (urc < 0)
388 return urc; 451 return urc;
389 if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high) 452 if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= ctrl.sp_high)
390 return -URC_FAILURE; 453 return -URC_FAILURE;
391 } 454 }
392 455
diff --git a/arch/arm/kernel/uprobes-arm.c b/arch/arm/kernel/uprobes-arm.c
new file mode 100644
index 000000000000..d3b655ff17da
--- /dev/null
+++ b/arch/arm/kernel/uprobes-arm.c
@@ -0,0 +1,234 @@
1/*
2 * Copyright (C) 2012 Rabin Vincent <rabin at rab.in>
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 version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/kernel.h>
10#include <linux/types.h>
11#include <linux/stddef.h>
12#include <linux/wait.h>
13#include <linux/uprobes.h>
14#include <linux/module.h>
15
16#include "probes.h"
17#include "probes-arm.h"
18#include "uprobes.h"
19
20static int uprobes_substitute_pc(unsigned long *pinsn, u32 oregs)
21{
22 probes_opcode_t insn = __mem_to_opcode_arm(*pinsn);
23 probes_opcode_t temp;
24 probes_opcode_t mask;
25 int freereg;
26 u32 free = 0xffff;
27 u32 regs;
28
29 for (regs = oregs; regs; regs >>= 4, insn >>= 4) {
30 if ((regs & 0xf) == REG_TYPE_NONE)
31 continue;
32
33 free &= ~(1 << (insn & 0xf));
34 }
35
36 /* No PC, no problem */
37 if (free & (1 << 15))
38 return 15;
39
40 if (!free)
41 return -1;
42
43 /*
44 * fls instead of ffs ensures that for "ldrd r0, r1, [pc]" we would
45 * pick LR instead of R1.
46 */
47 freereg = free = fls(free) - 1;
48
49 temp = __mem_to_opcode_arm(*pinsn);
50 insn = temp;
51 regs = oregs;
52 mask = 0xf;
53
54 for (; regs; regs >>= 4, mask <<= 4, free <<= 4, temp >>= 4) {
55 if ((regs & 0xf) == REG_TYPE_NONE)
56 continue;
57
58 if ((temp & 0xf) != 15)
59 continue;
60
61 insn &= ~mask;
62 insn |= free & mask;
63 }
64
65 *pinsn = __opcode_to_mem_arm(insn);
66 return freereg;
67}
68
69static void uprobe_set_pc(struct arch_uprobe *auprobe,
70 struct arch_uprobe_task *autask,
71 struct pt_regs *regs)
72{
73 u32 pcreg = auprobe->pcreg;
74
75 autask->backup = regs->uregs[pcreg];
76 regs->uregs[pcreg] = regs->ARM_pc + 8;
77}
78
79static void uprobe_unset_pc(struct arch_uprobe *auprobe,
80 struct arch_uprobe_task *autask,
81 struct pt_regs *regs)
82{
83 /* PC will be taken care of by common code */
84 regs->uregs[auprobe->pcreg] = autask->backup;
85}
86
87static void uprobe_aluwrite_pc(struct arch_uprobe *auprobe,
88 struct arch_uprobe_task *autask,
89 struct pt_regs *regs)
90{
91 u32 pcreg = auprobe->pcreg;
92
93 alu_write_pc(regs->uregs[pcreg], regs);
94 regs->uregs[pcreg] = autask->backup;
95}
96
97static void uprobe_write_pc(struct arch_uprobe *auprobe,
98 struct arch_uprobe_task *autask,
99 struct pt_regs *regs)
100{
101 u32 pcreg = auprobe->pcreg;
102
103 load_write_pc(regs->uregs[pcreg], regs);
104 regs->uregs[pcreg] = autask->backup;
105}
106
107enum probes_insn
108decode_pc_ro(probes_opcode_t insn, struct arch_probes_insn *asi,
109 const struct decode_header *d)
110{
111 struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe,
112 asi);
113 struct decode_emulate *decode = (struct decode_emulate *) d;
114 u32 regs = decode->header.type_regs.bits >> DECODE_TYPE_BITS;
115 int reg;
116
117 reg = uprobes_substitute_pc(&auprobe->ixol[0], regs);
118 if (reg == 15)
119 return INSN_GOOD;
120
121 if (reg == -1)
122 return INSN_REJECTED;
123
124 auprobe->pcreg = reg;
125 auprobe->prehandler = uprobe_set_pc;
126 auprobe->posthandler = uprobe_unset_pc;
127
128 return INSN_GOOD;
129}
130
131enum probes_insn
132decode_wb_pc(probes_opcode_t insn, struct arch_probes_insn *asi,
133 const struct decode_header *d, bool alu)
134{
135 struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe,
136 asi);
137 enum probes_insn ret = decode_pc_ro(insn, asi, d);
138
139 if (((insn >> 12) & 0xf) == 15)
140 auprobe->posthandler = alu ? uprobe_aluwrite_pc
141 : uprobe_write_pc;
142
143 return ret;
144}
145
146enum probes_insn
147decode_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
148 struct arch_probes_insn *asi,
149 const struct decode_header *d)
150{
151 return decode_wb_pc(insn, asi, d, true);
152}
153
154enum probes_insn
155decode_ldr(probes_opcode_t insn, struct arch_probes_insn *asi,
156 const struct decode_header *d)
157{
158 return decode_wb_pc(insn, asi, d, false);
159}
160
161enum probes_insn
162uprobe_decode_ldmstm(probes_opcode_t insn,
163 struct arch_probes_insn *asi,
164 const struct decode_header *d)
165{
166 struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe,
167 asi);
168 unsigned reglist = insn & 0xffff;
169 int rn = (insn >> 16) & 0xf;
170 int lbit = insn & (1 << 20);
171 unsigned used = reglist | (1 << rn);
172
173 if (rn == 15)
174 return INSN_REJECTED;
175
176 if (!(used & (1 << 15)))
177 return INSN_GOOD;
178
179 if (used & (1 << 14))
180 return INSN_REJECTED;
181
182 /* Use LR instead of PC */
183 insn ^= 0xc000;
184
185 auprobe->pcreg = 14;
186 auprobe->ixol[0] = __opcode_to_mem_arm(insn);
187
188 auprobe->prehandler = uprobe_set_pc;
189 if (lbit)
190 auprobe->posthandler = uprobe_write_pc;
191 else
192 auprobe->posthandler = uprobe_unset_pc;
193
194 return INSN_GOOD;
195}
196
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},
201 [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
202 [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
203 [PROBES_MRS] = {.handler = simulate_mrs},
204 [PROBES_BRANCH_REG] = {.handler = simulate_blx2bx},
205 [PROBES_CLZ] = {.handler = probes_simulate_nop},
206 [PROBES_SATURATING_ARITHMETIC] = {.handler = probes_simulate_nop},
207 [PROBES_MUL1] = {.handler = probes_simulate_nop},
208 [PROBES_MUL2] = {.handler = probes_simulate_nop},
209 [PROBES_SWP] = {.handler = probes_simulate_nop},
210 [PROBES_LDRSTRD] = {.decoder = decode_pc_ro},
211 [PROBES_LOAD_EXTRA] = {.decoder = decode_pc_ro},
212 [PROBES_LOAD] = {.decoder = decode_ldr},
213 [PROBES_STORE_EXTRA] = {.decoder = decode_pc_ro},
214 [PROBES_STORE] = {.decoder = decode_pc_ro},
215 [PROBES_MOV_IP_SP] = {.handler = simulate_mov_ipsp},
216 [PROBES_DATA_PROCESSING_REG] = {
217 .decoder = decode_rd12rn16rm0rs8_rwflags},
218 [PROBES_DATA_PROCESSING_IMM] = {
219 .decoder = decode_rd12rn16rm0rs8_rwflags},
220 [PROBES_MOV_HALFWORD] = {.handler = probes_simulate_nop},
221 [PROBES_SEV] = {.handler = probes_simulate_nop},
222 [PROBES_WFE] = {.handler = probes_simulate_nop},
223 [PROBES_SATURATE] = {.handler = probes_simulate_nop},
224 [PROBES_REV] = {.handler = probes_simulate_nop},
225 [PROBES_MMI] = {.handler = probes_simulate_nop},
226 [PROBES_PACK] = {.handler = probes_simulate_nop},
227 [PROBES_EXTEND] = {.handler = probes_simulate_nop},
228 [PROBES_EXTEND_ADD] = {.handler = probes_simulate_nop},
229 [PROBES_MUL_ADD_LONG] = {.handler = probes_simulate_nop},
230 [PROBES_MUL_ADD] = {.handler = probes_simulate_nop},
231 [PROBES_BITFIELD] = {.handler = probes_simulate_nop},
232 [PROBES_BRANCH] = {.handler = simulate_bbl},
233 [PROBES_LDMSTM] = {.decoder = uprobe_decode_ldmstm}
234};
diff --git a/arch/arm/kernel/uprobes.c b/arch/arm/kernel/uprobes.c
new file mode 100644
index 000000000000..f9bacee973bf
--- /dev/null
+++ b/arch/arm/kernel/uprobes.c
@@ -0,0 +1,210 @@
1/*
2 * Copyright (C) 2012 Rabin Vincent <rabin at rab.in>
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 version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/kernel.h>
10#include <linux/stddef.h>
11#include <linux/errno.h>
12#include <linux/highmem.h>
13#include <linux/sched.h>
14#include <linux/uprobes.h>
15#include <linux/notifier.h>
16
17#include <asm/opcodes.h>
18#include <asm/traps.h>
19
20#include "probes.h"
21#include "probes-arm.h"
22#include "uprobes.h"
23
24#define UPROBE_TRAP_NR UINT_MAX
25
26bool is_swbp_insn(uprobe_opcode_t *insn)
27{
28 return (__mem_to_opcode_arm(*insn) & 0x0fffffff) ==
29 (UPROBE_SWBP_ARM_INSN & 0x0fffffff);
30}
31
32int set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm,
33 unsigned long vaddr)
34{
35 return uprobe_write_opcode(mm, vaddr,
36 __opcode_to_mem_arm(auprobe->bpinsn));
37}
38
39bool arch_uprobe_ignore(struct arch_uprobe *auprobe, struct pt_regs *regs)
40{
41 if (!auprobe->asi.insn_check_cc(regs->ARM_cpsr)) {
42 regs->ARM_pc += 4;
43 return true;
44 }
45
46 return false;
47}
48
49bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
50{
51 probes_opcode_t opcode;
52
53 if (!auprobe->simulate)
54 return false;
55
56 opcode = __mem_to_opcode_arm(*(unsigned int *) auprobe->insn);
57
58 auprobe->asi.insn_singlestep(opcode, &auprobe->asi, regs);
59
60 return true;
61}
62
63unsigned long
64arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr,
65 struct pt_regs *regs)
66{
67 unsigned long orig_ret_vaddr;
68
69 orig_ret_vaddr = regs->ARM_lr;
70 /* Replace the return addr with trampoline addr */
71 regs->ARM_lr = trampoline_vaddr;
72 return orig_ret_vaddr;
73}
74
75int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
76 unsigned long addr)
77{
78 unsigned int insn;
79 unsigned int bpinsn;
80 enum probes_insn ret;
81
82 /* Thumb not yet support */
83 if (addr & 0x3)
84 return -EINVAL;
85
86 insn = __mem_to_opcode_arm(*(unsigned int *)auprobe->insn);
87 auprobe->ixol[0] = __opcode_to_mem_arm(insn);
88 auprobe->ixol[1] = __opcode_to_mem_arm(UPROBE_SS_ARM_INSN);
89
90 ret = arm_probes_decode_insn(insn, &auprobe->asi, false,
91 uprobes_probes_actions);
92 switch (ret) {
93 case INSN_REJECTED:
94 return -EINVAL;
95
96 case INSN_GOOD_NO_SLOT:
97 auprobe->simulate = true;
98 break;
99
100 case INSN_GOOD:
101 default:
102 break;
103 }
104
105 bpinsn = UPROBE_SWBP_ARM_INSN & 0x0fffffff;
106 if (insn >= 0xe0000000)
107 bpinsn |= 0xe0000000; /* Unconditional instruction */
108 else
109 bpinsn |= insn & 0xf0000000; /* Copy condition from insn */
110
111 auprobe->bpinsn = bpinsn;
112
113 return 0;
114}
115
116int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
117{
118 struct uprobe_task *utask = current->utask;
119
120 if (auprobe->prehandler)
121 auprobe->prehandler(auprobe, &utask->autask, regs);
122
123 utask->autask.saved_trap_no = current->thread.trap_no;
124 current->thread.trap_no = UPROBE_TRAP_NR;
125 regs->ARM_pc = utask->xol_vaddr;
126
127 return 0;
128}
129
130int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
131{
132 struct uprobe_task *utask = current->utask;
133
134 WARN_ON_ONCE(current->thread.trap_no != UPROBE_TRAP_NR);
135
136 current->thread.trap_no = utask->autask.saved_trap_no;
137 regs->ARM_pc = utask->vaddr + 4;
138
139 if (auprobe->posthandler)
140 auprobe->posthandler(auprobe, &utask->autask, regs);
141
142 return 0;
143}
144
145bool arch_uprobe_xol_was_trapped(struct task_struct *t)
146{
147 if (t->thread.trap_no != UPROBE_TRAP_NR)
148 return true;
149
150 return false;
151}
152
153void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
154{
155 struct uprobe_task *utask = current->utask;
156
157 current->thread.trap_no = utask->autask.saved_trap_no;
158 instruction_pointer_set(regs, utask->vaddr);
159}
160
161int arch_uprobe_exception_notify(struct notifier_block *self,
162 unsigned long val, void *data)
163{
164 return NOTIFY_DONE;
165}
166
167static int uprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
168{
169 unsigned long flags;
170
171 local_irq_save(flags);
172 instr &= 0x0fffffff;
173 if (instr == (UPROBE_SWBP_ARM_INSN & 0x0fffffff))
174 uprobe_pre_sstep_notifier(regs);
175 else if (instr == (UPROBE_SS_ARM_INSN & 0x0fffffff))
176 uprobe_post_sstep_notifier(regs);
177 local_irq_restore(flags);
178
179 return 0;
180}
181
182unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
183{
184 return instruction_pointer(regs);
185}
186
187static struct undef_hook uprobes_arm_break_hook = {
188 .instr_mask = 0x0fffffff,
189 .instr_val = (UPROBE_SWBP_ARM_INSN & 0x0fffffff),
190 .cpsr_mask = MODE_MASK,
191 .cpsr_val = USR_MODE,
192 .fn = uprobe_trap_handler,
193};
194
195static struct undef_hook uprobes_arm_ss_hook = {
196 .instr_mask = 0x0fffffff,
197 .instr_val = (UPROBE_SS_ARM_INSN & 0x0fffffff),
198 .cpsr_mask = MODE_MASK,
199 .cpsr_val = USR_MODE,
200 .fn = uprobe_trap_handler,
201};
202
203static int arch_uprobes_init(void)
204{
205 register_undef_hook(&uprobes_arm_break_hook);
206 register_undef_hook(&uprobes_arm_ss_hook);
207
208 return 0;
209}
210device_initcall(arch_uprobes_init);
diff --git a/arch/arm/kernel/uprobes.h b/arch/arm/kernel/uprobes.h
new file mode 100644
index 000000000000..1d0c12dfbd03
--- /dev/null
+++ b/arch/arm/kernel/uprobes.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (C) 2012 Rabin Vincent <rabin at rab.in>
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 version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef __ARM_KERNEL_UPROBES_H
10#define __ARM_KERNEL_UPROBES_H
11
12enum probes_insn uprobe_decode_ldmstm(probes_opcode_t insn,
13 struct arch_probes_insn *asi,
14 const struct decode_header *d);
15
16enum probes_insn decode_ldr(probes_opcode_t insn,
17 struct arch_probes_insn *asi,
18 const struct decode_header *d);
19
20enum probes_insn
21decode_rd12rn16rm0rs8_rwflags(probes_opcode_t insn,
22 struct arch_probes_insn *asi,
23 const struct decode_header *d);
24
25enum probes_insn
26decode_wb_pc(probes_opcode_t insn, struct arch_probes_insn *asi,
27 const struct decode_header *d, bool alu);
28
29enum probes_insn
30decode_pc_ro(probes_opcode_t insn, struct arch_probes_insn *asi,
31 const struct decode_header *d);
32
33extern const union decode_action uprobes_probes_actions[];
34
35#endif
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index 52886b89706c..9f12ed1eea86 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -37,6 +37,11 @@ UNWIND( .fnstart )
37 add r1, r1, r0, lsl #2 @ Get word offset 37 add r1, r1, r0, lsl #2 @ Get word offset
38 mov r3, r2, lsl r3 @ create mask 38 mov r3, r2, lsl r3 @ create mask
39 smp_dmb 39 smp_dmb
40#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
41 .arch_extension mp
42 ALT_SMP(W(pldw) [r1])
43 ALT_UP(W(nop))
44#endif
401: ldrex r2, [r1] 451: ldrex r2, [r1]
41 ands r0, r2, r3 @ save old value of bit 46 ands r0, r2, r3 @ save old value of bit
42 \instr r2, r2, r3 @ toggle bit 47 \instr r2, r2, r3 @ toggle bit
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
index 805e3f8fb007..3bc8eb811a73 100644
--- a/arch/arm/lib/copy_template.S
+++ b/arch/arm/lib/copy_template.S
@@ -197,24 +197,24 @@
197 197
19812: PLD( pld [r1, #124] ) 19812: PLD( pld [r1, #124] )
19913: ldr4w r1, r4, r5, r6, r7, abort=19f 19913: ldr4w r1, r4, r5, r6, r7, abort=19f
200 mov r3, lr, pull #\pull 200 mov r3, lr, lspull #\pull
201 subs r2, r2, #32 201 subs r2, r2, #32
202 ldr4w r1, r8, r9, ip, lr, abort=19f 202 ldr4w r1, r8, r9, ip, lr, abort=19f
203 orr r3, r3, r4, push #\push 203 orr r3, r3, r4, lspush #\push
204 mov r4, r4, pull #\pull 204 mov r4, r4, lspull #\pull
205 orr r4, r4, r5, push #\push 205 orr r4, r4, r5, lspush #\push
206 mov r5, r5, pull #\pull 206 mov r5, r5, lspull #\pull
207 orr r5, r5, r6, push #\push 207 orr r5, r5, r6, lspush #\push
208 mov r6, r6, pull #\pull 208 mov r6, r6, lspull #\pull
209 orr r6, r6, r7, push #\push 209 orr r6, r6, r7, lspush #\push
210 mov r7, r7, pull #\pull 210 mov r7, r7, lspull #\pull
211 orr r7, r7, r8, push #\push 211 orr r7, r7, r8, lspush #\push
212 mov r8, r8, pull #\pull 212 mov r8, r8, lspull #\pull
213 orr r8, r8, r9, push #\push 213 orr r8, r8, r9, lspush #\push
214 mov r9, r9, pull #\pull 214 mov r9, r9, lspull #\pull
215 orr r9, r9, ip, push #\push 215 orr r9, r9, ip, lspush #\push
216 mov ip, ip, pull #\pull 216 mov ip, ip, lspull #\pull
217 orr ip, ip, lr, push #\push 217 orr ip, ip, lr, lspush #\push
218 str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f 218 str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
219 bge 12b 219 bge 12b
220 PLD( cmn r2, #96 ) 220 PLD( cmn r2, #96 )
@@ -225,10 +225,10 @@
22514: ands ip, r2, #28 22514: ands ip, r2, #28
226 beq 16f 226 beq 16f
227 227
22815: mov r3, lr, pull #\pull 22815: mov r3, lr, lspull #\pull
229 ldr1w r1, lr, abort=21f 229 ldr1w r1, lr, abort=21f
230 subs ip, ip, #4 230 subs ip, ip, #4
231 orr r3, r3, lr, push #\push 231 orr r3, r3, lr, lspush #\push
232 str1w r0, r3, abort=21f 232 str1w r0, r3, abort=21f
233 bgt 15b 233 bgt 15b
234 CALGN( cmp r2, #0 ) 234 CALGN( cmp r2, #0 )
diff --git a/arch/arm/lib/csumpartialcopygeneric.S b/arch/arm/lib/csumpartialcopygeneric.S
index d620a5f22a09..d6e742d24007 100644
--- a/arch/arm/lib/csumpartialcopygeneric.S
+++ b/arch/arm/lib/csumpartialcopygeneric.S
@@ -141,7 +141,7 @@ FN_ENTRY
141 tst len, #2 141 tst len, #2
142 mov r5, r4, get_byte_0 142 mov r5, r4, get_byte_0
143 beq .Lexit 143 beq .Lexit
144 adcs sum, sum, r4, push #16 144 adcs sum, sum, r4, lspush #16
145 strb r5, [dst], #1 145 strb r5, [dst], #1
146 mov r5, r4, get_byte_1 146 mov r5, r4, get_byte_1
147 strb r5, [dst], #1 147 strb r5, [dst], #1
@@ -171,23 +171,23 @@ FN_ENTRY
171 cmp ip, #2 171 cmp ip, #2
172 beq .Lsrc2_aligned 172 beq .Lsrc2_aligned
173 bhi .Lsrc3_aligned 173 bhi .Lsrc3_aligned
174 mov r4, r5, pull #8 @ C = 0 174 mov r4, r5, lspull #8 @ C = 0
175 bics ip, len, #15 175 bics ip, len, #15
176 beq 2f 176 beq 2f
1771: load4l r5, r6, r7, r8 1771: load4l r5, r6, r7, r8
178 orr r4, r4, r5, push #24 178 orr r4, r4, r5, lspush #24
179 mov r5, r5, pull #8 179 mov r5, r5, lspull #8
180 orr r5, r5, r6, push #24 180 orr r5, r5, r6, lspush #24
181 mov r6, r6, pull #8 181 mov r6, r6, lspull #8
182 orr r6, r6, r7, push #24 182 orr r6, r6, r7, lspush #24
183 mov r7, r7, pull #8 183 mov r7, r7, lspull #8
184 orr r7, r7, r8, push #24 184 orr r7, r7, r8, lspush #24
185 stmia dst!, {r4, r5, r6, r7} 185 stmia dst!, {r4, r5, r6, r7}
186 adcs sum, sum, r4 186 adcs sum, sum, r4
187 adcs sum, sum, r5 187 adcs sum, sum, r5
188 adcs sum, sum, r6 188 adcs sum, sum, r6
189 adcs sum, sum, r7 189 adcs sum, sum, r7
190 mov r4, r8, pull #8 190 mov r4, r8, lspull #8
191 sub ip, ip, #16 191 sub ip, ip, #16
192 teq ip, #0 192 teq ip, #0
193 bne 1b 193 bne 1b
@@ -196,50 +196,50 @@ FN_ENTRY
196 tst ip, #8 196 tst ip, #8
197 beq 3f 197 beq 3f
198 load2l r5, r6 198 load2l r5, r6
199 orr r4, r4, r5, push #24 199 orr r4, r4, r5, lspush #24
200 mov r5, r5, pull #8 200 mov r5, r5, lspull #8
201 orr r5, r5, r6, push #24 201 orr r5, r5, r6, lspush #24
202 stmia dst!, {r4, r5} 202 stmia dst!, {r4, r5}
203 adcs sum, sum, r4 203 adcs sum, sum, r4
204 adcs sum, sum, r5 204 adcs sum, sum, r5
205 mov r4, r6, pull #8 205 mov r4, r6, lspull #8
206 tst ip, #4 206 tst ip, #4
207 beq 4f 207 beq 4f
2083: load1l r5 2083: load1l r5
209 orr r4, r4, r5, push #24 209 orr r4, r4, r5, lspush #24
210 str r4, [dst], #4 210 str r4, [dst], #4
211 adcs sum, sum, r4 211 adcs sum, sum, r4
212 mov r4, r5, pull #8 212 mov r4, r5, lspull #8
2134: ands len, len, #3 2134: ands len, len, #3
214 beq .Ldone 214 beq .Ldone
215 mov r5, r4, get_byte_0 215 mov r5, r4, get_byte_0
216 tst len, #2 216 tst len, #2
217 beq .Lexit 217 beq .Lexit
218 adcs sum, sum, r4, push #16 218 adcs sum, sum, r4, lspush #16
219 strb r5, [dst], #1 219 strb r5, [dst], #1
220 mov r5, r4, get_byte_1 220 mov r5, r4, get_byte_1
221 strb r5, [dst], #1 221 strb r5, [dst], #1
222 mov r5, r4, get_byte_2 222 mov r5, r4, get_byte_2
223 b .Lexit 223 b .Lexit
224 224
225.Lsrc2_aligned: mov r4, r5, pull #16 225.Lsrc2_aligned: mov r4, r5, lspull #16
226 adds sum, sum, #0 226 adds sum, sum, #0
227 bics ip, len, #15 227 bics ip, len, #15
228 beq 2f 228 beq 2f
2291: load4l r5, r6, r7, r8 2291: load4l r5, r6, r7, r8
230 orr r4, r4, r5, push #16 230 orr r4, r4, r5, lspush #16
231 mov r5, r5, pull #16 231 mov r5, r5, lspull #16
232 orr r5, r5, r6, push #16 232 orr r5, r5, r6, lspush #16
233 mov r6, r6, pull #16 233 mov r6, r6, lspull #16
234 orr r6, r6, r7, push #16 234 orr r6, r6, r7, lspush #16
235 mov r7, r7, pull #16 235 mov r7, r7, lspull #16
236 orr r7, r7, r8, push #16 236 orr r7, r7, r8, lspush #16
237 stmia dst!, {r4, r5, r6, r7} 237 stmia dst!, {r4, r5, r6, r7}
238 adcs sum, sum, r4 238 adcs sum, sum, r4
239 adcs sum, sum, r5 239 adcs sum, sum, r5
240 adcs sum, sum, r6 240 adcs sum, sum, r6
241 adcs sum, sum, r7 241 adcs sum, sum, r7
242 mov r4, r8, pull #16 242 mov r4, r8, lspull #16
243 sub ip, ip, #16 243 sub ip, ip, #16
244 teq ip, #0 244 teq ip, #0
245 bne 1b 245 bne 1b
@@ -248,20 +248,20 @@ FN_ENTRY
248 tst ip, #8 248 tst ip, #8
249 beq 3f 249 beq 3f
250 load2l r5, r6 250 load2l r5, r6
251 orr r4, r4, r5, push #16 251 orr r4, r4, r5, lspush #16
252 mov r5, r5, pull #16 252 mov r5, r5, lspull #16
253 orr r5, r5, r6, push #16 253 orr r5, r5, r6, lspush #16
254 stmia dst!, {r4, r5} 254 stmia dst!, {r4, r5}
255 adcs sum, sum, r4 255 adcs sum, sum, r4
256 adcs sum, sum, r5 256 adcs sum, sum, r5
257 mov r4, r6, pull #16 257 mov r4, r6, lspull #16
258 tst ip, #4 258 tst ip, #4
259 beq 4f 259 beq 4f
2603: load1l r5 2603: load1l r5
261 orr r4, r4, r5, push #16 261 orr r4, r4, r5, lspush #16
262 str r4, [dst], #4 262 str r4, [dst], #4
263 adcs sum, sum, r4 263 adcs sum, sum, r4
264 mov r4, r5, pull #16 264 mov r4, r5, lspull #16
2654: ands len, len, #3 2654: ands len, len, #3
266 beq .Ldone 266 beq .Ldone
267 mov r5, r4, get_byte_0 267 mov r5, r4, get_byte_0
@@ -276,24 +276,24 @@ FN_ENTRY
276 load1b r5 276 load1b r5
277 b .Lexit 277 b .Lexit
278 278
279.Lsrc3_aligned: mov r4, r5, pull #24 279.Lsrc3_aligned: mov r4, r5, lspull #24
280 adds sum, sum, #0 280 adds sum, sum, #0
281 bics ip, len, #15 281 bics ip, len, #15
282 beq 2f 282 beq 2f
2831: load4l r5, r6, r7, r8 2831: load4l r5, r6, r7, r8
284 orr r4, r4, r5, push #8 284 orr r4, r4, r5, lspush #8
285 mov r5, r5, pull #24 285 mov r5, r5, lspull #24
286 orr r5, r5, r6, push #8 286 orr r5, r5, r6, lspush #8
287 mov r6, r6, pull #24 287 mov r6, r6, lspull #24
288 orr r6, r6, r7, push #8 288 orr r6, r6, r7, lspush #8
289 mov r7, r7, pull #24 289 mov r7, r7, lspull #24
290 orr r7, r7, r8, push #8 290 orr r7, r7, r8, lspush #8
291 stmia dst!, {r4, r5, r6, r7} 291 stmia dst!, {r4, r5, r6, r7}
292 adcs sum, sum, r4 292 adcs sum, sum, r4
293 adcs sum, sum, r5 293 adcs sum, sum, r5
294 adcs sum, sum, r6 294 adcs sum, sum, r6
295 adcs sum, sum, r7 295 adcs sum, sum, r7
296 mov r4, r8, pull #24 296 mov r4, r8, lspull #24
297 sub ip, ip, #16 297 sub ip, ip, #16
298 teq ip, #0 298 teq ip, #0
299 bne 1b 299 bne 1b
@@ -302,20 +302,20 @@ FN_ENTRY
302 tst ip, #8 302 tst ip, #8
303 beq 3f 303 beq 3f
304 load2l r5, r6 304 load2l r5, r6
305 orr r4, r4, r5, push #8 305 orr r4, r4, r5, lspush #8
306 mov r5, r5, pull #24 306 mov r5, r5, lspull #24
307 orr r5, r5, r6, push #8 307 orr r5, r5, r6, lspush #8
308 stmia dst!, {r4, r5} 308 stmia dst!, {r4, r5}
309 adcs sum, sum, r4 309 adcs sum, sum, r4
310 adcs sum, sum, r5 310 adcs sum, sum, r5
311 mov r4, r6, pull #24 311 mov r4, r6, lspull #24
312 tst ip, #4 312 tst ip, #4
313 beq 4f 313 beq 4f
3143: load1l r5 3143: load1l r5
315 orr r4, r4, r5, push #8 315 orr r4, r4, r5, lspush #8
316 str r4, [dst], #4 316 str r4, [dst], #4
317 adcs sum, sum, r4 317 adcs sum, sum, r4
318 mov r4, r5, pull #24 318 mov r4, r5, lspull #24
3194: ands len, len, #3 3194: ands len, len, #3
320 beq .Ldone 320 beq .Ldone
321 mov r5, r4, get_byte_0 321 mov r5, r4, get_byte_0
@@ -326,7 +326,7 @@ FN_ENTRY
326 load1l r4 326 load1l r4
327 mov r5, r4, get_byte_0 327 mov r5, r4, get_byte_0
328 strb r5, [dst], #1 328 strb r5, [dst], #1
329 adcs sum, sum, r4, push #24 329 adcs sum, sum, r4, lspush #24
330 mov r5, r4, get_byte_1 330 mov r5, r4, get_byte_1
331 b .Lexit 331 b .Lexit
332FN_EXIT 332FN_EXIT
diff --git a/arch/arm/lib/io-readsl.S b/arch/arm/lib/io-readsl.S
index 5fb97e7f9f4b..7a7430950c79 100644
--- a/arch/arm/lib/io-readsl.S
+++ b/arch/arm/lib/io-readsl.S
@@ -47,25 +47,25 @@ ENTRY(__raw_readsl)
47 strb ip, [r1], #1 47 strb ip, [r1], #1
48 48
494: subs r2, r2, #1 494: subs r2, r2, #1
50 mov ip, r3, pull #24 50 mov ip, r3, lspull #24
51 ldrne r3, [r0] 51 ldrne r3, [r0]
52 orrne ip, ip, r3, push #8 52 orrne ip, ip, r3, lspush #8
53 strne ip, [r1], #4 53 strne ip, [r1], #4
54 bne 4b 54 bne 4b
55 b 8f 55 b 8f
56 56
575: subs r2, r2, #1 575: subs r2, r2, #1
58 mov ip, r3, pull #16 58 mov ip, r3, lspull #16
59 ldrne r3, [r0] 59 ldrne r3, [r0]
60 orrne ip, ip, r3, push #16 60 orrne ip, ip, r3, lspush #16
61 strne ip, [r1], #4 61 strne ip, [r1], #4
62 bne 5b 62 bne 5b
63 b 7f 63 b 7f
64 64
656: subs r2, r2, #1 656: subs r2, r2, #1
66 mov ip, r3, pull #8 66 mov ip, r3, lspull #8
67 ldrne r3, [r0] 67 ldrne r3, [r0]
68 orrne ip, ip, r3, push #24 68 orrne ip, ip, r3, lspush #24
69 strne ip, [r1], #4 69 strne ip, [r1], #4
70 bne 6b 70 bne 6b
71 71
diff --git a/arch/arm/lib/io-writesl.S b/arch/arm/lib/io-writesl.S
index 8d3b7813725c..d0d104a0dd11 100644
--- a/arch/arm/lib/io-writesl.S
+++ b/arch/arm/lib/io-writesl.S
@@ -41,26 +41,26 @@ ENTRY(__raw_writesl)
41 blt 5f 41 blt 5f
42 bgt 6f 42 bgt 6f
43 43
444: mov ip, r3, pull #16 444: mov ip, r3, lspull #16
45 ldr r3, [r1], #4 45 ldr r3, [r1], #4
46 subs r2, r2, #1 46 subs r2, r2, #1
47 orr ip, ip, r3, push #16 47 orr ip, ip, r3, lspush #16
48 str ip, [r0] 48 str ip, [r0]
49 bne 4b 49 bne 4b
50 mov pc, lr 50 mov pc, lr
51 51
525: mov ip, r3, pull #8 525: mov ip, r3, lspull #8
53 ldr r3, [r1], #4 53 ldr r3, [r1], #4
54 subs r2, r2, #1 54 subs r2, r2, #1
55 orr ip, ip, r3, push #24 55 orr ip, ip, r3, lspush #24
56 str ip, [r0] 56 str ip, [r0]
57 bne 5b 57 bne 5b
58 mov pc, lr 58 mov pc, lr
59 59
606: mov ip, r3, pull #24 606: mov ip, r3, lspull #24
61 ldr r3, [r1], #4 61 ldr r3, [r1], #4
62 subs r2, r2, #1 62 subs r2, r2, #1
63 orr ip, ip, r3, push #8 63 orr ip, ip, r3, lspush #8
64 str ip, [r0] 64 str ip, [r0]
65 bne 6b 65 bne 6b
66 mov pc, lr 66 mov pc, lr
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
index 938fc14f962d..d1fc0c0c342c 100644
--- a/arch/arm/lib/memmove.S
+++ b/arch/arm/lib/memmove.S
@@ -147,24 +147,24 @@ ENTRY(memmove)
147 147
14812: PLD( pld [r1, #-128] ) 14812: PLD( pld [r1, #-128] )
14913: ldmdb r1!, {r7, r8, r9, ip} 14913: ldmdb r1!, {r7, r8, r9, ip}
150 mov lr, r3, push #\push 150 mov lr, r3, lspush #\push
151 subs r2, r2, #32 151 subs r2, r2, #32
152 ldmdb r1!, {r3, r4, r5, r6} 152 ldmdb r1!, {r3, r4, r5, r6}
153 orr lr, lr, ip, pull #\pull 153 orr lr, lr, ip, lspull #\pull
154 mov ip, ip, push #\push 154 mov ip, ip, lspush #\push
155 orr ip, ip, r9, pull #\pull 155 orr ip, ip, r9, lspull #\pull
156 mov r9, r9, push #\push 156 mov r9, r9, lspush #\push
157 orr r9, r9, r8, pull #\pull 157 orr r9, r9, r8, lspull #\pull
158 mov r8, r8, push #\push 158 mov r8, r8, lspush #\push
159 orr r8, r8, r7, pull #\pull 159 orr r8, r8, r7, lspull #\pull
160 mov r7, r7, push #\push 160 mov r7, r7, lspush #\push
161 orr r7, r7, r6, pull #\pull 161 orr r7, r7, r6, lspull #\pull
162 mov r6, r6, push #\push 162 mov r6, r6, lspush #\push
163 orr r6, r6, r5, pull #\pull 163 orr r6, r6, r5, lspull #\pull
164 mov r5, r5, push #\push 164 mov r5, r5, lspush #\push
165 orr r5, r5, r4, pull #\pull 165 orr r5, r5, r4, lspull #\pull
166 mov r4, r4, push #\push 166 mov r4, r4, lspush #\push
167 orr r4, r4, r3, pull #\pull 167 orr r4, r4, r3, lspull #\pull
168 stmdb r0!, {r4 - r9, ip, lr} 168 stmdb r0!, {r4 - r9, ip, lr}
169 bge 12b 169 bge 12b
170 PLD( cmn r2, #96 ) 170 PLD( cmn r2, #96 )
@@ -175,10 +175,10 @@ ENTRY(memmove)
17514: ands ip, r2, #28 17514: ands ip, r2, #28
176 beq 16f 176 beq 16f
177 177
17815: mov lr, r3, push #\push 17815: mov lr, r3, lspush #\push
179 ldr r3, [r1, #-4]! 179 ldr r3, [r1, #-4]!
180 subs ip, ip, #4 180 subs ip, ip, #4
181 orr lr, lr, r3, pull #\pull 181 orr lr, lr, r3, lspull #\pull
182 str lr, [r0, #-4]! 182 str lr, [r0, #-4]!
183 bgt 15b 183 bgt 15b
184 CALGN( cmp r2, #0 ) 184 CALGN( cmp r2, #0 )
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
index 5c908b1cb8ed..e50520904b76 100644
--- a/arch/arm/lib/uaccess.S
+++ b/arch/arm/lib/uaccess.S
@@ -117,9 +117,9 @@ USER( TUSER( strgtb) r3, [r0], #1) @ May fault
117.Lc2u_1fupi: subs r2, r2, #4 117.Lc2u_1fupi: subs r2, r2, #4
118 addmi ip, r2, #4 118 addmi ip, r2, #4
119 bmi .Lc2u_1nowords 119 bmi .Lc2u_1nowords
120 mov r3, r7, pull #8 120 mov r3, r7, lspull #8
121 ldr r7, [r1], #4 121 ldr r7, [r1], #4
122 orr r3, r3, r7, push #24 122 orr r3, r3, r7, lspush #24
123USER( TUSER( str) r3, [r0], #4) @ May fault 123USER( TUSER( str) r3, [r0], #4) @ May fault
124 mov ip, r0, lsl #32 - PAGE_SHIFT 124 mov ip, r0, lsl #32 - PAGE_SHIFT
125 rsb ip, ip, #0 125 rsb ip, ip, #0
@@ -131,30 +131,30 @@ USER( TUSER( str) r3, [r0], #4) @ May fault
131 subs ip, ip, #16 131 subs ip, ip, #16
132 blt .Lc2u_1rem8lp 132 blt .Lc2u_1rem8lp
133 133
134.Lc2u_1cpy8lp: mov r3, r7, pull #8 134.Lc2u_1cpy8lp: mov r3, r7, lspull #8
135 ldmia r1!, {r4 - r7} 135 ldmia r1!, {r4 - r7}
136 subs ip, ip, #16 136 subs ip, ip, #16
137 orr r3, r3, r4, push #24 137 orr r3, r3, r4, lspush #24
138 mov r4, r4, pull #8 138 mov r4, r4, lspull #8
139 orr r4, r4, r5, push #24 139 orr r4, r4, r5, lspush #24
140 mov r5, r5, pull #8 140 mov r5, r5, lspull #8
141 orr r5, r5, r6, push #24 141 orr r5, r5, r6, lspush #24
142 mov r6, r6, pull #8 142 mov r6, r6, lspull #8
143 orr r6, r6, r7, push #24 143 orr r6, r6, r7, lspush #24
144 stmia r0!, {r3 - r6} @ Shouldnt fault 144 stmia r0!, {r3 - r6} @ Shouldnt fault
145 bpl .Lc2u_1cpy8lp 145 bpl .Lc2u_1cpy8lp
146 146
147.Lc2u_1rem8lp: tst ip, #8 147.Lc2u_1rem8lp: tst ip, #8
148 movne r3, r7, pull #8 148 movne r3, r7, lspull #8
149 ldmneia r1!, {r4, r7} 149 ldmneia r1!, {r4, r7}
150 orrne r3, r3, r4, push #24 150 orrne r3, r3, r4, lspush #24
151 movne r4, r4, pull #8 151 movne r4, r4, lspull #8
152 orrne r4, r4, r7, push #24 152 orrne r4, r4, r7, lspush #24
153 stmneia r0!, {r3 - r4} @ Shouldnt fault 153 stmneia r0!, {r3 - r4} @ Shouldnt fault
154 tst ip, #4 154 tst ip, #4
155 movne r3, r7, pull #8 155 movne r3, r7, lspull #8
156 ldrne r7, [r1], #4 156 ldrne r7, [r1], #4
157 orrne r3, r3, r7, push #24 157 orrne r3, r3, r7, lspush #24
158 TUSER( strne) r3, [r0], #4 @ Shouldnt fault 158 TUSER( strne) r3, [r0], #4 @ Shouldnt fault
159 ands ip, ip, #3 159 ands ip, ip, #3
160 beq .Lc2u_1fupi 160 beq .Lc2u_1fupi
@@ -172,9 +172,9 @@ USER( TUSER( strgtb) r3, [r0], #1) @ May fault
172.Lc2u_2fupi: subs r2, r2, #4 172.Lc2u_2fupi: subs r2, r2, #4
173 addmi ip, r2, #4 173 addmi ip, r2, #4
174 bmi .Lc2u_2nowords 174 bmi .Lc2u_2nowords
175 mov r3, r7, pull #16 175 mov r3, r7, lspull #16
176 ldr r7, [r1], #4 176 ldr r7, [r1], #4
177 orr r3, r3, r7, push #16 177 orr r3, r3, r7, lspush #16
178USER( TUSER( str) r3, [r0], #4) @ May fault 178USER( TUSER( str) r3, [r0], #4) @ May fault
179 mov ip, r0, lsl #32 - PAGE_SHIFT 179 mov ip, r0, lsl #32 - PAGE_SHIFT
180 rsb ip, ip, #0 180 rsb ip, ip, #0
@@ -186,30 +186,30 @@ USER( TUSER( str) r3, [r0], #4) @ May fault
186 subs ip, ip, #16 186 subs ip, ip, #16
187 blt .Lc2u_2rem8lp 187 blt .Lc2u_2rem8lp
188 188
189.Lc2u_2cpy8lp: mov r3, r7, pull #16 189.Lc2u_2cpy8lp: mov r3, r7, lspull #16
190 ldmia r1!, {r4 - r7} 190 ldmia r1!, {r4 - r7}
191 subs ip, ip, #16 191 subs ip, ip, #16
192 orr r3, r3, r4, push #16 192 orr r3, r3, r4, lspush #16
193 mov r4, r4, pull #16 193 mov r4, r4, lspull #16
194 orr r4, r4, r5, push #16 194 orr r4, r4, r5, lspush #16
195 mov r5, r5, pull #16 195 mov r5, r5, lspull #16
196 orr r5, r5, r6, push #16 196 orr r5, r5, r6, lspush #16
197 mov r6, r6, pull #16 197 mov r6, r6, lspull #16
198 orr r6, r6, r7, push #16 198 orr r6, r6, r7, lspush #16
199 stmia r0!, {r3 - r6} @ Shouldnt fault 199 stmia r0!, {r3 - r6} @ Shouldnt fault
200 bpl .Lc2u_2cpy8lp 200 bpl .Lc2u_2cpy8lp
201 201
202.Lc2u_2rem8lp: tst ip, #8 202.Lc2u_2rem8lp: tst ip, #8
203 movne r3, r7, pull #16 203 movne r3, r7, lspull #16
204 ldmneia r1!, {r4, r7} 204 ldmneia r1!, {r4, r7}
205 orrne r3, r3, r4, push #16 205 orrne r3, r3, r4, lspush #16
206 movne r4, r4, pull #16 206 movne r4, r4, lspull #16
207 orrne r4, r4, r7, push #16 207 orrne r4, r4, r7, lspush #16
208 stmneia r0!, {r3 - r4} @ Shouldnt fault 208 stmneia r0!, {r3 - r4} @ Shouldnt fault
209 tst ip, #4 209 tst ip, #4
210 movne r3, r7, pull #16 210 movne r3, r7, lspull #16
211 ldrne r7, [r1], #4 211 ldrne r7, [r1], #4
212 orrne r3, r3, r7, push #16 212 orrne r3, r3, r7, lspush #16
213 TUSER( strne) r3, [r0], #4 @ Shouldnt fault 213 TUSER( strne) r3, [r0], #4 @ Shouldnt fault
214 ands ip, ip, #3 214 ands ip, ip, #3
215 beq .Lc2u_2fupi 215 beq .Lc2u_2fupi
@@ -227,9 +227,9 @@ USER( TUSER( strgtb) r3, [r0], #1) @ May fault
227.Lc2u_3fupi: subs r2, r2, #4 227.Lc2u_3fupi: subs r2, r2, #4
228 addmi ip, r2, #4 228 addmi ip, r2, #4
229 bmi .Lc2u_3nowords 229 bmi .Lc2u_3nowords
230 mov r3, r7, pull #24 230 mov r3, r7, lspull #24
231 ldr r7, [r1], #4 231 ldr r7, [r1], #4
232 orr r3, r3, r7, push #8 232 orr r3, r3, r7, lspush #8
233USER( TUSER( str) r3, [r0], #4) @ May fault 233USER( TUSER( str) r3, [r0], #4) @ May fault
234 mov ip, r0, lsl #32 - PAGE_SHIFT 234 mov ip, r0, lsl #32 - PAGE_SHIFT
235 rsb ip, ip, #0 235 rsb ip, ip, #0
@@ -241,30 +241,30 @@ USER( TUSER( str) r3, [r0], #4) @ May fault
241 subs ip, ip, #16 241 subs ip, ip, #16
242 blt .Lc2u_3rem8lp 242 blt .Lc2u_3rem8lp
243 243
244.Lc2u_3cpy8lp: mov r3, r7, pull #24 244.Lc2u_3cpy8lp: mov r3, r7, lspull #24
245 ldmia r1!, {r4 - r7} 245 ldmia r1!, {r4 - r7}
246 subs ip, ip, #16 246 subs ip, ip, #16
247 orr r3, r3, r4, push #8 247 orr r3, r3, r4, lspush #8
248 mov r4, r4, pull #24 248 mov r4, r4, lspull #24
249 orr r4, r4, r5, push #8 249 orr r4, r4, r5, lspush #8
250 mov r5, r5, pull #24 250 mov r5, r5, lspull #24
251 orr r5, r5, r6, push #8 251 orr r5, r5, r6, lspush #8
252 mov r6, r6, pull #24 252 mov r6, r6, lspull #24
253 orr r6, r6, r7, push #8 253 orr r6, r6, r7, lspush #8
254 stmia r0!, {r3 - r6} @ Shouldnt fault 254 stmia r0!, {r3 - r6} @ Shouldnt fault
255 bpl .Lc2u_3cpy8lp 255 bpl .Lc2u_3cpy8lp
256 256
257.Lc2u_3rem8lp: tst ip, #8 257.Lc2u_3rem8lp: tst ip, #8
258 movne r3, r7, pull #24 258 movne r3, r7, lspull #24
259 ldmneia r1!, {r4, r7} 259 ldmneia r1!, {r4, r7}
260 orrne r3, r3, r4, push #8 260 orrne r3, r3, r4, lspush #8
261 movne r4, r4, pull #24 261 movne r4, r4, lspull #24
262 orrne r4, r4, r7, push #8 262 orrne r4, r4, r7, lspush #8
263 stmneia r0!, {r3 - r4} @ Shouldnt fault 263 stmneia r0!, {r3 - r4} @ Shouldnt fault
264 tst ip, #4 264 tst ip, #4
265 movne r3, r7, pull #24 265 movne r3, r7, lspull #24
266 ldrne r7, [r1], #4 266 ldrne r7, [r1], #4
267 orrne r3, r3, r7, push #8 267 orrne r3, r3, r7, lspush #8
268 TUSER( strne) r3, [r0], #4 @ Shouldnt fault 268 TUSER( strne) r3, [r0], #4 @ Shouldnt fault
269 ands ip, ip, #3 269 ands ip, ip, #3
270 beq .Lc2u_3fupi 270 beq .Lc2u_3fupi
@@ -382,9 +382,9 @@ USER( TUSER( ldr) r7, [r1], #4) @ May fault
382.Lcfu_1fupi: subs r2, r2, #4 382.Lcfu_1fupi: subs r2, r2, #4
383 addmi ip, r2, #4 383 addmi ip, r2, #4
384 bmi .Lcfu_1nowords 384 bmi .Lcfu_1nowords
385 mov r3, r7, pull #8 385 mov r3, r7, lspull #8
386USER( TUSER( ldr) r7, [r1], #4) @ May fault 386USER( TUSER( ldr) r7, [r1], #4) @ May fault
387 orr r3, r3, r7, push #24 387 orr r3, r3, r7, lspush #24
388 str r3, [r0], #4 388 str r3, [r0], #4
389 mov ip, r1, lsl #32 - PAGE_SHIFT 389 mov ip, r1, lsl #32 - PAGE_SHIFT
390 rsb ip, ip, #0 390 rsb ip, ip, #0
@@ -396,30 +396,30 @@ USER( TUSER( ldr) r7, [r1], #4) @ May fault
396 subs ip, ip, #16 396 subs ip, ip, #16
397 blt .Lcfu_1rem8lp 397 blt .Lcfu_1rem8lp
398 398
399.Lcfu_1cpy8lp: mov r3, r7, pull #8 399.Lcfu_1cpy8lp: mov r3, r7, lspull #8
400 ldmia r1!, {r4 - r7} @ Shouldnt fault 400 ldmia r1!, {r4 - r7} @ Shouldnt fault
401 subs ip, ip, #16 401 subs ip, ip, #16
402 orr r3, r3, r4, push #24 402 orr r3, r3, r4, lspush #24
403 mov r4, r4, pull #8 403 mov r4, r4, lspull #8
404 orr r4, r4, r5, push #24 404 orr r4, r4, r5, lspush #24
405 mov r5, r5, pull #8 405 mov r5, r5, lspull #8
406 orr r5, r5, r6, push #24 406 orr r5, r5, r6, lspush #24
407 mov r6, r6, pull #8 407 mov r6, r6, lspull #8
408 orr r6, r6, r7, push #24 408 orr r6, r6, r7, lspush #24
409 stmia r0!, {r3 - r6} 409 stmia r0!, {r3 - r6}
410 bpl .Lcfu_1cpy8lp 410 bpl .Lcfu_1cpy8lp
411 411
412.Lcfu_1rem8lp: tst ip, #8 412.Lcfu_1rem8lp: tst ip, #8
413 movne r3, r7, pull #8 413 movne r3, r7, lspull #8
414 ldmneia r1!, {r4, r7} @ Shouldnt fault 414 ldmneia r1!, {r4, r7} @ Shouldnt fault
415 orrne r3, r3, r4, push #24 415 orrne r3, r3, r4, lspush #24
416 movne r4, r4, pull #8 416 movne r4, r4, lspull #8
417 orrne r4, r4, r7, push #24 417 orrne r4, r4, r7, lspush #24
418 stmneia r0!, {r3 - r4} 418 stmneia r0!, {r3 - r4}
419 tst ip, #4 419 tst ip, #4
420 movne r3, r7, pull #8 420 movne r3, r7, lspull #8
421USER( TUSER( ldrne) r7, [r1], #4) @ May fault 421USER( TUSER( ldrne) r7, [r1], #4) @ May fault
422 orrne r3, r3, r7, push #24 422 orrne r3, r3, r7, lspush #24
423 strne r3, [r0], #4 423 strne r3, [r0], #4
424 ands ip, ip, #3 424 ands ip, ip, #3
425 beq .Lcfu_1fupi 425 beq .Lcfu_1fupi
@@ -437,9 +437,9 @@ USER( TUSER( ldrne) r7, [r1], #4) @ May fault
437.Lcfu_2fupi: subs r2, r2, #4 437.Lcfu_2fupi: subs r2, r2, #4
438 addmi ip, r2, #4 438 addmi ip, r2, #4
439 bmi .Lcfu_2nowords 439 bmi .Lcfu_2nowords
440 mov r3, r7, pull #16 440 mov r3, r7, lspull #16
441USER( TUSER( ldr) r7, [r1], #4) @ May fault 441USER( TUSER( ldr) r7, [r1], #4) @ May fault
442 orr r3, r3, r7, push #16 442 orr r3, r3, r7, lspush #16
443 str r3, [r0], #4 443 str r3, [r0], #4
444 mov ip, r1, lsl #32 - PAGE_SHIFT 444 mov ip, r1, lsl #32 - PAGE_SHIFT
445 rsb ip, ip, #0 445 rsb ip, ip, #0
@@ -452,30 +452,30 @@ USER( TUSER( ldr) r7, [r1], #4) @ May fault
452 blt .Lcfu_2rem8lp 452 blt .Lcfu_2rem8lp
453 453
454 454
455.Lcfu_2cpy8lp: mov r3, r7, pull #16 455.Lcfu_2cpy8lp: mov r3, r7, lspull #16
456 ldmia r1!, {r4 - r7} @ Shouldnt fault 456 ldmia r1!, {r4 - r7} @ Shouldnt fault
457 subs ip, ip, #16 457 subs ip, ip, #16
458 orr r3, r3, r4, push #16 458 orr r3, r3, r4, lspush #16
459 mov r4, r4, pull #16 459 mov r4, r4, lspull #16
460 orr r4, r4, r5, push #16 460 orr r4, r4, r5, lspush #16
461 mov r5, r5, pull #16 461 mov r5, r5, lspull #16
462 orr r5, r5, r6, push #16 462 orr r5, r5, r6, lspush #16
463 mov r6, r6, pull #16 463 mov r6, r6, lspull #16
464 orr r6, r6, r7, push #16 464 orr r6, r6, r7, lspush #16
465 stmia r0!, {r3 - r6} 465 stmia r0!, {r3 - r6}
466 bpl .Lcfu_2cpy8lp 466 bpl .Lcfu_2cpy8lp
467 467
468.Lcfu_2rem8lp: tst ip, #8 468.Lcfu_2rem8lp: tst ip, #8
469 movne r3, r7, pull #16 469 movne r3, r7, lspull #16
470 ldmneia r1!, {r4, r7} @ Shouldnt fault 470 ldmneia r1!, {r4, r7} @ Shouldnt fault
471 orrne r3, r3, r4, push #16 471 orrne r3, r3, r4, lspush #16
472 movne r4, r4, pull #16 472 movne r4, r4, lspull #16
473 orrne r4, r4, r7, push #16 473 orrne r4, r4, r7, lspush #16
474 stmneia r0!, {r3 - r4} 474 stmneia r0!, {r3 - r4}
475 tst ip, #4 475 tst ip, #4
476 movne r3, r7, pull #16 476 movne r3, r7, lspull #16
477USER( TUSER( ldrne) r7, [r1], #4) @ May fault 477USER( TUSER( ldrne) r7, [r1], #4) @ May fault
478 orrne r3, r3, r7, push #16 478 orrne r3, r3, r7, lspush #16
479 strne r3, [r0], #4 479 strne r3, [r0], #4
480 ands ip, ip, #3 480 ands ip, ip, #3
481 beq .Lcfu_2fupi 481 beq .Lcfu_2fupi
@@ -493,9 +493,9 @@ USER( TUSER( ldrgtb) r3, [r1], #0) @ May fault
493.Lcfu_3fupi: subs r2, r2, #4 493.Lcfu_3fupi: subs r2, r2, #4
494 addmi ip, r2, #4 494 addmi ip, r2, #4
495 bmi .Lcfu_3nowords 495 bmi .Lcfu_3nowords
496 mov r3, r7, pull #24 496 mov r3, r7, lspull #24
497USER( TUSER( ldr) r7, [r1], #4) @ May fault 497USER( TUSER( ldr) r7, [r1], #4) @ May fault
498 orr r3, r3, r7, push #8 498 orr r3, r3, r7, lspush #8
499 str r3, [r0], #4 499 str r3, [r0], #4
500 mov ip, r1, lsl #32 - PAGE_SHIFT 500 mov ip, r1, lsl #32 - PAGE_SHIFT
501 rsb ip, ip, #0 501 rsb ip, ip, #0
@@ -507,30 +507,30 @@ USER( TUSER( ldr) r7, [r1], #4) @ May fault
507 subs ip, ip, #16 507 subs ip, ip, #16
508 blt .Lcfu_3rem8lp 508 blt .Lcfu_3rem8lp
509 509
510.Lcfu_3cpy8lp: mov r3, r7, pull #24 510.Lcfu_3cpy8lp: mov r3, r7, lspull #24
511 ldmia r1!, {r4 - r7} @ Shouldnt fault 511 ldmia r1!, {r4 - r7} @ Shouldnt fault
512 orr r3, r3, r4, push #8 512 orr r3, r3, r4, lspush #8
513 mov r4, r4, pull #24 513 mov r4, r4, lspull #24
514 orr r4, r4, r5, push #8 514 orr r4, r4, r5, lspush #8
515 mov r5, r5, pull #24 515 mov r5, r5, lspull #24
516 orr r5, r5, r6, push #8 516 orr r5, r5, r6, lspush #8
517 mov r6, r6, pull #24 517 mov r6, r6, lspull #24
518 orr r6, r6, r7, push #8 518 orr r6, r6, r7, lspush #8
519 stmia r0!, {r3 - r6} 519 stmia r0!, {r3 - r6}
520 subs ip, ip, #16 520 subs ip, ip, #16
521 bpl .Lcfu_3cpy8lp 521 bpl .Lcfu_3cpy8lp
522 522
523.Lcfu_3rem8lp: tst ip, #8 523.Lcfu_3rem8lp: tst ip, #8
524 movne r3, r7, pull #24 524 movne r3, r7, lspull #24
525 ldmneia r1!, {r4, r7} @ Shouldnt fault 525 ldmneia r1!, {r4, r7} @ Shouldnt fault
526 orrne r3, r3, r4, push #8 526 orrne r3, r3, r4, lspush #8
527 movne r4, r4, pull #24 527 movne r4, r4, lspull #24
528 orrne r4, r4, r7, push #8 528 orrne r4, r4, r7, lspush #8
529 stmneia r0!, {r3 - r4} 529 stmneia r0!, {r3 - r4}
530 tst ip, #4 530 tst ip, #4
531 movne r3, r7, pull #24 531 movne r3, r7, lspull #24
532USER( TUSER( ldrne) r7, [r1], #4) @ May fault 532USER( TUSER( ldrne) r7, [r1], #4) @ May fault
533 orrne r3, r3, r7, push #8 533 orrne r3, r3, r7, lspush #8
534 strne r3, [r0], #4 534 strne r3, [r0], #4
535 ands ip, ip, #3 535 ands ip, ip, #3
536 beq .Lcfu_3fupi 536 beq .Lcfu_3fupi
diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c
index e38b279f402c..384dc859e6c6 100644
--- a/arch/arm/mach-cns3xxx/core.c
+++ b/arch/arm/mach-cns3xxx/core.c
@@ -155,7 +155,7 @@ static irqreturn_t cns3xxx_timer_interrupt(int irq, void *dev_id)
155 155
156static struct irqaction cns3xxx_timer_irq = { 156static struct irqaction cns3xxx_timer_irq = {
157 .name = "timer", 157 .name = "timer",
158 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 158 .flags = IRQF_TIMER | IRQF_IRQPOLL,
159 .handler = cns3xxx_timer_interrupt, 159 .handler = cns3xxx_timer_interrupt,
160}; 160};
161 161
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 68ac934d4565..8254e716b095 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -206,7 +206,7 @@ ebsa110_timer_interrupt(int irq, void *dev_id)
206 206
207static struct irqaction ebsa110_timer_irq = { 207static struct irqaction ebsa110_timer_irq = {
208 .name = "EBSA110 Timer Tick", 208 .name = "EBSA110 Timer Tick",
209 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 209 .flags = IRQF_TIMER | IRQF_IRQPOLL,
210 .handler = ebsa110_timer_interrupt, 210 .handler = ebsa110_timer_interrupt,
211}; 211};
212 212
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c
index 3971104d32d4..bf7aa7d298e7 100644
--- a/arch/arm/mach-footbridge/dc21285-timer.c
+++ b/arch/arm/mach-footbridge/dc21285-timer.c
@@ -105,7 +105,7 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id)
105static struct irqaction footbridge_timer_irq = { 105static struct irqaction footbridge_timer_irq = {
106 .name = "dc21285_timer1", 106 .name = "dc21285_timer1",
107 .handler = timer1_interrupt, 107 .handler = timer1_interrupt,
108 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 108 .flags = IRQF_TIMER | IRQF_IRQPOLL,
109 .dev_id = &ckevt_dc21285, 109 .dev_id = &ckevt_dc21285,
110}; 110};
111 111
@@ -125,7 +125,7 @@ void __init footbridge_timer_init(void)
125 clockevents_config_and_register(ce, rate, 0x4, 0xffffff); 125 clockevents_config_and_register(ce, rate, 0x4, 0xffffff);
126} 126}
127 127
128static u32 notrace footbridge_read_sched_clock(void) 128static u64 notrace footbridge_read_sched_clock(void)
129{ 129{
130 return ~*CSR_TIMER3_VALUE; 130 return ~*CSR_TIMER3_VALUE;
131} 131}
@@ -138,5 +138,5 @@ void __init footbridge_sched_clock(void)
138 *CSR_TIMER3_CLR = 0; 138 *CSR_TIMER3_CLR = 0;
139 *CSR_TIMER3_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16; 139 *CSR_TIMER3_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
140 140
141 setup_sched_clock(footbridge_read_sched_clock, 24, rate); 141 sched_clock_register(footbridge_read_sched_clock, 24, rate);
142} 142}
diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c
index 7c2fdae9a38b..96a3d73ef4bf 100644
--- a/arch/arm/mach-footbridge/dc21285.c
+++ b/arch/arm/mach-footbridge/dc21285.c
@@ -334,15 +334,15 @@ void __init dc21285_preinit(void)
334 /* 334 /*
335 * We don't care if these fail. 335 * We don't care if these fail.
336 */ 336 */
337 dc21285_request_irq(IRQ_PCI_SERR, dc21285_serr_irq, IRQF_DISABLED, 337 dc21285_request_irq(IRQ_PCI_SERR, dc21285_serr_irq, 0,
338 "PCI system error", &serr_timer); 338 "PCI system error", &serr_timer);
339 dc21285_request_irq(IRQ_PCI_PERR, dc21285_parity_irq, IRQF_DISABLED, 339 dc21285_request_irq(IRQ_PCI_PERR, dc21285_parity_irq, 0,
340 "PCI parity error", &perr_timer); 340 "PCI parity error", &perr_timer);
341 dc21285_request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, IRQF_DISABLED, 341 dc21285_request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, 0,
342 "PCI abort", NULL); 342 "PCI abort", NULL);
343 dc21285_request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, IRQF_DISABLED, 343 dc21285_request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, 0,
344 "Discard timer", NULL); 344 "Discard timer", NULL);
345 dc21285_request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, IRQF_DISABLED, 345 dc21285_request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, 0,
346 "PCI data parity", NULL); 346 "PCI data parity", NULL);
347 347
348 if (cfn_mode) { 348 if (cfn_mode) {
diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c
index d9301dd56354..b73f52e196b9 100644
--- a/arch/arm/mach-footbridge/isa-timer.c
+++ b/arch/arm/mach-footbridge/isa-timer.c
@@ -27,7 +27,7 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
27static struct irqaction pit_timer_irq = { 27static struct irqaction pit_timer_irq = {
28 .name = "pit", 28 .name = "pit",
29 .handler = pit_timer_interrupt, 29 .handler = pit_timer_interrupt,
30 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 30 .flags = IRQF_TIMER | IRQF_IRQPOLL,
31 .dev_id = &i8253_clockevent, 31 .dev_id = &i8253_clockevent,
32}; 32};
33 33
diff --git a/arch/arm/mach-gemini/idle.c b/arch/arm/mach-gemini/idle.c
index 87dff4f5059e..ddf8ec9d203b 100644
--- a/arch/arm/mach-gemini/idle.c
+++ b/arch/arm/mach-gemini/idle.c
@@ -3,7 +3,7 @@
3 */ 3 */
4 4
5#include <linux/init.h> 5#include <linux/init.h>
6#include <asm/system.h> 6#include <asm/system_misc.h>
7#include <asm/proc-fns.h> 7#include <asm/proc-fns.h>
8 8
9static void gemini_idle(void) 9static void gemini_idle(void)
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 17c0fe627435..e4f27f0e56ac 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -358,7 +358,7 @@ static struct clock_event_device integrator_clockevent = {
358 358
359static struct irqaction integrator_timer_irq = { 359static struct irqaction integrator_timer_irq = {
360 .name = "timer", 360 .name = "timer",
361 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 361 .flags = IRQF_TIMER | IRQF_IRQPOLL,
362 .handler = integrator_timer_interrupt, 362 .handler = integrator_timer_interrupt,
363 .dev_id = &integrator_clockevent, 363 .dev_id = &integrator_clockevent,
364}; 364};
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 6d68aed6548a..a465f27bc263 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -312,7 +312,7 @@ static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
312 312
313static struct irqaction ixp4xx_timer_irq = { 313static struct irqaction ixp4xx_timer_irq = {
314 .name = "timer1", 314 .name = "timer1",
315 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 315 .flags = IRQF_TIMER | IRQF_IRQPOLL,
316 .handler = ixp4xx_timer_interrupt, 316 .handler = ixp4xx_timer_interrupt,
317 .dev_id = &clockevent_ixp4xx, 317 .dev_id = &clockevent_ixp4xx,
318}; 318};
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
index 736dc692d540..43ee06d3abe5 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-setup.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -233,8 +233,7 @@ static int __init dsmg600_gpio_init(void)
233 233
234 gpio_request(DSMG600_RB_GPIO, "reset button"); 234 gpio_request(DSMG600_RB_GPIO, "reset button");
235 if (request_irq(gpio_to_irq(DSMG600_RB_GPIO), &dsmg600_reset_handler, 235 if (request_irq(gpio_to_irq(DSMG600_RB_GPIO), &dsmg600_reset_handler,
236 IRQF_DISABLED | IRQF_TRIGGER_LOW, 236 IRQF_TRIGGER_LOW, "DSM-G600 reset button", NULL) < 0) {
237 "DSM-G600 reset button", NULL) < 0) {
238 237
239 printk(KERN_DEBUG "Reset Button IRQ %d not available\n", 238 printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
240 gpio_to_irq(DSMG600_RB_GPIO)); 239 gpio_to_irq(DSMG600_RB_GPIO));
diff --git a/arch/arm/mach-ixp4xx/fsg-setup.c b/arch/arm/mach-ixp4xx/fsg-setup.c
index 429966b756ed..5c4b0c4a1b37 100644
--- a/arch/arm/mach-ixp4xx/fsg-setup.c
+++ b/arch/arm/mach-ixp4xx/fsg-setup.c
@@ -208,16 +208,14 @@ static void __init fsg_init(void)
208 platform_add_devices(fsg_devices, ARRAY_SIZE(fsg_devices)); 208 platform_add_devices(fsg_devices, ARRAY_SIZE(fsg_devices));
209 209
210 if (request_irq(gpio_to_irq(FSG_RB_GPIO), &fsg_reset_handler, 210 if (request_irq(gpio_to_irq(FSG_RB_GPIO), &fsg_reset_handler,
211 IRQF_DISABLED | IRQF_TRIGGER_LOW, 211 IRQF_TRIGGER_LOW, "FSG reset button", NULL) < 0) {
212 "FSG reset button", NULL) < 0) {
213 212
214 printk(KERN_DEBUG "Reset Button IRQ %d not available\n", 213 printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
215 gpio_to_irq(FSG_RB_GPIO)); 214 gpio_to_irq(FSG_RB_GPIO));
216 } 215 }
217 216
218 if (request_irq(gpio_to_irq(FSG_SB_GPIO), &fsg_power_handler, 217 if (request_irq(gpio_to_irq(FSG_SB_GPIO), &fsg_power_handler,
219 IRQF_DISABLED | IRQF_TRIGGER_LOW, 218 IRQF_TRIGGER_LOW, "FSG power button", NULL) < 0) {
220 "FSG power button", NULL) < 0) {
221 219
222 printk(KERN_DEBUG "Power Button IRQ %d not available\n", 220 printk(KERN_DEBUG "Power Button IRQ %d not available\n",
223 gpio_to_irq(FSG_SB_GPIO)); 221 gpio_to_irq(FSG_SB_GPIO));
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
index 507cb5233537..4e0f762bc651 100644
--- a/arch/arm/mach-ixp4xx/nas100d-setup.c
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -295,8 +295,7 @@ static void __init nas100d_init(void)
295 pm_power_off = nas100d_power_off; 295 pm_power_off = nas100d_power_off;
296 296
297 if (request_irq(gpio_to_irq(NAS100D_RB_GPIO), &nas100d_reset_handler, 297 if (request_irq(gpio_to_irq(NAS100D_RB_GPIO), &nas100d_reset_handler,
298 IRQF_DISABLED | IRQF_TRIGGER_LOW, 298 IRQF_TRIGGER_LOW, "NAS100D reset button", NULL) < 0) {
299 "NAS100D reset button", NULL) < 0) {
300 299
301 printk(KERN_DEBUG "Reset Button IRQ %d not available\n", 300 printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
302 gpio_to_irq(NAS100D_RB_GPIO)); 301 gpio_to_irq(NAS100D_RB_GPIO));
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
index ba5f1cda2a9d..88c025f52d8d 100644
--- a/arch/arm/mach-ixp4xx/nslu2-setup.c
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -265,16 +265,14 @@ static void __init nslu2_init(void)
265 pm_power_off = nslu2_power_off; 265 pm_power_off = nslu2_power_off;
266 266
267 if (request_irq(gpio_to_irq(NSLU2_RB_GPIO), &nslu2_reset_handler, 267 if (request_irq(gpio_to_irq(NSLU2_RB_GPIO), &nslu2_reset_handler,
268 IRQF_DISABLED | IRQF_TRIGGER_LOW, 268 IRQF_TRIGGER_LOW, "NSLU2 reset button", NULL) < 0) {
269 "NSLU2 reset button", NULL) < 0) {
270 269
271 printk(KERN_DEBUG "Reset Button IRQ %d not available\n", 270 printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
272 gpio_to_irq(NSLU2_RB_GPIO)); 271 gpio_to_irq(NSLU2_RB_GPIO));
273 } 272 }
274 273
275 if (request_irq(gpio_to_irq(NSLU2_PB_GPIO), &nslu2_power_handler, 274 if (request_irq(gpio_to_irq(NSLU2_PB_GPIO), &nslu2_power_handler,
276 IRQF_DISABLED | IRQF_TRIGGER_HIGH, 275 IRQF_TRIGGER_HIGH, "NSLU2 power button", NULL) < 0) {
277 "NSLU2 power button", NULL) < 0) {
278 276
279 printk(KERN_DEBUG "Power Button IRQ %d not available\n", 277 printk(KERN_DEBUG "Power Button IRQ %d not available\n",
280 gpio_to_irq(NSLU2_PB_GPIO)); 278 gpio_to_irq(NSLU2_PB_GPIO));
diff --git a/arch/arm/mach-ks8695/time.c b/arch/arm/mach-ks8695/time.c
index 426c97662f5b..a197874bf382 100644
--- a/arch/arm/mach-ks8695/time.c
+++ b/arch/arm/mach-ks8695/time.c
@@ -122,7 +122,7 @@ static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id)
122 122
123static struct irqaction ks8695_timer_irq = { 123static struct irqaction ks8695_timer_irq = {
124 .name = "ks8695_tick", 124 .name = "ks8695_tick",
125 .flags = IRQF_DISABLED | IRQF_TIMER, 125 .flags = IRQF_TIMER,
126 .handler = ks8695_timer_interrupt, 126 .handler = ks8695_timer_interrupt,
127}; 127};
128 128
diff --git a/arch/arm/mach-lpc32xx/timer.c b/arch/arm/mach-lpc32xx/timer.c
index 20eab63d10ba..4e5837299c04 100644
--- a/arch/arm/mach-lpc32xx/timer.c
+++ b/arch/arm/mach-lpc32xx/timer.c
@@ -90,7 +90,7 @@ static irqreturn_t lpc32xx_timer_interrupt(int irq, void *dev_id)
90 90
91static struct irqaction lpc32xx_timer_irq = { 91static struct irqaction lpc32xx_timer_irq = {
92 .name = "LPC32XX Timer Tick", 92 .name = "LPC32XX Timer Tick",
93 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 93 .flags = IRQF_TIMER | IRQF_IRQPOLL,
94 .handler = lpc32xx_timer_interrupt, 94 .handler = lpc32xx_timer_interrupt,
95}; 95};
96 96
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
index 024022d91fe3..bbcd2322fd27 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/arch/arm/mach-mmp/time.c
@@ -186,7 +186,7 @@ static void __init timer_config(void)
186 186
187static struct irqaction timer_irq = { 187static struct irqaction timer_irq = {
188 .name = "timer", 188 .name = "timer",
189 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 189 .flags = IRQF_TIMER | IRQF_IRQPOLL,
190 .handler = timer_interrupt, 190 .handler = timer_interrupt,
191 .dev_id = &ckevt, 191 .dev_id = &ckevt,
192}; 192};
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c
index 6df42e643031..3177c7a40930 100644
--- a/arch/arm/mach-netx/time.c
+++ b/arch/arm/mach-netx/time.c
@@ -99,7 +99,7 @@ netx_timer_interrupt(int irq, void *dev_id)
99 99
100static struct irqaction netx_timer_irq = { 100static struct irqaction netx_timer_irq = {
101 .name = "NetX Timer Tick", 101 .name = "NetX Timer Tick",
102 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 102 .flags = IRQF_TIMER | IRQF_IRQPOLL,
103 .handler = netx_timer_interrupt, 103 .handler = netx_timer_interrupt,
104}; 104};
105 105
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
index 5bb8ce86d54b..4be601b638d7 100644
--- a/arch/arm/mach-omap1/dma.c
+++ b/arch/arm/mach-omap1/dma.c
@@ -32,55 +32,51 @@
32 32
33#define OMAP1_DMA_BASE (0xfffed800) 33#define OMAP1_DMA_BASE (0xfffed800)
34#define OMAP1_LOGICAL_DMA_CH_COUNT 17 34#define OMAP1_LOGICAL_DMA_CH_COUNT 17
35#define OMAP1_DMA_STRIDE 0x40
36 35
37static u32 errata;
38static u32 enable_1510_mode; 36static u32 enable_1510_mode;
39static u8 dma_stride; 37
40static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end; 38static const struct omap_dma_reg reg_map[] = {
41 39 [GCR] = { 0x0400, 0x00, OMAP_DMA_REG_16BIT },
42static u16 reg_map[] = { 40 [GSCR] = { 0x0404, 0x00, OMAP_DMA_REG_16BIT },
43 [GCR] = 0x400, 41 [GRST1] = { 0x0408, 0x00, OMAP_DMA_REG_16BIT },
44 [GSCR] = 0x404, 42 [HW_ID] = { 0x0442, 0x00, OMAP_DMA_REG_16BIT },
45 [GRST1] = 0x408, 43 [PCH2_ID] = { 0x0444, 0x00, OMAP_DMA_REG_16BIT },
46 [HW_ID] = 0x442, 44 [PCH0_ID] = { 0x0446, 0x00, OMAP_DMA_REG_16BIT },
47 [PCH2_ID] = 0x444, 45 [PCH1_ID] = { 0x0448, 0x00, OMAP_DMA_REG_16BIT },
48 [PCH0_ID] = 0x446, 46 [PCHG_ID] = { 0x044a, 0x00, OMAP_DMA_REG_16BIT },
49 [PCH1_ID] = 0x448, 47 [PCHD_ID] = { 0x044c, 0x00, OMAP_DMA_REG_16BIT },
50 [PCHG_ID] = 0x44a, 48 [CAPS_0] = { 0x044e, 0x00, OMAP_DMA_REG_2X16BIT },
51 [PCHD_ID] = 0x44c, 49 [CAPS_1] = { 0x0452, 0x00, OMAP_DMA_REG_2X16BIT },
52 [CAPS_0] = 0x44e, 50 [CAPS_2] = { 0x0456, 0x00, OMAP_DMA_REG_16BIT },
53 [CAPS_1] = 0x452, 51 [CAPS_3] = { 0x0458, 0x00, OMAP_DMA_REG_16BIT },
54 [CAPS_2] = 0x456, 52 [CAPS_4] = { 0x045a, 0x00, OMAP_DMA_REG_16BIT },
55 [CAPS_3] = 0x458, 53 [PCH2_SR] = { 0x0460, 0x00, OMAP_DMA_REG_16BIT },
56 [CAPS_4] = 0x45a, 54 [PCH0_SR] = { 0x0480, 0x00, OMAP_DMA_REG_16BIT },
57 [PCH2_SR] = 0x460, 55 [PCH1_SR] = { 0x0482, 0x00, OMAP_DMA_REG_16BIT },
58 [PCH0_SR] = 0x480, 56 [PCHD_SR] = { 0x04c0, 0x00, OMAP_DMA_REG_16BIT },
59 [PCH1_SR] = 0x482,
60 [PCHD_SR] = 0x4c0,
61 57
62 /* Common Registers */ 58 /* Common Registers */
63 [CSDP] = 0x00, 59 [CSDP] = { 0x0000, 0x40, OMAP_DMA_REG_16BIT },
64 [CCR] = 0x02, 60 [CCR] = { 0x0002, 0x40, OMAP_DMA_REG_16BIT },
65 [CICR] = 0x04, 61 [CICR] = { 0x0004, 0x40, OMAP_DMA_REG_16BIT },
66 [CSR] = 0x06, 62 [CSR] = { 0x0006, 0x40, OMAP_DMA_REG_16BIT },
67 [CEN] = 0x10, 63 [CEN] = { 0x0010, 0x40, OMAP_DMA_REG_16BIT },
68 [CFN] = 0x12, 64 [CFN] = { 0x0012, 0x40, OMAP_DMA_REG_16BIT },
69 [CSFI] = 0x14, 65 [CSFI] = { 0x0014, 0x40, OMAP_DMA_REG_16BIT },
70 [CSEI] = 0x16, 66 [CSEI] = { 0x0016, 0x40, OMAP_DMA_REG_16BIT },
71 [CPC] = 0x18, /* 15xx only */ 67 [CPC] = { 0x0018, 0x40, OMAP_DMA_REG_16BIT }, /* 15xx only */
72 [CSAC] = 0x18, 68 [CSAC] = { 0x0018, 0x40, OMAP_DMA_REG_16BIT },
73 [CDAC] = 0x1a, 69 [CDAC] = { 0x001a, 0x40, OMAP_DMA_REG_16BIT },
74 [CDEI] = 0x1c, 70 [CDEI] = { 0x001c, 0x40, OMAP_DMA_REG_16BIT },
75 [CDFI] = 0x1e, 71 [CDFI] = { 0x001e, 0x40, OMAP_DMA_REG_16BIT },
76 [CLNK_CTRL] = 0x28, 72 [CLNK_CTRL] = { 0x0028, 0x40, OMAP_DMA_REG_16BIT },
77 73
78 /* Channel specific register offsets */ 74 /* Channel specific register offsets */
79 [CSSA] = 0x08, 75 [CSSA] = { 0x0008, 0x40, OMAP_DMA_REG_2X16BIT },
80 [CDSA] = 0x0c, 76 [CDSA] = { 0x000c, 0x40, OMAP_DMA_REG_2X16BIT },
81 [COLOR] = 0x20, 77 [COLOR] = { 0x0020, 0x40, OMAP_DMA_REG_2X16BIT },
82 [CCR2] = 0x24, 78 [CCR2] = { 0x0024, 0x40, OMAP_DMA_REG_16BIT },
83 [LCH_CTRL] = 0x2a, 79 [LCH_CTRL] = { 0x002a, 0x40, OMAP_DMA_REG_16BIT },
84}; 80};
85 81
86static struct resource res[] __initdata = { 82static struct resource res[] __initdata = {
@@ -181,44 +177,36 @@ static struct resource res[] __initdata = {
181static void __iomem *dma_base; 177static void __iomem *dma_base;
182static inline void dma_write(u32 val, int reg, int lch) 178static inline void dma_write(u32 val, int reg, int lch)
183{ 179{
184 u8 stride; 180 void __iomem *addr = dma_base;
185 u32 offset;
186 181
187 stride = (reg >= dma_common_ch_start) ? dma_stride : 0; 182 addr += reg_map[reg].offset;
188 offset = reg_map[reg] + (stride * lch); 183 addr += reg_map[reg].stride * lch;
189 184
190 __raw_writew(val, dma_base + offset); 185 __raw_writew(val, addr);
191 if ((reg > CLNK_CTRL && reg < CCEN) || 186 if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
192 (reg > PCHD_ID && reg < CAPS_2)) { 187 __raw_writew(val >> 16, addr + 2);
193 u32 offset2 = reg_map[reg] + 2 + (stride * lch);
194 __raw_writew(val >> 16, dma_base + offset2);
195 }
196} 188}
197 189
198static inline u32 dma_read(int reg, int lch) 190static inline u32 dma_read(int reg, int lch)
199{ 191{
200 u8 stride; 192 void __iomem *addr = dma_base;
201 u32 offset, val; 193 uint32_t val;
202 194
203 stride = (reg >= dma_common_ch_start) ? dma_stride : 0; 195 addr += reg_map[reg].offset;
204 offset = reg_map[reg] + (stride * lch); 196 addr += reg_map[reg].stride * lch;
205 197
206 val = __raw_readw(dma_base + offset); 198 val = __raw_readw(addr);
207 if ((reg > CLNK_CTRL && reg < CCEN) || 199 if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
208 (reg > PCHD_ID && reg < CAPS_2)) { 200 val |= __raw_readw(addr + 2) << 16;
209 u16 upper; 201
210 u32 offset2 = reg_map[reg] + 2 + (stride * lch);
211 upper = __raw_readw(dma_base + offset2);
212 val |= (upper << 16);
213 }
214 return val; 202 return val;
215} 203}
216 204
217static void omap1_clear_lch_regs(int lch) 205static void omap1_clear_lch_regs(int lch)
218{ 206{
219 int i = dma_common_ch_start; 207 int i;
220 208
221 for (; i <= dma_common_ch_end; i += 1) 209 for (i = CPC; i <= COLOR; i += 1)
222 dma_write(0, i, lch); 210 dma_write(0, i, lch);
223} 211}
224 212
@@ -255,8 +243,9 @@ static void omap1_show_dma_caps(void)
255 return; 243 return;
256} 244}
257 245
258static u32 configure_dma_errata(void) 246static unsigned configure_dma_errata(void)
259{ 247{
248 unsigned errata = 0;
260 249
261 /* 250 /*
262 * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is 251 * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
@@ -272,11 +261,23 @@ static const struct platform_device_info omap_dma_dev_info = {
272 .name = "omap-dma-engine", 261 .name = "omap-dma-engine",
273 .id = -1, 262 .id = -1,
274 .dma_mask = DMA_BIT_MASK(32), 263 .dma_mask = DMA_BIT_MASK(32),
264 .res = res,
265 .num_res = 1,
266};
267
268static struct omap_system_dma_plat_info dma_plat_info __initdata = {
269 .reg_map = reg_map,
270 .channel_stride = 0x40,
271 .show_dma_caps = omap1_show_dma_caps,
272 .clear_lch_regs = omap1_clear_lch_regs,
273 .clear_dma = omap1_clear_dma,
274 .dma_write = dma_write,
275 .dma_read = dma_read,
275}; 276};
276 277
277static int __init omap1_system_dma_init(void) 278static int __init omap1_system_dma_init(void)
278{ 279{
279 struct omap_system_dma_plat_info *p; 280 struct omap_system_dma_plat_info p;
280 struct omap_dma_dev_attr *d; 281 struct omap_dma_dev_attr *d;
281 struct platform_device *pdev, *dma_pdev; 282 struct platform_device *pdev, *dma_pdev;
282 int ret; 283 int ret;
@@ -302,20 +303,12 @@ static int __init omap1_system_dma_init(void)
302 goto exit_iounmap; 303 goto exit_iounmap;
303 } 304 }
304 305
305 p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
306 if (!p) {
307 dev_err(&pdev->dev, "%s: Unable to allocate 'p' for %s\n",
308 __func__, pdev->name);
309 ret = -ENOMEM;
310 goto exit_iounmap;
311 }
312
313 d = kzalloc(sizeof(struct omap_dma_dev_attr), GFP_KERNEL); 306 d = kzalloc(sizeof(struct omap_dma_dev_attr), GFP_KERNEL);
314 if (!d) { 307 if (!d) {
315 dev_err(&pdev->dev, "%s: Unable to allocate 'd' for %s\n", 308 dev_err(&pdev->dev, "%s: Unable to allocate 'd' for %s\n",
316 __func__, pdev->name); 309 __func__, pdev->name);
317 ret = -ENOMEM; 310 ret = -ENOMEM;
318 goto exit_release_p; 311 goto exit_iounmap;
319 } 312 }
320 313
321 d->lch_count = OMAP1_LOGICAL_DMA_CH_COUNT; 314 d->lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
@@ -336,17 +329,6 @@ static int __init omap1_system_dma_init(void)
336 d->dev_caps |= CLEAR_CSR_ON_READ; 329 d->dev_caps |= CLEAR_CSR_ON_READ;
337 d->dev_caps |= IS_WORD_16; 330 d->dev_caps |= IS_WORD_16;
338 331
339
340 d->chan = kzalloc(sizeof(struct omap_dma_lch) *
341 (d->lch_count), GFP_KERNEL);
342 if (!d->chan) {
343 dev_err(&pdev->dev,
344 "%s: Memory allocation failed for d->chan!\n",
345 __func__);
346 ret = -ENOMEM;
347 goto exit_release_d;
348 }
349
350 if (cpu_is_omap15xx()) 332 if (cpu_is_omap15xx())
351 d->chan_count = 9; 333 d->chan_count = 9;
352 else if (cpu_is_omap16xx() || cpu_is_omap7xx()) { 334 else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
@@ -356,35 +338,24 @@ static int __init omap1_system_dma_init(void)
356 d->chan_count = 9; 338 d->chan_count = 9;
357 } 339 }
358 340
359 p->dma_attr = d; 341 p = dma_plat_info;
360 342 p.dma_attr = d;
361 p->show_dma_caps = omap1_show_dma_caps; 343 p.errata = configure_dma_errata();
362 p->clear_lch_regs = omap1_clear_lch_regs;
363 p->clear_dma = omap1_clear_dma;
364 p->dma_write = dma_write;
365 p->dma_read = dma_read;
366 p->disable_irq_lch = NULL;
367
368 p->errata = configure_dma_errata();
369 344
370 ret = platform_device_add_data(pdev, p, sizeof(*p)); 345 ret = platform_device_add_data(pdev, &p, sizeof(p));
371 if (ret) { 346 if (ret) {
372 dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n", 347 dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
373 __func__, pdev->name, pdev->id); 348 __func__, pdev->name, pdev->id);
374 goto exit_release_chan; 349 goto exit_release_d;
375 } 350 }
376 351
377 ret = platform_device_add(pdev); 352 ret = platform_device_add(pdev);
378 if (ret) { 353 if (ret) {
379 dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n", 354 dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
380 __func__, pdev->name, pdev->id); 355 __func__, pdev->name, pdev->id);
381 goto exit_release_chan; 356 goto exit_release_d;
382 } 357 }
383 358
384 dma_stride = OMAP1_DMA_STRIDE;
385 dma_common_ch_start = CPC;
386 dma_common_ch_end = COLOR;
387
388 dma_pdev = platform_device_register_full(&omap_dma_dev_info); 359 dma_pdev = platform_device_register_full(&omap_dma_dev_info);
389 if (IS_ERR(dma_pdev)) { 360 if (IS_ERR(dma_pdev)) {
390 ret = PTR_ERR(dma_pdev); 361 ret = PTR_ERR(dma_pdev);
@@ -395,12 +366,8 @@ static int __init omap1_system_dma_init(void)
395 366
396exit_release_pdev: 367exit_release_pdev:
397 platform_device_del(pdev); 368 platform_device_del(pdev);
398exit_release_chan:
399 kfree(d->chan);
400exit_release_d: 369exit_release_d:
401 kfree(d); 370 kfree(d);
402exit_release_p:
403 kfree(p);
404exit_iounmap: 371exit_iounmap:
405 iounmap(dma_base); 372 iounmap(dma_base);
406exit_device_put: 373exit_device_put:
diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c
index 25b79a297365..6a6935caac1e 100644
--- a/arch/arm/mach-omap2/am35xx-emac.c
+++ b/arch/arm/mach-omap2/am35xx-emac.c
@@ -17,7 +17,6 @@
17 17
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/davinci_emac.h> 19#include <linux/davinci_emac.h>
20#include <asm/system.h>
21#include "omap_device.h" 20#include "omap_device.h"
22#include "am35xx.h" 21#include "am35xx.h"
23#include "control.h" 22#include "control.h"
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index 49fd0d501c9b..5689c88d986d 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -35,97 +35,80 @@
35#include "omap_hwmod.h" 35#include "omap_hwmod.h"
36#include "omap_device.h" 36#include "omap_device.h"
37 37
38#define OMAP2_DMA_STRIDE 0x60 38static enum omap_reg_offsets dma_common_ch_end;
39 39
40static u32 errata; 40static const struct omap_dma_reg reg_map[] = {
41static u8 dma_stride; 41 [REVISION] = { 0x0000, 0x00, OMAP_DMA_REG_32BIT },
42 42 [GCR] = { 0x0078, 0x00, OMAP_DMA_REG_32BIT },
43static struct omap_dma_dev_attr *d; 43 [IRQSTATUS_L0] = { 0x0008, 0x00, OMAP_DMA_REG_32BIT },
44 44 [IRQSTATUS_L1] = { 0x000c, 0x00, OMAP_DMA_REG_32BIT },
45static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end; 45 [IRQSTATUS_L2] = { 0x0010, 0x00, OMAP_DMA_REG_32BIT },
46 46 [IRQSTATUS_L3] = { 0x0014, 0x00, OMAP_DMA_REG_32BIT },
47static u16 reg_map[] = { 47 [IRQENABLE_L0] = { 0x0018, 0x00, OMAP_DMA_REG_32BIT },
48 [REVISION] = 0x00, 48 [IRQENABLE_L1] = { 0x001c, 0x00, OMAP_DMA_REG_32BIT },
49 [GCR] = 0x78, 49 [IRQENABLE_L2] = { 0x0020, 0x00, OMAP_DMA_REG_32BIT },
50 [IRQSTATUS_L0] = 0x08, 50 [IRQENABLE_L3] = { 0x0024, 0x00, OMAP_DMA_REG_32BIT },
51 [IRQSTATUS_L1] = 0x0c, 51 [SYSSTATUS] = { 0x0028, 0x00, OMAP_DMA_REG_32BIT },
52 [IRQSTATUS_L2] = 0x10, 52 [OCP_SYSCONFIG] = { 0x002c, 0x00, OMAP_DMA_REG_32BIT },
53 [IRQSTATUS_L3] = 0x14, 53 [CAPS_0] = { 0x0064, 0x00, OMAP_DMA_REG_32BIT },
54 [IRQENABLE_L0] = 0x18, 54 [CAPS_2] = { 0x006c, 0x00, OMAP_DMA_REG_32BIT },
55 [IRQENABLE_L1] = 0x1c, 55 [CAPS_3] = { 0x0070, 0x00, OMAP_DMA_REG_32BIT },
56 [IRQENABLE_L2] = 0x20, 56 [CAPS_4] = { 0x0074, 0x00, OMAP_DMA_REG_32BIT },
57 [IRQENABLE_L3] = 0x24,
58 [SYSSTATUS] = 0x28,
59 [OCP_SYSCONFIG] = 0x2c,
60 [CAPS_0] = 0x64,
61 [CAPS_2] = 0x6c,
62 [CAPS_3] = 0x70,
63 [CAPS_4] = 0x74,
64 57
65 /* Common register offsets */ 58 /* Common register offsets */
66 [CCR] = 0x80, 59 [CCR] = { 0x0080, 0x60, OMAP_DMA_REG_32BIT },
67 [CLNK_CTRL] = 0x84, 60 [CLNK_CTRL] = { 0x0084, 0x60, OMAP_DMA_REG_32BIT },
68 [CICR] = 0x88, 61 [CICR] = { 0x0088, 0x60, OMAP_DMA_REG_32BIT },
69 [CSR] = 0x8c, 62 [CSR] = { 0x008c, 0x60, OMAP_DMA_REG_32BIT },
70 [CSDP] = 0x90, 63 [CSDP] = { 0x0090, 0x60, OMAP_DMA_REG_32BIT },
71 [CEN] = 0x94, 64 [CEN] = { 0x0094, 0x60, OMAP_DMA_REG_32BIT },
72 [CFN] = 0x98, 65 [CFN] = { 0x0098, 0x60, OMAP_DMA_REG_32BIT },
73 [CSEI] = 0xa4, 66 [CSEI] = { 0x00a4, 0x60, OMAP_DMA_REG_32BIT },
74 [CSFI] = 0xa8, 67 [CSFI] = { 0x00a8, 0x60, OMAP_DMA_REG_32BIT },
75 [CDEI] = 0xac, 68 [CDEI] = { 0x00ac, 0x60, OMAP_DMA_REG_32BIT },
76 [CDFI] = 0xb0, 69 [CDFI] = { 0x00b0, 0x60, OMAP_DMA_REG_32BIT },
77 [CSAC] = 0xb4, 70 [CSAC] = { 0x00b4, 0x60, OMAP_DMA_REG_32BIT },
78 [CDAC] = 0xb8, 71 [CDAC] = { 0x00b8, 0x60, OMAP_DMA_REG_32BIT },
79 72
80 /* Channel specific register offsets */ 73 /* Channel specific register offsets */
81 [CSSA] = 0x9c, 74 [CSSA] = { 0x009c, 0x60, OMAP_DMA_REG_32BIT },
82 [CDSA] = 0xa0, 75 [CDSA] = { 0x00a0, 0x60, OMAP_DMA_REG_32BIT },
83 [CCEN] = 0xbc, 76 [CCEN] = { 0x00bc, 0x60, OMAP_DMA_REG_32BIT },
84 [CCFN] = 0xc0, 77 [CCFN] = { 0x00c0, 0x60, OMAP_DMA_REG_32BIT },
85 [COLOR] = 0xc4, 78 [COLOR] = { 0x00c4, 0x60, OMAP_DMA_REG_32BIT },
86 79
87 /* OMAP4 specific registers */ 80 /* OMAP4 specific registers */
88 [CDP] = 0xd0, 81 [CDP] = { 0x00d0, 0x60, OMAP_DMA_REG_32BIT },
89 [CNDP] = 0xd4, 82 [CNDP] = { 0x00d4, 0x60, OMAP_DMA_REG_32BIT },
90 [CCDN] = 0xd8, 83 [CCDN] = { 0x00d8, 0x60, OMAP_DMA_REG_32BIT },
91}; 84};
92 85
93static void __iomem *dma_base; 86static void __iomem *dma_base;
94static inline void dma_write(u32 val, int reg, int lch) 87static inline void dma_write(u32 val, int reg, int lch)
95{ 88{
96 u8 stride; 89 void __iomem *addr = dma_base;
97 u32 offset;
98 90
99 stride = (reg >= dma_common_ch_start) ? dma_stride : 0; 91 addr += reg_map[reg].offset;
100 offset = reg_map[reg] + (stride * lch); 92 addr += reg_map[reg].stride * lch;
101 __raw_writel(val, dma_base + offset); 93
94 __raw_writel(val, addr);
102} 95}
103 96
104static inline u32 dma_read(int reg, int lch) 97static inline u32 dma_read(int reg, int lch)
105{ 98{
106 u8 stride; 99 void __iomem *addr = dma_base;
107 u32 offset, val;
108
109 stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
110 offset = reg_map[reg] + (stride * lch);
111 val = __raw_readl(dma_base + offset);
112 return val;
113}
114 100
115static inline void omap2_disable_irq_lch(int lch) 101 addr += reg_map[reg].offset;
116{ 102 addr += reg_map[reg].stride * lch;
117 u32 val;
118 103
119 val = dma_read(IRQENABLE_L0, lch); 104 return __raw_readl(addr);
120 val &= ~(1 << lch);
121 dma_write(val, IRQENABLE_L0, lch);
122} 105}
123 106
124static void omap2_clear_dma(int lch) 107static void omap2_clear_dma(int lch)
125{ 108{
126 int i = dma_common_ch_start; 109 int i;
127 110
128 for (; i <= dma_common_ch_end; i += 1) 111 for (i = CSDP; i <= dma_common_ch_end; i += 1)
129 dma_write(0, i, lch); 112 dma_write(0, i, lch);
130} 113}
131 114
@@ -137,8 +120,9 @@ static void omap2_show_dma_caps(void)
137 return; 120 return;
138} 121}
139 122
140static u32 configure_dma_errata(void) 123static unsigned configure_dma_errata(void)
141{ 124{
125 unsigned errata = 0;
142 126
143 /* 127 /*
144 * Errata applicable for OMAP2430ES1.0 and all omap2420 128 * Errata applicable for OMAP2430ES1.0 and all omap2420
@@ -220,48 +204,50 @@ static u32 configure_dma_errata(void)
220 return errata; 204 return errata;
221} 205}
222 206
207static struct omap_system_dma_plat_info dma_plat_info __initdata = {
208 .reg_map = reg_map,
209 .channel_stride = 0x60,
210 .show_dma_caps = omap2_show_dma_caps,
211 .clear_dma = omap2_clear_dma,
212 .dma_write = dma_write,
213 .dma_read = dma_read,
214};
215
216static struct platform_device_info omap_dma_dev_info = {
217 .name = "omap-dma-engine",
218 .id = -1,
219 .dma_mask = DMA_BIT_MASK(32),
220};
221
223/* One time initializations */ 222/* One time initializations */
224static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) 223static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
225{ 224{
226 struct platform_device *pdev; 225 struct platform_device *pdev;
227 struct omap_system_dma_plat_info *p; 226 struct omap_system_dma_plat_info p;
227 struct omap_dma_dev_attr *d;
228 struct resource *mem; 228 struct resource *mem;
229 char *name = "omap_dma_system"; 229 char *name = "omap_dma_system";
230 230
231 dma_stride = OMAP2_DMA_STRIDE; 231 p = dma_plat_info;
232 dma_common_ch_start = CSDP; 232 p.dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
233 233 p.errata = configure_dma_errata();
234 p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
235 if (!p) {
236 pr_err("%s: Unable to allocate pdata for %s:%s\n",
237 __func__, name, oh->name);
238 return -ENOMEM;
239 }
240
241 p->dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
242 p->disable_irq_lch = omap2_disable_irq_lch;
243 p->show_dma_caps = omap2_show_dma_caps;
244 p->clear_dma = omap2_clear_dma;
245 p->dma_write = dma_write;
246 p->dma_read = dma_read;
247
248 p->clear_lch_regs = NULL;
249
250 p->errata = configure_dma_errata();
251 234
252 pdev = omap_device_build(name, 0, oh, p, sizeof(*p)); 235 pdev = omap_device_build(name, 0, oh, &p, sizeof(p));
253 kfree(p);
254 if (IS_ERR(pdev)) { 236 if (IS_ERR(pdev)) {
255 pr_err("%s: Can't build omap_device for %s:%s.\n", 237 pr_err("%s: Can't build omap_device for %s:%s.\n",
256 __func__, name, oh->name); 238 __func__, name, oh->name);
257 return PTR_ERR(pdev); 239 return PTR_ERR(pdev);
258 } 240 }
259 241
242 omap_dma_dev_info.res = pdev->resource;
243 omap_dma_dev_info.num_res = pdev->num_resources;
244
260 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 245 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
261 if (!mem) { 246 if (!mem) {
262 dev_err(&pdev->dev, "%s: no mem resource\n", __func__); 247 dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
263 return -EINVAL; 248 return -EINVAL;
264 } 249 }
250
265 dma_base = ioremap(mem->start, resource_size(mem)); 251 dma_base = ioremap(mem->start, resource_size(mem));
266 if (!dma_base) { 252 if (!dma_base) {
267 dev_err(&pdev->dev, "%s: ioremap fail\n", __func__); 253 dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
@@ -269,13 +255,6 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
269 } 255 }
270 256
271 d = oh->dev_attr; 257 d = oh->dev_attr;
272 d->chan = kzalloc(sizeof(struct omap_dma_lch) *
273 (d->lch_count), GFP_KERNEL);
274
275 if (!d->chan) {
276 dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__);
277 return -ENOMEM;
278 }
279 258
280 if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) 259 if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
281 d->dev_caps |= HS_CHANNELS_RESERVED; 260 d->dev_caps |= HS_CHANNELS_RESERVED;
@@ -289,12 +268,6 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
289 return 0; 268 return 0;
290} 269}
291 270
292static const struct platform_device_info omap_dma_dev_info = {
293 .name = "omap-dma-engine",
294 .id = -1,
295 .dma_mask = DMA_BIT_MASK(32),
296};
297
298static int __init omap2_system_dma_init(void) 271static int __init omap2_system_dma_init(void)
299{ 272{
300 struct platform_device *pdev; 273 struct platform_device *pdev;
diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c
index 85883b2e0e49..6d3517dc4772 100644
--- a/arch/arm/mach-rpc/dma.c
+++ b/arch/arm/mach-rpc/dma.c
@@ -141,7 +141,7 @@ static int iomd_request_dma(unsigned int chan, dma_t *dma)
141 struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma); 141 struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
142 142
143 return request_irq(idma->irq, iomd_dma_handle, 143 return request_irq(idma->irq, iomd_dma_handle,
144 IRQF_DISABLED, idma->dma.device_id, idma); 144 0, idma->dma.device_id, idma);
145} 145}
146 146
147static void iomd_free_dma(unsigned int chan, dma_t *dma) 147static void iomd_free_dma(unsigned int chan, dma_t *dma)
diff --git a/arch/arm/mach-rpc/time.c b/arch/arm/mach-rpc/time.c
index 9a6def14df01..9a5158861ca9 100644
--- a/arch/arm/mach-rpc/time.c
+++ b/arch/arm/mach-rpc/time.c
@@ -75,7 +75,6 @@ ioc_timer_interrupt(int irq, void *dev_id)
75 75
76static struct irqaction ioc_timer_irq = { 76static struct irqaction ioc_timer_irq = {
77 .name = "timer", 77 .name = "timer",
78 .flags = IRQF_DISABLED,
79 .handler = ioc_timer_interrupt 78 .handler = ioc_timer_interrupt
80}; 79};
81 80
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 831a15824ec8..f9874ba60cc8 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -43,6 +43,7 @@
43#include <asm/mach/arch.h> 43#include <asm/mach/arch.h>
44#include <asm/mach/flash.h> 44#include <asm/mach/flash.h>
45#include <asm/mach/map.h> 45#include <asm/mach/map.h>
46#include <asm/mach/irda.h>
46 47
47#include <asm/hardware/scoop.h> 48#include <asm/hardware/scoop.h>
48#include <asm/mach/sharpsl_param.h> 49#include <asm/mach/sharpsl_param.h>
@@ -96,6 +97,37 @@ static struct mcp_plat_data collie_mcp_data = {
96 .codec_pdata = &collie_ucb1x00_data, 97 .codec_pdata = &collie_ucb1x00_data,
97}; 98};
98 99
100static int collie_ir_startup(struct device *dev)
101{
102 int rc = gpio_request(COLLIE_GPIO_IR_ON, "IrDA");
103 if (rc)
104 return rc;
105 rc = gpio_direction_output(COLLIE_GPIO_IR_ON, 1);
106
107 if (!rc)
108 return 0;
109
110 gpio_free(COLLIE_GPIO_IR_ON);
111 return rc;
112}
113
114static void collie_ir_shutdown(struct device *dev)
115{
116 gpio_free(COLLIE_GPIO_IR_ON);
117}
118
119static int collie_ir_set_power(struct device *dev, unsigned int state)
120{
121 gpio_set_value(COLLIE_GPIO_IR_ON, !state);
122 return 0;
123}
124
125static struct irda_platform_data collie_ir_data = {
126 .startup = collie_ir_startup,
127 .shutdown = collie_ir_shutdown,
128 .set_power = collie_ir_set_power,
129};
130
99/* 131/*
100 * Collie AC IN 132 * Collie AC IN
101 */ 133 */
@@ -400,6 +432,7 @@ static void __init collie_init(void)
400 sa11x0_register_mtd(&collie_flash_data, collie_flash_resources, 432 sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
401 ARRAY_SIZE(collie_flash_resources)); 433 ARRAY_SIZE(collie_flash_resources));
402 sa11x0_register_mcp(&collie_mcp_data); 434 sa11x0_register_mcp(&collie_mcp_data);
435 sa11x0_register_irda(&collie_ir_data);
403 436
404 sharpsl_save_param(); 437 sharpsl_save_param();
405} 438}
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
index daa27c474c13..3c43219bc881 100644
--- a/arch/arm/mach-sa1100/h3100.c
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -122,15 +122,8 @@ static struct irda_platform_data h3100_irda_data = {
122 .shutdown = h3100_irda_shutdown, 122 .shutdown = h3100_irda_shutdown,
123}; 123};
124 124
125static struct gpio_default_state h3100_default_gpio[] = {
126 { H3XXX_GPIO_COM_DCD, GPIO_MODE_IN, "COM DCD" },
127 { H3XXX_GPIO_COM_CTS, GPIO_MODE_IN, "COM CTS" },
128 { H3XXX_GPIO_COM_RTS, GPIO_MODE_OUT0, "COM RTS" },
129};
130
131static void __init h3100_mach_init(void) 125static void __init h3100_mach_init(void)
132{ 126{
133 h3xxx_init_gpio(h3100_default_gpio, ARRAY_SIZE(h3100_default_gpio));
134 h3xxx_mach_init(); 127 h3xxx_mach_init();
135 128
136 sa11x0_register_lcd(&h3100_lcd_info); 129 sa11x0_register_lcd(&h3100_lcd_info);
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index a663e7230141..5be54c214c7c 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -130,15 +130,8 @@ static struct irda_platform_data h3600_irda_data = {
130 .shutdown = h3600_irda_shutdown, 130 .shutdown = h3600_irda_shutdown,
131}; 131};
132 132
133static struct gpio_default_state h3600_default_gpio[] = {
134 { H3XXX_GPIO_COM_DCD, GPIO_MODE_IN, "COM DCD" },
135 { H3XXX_GPIO_COM_CTS, GPIO_MODE_IN, "COM CTS" },
136 { H3XXX_GPIO_COM_RTS, GPIO_MODE_OUT0, "COM RTS" },
137};
138
139static void __init h3600_mach_init(void) 133static void __init h3600_mach_init(void)
140{ 134{
141 h3xxx_init_gpio(h3600_default_gpio, ARRAY_SIZE(h3600_default_gpio));
142 h3xxx_mach_init(); 135 h3xxx_mach_init();
143 136
144 sa11x0_register_lcd(&h3600_lcd_info); 137 sa11x0_register_lcd(&h3600_lcd_info);
diff --git a/arch/arm/mach-sa1100/h3xxx.c b/arch/arm/mach-sa1100/h3xxx.c
index f17e7382242a..c79bf467fb7f 100644
--- a/arch/arm/mach-sa1100/h3xxx.c
+++ b/arch/arm/mach-sa1100/h3xxx.c
@@ -28,37 +28,6 @@
28 28
29#include "generic.h" 29#include "generic.h"
30 30
31void h3xxx_init_gpio(struct gpio_default_state *s, size_t n)
32{
33 while (n--) {
34 const char *name = s->name;
35 int err;
36
37 if (!name)
38 name = "[init]";
39 err = gpio_request(s->gpio, name);
40 if (err) {
41 printk(KERN_ERR "gpio%u: unable to request: %d\n",
42 s->gpio, err);
43 continue;
44 }
45 if (s->mode >= 0) {
46 err = gpio_direction_output(s->gpio, s->mode);
47 } else {
48 err = gpio_direction_input(s->gpio);
49 }
50 if (err) {
51 printk(KERN_ERR "gpio%u: unable to set direction: %d\n",
52 s->gpio, err);
53 continue;
54 }
55 if (!s->name)
56 gpio_free(s->gpio);
57 s++;
58 }
59}
60
61
62/* 31/*
63 * H3xxx flash support 32 * H3xxx flash support
64 */ 33 */
@@ -116,9 +85,34 @@ static struct resource h3xxx_flash_resource =
116/* 85/*
117 * H3xxx uart support 86 * H3xxx uart support
118 */ 87 */
88static struct gpio h3xxx_uart_gpio[] = {
89 { H3XXX_GPIO_COM_DCD, GPIOF_IN, "COM DCD" },
90 { H3XXX_GPIO_COM_CTS, GPIOF_IN, "COM CTS" },
91 { H3XXX_GPIO_COM_RTS, GPIOF_OUT_INIT_LOW, "COM RTS" },
92};
93
94static bool h3xxx_uart_request_gpios(void)
95{
96 static bool h3xxx_uart_gpio_ok;
97 int rc;
98
99 if (h3xxx_uart_gpio_ok)
100 return true;
101
102 rc = gpio_request_array(h3xxx_uart_gpio, ARRAY_SIZE(h3xxx_uart_gpio));
103 if (rc)
104 pr_err("h3xxx_uart_request_gpios: error %d\n", rc);
105 else
106 h3xxx_uart_gpio_ok = true;
107
108 return h3xxx_uart_gpio_ok;
109}
110
119static void h3xxx_uart_set_mctrl(struct uart_port *port, u_int mctrl) 111static void h3xxx_uart_set_mctrl(struct uart_port *port, u_int mctrl)
120{ 112{
121 if (port->mapbase == _Ser3UTCR0) { 113 if (port->mapbase == _Ser3UTCR0) {
114 if (!h3xxx_uart_request_gpios())
115 return;
122 gpio_set_value(H3XXX_GPIO_COM_RTS, !(mctrl & TIOCM_RTS)); 116 gpio_set_value(H3XXX_GPIO_COM_RTS, !(mctrl & TIOCM_RTS));
123 } 117 }
124} 118}
@@ -128,6 +122,8 @@ static u_int h3xxx_uart_get_mctrl(struct uart_port *port)
128 u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; 122 u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
129 123
130 if (port->mapbase == _Ser3UTCR0) { 124 if (port->mapbase == _Ser3UTCR0) {
125 if (!h3xxx_uart_request_gpios())
126 return ret;
131 /* 127 /*
132 * DCD and CTS bits are inverted in GPLR by RS232 transceiver 128 * DCD and CTS bits are inverted in GPLR by RS232 transceiver
133 */ 129 */
diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h
index 50e1d850ee2e..b478ca180c19 100644
--- a/arch/arm/mach-sa1100/include/mach/collie.h
+++ b/arch/arm/mach-sa1100/include/mach/collie.h
@@ -80,7 +80,7 @@ extern void locomolcd_power(int on);
80#define COLLIE_TC35143_GPIO_VERSION0 UCB_IO_0 80#define COLLIE_TC35143_GPIO_VERSION0 UCB_IO_0
81#define COLLIE_TC35143_GPIO_TBL_CHK UCB_IO_1 81#define COLLIE_TC35143_GPIO_TBL_CHK UCB_IO_1
82#define COLLIE_TC35143_GPIO_VPEN_ON UCB_IO_2 82#define COLLIE_TC35143_GPIO_VPEN_ON UCB_IO_2
83#define COLLIE_TC35143_GPIO_IR_ON UCB_IO_3 83#define COLLIE_GPIO_IR_ON (COLLIE_TC35143_GPIO_BASE + 3)
84#define COLLIE_TC35143_GPIO_AMP_ON UCB_IO_4 84#define COLLIE_TC35143_GPIO_AMP_ON UCB_IO_4
85#define COLLIE_TC35143_GPIO_VERSION1 UCB_IO_5 85#define COLLIE_TC35143_GPIO_VERSION1 UCB_IO_5
86#define COLLIE_TC35143_GPIO_FS8KLPF UCB_IO_5 86#define COLLIE_TC35143_GPIO_FS8KLPF UCB_IO_5
diff --git a/arch/arm/mach-sa1100/include/mach/h3xxx.h b/arch/arm/mach-sa1100/include/mach/h3xxx.h
index c810620db53d..603d4343f7f6 100644
--- a/arch/arm/mach-sa1100/include/mach/h3xxx.h
+++ b/arch/arm/mach-sa1100/include/mach/h3xxx.h
@@ -79,17 +79,6 @@
79#define H3600_EGPIO_LCD_5V_ON (H3XXX_EGPIO_BASE + 14) /* enable 5V to LCD. active high. */ 79#define H3600_EGPIO_LCD_5V_ON (H3XXX_EGPIO_BASE + 14) /* enable 5V to LCD. active high. */
80#define H3600_EGPIO_LVDD_ON (H3XXX_EGPIO_BASE + 15) /* enable 9V and -6.5V to LCD. */ 80#define H3600_EGPIO_LVDD_ON (H3XXX_EGPIO_BASE + 15) /* enable 9V and -6.5V to LCD. */
81 81
82struct gpio_default_state {
83 int gpio;
84 int mode;
85 const char *name;
86};
87
88#define GPIO_MODE_IN -1
89#define GPIO_MODE_OUT0 0
90#define GPIO_MODE_OUT1 1
91
92void h3xxx_init_gpio(struct gpio_default_state *s, size_t n);
93void __init h3xxx_map_io(void); 82void __init h3xxx_map_io(void);
94void __init h3xxx_mach_init(void); 83void __init h3xxx_mach_init(void);
95 84
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index 6fd4acb8f187..4852c08cb526 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -112,7 +112,7 @@ static struct clock_event_device ckevt_sa1100_osmr0 = {
112 112
113static struct irqaction sa1100_timer_irq = { 113static struct irqaction sa1100_timer_irq = {
114 .name = "ost0", 114 .name = "ost0",
115 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 115 .flags = IRQF_TIMER | IRQF_IRQPOLL,
116 .handler = sa1100_ost0_interrupt, 116 .handler = sa1100_ost0_interrupt,
117 .dev_id = &ckevt_sa1100_osmr0, 117 .dev_id = &ckevt_sa1100_osmr0,
118}; 118};
diff --git a/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c
index d449673e40f7..218ba5b67d92 100644
--- a/arch/arm/mach-spear/time.c
+++ b/arch/arm/mach-spear/time.c
@@ -172,7 +172,7 @@ static irqreturn_t spear_timer_interrupt(int irq, void *dev_id)
172 172
173static struct irqaction spear_timer_irq = { 173static struct irqaction spear_timer_irq = {
174 .name = "timer", 174 .name = "timer",
175 .flags = IRQF_DISABLED | IRQF_TIMER, 175 .flags = IRQF_TIMER,
176 .handler = spear_timer_interrupt 176 .handler = spear_timer_interrupt
177}; 177};
178 178
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
index 0997e0b7494c..fc649bc09d0c 100644
--- a/arch/arm/mach-vexpress/Makefile
+++ b/arch/arm/mach-vexpress/Makefile
@@ -8,8 +8,11 @@ obj-y := v2m.o
8obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o 8obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
9obj-$(CONFIG_ARCH_VEXPRESS_DCSCB) += dcscb.o dcscb_setup.o 9obj-$(CONFIG_ARCH_VEXPRESS_DCSCB) += dcscb.o dcscb_setup.o
10CFLAGS_dcscb.o += -march=armv7-a 10CFLAGS_dcscb.o += -march=armv7-a
11CFLAGS_REMOVE_dcscb.o = -pg
11obj-$(CONFIG_ARCH_VEXPRESS_SPC) += spc.o 12obj-$(CONFIG_ARCH_VEXPRESS_SPC) += spc.o
13CFLAGS_REMOVE_spc.o = -pg
12obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM) += tc2_pm.o 14obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM) += tc2_pm.o
13CFLAGS_tc2_pm.o += -march=armv7-a 15CFLAGS_tc2_pm.o += -march=armv7-a
16CFLAGS_REMOVE_tc2_pm.o = -pg
14obj-$(CONFIG_SMP) += platsmp.o 17obj-$(CONFIG_SMP) += platsmp.o
15obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 18obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-w90x900/time.c b/arch/arm/mach-w90x900/time.c
index 30fbca844575..9230d3725599 100644
--- a/arch/arm/mach-w90x900/time.c
+++ b/arch/arm/mach-w90x900/time.c
@@ -111,7 +111,7 @@ static irqreturn_t nuc900_timer0_interrupt(int irq, void *dev_id)
111 111
112static struct irqaction nuc900_timer0_irq = { 112static struct irqaction nuc900_timer0_irq = {
113 .name = "nuc900-timer0", 113 .name = "nuc900-timer0",
114 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 114 .flags = IRQF_TIMER | IRQF_IRQPOLL,
115 .handler = nuc900_timer0_interrupt, 115 .handler = nuc900_timer0_interrupt,
116}; 116};
117 117
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 1f8fed94c2a4..ca8ecdee47d8 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -446,7 +446,6 @@ config CPU_32v5
446 446
447config CPU_32v6 447config CPU_32v6
448 bool 448 bool
449 select CPU_USE_DOMAINS if CPU_V6 && MMU
450 select TLS_REG_EMUL if !CPU_32v6K && !MMU 449 select TLS_REG_EMUL if !CPU_32v6K && !MMU
451 450
452config CPU_32v6K 451config CPU_32v6K
@@ -671,7 +670,7 @@ config ARM_VIRT_EXT
671 670
672config SWP_EMULATE 671config SWP_EMULATE
673 bool "Emulate SWP/SWPB instructions" 672 bool "Emulate SWP/SWPB instructions"
674 depends on !CPU_USE_DOMAINS && CPU_V7 673 depends on CPU_V7
675 default y if SMP 674 default y if SMP
676 select HAVE_PROC_CPU if PROC_FS 675 select HAVE_PROC_CPU if PROC_FS
677 help 676 help
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index 48bc3c0a87ce..aae891820f8f 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -331,7 +331,9 @@ static void __init enable_l2(void)
331 enable_icache(); 331 enable_icache();
332 if (d) 332 if (d)
333 enable_dcache(); 333 enable_dcache();
334 } 334 } else
335 pr_err(FW_BUG
336 "Feroceon L2: bootloader left the L2 cache on!\n");
335} 337}
336 338
337void __init feroceon_l2_init(int __l2_wt_override) 339void __init feroceon_l2_init(int __l2_wt_override)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 4fe42ce720d2..f62aa0677e5c 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -284,9 +284,6 @@ static void __dma_free_buffer(struct page *page, size_t size)
284} 284}
285 285
286#ifdef CONFIG_MMU 286#ifdef CONFIG_MMU
287#ifdef CONFIG_HUGETLB_PAGE
288#warning ARM Coherent DMA allocator does not (yet) support huge TLB
289#endif
290 287
291static void *__alloc_from_contiguous(struct device *dev, size_t size, 288static void *__alloc_from_contiguous(struct device *dev, size_t size,
292 pgprot_t prot, struct page **ret_page, 289 pgprot_t prot, struct page **ret_page,
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index a623cb3ad012..b68c6b22e1c8 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -516,6 +516,16 @@ static void __init build_mem_type_table(void)
516 s2_device_pgprot = mem_types[MT_DEVICE].prot_pte_s2; 516 s2_device_pgprot = mem_types[MT_DEVICE].prot_pte_s2;
517 517
518 /* 518 /*
519 * We don't use domains on ARMv6 (since this causes problems with
520 * v6/v7 kernels), so we must use a separate memory type for user
521 * r/o, kernel r/w to map the vectors page.
522 */
523#ifndef CONFIG_ARM_LPAE
524 if (cpu_arch == CPU_ARCH_ARMv6)
525 vecs_pgprot |= L_PTE_MT_VECTORS;
526#endif
527
528 /*
519 * ARMv6 and above have extended page tables. 529 * ARMv6 and above have extended page tables.
520 */ 530 */
521 if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { 531 if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index e3c48a3fe063..ee1d80593958 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -112,13 +112,9 @@
112 * 100x 1 0 1 r/o no acc 112 * 100x 1 0 1 r/o no acc
113 * 10x0 1 0 1 r/o no acc 113 * 10x0 1 0 1 r/o no acc
114 * 1011 0 0 1 r/w no acc 114 * 1011 0 0 1 r/w no acc
115 * 110x 0 1 0 r/w r/o
116 * 11x0 0 1 0 r/w r/o
117 * 1111 0 1 1 r/w r/w
118 *
119 * If !CONFIG_CPU_USE_DOMAINS, the following permissions are changed:
120 * 110x 1 1 1 r/o r/o 115 * 110x 1 1 1 r/o r/o
121 * 11x0 1 1 1 r/o r/o 116 * 11x0 1 1 1 r/o r/o
117 * 1111 0 1 1 r/w r/w
122 */ 118 */
123 .macro armv6_mt_table pfx 119 .macro armv6_mt_table pfx
124\pfx\()_mt_table: 120\pfx\()_mt_table:
@@ -137,7 +133,7 @@
137 .long PTE_EXT_TEX(2) @ L_PTE_MT_DEV_NONSHARED 133 .long PTE_EXT_TEX(2) @ L_PTE_MT_DEV_NONSHARED
138 .long 0x00 @ unused 134 .long 0x00 @ unused
139 .long 0x00 @ unused 135 .long 0x00 @ unused
140 .long 0x00 @ unused 136 .long PTE_CACHEABLE | PTE_BUFFERABLE | PTE_EXT_APX @ L_PTE_MT_VECTORS
141 .endm 137 .endm
142 138
143 .macro armv6_set_pte_ext pfx 139 .macro armv6_set_pte_ext pfx
@@ -158,24 +154,21 @@
158 154
159 tst r1, #L_PTE_USER 155 tst r1, #L_PTE_USER
160 orrne r3, r3, #PTE_EXT_AP1 156 orrne r3, r3, #PTE_EXT_AP1
161#ifdef CONFIG_CPU_USE_DOMAINS
162 @ allow kernel read/write access to read-only user pages
163 tstne r3, #PTE_EXT_APX 157 tstne r3, #PTE_EXT_APX
164 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 158
165#endif 159 @ user read-only -> kernel read-only
160 bicne r3, r3, #PTE_EXT_AP0
166 161
167 tst r1, #L_PTE_XN 162 tst r1, #L_PTE_XN
168 orrne r3, r3, #PTE_EXT_XN 163 orrne r3, r3, #PTE_EXT_XN
169 164
170 orr r3, r3, r2 165 eor r3, r3, r2
171 166
172 tst r1, #L_PTE_YOUNG 167 tst r1, #L_PTE_YOUNG
173 tstne r1, #L_PTE_PRESENT 168 tstne r1, #L_PTE_PRESENT
174 moveq r3, #0 169 moveq r3, #0
175#ifndef CONFIG_CPU_USE_DOMAINS
176 tstne r1, #L_PTE_NONE 170 tstne r1, #L_PTE_NONE
177 movne r3, #0 171 movne r3, #0
178#endif
179 172
180 str r3, [r0] 173 str r3, [r0]
181 mcr p15, 0, r0, c7, c10, 1 @ flush_pte 174 mcr p15, 0, r0, c7, c10, 1 @ flush_pte
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
index bdd3be4be77a..1f52915f2b28 100644
--- a/arch/arm/mm/proc-v7-2level.S
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -90,21 +90,14 @@ ENTRY(cpu_v7_set_pte_ext)
90 90
91 tst r1, #L_PTE_USER 91 tst r1, #L_PTE_USER
92 orrne r3, r3, #PTE_EXT_AP1 92 orrne r3, r3, #PTE_EXT_AP1
93#ifdef CONFIG_CPU_USE_DOMAINS
94 @ allow kernel read/write access to read-only user pages
95 tstne r3, #PTE_EXT_APX
96 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
97#endif
98 93
99 tst r1, #L_PTE_XN 94 tst r1, #L_PTE_XN
100 orrne r3, r3, #PTE_EXT_XN 95 orrne r3, r3, #PTE_EXT_XN
101 96
102 tst r1, #L_PTE_YOUNG 97 tst r1, #L_PTE_YOUNG
103 tstne r1, #L_PTE_VALID 98 tstne r1, #L_PTE_VALID
104#ifndef CONFIG_CPU_USE_DOMAINS
105 eorne r1, r1, #L_PTE_NONE 99 eorne r1, r1, #L_PTE_NONE
106 tstne r1, #L_PTE_NONE 100 tstne r1, #L_PTE_NONE
107#endif
108 moveq r3, #0 101 moveq r3, #0
109 102
110 ARM( str r3, [r0, #2048]! ) 103 ARM( str r3, [r0, #2048]! )
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 74f6033e76dd..195731d3813b 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -192,6 +192,7 @@ __v7_cr7mp_setup:
192 mov r10, #(1 << 0) @ Cache/TLB ops broadcasting 192 mov r10, #(1 << 0) @ Cache/TLB ops broadcasting
193 b 1f 193 b 1f
194__v7_ca7mp_setup: 194__v7_ca7mp_setup:
195__v7_ca12mp_setup:
195__v7_ca15mp_setup: 196__v7_ca15mp_setup:
196 mov r10, #0 197 mov r10, #0
1971: 1981:
@@ -484,6 +485,16 @@ __v7_ca7mp_proc_info:
484 .size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info 485 .size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info
485 486
486 /* 487 /*
488 * ARM Ltd. Cortex A12 processor.
489 */
490 .type __v7_ca12mp_proc_info, #object
491__v7_ca12mp_proc_info:
492 .long 0x410fc0d0
493 .long 0xff0ffff0
494 __v7_proc __v7_ca12mp_setup
495 .size __v7_ca12mp_proc_info, . - __v7_ca12mp_proc_info
496
497 /*
487 * ARM Ltd. Cortex A15 processor. 498 * ARM Ltd. Cortex A15 processor.
488 */ 499 */
489 .type __v7_ca15mp_proc_info, #object 500 .type __v7_ca15mp_proc_info, #object
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
index d70b73364a3f..6ad65d8ae237 100644
--- a/arch/arm/plat-iop/time.c
+++ b/arch/arm/plat-iop/time.c
@@ -127,7 +127,7 @@ iop_timer_interrupt(int irq, void *dev_id)
127static struct irqaction iop_timer_irq = { 127static struct irqaction iop_timer_irq = {
128 .name = "IOP Timer Tick", 128 .name = "IOP Timer Tick",
129 .handler = iop_timer_interrupt, 129 .handler = iop_timer_interrupt,
130 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 130 .flags = IRQF_TIMER | IRQF_IRQPOLL,
131 .dev_id = &iop_clockevent, 131 .dev_id = &iop_clockevent,
132}; 132};
133 133
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 01619c2910e3..5f5b975887fc 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -2000,6 +2000,12 @@ void omap_dma_global_context_restore(void)
2000 omap_clear_dma(ch); 2000 omap_clear_dma(ch);
2001} 2001}
2002 2002
2003struct omap_system_dma_plat_info *omap_get_plat_info(void)
2004{
2005 return p;
2006}
2007EXPORT_SYMBOL_GPL(omap_get_plat_info);
2008
2003static int omap_system_dma_probe(struct platform_device *pdev) 2009static int omap_system_dma_probe(struct platform_device *pdev)
2004{ 2010{
2005 int ch, ret = 0; 2011 int ch, ret = 0;
@@ -2024,9 +2030,16 @@ static int omap_system_dma_probe(struct platform_device *pdev)
2024 2030
2025 dma_lch_count = d->lch_count; 2031 dma_lch_count = d->lch_count;
2026 dma_chan_count = dma_lch_count; 2032 dma_chan_count = dma_lch_count;
2027 dma_chan = d->chan;
2028 enable_1510_mode = d->dev_caps & ENABLE_1510_MODE; 2033 enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;
2029 2034
2035 dma_chan = devm_kcalloc(&pdev->dev, dma_lch_count,
2036 sizeof(struct omap_dma_lch), GFP_KERNEL);
2037 if (!dma_chan) {
2038 dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__);
2039 return -ENOMEM;
2040 }
2041
2042
2030 if (dma_omap2plus()) { 2043 if (dma_omap2plus()) {
2031 dma_linked_lch = kzalloc(sizeof(struct dma_link_info) * 2044 dma_linked_lch = kzalloc(sizeof(struct dma_link_info) *
2032 dma_lch_count, GFP_KERNEL); 2045 dma_lch_count, GFP_KERNEL);
@@ -2111,7 +2124,6 @@ exit_dma_irq_fail:
2111 } 2124 }
2112 2125
2113exit_dma_lch_fail: 2126exit_dma_lch_fail:
2114 kfree(dma_chan);
2115 return ret; 2127 return ret;
2116} 2128}
2117 2129
@@ -2131,7 +2143,6 @@ static int omap_system_dma_remove(struct platform_device *pdev)
2131 free_irq(dma_irq, (void *)(irq_rel + 1)); 2143 free_irq(dma_irq, (void *)(irq_rel + 1));
2132 } 2144 }
2133 } 2145 }
2134 kfree(dma_chan);
2135 return 0; 2146 return 0;
2136} 2147}
2137 2148