Skip to contentSkip to conversation

powerpc: relative exception tables, and build-time sort

RFC PATCH Applied Nicholas Piggin 2 participants 6 messages Oct 13, 2016 – Nov 14, 2016 PowerPC

lore
Share & tools
lore

Nicholas Piggin

author reviewer
#0 lore raw

cover powerpc: relative exception tables, and build-time sort

This implements relative exception tables for powerpc, and converts it to use build-time sorting. I've tested 64s only so far, but 32-bit seems to build. Will obviously require some more testing and reviews.

Thanks,
Nick

Nicholas Piggin (3):
powerpc: EX_TABLE macro for exception tables
powerpc: relative exception tables
powerpc: build-time sort exception table

 arch/powerpc/Kconfig                              |   1 +
 arch/powerpc/include/asm/futex.h                  |  14 +-
 arch/powerpc/include/asm/io.h                     |  18 +-
 arch/powerpc/include/asm/linkage.h                |  22 ++
 arch/powerpc/include/asm/module.h                 |   4 -
 arch/powerpc/include/asm/uaccess.h                |  51 ++--
 arch/powerpc/include/asm/word-at-a-time.h         |   5 +-
 arch/powerpc/kernel/kprobes.c                     |   2 +-
 arch/powerpc/kernel/traps.c                       |   2 +-
 arch/powerpc/lib/checksum_32.S                    |  47 ++--
 arch/powerpc/lib/checksum_64.S                    |  20 +-
 arch/powerpc/lib/copy_32.S                        |  56 ++---
 arch/powerpc/lib/copyuser_64.S                    | 271 +++++++++++-----------
 arch/powerpc/lib/copyuser_power7.S                |  21 +-
 arch/powerpc/lib/ldstfp.S                         |  25 +-
 arch/powerpc/lib/sstep.c                          |  15 +-
 arch/powerpc/lib/string.S                         |  11 +-
 arch/powerpc/lib/string_64.S                      |  16 +-
 arch/powerpc/mm/fault.c                           |   2 +-
 arch/powerpc/platforms/embedded6xx/holly.c        |   2 +-
 arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c |   2 +-
 arch/powerpc/sysdev/fsl_rio.c                     |   7 +-
 arch/powerpc/sysdev/tsi108_pci.c                  |   5 +-
 scripts/sortextable.c                             |   2 +
 24 files changed, 274 insertions(+), 347 deletions(-)
Signature · 1 line
2.9.3
author reviewer
#1 lore raw

PATCH 1/3 powerpc: EX_TABLE macro for exception tables

This macro is taken from s390, and allows more flexibility in changing exception table format.

---
 arch/powerpc/include/asm/futex.h          |  14 +-
 arch/powerpc/include/asm/io.h             |  18 +-
 arch/powerpc/include/asm/linkage.h        |  22 +++
 arch/powerpc/include/asm/uaccess.h        |  24 +--
 arch/powerpc/include/asm/word-at-a-time.h |   5 +-
 arch/powerpc/lib/checksum_32.S            |  47 +++---
 arch/powerpc/lib/checksum_64.S            |  20 +--
 arch/powerpc/lib/copy_32.S                |  56 +++---
 arch/powerpc/lib/copyuser_64.S            | 271 +++++++++++++++---------------
 arch/powerpc/lib/copyuser_power7.S        |  21 +--
 arch/powerpc/lib/ldstfp.S                 |  25 ++-
 arch/powerpc/lib/sstep.c                  |  15 +-
 arch/powerpc/lib/string.S                 |  11 +-
 arch/powerpc/lib/string_64.S              |  16 +-
 arch/powerpc/sysdev/fsl_rio.c             |   5 +-
 arch/powerpc/sysdev/tsi108_pci.c          |   5 +-
 16 files changed, 248 insertions(+), 327 deletions(-)
arch/powerpc/include/asm/futex.h +5 -9
index 2a9cf84..eaada6c 100644
@@ -23,10 +23,8 @@
 "4:	li	%1,%3\n" \
 	"b	3b\n" \
 	".previous\n" \
-	".section __ex_table,\"a\"\n" \
-	".align 3\n" \
-	PPC_LONG "1b,4b,2b,4b\n" \
-	".previous" \
+	EX_TABLE(1b, 4b) \
+	EX_TABLE(2b, 4b) \
 	: "=&r" (oldval), "=&r" (ret) \
 	: "b" (uaddr), "i" (-EFAULT), "r" (oparg) \
 	: "cr0", "memory")
@@ -104,11 +102,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 "3:	.section .fixup,\"ax\"\n\
 4:	li	%0,%6\n\
 	b	3b\n\
-	.previous\n\
-	.section __ex_table,\"a\"\n\
-	.align 3\n\
-	" PPC_LONG "1b,4b,2b,4b\n\
-	.previous" \
+	.previous\n"
+	EX_TABLE(1b, 4b)
+	EX_TABLE(2b, 4b)
         : "+r" (ret), "=&r" (prev), "+m" (*uaddr)
         : "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT)
         : "cc", "memory");
arch/powerpc/include/asm/io.h +6 -12
index f6fda84..5219a19 100644
@@ -458,13 +458,10 @@ static inline unsigned int name(unsigned int port)	\
 		"5:	li	%0,-1\n"		\
 		"	b	4b\n"			\
 		".previous\n"				\
-		".section __ex_table,\"a\"\n"		\
-		"	.align	2\n"			\
-		"	.long	0b,5b\n"		\
-		"	.long	1b,5b\n"		\
-		"	.long	2b,5b\n"		\
-		"	.long	3b,5b\n"		\
-		".previous"				\
+		EX_TABLE(0b, 5b)			\
+		EX_TABLE(1b, 5b)			\
+		EX_TABLE(2b, 5b)			\
+		EX_TABLE(3b, 5b)			\
 		: "=&r" (x)				\
 		: "r" (port + _IO_BASE)			\
 		: "memory");  				\
@@ -479,11 +476,8 @@ static inline void name(unsigned int val, unsigned int port) \
 		"0:" op " %0,0,%1\n"			\
 		"1:	sync\n"				\
 		"2:\n"					\
-		".section __ex_table,\"a\"\n"		\
-		"	.align	2\n"			\
-		"	.long	0b,2b\n"		\
-		"	.long	1b,2b\n"		\
-		".previous"				\
+		EX_TABLE(0b, 2b)			\
+		EX_TABLE(1b, 2b)			\
 		: : "r" (val), "r" (port + _IO_BASE)	\
 		: "memory");   	   	   		\
 }
arch/powerpc/include/asm/linkage.h +22 -0
index 0cf5e21..fcb9e0d 100644
@@ -12,4 +12,26 @@
 	     "\t.globl ." #alias "\n\t.set ." #alias ", ." #name)
 #endif
 
+#ifndef __ASSEMBLY__
+/*
+ * Helper macro for exception table entries
+ */
+#define EX_TABLE(_fault, _target)	\
+	".section __ex_table,\"a\"\n"	\
+		PPC_LONG_ALIGN "\n"	\
+		PPC_LONG #_fault "\n"	\
+		PPC_LONG #_target "\n"	\
+	".previous\n"
+
+#else /* __ASSEMBLY__ */
+
+#define EX_TABLE(_fault, _target)	\
+	.section __ex_table,"a"	;	\
+		PPC_LONG_ALIGN ;	\
+		PPC_LONG _fault	;	\
+		PPC_LONG _target ;	\
+	.previous
+
+#endif /* __ASSEMBLY__ */
+
 #endif	/* _ASM_POWERPC_LINKAGE_H */
arch/powerpc/include/asm/uaccess.h +6 -18
index c266227..caff75e 100644
@@ -132,10 +132,7 @@ extern long __put_user_bad(void);
 		"3:	li %0,%3\n"				\
 		"	b 2b\n"					\
 		".previous\n"					\
-		".section __ex_table,\"a\"\n"			\
-			PPC_LONG_ALIGN "\n"			\
-			PPC_LONG "1b,3b\n"			\
-		".previous"					\
+		EX_TABLE(1b, 3b)				\
 		: "=r" (err)					\
 		: "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
 
@@ -152,11 +149,8 @@ extern long __put_user_bad(void);
 		"4:	li %0,%3\n"				\
 		"	b 3b\n"					\
 		".previous\n"					\
-		".section __ex_table,\"a\"\n"			\
-			PPC_LONG_ALIGN "\n"			\
-			PPC_LONG "1b,4b\n"			\
-			PPC_LONG "2b,4b\n"			\
-		".previous"					\
+		EX_TABLE(1b, 4b)				\
+		EX_TABLE(2b, 4b)				\
 		: "=r" (err)					\
 		: "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
 #endif /* __powerpc64__ */
@@ -215,10 +209,7 @@ extern long __get_user_bad(void);
 		"	li %1,0\n"			\
 		"	b 2b\n"				\
 		".previous\n"				\
-		".section __ex_table,\"a\"\n"		\
-			PPC_LONG_ALIGN "\n"		\
-			PPC_LONG "1b,3b\n"		\
-		".previous"				\
+		EX_TABLE(1b, 3b)			\
 		: "=r" (err), "=r" (x)			\
 		: "b" (addr), "i" (-EFAULT), "0" (err))
 
@@ -237,11 +228,8 @@ extern long __get_user_bad(void);
 		"	li %1+1,0\n"			\
 		"	b 3b\n"				\
 		".previous\n"				\
-		".section __ex_table,\"a\"\n"		\
-			PPC_LONG_ALIGN "\n"		\
-			PPC_LONG "1b,4b\n"		\
-			PPC_LONG "2b,4b\n"		\
-		".previous"				\
+		EX_TABLE(1b, 4b)			\
+		EX_TABLE(2b, 4b)			\
 		: "=r" (err), "=&r" (x)			\
 		: "b" (addr), "i" (-EFAULT), "0" (err))
 #endif /* __powerpc64__ */
arch/powerpc/include/asm/word-at-a-time.h +1 -4
index 4afe66a..2629755 100644
@@ -193,10 +193,7 @@ static inline unsigned long load_unaligned_zeropad(const void *addr)
 #endif
 	"b	2b\n"
 	".previous\n"
-	".section __ex_table,\"a\"\n\t"
-		PPC_LONG_ALIGN "\n\t"
-		PPC_LONG "1b,3b\n"
-	".previous"
+	EX_TABLE(1b, 3b)
 	: [tmp] "=&b" (tmp), [offset] "=&r" (offset), [ret] "=&r" (ret)
 	: [addr] "b" (addr), "m" (*(unsigned long *)addr));
 
arch/powerpc/lib/checksum_32.S +20 -27

68 lines not on this page · raw message

arch/powerpc/lib/checksum_64.S +4 -16
index fdec6e6..bc6573a 100644
@@ -180,34 +180,22 @@ _GLOBAL(__csum_partial)
 
 	.macro srcnr
 100:
-	.section __ex_table,"a"
-	.align 3
-	.llong 100b,.Lsrc_error_nr
-	.previous
+	EX_TABLE(100b,.Lsrc_error_nr)
 	.endm
 
 	.macro source
 150:
-	.section __ex_table,"a"
-	.align 3
-	.llong 150b,.Lsrc_error
-	.previous
+	EX_TABLE(150b,.Lsrc_error)
 	.endm
 
 	.macro dstnr
 200:
-	.section __ex_table,"a"
-	.align 3
-	.llong 200b,.Ldest_error_nr
-	.previous
+	EX_TABLE(200b,.Ldest_error_nr)
 	.endm
 
 	.macro dest
 250:
-	.section __ex_table,"a"
-	.align 3
-	.llong 250b,.Ldest_error
-	.previous
+	EX_TABLE(250b,.Ldest_error)
 	.endm
 
 /*
arch/powerpc/lib/copy_32.S +23 -33

83 lines not on this page · raw message

arch/powerpc/lib/copyuser_64.S +133 -138

286 lines not on this page · raw message

arch/powerpc/lib/copyuser_power7.S +5 -16
index da0c568..4133b0f6 100644
@@ -18,6 +18,7 @@
  * Author: Anton Blanchard <[email protected]>
  */
 #include <asm/ppc_asm.h>
+#include <asm/linkage.h>
 
 #ifdef __BIG_ENDIAN__
 #define LVS(VRT,RA,RB)		lvsl	VRT,RA,RB
@@ -29,35 +30,23 @@
 
 	.macro err1
 100:
-	.section __ex_table,"a"
-	.align 3
-	.llong 100b,.Ldo_err1
-	.previous
+	EX_TABLE(100b,.Ldo_err1)
 	.endm
 
 	.macro err2
 200:
-	.section __ex_table,"a"
-	.align 3
-	.llong 200b,.Ldo_err2
-	.previous
+	EX_TABLE(200b,.Ldo_err2)
 	.endm
 
 #ifdef CONFIG_ALTIVEC
 	.macro err3
 300:
-	.section __ex_table,"a"
-	.align 3
-	.llong 300b,.Ldo_err3
-	.previous
+	EX_TABLE(300b,.Ldo_err3)
 	.endm
 
 	.macro err4
 400:
-	.section __ex_table,"a"
-	.align 3
-	.llong 400b,.Ldo_err4
-	.previous
+	EX_TABLE(400b,.Ldo_err4)
 	.endm
 
 
arch/powerpc/lib/ldstfp.S +10 -15
index 5d0cdbf..0d0a622 100644
@@ -15,24 +15,19 @@
 #include <asm/ppc-opcode.h>
 #include <asm/reg.h>
 #include <asm/asm-offsets.h>
+#include <asm/linkage.h>
 #include <linux/errno.h>
 
 #ifdef CONFIG_PPC_FPU
 
 #define STKFRM	(PPC_MIN_STKFRM + 16)
 
-	.macro	extab	instr,handler
-	.section __ex_table,"a"
-	PPC_LONG \instr,\handler
-	.previous
-	.endm
-
 	.macro	inst32	op
 reg = 0
 	.rept	32
 20:	\op	reg,0,r4
 	b	3f
-	extab	20b,99f
+	EX_TABLE(20b,99f)
 reg = reg + 1
 	.endr
 	.endm
@@ -100,7 +95,7 @@ _GLOBAL(do_lfs)
 	mr	r3,r9
 	addi	r1,r1,STKFRM
 	blr
-	extab	2b,3b
+	EX_TABLE(2b,3b)
 
 /* Load FP reg N from double at *p.  N is in r3, p in r4. */
 _GLOBAL(do_lfd)
@@ -127,7 +122,7 @@ _GLOBAL(do_lfd)
 	mr	r3,r9
 	addi	r1,r1,STKFRM
 	blr
-	extab	2b,3b
+	EX_TABLE(2b,3b)
 
 /* Store FP reg N to float at *p.  N is in r3, p in r4. */
 _GLOBAL(do_stfs)
@@ -154,7 +149,7 @@ _GLOBAL(do_stfs)
 	mr	r3,r9
 	addi	r1,r1,STKFRM
 	blr
-	extab	2b,3b
+	EX_TABLE(2b,3b)
 
 /* Store FP reg N to double at *p.  N is in r3, p in r4. */
 _GLOBAL(do_stfd)
@@ -181,7 +176,7 @@ _GLOBAL(do_stfd)
 	mr	r3,r9
 	addi	r1,r1,STKFRM
 	blr
-	extab	2b,3b
+	EX_TABLE(2b,3b)
 
 #ifdef CONFIG_ALTIVEC
 /* Get the contents of vrN into v0; N is in r3. */
@@ -248,7 +243,7 @@ _GLOBAL(do_lvx)
 	mr	r3,r9
 	addi	r1,r1,STKFRM
 	blr
-	extab	2b,3b
+	EX_TABLE(2b,3b)
 
 /* Store vector reg N to *p.  N is in r3, p in r4. */
 _GLOBAL(do_stvx)
@@ -276,7 +271,7 @@ _GLOBAL(do_stvx)
 	mr	r3,r9
 	addi	r1,r1,STKFRM
 	blr
-	extab	2b,3b
+	EX_TABLE(2b,3b)
 #endif /* CONFIG_ALTIVEC */
 
 #ifdef CONFIG_VSX
@@ -344,7 +339,7 @@ _GLOBAL(do_lxvd2x)
 	mr	r3,r9
 	addi	r1,r1,STKFRM
 	blr
-	extab	2b,3b
+	EX_TABLE(2b,3b)
 
 /* Store VSX reg N to vector doubleword *p.  N is in r3, p in r4. */
 _GLOBAL(do_stxvd2x)
@@ -372,7 +367,7 @@ _GLOBAL(do_stxvd2x)
 	mr	r3,r9
 	addi	r1,r1,STKFRM
 	blr
-	extab	2b,3b
+	EX_TABLE(2b,3b)
 
 #endif /* CONFIG_VSX */
 
arch/powerpc/lib/sstep.c +3 -12
index 3362299..b64287c 100644
@@ -493,10 +493,7 @@ static int __kprobes do_vsx_store(int rn, int (*func)(int, unsigned long),
 		"3:	li	%0,%4\n"		\
 		"	b	2b\n"			\
 		".previous\n"				\
-		".section __ex_table,\"a\"\n"		\
-			PPC_LONG_ALIGN "\n"		\
-			PPC_LONG "1b,3b\n"		\
-		".previous"				\
+		EX_TABLE(1b, 3b)			\
 		: "=r" (err), "=r" (cr)			\
 		: "r" (x), "r" (addr), "i" (-EFAULT), "0" (err))
 
@@ -508,10 +505,7 @@ static int __kprobes do_vsx_store(int rn, int (*func)(int, unsigned long),
 		"3:	li	%0,%3\n"		\
 		"	b	2b\n"			\
 		".previous\n"				\
-		".section __ex_table,\"a\"\n"		\
-			PPC_LONG_ALIGN "\n"		\
-			PPC_LONG "1b,3b\n"		\
-		".previous"				\
+		EX_TABLE(1b, 3b)			\
 		: "=r" (err), "=r" (x)			\
 		: "r" (addr), "i" (-EFAULT), "0" (err))
 
@@ -523,10 +517,7 @@ static int __kprobes do_vsx_store(int rn, int (*func)(int, unsigned long),
 		"3:	li	%0,%3\n"		\
 		"	b	2b\n"			\
 		".previous\n"				\
-		".section __ex_table,\"a\"\n"		\
-			PPC_LONG_ALIGN "\n"		\
-			PPC_LONG "1b,3b\n"		\
-		".previous"				\
+		EX_TABLE(1b, 3b)			\
 		: "=r" (err)				\
 		: "r" (addr), "i" (-EFAULT), "0" (err))
 
arch/powerpc/lib/string.S +4 -7
index beabc68..9d5c9a5 100644
@@ -9,11 +9,10 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <asm/processor.h>
+#include <asm/linkage.h>
 #include <asm/errno.h>
 #include <asm/ppc_asm.h>
 
-	.section __ex_table,"a"
-	PPC_LONG_ALIGN
 	.text
 	
 /* This clears out any unused part of the destination buffer,
@@ -120,9 +119,7 @@ _GLOBAL(__clear_user)
 92:	mfctr	r3
 	blr
 
-	.section __ex_table,"a"
-	PPC_LONG	11b,90b
-	PPC_LONG	1b,91b
-	PPC_LONG	8b,92b
-	.text
+	EX_TABLE(11b, 90b)
+	EX_TABLE(1b, 91b)
+	EX_TABLE(8b, 92b)
 #endif
arch/powerpc/lib/string_64.S +4 -12
index 7bd9549..8c62804 100644
@@ -19,6 +19,7 @@
  */
 
 #include <asm/ppc_asm.h>
+#include <asm/linkage.h>
 #include <asm/asm-offsets.h>
 
 	.section	".toc","aw"
@@ -40,26 +41,17 @@ PPC64_CACHES:
 
 	.macro err1
 100:
-	.section __ex_table,"a"
-	.align 3
-	.llong 100b,.Ldo_err1
-	.previous
+	EX_TABLE(100b,.Ldo_err1)
 	.endm
 
 	.macro err2
 200:
-	.section __ex_table,"a"
-	.align 3
-	.llong 200b,.Ldo_err2
-	.previous
+	EX_TABLE(200b,.Ldo_err2)
 	.endm
 
 	.macro err3
 300:
-	.section __ex_table,"a"
-	.align 3
-	.llong 300b,.Ldo_err3
-	.previous
+	EX_TABLE(300b,.Ldo_err3)
 	.endm
 
 .Ldo_err1:
arch/powerpc/sysdev/fsl_rio.c +1 -4
index 3cc7cac..8ca4057 100644
@@ -80,10 +80,7 @@
 		"3:	li %1,-1\n"			\
 		"	li %0,%3\n"			\
 		"	b 2b\n"				\
-		".section __ex_table,\"a\"\n"		\
-			PPC_LONG_ALIGN "\n"		\
-			PPC_LONG "1b,3b\n"		\
-		".text"					\
+		EX_TABLE(1b, 3b)			\
 		: "=r" (err), "=r" (x)			\
 		: "b" (addr), "i" (-EFAULT), "0" (err))
 
arch/powerpc/sysdev/tsi108_pci.c +1 -4
index 57c971b..d64e741 100644
@@ -137,10 +137,7 @@ void tsi108_clear_pci_error(u32 pci_cfg_base)
 		".section .fixup,\"ax\"\n"		\
 		"3:	li %0,-1\n"			\
 		"	b 2b\n"				\
-		".section __ex_table,\"a\"\n"		\
-		"	.align 2\n"			\
-		"	.long 1b,3b\n"			\
-		".text"					\
+		EX_TABLE(1b, 3b)			\
 		: "=r"(x) : "r"(addr))
 
 int
Signature · 1 line
2.9.3
author reviewer
#2 lore raw

PATCH 2/3 powerpc: relative exception tables

In reply to Nicholas Piggin

This halves the exception table size on 64-bit builds, and it allows build-time sorting of exception tables to work on relocated kernels.

---
 arch/powerpc/include/asm/linkage.h                | 20 ++++++++---------
 arch/powerpc/include/asm/uaccess.h                | 27 ++++++++++++++---------
 arch/powerpc/kernel/kprobes.c                     |  2 +-
 arch/powerpc/kernel/traps.c                       |  2 +-
 arch/powerpc/mm/fault.c                           |  2 +-
 arch/powerpc/platforms/embedded6xx/holly.c        |  2 +-
 arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c |  2 +-
 arch/powerpc/sysdev/fsl_rio.c                     |  2 +-
 8 files changed, 33 insertions(+), 26 deletions(-)
arch/powerpc/include/asm/linkage.h +10 -10
index fcb9e0d..6898bf5 100644
@@ -16,20 +16,20 @@
 /*
  * Helper macro for exception table entries
  */
-#define EX_TABLE(_fault, _target)	\
-	".section __ex_table,\"a\"\n"	\
-		PPC_LONG_ALIGN "\n"	\
-		PPC_LONG #_fault "\n"	\
-		PPC_LONG #_target "\n"	\
+#define EX_TABLE(_fault, _target)			\
+	".section __ex_table,\"a\"\n"			\
+		".balign 4\n"				\
+		".long (" #_fault  ") - . \n"		\
+		".long (" #_target ") - . \n"		\
 	".previous\n"
 
 #else /* __ASSEMBLY__ */
 
-#define EX_TABLE(_fault, _target)	\
-	.section __ex_table,"a"	;	\
-		PPC_LONG_ALIGN ;	\
-		PPC_LONG _fault	;	\
-		PPC_LONG _target ;	\
+#define EX_TABLE(_fault, _target)			\
+	.section __ex_table,"a"	;			\
+		.balign 4;				\
+		.long (_fault) - . ;			\
+		.long (_target) - . ;			\
 	.previous
 
 #endif /* __ASSEMBLY__ */
arch/powerpc/include/asm/uaccess.h +17 -10
index caff75e..f485a01 100644
@@ -63,23 +63,30 @@
 	 __access_ok((__force unsigned long)(addr), (size), get_fs()))
 
 /*
- * The exception table consists of pairs of addresses: the first is the
- * address of an instruction that is allowed to fault, and the second is
+ * The exception table consists of pairs of relative addresses: the first is
+ * the address of an instruction that is allowed to fault, and the second is
  * the address at which the program should continue.  No registers are
- * modified, so it is entirely up to the continuation code to figure out
- * what to do.
+ * modified, so it is entirely up to the continuation code to figure out what
+ * to do.
  *
- * All the routines below use bits of fixup code that are out of line
- * with the main instruction path.  This means when everything is well,
- * we don't even have to jump over them.  Further, they do not intrude
- * on our cache or tlb entries.
+ * All the routines below use bits of fixup code that are out of line with the
+ * main instruction path.  This means when everything is well, we don't even
+ * have to jump over them.  Further, they do not intrude on our cache or tlb
+ * entries.
  */
 
+#define ARCH_HAS_RELATIVE_EXTABLE
+
 struct exception_table_entry {
-	unsigned long insn;
-	unsigned long fixup;
+	int insn;
+	int fixup;
 };
 
+static inline unsigned long extable_fixup(const struct exception_table_entry *x)
+{
+	return (unsigned long)&x->fixup + x->fixup;
+}
+
 /*
  * These are the main single-value transfer routines.  They automatically
  * use the right size if we just have the right pointer type.
arch/powerpc/kernel/kprobes.c +1 -1
index e785cc9..9479d8e 100644
@@ -449,7 +449,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 		 * zero, try to fix up.
 		 */
 		if ((entry = search_exception_tables(regs->nip)) != NULL) {
-			regs->nip = entry->fixup;
+			regs->nip = extable_fixup(entry);
 			return 1;
 		}
 
arch/powerpc/kernel/traps.c +1 -1
index a1f8f56..ec5fd09 100644
@@ -366,7 +366,7 @@ static inline int check_io_access(struct pt_regs *regs)
 			       (*nip & 0x100)? "OUT to": "IN from",
 			       regs->gpr[rb] - _IO_BASE, nip);
 			regs->msr |= MSR_RI;
-			regs->nip = entry->fixup;
+			regs->nip = extable_fixup(entry);
 			return 1;
 		}
 	}
arch/powerpc/mm/fault.c +1 -1
index d0b137d..73932f4 100644
@@ -512,7 +512,7 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
 
 	/* Are we prepared to handle this fault?  */
 	if ((entry = search_exception_tables(regs->nip)) != NULL) {
-		regs->nip = entry->fixup;
+		regs->nip = extable_fixup(entry);
 		return;
 	}
 
arch/powerpc/platforms/embedded6xx/holly.c +1 -1
index dfd3100..0409714 100644
@@ -263,7 +263,7 @@ static int ppc750_machine_check_exception(struct pt_regs *regs)
 	if ((entry = search_exception_tables(regs->nip)) != NULL) {
 		tsi108_clear_pci_cfg_error();
 		regs->msr |= MSR_RI;
-		regs->nip = entry->fixup;
+		regs->nip = extable_fixup(entry);
 		return 1;
 	}
 	return 0;
arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +1 -1
index f97bab8..9de100e 100644
@@ -174,7 +174,7 @@ static int mpc7448_machine_check_exception(struct pt_regs *regs)
 	if ((entry = search_exception_tables(regs->nip)) != NULL) {
 		tsi108_clear_pci_cfg_error();
 		regs->msr |= MSR_RI;
-		regs->nip = entry->fixup;
+		regs->nip = extable_fixup(entry);
 		return 1;
 	}
 	return 0;
arch/powerpc/sysdev/fsl_rio.c +1 -1
index 8ca4057..28fb243 100644
@@ -110,7 +110,7 @@ int fsl_rio_mcheck_exception(struct pt_regs *regs)
 			out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR),
 				 0);
 			regs->msr |= MSR_RI;
-			regs->nip = entry->fixup;
+			regs->nip = extable_fixup(entry);
 			return 1;
 		}
 	}
Signature · 1 line
2.9.3
author reviewer
#4 lore raw

PATCH 3/3 powerpc: build-time sort exception table

In reply to Nicholas Piggin
---
 arch/powerpc/Kconfig              | 1 +
 arch/powerpc/include/asm/module.h | 4 ----
 scripts/sortextable.c             | 2 ++
 3 files changed, 3 insertions(+), 4 deletions(-)
arch/powerpc/Kconfig +1 -0
index 5d43cb8..b49062b 100644
@@ -80,6 +80,7 @@ config ARCH_HAS_DMA_SET_COHERENT_MASK
 config PPC
 	bool
 	default y
+	select BUILDTIME_EXTABLE_SORT
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_MIGHT_HAVE_PC_SERIO
 	select BINFMT_ELF
arch/powerpc/include/asm/module.h +0 -4
index cd4ffd8..cc12c61 100644
@@ -90,10 +90,6 @@ static inline int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sec
 }
 #endif
 
-struct exception_table_entry;
-void sort_ex_table(struct exception_table_entry *start,
-		   struct exception_table_entry *finish);
-
 #if defined(CONFIG_MODVERSIONS) && defined(CONFIG_PPC64)
 #define ARCH_RELOCATES_KCRCTAB
 #define reloc_start PHYSICAL_START
scripts/sortextable.c +2 -0
index f453b7c..365a907 100644
@@ -316,6 +316,8 @@ do_file(char const *const fname)
 	case EM_S390:
 	case EM_AARCH64:
 	case EM_PARISC:
+	case EM_PPC:
+	case EM_PPC64:
 		custom_sort = sort_relative_table;
 		break;
 	case EM_ARCOMPACT:
Signature · 1 line
2.9.3