BE8 patch updates
Updated fixes for BE8 support.
These change the previous fixes to use <asm/opcodes.h> to deal with instruction generation.
PATCH 1/3 ARM: Correct BUG() assembly to ensure it is endian-agnostic
Currently BUG() uses .word or .hword to create the necessary illegal instructions. However if we are building BE8 then these get swapped by the linker into different illegal instructions in the text.
Change to using .inst and .inst.w to create the instructions and mark them as instructions so that the linker acts correctly.
Fixes issue reported by Dave Martin <[email protected]>
--- arch/arm/include/asm/bug.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/include/asm/bug.h +2 -2
@@ -12,10 +12,10 @@*/ #ifdef CONFIG_THUMB2_KERNEL #define BUG_INSTR_VALUE 0xde02 -#define BUG_INSTR_TYPE ".hword " +#define BUG_INSTR_TYPE ".inst.w "#else #define BUG_INSTR_VALUE 0xe7f001f2 -#define BUG_INSTR_TYPE ".word " +#define BUG_INSTR_TYPE ".inst "#endif
Signature · 1 line
1.7.10.4
PATCH 2/3 ARM: fix BUG() detection
In reply to Ben DooksThe detection of the instruction used by BUG() did not take into account the differences in endian-ness between instruction and data. Change the code to use the relevant helpers in <asm/opcodes.h> to translate the endian-ness of the instructions.
Fixes issue reported by Dave Martin <[email protected]>
--- arch/arm/include/asm/bug.h | 10 ++++++---- arch/arm/kernel/traps.c | 8 +++++--- 2 files changed, 11 insertions(+), 7 deletions(-)
arch/arm/include/asm/bug.h +6 -4
@@ -2,6 +2,8 @@#define _ASMARM_BUG_H#include <linux/linkage.h> +#include <linux/types.h> +#include <asm/opcodes.h> #ifdef CONFIG_BUG
@@ -12,10 +14,10 @@*/ #ifdef CONFIG_THUMB2_KERNEL #define BUG_INSTR_VALUE 0xde02 -#define BUG_INSTR_TYPE ".inst.w " +#define BUG_INSTR (__value) __inst_thumb16(__value)#else #define BUG_INSTR_VALUE 0xe7f001f2 -#define BUG_INSTR_TYPE ".inst " +#define BUG_INSTR (__value) __inst_arm(__value)#endif
@@ -33,7 +35,7 @@#define __BUG (__file, __line, __value) \ do { \ - asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n" \ + asm volatile("1:\t" BUG_INSTR(__value) "\n" \ ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \ "2:\t.asciz " #__file "\n" \ ".popsection\n" \
@@ -48,7 +50,7 @@ do { \#define __BUG (__file, __line, __value) \ do { \ - asm volatile(BUG_INSTR_TYPE #__value); \ + asm volatile(BUG_INSTR(__value) "\n"); \ unreachable(); \ } while (0)#endif /* CONFIG_DEBUG_BUGVERBOSE */
arch/arm/kernel/traps.c +5 -3
@@ -344,15 +344,17 @@ void arm_notify_die(const char *str, struct pt_regs *regs,int is_valid_bugaddr (unsigned long pc) {#ifdef CONFIG_THUMB2_KERNEL -unsigned short bkpt; +u16 bkpt; +u16 insn =__opcode_to_mem_thumb16 (BUG_INSTR_VALUE );#else -unsigned long bkpt; +u32 bkpt; +u32 insn =__opcode_to_mem_arm (BUG_INSTR_VALUE );#endif if (probe_kernel_address ((unsigned *)pc, bkpt))return 0 ; -return bkpt ==BUG_INSTR_VALUE ; +return bkpt == insn; }#endif
Signature · 1 line
1.7.10.4
PATCH 2/3 ARM: fix BUG() detection
Quoted 6 lines · Ben Dooks
The detection of the instruction used by
BUG()did not take into account the differences in endian-ness between instruction and data. Change the code to use the relevant helpers in <asm/opcodes.h> to translate the endian-ness of the instructions.Fixes issue reported by Dave Martin <[email protected]>
It probably makes sense to fold this with the preceding patch.
Quoted 21 lines
Signed-off-by Ben Dooks <[email protected]>--- arch/arm/include/asm/bug.h | 10 ++++++---- arch/arm/kernel/traps.c | 8 +++++--- 2 files changed, 11 insertions(+), 7 deletions(-)arch/arm/include/asm/bug.h +2
-0@@ -2,6 +2,8 @@#define _ASMARM_BUG_H#include <linux/linkage.h> +#include <linux/types.h> +#include <asm/opcodes.h> #ifdef CONFIG_BUG
arch/arm/include/asm/bug.h line 21
Quoted 10 lines
arch/arm/include/asm/bug.h +2
-2@@ -12,10 +14,10 @@*/ #ifdef CONFIG_THUMB2_KERNEL #define BUG_INSTR_VALUE 0xde02 -#define BUG_INSTR_TYPE ".inst.w " +#define BUG_INSTR (__value) __inst_thumb16(__value)#else #define BUG_INSTR_VALUE 0xe7f001f2 -#define BUG_INSTR_TYPE ".inst " +#define BUG_INSTR (__value) __inst_arm(__value)#endif
Looks OK. You could make things a bit less verbose by
#define BUG_INSTR __inst_thumb16(BUG_INSTR_VALUE) #else ... #define BUG_INSTR __inst_arm(BUG_INSTR_VALUE)
Quoted 28 lines
arch/arm/include/asm/bug.h +2
-2@@ -33,7 +35,7 @@#define __BUG (__file, __line, __value) \ do { \ - asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n" \ + asm volatile("1:\t" BUG_INSTR(__value) "\n" \ ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \ "2:\t.asciz " #__file "\n" \ ".popsection\n" \@@ -48,7 +50,7 @@ do { \#define __BUG (__file, __line, __value) \ do { \ - asm volatile(BUG_INSTR_TYPE #__value); \ + asm volatile(BUG_INSTR(__value) "\n"); \ unreachable(); \ } while (0)#endif /* CONFIG_DEBUG_BUGVERBOSE */ arch/arm/kernel/traps.c +0
-0@@ -344,15 +344,17 @@ void arm_notify_die(const char *str, struct pt_regs *regs,int is_valid_bugaddr (unsigned long pc) {#ifdef CONFIG_THUMB2_KERNEL
arch/arm/kernel/traps.c void arm_notify_die(const char *str, struct pt_regs *regs, · line 354
Quoted 10 lines
arch/arm/kernel/traps.c +4
-2-unsigned short bkpt; +u16 bkpt; +u16 insn =__opcode_to_mem_thumb16 (BUG_INSTR_VALUE );#else -unsigned long bkpt; +u32 bkpt; +u32 insn =__opcode_to_mem_arm (BUG_INSTR_VALUE );#endif if (probe_kernel_address ((unsigned *)pc, bkpt))
Hmm, the (unsigned *) actually looks weird here now I look at it.
probe_kernel_address does (__force typeof(bkpt) __user *) on it anyway, so I guess that's harmless. void * might make more sense, though this patch may not be the place to fix it.
Cheers
---Dave
Quoted 15 lines
arch/arm/kernel/traps.c +1
-1return 0 ; - return bkpt == BUG_INSTR_VALUE; + return bkpt == insn; }#endif Signature · 7 lines
1.7.10.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel at lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 2/3 ARM: fix BUG() detection
Quoted 44 lines · Dave Martin
Quoted 6 lines · Ben Dooks
The detection of the instruction used by
BUG()did not take into account the differences in endian-ness between instruction and data. Change the code to use the relevant helpers in<asm/opcodes.h> to translate the endian-ness of the instructions.Fixes issue reported by Dave Martin<[email protected]>
It probably makes sense to fold this with the preceding patch.
Quoted 21 lines
Signed-off-by Ben Dooks<[email protected]>--- arch/arm/include/asm/bug.h | 10 ++++++---- arch/arm/kernel/traps.c | 8 +++++--- 2 files changed, 11 insertions(+), 7 deletions(-)arch/arm/include/asm/bug.h +2
-0@@ -2,6 +2,8 @@#define _ASMARM_BUG_H#include <linux/linkage.h> +#include <linux/types.h> +#include <asm/opcodes.h> #ifdef CONFIG_BUG arch/arm/include/asm/bug.h line 21
Quoted 10 lines
arch/arm/include/asm/bug.h +2
-2@@ -12,10 +14,10 @@*/ #ifdef CONFIG_THUMB2_KERNEL #define BUG_INSTR_VALUE 0xde02 -#define BUG_INSTR_TYPE ".inst.w " +#define BUG_INSTR (__value) __inst_thumb16(__value)#else #define BUG_INSTR_VALUE 0xe7f001f2 -#define BUG_INSTR_TYPE ".inst " +#define BUG_INSTR (__value) __inst_arm(__value)#endif Looks OK. You could make things a bit less verbose by
Quoted 4 lines
#define BUG_INSTR __inst_thumb16(BUG_INSTR_VALUE) #else ... #define BUG_INSTR __inst_arm(BUG_INSTR_VALUE)
I was trying to keep the macro as similar as possible, although there is only one bug instruction value at the moment the __BUG() code seems to assume that in the future there may be more of them and that it should be able to handle them.
Quoted 62 lines
Quoted 27 lines
arch/arm/include/asm/bug.h +2
-2@@ -33,7 +35,7 @@#define __BUG (__file, __line, __value) \ do { \ - asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n" \ + asm volatile("1:\t" BUG_INSTR(__value) "\n" \ ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \ "2:\t.asciz " #__file "\n" \ ".popsection\n" \@@ -48,7 +50,7 @@ do { \#define __BUG (__file, __line, __value) \ do { \ - asm volatile(BUG_INSTR_TYPE #__value); \ + asm volatile(BUG_INSTR(__value) "\n"); \ unreachable(); \ } while (0)#endif /* CONFIG_DEBUG_BUGVERBOSE */ arch/arm/kernel/traps.c +0
-0@@ -344,15 +344,17 @@ void arm_notify_die(const char *str, struct pt_regs *regs,int is_valid_bugaddr (unsigned long pc) {#ifdef CONFIG_THUMB2_KERNEL arch/arm/kernel/traps.c void arm_notify_die(const char *str, struct pt_regs *regs, · line 354
Quoted 10 lines
arch/arm/kernel/traps.c +4
-2-unsigned short bkpt; +u16 bkpt; +u16 insn =__opcode_to_mem_thumb16 (BUG_INSTR_VALUE );#else -unsigned long bkpt; +u32 bkpt; +u32 insn =__opcode_to_mem_arm (BUG_INSTR_VALUE );#endif if (probe_kernel_address ((unsigned *)pc, bkpt))Hmm, the (unsigned *) actually looks weird here now I look at it.
probe_kernel_addressdoes (__forcetypeof(bkpt)__user*) on it anyway, so I guess that's harmless. void * might make more sense, though this patch may not be the place to fix it.Cheers
---DaveQuoted 15 lines
arch/arm/kernel/traps.c +1
-2return 0 ; -return bkpt ==BUG_INSTR_VALUE ; + return bkpt == insn; }#endif --1.7.10.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Signature · 2 lines
Ben Dooks http://www.codethink.co.uk/ Senior Engineer Codethink - Providing Genius
PATCH 2/3 ARM: fix BUG() detection
Quoted 50 lines · Ben Dooks
Quoted 44 lines · Dave Martin
Quoted 6 lines · Ben Dooks
The detection of the instruction used by
BUG()did not take into account the differences in endian-ness between instruction and data. Change the code to use the relevant helpers in<asm/opcodes.h> to translate the endian-ness of the instructions.Fixes issue reported by Dave Martin<[email protected]>
It probably makes sense to fold this with the preceding patch.
Quoted 21 lines
Signed-off-by Ben Dooks<[email protected]>--- arch/arm/include/asm/bug.h | 10 ++++++---- arch/arm/kernel/traps.c | 8 +++++--- 2 files changed, 11 insertions(+), 7 deletions(-)arch/arm/include/asm/bug.h +2
-0@@ -2,6 +2,8 @@#define _ASMARM_BUG_H#include <linux/linkage.h> +#include <linux/types.h> +#include <asm/opcodes.h> #ifdef CONFIG_BUG arch/arm/include/asm/bug.h line 21
Quoted 10 lines
arch/arm/include/asm/bug.h +2
-2@@ -12,10 +14,10 @@*/ #ifdef CONFIG_THUMB2_KERNEL #define BUG_INSTR_VALUE 0xde02 -#define BUG_INSTR_TYPE ".inst.w " +#define BUG_INSTR (__value) __inst_thumb16(__value)#else #define BUG_INSTR_VALUE 0xe7f001f2 -#define BUG_INSTR_TYPE ".inst " +#define BUG_INSTR (__value) __inst_arm(__value)#endif Looks OK. You could make things a bit less verbose by
Quoted 4 lines
#define BUG_INSTR __inst_thumb16(BUG_INSTR_VALUE) #else ... #define BUG_INSTR __inst_arm(BUG_INSTR_VALUE)
Quoted 4 lines
I was trying to keep the macro as similar as possible, although there is only one bug instruction value at the moment the
__BUG()code seems to assume that in the future there may be more of them and that it should be able to handle them.
No problem, it should work fine your way.
Cheers
---Dave
Quoted 73 lines
Quoted 63 lines
Quoted 28 lines
arch/arm/include/asm/bug.h +2
-2@@ -33,7 +35,7 @@#define __BUG (__file, __line, __value) \ do { \ - asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n" \ + asm volatile("1:\t" BUG_INSTR(__value) "\n" \ ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \ "2:\t.asciz " #__file "\n" \ ".popsection\n" \@@ -48,7 +50,7 @@ do { \#define __BUG (__file, __line, __value) \ do { \ - asm volatile(BUG_INSTR_TYPE #__value); \ + asm volatile(BUG_INSTR(__value) "\n"); \ unreachable(); \ } while (0)#endif /* CONFIG_DEBUG_BUGVERBOSE */ arch/arm/kernel/traps.c +0
-0@@ -344,15 +344,17 @@ void arm_notify_die(const char *str, struct pt_regs *regs,int is_valid_bugaddr (unsigned long pc) {#ifdef CONFIG_THUMB2_KERNEL arch/arm/kernel/traps.c void arm_notify_die(const char *str, struct pt_regs *regs, · line 354
Quoted 10 lines
arch/arm/kernel/traps.c +4
-2-unsigned short bkpt; +u16 bkpt; +u16 insn =__opcode_to_mem_thumb16 (BUG_INSTR_VALUE );#else -unsigned long bkpt; +u32 bkpt; +u32 insn =__opcode_to_mem_arm (BUG_INSTR_VALUE );#endif if (probe_kernel_address ((unsigned *)pc, bkpt))Hmm, the (unsigned *) actually looks weird here now I look at it.
probe_kernel_addressdoes (__forcetypeof(bkpt)__user*) on it anyway, so I guess that's harmless. void * might make more sense, though this patch may not be the place to fix it.Cheers
---DaveQuoted 15 lines
arch/arm/kernel/traps.c +1
-2return 0 ; -return bkpt ==BUG_INSTR_VALUE ; + return bkpt == insn; }#endif --1.7.10.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernelSignature · 7 lines
Ben Dooks http://www.codethink.co.uk/ Senior Engineer Codethink - Providing Genius _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel at lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 3/3 ARM: kdgb: use <asm/opcodes.h> for data to be assembled as intruction
In reply to Ben DooksThe arch_kgdb_breakpoint() function uses an inline assembly directive to assemble a specific instruction using .word. This means the linker will not treat is as an instruction, and therefore incorrectly swap the endian-ness if running BE8.
--- arch/arm/include/asm/kgdb.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/include/asm/kgdb.h +2 -1
@@ -11,6 +11,7 @@#define __ARM_KGDB_H__#include <linux/ptrace.h> +#include <asm/opcodes.h> /* * GDB assumes that we're a user process being debugged, so
@@ -41,7 +42,7 @@static inline void arch_kgdb_breakpoint (void ) { - asm(".word 0xe7ffdeff" ); + asm(__inst_arm(0xe7ffdeff)); }extern void kgdb_handle_bus_error (void );
Signature · 1 line
1.7.10.4
PATCH 3/3 ARM: kdgb: use <asm/opcodes.h> for data to be assembled as intruction
Quoted 6 lines · Ben Dooks
The
arch_kgdb_breakpoint()function uses an inline assembly directive to assemble a specific instruction using .word. This means the linker will not treat is as an instruction, and therefore incorrectly swap the endian-ness if running BE8.Signed-off-by Ben Dooks <[email protected]>
Cheers
---Dave
Quoted 17 lines
--- arch/arm/include/asm/kgdb.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)arch/arm/include/asm/kgdb.h +1
-0@@ -11,6 +11,7 @@#define __ARM_KGDB_H__#include <linux/ptrace.h> +#include <asm/opcodes.h> /* * GDB assumes that we're a user process being debugged, so
arch/arm/include/asm/kgdb.h line 45
Quoted 5 lines
arch/arm/include/asm/kgdb.h +1
-1@@ -41,7 +42,7 @@static inline void arch_kgdb_breakpoint (void ) { - asm(".word 0xe7ffdeff" ); + asm(__inst_arm(0xe7ffdeff));
Actually, the #define could be used directly now:
__inst_arm(KGDB_COMPILED_BREAK)
I don't know whether KGDB works with THUMB2_KERNEL or not... but this patch shouldn't break anything that isn't broken already.
Nico and Deepak were involved at some point, maybe they have ideas about this. The code in question predates THUMB2_KERNEL and has not been touched since, but because THUMB2_KERNEL implies !CPU_ENDIAN_BE32, the first instruction of the asm will be 0xdeff, which is bkpt #0xff.
Other aspects look broken, though.
Maybe it would be wise to make HAVE_ARCH_KGDB conflict with THUMB2_KERNEL for now.
Cheers
---Dave