aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/Kconfig.debug101
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/compressed/head.S2
-rw-r--r--arch/arm/boot/dts/exynos4210.dtsi9
-rw-r--r--arch/arm/boot/dts/exynos4x12.dtsi14
-rw-r--r--arch/arm/configs/iop32x_defconfig1
-rw-r--r--arch/arm/configs/iop33x_defconfig1
-rw-r--r--arch/arm/configs/ixp4xx_defconfig1
-rw-r--r--arch/arm/configs/lpc32xx_defconfig1
-rw-r--r--arch/arm/configs/mv78xx0_defconfig1
-rw-r--r--arch/arm/configs/orion5x_defconfig1
-rw-r--r--arch/arm/configs/rpc_defconfig1
-rw-r--r--arch/arm/include/asm/bitrev.h20
-rw-r--r--arch/arm/include/asm/compiler.h15
-rw-r--r--arch/arm/include/asm/insn.h (renamed from arch/arm/kernel/insn.h)0
-rw-r--r--arch/arm/include/asm/kprobes.h33
-rw-r--r--arch/arm/include/asm/outercache.h3
-rw-r--r--arch/arm/include/asm/patch.h (renamed from arch/arm/kernel/patch.h)0
-rw-r--r--arch/arm/include/asm/probes.h15
-rw-r--r--arch/arm/include/debug/ks8695.S (renamed from arch/arm/mach-ks8695/include/mach/debug-macro.S)10
-rw-r--r--arch/arm/include/debug/netx.S (renamed from arch/arm/mach-netx/include/mach/debug-macro.S)22
-rw-r--r--arch/arm/kernel/Makefile16
-rw-r--r--arch/arm/kernel/entry-armv.S3
-rw-r--r--arch/arm/kernel/ftrace.c3
-rw-r--r--arch/arm/kernel/head.S9
-rw-r--r--arch/arm/kernel/irq.c3
-rw-r--r--arch/arm/kernel/jump_label.c5
-rw-r--r--arch/arm/kernel/kgdb.c3
-rw-r--r--arch/arm/kernel/patch.c3
-rw-r--r--arch/arm/kernel/suspend.c4
-rw-r--r--arch/arm/lib/Makefile15
-rw-r--r--arch/arm/lib/uaccess.S564
-rw-r--r--arch/arm/mach-exynos/firmware.c50
-rw-r--r--arch/arm/mach-exynos/sleep.S46
-rw-r--r--arch/arm/mach-omap1/include/mach/debug-macro.S101
-rw-r--r--arch/arm/mach-omap2/board-generic.c6
-rw-r--r--arch/arm/mach-omap2/common.h8
-rw-r--r--arch/arm/mach-omap2/omap4-common.c16
-rw-r--r--arch/arm/mach-qcom/platsmp.c4
-rw-r--r--arch/arm/mach-sa1100/Makefile2
-rw-r--r--arch/arm/mach-sa1100/clock.c12
-rw-r--r--arch/arm/mach-sa1100/collie.c3
-rw-r--r--arch/arm/mach-sa1100/generic.c6
-rw-r--r--arch/arm/mach-sa1100/include/mach/irqs.h73
-rw-r--r--arch/arm/mach-sa1100/irq.c203
-rw-r--r--arch/arm/mach-sa1100/pm.c1
-rw-r--r--arch/arm/mach-sa1100/time.c139
-rw-r--r--arch/arm/mm/cache-l2x0.c439
-rw-r--r--arch/arm/mm/init.c5
-rw-r--r--arch/arm/probes/Makefile7
-rw-r--r--arch/arm/probes/decode-arm.c (renamed from arch/arm/kernel/probes-arm.c)18
-rw-r--r--arch/arm/probes/decode-arm.h (renamed from arch/arm/kernel/probes-arm.h)9
-rw-r--r--arch/arm/probes/decode-thumb.c (renamed from arch/arm/kernel/probes-thumb.c)16
-rw-r--r--arch/arm/probes/decode-thumb.h (renamed from arch/arm/kernel/probes-thumb.h)10
-rw-r--r--arch/arm/probes/decode.c (renamed from arch/arm/kernel/probes.c)81
-rw-r--r--arch/arm/probes/decode.h (renamed from arch/arm/kernel/probes.h)13
-rw-r--r--arch/arm/probes/kprobes/Makefile12
-rw-r--r--arch/arm/probes/kprobes/actions-arm.c (renamed from arch/arm/kernel/kprobes-arm.c)11
-rw-r--r--arch/arm/probes/kprobes/actions-common.c (renamed from arch/arm/kernel/kprobes-common.c)4
-rw-r--r--arch/arm/probes/kprobes/actions-thumb.c (renamed from arch/arm/kernel/kprobes-thumb.c)10
-rw-r--r--arch/arm/probes/kprobes/checkers-arm.c192
-rw-r--r--arch/arm/probes/kprobes/checkers-common.c101
-rw-r--r--arch/arm/probes/kprobes/checkers-thumb.c110
-rw-r--r--arch/arm/probes/kprobes/checkers.h55
-rw-r--r--arch/arm/probes/kprobes/core.c (renamed from arch/arm/kernel/kprobes.c)49
-rw-r--r--arch/arm/probes/kprobes/core.h (renamed from arch/arm/kernel/kprobes.h)12
-rw-r--r--arch/arm/probes/kprobes/opt-arm.c370
-rw-r--r--arch/arm/probes/kprobes/test-arm.c (renamed from arch/arm/kernel/kprobes-test-arm.c)40
-rw-r--r--arch/arm/probes/kprobes/test-core.c (renamed from arch/arm/kernel/kprobes-test.c)46
-rw-r--r--arch/arm/probes/kprobes/test-core.h (renamed from arch/arm/kernel/kprobes-test.h)35
-rw-r--r--arch/arm/probes/kprobes/test-thumb.c (renamed from arch/arm/kernel/kprobes-test-thumb.c)20
-rw-r--r--arch/arm/probes/uprobes/Makefile1
-rw-r--r--arch/arm/probes/uprobes/actions-arm.c (renamed from arch/arm/kernel/uprobes-arm.c)8
-rw-r--r--arch/arm/probes/uprobes/core.c (renamed from arch/arm/kernel/uprobes.c)8
-rw-r--r--arch/arm/probes/uprobes/core.h (renamed from arch/arm/kernel/uprobes.h)0
-rw-r--r--arch/arm64/Kconfig1
-rw-r--r--arch/arm64/include/asm/bitrev.h19
-rw-r--r--arch/x86/kernel/kprobes/opt.c3
79 files changed, 1807 insertions, 1450 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index dcb2e0c55be4..0850fc0f9658 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -29,6 +29,7 @@ config ARM
29 select HANDLE_DOMAIN_IRQ 29 select HANDLE_DOMAIN_IRQ
30 select HARDIRQS_SW_RESEND 30 select HARDIRQS_SW_RESEND
31 select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT) 31 select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT)
32 select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
32 select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL 33 select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
33 select HAVE_ARCH_KGDB 34 select HAVE_ARCH_KGDB
34 select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT) 35 select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
@@ -60,6 +61,7 @@ config ARM
60 select HAVE_MEMBLOCK 61 select HAVE_MEMBLOCK
61 select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND 62 select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND
62 select HAVE_OPROFILE if (HAVE_PERF_EVENTS) 63 select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
64 select HAVE_OPTPROBES if !THUMB2_KERNEL
63 select HAVE_PERF_EVENTS 65 select HAVE_PERF_EVENTS
64 select HAVE_PERF_REGS 66 select HAVE_PERF_REGS
65 select HAVE_PERF_USER_STACK_DUMP 67 select HAVE_PERF_USER_STACK_DUMP
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 5ddd4906f7a7..a324ecdfeb21 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -397,6 +397,13 @@ choice
397 Say Y here if you want the debug print routines to direct 397 Say Y here if you want the debug print routines to direct
398 their output to UART1 serial port on KEYSTONE2 devices. 398 their output to UART1 serial port on KEYSTONE2 devices.
399 399
400 config DEBUG_KS8695_UART
401 bool "KS8695 Debug UART"
402 depends on ARCH_KS8695
403 help
404 Say Y here if you want kernel low-level debugging support
405 on KS8695.
406
400 config DEBUG_MESON_UARTAO 407 config DEBUG_MESON_UARTAO
401 bool "Kernel low-level debugging via Meson6 UARTAO" 408 bool "Kernel low-level debugging via Meson6 UARTAO"
402 depends on ARCH_MESON 409 depends on ARCH_MESON
@@ -496,6 +503,13 @@ choice
496 Say Y here if you want kernel low-level debugging support 503 Say Y here if you want kernel low-level debugging support
497 on Vybrid based platforms. 504 on Vybrid based platforms.
498 505
506 config DEBUG_NETX_UART
507 bool "Kernel low-level debugging messages via NetX UART"
508 depends on ARCH_NETX
509 help
510 Say Y here if you want kernel low-level debugging support
511 on Hilscher NetX based platforms.
512
499 config DEBUG_NOMADIK_UART 513 config DEBUG_NOMADIK_UART
500 bool "Kernel low-level debugging messages via NOMADIK UART" 514 bool "Kernel low-level debugging messages via NOMADIK UART"
501 depends on ARCH_NOMADIK 515 depends on ARCH_NOMADIK
@@ -520,6 +534,30 @@ choice
520 Say Y here if you want kernel low-level debugging support 534 Say Y here if you want kernel low-level debugging support
521 on TI-NSPIRE CX models. 535 on TI-NSPIRE CX models.
522 536
537 config DEBUG_OMAP1UART1
538 bool "Kernel low-level debugging via OMAP1 UART1"
539 depends on ARCH_OMAP1
540 select DEBUG_UART_8250
541 help
542 Say Y here if you want kernel low-level debugging support
543 on OMAP1 based platforms (except OMAP730) on the UART1.
544
545 config DEBUG_OMAP1UART2
546 bool "Kernel low-level debugging via OMAP1 UART2"
547 depends on ARCH_OMAP1
548 select DEBUG_UART_8250
549 help
550 Say Y here if you want kernel low-level debugging support
551 on OMAP1 based platforms (except OMAP730) on the UART2.
552
553 config DEBUG_OMAP1UART3
554 bool "Kernel low-level debugging via OMAP1 UART3"
555 depends on ARCH_OMAP1
556 select DEBUG_UART_8250
557 help
558 Say Y here if you want kernel low-level debugging support
559 on OMAP1 based platforms (except OMAP730) on the UART3.
560
523 config DEBUG_OMAP2UART1 561 config DEBUG_OMAP2UART1
524 bool "OMAP2/3/4 UART1 (omap2/3 sdp boards and some omap3 boards)" 562 bool "OMAP2/3/4 UART1 (omap2/3 sdp boards and some omap3 boards)"
525 depends on ARCH_OMAP2PLUS 563 depends on ARCH_OMAP2PLUS
@@ -562,6 +600,30 @@ choice
562 depends on ARCH_OMAP2PLUS 600 depends on ARCH_OMAP2PLUS
563 select DEBUG_OMAP2PLUS_UART 601 select DEBUG_OMAP2PLUS_UART
564 602
603 config DEBUG_OMAP7XXUART1
604 bool "Kernel low-level debugging via OMAP730 UART1"
605 depends on ARCH_OMAP730
606 select DEBUG_UART_8250
607 help
608 Say Y here if you want kernel low-level debugging support
609 on OMAP730 based platforms on the UART1.
610
611 config DEBUG_OMAP7XXUART2
612 bool "Kernel low-level debugging via OMAP730 UART2"
613 depends on ARCH_OMAP730
614 select DEBUG_UART_8250
615 help
616 Say Y here if you want kernel low-level debugging support
617 on OMAP730 based platforms on the UART2.
618
619 config DEBUG_OMAP7XXUART3
620 bool "Kernel low-level debugging via OMAP730 UART3"
621 depends on ARCH_OMAP730
622 select DEBUG_UART_8250
623 help
624 Say Y here if you want kernel low-level debugging support
625 on OMAP730 based platforms on the UART3.
626
565 config DEBUG_TI81XXUART1 627 config DEBUG_TI81XXUART1
566 bool "Kernel low-level debugging messages via TI81XX UART1 (ti8148evm)" 628 bool "Kernel low-level debugging messages via TI81XX UART1 (ti8148evm)"
567 depends on ARCH_OMAP2PLUS 629 depends on ARCH_OMAP2PLUS
@@ -1031,15 +1093,6 @@ choice
1031 This option selects UART0 on VIA/Wondermedia System-on-a-chip 1093 This option selects UART0 on VIA/Wondermedia System-on-a-chip
1032 devices, including VT8500, WM8505, WM8650 and WM8850. 1094 devices, including VT8500, WM8505, WM8650 and WM8850.
1033 1095
1034 config DEBUG_LL_UART_NONE
1035 bool "No low-level debugging UART"
1036 depends on !ARCH_MULTIPLATFORM
1037 help
1038 Say Y here if your platform doesn't provide a UART option
1039 above. This relies on your platform choosing the right UART
1040 definition internally in order for low-level debugging to
1041 work.
1042
1043 config DEBUG_ICEDCC 1096 config DEBUG_ICEDCC
1044 bool "Kernel low-level debugging via EmbeddedICE DCC channel" 1097 bool "Kernel low-level debugging via EmbeddedICE DCC channel"
1045 help 1098 help
@@ -1183,7 +1236,9 @@ config DEBUG_LL_INCLUDE
1183 DEBUG_IMX6Q_UART || \ 1236 DEBUG_IMX6Q_UART || \
1184 DEBUG_IMX6SL_UART || \ 1237 DEBUG_IMX6SL_UART || \
1185 DEBUG_IMX6SX_UART 1238 DEBUG_IMX6SX_UART
1239 default "debug/ks8695.S" if DEBUG_KS8695_UART
1186 default "debug/msm.S" if DEBUG_MSM_UART || DEBUG_QCOM_UARTDM 1240 default "debug/msm.S" if DEBUG_MSM_UART || DEBUG_QCOM_UARTDM
1241 default "debug/netx.S" if DEBUG_NETX_UART
1187 default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART 1242 default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
1188 default "debug/renesas-scif.S" if DEBUG_R7S72100_SCIF2 1243 default "debug/renesas-scif.S" if DEBUG_R7S72100_SCIF2
1189 default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF0 1244 default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF0
@@ -1208,12 +1263,7 @@ config DEBUG_LL_INCLUDE
1208 1263
1209# Compatibility options for PL01x 1264# Compatibility options for PL01x
1210config DEBUG_UART_PL01X 1265config DEBUG_UART_PL01X
1211 def_bool ARCH_EP93XX || \ 1266 bool
1212 ARCH_INTEGRATOR || \
1213 ARCH_SPEAR3XX || \
1214 ARCH_SPEAR6XX || \
1215 ARCH_SPEAR13XX || \
1216 ARCH_VERSATILE
1217 1267
1218# Compatibility options for 8250 1268# Compatibility options for 8250
1219config DEBUG_UART_8250 1269config DEBUG_UART_8250
@@ -1229,6 +1279,7 @@ config DEBUG_UART_BCM63XX
1229 1279
1230config DEBUG_UART_PHYS 1280config DEBUG_UART_PHYS
1231 hex "Physical base address of debug UART" 1281 hex "Physical base address of debug UART"
1282 default 0x00100a00 if DEBUG_NETX_UART
1232 default 0x01c20000 if DEBUG_DAVINCI_DMx_UART0 1283 default 0x01c20000 if DEBUG_DAVINCI_DMx_UART0
1233 default 0x01c28000 if DEBUG_SUNXI_UART0 1284 default 0x01c28000 if DEBUG_SUNXI_UART0
1234 default 0x01c28400 if DEBUG_SUNXI_UART1 1285 default 0x01c28400 if DEBUG_SUNXI_UART1
@@ -1269,7 +1320,6 @@ config DEBUG_UART_PHYS
1269 DEBUG_S3C2410_UART2) 1320 DEBUG_S3C2410_UART2)
1270 default 0x78000000 if DEBUG_CNS3XXX 1321 default 0x78000000 if DEBUG_CNS3XXX
1271 default 0x7c0003f8 if FOOTBRIDGE 1322 default 0x7c0003f8 if FOOTBRIDGE
1272 default 0x78000000 if DEBUG_CNS3XXX
1273 default 0x80010000 if DEBUG_ASM9260_UART 1323 default 0x80010000 if DEBUG_ASM9260_UART
1274 default 0x80070000 if DEBUG_IMX23_UART 1324 default 0x80070000 if DEBUG_IMX23_UART
1275 default 0x80074000 if DEBUG_IMX28_UART 1325 default 0x80074000 if DEBUG_IMX28_UART
@@ -1310,12 +1360,17 @@ config DEBUG_UART_PHYS
1310 default 0xffe40000 if DEBUG_RCAR_GEN1_SCIF0 1360 default 0xffe40000 if DEBUG_RCAR_GEN1_SCIF0
1311 default 0xffe42000 if DEBUG_RCAR_GEN1_SCIF2 1361 default 0xffe42000 if DEBUG_RCAR_GEN1_SCIF2
1312 default 0xfff36000 if DEBUG_HIGHBANK_UART 1362 default 0xfff36000 if DEBUG_HIGHBANK_UART
1363 default 0xfffb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1
1364 default 0xfffb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2
1365 default 0xfffb9800 if DEBUG_OMAP1UART3 || DEBUG_OMAP7XXUART3
1313 default 0xfffe8600 if DEBUG_UART_BCM63XX 1366 default 0xfffe8600 if DEBUG_UART_BCM63XX
1314 default 0xfffff700 if ARCH_IOP33X 1367 default 0xfffff700 if ARCH_IOP33X
1315 depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ 1368 depends on ARCH_EP93XX || \
1369 DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
1316 DEBUG_LL_UART_EFM32 || \ 1370 DEBUG_LL_UART_EFM32 || \
1317 DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \ 1371 DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
1318 DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \ 1372 DEBUG_MSM_UART || DEBUG_NETX_UART || \
1373 DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \
1319 DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \ 1374 DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \
1320 DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \ 1375 DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \
1321 DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \ 1376 DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
@@ -1324,6 +1379,7 @@ config DEBUG_UART_PHYS
1324 1379
1325config DEBUG_UART_VIRT 1380config DEBUG_UART_VIRT
1326 hex "Virtual base address of debug UART" 1381 hex "Virtual base address of debug UART"
1382 default 0xe0000a00 if DEBUG_NETX_UART
1327 default 0xe0010fe0 if ARCH_RPC 1383 default 0xe0010fe0 if ARCH_RPC
1328 default 0xe1000000 if DEBUG_MSM_UART 1384 default 0xe1000000 if DEBUG_MSM_UART
1329 default 0xf0000be0 if ARCH_EBSA110 1385 default 0xf0000be0 if ARCH_EBSA110
@@ -1392,18 +1448,23 @@ config DEBUG_UART_VIRT
1392 default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN 1448 default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN
1393 default 0xfef00003 if ARCH_IXP4XX && CPU_BIG_ENDIAN 1449 default 0xfef00003 if ARCH_IXP4XX && CPU_BIG_ENDIAN
1394 default 0xfef36000 if DEBUG_HIGHBANK_UART 1450 default 0xfef36000 if DEBUG_HIGHBANK_UART
1451 default 0xfefb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1
1452 default 0xfefb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2
1453 default 0xfefb9800 if DEBUG_OMAP1UART3 || DEBUG_OMAP7XXUART3
1395 default 0xfefff700 if ARCH_IOP33X 1454 default 0xfefff700 if ARCH_IOP33X
1396 default 0xff003000 if DEBUG_U300_UART 1455 default 0xff003000 if DEBUG_U300_UART
1397 default DEBUG_UART_PHYS if !MMU 1456 default DEBUG_UART_PHYS if !MMU
1398 depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ 1457 depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
1399 DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \ 1458 DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
1400 DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \ 1459 DEBUG_MSM_UART || DEBUG_NETX_UART || \
1460 DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \
1401 DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART 1461 DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART
1402 1462
1403config DEBUG_UART_8250_SHIFT 1463config DEBUG_UART_8250_SHIFT
1404 int "Register offset shift for the 8250 debug UART" 1464 int "Register offset shift for the 8250 debug UART"
1405 depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 1465 depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
1406 default 0 if FOOTBRIDGE || ARCH_IOP32X || DEBUG_BCM_5301X 1466 default 0 if FOOTBRIDGE || ARCH_IOP32X || DEBUG_BCM_5301X || \
1467 DEBUG_OMAP7XXUART1 || DEBUG_OMAP7XXUART2 || DEBUG_OMAP7XXUART3
1407 default 2 1468 default 2
1408 1469
1409config DEBUG_UART_8250_WORD 1470config DEBUG_UART_8250_WORD
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c1785eec2cf7..7f99cd652203 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -266,6 +266,7 @@ core-$(CONFIG_KVM_ARM_HOST) += arch/arm/kvm/
266 266
267# If we have a machine-specific directory, then include it in the build. 267# If we have a machine-specific directory, then include it in the build.
268core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ 268core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
269core-y += arch/arm/probes/
269core-y += arch/arm/net/ 270core-y += arch/arm/net/
270core-y += arch/arm/crypto/ 271core-y += arch/arm/crypto/
271core-y += arch/arm/firmware/ 272core-y += arch/arm/firmware/
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 132c70e2d2f1..c41a793b519c 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -178,7 +178,7 @@ not_angel:
178 178
179 /* 179 /*
180 * Set up a page table only if it won't overwrite ourself. 180 * Set up a page table only if it won't overwrite ourself.
181 * That means r4 < pc && r4 - 16k page directory > &_end. 181 * That means r4 < pc || r4 - 16k page directory > &_end.
182 * Given that r4 > &_end is most unfrequent, we add a rough 182 * Given that r4 > &_end is most unfrequent, we add a rough
183 * additional 1MB of room for a possible appended DTB. 183 * additional 1MB of room for a possible appended DTB.
184 */ 184 */
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index bcc9e63c8070..8e45ea44317e 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -81,6 +81,15 @@
81 reg = <0x10023CA0 0x20>; 81 reg = <0x10023CA0 0x20>;
82 }; 82 };
83 83
84 l2c: l2-cache-controller@10502000 {
85 compatible = "arm,pl310-cache";
86 reg = <0x10502000 0x1000>;
87 cache-unified;
88 cache-level = <2>;
89 arm,tag-latency = <2 2 1>;
90 arm,data-latency = <2 2 1>;
91 };
92
84 gic: interrupt-controller@10490000 { 93 gic: interrupt-controller@10490000 {
85 cpu-offset = <0x8000>; 94 cpu-offset = <0x8000>;
86 }; 95 };
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index 93b70402e943..8bc97c415c9a 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -54,6 +54,20 @@
54 reg = <0x10023CA0 0x20>; 54 reg = <0x10023CA0 0x20>;
55 }; 55 };
56 56
57 l2c: l2-cache-controller@10502000 {
58 compatible = "arm,pl310-cache";
59 reg = <0x10502000 0x1000>;
60 cache-unified;
61 cache-level = <2>;
62 arm,tag-latency = <2 2 1>;
63 arm,data-latency = <3 2 1>;
64 arm,double-linefill = <1>;
65 arm,double-linefill-incr = <0>;
66 arm,double-linefill-wrap = <1>;
67 arm,prefetch-drop = <1>;
68 arm,prefetch-offset = <7>;
69 };
70
57 clock: clock-controller@10030000 { 71 clock: clock-controller@10030000 {
58 compatible = "samsung,exynos4412-clock"; 72 compatible = "samsung,exynos4412-clock";
59 reg = <0x10030000 0x20000>; 73 reg = <0x10030000 0x20000>;
diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig
index 4f2ec3ac138e..c3058da631da 100644
--- a/arch/arm/configs/iop32x_defconfig
+++ b/arch/arm/configs/iop32x_defconfig
@@ -106,6 +106,7 @@ CONFIG_MAGIC_SYSRQ=y
106CONFIG_DEBUG_KERNEL=y 106CONFIG_DEBUG_KERNEL=y
107CONFIG_DEBUG_USER=y 107CONFIG_DEBUG_USER=y
108CONFIG_DEBUG_LL=y 108CONFIG_DEBUG_LL=y
109CONFIG_DEBUG_LL_UART_8250=y
109CONFIG_KEYS=y 110CONFIG_KEYS=y
110CONFIG_KEYS_DEBUG_PROC_KEYS=y 111CONFIG_KEYS_DEBUG_PROC_KEYS=y
111CONFIG_CRYPTO_NULL=y 112CONFIG_CRYPTO_NULL=y
diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig
index aa36128abca2..713faeee8cf4 100644
--- a/arch/arm/configs/iop33x_defconfig
+++ b/arch/arm/configs/iop33x_defconfig
@@ -87,5 +87,6 @@ CONFIG_DEBUG_KERNEL=y
87# CONFIG_RCU_CPU_STALL_DETECTOR is not set 87# CONFIG_RCU_CPU_STALL_DETECTOR is not set
88CONFIG_DEBUG_USER=y 88CONFIG_DEBUG_USER=y
89CONFIG_DEBUG_LL=y 89CONFIG_DEBUG_LL=y
90CONFIG_DEBUG_LL_UART_8250=y
90# CONFIG_CRYPTO_ANSI_CPRNG is not set 91# CONFIG_CRYPTO_ANSI_CPRNG is not set
91# CONFIG_CRC32 is not set 92# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index 1af665e847d1..24636cfdf6df 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -202,3 +202,4 @@ CONFIG_MAGIC_SYSRQ=y
202CONFIG_DEBUG_KERNEL=y 202CONFIG_DEBUG_KERNEL=y
203CONFIG_DEBUG_ERRORS=y 203CONFIG_DEBUG_ERRORS=y
204CONFIG_DEBUG_LL=y 204CONFIG_DEBUG_LL=y
205CONFIG_DEBUG_LL_UART_8250=y
diff --git a/arch/arm/configs/lpc32xx_defconfig b/arch/arm/configs/lpc32xx_defconfig
index 9f56ca3985ae..c100b7df5441 100644
--- a/arch/arm/configs/lpc32xx_defconfig
+++ b/arch/arm/configs/lpc32xx_defconfig
@@ -204,6 +204,7 @@ CONFIG_DEBUG_INFO=y
204# CONFIG_FTRACE is not set 204# CONFIG_FTRACE is not set
205# CONFIG_ARM_UNWIND is not set 205# CONFIG_ARM_UNWIND is not set
206CONFIG_DEBUG_LL=y 206CONFIG_DEBUG_LL=y
207CONFIG_DEBUG_LL_UART_8250=y
207CONFIG_EARLY_PRINTK=y 208CONFIG_EARLY_PRINTK=y
208CONFIG_CRYPTO_ANSI_CPRNG=y 209CONFIG_CRYPTO_ANSI_CPRNG=y
209# CONFIG_CRYPTO_HW is not set 210# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig
index 0dae1c1f007a..85d10d2e3d66 100644
--- a/arch/arm/configs/mv78xx0_defconfig
+++ b/arch/arm/configs/mv78xx0_defconfig
@@ -132,6 +132,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
132CONFIG_DEBUG_USER=y 132CONFIG_DEBUG_USER=y
133CONFIG_DEBUG_ERRORS=y 133CONFIG_DEBUG_ERRORS=y
134CONFIG_DEBUG_LL=y 134CONFIG_DEBUG_LL=y
135CONFIG_DEBUG_LL_UART_8250=y
135CONFIG_CRYPTO_CBC=m 136CONFIG_CRYPTO_CBC=m
136CONFIG_CRYPTO_ECB=m 137CONFIG_CRYPTO_ECB=m
137CONFIG_CRYPTO_PCBC=m 138CONFIG_CRYPTO_PCBC=m
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index 952430d9e2d9..855143fac6bd 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -156,6 +156,7 @@ CONFIG_LATENCYTOP=y
156# CONFIG_FTRACE is not set 156# CONFIG_FTRACE is not set
157CONFIG_DEBUG_USER=y 157CONFIG_DEBUG_USER=y
158CONFIG_DEBUG_LL=y 158CONFIG_DEBUG_LL=y
159CONFIG_DEBUG_LL_UART_8250=y
159CONFIG_CRYPTO_CBC=m 160CONFIG_CRYPTO_CBC=m
160CONFIG_CRYPTO_ECB=m 161CONFIG_CRYPTO_ECB=m
161CONFIG_CRYPTO_PCBC=m 162CONFIG_CRYPTO_PCBC=m
diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig
index 00515ef9782d..89631795a915 100644
--- a/arch/arm/configs/rpc_defconfig
+++ b/arch/arm/configs/rpc_defconfig
@@ -131,3 +131,4 @@ CONFIG_DEBUG_KERNEL=y
131CONFIG_DEBUG_USER=y 131CONFIG_DEBUG_USER=y
132CONFIG_DEBUG_ERRORS=y 132CONFIG_DEBUG_ERRORS=y
133CONFIG_DEBUG_LL=y 133CONFIG_DEBUG_LL=y
134CONFIG_DEBUG_LL_UART_8250=y
diff --git a/arch/arm/include/asm/bitrev.h b/arch/arm/include/asm/bitrev.h
new file mode 100644
index 000000000000..ec291c350ea3
--- /dev/null
+++ b/arch/arm/include/asm/bitrev.h
@@ -0,0 +1,20 @@
1#ifndef __ASM_BITREV_H
2#define __ASM_BITREV_H
3
4static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
5{
6 __asm__ ("rbit %0, %1" : "=r" (x) : "r" (x));
7 return x;
8}
9
10static __always_inline __attribute_const__ u16 __arch_bitrev16(u16 x)
11{
12 return __arch_bitrev32((u32)x) >> 16;
13}
14
15static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x)
16{
17 return __arch_bitrev32((u32)x) >> 24;
18}
19
20#endif
diff --git a/arch/arm/include/asm/compiler.h b/arch/arm/include/asm/compiler.h
index 8155db2f7fa1..29fe85e59439 100644
--- a/arch/arm/include/asm/compiler.h
+++ b/arch/arm/include/asm/compiler.h
@@ -8,8 +8,21 @@
8 * This string is meant to be concatenated with the inline asm string and 8 * This string is meant to be concatenated with the inline asm string and
9 * will cause compilation to stop on mismatch. 9 * will cause compilation to stop on mismatch.
10 * (for details, see gcc PR 15089) 10 * (for details, see gcc PR 15089)
11 * For compatibility with clang, we have to specifically take the equivalence
12 * of 'r11' <-> 'fp' and 'r12' <-> 'ip' into account as well.
11 */ 13 */
12#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t" 14#define __asmeq(x, y) \
15 ".ifnc " x "," y "; " \
16 ".ifnc " x y ",fpr11; " \
17 ".ifnc " x y ",r11fp; " \
18 ".ifnc " x y ",ipr12; " \
19 ".ifnc " x y ",r12ip; " \
20 ".err; " \
21 ".endif; " \
22 ".endif; " \
23 ".endif; " \
24 ".endif; " \
25 ".endif\n\t"
13 26
14 27
15#endif /* __ASM_ARM_COMPILER_H */ 28#endif /* __ASM_ARM_COMPILER_H */
diff --git a/arch/arm/kernel/insn.h b/arch/arm/include/asm/insn.h
index e96065da4dae..e96065da4dae 100644
--- a/arch/arm/kernel/insn.h
+++ b/arch/arm/include/asm/insn.h
diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h
index 49fa0dfaad33..3ea9be559726 100644
--- a/arch/arm/include/asm/kprobes.h
+++ b/arch/arm/include/asm/kprobes.h
@@ -22,7 +22,6 @@
22 22
23#define __ARCH_WANT_KPROBES_INSN_SLOT 23#define __ARCH_WANT_KPROBES_INSN_SLOT
24#define MAX_INSN_SIZE 2 24#define MAX_INSN_SIZE 2
25#define MAX_STACK_SIZE 64 /* 32 would probably be OK */
26 25
27#define flush_insn_slot(p) do { } while (0) 26#define flush_insn_slot(p) do { } while (0)
28#define kretprobe_blacklist_size 0 27#define kretprobe_blacklist_size 0
@@ -51,5 +50,37 @@ int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
51int kprobe_exceptions_notify(struct notifier_block *self, 50int kprobe_exceptions_notify(struct notifier_block *self,
52 unsigned long val, void *data); 51 unsigned long val, void *data);
53 52
53/* optinsn template addresses */
54extern __visible kprobe_opcode_t optprobe_template_entry;
55extern __visible kprobe_opcode_t optprobe_template_val;
56extern __visible kprobe_opcode_t optprobe_template_call;
57extern __visible kprobe_opcode_t optprobe_template_end;
58extern __visible kprobe_opcode_t optprobe_template_sub_sp;
59extern __visible kprobe_opcode_t optprobe_template_add_sp;
60extern __visible kprobe_opcode_t optprobe_template_restore_begin;
61extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn;
62extern __visible kprobe_opcode_t optprobe_template_restore_end;
63
64#define MAX_OPTIMIZED_LENGTH 4
65#define MAX_OPTINSN_SIZE \
66 ((unsigned long)&optprobe_template_end - \
67 (unsigned long)&optprobe_template_entry)
68#define RELATIVEJUMP_SIZE 4
69
70struct arch_optimized_insn {
71 /*
72 * copy of the original instructions.
73 * Different from x86, ARM kprobe_opcode_t is u32.
74 */
75#define MAX_COPIED_INSN DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t))
76 kprobe_opcode_t copied_insn[MAX_COPIED_INSN];
77 /* detour code buffer */
78 kprobe_opcode_t *insn;
79 /*
80 * We always copy one instruction on ARM,
81 * so size will always be 4, and unlike x86, there is no
82 * need for a size field.
83 */
84};
54 85
55#endif /* _ARM_KPROBES_H */ 86#endif /* _ARM_KPROBES_H */
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index 891a56b35bcf..563b92fc2f41 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -23,6 +23,8 @@
23 23
24#include <linux/types.h> 24#include <linux/types.h>
25 25
26struct l2x0_regs;
27
26struct outer_cache_fns { 28struct outer_cache_fns {
27 void (*inv_range)(unsigned long, unsigned long); 29 void (*inv_range)(unsigned long, unsigned long);
28 void (*clean_range)(unsigned long, unsigned long); 30 void (*clean_range)(unsigned long, unsigned long);
@@ -36,6 +38,7 @@ struct outer_cache_fns {
36 38
37 /* This is an ARM L2C thing */ 39 /* This is an ARM L2C thing */
38 void (*write_sec)(unsigned long, unsigned); 40 void (*write_sec)(unsigned long, unsigned);
41 void (*configure)(const struct l2x0_regs *);
39}; 42};
40 43
41extern struct outer_cache_fns outer_cache; 44extern struct outer_cache_fns outer_cache;
diff --git a/arch/arm/kernel/patch.h b/arch/arm/include/asm/patch.h
index 77e054c2f6cd..77e054c2f6cd 100644
--- a/arch/arm/kernel/patch.h
+++ b/arch/arm/include/asm/patch.h
diff --git a/arch/arm/include/asm/probes.h b/arch/arm/include/asm/probes.h
index 806cfe622a9e..1e5b9bb92270 100644
--- a/arch/arm/include/asm/probes.h
+++ b/arch/arm/include/asm/probes.h
@@ -19,6 +19,8 @@
19#ifndef _ASM_PROBES_H 19#ifndef _ASM_PROBES_H
20#define _ASM_PROBES_H 20#define _ASM_PROBES_H
21 21
22#ifndef __ASSEMBLY__
23
22typedef u32 probes_opcode_t; 24typedef u32 probes_opcode_t;
23 25
24struct arch_probes_insn; 26struct arch_probes_insn;
@@ -38,6 +40,19 @@ struct arch_probes_insn {
38 probes_check_cc *insn_check_cc; 40 probes_check_cc *insn_check_cc;
39 probes_insn_singlestep_t *insn_singlestep; 41 probes_insn_singlestep_t *insn_singlestep;
40 probes_insn_fn_t *insn_fn; 42 probes_insn_fn_t *insn_fn;
43 int stack_space;
44 unsigned long register_usage_flags;
45 bool kprobe_direct_exec;
41}; 46};
42 47
48#endif /* __ASSEMBLY__ */
49
50/*
51 * We assume one instruction can consume at most 64 bytes stack, which is
52 * 'push {r0-r15}'. Instructions consume more or unknown stack space like
53 * 'str r0, [sp, #-80]' and 'str r0, [sp, r1]' should be prohibit to probe.
54 * Both kprobe and jprobe use this macro.
55 */
56#define MAX_STACK_SIZE 64
57
43#endif 58#endif
diff --git a/arch/arm/mach-ks8695/include/mach/debug-macro.S b/arch/arm/include/debug/ks8695.S
index a79e48981202..961da1f32ab3 100644
--- a/arch/arm/mach-ks8695/include/mach/debug-macro.S
+++ b/arch/arm/include/debug/ks8695.S
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/mach-ks8695/include/mach/debug-macro.S 2 * arch/arm/include/debug/ks8695.S
3 * 3 *
4 * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk> 4 * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
5 * Copyright (C) 2006 Simtec Electronics 5 * Copyright (C) 2006 Simtec Electronics
@@ -11,8 +11,12 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14#include <mach/hardware.h> 14#define KS8695_UART_PA 0x03ffe000
15#include <mach/regs-uart.h> 15#define KS8695_UART_VA 0xf00fe000
16#define KS8695_URTH (0x04)
17#define KS8695_URLS (0x14)
18#define URLS_URTE (1 << 6)
19#define URLS_URTHRE (1 << 5)
16 20
17 .macro addruart, rp, rv, tmp 21 .macro addruart, rp, rv, tmp
18 ldr \rp, =KS8695_UART_PA @ physical base address 22 ldr \rp, =KS8695_UART_PA @ physical base address
diff --git a/arch/arm/mach-netx/include/mach/debug-macro.S b/arch/arm/include/debug/netx.S
index 247781e096e2..81e1b2af70f7 100644
--- a/arch/arm/mach-netx/include/mach/debug-macro.S
+++ b/arch/arm/include/debug/netx.S
@@ -1,5 +1,4 @@
1/* arch/arm/mach-netx/include/mach/debug-macro.S 1/*
2 *
3 * Debugging macro include header 2 * Debugging macro include header
4 * 3 *
5 * Copyright (C) 1994-1999 Russell King 4 * Copyright (C) 1994-1999 Russell King
@@ -11,26 +10,27 @@
11 * 10 *
12*/ 11*/
13 12
14#include "hardware.h" 13#define UART_DATA 0
14#define UART_FLAG 0x18
15#define UART_FLAG_BUSY (1 << 3)
15 16
16 .macro addruart, rp, rv, tmp 17 .macro addruart, rp, rv, tmp
17 mov \rp, #0x00000a00 18 ldr \rp, =CONFIG_DEBUG_UART_PHYS
18 orr \rv, \rp, #io_p2v(0x00100000) @ virtual 19 ldr \rv, =CONFIG_DEBUG_UART_VIRT
19 orr \rp, \rp, #0x00100000 @ physical
20 .endm 20 .endm
21 21
22 .macro senduart,rd,rx 22 .macro senduart,rd,rx
23 str \rd, [\rx, #0] 23 str \rd, [\rx, #UART_DATA]
24 .endm 24 .endm
25 25
26 .macro busyuart,rd,rx 26 .macro busyuart,rd,rx
271002: ldr \rd, [\rx, #0x18] 271002: ldr \rd, [\rx, #UART_FLAG]
28 tst \rd, #(1 << 3) 28 tst \rd, #UART_FLAG_BUSY
29 bne 1002b 29 bne 1002b
30 .endm 30 .endm
31 31
32 .macro waituart,rd,rx 32 .macro waituart,rd,rx
331001: ldr \rd, [\rx, #0x18] 331001: ldr \rd, [\rx, #UART_FLAG]
34 tst \rd, #(1 << 3) 34 tst \rd, #UART_FLAG_BUSY
35 bne 1001b 35 bne 1001b
36 .endm 36 .endm
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index fb2b71ebe3f2..902397dd1000 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -51,20 +51,8 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o
51obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o 51obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o
52obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o 52obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o
53obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 53obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
54obj-$(CONFIG_UPROBES) += probes.o probes-arm.o uprobes.o uprobes-arm.o 54# Main staffs in KPROBES are in arch/arm/probes/ .
55obj-$(CONFIG_KPROBES) += probes.o kprobes.o kprobes-common.o patch.o 55obj-$(CONFIG_KPROBES) += patch.o insn.o
56ifdef CONFIG_THUMB2_KERNEL
57obj-$(CONFIG_KPROBES) += kprobes-thumb.o probes-thumb.o
58else
59obj-$(CONFIG_KPROBES) += kprobes-arm.o probes-arm.o
60endif
61obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o
62test-kprobes-objs := kprobes-test.o
63ifdef CONFIG_THUMB2_KERNEL
64test-kprobes-objs += kprobes-test-thumb.o
65else
66test-kprobes-objs += kprobes-test-arm.o
67endif
68obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o 56obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
69obj-$(CONFIG_ARM_THUMBEE) += thumbee.o 57obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
70obj-$(CONFIG_KGDB) += kgdb.o patch.o 58obj-$(CONFIG_KGDB) += kgdb.o patch.o
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 2f5555d307b3..672b21942fff 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -31,6 +31,7 @@
31 31
32#include "entry-header.S" 32#include "entry-header.S"
33#include <asm/entry-macro-multi.S> 33#include <asm/entry-macro-multi.S>
34#include <asm/probes.h>
34 35
35/* 36/*
36 * Interrupt handling. 37 * Interrupt handling.
@@ -249,7 +250,7 @@ __und_svc:
249 @ If a kprobe is about to simulate a "stmdb sp..." instruction, 250 @ If a kprobe is about to simulate a "stmdb sp..." instruction,
250 @ it obviously needs free stack space which then will belong to 251 @ it obviously needs free stack space which then will belong to
251 @ the saved context. 252 @ the saved context.
252 svc_entry 64 253 svc_entry MAX_STACK_SIZE
253#else 254#else
254 svc_entry 255 svc_entry
255#endif 256#endif
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index b8c75e45a950..709ee1d6d4df 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -20,8 +20,7 @@
20#include <asm/cacheflush.h> 20#include <asm/cacheflush.h>
21#include <asm/opcodes.h> 21#include <asm/opcodes.h>
22#include <asm/ftrace.h> 22#include <asm/ftrace.h>
23 23#include <asm/insn.h>
24#include "insn.h"
25 24
26#ifdef CONFIG_THUMB2_KERNEL 25#ifdef CONFIG_THUMB2_KERNEL
27#define NOP 0xf85deb04 /* pop.w {lr} */ 26#define NOP 0xf85deb04 /* pop.w {lr} */
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 664eee8c4a26..01963273c07a 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -346,6 +346,12 @@ __turn_mmu_on_loc:
346 346
347#if defined(CONFIG_SMP) 347#if defined(CONFIG_SMP)
348 .text 348 .text
349ENTRY(secondary_startup_arm)
350 .arm
351 THUMB( adr r9, BSYM(1f) ) @ Kernel is entered in ARM.
352 THUMB( bx r9 ) @ If this is a Thumb-2 kernel,
353 THUMB( .thumb ) @ switch to Thumb now.
354 THUMB(1: )
349ENTRY(secondary_startup) 355ENTRY(secondary_startup)
350 /* 356 /*
351 * Common entry point for secondary CPUs. 357 * Common entry point for secondary CPUs.
@@ -385,6 +391,7 @@ ENTRY(secondary_startup)
385 THUMB( add r12, r10, #PROCINFO_INITFUNC ) 391 THUMB( add r12, r10, #PROCINFO_INITFUNC )
386 THUMB( ret r12 ) 392 THUMB( ret r12 )
387ENDPROC(secondary_startup) 393ENDPROC(secondary_startup)
394ENDPROC(secondary_startup_arm)
388 395
389 /* 396 /*
390 * r6 = &secondary_data 397 * r6 = &secondary_data
@@ -586,7 +593,7 @@ __fixup_pv_table:
586 add r5, r5, r3 @ adjust table end address 593 add r5, r5, r3 @ adjust table end address
587 add r6, r6, r3 @ adjust __pv_phys_pfn_offset address 594 add r6, r6, r3 @ adjust __pv_phys_pfn_offset address
588 add r7, r7, r3 @ adjust __pv_offset address 595 add r7, r7, r3 @ adjust __pv_offset address
589 mov r0, r8, lsr #12 @ convert to PFN 596 mov r0, r8, lsr #PAGE_SHIFT @ convert to PFN
590 str r0, [r6] @ save computed PHYS_OFFSET to __pv_phys_pfn_offset 597 str r0, [r6] @ save computed PHYS_OFFSET to __pv_phys_pfn_offset
591 strcc ip, [r7, #HIGH_OFFSET] @ save to __pv_offset high bits 598 strcc ip, [r7, #HIGH_OFFSET] @ save to __pv_offset high bits
592 mov r6, r3, lsr #24 @ constant for add/sub instructions 599 mov r6, r3, lsr #24 @ constant for add/sub instructions
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index ad857bada96c..350f188c92d2 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -109,7 +109,8 @@ void __init init_IRQ(void)
109 109
110 if (IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_CACHE_L2X0) && 110 if (IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_CACHE_L2X0) &&
111 (machine_desc->l2c_aux_mask || machine_desc->l2c_aux_val)) { 111 (machine_desc->l2c_aux_mask || machine_desc->l2c_aux_val)) {
112 outer_cache.write_sec = machine_desc->l2c_write_sec; 112 if (!outer_cache.write_sec)
113 outer_cache.write_sec = machine_desc->l2c_write_sec;
113 ret = l2x0_of_init(machine_desc->l2c_aux_val, 114 ret = l2x0_of_init(machine_desc->l2c_aux_val,
114 machine_desc->l2c_aux_mask); 115 machine_desc->l2c_aux_mask);
115 if (ret) 116 if (ret)
diff --git a/arch/arm/kernel/jump_label.c b/arch/arm/kernel/jump_label.c
index afeeb9ea6f43..e39cbf488cfe 100644
--- a/arch/arm/kernel/jump_label.c
+++ b/arch/arm/kernel/jump_label.c
@@ -1,8 +1,7 @@
1#include <linux/kernel.h> 1#include <linux/kernel.h>
2#include <linux/jump_label.h> 2#include <linux/jump_label.h>
3 3#include <asm/patch.h>
4#include "insn.h" 4#include <asm/insn.h>
5#include "patch.h"
6 5
7#ifdef HAVE_JUMP_LABEL 6#ifdef HAVE_JUMP_LABEL
8 7
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
index 07db2f8a1b45..a6ad93c9bce3 100644
--- a/arch/arm/kernel/kgdb.c
+++ b/arch/arm/kernel/kgdb.c
@@ -14,10 +14,9 @@
14#include <linux/kgdb.h> 14#include <linux/kgdb.h>
15#include <linux/uaccess.h> 15#include <linux/uaccess.h>
16 16
17#include <asm/patch.h>
17#include <asm/traps.h> 18#include <asm/traps.h>
18 19
19#include "patch.h"
20
21struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = 20struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
22{ 21{
23 { "r0", 4, offsetof(struct pt_regs, ARM_r0)}, 22 { "r0", 4, offsetof(struct pt_regs, ARM_r0)},
diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
index 5038960e3c55..69bda1a5707e 100644
--- a/arch/arm/kernel/patch.c
+++ b/arch/arm/kernel/patch.c
@@ -8,8 +8,7 @@
8#include <asm/fixmap.h> 8#include <asm/fixmap.h>
9#include <asm/smp_plat.h> 9#include <asm/smp_plat.h>
10#include <asm/opcodes.h> 10#include <asm/opcodes.h>
11 11#include <asm/patch.h>
12#include "patch.h"
13 12
14struct patch { 13struct patch {
15 void *addr; 14 void *addr;
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
index 2835d35234ca..9a2f882a0a2d 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -14,10 +14,6 @@ extern int __cpu_suspend(unsigned long, int (*)(unsigned long), u32 cpuid);
14extern void cpu_resume_mmu(void); 14extern void cpu_resume_mmu(void);
15 15
16#ifdef CONFIG_MMU 16#ifdef CONFIG_MMU
17/*
18 * Hide the first two arguments to __cpu_suspend - these are an implementation
19 * detail which platform code shouldn't have to know about.
20 */
21int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) 17int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
22{ 18{
23 struct mm_struct *mm = current->active_mm; 19 struct mm_struct *mm = current->active_mm;
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 0573faab96ad..d8a780799506 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -15,19 +15,8 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
15 io-readsb.o io-writesb.o io-readsl.o io-writesl.o \ 15 io-readsb.o io-writesb.o io-readsl.o io-writesl.o \
16 call_with_stack.o bswapsdi2.o 16 call_with_stack.o bswapsdi2.o
17 17
18mmu-y := clear_user.o copy_page.o getuser.o putuser.o 18mmu-y := clear_user.o copy_page.o getuser.o putuser.o \
19 19 copy_from_user.o copy_to_user.o
20# the code in uaccess.S is not preemption safe and
21# probably faster on ARMv3 only
22ifeq ($(CONFIG_PREEMPT),y)
23 mmu-y += copy_from_user.o copy_to_user.o
24else
25ifneq ($(CONFIG_CPU_32v3),y)
26 mmu-y += copy_from_user.o copy_to_user.o
27else
28 mmu-y += uaccess.o
29endif
30endif
31 20
32# using lib_ here won't override already available weak symbols 21# using lib_ here won't override already available weak symbols
33obj-$(CONFIG_UACCESS_WITH_MEMCPY) += uaccess_with_memcpy.o 22obj-$(CONFIG_UACCESS_WITH_MEMCPY) += uaccess_with_memcpy.o
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
deleted file mode 100644
index e50520904b76..000000000000
--- a/arch/arm/lib/uaccess.S
+++ /dev/null
@@ -1,564 +0,0 @@
1/*
2 * linux/arch/arm/lib/uaccess.S
3 *
4 * Copyright (C) 1995, 1996,1997,1998 Russell King
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 * Routines to block copy data to/from user memory
11 * These are highly optimised both for the 4k page size
12 * and for various alignments.
13 */
14#include <linux/linkage.h>
15#include <asm/assembler.h>
16#include <asm/errno.h>
17#include <asm/domain.h>
18
19 .text
20
21#define PAGE_SHIFT 12
22
23/* Prototype: int __copy_to_user(void *to, const char *from, size_t n)
24 * Purpose : copy a block to user memory from kernel memory
25 * Params : to - user memory
26 * : from - kernel memory
27 * : n - number of bytes to copy
28 * Returns : Number of bytes NOT copied.
29 */
30
31.Lc2u_dest_not_aligned:
32 rsb ip, ip, #4
33 cmp ip, #2
34 ldrb r3, [r1], #1
35USER( TUSER( strb) r3, [r0], #1) @ May fault
36 ldrgeb r3, [r1], #1
37USER( TUSER( strgeb) r3, [r0], #1) @ May fault
38 ldrgtb r3, [r1], #1
39USER( TUSER( strgtb) r3, [r0], #1) @ May fault
40 sub r2, r2, ip
41 b .Lc2u_dest_aligned
42
43ENTRY(__copy_to_user)
44 stmfd sp!, {r2, r4 - r7, lr}
45 cmp r2, #4
46 blt .Lc2u_not_enough
47 ands ip, r0, #3
48 bne .Lc2u_dest_not_aligned
49.Lc2u_dest_aligned:
50
51 ands ip, r1, #3
52 bne .Lc2u_src_not_aligned
53/*
54 * Seeing as there has to be at least 8 bytes to copy, we can
55 * copy one word, and force a user-mode page fault...
56 */
57
58.Lc2u_0fupi: subs r2, r2, #4
59 addmi ip, r2, #4
60 bmi .Lc2u_0nowords
61 ldr r3, [r1], #4
62USER( TUSER( str) r3, [r0], #4) @ May fault
63 mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
64 rsb ip, ip, #0
65 movs ip, ip, lsr #32 - PAGE_SHIFT
66 beq .Lc2u_0fupi
67/*
68 * ip = max no. of bytes to copy before needing another "strt" insn
69 */
70 cmp r2, ip
71 movlt ip, r2
72 sub r2, r2, ip
73 subs ip, ip, #32
74 blt .Lc2u_0rem8lp
75
76.Lc2u_0cpy8lp: ldmia r1!, {r3 - r6}
77 stmia r0!, {r3 - r6} @ Shouldnt fault
78 ldmia r1!, {r3 - r6}
79 subs ip, ip, #32
80 stmia r0!, {r3 - r6} @ Shouldnt fault
81 bpl .Lc2u_0cpy8lp
82
83.Lc2u_0rem8lp: cmn ip, #16
84 ldmgeia r1!, {r3 - r6}
85 stmgeia r0!, {r3 - r6} @ Shouldnt fault
86 tst ip, #8
87 ldmneia r1!, {r3 - r4}
88 stmneia r0!, {r3 - r4} @ Shouldnt fault
89 tst ip, #4
90 ldrne r3, [r1], #4
91 TUSER( strne) r3, [r0], #4 @ Shouldnt fault
92 ands ip, ip, #3
93 beq .Lc2u_0fupi
94.Lc2u_0nowords: teq ip, #0
95 beq .Lc2u_finished
96.Lc2u_nowords: cmp ip, #2
97 ldrb r3, [r1], #1
98USER( TUSER( strb) r3, [r0], #1) @ May fault
99 ldrgeb r3, [r1], #1
100USER( TUSER( strgeb) r3, [r0], #1) @ May fault
101 ldrgtb r3, [r1], #1
102USER( TUSER( strgtb) r3, [r0], #1) @ May fault
103 b .Lc2u_finished
104
105.Lc2u_not_enough:
106 movs ip, r2
107 bne .Lc2u_nowords
108.Lc2u_finished: mov r0, #0
109 ldmfd sp!, {r2, r4 - r7, pc}
110
111.Lc2u_src_not_aligned:
112 bic r1, r1, #3
113 ldr r7, [r1], #4
114 cmp ip, #2
115 bgt .Lc2u_3fupi
116 beq .Lc2u_2fupi
117.Lc2u_1fupi: subs r2, r2, #4
118 addmi ip, r2, #4
119 bmi .Lc2u_1nowords
120 mov r3, r7, lspull #8
121 ldr r7, [r1], #4
122 orr r3, r3, r7, lspush #24
123USER( TUSER( str) r3, [r0], #4) @ May fault
124 mov ip, r0, lsl #32 - PAGE_SHIFT
125 rsb ip, ip, #0
126 movs ip, ip, lsr #32 - PAGE_SHIFT
127 beq .Lc2u_1fupi
128 cmp r2, ip
129 movlt ip, r2
130 sub r2, r2, ip
131 subs ip, ip, #16
132 blt .Lc2u_1rem8lp
133
134.Lc2u_1cpy8lp: mov r3, r7, lspull #8
135 ldmia r1!, {r4 - r7}
136 subs ip, ip, #16
137 orr r3, r3, r4, lspush #24
138 mov r4, r4, lspull #8
139 orr r4, r4, r5, lspush #24
140 mov r5, r5, lspull #8
141 orr r5, r5, r6, lspush #24
142 mov r6, r6, lspull #8
143 orr r6, r6, r7, lspush #24
144 stmia r0!, {r3 - r6} @ Shouldnt fault
145 bpl .Lc2u_1cpy8lp
146
147.Lc2u_1rem8lp: tst ip, #8
148 movne r3, r7, lspull #8
149 ldmneia r1!, {r4, r7}
150 orrne r3, r3, r4, lspush #24
151 movne r4, r4, lspull #8
152 orrne r4, r4, r7, lspush #24
153 stmneia r0!, {r3 - r4} @ Shouldnt fault
154 tst ip, #4
155 movne r3, r7, lspull #8
156 ldrne r7, [r1], #4
157 orrne r3, r3, r7, lspush #24
158 TUSER( strne) r3, [r0], #4 @ Shouldnt fault
159 ands ip, ip, #3
160 beq .Lc2u_1fupi
161.Lc2u_1nowords: mov r3, r7, get_byte_1
162 teq ip, #0
163 beq .Lc2u_finished
164 cmp ip, #2
165USER( TUSER( strb) r3, [r0], #1) @ May fault
166 movge r3, r7, get_byte_2
167USER( TUSER( strgeb) r3, [r0], #1) @ May fault
168 movgt r3, r7, get_byte_3
169USER( TUSER( strgtb) r3, [r0], #1) @ May fault
170 b .Lc2u_finished
171
172.Lc2u_2fupi: subs r2, r2, #4
173 addmi ip, r2, #4
174 bmi .Lc2u_2nowords
175 mov r3, r7, lspull #16
176 ldr r7, [r1], #4
177 orr r3, r3, r7, lspush #16
178USER( TUSER( str) r3, [r0], #4) @ May fault
179 mov ip, r0, lsl #32 - PAGE_SHIFT
180 rsb ip, ip, #0
181 movs ip, ip, lsr #32 - PAGE_SHIFT
182 beq .Lc2u_2fupi
183 cmp r2, ip
184 movlt ip, r2
185 sub r2, r2, ip
186 subs ip, ip, #16
187 blt .Lc2u_2rem8lp
188
189.Lc2u_2cpy8lp: mov r3, r7, lspull #16
190 ldmia r1!, {r4 - r7}
191 subs ip, ip, #16
192 orr r3, r3, r4, lspush #16
193 mov r4, r4, lspull #16
194 orr r4, r4, r5, lspush #16
195 mov r5, r5, lspull #16
196 orr r5, r5, r6, lspush #16
197 mov r6, r6, lspull #16
198 orr r6, r6, r7, lspush #16
199 stmia r0!, {r3 - r6} @ Shouldnt fault
200 bpl .Lc2u_2cpy8lp
201
202.Lc2u_2rem8lp: tst ip, #8
203 movne r3, r7, lspull #16
204 ldmneia r1!, {r4, r7}
205 orrne r3, r3, r4, lspush #16
206 movne r4, r4, lspull #16
207 orrne r4, r4, r7, lspush #16
208 stmneia r0!, {r3 - r4} @ Shouldnt fault
209 tst ip, #4
210 movne r3, r7, lspull #16
211 ldrne r7, [r1], #4
212 orrne r3, r3, r7, lspush #16
213 TUSER( strne) r3, [r0], #4 @ Shouldnt fault
214 ands ip, ip, #3
215 beq .Lc2u_2fupi
216.Lc2u_2nowords: mov r3, r7, get_byte_2
217 teq ip, #0
218 beq .Lc2u_finished
219 cmp ip, #2
220USER( TUSER( strb) r3, [r0], #1) @ May fault
221 movge r3, r7, get_byte_3
222USER( TUSER( strgeb) r3, [r0], #1) @ May fault
223 ldrgtb r3, [r1], #0
224USER( TUSER( strgtb) r3, [r0], #1) @ May fault
225 b .Lc2u_finished
226
227.Lc2u_3fupi: subs r2, r2, #4
228 addmi ip, r2, #4
229 bmi .Lc2u_3nowords
230 mov r3, r7, lspull #24
231 ldr r7, [r1], #4
232 orr r3, r3, r7, lspush #8
233USER( TUSER( str) r3, [r0], #4) @ May fault
234 mov ip, r0, lsl #32 - PAGE_SHIFT
235 rsb ip, ip, #0
236 movs ip, ip, lsr #32 - PAGE_SHIFT
237 beq .Lc2u_3fupi
238 cmp r2, ip
239 movlt ip, r2
240 sub r2, r2, ip
241 subs ip, ip, #16
242 blt .Lc2u_3rem8lp
243
244.Lc2u_3cpy8lp: mov r3, r7, lspull #24
245 ldmia r1!, {r4 - r7}
246 subs ip, ip, #16
247 orr r3, r3, r4, lspush #8
248 mov r4, r4, lspull #24
249 orr r4, r4, r5, lspush #8
250 mov r5, r5, lspull #24
251 orr r5, r5, r6, lspush #8
252 mov r6, r6, lspull #24
253 orr r6, r6, r7, lspush #8
254 stmia r0!, {r3 - r6} @ Shouldnt fault
255 bpl .Lc2u_3cpy8lp
256
257.Lc2u_3rem8lp: tst ip, #8
258 movne r3, r7, lspull #24
259 ldmneia r1!, {r4, r7}
260 orrne r3, r3, r4, lspush #8
261 movne r4, r4, lspull #24
262 orrne r4, r4, r7, lspush #8
263 stmneia r0!, {r3 - r4} @ Shouldnt fault
264 tst ip, #4
265 movne r3, r7, lspull #24
266 ldrne r7, [r1], #4
267 orrne r3, r3, r7, lspush #8
268 TUSER( strne) r3, [r0], #4 @ Shouldnt fault
269 ands ip, ip, #3
270 beq .Lc2u_3fupi
271.Lc2u_3nowords: mov r3, r7, get_byte_3
272 teq ip, #0
273 beq .Lc2u_finished
274 cmp ip, #2
275USER( TUSER( strb) r3, [r0], #1) @ May fault
276 ldrgeb r3, [r1], #1
277USER( TUSER( strgeb) r3, [r0], #1) @ May fault
278 ldrgtb r3, [r1], #0
279USER( TUSER( strgtb) r3, [r0], #1) @ May fault
280 b .Lc2u_finished
281ENDPROC(__copy_to_user)
282
283 .pushsection .fixup,"ax"
284 .align 0
2859001: ldmfd sp!, {r0, r4 - r7, pc}
286 .popsection
287
288/* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n);
289 * Purpose : copy a block from user memory to kernel memory
290 * Params : to - kernel memory
291 * : from - user memory
292 * : n - number of bytes to copy
293 * Returns : Number of bytes NOT copied.
294 */
295.Lcfu_dest_not_aligned:
296 rsb ip, ip, #4
297 cmp ip, #2
298USER( TUSER( ldrb) r3, [r1], #1) @ May fault
299 strb r3, [r0], #1
300USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault
301 strgeb r3, [r0], #1
302USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault
303 strgtb r3, [r0], #1
304 sub r2, r2, ip
305 b .Lcfu_dest_aligned
306
307ENTRY(__copy_from_user)
308 stmfd sp!, {r0, r2, r4 - r7, lr}
309 cmp r2, #4
310 blt .Lcfu_not_enough
311 ands ip, r0, #3
312 bne .Lcfu_dest_not_aligned
313.Lcfu_dest_aligned:
314 ands ip, r1, #3
315 bne .Lcfu_src_not_aligned
316
317/*
318 * Seeing as there has to be at least 8 bytes to copy, we can
319 * copy one word, and force a user-mode page fault...
320 */
321
322.Lcfu_0fupi: subs r2, r2, #4
323 addmi ip, r2, #4
324 bmi .Lcfu_0nowords
325USER( TUSER( ldr) r3, [r1], #4)
326 str r3, [r0], #4
327 mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
328 rsb ip, ip, #0
329 movs ip, ip, lsr #32 - PAGE_SHIFT
330 beq .Lcfu_0fupi
331/*
332 * ip = max no. of bytes to copy before needing another "strt" insn
333 */
334 cmp r2, ip
335 movlt ip, r2
336 sub r2, r2, ip
337 subs ip, ip, #32
338 blt .Lcfu_0rem8lp
339
340.Lcfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldnt fault
341 stmia r0!, {r3 - r6}
342 ldmia r1!, {r3 - r6} @ Shouldnt fault
343 subs ip, ip, #32
344 stmia r0!, {r3 - r6}
345 bpl .Lcfu_0cpy8lp
346
347.Lcfu_0rem8lp: cmn ip, #16
348 ldmgeia r1!, {r3 - r6} @ Shouldnt fault
349 stmgeia r0!, {r3 - r6}
350 tst ip, #8
351 ldmneia r1!, {r3 - r4} @ Shouldnt fault
352 stmneia r0!, {r3 - r4}
353 tst ip, #4
354 TUSER( ldrne) r3, [r1], #4 @ Shouldnt fault
355 strne r3, [r0], #4
356 ands ip, ip, #3
357 beq .Lcfu_0fupi
358.Lcfu_0nowords: teq ip, #0
359 beq .Lcfu_finished
360.Lcfu_nowords: cmp ip, #2
361USER( TUSER( ldrb) r3, [r1], #1) @ May fault
362 strb r3, [r0], #1
363USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault
364 strgeb r3, [r0], #1
365USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault
366 strgtb r3, [r0], #1
367 b .Lcfu_finished
368
369.Lcfu_not_enough:
370 movs ip, r2
371 bne .Lcfu_nowords
372.Lcfu_finished: mov r0, #0
373 add sp, sp, #8
374 ldmfd sp!, {r4 - r7, pc}
375
376.Lcfu_src_not_aligned:
377 bic r1, r1, #3
378USER( TUSER( ldr) r7, [r1], #4) @ May fault
379 cmp ip, #2
380 bgt .Lcfu_3fupi
381 beq .Lcfu_2fupi
382.Lcfu_1fupi: subs r2, r2, #4
383 addmi ip, r2, #4
384 bmi .Lcfu_1nowords
385 mov r3, r7, lspull #8
386USER( TUSER( ldr) r7, [r1], #4) @ May fault
387 orr r3, r3, r7, lspush #24
388 str r3, [r0], #4
389 mov ip, r1, lsl #32 - PAGE_SHIFT
390 rsb ip, ip, #0
391 movs ip, ip, lsr #32 - PAGE_SHIFT
392 beq .Lcfu_1fupi
393 cmp r2, ip
394 movlt ip, r2
395 sub r2, r2, ip
396 subs ip, ip, #16
397 blt .Lcfu_1rem8lp
398
399.Lcfu_1cpy8lp: mov r3, r7, lspull #8
400 ldmia r1!, {r4 - r7} @ Shouldnt fault
401 subs ip, ip, #16
402 orr r3, r3, r4, lspush #24
403 mov r4, r4, lspull #8
404 orr r4, r4, r5, lspush #24
405 mov r5, r5, lspull #8
406 orr r5, r5, r6, lspush #24
407 mov r6, r6, lspull #8
408 orr r6, r6, r7, lspush #24
409 stmia r0!, {r3 - r6}
410 bpl .Lcfu_1cpy8lp
411
412.Lcfu_1rem8lp: tst ip, #8
413 movne r3, r7, lspull #8
414 ldmneia r1!, {r4, r7} @ Shouldnt fault
415 orrne r3, r3, r4, lspush #24
416 movne r4, r4, lspull #8
417 orrne r4, r4, r7, lspush #24
418 stmneia r0!, {r3 - r4}
419 tst ip, #4
420 movne r3, r7, lspull #8
421USER( TUSER( ldrne) r7, [r1], #4) @ May fault
422 orrne r3, r3, r7, lspush #24
423 strne r3, [r0], #4
424 ands ip, ip, #3
425 beq .Lcfu_1fupi
426.Lcfu_1nowords: mov r3, r7, get_byte_1
427 teq ip, #0
428 beq .Lcfu_finished
429 cmp ip, #2
430 strb r3, [r0], #1
431 movge r3, r7, get_byte_2
432 strgeb r3, [r0], #1
433 movgt r3, r7, get_byte_3
434 strgtb r3, [r0], #1
435 b .Lcfu_finished
436
437.Lcfu_2fupi: subs r2, r2, #4
438 addmi ip, r2, #4
439 bmi .Lcfu_2nowords
440 mov r3, r7, lspull #16
441USER( TUSER( ldr) r7, [r1], #4) @ May fault
442 orr r3, r3, r7, lspush #16
443 str r3, [r0], #4
444 mov ip, r1, lsl #32 - PAGE_SHIFT
445 rsb ip, ip, #0
446 movs ip, ip, lsr #32 - PAGE_SHIFT
447 beq .Lcfu_2fupi
448 cmp r2, ip
449 movlt ip, r2
450 sub r2, r2, ip
451 subs ip, ip, #16
452 blt .Lcfu_2rem8lp
453
454
455.Lcfu_2cpy8lp: mov r3, r7, lspull #16
456 ldmia r1!, {r4 - r7} @ Shouldnt fault
457 subs ip, ip, #16
458 orr r3, r3, r4, lspush #16
459 mov r4, r4, lspull #16
460 orr r4, r4, r5, lspush #16
461 mov r5, r5, lspull #16
462 orr r5, r5, r6, lspush #16
463 mov r6, r6, lspull #16
464 orr r6, r6, r7, lspush #16
465 stmia r0!, {r3 - r6}
466 bpl .Lcfu_2cpy8lp
467
468.Lcfu_2rem8lp: tst ip, #8
469 movne r3, r7, lspull #16
470 ldmneia r1!, {r4, r7} @ Shouldnt fault
471 orrne r3, r3, r4, lspush #16
472 movne r4, r4, lspull #16
473 orrne r4, r4, r7, lspush #16
474 stmneia r0!, {r3 - r4}
475 tst ip, #4
476 movne r3, r7, lspull #16
477USER( TUSER( ldrne) r7, [r1], #4) @ May fault
478 orrne r3, r3, r7, lspush #16
479 strne r3, [r0], #4
480 ands ip, ip, #3
481 beq .Lcfu_2fupi
482.Lcfu_2nowords: mov r3, r7, get_byte_2
483 teq ip, #0
484 beq .Lcfu_finished
485 cmp ip, #2
486 strb r3, [r0], #1
487 movge r3, r7, get_byte_3
488 strgeb r3, [r0], #1
489USER( TUSER( ldrgtb) r3, [r1], #0) @ May fault
490 strgtb r3, [r0], #1
491 b .Lcfu_finished
492
493.Lcfu_3fupi: subs r2, r2, #4
494 addmi ip, r2, #4
495 bmi .Lcfu_3nowords
496 mov r3, r7, lspull #24
497USER( TUSER( ldr) r7, [r1], #4) @ May fault
498 orr r3, r3, r7, lspush #8
499 str r3, [r0], #4
500 mov ip, r1, lsl #32 - PAGE_SHIFT
501 rsb ip, ip, #0
502 movs ip, ip, lsr #32 - PAGE_SHIFT
503 beq .Lcfu_3fupi
504 cmp r2, ip
505 movlt ip, r2
506 sub r2, r2, ip
507 subs ip, ip, #16
508 blt .Lcfu_3rem8lp
509
510.Lcfu_3cpy8lp: mov r3, r7, lspull #24
511 ldmia r1!, {r4 - r7} @ Shouldnt fault
512 orr r3, r3, r4, lspush #8
513 mov r4, r4, lspull #24
514 orr r4, r4, r5, lspush #8
515 mov r5, r5, lspull #24
516 orr r5, r5, r6, lspush #8
517 mov r6, r6, lspull #24
518 orr r6, r6, r7, lspush #8
519 stmia r0!, {r3 - r6}
520 subs ip, ip, #16
521 bpl .Lcfu_3cpy8lp
522
523.Lcfu_3rem8lp: tst ip, #8
524 movne r3, r7, lspull #24
525 ldmneia r1!, {r4, r7} @ Shouldnt fault
526 orrne r3, r3, r4, lspush #8
527 movne r4, r4, lspull #24
528 orrne r4, r4, r7, lspush #8
529 stmneia r0!, {r3 - r4}
530 tst ip, #4
531 movne r3, r7, lspull #24
532USER( TUSER( ldrne) r7, [r1], #4) @ May fault
533 orrne r3, r3, r7, lspush #8
534 strne r3, [r0], #4
535 ands ip, ip, #3
536 beq .Lcfu_3fupi
537.Lcfu_3nowords: mov r3, r7, get_byte_3
538 teq ip, #0
539 beq .Lcfu_finished
540 cmp ip, #2
541 strb r3, [r0], #1
542USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault
543 strgeb r3, [r0], #1
544USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault
545 strgtb r3, [r0], #1
546 b .Lcfu_finished
547ENDPROC(__copy_from_user)
548
549 .pushsection .fixup,"ax"
550 .align 0
551 /*
552 * We took an exception. r0 contains a pointer to
553 * the byte not copied.
554 */
5559001: ldr r2, [sp], #4 @ void *to
556 sub r2, r0, r2 @ bytes copied
557 ldr r1, [sp], #4 @ unsigned long count
558 subs r4, r1, r2 @ bytes left to copy
559 movne r1, r4
560 blne __memzero
561 mov r0, r4
562 ldmfd sp!, {r4 - r7, pc}
563 .popsection
564
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index 766f57d2f029..4791a3cc00f9 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -17,6 +17,7 @@
17#include <asm/cacheflush.h> 17#include <asm/cacheflush.h>
18#include <asm/cputype.h> 18#include <asm/cputype.h>
19#include <asm/firmware.h> 19#include <asm/firmware.h>
20#include <asm/hardware/cache-l2x0.h>
20#include <asm/suspend.h> 21#include <asm/suspend.h>
21 22
22#include <mach/map.h> 23#include <mach/map.h>
@@ -136,6 +137,43 @@ static const struct firmware_ops exynos_firmware_ops = {
136 .resume = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL, 137 .resume = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
137}; 138};
138 139
140static void exynos_l2_write_sec(unsigned long val, unsigned reg)
141{
142 static int l2cache_enabled;
143
144 switch (reg) {
145 case L2X0_CTRL:
146 if (val & L2X0_CTRL_EN) {
147 /*
148 * Before the cache can be enabled, due to firmware
149 * design, SMC_CMD_L2X0INVALL must be called.
150 */
151 if (!l2cache_enabled) {
152 exynos_smc(SMC_CMD_L2X0INVALL, 0, 0, 0);
153 l2cache_enabled = 1;
154 }
155 } else {
156 l2cache_enabled = 0;
157 }
158 exynos_smc(SMC_CMD_L2X0CTRL, val, 0, 0);
159 break;
160
161 case L2X0_DEBUG_CTRL:
162 exynos_smc(SMC_CMD_L2X0DEBUG, val, 0, 0);
163 break;
164
165 default:
166 WARN_ONCE(1, "%s: ignoring write to reg 0x%x\n", __func__, reg);
167 }
168}
169
170static void exynos_l2_configure(const struct l2x0_regs *regs)
171{
172 exynos_smc(SMC_CMD_L2X0SETUP1, regs->tag_latency, regs->data_latency,
173 regs->prefetch_ctrl);
174 exynos_smc(SMC_CMD_L2X0SETUP2, regs->pwr_ctrl, regs->aux_ctrl, 0);
175}
176
139void __init exynos_firmware_init(void) 177void __init exynos_firmware_init(void)
140{ 178{
141 struct device_node *nd; 179 struct device_node *nd;
@@ -155,4 +193,16 @@ void __init exynos_firmware_init(void)
155 pr_info("Running under secure firmware.\n"); 193 pr_info("Running under secure firmware.\n");
156 194
157 register_firmware_ops(&exynos_firmware_ops); 195 register_firmware_ops(&exynos_firmware_ops);
196
197 /*
198 * Exynos 4 SoCs (based on Cortex A9 and equipped with L2C-310),
199 * running under secure firmware, require certain registers of L2
200 * cache controller to be written in secure mode. Here .write_sec
201 * callback is provided to perform necessary SMC calls.
202 */
203 if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
204 read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
205 outer_cache.write_sec = exynos_l2_write_sec;
206 outer_cache.configure = exynos_l2_configure;
207 }
158} 208}
diff --git a/arch/arm/mach-exynos/sleep.S b/arch/arm/mach-exynos/sleep.S
index e3c373082bbe..31d25834b9c4 100644
--- a/arch/arm/mach-exynos/sleep.S
+++ b/arch/arm/mach-exynos/sleep.S
@@ -16,6 +16,8 @@
16 */ 16 */
17 17
18#include <linux/linkage.h> 18#include <linux/linkage.h>
19#include <asm/asm-offsets.h>
20#include <asm/hardware/cache-l2x0.h>
19#include "smc.h" 21#include "smc.h"
20 22
21#define CPU_MASK 0xff0ffff0 23#define CPU_MASK 0xff0ffff0
@@ -74,6 +76,45 @@ ENTRY(exynos_cpu_resume_ns)
74 mov r0, #SMC_CMD_C15RESUME 76 mov r0, #SMC_CMD_C15RESUME
75 dsb 77 dsb
76 smc #0 78 smc #0
79#ifdef CONFIG_CACHE_L2X0
80 adr r0, 1f
81 ldr r2, [r0]
82 add r0, r2, r0
83
84 /* Check that the address has been initialised. */
85 ldr r1, [r0, #L2X0_R_PHY_BASE]
86 teq r1, #0
87 beq skip_l2x0
88
89 /* Check if controller has been enabled. */
90 ldr r2, [r1, #L2X0_CTRL]
91 tst r2, #0x1
92 bne skip_l2x0
93
94 ldr r1, [r0, #L2X0_R_TAG_LATENCY]
95 ldr r2, [r0, #L2X0_R_DATA_LATENCY]
96 ldr r3, [r0, #L2X0_R_PREFETCH_CTRL]
97 mov r0, #SMC_CMD_L2X0SETUP1
98 smc #0
99
100 /* Reload saved regs pointer because smc corrupts registers. */
101 adr r0, 1f
102 ldr r2, [r0]
103 add r0, r2, r0
104
105 ldr r1, [r0, #L2X0_R_PWR_CTRL]
106 ldr r2, [r0, #L2X0_R_AUX_CTRL]
107 mov r0, #SMC_CMD_L2X0SETUP2
108 smc #0
109
110 mov r0, #SMC_CMD_L2X0INVALL
111 smc #0
112
113 mov r1, #1
114 mov r0, #SMC_CMD_L2X0CTRL
115 smc #0
116skip_l2x0:
117#endif /* CONFIG_CACHE_L2X0 */
77skip_cp15: 118skip_cp15:
78 b cpu_resume 119 b cpu_resume
79ENDPROC(exynos_cpu_resume_ns) 120ENDPROC(exynos_cpu_resume_ns)
@@ -83,3 +124,8 @@ cp15_save_diag:
83 .globl cp15_save_power 124 .globl cp15_save_power
84cp15_save_power: 125cp15_save_power:
85 .long 0 @ cp15 power control 126 .long 0 @ cp15 power control
127
128#ifdef CONFIG_CACHE_L2X0
129 .align
1301: .long l2x0_saved_regs - .
131#endif /* CONFIG_CACHE_L2X0 */
diff --git a/arch/arm/mach-omap1/include/mach/debug-macro.S b/arch/arm/mach-omap1/include/mach/debug-macro.S
deleted file mode 100644
index 5c1a26c9f490..000000000000
--- a/arch/arm/mach-omap1/include/mach/debug-macro.S
+++ /dev/null
@@ -1,101 +0,0 @@
1/* arch/arm/mach-omap1/include/mach/debug-macro.S
2 *
3 * Debugging macro include header
4 *
5 * Copyright (C) 1994-1999 Russell King
6 * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
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*/
13
14#include <linux/serial_reg.h>
15
16#include "serial.h"
17
18 .pushsection .data
19omap_uart_phys: .word 0x0
20omap_uart_virt: .word 0x0
21 .popsection
22
23 /*
24 * Note that this code won't work if the bootloader passes
25 * a wrong machine ID number in r1. To debug, just hardcode
26 * the desired UART phys and virt addresses temporarily into
27 * the omap_uart_phys and omap_uart_virt above.
28 */
29 .macro addruart, rp, rv, tmp
30
31 /* Use omap_uart_phys/virt if already configured */
329: adr \rp, 99f @ get effective addr of 99f
33 ldr \rv, [\rp] @ get absolute addr of 99f
34 sub \rv, \rv, \rp @ offset between the two
35 ldr \rp, [\rp, #4] @ abs addr of omap_uart_phys
36 sub \tmp, \rp, \rv @ make it effective
37 ldr \rp, [\tmp, #0] @ omap_uart_phys
38 ldr \rv, [\tmp, #4] @ omap_uart_virt
39 cmp \rp, #0 @ is port configured?
40 cmpne \rv, #0
41 bne 100f @ already configured
42
43 /* Check the debug UART configuration set in uncompress.h */
44 and \rp, pc, #0xff000000
45 ldr \rv, =OMAP_UART_INFO_OFS
46 ldr \rp, [\rp, \rv]
47
48 /* Select the UART to use based on the UART1 scratchpad value */
4910: cmp \rp, #0 @ no port configured?
50 beq 11f @ if none, try to use UART1
51 cmp \rp, #OMAP1UART1
52 beq 11f @ configure OMAP1UART1
53 cmp \rp, #OMAP1UART2
54 beq 12f @ configure OMAP1UART2
55 cmp \rp, #OMAP1UART3
56 beq 13f @ configure OMAP2UART3
57
58 /* Configure the UART offset from the phys/virt base */
5911: mov \rp, #0x00fb0000 @ OMAP1UART1
60 b 98f
6112: mov \rp, #0x00fb0000 @ OMAP1UART1
62 orr \rp, \rp, #0x00000800 @ OMAP1UART2
63 b 98f
6413: mov \rp, #0x00fb0000 @ OMAP1UART1
65 orr \rp, \rp, #0x00000800 @ OMAP1UART2
66 orr \rp, \rp, #0x00009000 @ OMAP1UART3
67
68 /* Store both phys and virt address for the uart */
6998: add \rp, \rp, #0xff000000 @ phys base
70 str \rp, [\tmp, #0] @ omap_uart_phys
71 sub \rp, \rp, #0xff000000 @ phys base
72 add \rp, \rp, #0xfe000000 @ virt base
73 str \rp, [\tmp, #4] @ omap_uart_virt
74 b 9b
75
76 .align
7799: .word .
78 .word omap_uart_phys
79 .ltorg
80
81100:
82 .endm
83
84 .macro senduart,rd,rx
85 strb \rd, [\rx]
86 .endm
87
88 .macro busyuart,rd,rx
891001: ldrb \rd, [\rx, #(UART_LSR << OMAP_PORT_SHIFT)]
90 and \rd, \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
91 teq \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
92 beq 1002f
93 ldrb \rd, [\rx, #(UART_LSR << OMAP7XX_PORT_SHIFT)]
94 and \rd, \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
95 teq \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
96 bne 1001b
971002:
98 .endm
99
100 .macro waituart,rd,rx
101 .endm
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index b61c049f92d6..42b7f4c9169b 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -189,6 +189,9 @@ static const char *const omap4_boards_compat[] __initconst = {
189}; 189};
190 190
191DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)") 191DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")
192 .l2c_aux_val = OMAP_L2C_AUX_CTRL,
193 .l2c_aux_mask = 0xcf9fffff,
194 .l2c_write_sec = omap4_l2c310_write_sec,
192 .reserve = omap_reserve, 195 .reserve = omap_reserve,
193 .smp = smp_ops(omap4_smp_ops), 196 .smp = smp_ops(omap4_smp_ops),
194 .map_io = omap4_map_io, 197 .map_io = omap4_map_io,
@@ -232,6 +235,9 @@ static const char *const am43_boards_compat[] __initconst = {
232}; 235};
233 236
234DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)") 237DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)")
238 .l2c_aux_val = OMAP_L2C_AUX_CTRL,
239 .l2c_aux_mask = 0xcf9fffff,
240 .l2c_write_sec = omap4_l2c310_write_sec,
235 .map_io = am33xx_map_io, 241 .map_io = am33xx_map_io,
236 .init_early = am43xx_init_early, 242 .init_early = am43xx_init_early,
237 .init_late = am43xx_init_late, 243 .init_late = am43xx_init_late,
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 64e44d6d07c0..3933b8aa4f01 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -35,6 +35,7 @@
35#include <linux/irqchip/irq-omap-intc.h> 35#include <linux/irqchip/irq-omap-intc.h>
36 36
37#include <asm/proc-fns.h> 37#include <asm/proc-fns.h>
38#include <asm/hardware/cache-l2x0.h>
38 39
39#include "i2c.h" 40#include "i2c.h"
40#include "serial.h" 41#include "serial.h"
@@ -94,11 +95,18 @@ extern void omap3_gptimer_timer_init(void);
94extern void omap4_local_timer_init(void); 95extern void omap4_local_timer_init(void);
95#ifdef CONFIG_CACHE_L2X0 96#ifdef CONFIG_CACHE_L2X0
96int omap_l2_cache_init(void); 97int omap_l2_cache_init(void);
98#define OMAP_L2C_AUX_CTRL (L2C_AUX_CTRL_SHARED_OVERRIDE | \
99 L310_AUX_CTRL_DATA_PREFETCH | \
100 L310_AUX_CTRL_INSTR_PREFETCH)
101void omap4_l2c310_write_sec(unsigned long val, unsigned reg);
97#else 102#else
98static inline int omap_l2_cache_init(void) 103static inline int omap_l2_cache_init(void)
99{ 104{
100 return 0; 105 return 0;
101} 106}
107
108#define OMAP_L2C_AUX_CTRL 0
109#define omap4_l2c310_write_sec NULL
102#endif 110#endif
103extern void omap5_realtime_timer_init(void); 111extern void omap5_realtime_timer_init(void);
104 112
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index cc30e49a4cc2..2418bdf28ca2 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -166,7 +166,7 @@ void __iomem *omap4_get_l2cache_base(void)
166 return l2cache_base; 166 return l2cache_base;
167} 167}
168 168
169static void omap4_l2c310_write_sec(unsigned long val, unsigned reg) 169void omap4_l2c310_write_sec(unsigned long val, unsigned reg)
170{ 170{
171 unsigned smc_op; 171 unsigned smc_op;
172 172
@@ -201,24 +201,10 @@ static void omap4_l2c310_write_sec(unsigned long val, unsigned reg)
201 201
202int __init omap_l2_cache_init(void) 202int __init omap_l2_cache_init(void)
203{ 203{
204 u32 aux_ctrl;
205
206 /* Static mapping, never released */ 204 /* Static mapping, never released */
207 l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K); 205 l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
208 if (WARN_ON(!l2cache_base)) 206 if (WARN_ON(!l2cache_base))
209 return -ENOMEM; 207 return -ENOMEM;
210
211 /* 16-way associativity, parity disabled, way size - 64KB (es2.0 +) */
212 aux_ctrl = L2C_AUX_CTRL_SHARED_OVERRIDE |
213 L310_AUX_CTRL_DATA_PREFETCH |
214 L310_AUX_CTRL_INSTR_PREFETCH;
215
216 outer_cache.write_sec = omap4_l2c310_write_sec;
217 if (of_have_populated_dt())
218 l2x0_of_init(aux_ctrl, 0xcf9fffff);
219 else
220 l2x0_init(l2cache_base, aux_ctrl, 0xcf9fffff);
221
222 return 0; 208 return 0;
223} 209}
224#endif 210#endif
diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
index d6908569ecaf..09cffed4c0a4 100644
--- a/arch/arm/mach-qcom/platsmp.c
+++ b/arch/arm/mach-qcom/platsmp.c
@@ -44,7 +44,7 @@
44#define APCS_SAW2_VCTL 0x14 44#define APCS_SAW2_VCTL 0x14
45#define APCS_SAW2_2_VCTL 0x1c 45#define APCS_SAW2_2_VCTL 0x1c
46 46
47extern void secondary_startup(void); 47extern void secondary_startup_arm(void);
48 48
49static DEFINE_SPINLOCK(boot_lock); 49static DEFINE_SPINLOCK(boot_lock);
50 50
@@ -337,7 +337,7 @@ static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
337 flags |= cold_boot_flags[map]; 337 flags |= cold_boot_flags[map];
338 } 338 }
339 339
340 if (scm_set_boot_addr(virt_to_phys(secondary_startup), flags)) { 340 if (scm_set_boot_addr(virt_to_phys(secondary_startup_arm), flags)) {
341 for_each_present_cpu(cpu) { 341 for_each_present_cpu(cpu) {
342 if (cpu == smp_processor_id()) 342 if (cpu == smp_processor_id())
343 continue; 343 continue;
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
index f1114d11fe13..61ff91e76e0a 100644
--- a/arch/arm/mach-sa1100/Makefile
+++ b/arch/arm/mach-sa1100/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := clock.o generic.o irq.o time.o #nmi-oopser.o 6obj-y := clock.o generic.o irq.o #nmi-oopser.o
7 7
8# Specific board support 8# Specific board support
9obj-$(CONFIG_SA1100_ASSABET) += assabet.o 9obj-$(CONFIG_SA1100_ASSABET) += assabet.o
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index 03c75a811cb0..cbf53bb9c814 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -119,6 +119,17 @@ static DEFINE_CLK(gpio27, &clk_gpio27_ops);
119 119
120static DEFINE_CLK(cpu, &clk_cpu_ops); 120static DEFINE_CLK(cpu, &clk_cpu_ops);
121 121
122static unsigned long clk_36864_get_rate(struct clk *clk)
123{
124 return 3686400;
125}
126
127static struct clkops clk_36864_ops = {
128 .get_rate = clk_36864_get_rate,
129};
130
131static DEFINE_CLK(36864, &clk_36864_ops);
132
122static struct clk_lookup sa11xx_clkregs[] = { 133static struct clk_lookup sa11xx_clkregs[] = {
123 CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27), 134 CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
124 CLKDEV_INIT("sa1100-rtc", NULL, NULL), 135 CLKDEV_INIT("sa1100-rtc", NULL, NULL),
@@ -126,6 +137,7 @@ static struct clk_lookup sa11xx_clkregs[] = {
126 CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu), 137 CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu),
127 /* sa1111 names devices using internal offsets, PCMCIA is at 0x1800 */ 138 /* sa1111 names devices using internal offsets, PCMCIA is at 0x1800 */
128 CLKDEV_INIT("1800", NULL, &clk_cpu), 139 CLKDEV_INIT("1800", NULL, &clk_cpu),
140 CLKDEV_INIT(NULL, "OSTIMER0", &clk_36864),
129}; 141};
130 142
131static int __init sa11xx_clk_init(void) 143static int __init sa11xx_clk_init(void)
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 7fcbe3d119c7..3cc2b71e16f0 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -371,8 +371,7 @@ static void __init collie_init(void)
371 PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS | 371 PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS |
372 PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM; 372 PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM;
373 373
374 PWER = _COLLIE_GPIO_AC_IN | _COLLIE_GPIO_CO | _COLLIE_GPIO_ON_KEY | 374 PWER = 0;
375 _COLLIE_GPIO_WAKEUP | _COLLIE_GPIO_nREMOCON_INT | PWER_RTC;
376 375
377 PGSR = _COLLIE_GPIO_nREMOCON_ON; 376 PGSR = _COLLIE_GPIO_nREMOCON_ON;
378 377
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index d4ea142c4edd..40e0d8619a2d 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -33,6 +33,7 @@
33#include <mach/irqs.h> 33#include <mach/irqs.h>
34 34
35#include "generic.h" 35#include "generic.h"
36#include <clocksource/pxa.h>
36 37
37unsigned int reset_status; 38unsigned int reset_status;
38EXPORT_SYMBOL(reset_status); 39EXPORT_SYMBOL(reset_status);
@@ -369,6 +370,11 @@ void __init sa1100_map_io(void)
369 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); 370 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
370} 371}
371 372
373void __init sa1100_timer_init(void)
374{
375 pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x90000000), 3686400);
376}
377
372/* 378/*
373 * Disable the memory bus request/grant signals on the SA1110 to 379 * Disable the memory bus request/grant signals on the SA1110 to
374 * ensure that we don't receive spurious memory requests. We set 380 * ensure that we don't receive spurious memory requests. We set
diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h
index de0983494c7e..734e30e406a3 100644
--- a/arch/arm/mach-sa1100/include/mach/irqs.h
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -8,17 +8,17 @@
8 * 2001/11/14 RMK Cleaned up and standardised a lot of the IRQs. 8 * 2001/11/14 RMK Cleaned up and standardised a lot of the IRQs.
9 */ 9 */
10 10
11#define IRQ_GPIO0 1 11#define IRQ_GPIO0_SC 1
12#define IRQ_GPIO1 2 12#define IRQ_GPIO1_SC 2
13#define IRQ_GPIO2 3 13#define IRQ_GPIO2_SC 3
14#define IRQ_GPIO3 4 14#define IRQ_GPIO3_SC 4
15#define IRQ_GPIO4 5 15#define IRQ_GPIO4_SC 5
16#define IRQ_GPIO5 6 16#define IRQ_GPIO5_SC 6
17#define IRQ_GPIO6 7 17#define IRQ_GPIO6_SC 7
18#define IRQ_GPIO7 8 18#define IRQ_GPIO7_SC 8
19#define IRQ_GPIO8 9 19#define IRQ_GPIO8_SC 9
20#define IRQ_GPIO9 10 20#define IRQ_GPIO9_SC 10
21#define IRQ_GPIO10 11 21#define IRQ_GPIO10_SC 11
22#define IRQ_GPIO11_27 12 22#define IRQ_GPIO11_27 12
23#define IRQ_LCD 13 /* LCD controller */ 23#define IRQ_LCD 13 /* LCD controller */
24#define IRQ_Ser0UDC 14 /* Ser. port 0 UDC */ 24#define IRQ_Ser0UDC 14 /* Ser. port 0 UDC */
@@ -41,32 +41,43 @@
41#define IRQ_RTC1Hz 31 /* RTC 1 Hz clock */ 41#define IRQ_RTC1Hz 31 /* RTC 1 Hz clock */
42#define IRQ_RTCAlrm 32 /* RTC Alarm */ 42#define IRQ_RTCAlrm 32 /* RTC Alarm */
43 43
44#define IRQ_GPIO11 33 44#define IRQ_GPIO0 33
45#define IRQ_GPIO12 34 45#define IRQ_GPIO1 34
46#define IRQ_GPIO13 35 46#define IRQ_GPIO2 35
47#define IRQ_GPIO14 36 47#define IRQ_GPIO3 36
48#define IRQ_GPIO15 37 48#define IRQ_GPIO4 37
49#define IRQ_GPIO16 38 49#define IRQ_GPIO5 38
50#define IRQ_GPIO17 39 50#define IRQ_GPIO6 39
51#define IRQ_GPIO18 40 51#define IRQ_GPIO7 40
52#define IRQ_GPIO19 41 52#define IRQ_GPIO8 41
53#define IRQ_GPIO20 42 53#define IRQ_GPIO9 42
54#define IRQ_GPIO21 43 54#define IRQ_GPIO10 43
55#define IRQ_GPIO22 44 55#define IRQ_GPIO11 44
56#define IRQ_GPIO23 45 56#define IRQ_GPIO12 45
57#define IRQ_GPIO24 46 57#define IRQ_GPIO13 46
58#define IRQ_GPIO25 47 58#define IRQ_GPIO14 47
59#define IRQ_GPIO26 48 59#define IRQ_GPIO15 48
60#define IRQ_GPIO27 49 60#define IRQ_GPIO16 49
61#define IRQ_GPIO17 50
62#define IRQ_GPIO18 51
63#define IRQ_GPIO19 52
64#define IRQ_GPIO20 53
65#define IRQ_GPIO21 54
66#define IRQ_GPIO22 55
67#define IRQ_GPIO23 56
68#define IRQ_GPIO24 57
69#define IRQ_GPIO25 58
70#define IRQ_GPIO26 59
71#define IRQ_GPIO27 60
61 72
62/* 73/*
63 * The next 16 interrupts are for board specific purposes. Since 74 * The next 16 interrupts are for board specific purposes. Since
64 * the kernel can only run on one machine at a time, we can re-use 75 * the kernel can only run on one machine at a time, we can re-use
65 * these. If you need more, increase IRQ_BOARD_END, but keep it 76 * these. If you need more, increase IRQ_BOARD_END, but keep it
66 * within sensible limits. IRQs 49 to 64 are available. 77 * within sensible limits. IRQs 61 to 76 are available.
67 */ 78 */
68#define IRQ_BOARD_START 50 79#define IRQ_BOARD_START 61
69#define IRQ_BOARD_END 66 80#define IRQ_BOARD_END 77
70 81
71/* 82/*
72 * Figure out the MAX IRQ number. 83 * Figure out the MAX IRQ number.
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 63e2901db416..65aebfa66fe5 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -80,170 +80,6 @@ static struct irq_domain_ops sa1100_normal_irqdomain_ops = {
80 80
81static struct irq_domain *sa1100_normal_irqdomain; 81static struct irq_domain *sa1100_normal_irqdomain;
82 82
83/*
84 * SA1100 GPIO edge detection for IRQs:
85 * IRQs are generated on Falling-Edge, Rising-Edge, or both.
86 * Use this instead of directly setting GRER/GFER.
87 */
88static int GPIO_IRQ_rising_edge;
89static int GPIO_IRQ_falling_edge;
90static int GPIO_IRQ_mask = (1 << 11) - 1;
91
92static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
93{
94 unsigned int mask;
95
96 mask = BIT(d->hwirq);
97
98 if (type == IRQ_TYPE_PROBE) {
99 if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
100 return 0;
101 type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
102 }
103
104 if (type & IRQ_TYPE_EDGE_RISING) {
105 GPIO_IRQ_rising_edge |= mask;
106 } else
107 GPIO_IRQ_rising_edge &= ~mask;
108 if (type & IRQ_TYPE_EDGE_FALLING) {
109 GPIO_IRQ_falling_edge |= mask;
110 } else
111 GPIO_IRQ_falling_edge &= ~mask;
112
113 GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
114 GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
115
116 return 0;
117}
118
119/*
120 * GPIO IRQs must be acknowledged.
121 */
122static void sa1100_gpio_ack(struct irq_data *d)
123{
124 GEDR = BIT(d->hwirq);
125}
126
127static int sa1100_gpio_wake(struct irq_data *d, unsigned int on)
128{
129 if (on)
130 PWER |= BIT(d->hwirq);
131 else
132 PWER &= ~BIT(d->hwirq);
133 return 0;
134}
135
136/*
137 * This is for IRQs from 0 to 10.
138 */
139static struct irq_chip sa1100_low_gpio_chip = {
140 .name = "GPIO-l",
141 .irq_ack = sa1100_gpio_ack,
142 .irq_mask = sa1100_mask_irq,
143 .irq_unmask = sa1100_unmask_irq,
144 .irq_set_type = sa1100_gpio_type,
145 .irq_set_wake = sa1100_gpio_wake,
146};
147
148static int sa1100_low_gpio_irqdomain_map(struct irq_domain *d,
149 unsigned int irq, irq_hw_number_t hwirq)
150{
151 irq_set_chip_and_handler(irq, &sa1100_low_gpio_chip,
152 handle_edge_irq);
153 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
154
155 return 0;
156}
157
158static struct irq_domain_ops sa1100_low_gpio_irqdomain_ops = {
159 .map = sa1100_low_gpio_irqdomain_map,
160 .xlate = irq_domain_xlate_onetwocell,
161};
162
163static struct irq_domain *sa1100_low_gpio_irqdomain;
164
165/*
166 * IRQ11 (GPIO11 through 27) handler. We enter here with the
167 * irq_controller_lock held, and IRQs disabled. Decode the IRQ
168 * and call the handler.
169 */
170static void
171sa1100_high_gpio_handler(unsigned int irq, struct irq_desc *desc)
172{
173 unsigned int mask;
174
175 mask = GEDR & 0xfffff800;
176 do {
177 /*
178 * clear down all currently active IRQ sources.
179 * We will be processing them all.
180 */
181 GEDR = mask;
182
183 irq = IRQ_GPIO11;
184 mask >>= 11;
185 do {
186 if (mask & 1)
187 generic_handle_irq(irq);
188 mask >>= 1;
189 irq++;
190 } while (mask);
191
192 mask = GEDR & 0xfffff800;
193 } while (mask);
194}
195
196/*
197 * Like GPIO0 to 10, GPIO11-27 IRQs need to be handled specially.
198 * In addition, the IRQs are all collected up into one bit in the
199 * interrupt controller registers.
200 */
201static void sa1100_high_gpio_mask(struct irq_data *d)
202{
203 unsigned int mask = BIT(d->hwirq);
204
205 GPIO_IRQ_mask &= ~mask;
206
207 GRER &= ~mask;
208 GFER &= ~mask;
209}
210
211static void sa1100_high_gpio_unmask(struct irq_data *d)
212{
213 unsigned int mask = BIT(d->hwirq);
214
215 GPIO_IRQ_mask |= mask;
216
217 GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
218 GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
219}
220
221static struct irq_chip sa1100_high_gpio_chip = {
222 .name = "GPIO-h",
223 .irq_ack = sa1100_gpio_ack,
224 .irq_mask = sa1100_high_gpio_mask,
225 .irq_unmask = sa1100_high_gpio_unmask,
226 .irq_set_type = sa1100_gpio_type,
227 .irq_set_wake = sa1100_gpio_wake,
228};
229
230static int sa1100_high_gpio_irqdomain_map(struct irq_domain *d,
231 unsigned int irq, irq_hw_number_t hwirq)
232{
233 irq_set_chip_and_handler(irq, &sa1100_high_gpio_chip,
234 handle_edge_irq);
235 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
236
237 return 0;
238}
239
240static struct irq_domain_ops sa1100_high_gpio_irqdomain_ops = {
241 .map = sa1100_high_gpio_irqdomain_map,
242 .xlate = irq_domain_xlate_onetwocell,
243};
244
245static struct irq_domain *sa1100_high_gpio_irqdomain;
246
247static struct resource irq_resource = 83static struct resource irq_resource =
248 DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs"); 84 DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs");
249 85
@@ -270,17 +106,6 @@ static int sa1100irq_suspend(void)
270 IC_GPIO6|IC_GPIO5|IC_GPIO4|IC_GPIO3|IC_GPIO2| 106 IC_GPIO6|IC_GPIO5|IC_GPIO4|IC_GPIO3|IC_GPIO2|
271 IC_GPIO1|IC_GPIO0); 107 IC_GPIO1|IC_GPIO0);
272 108
273 /*
274 * Set the appropriate edges for wakeup.
275 */
276 GRER = PWER & GPIO_IRQ_rising_edge;
277 GFER = PWER & GPIO_IRQ_falling_edge;
278
279 /*
280 * Clear any pending GPIO interrupts.
281 */
282 GEDR = GEDR;
283
284 return 0; 109 return 0;
285} 110}
286 111
@@ -292,9 +117,6 @@ static void sa1100irq_resume(void)
292 ICCR = st->iccr; 117 ICCR = st->iccr;
293 ICLR = st->iclr; 118 ICLR = st->iclr;
294 119
295 GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
296 GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
297
298 ICMR = st->icmr; 120 ICMR = st->icmr;
299 } 121 }
300} 122}
@@ -325,7 +147,8 @@ sa1100_handle_irq(struct pt_regs *regs)
325 if (mask == 0) 147 if (mask == 0)
326 break; 148 break;
327 149
328 handle_IRQ(ffs(mask) - 1 + IRQ_GPIO0, regs); 150 handle_domain_irq(sa1100_normal_irqdomain,
151 ffs(mask) - 1, regs);
329 } while (1); 152 } while (1);
330} 153}
331 154
@@ -339,34 +162,16 @@ void __init sa1100_init_irq(void)
339 /* all IRQs are IRQ, not FIQ */ 162 /* all IRQs are IRQ, not FIQ */
340 ICLR = 0; 163 ICLR = 0;
341 164
342 /* clear all GPIO edge detects */
343 GFER = 0;
344 GRER = 0;
345 GEDR = -1;
346
347 /* 165 /*
348 * Whatever the doc says, this has to be set for the wait-on-irq 166 * Whatever the doc says, this has to be set for the wait-on-irq
349 * instruction to work... on a SA1100 rev 9 at least. 167 * instruction to work... on a SA1100 rev 9 at least.
350 */ 168 */
351 ICCR = 1; 169 ICCR = 1;
352 170
353 sa1100_low_gpio_irqdomain = irq_domain_add_legacy(NULL, 171 sa1100_normal_irqdomain = irq_domain_add_simple(NULL,
354 11, IRQ_GPIO0, 0, 172 32, IRQ_GPIO0_SC,
355 &sa1100_low_gpio_irqdomain_ops, NULL);
356
357 sa1100_normal_irqdomain = irq_domain_add_legacy(NULL,
358 21, IRQ_GPIO11_27, 11,
359 &sa1100_normal_irqdomain_ops, NULL); 173 &sa1100_normal_irqdomain_ops, NULL);
360 174
361 sa1100_high_gpio_irqdomain = irq_domain_add_legacy(NULL,
362 17, IRQ_GPIO11, 11,
363 &sa1100_high_gpio_irqdomain_ops, NULL);
364
365 /*
366 * Install handler for GPIO 11-27 edge detect interrupts
367 */
368 irq_set_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler);
369
370 set_handle_irq(sa1100_handle_irq); 175 set_handle_irq(sa1100_handle_irq);
371 176
372 sa1100_init_gpio(); 177 sa1100_init_gpio();
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index 6645d1e31f14..34853d5dfda2 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -81,6 +81,7 @@ static int sa11x0_pm_enter(suspend_state_t state)
81 /* 81 /*
82 * Ensure not to come back here if it wasn't intended 82 * Ensure not to come back here if it wasn't intended
83 */ 83 */
84 RCSR = RCSR_SMR;
84 PSPR = 0; 85 PSPR = 0;
85 86
86 /* 87 /*
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
deleted file mode 100644
index 1dea6cfafb31..000000000000
--- a/arch/arm/mach-sa1100/time.c
+++ /dev/null
@@ -1,139 +0,0 @@
1/*
2 * linux/arch/arm/mach-sa1100/time.c
3 *
4 * Copyright (C) 1998 Deborah Wallach.
5 * Twiddles (C) 1999 Hugo Fiennes <hugo@empeg.com>
6 *
7 * 2000/03/29 (C) Nicolas Pitre <nico@fluxnic.net>
8 * Rewritten: big cleanup, much simpler, better HZ accuracy.
9 *
10 */
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/errno.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/timex.h>
17#include <linux/clockchips.h>
18#include <linux/sched_clock.h>
19
20#include <asm/mach/time.h>
21#include <mach/hardware.h>
22#include <mach/irqs.h>
23
24#define SA1100_CLOCK_FREQ 3686400
25#define SA1100_LATCH DIV_ROUND_CLOSEST(SA1100_CLOCK_FREQ, HZ)
26
27static u64 notrace sa1100_read_sched_clock(void)
28{
29 return readl_relaxed(OSCR);
30}
31
32#define MIN_OSCR_DELTA 2
33
34static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id)
35{
36 struct clock_event_device *c = dev_id;
37
38 /* Disarm the compare/match, signal the event. */
39 writel_relaxed(readl_relaxed(OIER) & ~OIER_E0, OIER);
40 writel_relaxed(OSSR_M0, OSSR);
41 c->event_handler(c);
42
43 return IRQ_HANDLED;
44}
45
46static int
47sa1100_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c)
48{
49 unsigned long next, oscr;
50
51 writel_relaxed(readl_relaxed(OIER) | OIER_E0, OIER);
52 next = readl_relaxed(OSCR) + delta;
53 writel_relaxed(next, OSMR0);
54 oscr = readl_relaxed(OSCR);
55
56 return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
57}
58
59static void
60sa1100_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *c)
61{
62 switch (mode) {
63 case CLOCK_EVT_MODE_ONESHOT:
64 case CLOCK_EVT_MODE_UNUSED:
65 case CLOCK_EVT_MODE_SHUTDOWN:
66 writel_relaxed(readl_relaxed(OIER) & ~OIER_E0, OIER);
67 writel_relaxed(OSSR_M0, OSSR);
68 break;
69
70 case CLOCK_EVT_MODE_RESUME:
71 case CLOCK_EVT_MODE_PERIODIC:
72 break;
73 }
74}
75
76#ifdef CONFIG_PM
77unsigned long osmr[4], oier;
78
79static void sa1100_timer_suspend(struct clock_event_device *cedev)
80{
81 osmr[0] = readl_relaxed(OSMR0);
82 osmr[1] = readl_relaxed(OSMR1);
83 osmr[2] = readl_relaxed(OSMR2);
84 osmr[3] = readl_relaxed(OSMR3);
85 oier = readl_relaxed(OIER);
86}
87
88static void sa1100_timer_resume(struct clock_event_device *cedev)
89{
90 writel_relaxed(0x0f, OSSR);
91 writel_relaxed(osmr[0], OSMR0);
92 writel_relaxed(osmr[1], OSMR1);
93 writel_relaxed(osmr[2], OSMR2);
94 writel_relaxed(osmr[3], OSMR3);
95 writel_relaxed(oier, OIER);
96
97 /*
98 * OSMR0 is the system timer: make sure OSCR is sufficiently behind
99 */
100 writel_relaxed(OSMR0 - SA1100_LATCH, OSCR);
101}
102#else
103#define sa1100_timer_suspend NULL
104#define sa1100_timer_resume NULL
105#endif
106
107static struct clock_event_device ckevt_sa1100_osmr0 = {
108 .name = "osmr0",
109 .features = CLOCK_EVT_FEAT_ONESHOT,
110 .rating = 200,
111 .set_next_event = sa1100_osmr0_set_next_event,
112 .set_mode = sa1100_osmr0_set_mode,
113 .suspend = sa1100_timer_suspend,
114 .resume = sa1100_timer_resume,
115};
116
117static struct irqaction sa1100_timer_irq = {
118 .name = "ost0",
119 .flags = IRQF_TIMER | IRQF_IRQPOLL,
120 .handler = sa1100_ost0_interrupt,
121 .dev_id = &ckevt_sa1100_osmr0,
122};
123
124void __init sa1100_timer_init(void)
125{
126 writel_relaxed(0, OIER);
127 writel_relaxed(OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3, OSSR);
128
129 sched_clock_register(sa1100_read_sched_clock, 32, 3686400);
130
131 ckevt_sa1100_osmr0.cpumask = cpumask_of(0);
132
133 setup_irq(IRQ_OST0, &sa1100_timer_irq);
134
135 clocksource_mmio_init(OSCR, "oscr", SA1100_CLOCK_FREQ, 200, 32,
136 clocksource_mmio_readl_up);
137 clockevents_config_and_register(&ckevt_sa1100_osmr0, 3686400,
138 MIN_OSCR_DELTA * 2, 0x7fffffff);
139}
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index c7fc009ad21c..c6c7696b8db9 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -41,12 +41,14 @@ struct l2c_init_data {
41 void (*enable)(void __iomem *, u32, unsigned); 41 void (*enable)(void __iomem *, u32, unsigned);
42 void (*fixup)(void __iomem *, u32, struct outer_cache_fns *); 42 void (*fixup)(void __iomem *, u32, struct outer_cache_fns *);
43 void (*save)(void __iomem *); 43 void (*save)(void __iomem *);
44 void (*configure)(void __iomem *);
44 struct outer_cache_fns outer_cache; 45 struct outer_cache_fns outer_cache;
45}; 46};
46 47
47#define CACHE_LINE_SIZE 32 48#define CACHE_LINE_SIZE 32
48 49
49static void __iomem *l2x0_base; 50static void __iomem *l2x0_base;
51static const struct l2c_init_data *l2x0_data;
50static DEFINE_RAW_SPINLOCK(l2x0_lock); 52static DEFINE_RAW_SPINLOCK(l2x0_lock);
51static u32 l2x0_way_mask; /* Bitmask of active ways */ 53static u32 l2x0_way_mask; /* Bitmask of active ways */
52static u32 l2x0_size; 54static u32 l2x0_size;
@@ -106,6 +108,19 @@ static inline void l2c_unlock(void __iomem *base, unsigned num)
106 } 108 }
107} 109}
108 110
111static void l2c_configure(void __iomem *base)
112{
113 if (outer_cache.configure) {
114 outer_cache.configure(&l2x0_saved_regs);
115 return;
116 }
117
118 if (l2x0_data->configure)
119 l2x0_data->configure(base);
120
121 l2c_write_sec(l2x0_saved_regs.aux_ctrl, base, L2X0_AUX_CTRL);
122}
123
109/* 124/*
110 * Enable the L2 cache controller. This function must only be 125 * Enable the L2 cache controller. This function must only be
111 * called when the cache controller is known to be disabled. 126 * called when the cache controller is known to be disabled.
@@ -114,7 +129,12 @@ static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
114{ 129{
115 unsigned long flags; 130 unsigned long flags;
116 131
117 l2c_write_sec(aux, base, L2X0_AUX_CTRL); 132 /* Do not touch the controller if already enabled. */
133 if (readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)
134 return;
135
136 l2x0_saved_regs.aux_ctrl = aux;
137 l2c_configure(base);
118 138
119 l2c_unlock(base, num_lock); 139 l2c_unlock(base, num_lock);
120 140
@@ -136,76 +156,14 @@ static void l2c_disable(void)
136 dsb(st); 156 dsb(st);
137} 157}
138 158
139#ifdef CONFIG_CACHE_PL310 159static void l2c_save(void __iomem *base)
140static inline void cache_wait(void __iomem *reg, unsigned long mask)
141{
142 /* cache operations by line are atomic on PL310 */
143}
144#else
145#define cache_wait l2c_wait_mask
146#endif
147
148static inline void cache_sync(void)
149{
150 void __iomem *base = l2x0_base;
151
152 writel_relaxed(0, base + sync_reg_offset);
153 cache_wait(base + L2X0_CACHE_SYNC, 1);
154}
155
156#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
157static inline void debug_writel(unsigned long val)
158{
159 l2c_set_debug(l2x0_base, val);
160}
161#else
162/* Optimised out for non-errata case */
163static inline void debug_writel(unsigned long val)
164{
165}
166#endif
167
168static void l2x0_cache_sync(void)
169{
170 unsigned long flags;
171
172 raw_spin_lock_irqsave(&l2x0_lock, flags);
173 cache_sync();
174 raw_spin_unlock_irqrestore(&l2x0_lock, flags);
175}
176
177static void __l2x0_flush_all(void)
178{
179 debug_writel(0x03);
180 __l2c_op_way(l2x0_base + L2X0_CLEAN_INV_WAY);
181 cache_sync();
182 debug_writel(0x00);
183}
184
185static void l2x0_flush_all(void)
186{
187 unsigned long flags;
188
189 /* clean all ways */
190 raw_spin_lock_irqsave(&l2x0_lock, flags);
191 __l2x0_flush_all();
192 raw_spin_unlock_irqrestore(&l2x0_lock, flags);
193}
194
195static void l2x0_disable(void)
196{ 160{
197 unsigned long flags; 161 l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
198
199 raw_spin_lock_irqsave(&l2x0_lock, flags);
200 __l2x0_flush_all();
201 l2c_write_sec(0, l2x0_base, L2X0_CTRL);
202 dsb(st);
203 raw_spin_unlock_irqrestore(&l2x0_lock, flags);
204} 162}
205 163
206static void l2c_save(void __iomem *base) 164static void l2c_resume(void)
207{ 165{
208 l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); 166 l2c_enable(l2x0_base, l2x0_saved_regs.aux_ctrl, l2x0_data->num_lock);
209} 167}
210 168
211/* 169/*
@@ -288,14 +246,6 @@ static void l2c210_sync(void)
288 __l2c210_cache_sync(l2x0_base); 246 __l2c210_cache_sync(l2x0_base);
289} 247}
290 248
291static void l2c210_resume(void)
292{
293 void __iomem *base = l2x0_base;
294
295 if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN))
296 l2c_enable(base, l2x0_saved_regs.aux_ctrl, 1);
297}
298
299static const struct l2c_init_data l2c210_data __initconst = { 249static const struct l2c_init_data l2c210_data __initconst = {
300 .type = "L2C-210", 250 .type = "L2C-210",
301 .way_size_0 = SZ_8K, 251 .way_size_0 = SZ_8K,
@@ -309,7 +259,7 @@ static const struct l2c_init_data l2c210_data __initconst = {
309 .flush_all = l2c210_flush_all, 259 .flush_all = l2c210_flush_all,
310 .disable = l2c_disable, 260 .disable = l2c_disable,
311 .sync = l2c210_sync, 261 .sync = l2c210_sync,
312 .resume = l2c210_resume, 262 .resume = l2c_resume,
313 }, 263 },
314}; 264};
315 265
@@ -466,7 +416,7 @@ static const struct l2c_init_data l2c220_data = {
466 .flush_all = l2c220_flush_all, 416 .flush_all = l2c220_flush_all,
467 .disable = l2c_disable, 417 .disable = l2c_disable,
468 .sync = l2c220_sync, 418 .sync = l2c220_sync,
469 .resume = l2c210_resume, 419 .resume = l2c_resume,
470 }, 420 },
471}; 421};
472 422
@@ -615,39 +565,29 @@ static void __init l2c310_save(void __iomem *base)
615 L310_POWER_CTRL); 565 L310_POWER_CTRL);
616} 566}
617 567
618static void l2c310_resume(void) 568static void l2c310_configure(void __iomem *base)
619{ 569{
620 void __iomem *base = l2x0_base; 570 unsigned revision;
621 571
622 if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)) { 572 /* restore pl310 setup */
623 unsigned revision; 573 l2c_write_sec(l2x0_saved_regs.tag_latency, base,
624 574 L310_TAG_LATENCY_CTRL);
625 /* restore pl310 setup */ 575 l2c_write_sec(l2x0_saved_regs.data_latency, base,
626 writel_relaxed(l2x0_saved_regs.tag_latency, 576 L310_DATA_LATENCY_CTRL);
627 base + L310_TAG_LATENCY_CTRL); 577 l2c_write_sec(l2x0_saved_regs.filter_end, base,
628 writel_relaxed(l2x0_saved_regs.data_latency, 578 L310_ADDR_FILTER_END);
629 base + L310_DATA_LATENCY_CTRL); 579 l2c_write_sec(l2x0_saved_regs.filter_start, base,
630 writel_relaxed(l2x0_saved_regs.filter_end, 580 L310_ADDR_FILTER_START);
631 base + L310_ADDR_FILTER_END); 581
632 writel_relaxed(l2x0_saved_regs.filter_start, 582 revision = readl_relaxed(base + L2X0_CACHE_ID) &
633 base + L310_ADDR_FILTER_START); 583 L2X0_CACHE_ID_RTL_MASK;
634 584
635 revision = readl_relaxed(base + L2X0_CACHE_ID) & 585 if (revision >= L310_CACHE_ID_RTL_R2P0)
636 L2X0_CACHE_ID_RTL_MASK; 586 l2c_write_sec(l2x0_saved_regs.prefetch_ctrl, base,
637 587 L310_PREFETCH_CTRL);
638 if (revision >= L310_CACHE_ID_RTL_R2P0) 588 if (revision >= L310_CACHE_ID_RTL_R3P0)
639 l2c_write_sec(l2x0_saved_regs.prefetch_ctrl, base, 589 l2c_write_sec(l2x0_saved_regs.pwr_ctrl, base,
640 L310_PREFETCH_CTRL); 590 L310_POWER_CTRL);
641 if (revision >= L310_CACHE_ID_RTL_R3P0)
642 l2c_write_sec(l2x0_saved_regs.pwr_ctrl, base,
643 L310_POWER_CTRL);
644
645 l2c_enable(base, l2x0_saved_regs.aux_ctrl, 8);
646
647 /* Re-enable full-line-of-zeros for Cortex-A9 */
648 if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_FULL_LINE_ZERO)
649 set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
650 }
651} 591}
652 592
653static int l2c310_cpu_enable_flz(struct notifier_block *nb, unsigned long act, void *data) 593static int l2c310_cpu_enable_flz(struct notifier_block *nb, unsigned long act, void *data)
@@ -699,6 +639,23 @@ static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
699 aux &= ~(L310_AUX_CTRL_FULL_LINE_ZERO | L310_AUX_CTRL_EARLY_BRESP); 639 aux &= ~(L310_AUX_CTRL_FULL_LINE_ZERO | L310_AUX_CTRL_EARLY_BRESP);
700 } 640 }
701 641
642 /* r3p0 or later has power control register */
643 if (rev >= L310_CACHE_ID_RTL_R3P0)
644 l2x0_saved_regs.pwr_ctrl = L310_DYNAMIC_CLK_GATING_EN |
645 L310_STNDBY_MODE_EN;
646
647 /*
648 * Always enable non-secure access to the lockdown registers -
649 * we write to them as part of the L2C enable sequence so they
650 * need to be accessible.
651 */
652 aux |= L310_AUX_CTRL_NS_LOCKDOWN;
653
654 l2c_enable(base, aux, num_lock);
655
656 /* Read back resulting AUX_CTRL value as it could have been altered. */
657 aux = readl_relaxed(base + L2X0_AUX_CTRL);
658
702 if (aux & (L310_AUX_CTRL_DATA_PREFETCH | L310_AUX_CTRL_INSTR_PREFETCH)) { 659 if (aux & (L310_AUX_CTRL_DATA_PREFETCH | L310_AUX_CTRL_INSTR_PREFETCH)) {
703 u32 prefetch = readl_relaxed(base + L310_PREFETCH_CTRL); 660 u32 prefetch = readl_relaxed(base + L310_PREFETCH_CTRL);
704 661
@@ -712,23 +669,12 @@ static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
712 if (rev >= L310_CACHE_ID_RTL_R3P0) { 669 if (rev >= L310_CACHE_ID_RTL_R3P0) {
713 u32 power_ctrl; 670 u32 power_ctrl;
714 671
715 l2c_write_sec(L310_DYNAMIC_CLK_GATING_EN | L310_STNDBY_MODE_EN,
716 base, L310_POWER_CTRL);
717 power_ctrl = readl_relaxed(base + L310_POWER_CTRL); 672 power_ctrl = readl_relaxed(base + L310_POWER_CTRL);
718 pr_info("L2C-310 dynamic clock gating %sabled, standby mode %sabled\n", 673 pr_info("L2C-310 dynamic clock gating %sabled, standby mode %sabled\n",
719 power_ctrl & L310_DYNAMIC_CLK_GATING_EN ? "en" : "dis", 674 power_ctrl & L310_DYNAMIC_CLK_GATING_EN ? "en" : "dis",
720 power_ctrl & L310_STNDBY_MODE_EN ? "en" : "dis"); 675 power_ctrl & L310_STNDBY_MODE_EN ? "en" : "dis");
721 } 676 }
722 677
723 /*
724 * Always enable non-secure access to the lockdown registers -
725 * we write to them as part of the L2C enable sequence so they
726 * need to be accessible.
727 */
728 aux |= L310_AUX_CTRL_NS_LOCKDOWN;
729
730 l2c_enable(base, aux, num_lock);
731
732 if (aux & L310_AUX_CTRL_FULL_LINE_ZERO) { 678 if (aux & L310_AUX_CTRL_FULL_LINE_ZERO) {
733 set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1)); 679 set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
734 cpu_notifier(l2c310_cpu_enable_flz, 0); 680 cpu_notifier(l2c310_cpu_enable_flz, 0);
@@ -760,11 +706,11 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
760 706
761 if (revision >= L310_CACHE_ID_RTL_R3P0 && 707 if (revision >= L310_CACHE_ID_RTL_R3P0 &&
762 revision < L310_CACHE_ID_RTL_R3P2) { 708 revision < L310_CACHE_ID_RTL_R3P2) {
763 u32 val = readl_relaxed(base + L310_PREFETCH_CTRL); 709 u32 val = l2x0_saved_regs.prefetch_ctrl;
764 /* I don't think bit23 is required here... but iMX6 does so */ 710 /* I don't think bit23 is required here... but iMX6 does so */
765 if (val & (BIT(30) | BIT(23))) { 711 if (val & (BIT(30) | BIT(23))) {
766 val &= ~(BIT(30) | BIT(23)); 712 val &= ~(BIT(30) | BIT(23));
767 l2c_write_sec(val, base, L310_PREFETCH_CTRL); 713 l2x0_saved_regs.prefetch_ctrl = val;
768 errata[n++] = "752271"; 714 errata[n++] = "752271";
769 } 715 }
770 } 716 }
@@ -800,6 +746,15 @@ static void l2c310_disable(void)
800 l2c_disable(); 746 l2c_disable();
801} 747}
802 748
749static void l2c310_resume(void)
750{
751 l2c_resume();
752
753 /* Re-enable full-line-of-zeros for Cortex-A9 */
754 if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_FULL_LINE_ZERO)
755 set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
756}
757
803static const struct l2c_init_data l2c310_init_fns __initconst = { 758static const struct l2c_init_data l2c310_init_fns __initconst = {
804 .type = "L2C-310", 759 .type = "L2C-310",
805 .way_size_0 = SZ_8K, 760 .way_size_0 = SZ_8K,
@@ -807,6 +762,7 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
807 .enable = l2c310_enable, 762 .enable = l2c310_enable,
808 .fixup = l2c310_fixup, 763 .fixup = l2c310_fixup,
809 .save = l2c310_save, 764 .save = l2c310_save,
765 .configure = l2c310_configure,
810 .outer_cache = { 766 .outer_cache = {
811 .inv_range = l2c210_inv_range, 767 .inv_range = l2c210_inv_range,
812 .clean_range = l2c210_clean_range, 768 .clean_range = l2c210_clean_range,
@@ -818,14 +774,22 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
818 }, 774 },
819}; 775};
820 776
821static void __init __l2c_init(const struct l2c_init_data *data, 777static int __init __l2c_init(const struct l2c_init_data *data,
822 u32 aux_val, u32 aux_mask, u32 cache_id) 778 u32 aux_val, u32 aux_mask, u32 cache_id)
823{ 779{
824 struct outer_cache_fns fns; 780 struct outer_cache_fns fns;
825 unsigned way_size_bits, ways; 781 unsigned way_size_bits, ways;
826 u32 aux, old_aux; 782 u32 aux, old_aux;
827 783
828 /* 784 /*
785 * Save the pointer globally so that callbacks which do not receive
786 * context from callers can access the structure.
787 */
788 l2x0_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
789 if (!l2x0_data)
790 return -ENOMEM;
791
792 /*
829 * Sanity check the aux values. aux_mask is the bits we preserve 793 * Sanity check the aux values. aux_mask is the bits we preserve
830 * from reading the hardware register, and aux_val is the bits we 794 * from reading the hardware register, and aux_val is the bits we
831 * set. 795 * set.
@@ -884,6 +848,7 @@ static void __init __l2c_init(const struct l2c_init_data *data,
884 848
885 fns = data->outer_cache; 849 fns = data->outer_cache;
886 fns.write_sec = outer_cache.write_sec; 850 fns.write_sec = outer_cache.write_sec;
851 fns.configure = outer_cache.configure;
887 if (data->fixup) 852 if (data->fixup)
888 data->fixup(l2x0_base, cache_id, &fns); 853 data->fixup(l2x0_base, cache_id, &fns);
889 854
@@ -910,6 +875,8 @@ static void __init __l2c_init(const struct l2c_init_data *data,
910 data->type, ways, l2x0_size >> 10); 875 data->type, ways, l2x0_size >> 10);
911 pr_info("%s: CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n", 876 pr_info("%s: CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
912 data->type, cache_id, aux); 877 data->type, cache_id, aux);
878
879 return 0;
913} 880}
914 881
915void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) 882void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
@@ -936,6 +903,10 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
936 break; 903 break;
937 } 904 }
938 905
906 /* Read back current (default) hardware configuration */
907 if (data->save)
908 data->save(l2x0_base);
909
939 __l2c_init(data, aux_val, aux_mask, cache_id); 910 __l2c_init(data, aux_val, aux_mask, cache_id);
940} 911}
941 912
@@ -1102,7 +1073,7 @@ static const struct l2c_init_data of_l2c210_data __initconst = {
1102 .flush_all = l2c210_flush_all, 1073 .flush_all = l2c210_flush_all,
1103 .disable = l2c_disable, 1074 .disable = l2c_disable,
1104 .sync = l2c210_sync, 1075 .sync = l2c210_sync,
1105 .resume = l2c210_resume, 1076 .resume = l2c_resume,
1106 }, 1077 },
1107}; 1078};
1108 1079
@@ -1120,7 +1091,7 @@ static const struct l2c_init_data of_l2c220_data __initconst = {
1120 .flush_all = l2c220_flush_all, 1091 .flush_all = l2c220_flush_all,
1121 .disable = l2c_disable, 1092 .disable = l2c_disable,
1122 .sync = l2c220_sync, 1093 .sync = l2c220_sync,
1123 .resume = l2c210_resume, 1094 .resume = l2c_resume,
1124 }, 1095 },
1125}; 1096};
1126 1097
@@ -1131,32 +1102,32 @@ static void __init l2c310_of_parse(const struct device_node *np,
1131 u32 tag[3] = { 0, 0, 0 }; 1102 u32 tag[3] = { 0, 0, 0 };
1132 u32 filter[2] = { 0, 0 }; 1103 u32 filter[2] = { 0, 0 };
1133 u32 assoc; 1104 u32 assoc;
1105 u32 prefetch;
1106 u32 val;
1134 int ret; 1107 int ret;
1135 1108
1136 of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag)); 1109 of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
1137 if (tag[0] && tag[1] && tag[2]) 1110 if (tag[0] && tag[1] && tag[2])
1138 writel_relaxed( 1111 l2x0_saved_regs.tag_latency =
1139 L310_LATENCY_CTRL_RD(tag[0] - 1) | 1112 L310_LATENCY_CTRL_RD(tag[0] - 1) |
1140 L310_LATENCY_CTRL_WR(tag[1] - 1) | 1113 L310_LATENCY_CTRL_WR(tag[1] - 1) |
1141 L310_LATENCY_CTRL_SETUP(tag[2] - 1), 1114 L310_LATENCY_CTRL_SETUP(tag[2] - 1);
1142 l2x0_base + L310_TAG_LATENCY_CTRL);
1143 1115
1144 of_property_read_u32_array(np, "arm,data-latency", 1116 of_property_read_u32_array(np, "arm,data-latency",
1145 data, ARRAY_SIZE(data)); 1117 data, ARRAY_SIZE(data));
1146 if (data[0] && data[1] && data[2]) 1118 if (data[0] && data[1] && data[2])
1147 writel_relaxed( 1119 l2x0_saved_regs.data_latency =
1148 L310_LATENCY_CTRL_RD(data[0] - 1) | 1120 L310_LATENCY_CTRL_RD(data[0] - 1) |
1149 L310_LATENCY_CTRL_WR(data[1] - 1) | 1121 L310_LATENCY_CTRL_WR(data[1] - 1) |
1150 L310_LATENCY_CTRL_SETUP(data[2] - 1), 1122 L310_LATENCY_CTRL_SETUP(data[2] - 1);
1151 l2x0_base + L310_DATA_LATENCY_CTRL);
1152 1123
1153 of_property_read_u32_array(np, "arm,filter-ranges", 1124 of_property_read_u32_array(np, "arm,filter-ranges",
1154 filter, ARRAY_SIZE(filter)); 1125 filter, ARRAY_SIZE(filter));
1155 if (filter[1]) { 1126 if (filter[1]) {
1156 writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M), 1127 l2x0_saved_regs.filter_end =
1157 l2x0_base + L310_ADDR_FILTER_END); 1128 ALIGN(filter[0] + filter[1], SZ_1M);
1158 writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L310_ADDR_FILTER_EN, 1129 l2x0_saved_regs.filter_start = (filter[0] & ~(SZ_1M - 1))
1159 l2x0_base + L310_ADDR_FILTER_START); 1130 | L310_ADDR_FILTER_EN;
1160 } 1131 }
1161 1132
1162 ret = l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_512K); 1133 ret = l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_512K);
@@ -1178,6 +1149,58 @@ static void __init l2c310_of_parse(const struct device_node *np,
1178 assoc); 1149 assoc);
1179 break; 1150 break;
1180 } 1151 }
1152
1153 prefetch = l2x0_saved_regs.prefetch_ctrl;
1154
1155 ret = of_property_read_u32(np, "arm,double-linefill", &val);
1156 if (ret == 0) {
1157 if (val)
1158 prefetch |= L310_PREFETCH_CTRL_DBL_LINEFILL;
1159 else
1160 prefetch &= ~L310_PREFETCH_CTRL_DBL_LINEFILL;
1161 } else if (ret != -EINVAL) {
1162 pr_err("L2C-310 OF arm,double-linefill property value is missing\n");
1163 }
1164
1165 ret = of_property_read_u32(np, "arm,double-linefill-incr", &val);
1166 if (ret == 0) {
1167 if (val)
1168 prefetch |= L310_PREFETCH_CTRL_DBL_LINEFILL_INCR;
1169 else
1170 prefetch &= ~L310_PREFETCH_CTRL_DBL_LINEFILL_INCR;
1171 } else if (ret != -EINVAL) {
1172 pr_err("L2C-310 OF arm,double-linefill-incr property value is missing\n");
1173 }
1174
1175 ret = of_property_read_u32(np, "arm,double-linefill-wrap", &val);
1176 if (ret == 0) {
1177 if (!val)
1178 prefetch |= L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP;
1179 else
1180 prefetch &= ~L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP;
1181 } else if (ret != -EINVAL) {
1182 pr_err("L2C-310 OF arm,double-linefill-wrap property value is missing\n");
1183 }
1184
1185 ret = of_property_read_u32(np, "arm,prefetch-drop", &val);
1186 if (ret == 0) {
1187 if (val)
1188 prefetch |= L310_PREFETCH_CTRL_PREFETCH_DROP;
1189 else
1190 prefetch &= ~L310_PREFETCH_CTRL_PREFETCH_DROP;
1191 } else if (ret != -EINVAL) {
1192 pr_err("L2C-310 OF arm,prefetch-drop property value is missing\n");
1193 }
1194
1195 ret = of_property_read_u32(np, "arm,prefetch-offset", &val);
1196 if (ret == 0) {
1197 prefetch &= ~L310_PREFETCH_CTRL_OFFSET_MASK;
1198 prefetch |= val & L310_PREFETCH_CTRL_OFFSET_MASK;
1199 } else if (ret != -EINVAL) {
1200 pr_err("L2C-310 OF arm,prefetch-offset property value is missing\n");
1201 }
1202
1203 l2x0_saved_regs.prefetch_ctrl = prefetch;
1181} 1204}
1182 1205
1183static const struct l2c_init_data of_l2c310_data __initconst = { 1206static const struct l2c_init_data of_l2c310_data __initconst = {
@@ -1188,6 +1211,7 @@ static const struct l2c_init_data of_l2c310_data __initconst = {
1188 .enable = l2c310_enable, 1211 .enable = l2c310_enable,
1189 .fixup = l2c310_fixup, 1212 .fixup = l2c310_fixup,
1190 .save = l2c310_save, 1213 .save = l2c310_save,
1214 .configure = l2c310_configure,
1191 .outer_cache = { 1215 .outer_cache = {
1192 .inv_range = l2c210_inv_range, 1216 .inv_range = l2c210_inv_range,
1193 .clean_range = l2c210_clean_range, 1217 .clean_range = l2c210_clean_range,
@@ -1216,6 +1240,7 @@ static const struct l2c_init_data of_l2c310_coherent_data __initconst = {
1216 .enable = l2c310_enable, 1240 .enable = l2c310_enable,
1217 .fixup = l2c310_fixup, 1241 .fixup = l2c310_fixup,
1218 .save = l2c310_save, 1242 .save = l2c310_save,
1243 .configure = l2c310_configure,
1219 .outer_cache = { 1244 .outer_cache = {
1220 .inv_range = l2c210_inv_range, 1245 .inv_range = l2c210_inv_range,
1221 .clean_range = l2c210_clean_range, 1246 .clean_range = l2c210_clean_range,
@@ -1231,7 +1256,7 @@ static const struct l2c_init_data of_l2c310_coherent_data __initconst = {
1231 * noninclusive, while the hardware cache range operations use 1256 * noninclusive, while the hardware cache range operations use
1232 * inclusive start and end addresses. 1257 * inclusive start and end addresses.
1233 */ 1258 */
1234static unsigned long calc_range_end(unsigned long start, unsigned long end) 1259static unsigned long aurora_range_end(unsigned long start, unsigned long end)
1235{ 1260{
1236 /* 1261 /*
1237 * Limit the number of cache lines processed at once, 1262 * Limit the number of cache lines processed at once,
@@ -1250,25 +1275,13 @@ static unsigned long calc_range_end(unsigned long start, unsigned long end)
1250 return end; 1275 return end;
1251} 1276}
1252 1277
1253/*
1254 * Make sure 'start' and 'end' reference the same page, as L2 is PIPT
1255 * and range operations only do a TLB lookup on the start address.
1256 */
1257static void aurora_pa_range(unsigned long start, unsigned long end, 1278static void aurora_pa_range(unsigned long start, unsigned long end,
1258 unsigned long offset) 1279 unsigned long offset)
1259{ 1280{
1281 void __iomem *base = l2x0_base;
1282 unsigned long range_end;
1260 unsigned long flags; 1283 unsigned long flags;
1261 1284
1262 raw_spin_lock_irqsave(&l2x0_lock, flags);
1263 writel_relaxed(start, l2x0_base + AURORA_RANGE_BASE_ADDR_REG);
1264 writel_relaxed(end, l2x0_base + offset);
1265 raw_spin_unlock_irqrestore(&l2x0_lock, flags);
1266
1267 cache_sync();
1268}
1269
1270static void aurora_inv_range(unsigned long start, unsigned long end)
1271{
1272 /* 1285 /*
1273 * round start and end adresses up to cache line size 1286 * round start and end adresses up to cache line size
1274 */ 1287 */
@@ -1276,15 +1289,24 @@ static void aurora_inv_range(unsigned long start, unsigned long end)
1276 end = ALIGN(end, CACHE_LINE_SIZE); 1289 end = ALIGN(end, CACHE_LINE_SIZE);
1277 1290
1278 /* 1291 /*
1279 * Invalidate all full cache lines between 'start' and 'end'. 1292 * perform operation on all full cache lines between 'start' and 'end'
1280 */ 1293 */
1281 while (start < end) { 1294 while (start < end) {
1282 unsigned long range_end = calc_range_end(start, end); 1295 range_end = aurora_range_end(start, end);
1283 aurora_pa_range(start, range_end - CACHE_LINE_SIZE, 1296
1284 AURORA_INVAL_RANGE_REG); 1297 raw_spin_lock_irqsave(&l2x0_lock, flags);
1298 writel_relaxed(start, base + AURORA_RANGE_BASE_ADDR_REG);
1299 writel_relaxed(range_end - CACHE_LINE_SIZE, base + offset);
1300 raw_spin_unlock_irqrestore(&l2x0_lock, flags);
1301
1302 writel_relaxed(0, base + AURORA_SYNC_REG);
1285 start = range_end; 1303 start = range_end;
1286 } 1304 }
1287} 1305}
1306static void aurora_inv_range(unsigned long start, unsigned long end)
1307{
1308 aurora_pa_range(start, end, AURORA_INVAL_RANGE_REG);
1309}
1288 1310
1289static void aurora_clean_range(unsigned long start, unsigned long end) 1311static void aurora_clean_range(unsigned long start, unsigned long end)
1290{ 1312{
@@ -1292,52 +1314,53 @@ static void aurora_clean_range(unsigned long start, unsigned long end)
1292 * If L2 is forced to WT, the L2 will always be clean and we 1314 * If L2 is forced to WT, the L2 will always be clean and we
1293 * don't need to do anything here. 1315 * don't need to do anything here.
1294 */ 1316 */
1295 if (!l2_wt_override) { 1317 if (!l2_wt_override)
1296 start &= ~(CACHE_LINE_SIZE - 1); 1318 aurora_pa_range(start, end, AURORA_CLEAN_RANGE_REG);
1297 end = ALIGN(end, CACHE_LINE_SIZE);
1298 while (start != end) {
1299 unsigned long range_end = calc_range_end(start, end);
1300 aurora_pa_range(start, range_end - CACHE_LINE_SIZE,
1301 AURORA_CLEAN_RANGE_REG);
1302 start = range_end;
1303 }
1304 }
1305} 1319}
1306 1320
1307static void aurora_flush_range(unsigned long start, unsigned long end) 1321static void aurora_flush_range(unsigned long start, unsigned long end)
1308{ 1322{
1309 start &= ~(CACHE_LINE_SIZE - 1); 1323 if (l2_wt_override)
1310 end = ALIGN(end, CACHE_LINE_SIZE); 1324 aurora_pa_range(start, end, AURORA_INVAL_RANGE_REG);
1311 while (start != end) { 1325 else
1312 unsigned long range_end = calc_range_end(start, end); 1326 aurora_pa_range(start, end, AURORA_FLUSH_RANGE_REG);
1313 /*
1314 * If L2 is forced to WT, the L2 will always be clean and we
1315 * just need to invalidate.
1316 */
1317 if (l2_wt_override)
1318 aurora_pa_range(start, range_end - CACHE_LINE_SIZE,
1319 AURORA_INVAL_RANGE_REG);
1320 else
1321 aurora_pa_range(start, range_end - CACHE_LINE_SIZE,
1322 AURORA_FLUSH_RANGE_REG);
1323 start = range_end;
1324 }
1325} 1327}
1326 1328
1327static void aurora_save(void __iomem *base) 1329static void aurora_flush_all(void)
1328{ 1330{
1329 l2x0_saved_regs.ctrl = readl_relaxed(base + L2X0_CTRL); 1331 void __iomem *base = l2x0_base;
1330 l2x0_saved_regs.aux_ctrl = readl_relaxed(base + L2X0_AUX_CTRL); 1332 unsigned long flags;
1333
1334 /* clean all ways */
1335 raw_spin_lock_irqsave(&l2x0_lock, flags);
1336 __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
1337 raw_spin_unlock_irqrestore(&l2x0_lock, flags);
1338
1339 writel_relaxed(0, base + AURORA_SYNC_REG);
1331} 1340}
1332 1341
1333static void aurora_resume(void) 1342static void aurora_cache_sync(void)
1343{
1344 writel_relaxed(0, l2x0_base + AURORA_SYNC_REG);
1345}
1346
1347static void aurora_disable(void)
1334{ 1348{
1335 void __iomem *base = l2x0_base; 1349 void __iomem *base = l2x0_base;
1350 unsigned long flags;
1336 1351
1337 if (!(readl(base + L2X0_CTRL) & L2X0_CTRL_EN)) { 1352 raw_spin_lock_irqsave(&l2x0_lock, flags);
1338 writel_relaxed(l2x0_saved_regs.aux_ctrl, base + L2X0_AUX_CTRL); 1353 __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
1339 writel_relaxed(l2x0_saved_regs.ctrl, base + L2X0_CTRL); 1354 writel_relaxed(0, base + AURORA_SYNC_REG);
1340 } 1355 l2c_write_sec(0, base, L2X0_CTRL);
1356 dsb(st);
1357 raw_spin_unlock_irqrestore(&l2x0_lock, flags);
1358}
1359
1360static void aurora_save(void __iomem *base)
1361{
1362 l2x0_saved_regs.ctrl = readl_relaxed(base + L2X0_CTRL);
1363 l2x0_saved_regs.aux_ctrl = readl_relaxed(base + L2X0_AUX_CTRL);
1341} 1364}
1342 1365
1343/* 1366/*
@@ -1398,10 +1421,10 @@ static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
1398 .inv_range = aurora_inv_range, 1421 .inv_range = aurora_inv_range,
1399 .clean_range = aurora_clean_range, 1422 .clean_range = aurora_clean_range,
1400 .flush_range = aurora_flush_range, 1423 .flush_range = aurora_flush_range,
1401 .flush_all = l2x0_flush_all, 1424 .flush_all = aurora_flush_all,
1402 .disable = l2x0_disable, 1425 .disable = aurora_disable,
1403 .sync = l2x0_cache_sync, 1426 .sync = aurora_cache_sync,
1404 .resume = aurora_resume, 1427 .resume = l2c_resume,
1405 }, 1428 },
1406}; 1429};
1407 1430
@@ -1414,7 +1437,7 @@ static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
1414 .fixup = aurora_fixup, 1437 .fixup = aurora_fixup,
1415 .save = aurora_save, 1438 .save = aurora_save,
1416 .outer_cache = { 1439 .outer_cache = {
1417 .resume = aurora_resume, 1440 .resume = l2c_resume,
1418 }, 1441 },
1419}; 1442};
1420 1443
@@ -1562,6 +1585,7 @@ static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
1562 .of_parse = l2c310_of_parse, 1585 .of_parse = l2c310_of_parse,
1563 .enable = l2c310_enable, 1586 .enable = l2c310_enable,
1564 .save = l2c310_save, 1587 .save = l2c310_save,
1588 .configure = l2c310_configure,
1565 .outer_cache = { 1589 .outer_cache = {
1566 .inv_range = bcm_inv_range, 1590 .inv_range = bcm_inv_range,
1567 .clean_range = bcm_clean_range, 1591 .clean_range = bcm_clean_range,
@@ -1583,18 +1607,12 @@ static void __init tauros3_save(void __iomem *base)
1583 readl_relaxed(base + L310_PREFETCH_CTRL); 1607 readl_relaxed(base + L310_PREFETCH_CTRL);
1584} 1608}
1585 1609
1586static void tauros3_resume(void) 1610static void tauros3_configure(void __iomem *base)
1587{ 1611{
1588 void __iomem *base = l2x0_base; 1612 writel_relaxed(l2x0_saved_regs.aux2_ctrl,
1589 1613 base + TAUROS3_AUX2_CTRL);
1590 if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)) { 1614 writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
1591 writel_relaxed(l2x0_saved_regs.aux2_ctrl, 1615 base + L310_PREFETCH_CTRL);
1592 base + TAUROS3_AUX2_CTRL);
1593 writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
1594 base + L310_PREFETCH_CTRL);
1595
1596 l2c_enable(base, l2x0_saved_regs.aux_ctrl, 8);
1597 }
1598} 1616}
1599 1617
1600static const struct l2c_init_data of_tauros3_data __initconst = { 1618static const struct l2c_init_data of_tauros3_data __initconst = {
@@ -1603,9 +1621,10 @@ static const struct l2c_init_data of_tauros3_data __initconst = {
1603 .num_lock = 8, 1621 .num_lock = 8,
1604 .enable = l2c_enable, 1622 .enable = l2c_enable,
1605 .save = tauros3_save, 1623 .save = tauros3_save,
1624 .configure = tauros3_configure,
1606 /* Tauros3 broadcasts L1 cache operations to L2 */ 1625 /* Tauros3 broadcasts L1 cache operations to L2 */
1607 .outer_cache = { 1626 .outer_cache = {
1608 .resume = tauros3_resume, 1627 .resume = l2c_resume,
1609 }, 1628 },
1610}; 1629};
1611 1630
@@ -1661,6 +1680,10 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
1661 if (!of_property_read_bool(np, "cache-unified")) 1680 if (!of_property_read_bool(np, "cache-unified"))
1662 pr_err("L2C: device tree omits to specify unified cache\n"); 1681 pr_err("L2C: device tree omits to specify unified cache\n");
1663 1682
1683 /* Read back current (default) hardware configuration */
1684 if (data->save)
1685 data->save(l2x0_base);
1686
1664 /* L2 configuration can only be changed if the cache is disabled */ 1687 /* L2 configuration can only be changed if the cache is disabled */
1665 if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) 1688 if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
1666 if (data->of_parse) 1689 if (data->of_parse)
@@ -1671,8 +1694,6 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
1671 else 1694 else
1672 cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID); 1695 cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
1673 1696
1674 __l2c_init(data, aux_val, aux_mask, cache_id); 1697 return __l2c_init(data, aux_val, aux_mask, cache_id);
1675
1676 return 0;
1677} 1698}
1678#endif 1699#endif
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 2495c8cb47ba..1609b022a72f 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -319,10 +319,7 @@ void __init arm_memblock_init(const struct machine_desc *mdesc)
319 319
320 early_init_fdt_scan_reserved_mem(); 320 early_init_fdt_scan_reserved_mem();
321 321
322 /* 322 /* reserve memory for DMA contiguous allocations */
323 * reserve memory for DMA contigouos allocations,
324 * must come from DMA area inside low memory
325 */
326 dma_contiguous_reserve(arm_dma_limit); 323 dma_contiguous_reserve(arm_dma_limit);
327 324
328 arm_memblock_steal_permitted = false; 325 arm_memblock_steal_permitted = false;
diff --git a/arch/arm/probes/Makefile b/arch/arm/probes/Makefile
new file mode 100644
index 000000000000..aa1f8590dcdd
--- /dev/null
+++ b/arch/arm/probes/Makefile
@@ -0,0 +1,7 @@
1obj-$(CONFIG_UPROBES) += decode.o decode-arm.o uprobes/
2obj-$(CONFIG_KPROBES) += decode.o kprobes/
3ifdef CONFIG_THUMB2_KERNEL
4obj-$(CONFIG_KPROBES) += decode-thumb.o
5else
6obj-$(CONFIG_KPROBES) += decode-arm.o
7endif
diff --git a/arch/arm/kernel/probes-arm.c b/arch/arm/probes/decode-arm.c
index 8eaef81d8344..f72c33a2dcfb 100644
--- a/arch/arm/kernel/probes-arm.c
+++ b/arch/arm/probes/decode-arm.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * arch/arm/kernel/probes-arm.c 2 *
3 * arch/arm/probes/decode-arm.c
3 * 4 *
4 * Some code moved here from arch/arm/kernel/kprobes-arm.c 5 * Some code moved here from arch/arm/kernel/kprobes-arm.c
5 * 6 *
@@ -20,8 +21,8 @@
20#include <linux/stddef.h> 21#include <linux/stddef.h>
21#include <linux/ptrace.h> 22#include <linux/ptrace.h>
22 23
23#include "probes.h" 24#include "decode.h"
24#include "probes-arm.h" 25#include "decode-arm.h"
25 26
26#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit))))) 27#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
27 28
@@ -369,17 +370,17 @@ static const union decode_item arm_cccc_001x_table[] = {
369 370
370 /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */ 371 /* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
371 /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */ 372 /* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
372 DECODE_EMULATEX (0x0fb00000, 0x03000000, PROBES_DATA_PROCESSING_IMM, 373 DECODE_EMULATEX (0x0fb00000, 0x03000000, PROBES_MOV_HALFWORD,
373 REGS(0, NOPC, 0, 0, 0)), 374 REGS(0, NOPC, 0, 0, 0)),
374 375
375 /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */ 376 /* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
376 DECODE_OR (0x0fff00ff, 0x03200001), 377 DECODE_OR (0x0fff00ff, 0x03200001),
377 /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */ 378 /* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
378 DECODE_EMULATE (0x0fff00ff, 0x03200004, PROBES_EMULATE_NONE), 379 DECODE_EMULATE (0x0fff00ff, 0x03200004, PROBES_SEV),
379 /* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */ 380 /* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
380 /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */ 381 /* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
381 /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */ 382 /* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
382 DECODE_SIMULATE (0x0fff00fc, 0x03200000, PROBES_SIMULATE_NOP), 383 DECODE_SIMULATE (0x0fff00fc, 0x03200000, PROBES_WFE),
383 /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */ 384 /* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */
384 /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */ 385 /* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
385 /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */ 386 /* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
@@ -725,10 +726,11 @@ static void __kprobes arm_singlestep(probes_opcode_t insn,
725 */ 726 */
726enum probes_insn __kprobes 727enum probes_insn __kprobes
727arm_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 728arm_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
728 bool emulate, const union decode_action *actions) 729 bool emulate, const union decode_action *actions,
730 const struct decode_checker *checkers[])
729{ 731{
730 asi->insn_singlestep = arm_singlestep; 732 asi->insn_singlestep = arm_singlestep;
731 asi->insn_check_cc = probes_condition_checks[insn>>28]; 733 asi->insn_check_cc = probes_condition_checks[insn>>28];
732 return probes_decode_insn(insn, asi, probes_decode_arm_table, false, 734 return probes_decode_insn(insn, asi, probes_decode_arm_table, false,
733 emulate, actions); 735 emulate, actions, checkers);
734} 736}
diff --git a/arch/arm/kernel/probes-arm.h b/arch/arm/probes/decode-arm.h
index ace6572f6e26..b3b80f6d414b 100644
--- a/arch/arm/kernel/probes-arm.h
+++ b/arch/arm/probes/decode-arm.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/probes-arm.h 2 * arch/arm/probes/decode-arm.h
3 * 3 *
4 * Copyright 2013 Linaro Ltd. 4 * Copyright 2013 Linaro Ltd.
5 * Written by: David A. Long 5 * Written by: David A. Long
@@ -15,9 +15,9 @@
15#ifndef _ARM_KERNEL_PROBES_ARM_H 15#ifndef _ARM_KERNEL_PROBES_ARM_H
16#define _ARM_KERNEL_PROBES_ARM_H 16#define _ARM_KERNEL_PROBES_ARM_H
17 17
18#include "decode.h"
19
18enum probes_arm_action { 20enum probes_arm_action {
19 PROBES_EMULATE_NONE,
20 PROBES_SIMULATE_NOP,
21 PROBES_PRELOAD_IMM, 21 PROBES_PRELOAD_IMM,
22 PROBES_PRELOAD_REG, 22 PROBES_PRELOAD_REG,
23 PROBES_BRANCH_IMM, 23 PROBES_BRANCH_IMM,
@@ -68,6 +68,7 @@ extern const union decode_item probes_decode_arm_table[];
68 68
69enum probes_insn arm_probes_decode_insn(probes_opcode_t, 69enum probes_insn arm_probes_decode_insn(probes_opcode_t,
70 struct arch_probes_insn *, bool emulate, 70 struct arch_probes_insn *, bool emulate,
71 const union decode_action *actions); 71 const union decode_action *actions,
72 const struct decode_checker *checkers[]);
72 73
73#endif 74#endif
diff --git a/arch/arm/kernel/probes-thumb.c b/arch/arm/probes/decode-thumb.c
index 4131351e812f..985e7dd4cac6 100644
--- a/arch/arm/kernel/probes-thumb.c
+++ b/arch/arm/probes/decode-thumb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/probes-thumb.c 2 * arch/arm/probes/decode-thumb.c
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -12,8 +12,8 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/module.h> 13#include <linux/module.h>
14 14
15#include "probes.h" 15#include "decode.h"
16#include "probes-thumb.h" 16#include "decode-thumb.h"
17 17
18 18
19static const union decode_item t32_table_1110_100x_x0xx[] = { 19static const union decode_item t32_table_1110_100x_x0xx[] = {
@@ -863,20 +863,22 @@ static void __kprobes thumb32_singlestep(probes_opcode_t opcode,
863 863
864enum probes_insn __kprobes 864enum probes_insn __kprobes
865thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 865thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
866 bool emulate, const union decode_action *actions) 866 bool emulate, const union decode_action *actions,
867 const struct decode_checker *checkers[])
867{ 868{
868 asi->insn_singlestep = thumb16_singlestep; 869 asi->insn_singlestep = thumb16_singlestep;
869 asi->insn_check_cc = thumb_check_cc; 870 asi->insn_check_cc = thumb_check_cc;
870 return probes_decode_insn(insn, asi, probes_decode_thumb16_table, true, 871 return probes_decode_insn(insn, asi, probes_decode_thumb16_table, true,
871 emulate, actions); 872 emulate, actions, checkers);
872} 873}
873 874
874enum probes_insn __kprobes 875enum probes_insn __kprobes
875thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 876thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
876 bool emulate, const union decode_action *actions) 877 bool emulate, const union decode_action *actions,
878 const struct decode_checker *checkers[])
877{ 879{
878 asi->insn_singlestep = thumb32_singlestep; 880 asi->insn_singlestep = thumb32_singlestep;
879 asi->insn_check_cc = thumb_check_cc; 881 asi->insn_check_cc = thumb_check_cc;
880 return probes_decode_insn(insn, asi, probes_decode_thumb32_table, true, 882 return probes_decode_insn(insn, asi, probes_decode_thumb32_table, true,
881 emulate, actions); 883 emulate, actions, checkers);
882} 884}
diff --git a/arch/arm/kernel/probes-thumb.h b/arch/arm/probes/decode-thumb.h
index 7c6f6ebe514f..8457add0a2d8 100644
--- a/arch/arm/kernel/probes-thumb.h
+++ b/arch/arm/probes/decode-thumb.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/probes-thumb.h 2 * arch/arm/probes/decode-thumb.h
3 * 3 *
4 * Copyright 2013 Linaro Ltd. 4 * Copyright 2013 Linaro Ltd.
5 * Written by: David A. Long 5 * Written by: David A. Long
@@ -15,6 +15,8 @@
15#ifndef _ARM_KERNEL_PROBES_THUMB_H 15#ifndef _ARM_KERNEL_PROBES_THUMB_H
16#define _ARM_KERNEL_PROBES_THUMB_H 16#define _ARM_KERNEL_PROBES_THUMB_H
17 17
18#include "decode.h"
19
18/* 20/*
19 * True if current instruction is in an IT block. 21 * True if current instruction is in an IT block.
20 */ 22 */
@@ -89,9 +91,11 @@ extern const union decode_item probes_decode_thumb16_table[];
89 91
90enum probes_insn __kprobes 92enum probes_insn __kprobes
91thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 93thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
92 bool emulate, const union decode_action *actions); 94 bool emulate, const union decode_action *actions,
95 const struct decode_checker *checkers[]);
93enum probes_insn __kprobes 96enum probes_insn __kprobes
94thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 97thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
95 bool emulate, const union decode_action *actions); 98 bool emulate, const union decode_action *actions,
99 const struct decode_checker *checkers[]);
96 100
97#endif 101#endif
diff --git a/arch/arm/kernel/probes.c b/arch/arm/probes/decode.c
index a8ab540d7e73..880ebe0cdf19 100644
--- a/arch/arm/kernel/probes.c
+++ b/arch/arm/probes/decode.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/probes.c 2 * arch/arm/probes/decode.c
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -17,7 +17,7 @@
17#include <asm/ptrace.h> 17#include <asm/ptrace.h>
18#include <linux/bug.h> 18#include <linux/bug.h>
19 19
20#include "probes.h" 20#include "decode.h"
21 21
22 22
23#ifndef find_str_pc_offset 23#ifndef find_str_pc_offset
@@ -342,6 +342,31 @@ static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
342 [DECODE_TYPE_REJECT] = sizeof(struct decode_reject) 342 [DECODE_TYPE_REJECT] = sizeof(struct decode_reject)
343}; 343};
344 344
345static int run_checkers(const struct decode_checker *checkers[],
346 int action, probes_opcode_t insn,
347 struct arch_probes_insn *asi,
348 const struct decode_header *h)
349{
350 const struct decode_checker **p;
351
352 if (!checkers)
353 return INSN_GOOD;
354
355 p = checkers;
356 while (*p != NULL) {
357 int retval;
358 probes_check_t *checker_func = (*p)[action].checker;
359
360 retval = INSN_GOOD;
361 if (checker_func)
362 retval = checker_func(insn, asi, h);
363 if (retval == INSN_REJECTED)
364 return retval;
365 p++;
366 }
367 return INSN_GOOD;
368}
369
345/* 370/*
346 * probes_decode_insn operates on data tables in order to decode an ARM 371 * probes_decode_insn operates on data tables in order to decode an ARM
347 * architecture instruction onto which a kprobe has been placed. 372 * architecture instruction onto which a kprobe has been placed.
@@ -388,11 +413,34 @@ static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
388int __kprobes 413int __kprobes
389probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 414probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
390 const union decode_item *table, bool thumb, 415 const union decode_item *table, bool thumb,
391 bool emulate, const union decode_action *actions) 416 bool emulate, const union decode_action *actions,
417 const struct decode_checker *checkers[])
392{ 418{
393 const struct decode_header *h = (struct decode_header *)table; 419 const struct decode_header *h = (struct decode_header *)table;
394 const struct decode_header *next; 420 const struct decode_header *next;
395 bool matched = false; 421 bool matched = false;
422 /*
423 * @insn can be modified by decode_regs. Save its original
424 * value for checkers.
425 */
426 probes_opcode_t origin_insn = insn;
427
428 /*
429 * stack_space is initialized to 0 here. Checker functions
430 * should update is value if they find this is a stack store
431 * instruction: positive value means bytes of stack usage,
432 * negitive value means unable to determine stack usage
433 * statically. For instruction doesn't store to stack, checker
434 * do nothing with it.
435 */
436 asi->stack_space = 0;
437
438 /*
439 * Similarly to stack_space, register_usage_flags is filled by
440 * checkers. Its default value is set to ~0, which is 'all
441 * registers are used', to prevent any potential optimization.
442 */
443 asi->register_usage_flags = ~0UL;
396 444
397 if (emulate) 445 if (emulate)
398 insn = prepare_emulated_insn(insn, asi, thumb); 446 insn = prepare_emulated_insn(insn, asi, thumb);
@@ -422,24 +470,41 @@ probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
422 } 470 }
423 471
424 case DECODE_TYPE_CUSTOM: { 472 case DECODE_TYPE_CUSTOM: {
473 int err;
425 struct decode_custom *d = (struct decode_custom *)h; 474 struct decode_custom *d = (struct decode_custom *)h;
426 return actions[d->decoder.action].decoder(insn, asi, h); 475 int action = d->decoder.action;
476
477 err = run_checkers(checkers, action, origin_insn, asi, h);
478 if (err == INSN_REJECTED)
479 return INSN_REJECTED;
480 return actions[action].decoder(insn, asi, h);
427 } 481 }
428 482
429 case DECODE_TYPE_SIMULATE: { 483 case DECODE_TYPE_SIMULATE: {
484 int err;
430 struct decode_simulate *d = (struct decode_simulate *)h; 485 struct decode_simulate *d = (struct decode_simulate *)h;
431 asi->insn_handler = actions[d->handler.action].handler; 486 int action = d->handler.action;
487
488 err = run_checkers(checkers, action, origin_insn, asi, h);
489 if (err == INSN_REJECTED)
490 return INSN_REJECTED;
491 asi->insn_handler = actions[action].handler;
432 return INSN_GOOD_NO_SLOT; 492 return INSN_GOOD_NO_SLOT;
433 } 493 }
434 494
435 case DECODE_TYPE_EMULATE: { 495 case DECODE_TYPE_EMULATE: {
496 int err;
436 struct decode_emulate *d = (struct decode_emulate *)h; 497 struct decode_emulate *d = (struct decode_emulate *)h;
498 int action = d->handler.action;
499
500 err = run_checkers(checkers, action, origin_insn, asi, h);
501 if (err == INSN_REJECTED)
502 return INSN_REJECTED;
437 503
438 if (!emulate) 504 if (!emulate)
439 return actions[d->handler.action].decoder(insn, 505 return actions[action].decoder(insn, asi, h);
440 asi, h);
441 506
442 asi->insn_handler = actions[d->handler.action].handler; 507 asi->insn_handler = actions[action].handler;
443 set_emulated_insn(insn, asi, thumb); 508 set_emulated_insn(insn, asi, thumb);
444 return INSN_GOOD; 509 return INSN_GOOD;
445 } 510 }
diff --git a/arch/arm/kernel/probes.h b/arch/arm/probes/decode.h
index dba9f2466a93..f9b08ba7fe73 100644
--- a/arch/arm/kernel/probes.h
+++ b/arch/arm/probes/decode.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/probes.h 2 * arch/arm/probes/decode.h
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -314,6 +314,14 @@ union decode_action {
314 probes_custom_decode_t *decoder; 314 probes_custom_decode_t *decoder;
315}; 315};
316 316
317typedef enum probes_insn (probes_check_t)(probes_opcode_t,
318 struct arch_probes_insn *,
319 const struct decode_header *);
320
321struct decode_checker {
322 probes_check_t *checker;
323};
324
317#define DECODE_END \ 325#define DECODE_END \
318 {.bits = DECODE_TYPE_END} 326 {.bits = DECODE_TYPE_END}
319 327
@@ -402,6 +410,7 @@ probes_insn_handler_t probes_emulate_none;
402int __kprobes 410int __kprobes
403probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi, 411probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
404 const union decode_item *table, bool thumb, bool emulate, 412 const union decode_item *table, bool thumb, bool emulate,
405 const union decode_action *actions); 413 const union decode_action *actions,
414 const struct decode_checker **checkers);
406 415
407#endif 416#endif
diff --git a/arch/arm/probes/kprobes/Makefile b/arch/arm/probes/kprobes/Makefile
new file mode 100644
index 000000000000..76a36bf102b7
--- /dev/null
+++ b/arch/arm/probes/kprobes/Makefile
@@ -0,0 +1,12 @@
1obj-$(CONFIG_KPROBES) += core.o actions-common.o checkers-common.o
2obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o
3test-kprobes-objs := test-core.o
4
5ifdef CONFIG_THUMB2_KERNEL
6obj-$(CONFIG_KPROBES) += actions-thumb.o checkers-thumb.o
7test-kprobes-objs += test-thumb.o
8else
9obj-$(CONFIG_KPROBES) += actions-arm.o checkers-arm.o
10obj-$(CONFIG_OPTPROBES) += opt-arm.o
11test-kprobes-objs += test-arm.o
12endif
diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/probes/kprobes/actions-arm.c
index ac300c60d656..b9056d649607 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/probes/kprobes/actions-arm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/kprobes-decode.c 2 * arch/arm/probes/kprobes/actions-arm.c
3 * 3 *
4 * Copyright (C) 2006, 2007 Motorola Inc. 4 * Copyright (C) 2006, 2007 Motorola Inc.
5 * 5 *
@@ -62,8 +62,9 @@
62#include <linux/kprobes.h> 62#include <linux/kprobes.h>
63#include <linux/ptrace.h> 63#include <linux/ptrace.h>
64 64
65#include "kprobes.h" 65#include "../decode-arm.h"
66#include "probes-arm.h" 66#include "core.h"
67#include "checkers.h"
67 68
68#if __LINUX_ARM_ARCH__ >= 6 69#if __LINUX_ARM_ARCH__ >= 6
69#define BLX(reg) "blx "reg" \n\t" 70#define BLX(reg) "blx "reg" \n\t"
@@ -302,8 +303,6 @@ emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(probes_opcode_t insn,
302} 303}
303 304
304const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = { 305const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
305 [PROBES_EMULATE_NONE] = {.handler = probes_emulate_none},
306 [PROBES_SIMULATE_NOP] = {.handler = probes_simulate_nop},
307 [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop}, 306 [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
308 [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop}, 307 [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
309 [PROBES_BRANCH_IMM] = {.handler = simulate_blx1}, 308 [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
@@ -341,3 +340,5 @@ const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
341 [PROBES_BRANCH] = {.handler = simulate_bbl}, 340 [PROBES_BRANCH] = {.handler = simulate_bbl},
342 [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm} 341 [PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm}
343}; 342};
343
344const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker, arm_regs_checker, NULL};
diff --git a/arch/arm/kernel/kprobes-common.c b/arch/arm/probes/kprobes/actions-common.c
index 0bf5d64eba1d..bd20a71cd34a 100644
--- a/arch/arm/kernel/kprobes-common.c
+++ b/arch/arm/probes/kprobes/actions-common.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/kprobes-common.c 2 * arch/arm/probes/kprobes/actions-common.c
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -15,7 +15,7 @@
15#include <linux/kprobes.h> 15#include <linux/kprobes.h>
16#include <asm/opcodes.h> 16#include <asm/opcodes.h>
17 17
18#include "kprobes.h" 18#include "core.h"
19 19
20 20
21static void __kprobes simulate_ldm1stm1(probes_opcode_t insn, 21static void __kprobes simulate_ldm1stm1(probes_opcode_t insn,
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/probes/kprobes/actions-thumb.c
index 9495d7f3516f..07cfd9bef340 100644
--- a/arch/arm/kernel/kprobes-thumb.c
+++ b/arch/arm/probes/kprobes/actions-thumb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/kprobes-thumb.c 2 * arch/arm/probes/kprobes/actions-thumb.c
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -13,8 +13,9 @@
13#include <linux/ptrace.h> 13#include <linux/ptrace.h>
14#include <linux/kprobes.h> 14#include <linux/kprobes.h>
15 15
16#include "kprobes.h" 16#include "../decode-thumb.h"
17#include "probes-thumb.h" 17#include "core.h"
18#include "checkers.h"
18 19
19/* These emulation encodings are functionally equivalent... */ 20/* These emulation encodings are functionally equivalent... */
20#define t32_emulate_rd8rn16rm0ra12_noflags \ 21#define t32_emulate_rd8rn16rm0ra12_noflags \
@@ -664,3 +665,6 @@ const union decode_action kprobes_t32_actions[NUM_PROBES_T32_ACTIONS] = {
664 [PROBES_T32_MUL_ADD_LONG] = { 665 [PROBES_T32_MUL_ADD_LONG] = {
665 .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags}, 666 .handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags},
666}; 667};
668
669const struct decode_checker *kprobes_t32_checkers[] = {t32_stack_checker, NULL};
670const struct decode_checker *kprobes_t16_checkers[] = {t16_stack_checker, NULL};
diff --git a/arch/arm/probes/kprobes/checkers-arm.c b/arch/arm/probes/kprobes/checkers-arm.c
new file mode 100644
index 000000000000..7b9817333b68
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers-arm.c
@@ -0,0 +1,192 @@
1/*
2 * arch/arm/probes/kprobes/checkers-arm.c
3 *
4 * Copyright (C) 2014 Huawei Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include "../decode.h"
18#include "../decode-arm.h"
19#include "checkers.h"
20
21static enum probes_insn __kprobes arm_check_stack(probes_opcode_t insn,
22 struct arch_probes_insn *asi,
23 const struct decode_header *h)
24{
25 /*
26 * PROBES_LDRSTRD, PROBES_LDMSTM, PROBES_STORE,
27 * PROBES_STORE_EXTRA may get here. Simply mark all normal
28 * insns as STACK_USE_NONE.
29 */
30 static const union decode_item table[] = {
31 /*
32 * 'STR{,D,B,H}, Rt, [Rn, Rm]' should be marked as UNKNOWN
33 * if Rn or Rm is SP.
34 * x
35 * STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx
36 * STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx
37 */
38 DECODE_OR (0x0e10000f, 0x0600000d),
39 DECODE_OR (0x0e1f0000, 0x060d0000),
40
41 /*
42 * x
43 * STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx
44 * STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx
45 */
46 DECODE_OR (0x0e5000bf, 0x000000bd),
47 DECODE_CUSTOM (0x0e5f00b0, 0x000d00b0, STACK_USE_UNKNOWN),
48
49 /*
50 * For PROBES_LDMSTM, only stmdx sp, [...] need to examine
51 *
52 * Bit B/A (bit 24) encodes arithmetic operation order. 1 means
53 * before, 0 means after.
54 * Bit I/D (bit 23) encodes arithmetic operation. 1 means
55 * increment, 0 means decrement.
56 *
57 * So:
58 * B I
59 * / /
60 * A D | Rn |
61 * STMDX SP, [...] cccc 100x 00x0 xxxx xxxx xxxx xxxx xxxx
62 */
63 DECODE_CUSTOM (0x0edf0000, 0x080d0000, STACK_USE_STMDX),
64
65 /* P U W | Rn | Rt | imm12 |*/
66 /* STR (immediate) cccc 010x x0x0 1101 xxxx xxxx xxxx xxxx */
67 /* STRB (immediate) cccc 010x x1x0 1101 xxxx xxxx xxxx xxxx */
68 /* P U W | Rn | Rt |imm4| |imm4|*/
69 /* STRD (immediate) cccc 000x x1x0 1101 xxxx xxxx 1111 xxxx */
70 /* STRH (immediate) cccc 000x x1x0 1101 xxxx xxxx 1011 xxxx */
71 /*
72 * index = (P == '1'); add = (U == '1').
73 * Above insns with:
74 * index == 0 (str{,d,h} rx, [sp], #+/-imm) or
75 * add == 1 (str{,d,h} rx, [sp, #+<imm>])
76 * should be STACK_USE_NONE.
77 * Only str{,b,d,h} rx,[sp,#-n] (P == 1 and U == 0) are
78 * required to be examined.
79 */
80 /* STR{,B} Rt,[SP,#-n] cccc 0101 0xx0 1101 xxxx xxxx xxxx xxxx */
81 DECODE_CUSTOM (0x0f9f0000, 0x050d0000, STACK_USE_FIXED_XXX),
82
83 /* STR{D,H} Rt,[SP,#-n] cccc 0001 01x0 1101 xxxx xxxx 1x11 xxxx */
84 DECODE_CUSTOM (0x0fdf00b0, 0x014d00b0, STACK_USE_FIXED_X0X),
85
86 /* fall through */
87 DECODE_CUSTOM (0, 0, STACK_USE_NONE),
88 DECODE_END
89 };
90
91 return probes_decode_insn(insn, asi, table, false, false, stack_check_actions, NULL);
92}
93
94const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = {
95 [PROBES_LDRSTRD] = {.checker = arm_check_stack},
96 [PROBES_STORE_EXTRA] = {.checker = arm_check_stack},
97 [PROBES_STORE] = {.checker = arm_check_stack},
98 [PROBES_LDMSTM] = {.checker = arm_check_stack},
99};
100
101static enum probes_insn __kprobes arm_check_regs_nouse(probes_opcode_t insn,
102 struct arch_probes_insn *asi,
103 const struct decode_header *h)
104{
105 asi->register_usage_flags = 0;
106 return INSN_GOOD;
107}
108
109static enum probes_insn arm_check_regs_normal(probes_opcode_t insn,
110 struct arch_probes_insn *asi,
111 const struct decode_header *h)
112{
113 u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS;
114 int i;
115
116 asi->register_usage_flags = 0;
117 for (i = 0; i < 5; regs >>= 4, insn >>= 4, i++)
118 if (regs & 0xf)
119 asi->register_usage_flags |= 1 << (insn & 0xf);
120
121 return INSN_GOOD;
122}
123
124
125static enum probes_insn arm_check_regs_ldmstm(probes_opcode_t insn,
126 struct arch_probes_insn *asi,
127 const struct decode_header *h)
128{
129 unsigned int reglist = insn & 0xffff;
130 unsigned int rn = (insn >> 16) & 0xf;
131 asi->register_usage_flags = reglist | (1 << rn);
132 return INSN_GOOD;
133}
134
135static enum probes_insn arm_check_regs_mov_ip_sp(probes_opcode_t insn,
136 struct arch_probes_insn *asi,
137 const struct decode_header *h)
138{
139 /* Instruction is 'mov ip, sp' i.e. 'mov r12, r13' */
140 asi->register_usage_flags = (1 << 12) | (1<< 13);
141 return INSN_GOOD;
142}
143
144/*
145 * | Rn |Rt/d| | Rm |
146 * LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx
147 * STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx
148 * | Rn |Rt/d| |imm4L|
149 * LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx
150 * STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx
151 *
152 * Such instructions access Rt/d and its next register, so different
153 * from others, a specific checker is required to handle this extra
154 * implicit register usage.
155 */
156static enum probes_insn arm_check_regs_ldrdstrd(probes_opcode_t insn,
157 struct arch_probes_insn *asi,
158 const struct decode_header *h)
159{
160 int rdt = (insn >> 12) & 0xf;
161 arm_check_regs_normal(insn, asi, h);
162 asi->register_usage_flags |= 1 << (rdt + 1);
163 return INSN_GOOD;
164}
165
166
167const struct decode_checker arm_regs_checker[NUM_PROBES_ARM_ACTIONS] = {
168 [PROBES_MRS] = {.checker = arm_check_regs_normal},
169 [PROBES_SATURATING_ARITHMETIC] = {.checker = arm_check_regs_normal},
170 [PROBES_MUL1] = {.checker = arm_check_regs_normal},
171 [PROBES_MUL2] = {.checker = arm_check_regs_normal},
172 [PROBES_MUL_ADD_LONG] = {.checker = arm_check_regs_normal},
173 [PROBES_MUL_ADD] = {.checker = arm_check_regs_normal},
174 [PROBES_LOAD] = {.checker = arm_check_regs_normal},
175 [PROBES_LOAD_EXTRA] = {.checker = arm_check_regs_normal},
176 [PROBES_STORE] = {.checker = arm_check_regs_normal},
177 [PROBES_STORE_EXTRA] = {.checker = arm_check_regs_normal},
178 [PROBES_DATA_PROCESSING_REG] = {.checker = arm_check_regs_normal},
179 [PROBES_DATA_PROCESSING_IMM] = {.checker = arm_check_regs_normal},
180 [PROBES_SEV] = {.checker = arm_check_regs_nouse},
181 [PROBES_WFE] = {.checker = arm_check_regs_nouse},
182 [PROBES_SATURATE] = {.checker = arm_check_regs_normal},
183 [PROBES_REV] = {.checker = arm_check_regs_normal},
184 [PROBES_MMI] = {.checker = arm_check_regs_normal},
185 [PROBES_PACK] = {.checker = arm_check_regs_normal},
186 [PROBES_EXTEND] = {.checker = arm_check_regs_normal},
187 [PROBES_EXTEND_ADD] = {.checker = arm_check_regs_normal},
188 [PROBES_BITFIELD] = {.checker = arm_check_regs_normal},
189 [PROBES_LDMSTM] = {.checker = arm_check_regs_ldmstm},
190 [PROBES_MOV_IP_SP] = {.checker = arm_check_regs_mov_ip_sp},
191 [PROBES_LDRSTRD] = {.checker = arm_check_regs_ldrdstrd},
192};
diff --git a/arch/arm/probes/kprobes/checkers-common.c b/arch/arm/probes/kprobes/checkers-common.c
new file mode 100644
index 000000000000..971119c29474
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers-common.c
@@ -0,0 +1,101 @@
1/*
2 * arch/arm/probes/kprobes/checkers-common.c
3 *
4 * Copyright (C) 2014 Huawei Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include "../decode.h"
18#include "../decode-arm.h"
19#include "checkers.h"
20
21enum probes_insn checker_stack_use_none(probes_opcode_t insn,
22 struct arch_probes_insn *asi,
23 const struct decode_header *h)
24{
25 asi->stack_space = 0;
26 return INSN_GOOD_NO_SLOT;
27}
28
29enum probes_insn checker_stack_use_unknown(probes_opcode_t insn,
30 struct arch_probes_insn *asi,
31 const struct decode_header *h)
32{
33 asi->stack_space = -1;
34 return INSN_GOOD_NO_SLOT;
35}
36
37#ifdef CONFIG_THUMB2_KERNEL
38enum probes_insn checker_stack_use_imm_0xx(probes_opcode_t insn,
39 struct arch_probes_insn *asi,
40 const struct decode_header *h)
41{
42 int imm = insn & 0xff;
43 asi->stack_space = imm;
44 return INSN_GOOD_NO_SLOT;
45}
46
47/*
48 * Different from other insn uses imm8, the real addressing offset of
49 * STRD in T32 encoding should be imm8 * 4. See ARMARM description.
50 */
51enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn,
52 struct arch_probes_insn *asi,
53 const struct decode_header *h)
54{
55 int imm = insn & 0xff;
56 asi->stack_space = imm << 2;
57 return INSN_GOOD_NO_SLOT;
58}
59#else
60enum probes_insn checker_stack_use_imm_x0x(probes_opcode_t insn,
61 struct arch_probes_insn *asi,
62 const struct decode_header *h)
63{
64 int imm = ((insn & 0xf00) >> 4) + (insn & 0xf);
65 asi->stack_space = imm;
66 return INSN_GOOD_NO_SLOT;
67}
68#endif
69
70enum probes_insn checker_stack_use_imm_xxx(probes_opcode_t insn,
71 struct arch_probes_insn *asi,
72 const struct decode_header *h)
73{
74 int imm = insn & 0xfff;
75 asi->stack_space = imm;
76 return INSN_GOOD_NO_SLOT;
77}
78
79enum probes_insn checker_stack_use_stmdx(probes_opcode_t insn,
80 struct arch_probes_insn *asi,
81 const struct decode_header *h)
82{
83 unsigned int reglist = insn & 0xffff;
84 int pbit = insn & (1 << 24);
85 asi->stack_space = (hweight32(reglist) - (!pbit ? 1 : 0)) * 4;
86
87 return INSN_GOOD_NO_SLOT;
88}
89
90const union decode_action stack_check_actions[] = {
91 [STACK_USE_NONE] = {.decoder = checker_stack_use_none},
92 [STACK_USE_UNKNOWN] = {.decoder = checker_stack_use_unknown},
93#ifdef CONFIG_THUMB2_KERNEL
94 [STACK_USE_FIXED_0XX] = {.decoder = checker_stack_use_imm_0xx},
95 [STACK_USE_T32STRD] = {.decoder = checker_stack_use_t32strd},
96#else
97 [STACK_USE_FIXED_X0X] = {.decoder = checker_stack_use_imm_x0x},
98#endif
99 [STACK_USE_FIXED_XXX] = {.decoder = checker_stack_use_imm_xxx},
100 [STACK_USE_STMDX] = {.decoder = checker_stack_use_stmdx},
101};
diff --git a/arch/arm/probes/kprobes/checkers-thumb.c b/arch/arm/probes/kprobes/checkers-thumb.c
new file mode 100644
index 000000000000..d608e3b9017a
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers-thumb.c
@@ -0,0 +1,110 @@
1/*
2 * arch/arm/probes/kprobes/checkers-thumb.c
3 *
4 * Copyright (C) 2014 Huawei Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include "../decode.h"
18#include "../decode-thumb.h"
19#include "checkers.h"
20
21static enum probes_insn __kprobes t32_check_stack(probes_opcode_t insn,
22 struct arch_probes_insn *asi,
23 const struct decode_header *h)
24{
25 /*
26 * PROBES_T32_LDMSTM, PROBES_T32_LDRDSTRD and PROBES_T32_LDRSTR
27 * may get here. Simply mark all normal insns as STACK_USE_NONE.
28 */
29 static const union decode_item table[] = {
30
31 /*
32 * First, filter out all ldr insns to make our life easier.
33 * Following load insns may come here:
34 * LDM, LDRD, LDR.
35 * In T32 encoding, bit 20 is enough for distinguishing
36 * load and store. All load insns have this bit set, when
37 * all store insns have this bit clear.
38 */
39 DECODE_CUSTOM (0x00100000, 0x00100000, STACK_USE_NONE),
40
41 /*
42 * Mark all 'STR{,B,H}, Rt, [Rn, Rm]' as STACK_USE_UNKNOWN
43 * if Rn or Rm is SP. T32 doesn't encode STRD.
44 */
45 /* xx | Rn | Rt | | Rm |*/
46 /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */
47 /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */
48 /* STRH (register) 1111 1000 0010 xxxx xxxx 0000 00xx xxxx */
49 /* INVALID INSN 1111 1000 0110 xxxx xxxx 0000 00xx xxxx */
50 /* By Introducing INVALID INSN, bit 21 and 22 can be ignored. */
51 DECODE_OR (0xff9f0fc0, 0xf80d0000),
52 DECODE_CUSTOM (0xff900fcf, 0xf800000d, STACK_USE_UNKNOWN),
53
54
55 /* xx | Rn | Rt | PUW| imm8 |*/
56 /* STR (imm 8) 1111 1000 0100 1101 xxxx 110x xxxx xxxx */
57 /* STRB (imm 8) 1111 1000 0000 1101 xxxx 110x xxxx xxxx */
58 /* STRH (imm 8) 1111 1000 0010 1101 xxxx 110x xxxx xxxx */
59 /* INVALID INSN 1111 1000 0110 1101 xxxx 110x xxxx xxxx */
60 /* Only consider U == 0 and P == 1: strx rx, [sp, #-<imm>] */
61 DECODE_CUSTOM (0xff9f0e00, 0xf80d0c00, STACK_USE_FIXED_0XX),
62
63 /* For STR{,B,H} (imm 12), offset is always positive, so ignore them. */
64
65 /* P U W | Rn | Rt | Rt2| imm8 |*/
66 /* STRD (immediate) 1110 1001 01x0 1101 xxxx xxxx xxxx xxxx */
67 /*
68 * Only consider U == 0 and P == 1.
69 * Also note that STRD in T32 encoding is special:
70 * imm = ZeroExtend(imm8:'00', 32)
71 */
72 DECODE_CUSTOM (0xffdf0000, 0xe94d0000, STACK_USE_T32STRD),
73
74 /* | Rn | */
75 /* STMDB 1110 1001 00x0 1101 xxxx xxxx xxxx xxxx */
76 DECODE_CUSTOM (0xffdf0000, 0xe90d0000, STACK_USE_STMDX),
77
78 /* fall through */
79 DECODE_CUSTOM (0, 0, STACK_USE_NONE),
80 DECODE_END
81 };
82
83 return probes_decode_insn(insn, asi, table, false, false, stack_check_actions, NULL);
84}
85
86const struct decode_checker t32_stack_checker[NUM_PROBES_T32_ACTIONS] = {
87 [PROBES_T32_LDMSTM] = {.checker = t32_check_stack},
88 [PROBES_T32_LDRDSTRD] = {.checker = t32_check_stack},
89 [PROBES_T32_LDRSTR] = {.checker = t32_check_stack},
90};
91
92/*
93 * See following comments. This insn must be 'push'.
94 */
95static enum probes_insn __kprobes t16_check_stack(probes_opcode_t insn,
96 struct arch_probes_insn *asi,
97 const struct decode_header *h)
98{
99 unsigned int reglist = insn & 0x1ff;
100 asi->stack_space = hweight32(reglist) * 4;
101 return INSN_GOOD;
102}
103
104/*
105 * T16 encoding is simple: only the 'push' insn can need extra stack space.
106 * Other insns, like str, can only use r0-r7 as Rn.
107 */
108const struct decode_checker t16_stack_checker[NUM_PROBES_T16_ACTIONS] = {
109 [PROBES_T16_PUSH] = {.checker = t16_check_stack},
110};
diff --git a/arch/arm/probes/kprobes/checkers.h b/arch/arm/probes/kprobes/checkers.h
new file mode 100644
index 000000000000..cf6c9e74d666
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers.h
@@ -0,0 +1,55 @@
1/*
2 * arch/arm/probes/kprobes/checkers.h
3 *
4 * Copyright (C) 2014 Huawei Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15#ifndef _ARM_KERNEL_PROBES_CHECKERS_H
16#define _ARM_KERNEL_PROBES_CHECKERS_H
17
18#include <linux/kernel.h>
19#include <linux/types.h>
20#include "../decode.h"
21
22extern probes_check_t checker_stack_use_none;
23extern probes_check_t checker_stack_use_unknown;
24#ifdef CONFIG_THUMB2_KERNEL
25extern probes_check_t checker_stack_use_imm_0xx;
26#else
27extern probes_check_t checker_stack_use_imm_x0x;
28#endif
29extern probes_check_t checker_stack_use_imm_xxx;
30extern probes_check_t checker_stack_use_stmdx;
31
32enum {
33 STACK_USE_NONE,
34 STACK_USE_UNKNOWN,
35#ifdef CONFIG_THUMB2_KERNEL
36 STACK_USE_FIXED_0XX,
37 STACK_USE_T32STRD,
38#else
39 STACK_USE_FIXED_X0X,
40#endif
41 STACK_USE_FIXED_XXX,
42 STACK_USE_STMDX,
43 NUM_STACK_USE_TYPES
44};
45
46extern const union decode_action stack_check_actions[];
47
48#ifndef CONFIG_THUMB2_KERNEL
49extern const struct decode_checker arm_stack_checker[];
50extern const struct decode_checker arm_regs_checker[];
51#else
52#endif
53extern const struct decode_checker t32_stack_checker[];
54extern const struct decode_checker t16_stack_checker[];
55#endif
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/probes/kprobes/core.c
index 6d644202c8dc..a4ec240ee7ba 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/probes/kprobes/core.c
@@ -30,11 +30,11 @@
30#include <asm/cacheflush.h> 30#include <asm/cacheflush.h>
31#include <linux/percpu.h> 31#include <linux/percpu.h>
32#include <linux/bug.h> 32#include <linux/bug.h>
33#include <asm/patch.h>
33 34
34#include "kprobes.h" 35#include "../decode-arm.h"
35#include "probes-arm.h" 36#include "../decode-thumb.h"
36#include "probes-thumb.h" 37#include "core.h"
37#include "patch.h"
38 38
39#define MIN_STACK_SIZE(addr) \ 39#define MIN_STACK_SIZE(addr) \
40 min((unsigned long)MAX_STACK_SIZE, \ 40 min((unsigned long)MAX_STACK_SIZE, \
@@ -61,6 +61,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
61 kprobe_decode_insn_t *decode_insn; 61 kprobe_decode_insn_t *decode_insn;
62 const union decode_action *actions; 62 const union decode_action *actions;
63 int is; 63 int is;
64 const struct decode_checker **checkers;
64 65
65 if (in_exception_text(addr)) 66 if (in_exception_text(addr))
66 return -EINVAL; 67 return -EINVAL;
@@ -74,9 +75,11 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
74 insn = __opcode_thumb32_compose(insn, inst2); 75 insn = __opcode_thumb32_compose(insn, inst2);
75 decode_insn = thumb32_probes_decode_insn; 76 decode_insn = thumb32_probes_decode_insn;
76 actions = kprobes_t32_actions; 77 actions = kprobes_t32_actions;
78 checkers = kprobes_t32_checkers;
77 } else { 79 } else {
78 decode_insn = thumb16_probes_decode_insn; 80 decode_insn = thumb16_probes_decode_insn;
79 actions = kprobes_t16_actions; 81 actions = kprobes_t16_actions;
82 checkers = kprobes_t16_checkers;
80 } 83 }
81#else /* !CONFIG_THUMB2_KERNEL */ 84#else /* !CONFIG_THUMB2_KERNEL */
82 thumb = false; 85 thumb = false;
@@ -85,12 +88,13 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
85 insn = __mem_to_opcode_arm(*p->addr); 88 insn = __mem_to_opcode_arm(*p->addr);
86 decode_insn = arm_probes_decode_insn; 89 decode_insn = arm_probes_decode_insn;
87 actions = kprobes_arm_actions; 90 actions = kprobes_arm_actions;
91 checkers = kprobes_arm_checkers;
88#endif 92#endif
89 93
90 p->opcode = insn; 94 p->opcode = insn;
91 p->ainsn.insn = tmp_insn; 95 p->ainsn.insn = tmp_insn;
92 96
93 switch ((*decode_insn)(insn, &p->ainsn, true, actions)) { 97 switch ((*decode_insn)(insn, &p->ainsn, true, actions, checkers)) {
94 case INSN_REJECTED: /* not supported */ 98 case INSN_REJECTED: /* not supported */
95 return -EINVAL; 99 return -EINVAL;
96 100
@@ -111,6 +115,15 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
111 break; 115 break;
112 } 116 }
113 117
118 /*
119 * Never instrument insn like 'str r0, [sp, +/-r1]'. Also, insn likes
120 * 'str r0, [sp, #-68]' should also be prohibited.
121 * See __und_svc.
122 */
123 if ((p->ainsn.stack_space < 0) ||
124 (p->ainsn.stack_space > MAX_STACK_SIZE))
125 return -EINVAL;
126
114 return 0; 127 return 0;
115} 128}
116 129
@@ -150,19 +163,31 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
150 * memory. It is also needed to atomically set the two half-words of a 32-bit 163 * memory. It is also needed to atomically set the two half-words of a 32-bit
151 * Thumb breakpoint. 164 * Thumb breakpoint.
152 */ 165 */
153int __kprobes __arch_disarm_kprobe(void *p) 166struct patch {
154{ 167 void *addr;
155 struct kprobe *kp = p; 168 unsigned int insn;
156 void *addr = (void *)((uintptr_t)kp->addr & ~1); 169};
157
158 __patch_text(addr, kp->opcode);
159 170
171static int __kprobes_remove_breakpoint(void *data)
172{
173 struct patch *p = data;
174 __patch_text(p->addr, p->insn);
160 return 0; 175 return 0;
161} 176}
162 177
178void __kprobes kprobes_remove_breakpoint(void *addr, unsigned int insn)
179{
180 struct patch p = {
181 .addr = addr,
182 .insn = insn,
183 };
184 stop_machine(__kprobes_remove_breakpoint, &p, cpu_online_mask);
185}
186
163void __kprobes arch_disarm_kprobe(struct kprobe *p) 187void __kprobes arch_disarm_kprobe(struct kprobe *p)
164{ 188{
165 stop_machine(__arch_disarm_kprobe, p, cpu_online_mask); 189 kprobes_remove_breakpoint((void *)((uintptr_t)p->addr & ~1),
190 p->opcode);
166} 191}
167 192
168void __kprobes arch_remove_kprobe(struct kprobe *p) 193void __kprobes arch_remove_kprobe(struct kprobe *p)
diff --git a/arch/arm/kernel/kprobes.h b/arch/arm/probes/kprobes/core.h
index 9a2712ecefc3..ec5d1f20a085 100644
--- a/arch/arm/kernel/kprobes.h
+++ b/arch/arm/probes/kprobes/core.h
@@ -19,7 +19,8 @@
19#ifndef _ARM_KERNEL_KPROBES_H 19#ifndef _ARM_KERNEL_KPROBES_H
20#define _ARM_KERNEL_KPROBES_H 20#define _ARM_KERNEL_KPROBES_H
21 21
22#include "probes.h" 22#include <asm/kprobes.h>
23#include "../decode.h"
23 24
24/* 25/*
25 * These undefined instructions must be unique and 26 * These undefined instructions must be unique and
@@ -29,6 +30,8 @@
29#define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18 30#define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18
30#define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018 31#define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018
31 32
33extern void kprobes_remove_breakpoint(void *addr, unsigned int insn);
34
32enum probes_insn __kprobes 35enum probes_insn __kprobes
33kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_probes_insn *asi, 36kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_probes_insn *asi,
34 const struct decode_header *h); 37 const struct decode_header *h);
@@ -36,16 +39,19 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_probes_insn *asi,
36typedef enum probes_insn (kprobe_decode_insn_t)(probes_opcode_t, 39typedef enum probes_insn (kprobe_decode_insn_t)(probes_opcode_t,
37 struct arch_probes_insn *, 40 struct arch_probes_insn *,
38 bool, 41 bool,
39 const union decode_action *); 42 const union decode_action *,
43 const struct decode_checker *[]);
40 44
41#ifdef CONFIG_THUMB2_KERNEL 45#ifdef CONFIG_THUMB2_KERNEL
42 46
43extern const union decode_action kprobes_t32_actions[]; 47extern const union decode_action kprobes_t32_actions[];
44extern const union decode_action kprobes_t16_actions[]; 48extern const union decode_action kprobes_t16_actions[];
45 49extern const struct decode_checker *kprobes_t32_checkers[];
50extern const struct decode_checker *kprobes_t16_checkers[];
46#else /* !CONFIG_THUMB2_KERNEL */ 51#else /* !CONFIG_THUMB2_KERNEL */
47 52
48extern const union decode_action kprobes_arm_actions[]; 53extern const union decode_action kprobes_arm_actions[];
54extern const struct decode_checker *kprobes_arm_checkers[];
49 55
50#endif 56#endif
51 57
diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c
new file mode 100644
index 000000000000..bcdecc25461b
--- /dev/null
+++ b/arch/arm/probes/kprobes/opt-arm.c
@@ -0,0 +1,370 @@
1/*
2 * Kernel Probes Jump Optimization (Optprobes)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * Copyright (C) IBM Corporation, 2002, 2004
19 * Copyright (C) Hitachi Ltd., 2012
20 * Copyright (C) Huawei Inc., 2014
21 */
22
23#include <linux/kprobes.h>
24#include <linux/jump_label.h>
25#include <asm/kprobes.h>
26#include <asm/cacheflush.h>
27/* for arm_gen_branch */
28#include <asm/insn.h>
29/* for patch_text */
30#include <asm/patch.h>
31
32#include "core.h"
33
34/*
35 * See register_usage_flags. If the probed instruction doesn't use PC,
36 * we can copy it into template and have it executed directly without
37 * simulation or emulation.
38 */
39#define ARM_REG_PC 15
40#define can_kprobe_direct_exec(m) (!test_bit(ARM_REG_PC, &(m)))
41
42/*
43 * NOTE: the first sub and add instruction will be modified according
44 * to the stack cost of the instruction.
45 */
46asm (
47 ".global optprobe_template_entry\n"
48 "optprobe_template_entry:\n"
49 ".global optprobe_template_sub_sp\n"
50 "optprobe_template_sub_sp:"
51 " sub sp, sp, #0xff\n"
52 " stmia sp, {r0 - r14} \n"
53 ".global optprobe_template_add_sp\n"
54 "optprobe_template_add_sp:"
55 " add r3, sp, #0xff\n"
56 " str r3, [sp, #52]\n"
57 " mrs r4, cpsr\n"
58 " str r4, [sp, #64]\n"
59 " mov r1, sp\n"
60 " ldr r0, 1f\n"
61 " ldr r2, 2f\n"
62 /*
63 * AEABI requires an 8-bytes alignment stack. If
64 * SP % 8 != 0 (SP % 4 == 0 should be ensured),
65 * alloc more bytes here.
66 */
67 " and r4, sp, #4\n"
68 " sub sp, sp, r4\n"
69#if __LINUX_ARM_ARCH__ >= 5
70 " blx r2\n"
71#else
72 " mov lr, pc\n"
73 " mov pc, r2\n"
74#endif
75 " add sp, sp, r4\n"
76 " ldr r1, [sp, #64]\n"
77 " tst r1, #"__stringify(PSR_T_BIT)"\n"
78 " ldrne r2, [sp, #60]\n"
79 " orrne r2, #1\n"
80 " strne r2, [sp, #60] @ set bit0 of PC for thumb\n"
81 " msr cpsr_cxsf, r1\n"
82 ".global optprobe_template_restore_begin\n"
83 "optprobe_template_restore_begin:\n"
84 " ldmia sp, {r0 - r15}\n"
85 ".global optprobe_template_restore_orig_insn\n"
86 "optprobe_template_restore_orig_insn:\n"
87 " nop\n"
88 ".global optprobe_template_restore_end\n"
89 "optprobe_template_restore_end:\n"
90 " nop\n"
91 ".global optprobe_template_val\n"
92 "optprobe_template_val:\n"
93 "1: .long 0\n"
94 ".global optprobe_template_call\n"
95 "optprobe_template_call:\n"
96 "2: .long 0\n"
97 ".global optprobe_template_end\n"
98 "optprobe_template_end:\n");
99
100#define TMPL_VAL_IDX \
101 ((unsigned long *)&optprobe_template_val - (unsigned long *)&optprobe_template_entry)
102#define TMPL_CALL_IDX \
103 ((unsigned long *)&optprobe_template_call - (unsigned long *)&optprobe_template_entry)
104#define TMPL_END_IDX \
105 ((unsigned long *)&optprobe_template_end - (unsigned long *)&optprobe_template_entry)
106#define TMPL_ADD_SP \
107 ((unsigned long *)&optprobe_template_add_sp - (unsigned long *)&optprobe_template_entry)
108#define TMPL_SUB_SP \
109 ((unsigned long *)&optprobe_template_sub_sp - (unsigned long *)&optprobe_template_entry)
110#define TMPL_RESTORE_BEGIN \
111 ((unsigned long *)&optprobe_template_restore_begin - (unsigned long *)&optprobe_template_entry)
112#define TMPL_RESTORE_ORIGN_INSN \
113 ((unsigned long *)&optprobe_template_restore_orig_insn - (unsigned long *)&optprobe_template_entry)
114#define TMPL_RESTORE_END \
115 ((unsigned long *)&optprobe_template_restore_end - (unsigned long *)&optprobe_template_entry)
116
117/*
118 * ARM can always optimize an instruction when using ARM ISA, except
119 * instructions like 'str r0, [sp, r1]' which store to stack and unable
120 * to determine stack space consumption statically.
121 */
122int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
123{
124 return optinsn->insn != NULL;
125}
126
127/*
128 * In ARM ISA, kprobe opt always replace one instruction (4 bytes
129 * aligned and 4 bytes long). It is impossible to encounter another
130 * kprobe in the address range. So always return 0.
131 */
132int arch_check_optimized_kprobe(struct optimized_kprobe *op)
133{
134 return 0;
135}
136
137/* Caller must ensure addr & 3 == 0 */
138static int can_optimize(struct kprobe *kp)
139{
140 if (kp->ainsn.stack_space < 0)
141 return 0;
142 /*
143 * 255 is the biggest imm can be used in 'sub r0, r0, #<imm>'.
144 * Number larger than 255 needs special encoding.
145 */
146 if (kp->ainsn.stack_space > 255 - sizeof(struct pt_regs))
147 return 0;
148 return 1;
149}
150
151/* Free optimized instruction slot */
152static void
153__arch_remove_optimized_kprobe(struct optimized_kprobe *op, int dirty)
154{
155 if (op->optinsn.insn) {
156 free_optinsn_slot(op->optinsn.insn, dirty);
157 op->optinsn.insn = NULL;
158 }
159}
160
161extern void kprobe_handler(struct pt_regs *regs);
162
163static void
164optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
165{
166 unsigned long flags;
167 struct kprobe *p = &op->kp;
168 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
169
170 /* Save skipped registers */
171 regs->ARM_pc = (unsigned long)op->kp.addr;
172 regs->ARM_ORIG_r0 = ~0UL;
173
174 local_irq_save(flags);
175
176 if (kprobe_running()) {
177 kprobes_inc_nmissed_count(&op->kp);
178 } else {
179 __this_cpu_write(current_kprobe, &op->kp);
180 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
181 opt_pre_handler(&op->kp, regs);
182 __this_cpu_write(current_kprobe, NULL);
183 }
184
185 /*
186 * We singlestep the replaced instruction only when it can't be
187 * executed directly during restore.
188 */
189 if (!p->ainsn.kprobe_direct_exec)
190 op->kp.ainsn.insn_singlestep(p->opcode, &p->ainsn, regs);
191
192 local_irq_restore(flags);
193}
194
195int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
196{
197 kprobe_opcode_t *code;
198 unsigned long rel_chk;
199 unsigned long val;
200 unsigned long stack_protect = sizeof(struct pt_regs);
201
202 if (!can_optimize(orig))
203 return -EILSEQ;
204
205 code = get_optinsn_slot();
206 if (!code)
207 return -ENOMEM;
208
209 /*
210 * Verify if the address gap is in 32MiB range, because this uses
211 * a relative jump.
212 *
213 * kprobe opt use a 'b' instruction to branch to optinsn.insn.
214 * According to ARM manual, branch instruction is:
215 *
216 * 31 28 27 24 23 0
217 * +------+---+---+---+---+----------------+
218 * | cond | 1 | 0 | 1 | 0 | imm24 |
219 * +------+---+---+---+---+----------------+
220 *
221 * imm24 is a signed 24 bits integer. The real branch offset is computed
222 * by: imm32 = SignExtend(imm24:'00', 32);
223 *
224 * So the maximum forward branch should be:
225 * (0x007fffff << 2) = 0x01fffffc = 0x1fffffc
226 * The maximum backword branch should be:
227 * (0xff800000 << 2) = 0xfe000000 = -0x2000000
228 *
229 * We can simply check (rel & 0xfe000003):
230 * if rel is positive, (rel & 0xfe000000) shoule be 0
231 * if rel is negitive, (rel & 0xfe000000) should be 0xfe000000
232 * the last '3' is used for alignment checking.
233 */
234 rel_chk = (unsigned long)((long)code -
235 (long)orig->addr + 8) & 0xfe000003;
236
237 if ((rel_chk != 0) && (rel_chk != 0xfe000000)) {
238 /*
239 * Different from x86, we free code buf directly instead of
240 * calling __arch_remove_optimized_kprobe() because
241 * we have not fill any field in op.
242 */
243 free_optinsn_slot(code, 0);
244 return -ERANGE;
245 }
246
247 /* Copy arch-dep-instance from template. */
248 memcpy(code, &optprobe_template_entry,
249 TMPL_END_IDX * sizeof(kprobe_opcode_t));
250
251 /* Adjust buffer according to instruction. */
252 BUG_ON(orig->ainsn.stack_space < 0);
253
254 stack_protect += orig->ainsn.stack_space;
255
256 /* Should have been filtered by can_optimize(). */
257 BUG_ON(stack_protect > 255);
258
259 /* Create a 'sub sp, sp, #<stack_protect>' */
260 code[TMPL_SUB_SP] = __opcode_to_mem_arm(0xe24dd000 | stack_protect);
261 /* Create a 'add r3, sp, #<stack_protect>' */
262 code[TMPL_ADD_SP] = __opcode_to_mem_arm(0xe28d3000 | stack_protect);
263
264 /* Set probe information */
265 val = (unsigned long)op;
266 code[TMPL_VAL_IDX] = val;
267
268 /* Set probe function call */
269 val = (unsigned long)optimized_callback;
270 code[TMPL_CALL_IDX] = val;
271
272 /* If possible, copy insn and have it executed during restore */
273 orig->ainsn.kprobe_direct_exec = false;
274 if (can_kprobe_direct_exec(orig->ainsn.register_usage_flags)) {
275 kprobe_opcode_t final_branch = arm_gen_branch(
276 (unsigned long)(&code[TMPL_RESTORE_END]),
277 (unsigned long)(op->kp.addr) + 4);
278 if (final_branch != 0) {
279 /*
280 * Replace original 'ldmia sp, {r0 - r15}' with
281 * 'ldmia {r0 - r14}', restore all registers except pc.
282 */
283 code[TMPL_RESTORE_BEGIN] = __opcode_to_mem_arm(0xe89d7fff);
284
285 /* The original probed instruction */
286 code[TMPL_RESTORE_ORIGN_INSN] = __opcode_to_mem_arm(orig->opcode);
287
288 /* Jump back to next instruction */
289 code[TMPL_RESTORE_END] = __opcode_to_mem_arm(final_branch);
290 orig->ainsn.kprobe_direct_exec = true;
291 }
292 }
293
294 flush_icache_range((unsigned long)code,
295 (unsigned long)(&code[TMPL_END_IDX]));
296
297 /* Set op->optinsn.insn means prepared. */
298 op->optinsn.insn = code;
299 return 0;
300}
301
302void __kprobes arch_optimize_kprobes(struct list_head *oplist)
303{
304 struct optimized_kprobe *op, *tmp;
305
306 list_for_each_entry_safe(op, tmp, oplist, list) {
307 unsigned long insn;
308 WARN_ON(kprobe_disabled(&op->kp));
309
310 /*
311 * Backup instructions which will be replaced
312 * by jump address
313 */
314 memcpy(op->optinsn.copied_insn, op->kp.addr,
315 RELATIVEJUMP_SIZE);
316
317 insn = arm_gen_branch((unsigned long)op->kp.addr,
318 (unsigned long)op->optinsn.insn);
319 BUG_ON(insn == 0);
320
321 /*
322 * Make it a conditional branch if replaced insn
323 * is consitional
324 */
325 insn = (__mem_to_opcode_arm(
326 op->optinsn.copied_insn[0]) & 0xf0000000) |
327 (insn & 0x0fffffff);
328
329 /*
330 * Similar to __arch_disarm_kprobe, operations which
331 * removing breakpoints must be wrapped by stop_machine
332 * to avoid racing.
333 */
334 kprobes_remove_breakpoint(op->kp.addr, insn);
335
336 list_del_init(&op->list);
337 }
338}
339
340void arch_unoptimize_kprobe(struct optimized_kprobe *op)
341{
342 arch_arm_kprobe(&op->kp);
343}
344
345/*
346 * Recover original instructions and breakpoints from relative jumps.
347 * Caller must call with locking kprobe_mutex.
348 */
349void arch_unoptimize_kprobes(struct list_head *oplist,
350 struct list_head *done_list)
351{
352 struct optimized_kprobe *op, *tmp;
353
354 list_for_each_entry_safe(op, tmp, oplist, list) {
355 arch_unoptimize_kprobe(op);
356 list_move(&op->list, done_list);
357 }
358}
359
360int arch_within_optimized_kprobe(struct optimized_kprobe *op,
361 unsigned long addr)
362{
363 return ((unsigned long)op->kp.addr <= addr &&
364 (unsigned long)op->kp.addr + RELATIVEJUMP_SIZE > addr);
365}
366
367void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
368{
369 __arch_remove_optimized_kprobe(op, 1);
370}
diff --git a/arch/arm/kernel/kprobes-test-arm.c b/arch/arm/probes/kprobes/test-arm.c
index cb1424240ff6..8866aedfdea2 100644
--- a/arch/arm/kernel/kprobes-test-arm.c
+++ b/arch/arm/probes/kprobes/test-arm.c
@@ -12,8 +12,9 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <asm/system_info.h> 13#include <asm/system_info.h>
14#include <asm/opcodes.h> 14#include <asm/opcodes.h>
15#include <asm/probes.h>
15 16
16#include "kprobes-test.h" 17#include "test-core.h"
17 18
18 19
19#define TEST_ISA "32" 20#define TEST_ISA "32"
@@ -203,9 +204,9 @@ void kprobe_arm_test_cases(void)
203#endif 204#endif
204 TEST_GROUP("Miscellaneous instructions") 205 TEST_GROUP("Miscellaneous instructions")
205 206
206 TEST("mrs r0, cpsr") 207 TEST_RMASKED("mrs r",0,~PSR_IGNORE_BITS,", cpsr")
207 TEST("mrspl r7, cpsr") 208 TEST_RMASKED("mrspl r",7,~PSR_IGNORE_BITS,", cpsr")
208 TEST("mrs r14, cpsr") 209 TEST_RMASKED("mrs r",14,~PSR_IGNORE_BITS,", cpsr")
209 TEST_UNSUPPORTED(__inst_arm(0xe10ff000) " @ mrs r15, cpsr") 210 TEST_UNSUPPORTED(__inst_arm(0xe10ff000) " @ mrs r15, cpsr")
210 TEST_UNSUPPORTED("mrs r0, spsr") 211 TEST_UNSUPPORTED("mrs r0, spsr")
211 TEST_UNSUPPORTED("mrs lr, spsr") 212 TEST_UNSUPPORTED("mrs lr, spsr")
@@ -214,9 +215,12 @@ void kprobe_arm_test_cases(void)
214 TEST_UNSUPPORTED("msr cpsr_f, lr") 215 TEST_UNSUPPORTED("msr cpsr_f, lr")
215 TEST_UNSUPPORTED("msr spsr, r0") 216 TEST_UNSUPPORTED("msr spsr, r0")
216 217
218#if __LINUX_ARM_ARCH__ >= 5 || \
219 (__LINUX_ARM_ARCH__ == 4 && !defined(CONFIG_CPU_32v4))
217 TEST_BF_R("bx r",0,2f,"") 220 TEST_BF_R("bx r",0,2f,"")
218 TEST_BB_R("bx r",7,2f,"") 221 TEST_BB_R("bx r",7,2f,"")
219 TEST_BF_R("bxeq r",14,2f,"") 222 TEST_BF_R("bxeq r",14,2f,"")
223#endif
220 224
221#if __LINUX_ARM_ARCH__ >= 5 225#if __LINUX_ARM_ARCH__ >= 5
222 TEST_R("clz r0, r",0, 0x0,"") 226 TEST_R("clz r0, r",0, 0x0,"")
@@ -476,7 +480,9 @@ void kprobe_arm_test_cases(void)
476 TEST_GROUP("Extra load/store instructions") 480 TEST_GROUP("Extra load/store instructions")
477 481
478 TEST_RPR( "strh r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") 482 TEST_RPR( "strh r",0, VAL1,", [r",1, 48,", -r",2, 24,"]")
479 TEST_RPR( "streqh r",14,VAL2,", [r",13,0, ", r",12, 48,"]") 483 TEST_RPR( "streqh r",14,VAL2,", [r",11,0, ", r",12, 48,"]")
484 TEST_UNSUPPORTED( "streqh r14, [r13, r12]")
485 TEST_UNSUPPORTED( "streqh r14, [r12, r13]")
480 TEST_RPR( "strh r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") 486 TEST_RPR( "strh r",1, VAL1,", [r",2, 24,", r",3, 48,"]!")
481 TEST_RPR( "strneh r",12,VAL2,", [r",11,48,", -r",10,24,"]!") 487 TEST_RPR( "strneh r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
482 TEST_RPR( "strh r",2, VAL1,", [r",3, 24,"], r",4, 48,"") 488 TEST_RPR( "strh r",2, VAL1,", [r",3, 24,"], r",4, 48,"")
@@ -501,6 +507,9 @@ void kprobe_arm_test_cases(void)
501 TEST_RP( "strplh r",12,VAL2,", [r",11,24,", #-4]!") 507 TEST_RP( "strplh r",12,VAL2,", [r",11,24,", #-4]!")
502 TEST_RP( "strh r",2, VAL1,", [r",3, 24,"], #48") 508 TEST_RP( "strh r",2, VAL1,", [r",3, 24,"], #48")
503 TEST_RP( "strh r",10,VAL2,", [r",9, 64,"], #-48") 509 TEST_RP( "strh r",10,VAL2,", [r",9, 64,"], #-48")
510 TEST_RP( "strh r",3, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!")
511 TEST_UNSUPPORTED("strh r3, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!")
512 TEST_RP( "strh r",4, VAL1,", [r",14,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!")
504 TEST_UNSUPPORTED(__inst_arm(0xe1efc3b0) " @ strh r12, [pc, #48]!") 513 TEST_UNSUPPORTED(__inst_arm(0xe1efc3b0) " @ strh r12, [pc, #48]!")
505 TEST_UNSUPPORTED(__inst_arm(0xe0c9f3b0) " @ strh pc, [r9], #48") 514 TEST_UNSUPPORTED(__inst_arm(0xe0c9f3b0) " @ strh pc, [r9], #48")
506 515
@@ -565,7 +574,9 @@ void kprobe_arm_test_cases(void)
565 574
566#if __LINUX_ARM_ARCH__ >= 5 575#if __LINUX_ARM_ARCH__ >= 5
567 TEST_RPR( "strd r",0, VAL1,", [r",1, 48,", -r",2,24,"]") 576 TEST_RPR( "strd r",0, VAL1,", [r",1, 48,", -r",2,24,"]")
568 TEST_RPR( "strccd r",8, VAL2,", [r",13,0, ", r",12,48,"]") 577 TEST_RPR( "strccd r",8, VAL2,", [r",11,0, ", r",12,48,"]")
578 TEST_UNSUPPORTED( "strccd r8, [r13, r12]")
579 TEST_UNSUPPORTED( "strccd r8, [r12, r13]")
569 TEST_RPR( "strd r",4, VAL1,", [r",2, 24,", r",3, 48,"]!") 580 TEST_RPR( "strd r",4, VAL1,", [r",2, 24,", r",3, 48,"]!")
570 TEST_RPR( "strcsd r",12,VAL2,", [r",11,48,", -r",10,24,"]!") 581 TEST_RPR( "strcsd r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
571 TEST_RPR( "strd r",2, VAL1,", [r",5, 24,"], r",4,48,"") 582 TEST_RPR( "strd r",2, VAL1,", [r",5, 24,"], r",4,48,"")
@@ -589,6 +600,9 @@ void kprobe_arm_test_cases(void)
589 TEST_RP( "strvcd r",12,VAL2,", [r",11,24,", #-16]!") 600 TEST_RP( "strvcd r",12,VAL2,", [r",11,24,", #-16]!")
590 TEST_RP( "strd r",2, VAL1,", [r",4, 24,"], #48") 601 TEST_RP( "strd r",2, VAL1,", [r",4, 24,"], #48")
591 TEST_RP( "strd r",10,VAL2,", [r",9, 64,"], #-48") 602 TEST_RP( "strd r",10,VAL2,", [r",9, 64,"], #-48")
603 TEST_RP( "strd r",6, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!")
604 TEST_UNSUPPORTED("strd r6, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!")
605 TEST_RP( "strd r",4, VAL1,", [r",12,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!")
592 TEST_UNSUPPORTED(__inst_arm(0xe1efc3f0) " @ strd r12, [pc, #48]!") 606 TEST_UNSUPPORTED(__inst_arm(0xe1efc3f0) " @ strd r12, [pc, #48]!")
593 607
594 TEST_P( "ldrd r0, [r",0, 24,", #-8]") 608 TEST_P( "ldrd r0, [r",0, 24,", #-8]")
@@ -637,14 +651,20 @@ void kprobe_arm_test_cases(void)
637 TEST_RP( "str"byte" r",12,VAL2,", [r",11,24,", #-4]!") \ 651 TEST_RP( "str"byte" r",12,VAL2,", [r",11,24,", #-4]!") \
638 TEST_RP( "str"byte" r",2, VAL1,", [r",3, 24,"], #48") \ 652 TEST_RP( "str"byte" r",2, VAL1,", [r",3, 24,"], #48") \
639 TEST_RP( "str"byte" r",10,VAL2,", [r",9, 64,"], #-48") \ 653 TEST_RP( "str"byte" r",10,VAL2,", [r",9, 64,"], #-48") \
654 TEST_RP( "str"byte" r",3, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!") \
655 TEST_UNSUPPORTED("str"byte" r3, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!") \
656 TEST_RP( "str"byte" r",4, VAL1,", [r",10,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!") \
640 TEST_RPR("str"byte" r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") \ 657 TEST_RPR("str"byte" r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") \
641 TEST_RPR("str"byte" r",14,VAL2,", [r",13,0, ", r",12, 48,"]") \ 658 TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 48,"]") \
659 TEST_UNSUPPORTED("str"byte" r14, [r13, r12]") \
660 TEST_UNSUPPORTED("str"byte" r14, [r12, r13]") \
642 TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") \ 661 TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") \
643 TEST_RPR("str"byte" r",12,VAL2,", [r",11,48,", -r",10,24,"]!") \ 662 TEST_RPR("str"byte" r",12,VAL2,", [r",11,48,", -r",10,24,"]!") \
644 TEST_RPR("str"byte" r",2, VAL1,", [r",3, 24,"], r",4, 48,"") \ 663 TEST_RPR("str"byte" r",2, VAL1,", [r",3, 24,"], r",4, 48,"") \
645 TEST_RPR("str"byte" r",10,VAL2,", [r",9, 48,"], -r",11,24,"") \ 664 TEST_RPR("str"byte" r",10,VAL2,", [r",9, 48,"], -r",11,24,"") \
646 TEST_RPR("str"byte" r",0, VAL1,", [r",1, 24,", r",2, 32,", asl #1]")\ 665 TEST_RPR("str"byte" r",0, VAL1,", [r",1, 24,", r",2, 32,", asl #1]")\
647 TEST_RPR("str"byte" r",14,VAL2,", [r",13,0, ", r",12, 32,", lsr #2]")\ 666 TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 32,", lsr #2]")\
667 TEST_UNSUPPORTED("str"byte" r14, [r13, r12, lsr #2]") \
648 TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 32,", asr #3]!")\ 668 TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 32,", asr #3]!")\
649 TEST_RPR("str"byte" r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\ 669 TEST_RPR("str"byte" r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\
650 TEST_P( "ldr"byte" r0, [r",0, 24,", #-2]") \ 670 TEST_P( "ldr"byte" r0, [r",0, 24,", #-2]") \
@@ -668,12 +688,12 @@ void kprobe_arm_test_cases(void)
668 688
669 LOAD_STORE("") 689 LOAD_STORE("")
670 TEST_P( "str pc, [r",0,0,", #15*4]") 690 TEST_P( "str pc, [r",0,0,", #15*4]")
671 TEST_R( "str pc, [sp, r",2,15*4,"]") 691 TEST_UNSUPPORTED( "str pc, [sp, r2]")
672 TEST_BF( "ldr pc, [sp, #15*4]") 692 TEST_BF( "ldr pc, [sp, #15*4]")
673 TEST_BF_R("ldr pc, [sp, r",2,15*4,"]") 693 TEST_BF_R("ldr pc, [sp, r",2,15*4,"]")
674 694
675 TEST_P( "str sp, [r",0,0,", #13*4]") 695 TEST_P( "str sp, [r",0,0,", #13*4]")
676 TEST_R( "str sp, [sp, r",2,13*4,"]") 696 TEST_UNSUPPORTED( "str sp, [sp, r2]")
677 TEST_BF( "ldr sp, [sp, #13*4]") 697 TEST_BF( "ldr sp, [sp, #13*4]")
678 TEST_BF_R("ldr sp, [sp, r",2,13*4,"]") 698 TEST_BF_R("ldr sp, [sp, r",2,13*4,"]")
679 699
diff --git a/arch/arm/kernel/kprobes-test.c b/arch/arm/probes/kprobes/test-core.c
index b206d7790c77..9775de22e2ff 100644
--- a/arch/arm/kernel/kprobes-test.c
+++ b/arch/arm/probes/kprobes/test-core.c
@@ -209,10 +209,10 @@
209#include <linux/bug.h> 209#include <linux/bug.h>
210#include <asm/opcodes.h> 210#include <asm/opcodes.h>
211 211
212#include "kprobes.h" 212#include "core.h"
213#include "probes-arm.h" 213#include "test-core.h"
214#include "probes-thumb.h" 214#include "../decode-arm.h"
215#include "kprobes-test.h" 215#include "../decode-thumb.h"
216 216
217 217
218#define BENCHMARKING 1 218#define BENCHMARKING 1
@@ -236,6 +236,8 @@ static int tests_failed;
236 236
237#ifndef CONFIG_THUMB2_KERNEL 237#ifndef CONFIG_THUMB2_KERNEL
238 238
239#define RET(reg) "mov pc, "#reg
240
239long arm_func(long r0, long r1); 241long arm_func(long r0, long r1);
240 242
241static void __used __naked __arm_kprobes_test_func(void) 243static void __used __naked __arm_kprobes_test_func(void)
@@ -245,7 +247,7 @@ static void __used __naked __arm_kprobes_test_func(void)
245 ".type arm_func, %%function \n\t" 247 ".type arm_func, %%function \n\t"
246 "arm_func: \n\t" 248 "arm_func: \n\t"
247 "adds r0, r0, r1 \n\t" 249 "adds r0, r0, r1 \n\t"
248 "bx lr \n\t" 250 "mov pc, lr \n\t"
249 ".code "NORMAL_ISA /* Back to Thumb if necessary */ 251 ".code "NORMAL_ISA /* Back to Thumb if necessary */
250 : : : "r0", "r1", "cc" 252 : : : "r0", "r1", "cc"
251 ); 253 );
@@ -253,6 +255,8 @@ static void __used __naked __arm_kprobes_test_func(void)
253 255
254#else /* CONFIG_THUMB2_KERNEL */ 256#else /* CONFIG_THUMB2_KERNEL */
255 257
258#define RET(reg) "bx "#reg
259
256long thumb16_func(long r0, long r1); 260long thumb16_func(long r0, long r1);
257long thumb32even_func(long r0, long r1); 261long thumb32even_func(long r0, long r1);
258long thumb32odd_func(long r0, long r1); 262long thumb32odd_func(long r0, long r1);
@@ -494,7 +498,7 @@ static void __naked benchmark_nop(void)
494{ 498{
495 __asm__ __volatile__ ( 499 __asm__ __volatile__ (
496 "nop \n\t" 500 "nop \n\t"
497 "bx lr" 501 RET(lr)" \n\t"
498 ); 502 );
499} 503}
500 504
@@ -977,7 +981,7 @@ void __naked __kprobes_test_case_start(void)
977 "bic r0, lr, #1 @ r0 = inline data \n\t" 981 "bic r0, lr, #1 @ r0 = inline data \n\t"
978 "mov r1, sp \n\t" 982 "mov r1, sp \n\t"
979 "bl kprobes_test_case_start \n\t" 983 "bl kprobes_test_case_start \n\t"
980 "bx r0 \n\t" 984 RET(r0)" \n\t"
981 ); 985 );
982} 986}
983 987
@@ -1056,15 +1060,6 @@ static int test_case_run_count;
1056static bool test_case_is_thumb; 1060static bool test_case_is_thumb;
1057static int test_instance; 1061static int test_instance;
1058 1062
1059/*
1060 * We ignore the state of the imprecise abort disable flag (CPSR.A) because this
1061 * can change randomly as the kernel doesn't take care to preserve or initialise
1062 * this across context switches. Also, with Security Extentions, the flag may
1063 * not be under control of the kernel; for this reason we ignore the state of
1064 * the FIQ disable flag CPSR.F as well.
1065 */
1066#define PSR_IGNORE_BITS (PSR_A_BIT | PSR_F_BIT)
1067
1068static unsigned long test_check_cc(int cc, unsigned long cpsr) 1063static unsigned long test_check_cc(int cc, unsigned long cpsr)
1069{ 1064{
1070 int ret = arm_check_condition(cc << 28, cpsr); 1065 int ret = arm_check_condition(cc << 28, cpsr);
@@ -1196,6 +1191,13 @@ static void setup_test_context(struct pt_regs *regs)
1196 regs->uregs[arg->reg] = 1191 regs->uregs[arg->reg] =
1197 (unsigned long)current_stack + arg->val; 1192 (unsigned long)current_stack + arg->val;
1198 memory_needs_checking = true; 1193 memory_needs_checking = true;
1194 /*
1195 * Test memory at an address below SP is in danger of
1196 * being altered by an interrupt occurring and pushing
1197 * data onto the stack. Disable interrupts to stop this.
1198 */
1199 if (arg->reg == 13)
1200 regs->ARM_cpsr |= PSR_I_BIT;
1199 break; 1201 break;
1200 } 1202 }
1201 case ARG_TYPE_MEM: { 1203 case ARG_TYPE_MEM: {
@@ -1264,14 +1266,26 @@ test_case_pre_handler(struct kprobe *p, struct pt_regs *regs)
1264static int __kprobes 1266static int __kprobes
1265test_after_pre_handler(struct kprobe *p, struct pt_regs *regs) 1267test_after_pre_handler(struct kprobe *p, struct pt_regs *regs)
1266{ 1268{
1269 struct test_arg *args;
1270
1267 if (container_of(p, struct test_probe, kprobe)->hit == test_instance) 1271 if (container_of(p, struct test_probe, kprobe)->hit == test_instance)
1268 return 0; /* Already run for this test instance */ 1272 return 0; /* Already run for this test instance */
1269 1273
1270 result_regs = *regs; 1274 result_regs = *regs;
1275
1276 /* Mask out results which are indeterminate */
1271 result_regs.ARM_cpsr &= ~PSR_IGNORE_BITS; 1277 result_regs.ARM_cpsr &= ~PSR_IGNORE_BITS;
1278 for (args = current_args; args[0].type != ARG_TYPE_END; ++args)
1279 if (args[0].type == ARG_TYPE_REG_MASKED) {
1280 struct test_arg_regptr *arg =
1281 (struct test_arg_regptr *)args;
1282 result_regs.uregs[arg->reg] &= arg->val;
1283 }
1272 1284
1273 /* Undo any changes done to SP by the test case */ 1285 /* Undo any changes done to SP by the test case */
1274 regs->ARM_sp = (unsigned long)current_stack; 1286 regs->ARM_sp = (unsigned long)current_stack;
1287 /* Enable interrupts in case setup_test_context disabled them */
1288 regs->ARM_cpsr &= ~PSR_I_BIT;
1275 1289
1276 container_of(p, struct test_probe, kprobe)->hit = test_instance; 1290 container_of(p, struct test_probe, kprobe)->hit = test_instance;
1277 return 0; 1291 return 0;
diff --git a/arch/arm/kernel/kprobes-test.h b/arch/arm/probes/kprobes/test-core.h
index 4430990e90e7..94285203e9f7 100644
--- a/arch/arm/kernel/kprobes-test.h
+++ b/arch/arm/probes/kprobes/test-core.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/kprobes-test.h 2 * arch/arm/probes/kprobes/test-core.h
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -45,10 +45,11 @@ extern int kprobe_test_cc_position;
45 * 45 *
46 */ 46 */
47 47
48#define ARG_TYPE_END 0 48#define ARG_TYPE_END 0
49#define ARG_TYPE_REG 1 49#define ARG_TYPE_REG 1
50#define ARG_TYPE_PTR 2 50#define ARG_TYPE_PTR 2
51#define ARG_TYPE_MEM 3 51#define ARG_TYPE_MEM 3
52#define ARG_TYPE_REG_MASKED 4
52 53
53#define ARG_FLAG_UNSUPPORTED 0x01 54#define ARG_FLAG_UNSUPPORTED 0x01
54#define ARG_FLAG_SUPPORTED 0x02 55#define ARG_FLAG_SUPPORTED 0x02
@@ -61,7 +62,7 @@ struct test_arg {
61}; 62};
62 63
63struct test_arg_regptr { 64struct test_arg_regptr {
64 u8 type; /* ARG_TYPE_REG or ARG_TYPE_PTR */ 65 u8 type; /* ARG_TYPE_REG or ARG_TYPE_PTR or ARG_TYPE_REG_MASKED */
65 u8 reg; 66 u8 reg;
66 u8 _padding[2]; 67 u8 _padding[2];
67 u32 val; 68 u32 val;
@@ -138,6 +139,12 @@ struct test_arg_end {
138 ".short 0 \n\t" \ 139 ".short 0 \n\t" \
139 ".word "#val" \n\t" 140 ".word "#val" \n\t"
140 141
142#define TEST_ARG_REG_MASKED(reg, val) \
143 ".byte "__stringify(ARG_TYPE_REG_MASKED)" \n\t" \
144 ".byte "#reg" \n\t" \
145 ".short 0 \n\t" \
146 ".word "#val" \n\t"
147
141#define TEST_ARG_END(flags) \ 148#define TEST_ARG_END(flags) \
142 ".byte "__stringify(ARG_TYPE_END)" \n\t" \ 149 ".byte "__stringify(ARG_TYPE_END)" \n\t" \
143 ".byte "TEST_ISA flags" \n\t" \ 150 ".byte "TEST_ISA flags" \n\t" \
@@ -395,6 +402,22 @@ struct test_arg_end {
395 " "codex" \n\t" \ 402 " "codex" \n\t" \
396 TESTCASE_END 403 TESTCASE_END
397 404
405#define TEST_RMASKED(code1, reg, mask, code2) \
406 TESTCASE_START(code1 #reg code2) \
407 TEST_ARG_REG_MASKED(reg, mask) \
408 TEST_ARG_END("") \
409 TEST_INSTRUCTION(code1 #reg code2) \
410 TESTCASE_END
411
412/*
413 * We ignore the state of the imprecise abort disable flag (CPSR.A) because this
414 * can change randomly as the kernel doesn't take care to preserve or initialise
415 * this across context switches. Also, with Security Extensions, the flag may
416 * not be under control of the kernel; for this reason we ignore the state of
417 * the FIQ disable flag CPSR.F as well.
418 */
419#define PSR_IGNORE_BITS (PSR_A_BIT | PSR_F_BIT)
420
398 421
399/* 422/*
400 * Macros for defining space directives spread over multiple lines. 423 * Macros for defining space directives spread over multiple lines.
diff --git a/arch/arm/kernel/kprobes-test-thumb.c b/arch/arm/probes/kprobes/test-thumb.c
index 844dd10d8593..b683b4517458 100644
--- a/arch/arm/kernel/kprobes-test-thumb.c
+++ b/arch/arm/probes/kprobes/test-thumb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/kernel/kprobes-test-thumb.c 2 * arch/arm/probes/kprobes/test-thumb.c
3 * 3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. 4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 * 5 *
@@ -11,8 +11,9 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <asm/opcodes.h> 13#include <asm/opcodes.h>
14#include <asm/probes.h>
14 15
15#include "kprobes-test.h" 16#include "test-core.h"
16 17
17 18
18#define TEST_ISA "16" 19#define TEST_ISA "16"
@@ -416,6 +417,9 @@ void kprobe_thumb32_test_cases(void)
416 TEST_RR( "strd r",14,VAL2,", r",12,VAL1,", [sp, #16]!") 417 TEST_RR( "strd r",14,VAL2,", r",12,VAL1,", [sp, #16]!")
417 TEST_RRP("strd r",1, VAL1,", r",0, VAL2,", [r",7, 24,"], #16") 418 TEST_RRP("strd r",1, VAL1,", r",0, VAL2,", [r",7, 24,"], #16")
418 TEST_RR( "strd r",7, VAL2,", r",8, VAL1,", [sp], #-16") 419 TEST_RR( "strd r",7, VAL2,", r",8, VAL1,", [sp], #-16")
420 TEST_RRP("strd r",6, VAL1,", r",7, VAL2,", [r",13, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!")
421 TEST_UNSUPPORTED("strd r6, r7, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!")
422 TEST_RRP("strd r",4, VAL1,", r",5, VAL2,", [r",14, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!")
419 TEST_UNSUPPORTED(__inst_thumb32(0xe9efec04) " @ strd r14, r12, [pc, #16]!") 423 TEST_UNSUPPORTED(__inst_thumb32(0xe9efec04) " @ strd r14, r12, [pc, #16]!")
420 TEST_UNSUPPORTED(__inst_thumb32(0xe8efec04) " @ strd r14, r12, [pc], #16") 424 TEST_UNSUPPORTED(__inst_thumb32(0xe8efec04) " @ strd r14, r12, [pc], #16")
421 425
@@ -774,8 +778,8 @@ CONDITION_INSTRUCTIONS(22,
774 778
775 TEST_UNSUPPORTED("subs pc, lr, #4") 779 TEST_UNSUPPORTED("subs pc, lr, #4")
776 780
777 TEST("mrs r0, cpsr") 781 TEST_RMASKED("mrs r",0,~PSR_IGNORE_BITS,", cpsr")
778 TEST("mrs r14, cpsr") 782 TEST_RMASKED("mrs r",14,~PSR_IGNORE_BITS,", cpsr")
779 TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8d00) " @ mrs sp, spsr") 783 TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8d00) " @ mrs sp, spsr")
780 TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8f00) " @ mrs pc, spsr") 784 TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8f00) " @ mrs pc, spsr")
781 TEST_UNSUPPORTED("mrs r0, spsr") 785 TEST_UNSUPPORTED("mrs r0, spsr")
@@ -821,14 +825,22 @@ CONDITION_INSTRUCTIONS(22,
821 TEST_RP( "str"size" r",14,VAL2,", [r",1, 256, ", #-128]!") \ 825 TEST_RP( "str"size" r",14,VAL2,", [r",1, 256, ", #-128]!") \
822 TEST_RPR("str"size".w r",0, VAL1,", [r",1, 0,", r",2, 4,"]") \ 826 TEST_RPR("str"size".w r",0, VAL1,", [r",1, 0,", r",2, 4,"]") \
823 TEST_RPR("str"size" r",14,VAL2,", [r",10,0,", r",11,4,", lsl #1]") \ 827 TEST_RPR("str"size" r",14,VAL2,", [r",10,0,", r",11,4,", lsl #1]") \
828 TEST_UNSUPPORTED("str"size" r0, [r13, r1]") \
824 TEST_R( "str"size".w r",7, VAL1,", [sp, #24]") \ 829 TEST_R( "str"size".w r",7, VAL1,", [sp, #24]") \
825 TEST_RP( "str"size".w r",0, VAL2,", [r",0,0, "]") \ 830 TEST_RP( "str"size".w r",0, VAL2,", [r",0,0, "]") \
831 TEST_RP( "str"size" r",6, VAL1,", [r",13, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!") \
832 TEST_UNSUPPORTED("str"size" r6, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!") \
833 TEST_RP( "str"size" r",4, VAL2,", [r",12, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!") \
826 TEST_UNSUPPORTED("str"size"t r0, [r1, #4]") 834 TEST_UNSUPPORTED("str"size"t r0, [r1, #4]")
827 835
828 SINGLE_STORE("b") 836 SINGLE_STORE("b")
829 SINGLE_STORE("h") 837 SINGLE_STORE("h")
830 SINGLE_STORE("") 838 SINGLE_STORE("")
831 839
840 TEST_UNSUPPORTED(__inst_thumb32(0xf801000d) " @ strb r0, [r1, r13]")
841 TEST_UNSUPPORTED(__inst_thumb32(0xf821000d) " @ strh r0, [r1, r13]")
842 TEST_UNSUPPORTED(__inst_thumb32(0xf841000d) " @ str r0, [r1, r13]")
843
832 TEST("str sp, [sp]") 844 TEST("str sp, [sp]")
833 TEST_UNSUPPORTED(__inst_thumb32(0xf8cfe000) " @ str r14, [pc]") 845 TEST_UNSUPPORTED(__inst_thumb32(0xf8cfe000) " @ str r14, [pc]")
834 TEST_UNSUPPORTED(__inst_thumb32(0xf8cef000) " @ str pc, [r14]") 846 TEST_UNSUPPORTED(__inst_thumb32(0xf8cef000) " @ str pc, [r14]")
diff --git a/arch/arm/probes/uprobes/Makefile b/arch/arm/probes/uprobes/Makefile
new file mode 100644
index 000000000000..e1dc3d0f6d5a
--- /dev/null
+++ b/arch/arm/probes/uprobes/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_UPROBES) += core.o actions-arm.o
diff --git a/arch/arm/kernel/uprobes-arm.c b/arch/arm/probes/uprobes/actions-arm.c
index d3b655ff17da..76eb44972ebe 100644
--- a/arch/arm/kernel/uprobes-arm.c
+++ b/arch/arm/probes/uprobes/actions-arm.c
@@ -13,9 +13,9 @@
13#include <linux/uprobes.h> 13#include <linux/uprobes.h>
14#include <linux/module.h> 14#include <linux/module.h>
15 15
16#include "probes.h" 16#include "../decode.h"
17#include "probes-arm.h" 17#include "../decode-arm.h"
18#include "uprobes.h" 18#include "core.h"
19 19
20static int uprobes_substitute_pc(unsigned long *pinsn, u32 oregs) 20static int uprobes_substitute_pc(unsigned long *pinsn, u32 oregs)
21{ 21{
@@ -195,8 +195,6 @@ uprobe_decode_ldmstm(probes_opcode_t insn,
195} 195}
196 196
197const union decode_action uprobes_probes_actions[] = { 197const union decode_action uprobes_probes_actions[] = {
198 [PROBES_EMULATE_NONE] = {.handler = probes_simulate_nop},
199 [PROBES_SIMULATE_NOP] = {.handler = probes_simulate_nop},
200 [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop}, 198 [PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
201 [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop}, 199 [PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
202 [PROBES_BRANCH_IMM] = {.handler = simulate_blx1}, 200 [PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
diff --git a/arch/arm/kernel/uprobes.c b/arch/arm/probes/uprobes/core.c
index 56adf9c1fde0..d1329f1ba4e4 100644
--- a/arch/arm/kernel/uprobes.c
+++ b/arch/arm/probes/uprobes/core.c
@@ -17,9 +17,9 @@
17#include <asm/opcodes.h> 17#include <asm/opcodes.h>
18#include <asm/traps.h> 18#include <asm/traps.h>
19 19
20#include "probes.h" 20#include "../decode.h"
21#include "probes-arm.h" 21#include "../decode-arm.h"
22#include "uprobes.h" 22#include "core.h"
23 23
24#define UPROBE_TRAP_NR UINT_MAX 24#define UPROBE_TRAP_NR UINT_MAX
25 25
@@ -88,7 +88,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
88 auprobe->ixol[1] = __opcode_to_mem_arm(UPROBE_SS_ARM_INSN); 88 auprobe->ixol[1] = __opcode_to_mem_arm(UPROBE_SS_ARM_INSN);
89 89
90 ret = arm_probes_decode_insn(insn, &auprobe->asi, false, 90 ret = arm_probes_decode_insn(insn, &auprobe->asi, false,
91 uprobes_probes_actions); 91 uprobes_probes_actions, NULL);
92 switch (ret) { 92 switch (ret) {
93 case INSN_REJECTED: 93 case INSN_REJECTED:
94 return -EINVAL; 94 return -EINVAL;
diff --git a/arch/arm/kernel/uprobes.h b/arch/arm/probes/uprobes/core.h
index 1d0c12dfbd03..1d0c12dfbd03 100644
--- a/arch/arm/kernel/uprobes.h
+++ b/arch/arm/probes/uprobes/core.h
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index d3f7e4941231..2814304cec04 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -39,6 +39,7 @@ config ARM64
39 select HARDIRQS_SW_RESEND 39 select HARDIRQS_SW_RESEND
40 select HAVE_ALIGNED_STRUCT_PAGE if SLUB 40 select HAVE_ALIGNED_STRUCT_PAGE if SLUB
41 select HAVE_ARCH_AUDITSYSCALL 41 select HAVE_ARCH_AUDITSYSCALL
42 select HAVE_ARCH_BITREVERSE
42 select HAVE_ARCH_JUMP_LABEL 43 select HAVE_ARCH_JUMP_LABEL
43 select HAVE_ARCH_KGDB 44 select HAVE_ARCH_KGDB
44 select HAVE_ARCH_SECCOMP_FILTER 45 select HAVE_ARCH_SECCOMP_FILTER
diff --git a/arch/arm64/include/asm/bitrev.h b/arch/arm64/include/asm/bitrev.h
new file mode 100644
index 000000000000..a5a0c3660137
--- /dev/null
+++ b/arch/arm64/include/asm/bitrev.h
@@ -0,0 +1,19 @@
1#ifndef __ASM_BITREV_H
2#define __ASM_BITREV_H
3static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
4{
5 __asm__ ("rbit %w0, %w1" : "=r" (x) : "r" (x));
6 return x;
7}
8
9static __always_inline __attribute_const__ u16 __arch_bitrev16(u16 x)
10{
11 return __arch_bitrev32((u32)x) >> 16;
12}
13
14static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x)
15{
16 return __arch_bitrev32((u32)x) >> 24;
17}
18
19#endif
diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
index 7c523bbf3dc8..0dd8d089c315 100644
--- a/arch/x86/kernel/kprobes/opt.c
+++ b/arch/x86/kernel/kprobes/opt.c
@@ -322,7 +322,8 @@ void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
322 * Target instructions MUST be relocatable (checked inside) 322 * Target instructions MUST be relocatable (checked inside)
323 * This is called when new aggr(opt)probe is allocated or reused. 323 * This is called when new aggr(opt)probe is allocated or reused.
324 */ 324 */
325int arch_prepare_optimized_kprobe(struct optimized_kprobe *op) 325int arch_prepare_optimized_kprobe(struct optimized_kprobe *op,
326 struct kprobe *__unused)
326{ 327{
327 u8 *buf; 328 u8 *buf;
328 int ret; 329 int ret;