Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61dbbaeb authored by Helge Deller's avatar Helge Deller
Browse files

parisc: provide macro to create exception table entries



Provide a macro ASM_EXCEPTIONTABLE_ENTRY() to create exception table
entries and convert all open-coded places to use that macro.

This patch is a first step toward creating a exception table which only
holds 32bit pointers even on a 64bit kernel. That way in my own kernel
I was able to reduce the in-kernel exception table from 44kB to 22kB.

Signed-off-by: default avatarHelge Deller <deller@gmx.de>
parent 5e01dc7b
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -515,5 +515,17 @@
	nop	/* 7 */
	.endm

	/*
	 * ASM_EXCEPTIONTABLE_ENTRY
	 *
	 * Creates an exception table entry.
	 * Do not convert to a assembler macro. This won't work.
	 */
#define ASM_EXCEPTIONTABLE_ENTRY(fault_addr, except_addr)	\
	.section __ex_table,"aw"			!	\
	ASM_ULONG_INSN	fault_addr, except_addr		!	\
	.previous


#endif /* __ASSEMBLY__ */
#endif
+4 −3
Original line number Diff line number Diff line
@@ -59,12 +59,13 @@ static inline long access_ok(int type, const void __user * addr,
/*
 * The exception table contains two values: the first is an address
 * for an instruction that is allowed to fault, and the second is
 * the address to the fixup routine. 
 * the address to the fixup routine. Even on a 64bit kernel we could
 * use a 32bit (unsigned int) address here.
 */

struct exception_table_entry {
	unsigned long insn;	/* address of insn that is allowed to fault. */
	long fixup;          /* fixup routine */
	unsigned long fixup;	/* fixup routine */
};

#define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\
+2 −4
Original line number Diff line number Diff line
@@ -649,10 +649,8 @@ cas_action:
	/* Two exception table entries, one for the load,
	   the other for the store. Either return -EFAULT.
	   Each of the entries must be relocated. */
	.section __ex_table,"aw"
	ASM_ULONG_INSN (1b - linux_gateway_page), (3b - linux_gateway_page)
	ASM_ULONG_INSN (2b - linux_gateway_page), (3b - linux_gateway_page)
	.previous
	ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 3b-linux_gateway_page)
	ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 3b-linux_gateway_page)


	/* Make sure nothing else is placed on this page */
+3 −7
Original line number Diff line number Diff line
@@ -88,9 +88,7 @@ ENDPROC(lclear_user)
	ldo        1(%r25),%r25
	.previous

	.section __ex_table,"aw"
	ASM_ULONG_INSN 1b,2b
	.previous
	ASM_EXCEPTIONTABLE_ENTRY(1b,2b)

	.procend

@@ -129,10 +127,8 @@ ENDPROC(lstrnlen_user)
	copy        %r24,%r26    /* reset r26 so 0 is returned on fault */
	.previous

	.section __ex_table,"aw"
	ASM_ULONG_INSN 1b,3b
	ASM_ULONG_INSN 2b,3b
	.previous
	ASM_EXCEPTIONTABLE_ENTRY(1b,3b)
	ASM_EXCEPTIONTABLE_ENTRY(2b,3b)

	.procend

+6 −0
Original line number Diff line number Diff line
@@ -142,6 +142,12 @@ int fixup_exception(struct pt_regs *regs)
{
	const struct exception_table_entry *fix;

	/* If we only stored 32bit addresses in the exception table we can drop
	 * out if we faulted on a 64bit address. */
	if ((sizeof(regs->iaoq[0]) > sizeof(fix->insn))
		&& (regs->iaoq[0] >> 32))
			return 0;

	fix = search_exception_tables(regs->iaoq[0]);
	if (fix) {
		struct exception_data *d;