diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/probes/kprobes/test-arm.c | 6 | ||||
-rw-r--r-- | arch/arm/probes/kprobes/test-core.c | 19 | ||||
-rw-r--r-- | arch/arm/probes/kprobes/test-core.h | 33 | ||||
-rw-r--r-- | arch/arm/probes/kprobes/test-thumb.c | 4 |
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; | |||
1056 | static bool test_case_is_thumb; | 1056 | static bool test_case_is_thumb; |
1057 | static int test_instance; | 1057 | static 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 | |||
1068 | static unsigned long test_check_cc(int cc, unsigned long cpsr) | 1059 | static 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) | |||
1271 | static int __kprobes | 1262 | static int __kprobes |
1272 | test_after_pre_handler(struct kprobe *p, struct pt_regs *regs) | 1263 | test_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 | ||
63 | struct test_arg_regptr { | 64 | struct 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") |