aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJon Medhurst (Tixy) <tixy@linaro.org>2015-01-05 06:29:40 -0500
committerJon Medhurst <tixy@linaro.org>2015-01-13 11:10:17 -0500
commit4cd872d973c7e1ce6a41e36db9d9352152da32d4 (patch)
tree9418dd882418266bcbd60e0d7d757615b02ac6d0 /arch
parent0dc016dbd820260b8ea74337980735b8c88d4ef2 (diff)
ARM: kprobes: Fix unreliable MRS instruction tests
For the instruction 'mrs Rn, cpsr' the resulting value of Rn can vary due to external factors we can't control. So get the test code to mask out these indeterminate bits. Signed-off-by: Jon Medhurst <tixy@linaro.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/probes/kprobes/test-arm.c6
-rw-r--r--arch/arm/probes/kprobes/test-core.c19
-rw-r--r--arch/arm/probes/kprobes/test-core.h33
-rw-r--r--arch/arm/probes/kprobes/test-thumb.c4
4 files changed, 43 insertions, 19 deletions
diff --git a/arch/arm/probes/kprobes/test-arm.c b/arch/arm/probes/kprobes/test-arm.c
index 9b3b1b4a0939..e72b07e8cd9a 100644
--- a/arch/arm/probes/kprobes/test-arm.c
+++ b/arch/arm/probes/kprobes/test-arm.c
@@ -204,9 +204,9 @@ void kprobe_arm_test_cases(void)
204#endif 204#endif
205 TEST_GROUP("Miscellaneous instructions") 205 TEST_GROUP("Miscellaneous instructions")
206 206
207 TEST("mrs r0, cpsr") 207 TEST_RMASKED("mrs r",0,~PSR_IGNORE_BITS,", cpsr")
208 TEST("mrspl r7, cpsr") 208 TEST_RMASKED("mrspl r",7,~PSR_IGNORE_BITS,", cpsr")
209 TEST("mrs r14, cpsr") 209 TEST_RMASKED("mrs r",14,~PSR_IGNORE_BITS,", cpsr")
210 TEST_UNSUPPORTED(__inst_arm(0xe10ff000) " @ mrs r15, cpsr") 210 TEST_UNSUPPORTED(__inst_arm(0xe10ff000) " @ mrs r15, cpsr")
211 TEST_UNSUPPORTED("mrs r0, spsr") 211 TEST_UNSUPPORTED("mrs r0, spsr")
212 TEST_UNSUPPORTED("mrs lr, spsr") 212 TEST_UNSUPPORTED("mrs lr, spsr")
diff --git a/arch/arm/probes/kprobes/test-core.c b/arch/arm/probes/kprobes/test-core.c
index 7c5ddd5a6afd..e495127d7571 100644
--- a/arch/arm/probes/kprobes/test-core.c
+++ b/arch/arm/probes/kprobes/test-core.c
@@ -1056,15 +1056,6 @@ static int test_case_run_count;
1056static bool test_case_is_thumb; 1056static bool test_case_is_thumb;
1057static int test_instance; 1057static int test_instance;
1058 1058
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) 1059static unsigned long test_check_cc(int cc, unsigned long cpsr)
1069{ 1060{
1070 int ret = arm_check_condition(cc << 28, cpsr); 1061 int ret = arm_check_condition(cc << 28, cpsr);
@@ -1271,11 +1262,21 @@ test_case_pre_handler(struct kprobe *p, struct pt_regs *regs)
1271static int __kprobes 1262static int __kprobes
1272test_after_pre_handler(struct kprobe *p, struct pt_regs *regs) 1263test_after_pre_handler(struct kprobe *p, struct pt_regs *regs)
1273{ 1264{
1265 struct test_arg *args;
1266
1274 if (container_of(p, struct test_probe, kprobe)->hit == test_instance) 1267 if (container_of(p, struct test_probe, kprobe)->hit == test_instance)
1275 return 0; /* Already run for this test instance */ 1268 return 0; /* Already run for this test instance */
1276 1269
1277 result_regs = *regs; 1270 result_regs = *regs;
1271
1272 /* Mask out results which are indeterminate */
1278 result_regs.ARM_cpsr &= ~PSR_IGNORE_BITS; 1273 result_regs.ARM_cpsr &= ~PSR_IGNORE_BITS;
1274 for (args = current_args; args[0].type != ARG_TYPE_END; ++args)
1275 if (args[0].type == ARG_TYPE_REG_MASKED) {
1276 struct test_arg_regptr *arg =
1277 (struct test_arg_regptr *)args;
1278 result_regs.uregs[arg->reg] &= arg->val;
1279 }
1279 1280
1280 /* Undo any changes done to SP by the test case */ 1281 /* Undo any changes done to SP by the test case */
1281 regs->ARM_sp = (unsigned long)current_stack; 1282 regs->ARM_sp = (unsigned long)current_stack;
diff --git a/arch/arm/probes/kprobes/test-core.h b/arch/arm/probes/kprobes/test-core.h
index 9991754947bc..94285203e9f7 100644
--- a/arch/arm/probes/kprobes/test-core.h
+++ b/arch/arm/probes/kprobes/test-core.h
@@ -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/probes/kprobes/test-thumb.c b/arch/arm/probes/kprobes/test-thumb.c
index e8cf193db1ea..b683b4517458 100644
--- a/arch/arm/probes/kprobes/test-thumb.c
+++ b/arch/arm/probes/kprobes/test-thumb.c
@@ -778,8 +778,8 @@ CONDITION_INSTRUCTIONS(22,
778 778
779 TEST_UNSUPPORTED("subs pc, lr, #4") 779 TEST_UNSUPPORTED("subs pc, lr, #4")
780 780
781 TEST("mrs r0, cpsr") 781 TEST_RMASKED("mrs r",0,~PSR_IGNORE_BITS,", cpsr")
782 TEST("mrs r14, cpsr") 782 TEST_RMASKED("mrs r",14,~PSR_IGNORE_BITS,", cpsr")
783 TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8d00) " @ mrs sp, spsr") 783 TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8d00) " @ mrs sp, spsr")
784 TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8f00) " @ mrs pc, spsr") 784 TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8f00) " @ mrs pc, spsr")
785 TEST_UNSUPPORTED("mrs r0, spsr") 785 TEST_UNSUPPORTED("mrs r0, spsr")