Add generic ARM ISA condition code check
cover Add generic ARM ISA condition code check
There are several locations in the kernel where software needs to inspect the condition codes of trapped instructions. The original bitmask implementation in the nwfpe code does this in an efficient manner. This series breaks this code out of nwfpe/fpopcode.{ch} into a standalone file for opcode operations, and contains additional patches to kprobes and SWP eumlation to use this interface.
---
Reworked based on feedback on RFC set submitted on 2011-11-25.
Leif Lindholm (4):
Add generic ARM instruction set condition code checks. Use generic ARM instruction set condition code checks for nwfpe. Add condition code checking to SWP emulation handler. Use generic ARM instruction set condition code checks for kprobes.
arch/arm/include/asm/opcodes.h | 20 ++++++++++++ arch/arm/kernel/Makefile | 2 + arch/arm/kernel/kprobes-test.c | 66 +++----------------------------------- arch/arm/kernel/opcodes.c | 69 ++++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/swp_emulate.c | 12 +++++++ arch/arm/nwfpe/entry.S | 8 +++-- arch/arm/nwfpe/fpopcode.c | 26 --------------- arch/arm/nwfpe/fpopcode.h | 3 -- 8 files changed, 113 insertions(+), 93 deletions(-) create mode 100644 arch/arm/include/asm/opcodes.h create mode 100644 arch/arm/kernel/opcodes.c
Signature · 1 line
Signature
PATCH 1/4 Add generic ARM instruction set condition code checks.
This patch breaks the ARM condition checking code out of nwfpe/fpopcode.{ch} into a standalone file for opcode operations. It also modifies the code somewhat for coding style adherence, and adds some temporary variables for increased readability.
--- arch/arm/include/asm/opcodes.h | 20 ++++++++++++ arch/arm/kernel/Makefile | 2 + arch/arm/kernel/opcodes.c | 69 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletions(-) create mode 100644 arch/arm/include/asm/opcodes.h create mode 100644 arch/arm/kernel/opcodes.c
arch/arm/include/asm/opcodes.h new file +20 -0
@@ -0,0 +1,20 @@ +/* +* arch/arm/include/asm/opcodes.h +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARM_OPCODES_H +#define __ASM_ARM_OPCODES_H + +#ifndef __ASSEMBLY__ +extern unsigned int arm_check_condition (unsigned int opcode,unsigned int psr); +#endif + +#define ARM_OPCODE_CONDTEST_FAIL 0 +#define ARM_OPCODE_CONDTEST_PASS 1 +#define ARM_OPCODE_CONDTEST_UNCOND 2 + +#endif /* __ASM_ARM_OPCODES_H */
arch/arm/kernel/Makefile +1 -1
@@ -13,7 +13,7 @@ CFLAGS_REMOVE_return_address.o = -pg # Object file lists. -obj-y := elf.o entry-armv.o entry-common.o irq.o \ +obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \ process.o ptrace.o return_address.o setup.o signal.o \ sys_arm.o stacktrace.o time.o traps.o
arch/arm/kernel/opcodes.c new file +69 -0
69 lines not on this page · raw message
PATCH 1/4 Add generic ARM instruction set condition code checks.
Hi Leif,
This looks largely there, but I have some small comments inline.
Quoted 10 lines · Leif Lindholm
arch/arm/include/asm/opcodes.h new file +4
-0@@ -0,0 +1,20 @@ +/* +* arch/arm/include/asm/opcodes.h +* +* This program is free software; you can redistribute it and/or modify
arch/arm/include/asm/opcodes.h line 14
Quoted 10 lines
arch/arm/include/asm/opcodes.h new file +10
-0+* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARM_OPCODES_H +#define __ASM_ARM_OPCODES_H + +#ifndef __ASSEMBLY__ +extern unsigned int arm_check_condition (unsigned int opcode,unsigned int psr); +#endif
You could use u32 for the parameters to reinforce the point that they're words.
Quoted 51 lines
arch/arm/kernel/opcodes.c new file +45
-0@@ -0,0 +1,69 @@ +/* +* linux/arch/arm/kernel/opcodes.c +* +* A32 condition code lookup feature moved from nwfpe/fpopcode.c +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/module.h> +#include <asm/opcodes.h> + +#define ARM_OPCODE_CONDITION_UNCOND 0xf + +/* +* condition code lookup table +* index into the table is test code: EQ, NE, ... LT, GT, AL, NV +* +* bit position in short is condition code: NZCV +*/ +static const unsigned short cc_map[16 ] = { +0xF0F0 ,/* EQ == Z set */ +0x0F0F ,/* NE */ +0xCCCC ,/* CS == C set */ +0x3333 ,/* CC */ +0xFF00 ,/* MI == N set */ +0x00FF ,/* PL */ +0xAAAA ,/* VS == V set */ +0x5555 ,/* VC */ +0x0C0C ,/* HI == C set && Z clear */ +0xF3F3 ,/* LS == C clear || Z set */ +0xAA55 ,/* GE == (N==V) */ +0x55AA ,/* LT == (N!=V) */ +0x0A05 ,/* GT == (!Z && (N==V)) */ +0xF5FA ,/* LE == (Z || (N!=V)) */ +0xFFFF ,/* AL always */ +0 /* NV */ +}; + +/* +* Returns: +* ARM_OPCODE_CONDTEST_FAIL - if condition fails +* ARM_OPCODE_CONDTEST_PASS - if condition passes (including AL) +* ARM_OPCODE_CONDTEST_UNCOND - if NV condition, or separate unconditional
arch/arm/kernel/opcodes.c line 55
Quoted 10 lines
arch/arm/kernel/opcodes.c new file +10
-0+* opcode space from v5 onwards +* +* Code that tests whether a conditional instruction would pass its condition +* check should check that return value == ARM_OPCODE_CONDTEST_PASS. +* +* Code that tests if a condition means that the instruction would be executed +* (regardless of conditional or unconditional) should instead check that the +* return value != ARM_OPCODE_CONDTEST_FAIL. +*/ +unsigned int arm_check_condition (unsigned int opcode,unsigned int psr)
I think you want asmlinkage for this function.
arch/arm/kernel/opcodes.c line 68
Quoted 13 lines
arch/arm/kernel/opcodes.c new file +13
-0+{ +unsigned int cc_bits = opcode >>28 ; +unsigned int psr_cond = psr >>28 ; + +if (cc_bits !=ARM_OPCODE_CONDITION_UNCOND ) { +if ((cc_map[cc_bits] >> (psr_cond)) &1 ) +return ARM_OPCODE_CONDTEST_PASS ; +else +return ARM_OPCODE_CONDTEST_FAIL ; + }else { +return ARM_OPCODE_CONDTEST_UNCOND ; + } +}
Maybe have a single return here returning a ret value which you assign in the conditional blocks.
arch/arm/kernel/opcodes.c line 69
Quoted 1 line
arch/arm/kernel/opcodes.c new file +1
-0+EXPORT_SYMBOL (arm_check_condition);
EXPORT_SYMBOL_GPL?
Will
PATCH 1/4 Add generic ARM instruction set condition code checks.
Quoted 11 lines · Will Deacon
Hi Leif,
This looks largely there, but I have some small comments inline.
arch/arm/include/asm/opcodes.h line 14
Quoted 3 lines · Leif Lindholm
arch/arm/include/asm/opcodes.h new file +3
-0+#ifndef __ASSEMBLY__ +extern unsigned int arm_check_condition (unsigned int opcode,unsigned int psr); +#endif You could use u32 for the parameters to reinforce the point that they're words.
Yeah, fair point. I just kept the types from the original nwfpe code.
Quoted 3 lines
Quoted 1 line
+unsigned int
arm_check_condition(unsigned int opcode, unsigned int psr)I think you want asmlinkage for this function.
OK
Quoted 8 lines
Quoted 8 lines
arch/arm/kernel/opcodes.c new file +8
-0+{ +unsigned int cc_bits = opcode>>28 ; +unsigned int psr_cond = psr>>28 ; + +if (cc_bits !=ARM_OPCODE_CONDITION_UNCOND ) { +if ((cc_map[cc_bits]>> (psr_cond))&1 ) +return ARM_OPCODE_CONDTEST_PASS ; +else
Quoted 8 lines
arch/arm/kernel/opcodes.c line 68
Quoted 5 lines
arch/arm/kernel/opcodes.c new file +5
-0+return ARM_OPCODE_CONDTEST_FAIL ; + }else { +return ARM_OPCODE_CONDTEST_UNCOND ; + } +}Maybe have a single return here returning a ret value which you assign in the conditional blocks.
OK
Quoted 3 lines
Quoted 1 line
+EXPORT_SYMBOL(arm_check_condition);
EXPORT_SYMBOL_GPL?
OK
/
Leif
-- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
PATCH 2/4 Use generic ARM instruction set condition code checks for nwfpe.
In reply to Leif LindholmThis patch changes the nwfpe implementation to use the new generic ARM instruction set condition code checks, rather than a local implementation. It also removes the existing condition code checking, which has been used for the generic support (in kernel/opcodes.{ch}).
---
This code has not been tested beyond building, linking and booting.
arch/arm/nwfpe/entry.S | 8 +++++--- arch/arm/nwfpe/fpopcode.c | 26 -------------------------- arch/arm/nwfpe/fpopcode.h | 3 --- 3 files changed, 5 insertions(+), 32 deletions(-)
arch/arm/nwfpe/entry.S +5 -3
@@ -20,6 +20,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <asm/opcodes.h> + /* This is the kernel's entry point into the floating point emulator. It is called from the kernel with code similar to this:
@@ -81,11 +83,11 @@ nwfpe_enter: mov r6, r0 @ save the opcode emulate: ldr r1, [sp, #S_PSR] @ fetch the PSR - bl checkCondition @ check the condition - cmp r0, #0 @ r0 = 0 ==> condition failed + bl arm_check_condition @ check the condition + cmp r0, #ARM_OPCODE_CONDTEST_PASS @ condition passed? @ if condition code failed to match, next insn - beq next @ get the next instruction; + bne next @ get the next instruction; mov r0, r6 @ prepare for EmulateAll() bl EmulateAll @ emulate the instruction
arch/arm/nwfpe/fpopcode.c +0 -26
@@ -61,29 +61,3 @@ const float32 float32Constant[] = { 0x41200000 /* single 10.0 */ }; -/* condition code lookup table -index into the table is test code: EQ, NE, ... LT, GT, AL, NV -bit position in short is condition code: NZCV */ -static const unsigned short aCC[16 ] = { -0xF0F0 ,// EQ == Z set -0x0F0F ,// NE -0xCCCC ,// CS == C set -0x3333 ,// CC -0xFF00 ,// MI == N set -0x00FF ,// PL -0xAAAA ,// VS == V set -0x5555 ,// VC -0x0C0C ,// HI == C set && Z clear -0xF3F3 ,// LS == C clear || Z set -0xAA55 ,// GE == (N==V) -0x55AA ,// LT == (N!=V) -0x0A05 ,// GT == (!Z && (N==V)) -0xF5FA ,// LE == (Z || (N!=V)) -0xFFFF ,// AL always -0 // NV -}; - -unsigned int checkCondition (const unsigned int opcode,const unsigned int ccodes) -{ -return (aCC[opcode >>28 ] >> (ccodes >>28 )) &1 ; -}
arch/arm/nwfpe/fpopcode.h +0 -3
@@ -475,9 +475,6 @@ static inline unsigned int getDestinationSize(const unsigned int opcode)return (nRc); } -extern unsigned int checkCondition (const unsigned int opcode, -const unsigned int ccodes); -extern const float64 float64Constant[];extern const float32 float32Constant[];
PATCH 3/4 Add condition code checking to SWP emulation handler.
In reply to Leif LindholmThis patch fixes two separate issues with the SWP emulation handler:
1: Certain processors implementing ARMv7-A can (legally) take an
undef exception even when the condition code would have meant that the instruction should not have been executed.
2: Opcodes with all flags set (condition code = 0xf) have been reused
in recent, and not-so-recent, versions of the ARM architecture to implement unconditional extensions to the instruction set. The existing code would still have processed any undefs triggered by executing an opcode with such a value.
This patch uses the new generic ARM instruction set condition code checks to implement proper handling of these situations.
--- arch/arm/kernel/swp_emulate.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-)
arch/arm/kernel/swp_emulate.c +12 -0
@@ -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,17 @@ 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_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 ; + } +if (current->pid != previous_pid) {pr_debug ("\"%s\" (%ld) uses deprecated SWP{B} instruction\n" , current->comm, (unsigned long )current->pid);
PATCH 3/4 Add condition code checking to SWP emulation handler.
Quoted 17 lines · Leif Lindholm
arch/arm/kernel/swp_emulate.c +2
-0@@ -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,17 @@ 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);
arch/arm/kernel/swp_emulate.c static int swp_handler(struct pt_regs *regs, unsigned int instr) · line 199
Quoted 10 lines
arch/arm/kernel/swp_emulate.c +10
-0+switch (res) { +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 ; + } +
Maybe have:
case ARM_OPCODE_CONDTEST_PASS: break;
for clarity. You could always have -EFAULT for the default case.
Will
PATCH 4/4 Use generic ARM instruction set condition code checks for kprobes.
In reply to Leif LindholmThis patch changes the kprobes implementation to use the generic ARM instruction set condition code checks, rather than a dedicated implementation.
--- arch/arm/kernel/kprobes-test.c | 66 ++++------------------------------------ 1 files changed, 6 insertions(+), 60 deletions(-)
arch/arm/kernel/kprobes-test.c +6 -60
@@ -202,6 +202,8 @@#include <linux/slab.h> #include <linux/kprobes.h> +#include <asm/opcodes.h> +#include "kprobes.h" #include "kprobes-test.h"
@@ -1048,67 +1050,11 @@ static int test_instance;*/ #define PSR_IGNORE_BITS (PSR_A_BIT | PSR_F_BIT) -static unsigned long test_check_cc (int cc,unsigned long cpsr) +inline unsigned long test_check_cc (int cc,unsigned long cpsr) { -unsigned long temp; - -switch (cc) { -case 0x0 :/* eq */ -return cpsr &PSR_Z_BIT ; - -case 0x1 :/* ne */ -return (~cpsr) &PSR_Z_BIT ; - -case 0x2 :/* cs */ -return cpsr &PSR_C_BIT ; - -case 0x3 :/* cc */ -return (~cpsr) &PSR_C_BIT ; - -case 0x4 :/* mi */ -return cpsr &PSR_N_BIT ; - -case 0x5 :/* pl */ -return (~cpsr) &PSR_N_BIT ; - -case 0x6 :/* vs */ -return cpsr &PSR_V_BIT ; - -case 0x7 :/* vc */ -return (~cpsr) &PSR_V_BIT ; +int ret =arm_check_condition (cc <<28 , cpsr); -case 0x8 :/* hi */ - cpsr &= ~(cpsr >>1 );/* PSR_C_BIT &= ~PSR_Z_BIT */ -return cpsr &PSR_C_BIT ; - -case 0x9 :/* ls */ - cpsr &= ~(cpsr >>1 );/* PSR_C_BIT &= ~PSR_Z_BIT */ -return (~cpsr) &PSR_C_BIT ; - -case 0xa :/* ge */ - cpsr ^= (cpsr <<3 );/* PSR_N_BIT ^= PSR_V_BIT */ -return (~cpsr) &PSR_N_BIT ; - -case 0xb :/* lt */ - cpsr ^= (cpsr <<3 );/* PSR_N_BIT ^= PSR_V_BIT */ -return cpsr &PSR_N_BIT ; - -case 0xc :/* gt */ - temp = cpsr ^ (cpsr <<3 );/* PSR_N_BIT ^= PSR_V_BIT */ - temp |= (cpsr <<1 );/* PSR_N_BIT |= PSR_Z_BIT */ -return (~temp) &PSR_N_BIT ; - -case 0xd :/* le */ - temp = cpsr ^ (cpsr <<3 );/* PSR_N_BIT ^= PSR_V_BIT */ - temp |= (cpsr <<1 );/* PSR_N_BIT |= PSR_Z_BIT */ -return temp &PSR_N_BIT ; - -case 0xe :/* al */ -case 0xf :/* unconditional */ -return true; - } -BUG (); -return false; +return (ret !=ARM_OPCODE_CONDTEST_FAIL ); }static int is_last_scenario;
@@ -1128,7 +1074,7 @@ static unsigned long test_context_cpsr(int scenario)if (!test_case_is_thumb) {/* Testing ARM code */ - probe_should_run =test_check_cc (current_instruction >>28 , cpsr) !=0 ; + probe_should_run =arm_check_condition (current_instruction, cpsr) !=ARM_OPCODE_CONDTEST_FAIL ;if (scenario ==15 ) is_last_scenario = true;
PATCH 4/4 Use generic ARM instruction set condition code checks for kprobes.
DISCLAIMER: I'm not a kprobes expert!
Quoted 10 lines · Leif Lindholm
arch/arm/kernel/kprobes-test.c +2
-0@@ -202,6 +202,8 @@#include <linux/slab.h> #include <linux/kprobes.h> +#include <asm/opcodes.h> +
[...]
arch/arm/kernel/kprobes-test.c static int test_instance; · line 1053
Quoted 2 lines
arch/arm/kernel/kprobes-test.c +1
-1-static unsigned long test_check_cc (int cc,unsigned long cpsr) +inline unsigned long test_check_cc (int cc,unsigned long cpsr)
Not sure why you make this change, surely you can just leave it as static?
Quoted 18 lines
{
arch/arm/kernel/kprobes-test.c +0
-17-unsigned long temp; - -switch (cc) { -case 0x0 :/* eq */ -return cpsr &PSR_Z_BIT ; - -case 0x1 :/* ne */ -return (~cpsr) &PSR_Z_BIT ; - -case 0x2 :/* cs */ -return cpsr &PSR_C_BIT ; - -case 0x3 :/* cc */ -return (~cpsr) &PSR_C_BIT ; - -case 0x4 :/* mi */ -return cpsr &PSR_N_BIT ;
arch/arm/kernel/kprobes-test.c static int test_instance; · line 1055
Quoted 10 lines
arch/arm/kernel/kprobes-test.c +1
-9- -case 0x5 :/* pl */ -return (~cpsr) &PSR_N_BIT ; - -case 0x6 :/* vs */ -return cpsr &PSR_V_BIT ; - -case 0x7 :/* vc */ -return (~cpsr) &PSR_V_BIT ; +int ret =arm_check_condition (cc <<28 , cpsr);
[...]
Maybe it's best just to change all of the callers to call arm_check_condition directly, like you have done below for the ARM case. For the Thumb cases will it work if you make sure that you put the condition code in the top bits?
arch/arm/kernel/kprobes-test.c static unsigned long test_context_cpsr(int scenario) · line 1079
Quoted 8 lines
arch/arm/kernel/kprobes-test.c +1
-1@@ -1128,7 +1074,7 @@ static unsigned long test_context_cpsr(int scenario)if (!test_case_is_thumb) {/* Testing ARM code */ - probe_should_run =test_check_cc (current_instruction >>28 , cpsr) !=0 ; + probe_should_run =arm_check_condition (current_instruction, cpsr) !=ARM_OPCODE_CONDTEST_FAIL ;if (scenario ==15 ) is_last_scenario = true;
Will
PATCH 4/4 Use generic ARM instruction set condition code checks for kprobes.
Quoted 5 lines · Will Deacon
arch/arm/kernel/kprobes-test.c static int test_instance; · line 1053
Quoted 2 lines · Leif Lindholm
arch/arm/kernel/kprobes-test.c +1
-1-static unsigned long test_check_cc (int cc,unsigned long cpsr) +inline unsigned long test_check_cc (int cc,unsigned long cpsr)Not sure why you make this change, surely you can just leave it as static?
As the function is now only a wrapper on arm_check_condition (with an inline shift), it made more sense to me. This was also suggested by Tixy, and he's since ACKed this patch.
Quoted 4 lines
Maybe it's best just to change all of the callers to call
arm_check_conditiondirectly, like you have done below for the ARM case. For the Thumb cases will it work if you make sure that you put the condition code in the top bits?
Yes, that is functionally equivalent, and what I did in the RFC version, but it ended up looking messy at the calling point.
Also, since in the other locations test_check_cc is actually used to check conditions for Thumb instructions (rather than ARM), it makes sense to me to wrap it behind something that doesn't appear to suggest otherwise.
Any sane compiler should generate pretty identical code for these two alternative solutions (unless it neglected to auto-inline the static variant).
/
Leif
PATCH 4/4 Use generic ARM instruction set condition code checks for kprobes.
Quoted 10 lines · Leif Lindholm
Quoted 5 lines · Will Deacon
arch/arm/kernel/kprobes-test.c static int test_instance; · line 1053
Quoted 2 lines · Leif Lindholm
arch/arm/kernel/kprobes-test.c +1
-1-static unsigned long test_check_cc (int cc,unsigned long cpsr) +inline unsigned long test_check_cc (int cc,unsigned long cpsr)Not sure why you make this change, surely you can just leave it as static?
As the function is now only a wrapper on
arm_check_condition(with an inline shift), it made more sense to me. This was also suggested by Tixy, and he's since ACKed this patch.
Hmm, I still don't see why you should change the linkage. Make it static inline if you really want the inline, but that seems weird outside of a header file stub.
Quoted 7 lines
Quoted 4 lines
Maybe it's best just to change all of the callers to call
arm_check_conditiondirectly, like you have done below for the ARM case. For the Thumb cases will it work if you make sure that you put the condition code in the top bits?Yes, that is functionally equivalent, and what I did in the RFC version, but it ended up looking messy at the calling point.
Ok, then could you route the ARM variant through the wrapper too?
Quoted 3 lines
Any sane compiler should generate pretty identical code for these two alternative solutions (unless it neglected to auto-inline the static variant).
The problem is when somebody else decides to call test_check_cc from another compilation unit, rather than go through arm_check_condition.
Will
PATCH 4/4 Use generic ARM instruction set condition code checks for kprobes.
Quoted 3 lines · Will Deacon
Hmm, I still don't see why you should change the linkage. Make it static inline if you really want the inline, but that seems weird outside of a header file stub.
OK
Quoted 9 lines
Quoted 7 lines
Quoted 4 lines
Maybe it's best just to change all of the callers to call
arm_check_conditiondirectly, like you have done below for the ARM case. For the Thumb cases will it work if you make sure that you put the condition code in the top bits?Yes, that is functionally equivalent, and what I did in the RFC version, but it ended up looking messy at the calling point.
Ok, then could you route the ARM variant through the wrapper too?
I would have preferred the opposite, but that would seem to require more invasive changes to the Thumb handling code (at least for the 'kprobe_test_flags & TEST_FLAG_NO_ITBLOCK' case). Will do.
/
Leif
-- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
PATCH 4/4 Use generic ARM instruction set condition code checks for kprobes.
In reply to Will DeaconQuoted 8 lines · Will Deacon
Quoted 7 lines · Leif Lindholm
Quoted 5 lines · Will Deacon
arch/arm/kernel/kprobes-test.c static int test_instance; · line 1053
Quoted 2 lines · Leif Lindholm
arch/arm/kernel/kprobes-test.c +1
-1-static unsigned long test_check_cc (int cc,unsigned long cpsr) +inline unsigned long test_check_cc (int cc,unsigned long cpsr)Not sure why you make this change, surely you can just leave it as static?
Quoted 7 lines
Quoted 3 lines
As the function is now only a wrapper on
arm_check_condition(with an inline shift), it made more sense to me. This was also suggested by Tixy, and he's since ACKed this patch.Hmm, I still don't see why you should change the linkage. Make it static inline if you really want the inline, but that seems weird outside of a header file stub.
As you pointed out later, it does need to be static, to avoid potential linkage issues. (I always incorrectly imagine that 'inline' is a glorified macro.)
Quoted 9 lines
Quoted 7 lines
Quoted 4 lines
Maybe it's best just to change all of the callers to call
arm_check_conditiondirectly, like you have done below for the ARM case. For the Thumb cases will it work if you make sure that you put the condition code in the top bits?Yes, that is functionally equivalent, and what I did in the RFC version, but it ended up looking messy at the calling point.
Ok, then could you route the ARM variant through the wrapper too?
The function Leif added is for checking the condition code in an ARM instruction, so it doesn't need a wrapper when used for this.
The other locations in the kprobes tests get the condition nibble from the ITSATE or from thumb conditional branch instructions. In these cases the code looks cleaner if the condition is passed as a value between 0x0 and 0xf, rather than being shift up to bit position 28 where the conditional ARM instructions have it encoded.
Quoted 6 lines
Quoted 3 lines
Any sane compiler should generate pretty identical code for these two alternative solutions (unless it neglected to auto-inline the static variant).
The problem is when somebody else decides to call
test_check_ccfrom another compilation unit, rather than go througharm_check_condition.
Signature · 1 line
Tixy
PATCH 4/4 Use generic ARM instruction set condition code checks for kprobes.
Quoted 7 lines · Jon Medhurst (Tixy)
Quoted 4 lines
Quoted 2 lines
Yes, that is functionally equivalent, and what I did in the RFC version, but it ended up looking messy at the calling point.
Ok, then could you route the ARM variant through the wrapper too?
The function Leif added is for checking the condition code in an ARM instruction, so it doesn't need a wrapper when used for this.
It doesn't, but...
Quoted 5 lines
The other locations in the kprobes tests get the condition nibble from the ITSATE or from thumb conditional branch instructions. In these cases the code looks cleaner if the condition is passed as a value between
0x0and0xf, rather than being shift up to bit position 28 where the conditional ARM instructions have it encoded.
I did what Will suggested though, and it does make it a bit cleaner. It also moves the ARM_OPCODE_* testing out of the test_context_cpsr code, so that all three cases have the probe_should_run setting pretty much identical.
I'll post the updated set shortly, so you can have a look.
/
Leif
-- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
PATCH 4/4 Use generic ARM instruction set condition code checks for kprobes.
In reply to Jon Medhurst (Tixy)Quoted 7 lines · Jon Medhurst (Tixy)
Quoted 4 lines
Quoted 2 lines
Yes, that is functionally equivalent, and what I did in the RFC version, but it ended up looking messy at the calling point.
Ok, then could you route the ARM variant through the wrapper too?
The function Leif added is for checking the condition code in an ARM instruction, so it doesn't need a wrapper when used for this.
It doesn't, but...
Quoted 5 lines
The other locations in the kprobes tests get the condition nibble from the ITSATE or from thumb conditional branch instructions. In these cases the code looks cleaner if the condition is passed as a value between
0x0and0xf, rather than being shift up to bit position 28 where the conditional ARM instructions have it encoded.
I did what Will suggested though, and it does make it a bit cleaner. It also moves the ARM_OPCODE_* testing out of the test_context_cpsr code, so that all three cases have the probe_should_run setting pretty much identical.
I'll post the updated set shortly, so you can have a look.
/
Leif
cover Add generic ARM ISA condition code check
In reply to Leif LindholmHi Leif,
Quoted 6 lines · Leif Lindholm
There are several locations in the kernel where software needs to inspect the condition codes of trapped instructions. The original bitmask implementation in the nwfpe code does this in an efficient manner. This series breaks this code out of nwfpe/fpopcode.{ch} into a standalone file for opcode operations, and contains additional patches to kprobes and SWP eumlation to use this interface.
Dave's been posting an opcodes.h which seems to fit in with some of this, so it's definitely worth you guys syncing up if you haven't already.
Dave - any comments?
Will
cover Add generic ARM ISA condition code check
Quoted 10 lines · Will Deacon
Hi Leif,
Quoted 6 lines · Leif Lindholm
There are several locations in the kernel where software needs to inspect the condition codes of trapped instructions. The original bitmask implementation in the nwfpe code does this in an efficient manner. This series breaks this code out of nwfpe/fpopcode.{ch} into a standalone file for opcode operations, and contains additional patches to kprobes and SWP eumlation to use this interface.
Quoted 4 lines
Dave's been posting an
opcodes.hwhich seems to fit in with some of this, so it's definitely worth you guys syncing up if you haven't already.Dave - any comments?
Rather than risk conflicts, I will wait for Leif's patch to go into the patch system, and then I will rebase on top.
Cheers
---Dave