aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/Makefile2
-rw-r--r--arch/arm/kernel/kprobes-arm.c92
-rw-r--r--arch/arm/kernel/kprobes-common.c105
-rw-r--r--arch/arm/kernel/kprobes.h2
4 files changed, 109 insertions, 92 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 914c7a6f1706..a22b8f1c7b14 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -37,7 +37,7 @@ obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
37obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 37obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
38obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 38obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
39obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 39obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
40obj-$(CONFIG_KPROBES) += kprobes.o 40obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o
41obj-$(CONFIG_KPROBES) += kprobes-arm.o 41obj-$(CONFIG_KPROBES) += kprobes-arm.o
42obj-$(CONFIG_ATAGS_PROC) += atags.o 42obj-$(CONFIG_ATAGS_PROC) += atags.o
43obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o 43obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c
index 976ce14c5576..8d4464f9471b 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/kernel/kprobes-arm.c
@@ -1523,96 +1523,6 @@ space_cccc_11xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1523 return INSN_REJECTED; 1523 return INSN_REJECTED;
1524} 1524}
1525 1525
1526static unsigned long __kprobes __check_eq(unsigned long cpsr)
1527{
1528 return cpsr & PSR_Z_BIT;
1529}
1530
1531static unsigned long __kprobes __check_ne(unsigned long cpsr)
1532{
1533 return (~cpsr) & PSR_Z_BIT;
1534}
1535
1536static unsigned long __kprobes __check_cs(unsigned long cpsr)
1537{
1538 return cpsr & PSR_C_BIT;
1539}
1540
1541static unsigned long __kprobes __check_cc(unsigned long cpsr)
1542{
1543 return (~cpsr) & PSR_C_BIT;
1544}
1545
1546static unsigned long __kprobes __check_mi(unsigned long cpsr)
1547{
1548 return cpsr & PSR_N_BIT;
1549}
1550
1551static unsigned long __kprobes __check_pl(unsigned long cpsr)
1552{
1553 return (~cpsr) & PSR_N_BIT;
1554}
1555
1556static unsigned long __kprobes __check_vs(unsigned long cpsr)
1557{
1558 return cpsr & PSR_V_BIT;
1559}
1560
1561static unsigned long __kprobes __check_vc(unsigned long cpsr)
1562{
1563 return (~cpsr) & PSR_V_BIT;
1564}
1565
1566static unsigned long __kprobes __check_hi(unsigned long cpsr)
1567{
1568 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
1569 return cpsr & PSR_C_BIT;
1570}
1571
1572static unsigned long __kprobes __check_ls(unsigned long cpsr)
1573{
1574 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
1575 return (~cpsr) & PSR_C_BIT;
1576}
1577
1578static unsigned long __kprobes __check_ge(unsigned long cpsr)
1579{
1580 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
1581 return (~cpsr) & PSR_N_BIT;
1582}
1583
1584static unsigned long __kprobes __check_lt(unsigned long cpsr)
1585{
1586 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
1587 return cpsr & PSR_N_BIT;
1588}
1589
1590static unsigned long __kprobes __check_gt(unsigned long cpsr)
1591{
1592 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
1593 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
1594 return (~temp) & PSR_N_BIT;
1595}
1596
1597static unsigned long __kprobes __check_le(unsigned long cpsr)
1598{
1599 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
1600 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
1601 return temp & PSR_N_BIT;
1602}
1603
1604static unsigned long __kprobes __check_al(unsigned long cpsr)
1605{
1606 return true;
1607}
1608
1609static kprobe_check_cc * const condition_checks[16] = {
1610 &__check_eq, &__check_ne, &__check_cs, &__check_cc,
1611 &__check_mi, &__check_pl, &__check_vs, &__check_vc,
1612 &__check_hi, &__check_ls, &__check_ge, &__check_lt,
1613 &__check_gt, &__check_le, &__check_al, &__check_al
1614};
1615
1616/* Return: 1526/* Return:
1617 * INSN_REJECTED If instruction is one not allowed to kprobe, 1527 * INSN_REJECTED If instruction is one not allowed to kprobe,
1618 * INSN_GOOD If instruction is supported and uses instruction slot, 1528 * INSN_GOOD If instruction is supported and uses instruction slot,
@@ -1628,7 +1538,7 @@ static kprobe_check_cc * const condition_checks[16] = {
1628enum kprobe_insn __kprobes 1538enum kprobe_insn __kprobes
1629arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1539arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1630{ 1540{
1631 asi->insn_check_cc = condition_checks[insn>>28]; 1541 asi->insn_check_cc = kprobe_condition_checks[insn>>28];
1632 asi->insn[1] = KPROBE_RETURN_INSTRUCTION; 1542 asi->insn[1] = KPROBE_RETURN_INSTRUCTION;
1633 1543
1634 if ((insn & 0xf0000000) == 0xf0000000) 1544 if ((insn & 0xf0000000) == 0xf0000000)
diff --git a/arch/arm/kernel/kprobes-common.c b/arch/arm/kernel/kprobes-common.c
new file mode 100644
index 000000000000..794827ec27d7
--- /dev/null
+++ b/arch/arm/kernel/kprobes-common.c
@@ -0,0 +1,105 @@
1/*
2 * arch/arm/kernel/kprobes-common.c
3 *
4 * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/kernel.h>
12#include <linux/kprobes.h>
13
14#include "kprobes.h"
15
16
17static unsigned long __kprobes __check_eq(unsigned long cpsr)
18{
19 return cpsr & PSR_Z_BIT;
20}
21
22static unsigned long __kprobes __check_ne(unsigned long cpsr)
23{
24 return (~cpsr) & PSR_Z_BIT;
25}
26
27static unsigned long __kprobes __check_cs(unsigned long cpsr)
28{
29 return cpsr & PSR_C_BIT;
30}
31
32static unsigned long __kprobes __check_cc(unsigned long cpsr)
33{
34 return (~cpsr) & PSR_C_BIT;
35}
36
37static unsigned long __kprobes __check_mi(unsigned long cpsr)
38{
39 return cpsr & PSR_N_BIT;
40}
41
42static unsigned long __kprobes __check_pl(unsigned long cpsr)
43{
44 return (~cpsr) & PSR_N_BIT;
45}
46
47static unsigned long __kprobes __check_vs(unsigned long cpsr)
48{
49 return cpsr & PSR_V_BIT;
50}
51
52static unsigned long __kprobes __check_vc(unsigned long cpsr)
53{
54 return (~cpsr) & PSR_V_BIT;
55}
56
57static unsigned long __kprobes __check_hi(unsigned long cpsr)
58{
59 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
60 return cpsr & PSR_C_BIT;
61}
62
63static unsigned long __kprobes __check_ls(unsigned long cpsr)
64{
65 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
66 return (~cpsr) & PSR_C_BIT;
67}
68
69static unsigned long __kprobes __check_ge(unsigned long cpsr)
70{
71 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
72 return (~cpsr) & PSR_N_BIT;
73}
74
75static unsigned long __kprobes __check_lt(unsigned long cpsr)
76{
77 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
78 return cpsr & PSR_N_BIT;
79}
80
81static unsigned long __kprobes __check_gt(unsigned long cpsr)
82{
83 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
84 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
85 return (~temp) & PSR_N_BIT;
86}
87
88static unsigned long __kprobes __check_le(unsigned long cpsr)
89{
90 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
91 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
92 return temp & PSR_N_BIT;
93}
94
95static unsigned long __kprobes __check_al(unsigned long cpsr)
96{
97 return true;
98}
99
100kprobe_check_cc * const kprobe_condition_checks[16] = {
101 &__check_eq, &__check_ne, &__check_cs, &__check_cc,
102 &__check_mi, &__check_pl, &__check_vs, &__check_vc,
103 &__check_hi, &__check_ls, &__check_ge, &__check_lt,
104 &__check_gt, &__check_le, &__check_al, &__check_al
105};
diff --git a/arch/arm/kernel/kprobes.h b/arch/arm/kernel/kprobes.h
index 87a5241b2f18..792f2316227a 100644
--- a/arch/arm/kernel/kprobes.h
+++ b/arch/arm/kernel/kprobes.h
@@ -34,4 +34,6 @@ enum kprobe_insn arm_kprobe_decode_insn(kprobe_opcode_t,
34 34
35void __init arm_kprobe_decode_init(void); 35void __init arm_kprobe_decode_init(void);
36 36
37extern kprobe_check_cc * const kprobe_condition_checks[16];
38
37#endif /* _ARM_KERNEL_KPROBES_H */ 39#endif /* _ARM_KERNEL_KPROBES_H */