diff options
Diffstat (limited to 'arch/arm/kernel/swp_emulate.c')
| -rw-r--r-- | arch/arm/kernel/swp_emulate.c | 16 | 
1 files changed, 16 insertions, 0 deletions
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c index 5f452f8fde0..df745188f5d 100644 --- a/arch/arm/kernel/swp_emulate.c +++ b/arch/arm/kernel/swp_emulate.c @@ -25,6 +25,7 @@  #include <linux/syscalls.h>  #include <linux/perf_event.h> +#include <asm/opcodes.h>  #include <asm/traps.h>  #include <asm/uaccess.h> @@ -185,6 +186,21 @@ static int swp_handler(struct pt_regs *regs, unsigned int instr)  	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->ARM_pc); +	res = arm_check_condition(instr, regs->ARM_cpsr); +	switch (res) { +	case ARM_OPCODE_CONDTEST_PASS: +		break; +	case ARM_OPCODE_CONDTEST_FAIL: +		/* Condition failed - return to next instruction */ +		regs->ARM_pc += 4; +		return 0; +	case ARM_OPCODE_CONDTEST_UNCOND: +		/* If unconditional encoding - not a SWP, undef */ +		return -EFAULT; +	default: +		return -EINVAL; +	} +  	if (current->pid != previous_pid) {  		pr_debug("\"%s\" (%ld) uses deprecated SWP{B} instruction\n",  			 current->comm, (unsigned long)current->pid);  |