summaryrefslogtreecommitdiff
path: root/arch/arm/probes/kprobes/test-core.c
diff options
context:
space:
mode:
authorJon Medhurst (Tixy) <tixy@linaro.org>2015-01-05 19:29:40 +0800
committerJon Medhurst <tixy@linaro.org>2015-01-13 16:10:17 +0000
commit4cd872d973c7e1ce6a41e36db9d9352152da32d4 (patch)
tree9418dd882418266bcbd60e0d7d757615b02ac6d0 /arch/arm/probes/kprobes/test-core.c
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/arm/probes/kprobes/test-core.c')
-rw-r--r--arch/arm/probes/kprobes/test-core.c19
1 files changed, 10 insertions, 9 deletions
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;
static bool test_case_is_thumb;
static int test_instance;
-/*
- * We ignore the state of the imprecise abort disable flag (CPSR.A) because this
- * can change randomly as the kernel doesn't take care to preserve or initialise
- * this across context switches. Also, with Security Extentions, the flag may
- * not be under control of the kernel; for this reason we ignore the state of
- * the FIQ disable flag CPSR.F as well.
- */
-#define PSR_IGNORE_BITS (PSR_A_BIT | PSR_F_BIT)
-
static unsigned long test_check_cc(int cc, unsigned long cpsr)
{
int ret = arm_check_condition(cc << 28, cpsr);
@@ -1271,11 +1262,21 @@ test_case_pre_handler(struct kprobe *p, struct pt_regs *regs)
static int __kprobes
test_after_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
+ struct test_arg *args;
+
if (container_of(p, struct test_probe, kprobe)->hit == test_instance)
return 0; /* Already run for this test instance */
result_regs = *regs;
+
+ /* Mask out results which are indeterminate */
result_regs.ARM_cpsr &= ~PSR_IGNORE_BITS;
+ for (args = current_args; args[0].type != ARG_TYPE_END; ++args)
+ if (args[0].type == ARG_TYPE_REG_MASKED) {
+ struct test_arg_regptr *arg =
+ (struct test_arg_regptr *)args;
+ result_regs.uregs[arg->reg] &= arg->val;
+ }
/* Undo any changes done to SP by the test case */
regs->ARM_sp = (unsigned long)current_stack;