Skip to contentSkip to conversation

BE8 patch updates

PATCH New Ben Dooks 2 participants 8 messages Aug 14, 2013 – Aug 16, 2013 Arm (32-bit)

lore
Share & tools
lore

Ben Dooks

author
#0 lore raw

Updated fixes for BE8 support.

These change the previous fixes to use <asm/opcodes.h> to deal with instruction generation.

author
#1 lore raw

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
index 7af5c6c..b95da52 100644
@@ -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
author
#2 lore raw

PATCH 2/3 ARM: fix BUG() detection

In reply to 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]>

---
 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
index b95da52..b274bde 100644
@@ -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
index cb67b04..ae2d828 100644
@@ -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
#3 lore raw

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
---
 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
index b95da52..b274bde 100644
@@ -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
index cb67b04..ae2d828 100644
@@ -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 -1
 		return 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
author
#4 lore raw

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
---
  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
index b95da52..b274bde 100644
@@ -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
index cb67b04..ae2d828 100644
@@ -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 -2
  		return 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
#5 lore raw

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
---
 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
index b95da52..b274bde 100644
@@ -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
index cb67b04..ae2d828 100644
@@ -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 -2
 		return 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 · 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
author
#6 lore raw

PATCH 3/3 ARM: kdgb: use <asm/opcodes.h> for data to be assembled as intruction

In reply to 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.

---
 arch/arm/include/asm/kgdb.h |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/include/asm/kgdb.h +2 -1
index 48066ce..0a9d5dd 100644
@@ -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
#7 lore raw

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.

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
index 48066ce..0a9d5dd 100644
@@ -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