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

Commit 61a92f70 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

powerpc: Add support for relative exception tables



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

Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
[mpe: Minor asm fixups and bits to keep the selftests working]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 24bfa6a9
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -785,9 +785,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 */
#define EX_TABLE(_fault, _target)		\
	stringify_in_c(.section __ex_table,"a";)\
	PPC_LONG_ALIGN stringify_in_c(;)	\
	PPC_LONG stringify_in_c(_fault;)	\
	PPC_LONG stringify_in_c(_target;)	\
	stringify_in_c(.balign 4;)		\
	stringify_in_c(.long (_fault) - . ;)	\
	stringify_in_c(.long (_target) - . ;)	\
	stringify_in_c(.previous)

#endif /* _ASM_POWERPC_PPC_ASM_H */
+17 −10
Original line number Diff line number Diff line
@@ -64,23 +64,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.
+1 −1
Original line number Diff line number Diff line
@@ -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;
		}

+1 −1
Original line number Diff line number Diff line
@@ -365,7 +365,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;
		}
	}
+1 −1
Original line number Diff line number Diff line
@@ -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;
	}

Loading