* [PATCH] powerpc: remove interrupt handler functions from the noinstr section
@ 2021-02-11 6:36 Nicholas Piggin
2021-02-12 0:20 ` Michael Ellerman
0 siblings, 1 reply; 2+ messages in thread
From: Nicholas Piggin @ 2021-02-11 6:36 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Stephen Rothwell, Nicholas Piggin
The allyesconfig ppc64 kernel fails to link with relocations unable to
fit after commit 3a96570ffceb ("powerpc: convert interrupt handlers to
use wrappers"), which is due to the interrupt handler functions being
put into the .noinstr.text section, which the linker script places on
the opposite side of the main .text section from the interrupt entry
asm code which calls the handlers.
This results in a lot of linker stubs that overwhelm the 252-byte sized
space we allow for them, or in the case of BE a .opd relocation link
error for some reason.
It's not required to put interrupt handlers in the .noinstr section,
previously they used NOKPROBE_SYMBOL, so take them out and replace
with a NOKPROBE_SYMBOL in the wrapper macro. Remove the explicit
NOKPROBE_SYMBOL macros in the interrupt handler functions. This makes
a number of interrupt handlers nokprobe that were not prior to the
interrupt wrappers commit, but since that commit they were made
nokprobe due to being in .noinstr.text, so this fix does not change
that.
The fixes tag is different to the commit that first exposes the problem
because it is where the wrapper macros were introduced.
Fixes: 8d41fc618ab8 ("powerpc: interrupt handler wrapper functions")
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/interrupt.h | 25 ++++++++++++++++++++-----
arch/powerpc/kernel/traps.c | 9 ---------
arch/powerpc/mm/fault.c | 1 -
3 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
index 4badb3e51c19..ffb568587553 100644
--- a/arch/powerpc/include/asm/interrupt.h
+++ b/arch/powerpc/include/asm/interrupt.h
@@ -6,6 +6,7 @@
#include <linux/hardirq.h>
#include <asm/cputime.h>
#include <asm/ftrace.h>
+#include <asm/kprobes.h>
#include <asm/runlatch.h>
struct interrupt_state {
@@ -164,6 +165,15 @@ static inline void interrupt_nmi_exit_prepare(struct pt_regs *regs, struct inter
#endif
}
+/*
+ * Don't use like to use noinstr here like x86, but rather add NOKPROBE_SYMBOL
+ * to each function definition. The reason for this is the noinstr section
+ * is placed after the main text section, i.e., very far away from the
+ * interrupt entry asm. That creates problems with fitting linker stubs when
+ * building large kernels.
+ */
+#define interrupt_handler __visible noinline notrace __no_kcsan __no_sanitize_address
+
/**
* DECLARE_INTERRUPT_HANDLER_RAW - Declare raw interrupt handler function
* @func: Function name of the entry point
@@ -198,7 +208,7 @@ static inline void interrupt_nmi_exit_prepare(struct pt_regs *regs, struct inter
#define DEFINE_INTERRUPT_HANDLER_RAW(func) \
static __always_inline long ____##func(struct pt_regs *regs); \
\
-__visible noinstr long func(struct pt_regs *regs) \
+interrupt_handler long func(struct pt_regs *regs) \
{ \
long ret; \
\
@@ -206,6 +216,7 @@ __visible noinstr long func(struct pt_regs *regs) \
\
return ret; \
} \
+NOKPROBE_SYMBOL(func); \
\
static __always_inline long ____##func(struct pt_regs *regs)
@@ -228,7 +239,7 @@ static __always_inline long ____##func(struct pt_regs *regs)
#define DEFINE_INTERRUPT_HANDLER(func) \
static __always_inline void ____##func(struct pt_regs *regs); \
\
-__visible noinstr void func(struct pt_regs *regs) \
+interrupt_handler void func(struct pt_regs *regs) \
{ \
struct interrupt_state state; \
\
@@ -238,6 +249,7 @@ __visible noinstr void func(struct pt_regs *regs) \
\
interrupt_exit_prepare(regs, &state); \
} \
+NOKPROBE_SYMBOL(func); \
\
static __always_inline void ____##func(struct pt_regs *regs)
@@ -262,7 +274,7 @@ static __always_inline void ____##func(struct pt_regs *regs)
#define DEFINE_INTERRUPT_HANDLER_RET(func) \
static __always_inline long ____##func(struct pt_regs *regs); \
\
-__visible noinstr long func(struct pt_regs *regs) \
+interrupt_handler long func(struct pt_regs *regs) \
{ \
struct interrupt_state state; \
long ret; \
@@ -275,6 +287,7 @@ __visible noinstr long func(struct pt_regs *regs) \
\
return ret; \
} \
+NOKPROBE_SYMBOL(func); \
\
static __always_inline long ____##func(struct pt_regs *regs)
@@ -297,7 +310,7 @@ static __always_inline long ____##func(struct pt_regs *regs)
#define DEFINE_INTERRUPT_HANDLER_ASYNC(func) \
static __always_inline void ____##func(struct pt_regs *regs); \
\
-__visible noinstr void func(struct pt_regs *regs) \
+interrupt_handler void func(struct pt_regs *regs) \
{ \
struct interrupt_state state; \
\
@@ -307,6 +320,7 @@ __visible noinstr void func(struct pt_regs *regs) \
\
interrupt_async_exit_prepare(regs, &state); \
} \
+NOKPROBE_SYMBOL(func); \
\
static __always_inline void ____##func(struct pt_regs *regs)
@@ -331,7 +345,7 @@ static __always_inline void ____##func(struct pt_regs *regs)
#define DEFINE_INTERRUPT_HANDLER_NMI(func) \
static __always_inline long ____##func(struct pt_regs *regs); \
\
-__visible noinstr long func(struct pt_regs *regs) \
+interrupt_handler long func(struct pt_regs *regs) \
{ \
struct interrupt_nmi_state state; \
long ret; \
@@ -344,6 +358,7 @@ __visible noinstr long func(struct pt_regs *regs) \
\
return ret; \
} \
+NOKPROBE_SYMBOL(func); \
\
static __always_inline long ____##func(struct pt_regs *regs)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 39c8b7e9b91a..1583fd1c6010 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -513,7 +513,6 @@ DEFINE_INTERRUPT_HANDLER_NMI(system_reset_exception)
return 0;
}
-NOKPROBE_SYMBOL(system_reset_exception);
/*
* I/O accesses can cause machine checks on powermacs.
@@ -798,7 +797,6 @@ void die_mce(const char *str, struct pt_regs *regs, long err)
nmi_exit();
die(str, regs, err);
}
-NOKPROBE_SYMBOL(die_mce);
/*
* BOOK3S_64 does not call this handler as a non-maskable interrupt
@@ -851,7 +849,6 @@ DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception)
return 0;
#endif
}
-NOKPROBE_SYMBOL(machine_check_exception);
DEFINE_INTERRUPT_HANDLER(SMIException) /* async? */
{
@@ -1113,7 +1110,6 @@ DEFINE_INTERRUPT_HANDLER(single_step_exception)
_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
}
-NOKPROBE_SYMBOL(single_step_exception);
/*
* After we have successfully emulated an instruction, we have to
@@ -1556,7 +1552,6 @@ DEFINE_INTERRUPT_HANDLER(program_check_exception)
{
do_program_check(regs);
}
-NOKPROBE_SYMBOL(program_check_exception);
/*
* This occurs when running in hypervisor mode on POWER6 or later
@@ -1567,7 +1562,6 @@ DEFINE_INTERRUPT_HANDLER(emulation_assist_interrupt)
regs->msr |= REASON_ILLEGAL;
do_program_check(regs);
}
-NOKPROBE_SYMBOL(emulation_assist_interrupt);
DEFINE_INTERRUPT_HANDLER(alignment_exception)
{
@@ -2034,7 +2028,6 @@ DEFINE_INTERRUPT_HANDLER(DebugException)
} else
handle_debug(regs, debug_status);
}
-NOKPROBE_SYMBOL(DebugException);
#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
#ifdef CONFIG_ALTIVEC
@@ -2183,7 +2176,6 @@ DEFINE_INTERRUPT_HANDLER(unrecoverable_exception)
regs->trap, regs->nip, regs->msr);
die("Unrecoverable exception", regs, SIGABRT);
}
-NOKPROBE_SYMBOL(unrecoverable_exception);
#if defined(CONFIG_BOOKE_WDT) || defined(CONFIG_40x)
/*
@@ -2214,7 +2206,6 @@ DEFINE_INTERRUPT_HANDLER(kernel_bad_stack)
regs->gpr[1], regs->nip);
die("Bad kernel stack pointer", regs, SIGABRT);
}
-NOKPROBE_SYMBOL(kernel_bad_stack);
void __init trap_init(void)
{
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index b26a7643fc6e..bb368257b55c 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -566,7 +566,6 @@ DEFINE_INTERRUPT_HANDLER_RET(do_page_fault)
{
return __do_page_fault(regs);
}
-NOKPROBE_SYMBOL(do_page_fault);
#ifdef CONFIG_PPC_BOOK3S_64
/* Same as do_page_fault but interrupt entry has already run in do_hash_fault */
--
2.23.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] powerpc: remove interrupt handler functions from the noinstr section
2021-02-11 6:36 [PATCH] powerpc: remove interrupt handler functions from the noinstr section Nicholas Piggin
@ 2021-02-12 0:20 ` Michael Ellerman
0 siblings, 0 replies; 2+ messages in thread
From: Michael Ellerman @ 2021-02-12 0:20 UTC (permalink / raw)
To: Nicholas Piggin, linuxppc-dev; +Cc: Stephen Rothwell
On Thu, 11 Feb 2021 16:36:36 +1000, Nicholas Piggin wrote:
> The allyesconfig ppc64 kernel fails to link with relocations unable to
> fit after commit 3a96570ffceb ("powerpc: convert interrupt handlers to
> use wrappers"), which is due to the interrupt handler functions being
> put into the .noinstr.text section, which the linker script places on
> the opposite side of the main .text section from the interrupt entry
> asm code which calls the handlers.
>
> [...]
Applied to powerpc/next.
[1/1] powerpc: remove interrupt handler functions from the noinstr section
https://git.kernel.org/powerpc/c/e4bb64c7a42e61bcb6f8b70279fc1f7805eaad3f
cheers
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-02-12 0:48 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-02-11 6:36 [PATCH] powerpc: remove interrupt handler functions from the noinstr section Nicholas Piggin
2021-02-12 0:20 ` Michael Ellerman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).