diff mbox series

[2/8] arm64: remove __exception annotations

Message ID 20191003171642.135652-3-james.morse@arm.com (mailing list archive)
State New, archived
Headers show
Series arm64: Convert entry.S synchronous exception handling to C | expand

Commit Message

James Morse Oct. 3, 2019, 5:16 p.m. UTC
Since commit 732674980139 ("arm64: unwind: reference pt_regs via embedded
stack frame") arm64 has has not used the __exception annotation to dump
the pt_regs during stack tracing. in_exception_text() has no callers.

This annotation is only used to blacklist kprobes, it means the same as
__kprobes.

Section annotations like this require the functions to be grouped
together between the start/end markers, and placed according to
the linker script. For kprobes we also have NOKPROBE_SYMBOL() which
logs the symbol address in a section that kprobes parses and
blacklists at boot.

Using NOKPROBE_SYMBOL() instead lets kprobes publish the list of
blacklisted symbols, and saves us from having an arm64 specific
spelling of __kprobes.

Signed-off-by: James Morse <james.morse@arm.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>

---
(__exception_irq_entry means no-kprobes and optionally in a section
 ftrace can use to pretty-print interrupt handler boundaries.)
---
 arch/arm64/include/asm/exception.h |  4 ++--
 arch/arm64/include/asm/traps.h     | 10 ---------
 arch/arm64/kernel/probes/kprobes.c |  4 ----
 arch/arm64/kernel/traps.c          | 10 ++++++---
 arch/arm64/kernel/vmlinux.lds.S    |  3 ---
 arch/arm64/mm/fault.c              | 34 +++++++++++++++---------------
 6 files changed, 26 insertions(+), 39 deletions(-)

Comments

Mark Rutland Oct. 4, 2019, 10:17 a.m. UTC | #1
On Thu, Oct 03, 2019 at 06:16:36PM +0100, James Morse wrote:
> Since commit 732674980139 ("arm64: unwind: reference pt_regs via embedded
> stack frame") arm64 has has not used the __exception annotation to dump
> the pt_regs during stack tracing. in_exception_text() has no callers.
> 
> This annotation is only used to blacklist kprobes, it means the same as
> __kprobes.
> 
> Section annotations like this require the functions to be grouped
> together between the start/end markers, and placed according to
> the linker script. For kprobes we also have NOKPROBE_SYMBOL() which
> logs the symbol address in a section that kprobes parses and
> blacklists at boot.
> 
> Using NOKPROBE_SYMBOL() instead lets kprobes publish the list of
> blacklisted symbols, and saves us from having an arm64 specific
> spelling of __kprobes.
> 
> Signed-off-by: James Morse <james.morse@arm.com>
> Cc: Masami Hiramatsu <mhiramat@kernel.org>
> 
> ---
> (__exception_irq_entry means no-kprobes and optionally in a section
>  ftrace can use to pretty-print interrupt handler boundaries.)
> ---
>  arch/arm64/include/asm/exception.h |  4 ++--
>  arch/arm64/include/asm/traps.h     | 10 ---------
>  arch/arm64/kernel/probes/kprobes.c |  4 ----
>  arch/arm64/kernel/traps.c          | 10 ++++++---
>  arch/arm64/kernel/vmlinux.lds.S    |  3 ---
>  arch/arm64/mm/fault.c              | 34 +++++++++++++++---------------
>  6 files changed, 26 insertions(+), 39 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
> index a17393ff6677..b0b3ba56e919 100644
> --- a/arch/arm64/include/asm/exception.h
> +++ b/arch/arm64/include/asm/exception.h

[...]

> -asmlinkage void __exception do_debug_exception(unsigned long addr_if_watchpoint,
> -					       unsigned int esr,
> -					       struct pt_regs *regs)
> +asmlinkage void do_debug_exception(unsigned long addr_if_watchpoint,
> +				   unsigned int esr, struct pt_regs *regs)
>  {
>  	const struct fault_info *inf = esr_to_debug_fault_info(esr);
>  	unsigned long pc = instruction_pointer(regs);

I assume you meant to add NOKPROBE_SYMBOL(do_debug_exception) here.

Assuming so, and with that fixed up:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Mark.
Marc Gonzalez Oct. 4, 2019, 1:03 p.m. UTC | #2
On 03/10/2019 19:16, James Morse wrote:

> Since commit 732674980139 ("arm64: unwind: reference pt_regs via embedded
> stack frame") arm64 has has not used the __exception annotation to dump

s/has has not/has not/  ?
Masami Hiramatsu (Google) Oct. 4, 2019, 2:10 p.m. UTC | #3
On Fri, 4 Oct 2019 11:17:17 +0100
Mark Rutland <mark.rutland@arm.com> wrote:

> On Thu, Oct 03, 2019 at 06:16:36PM +0100, James Morse wrote:
> > Since commit 732674980139 ("arm64: unwind: reference pt_regs via embedded
> > stack frame") arm64 has has not used the __exception annotation to dump
> > the pt_regs during stack tracing. in_exception_text() has no callers.
> > 
> > This annotation is only used to blacklist kprobes, it means the same as
> > __kprobes.
> > 
> > Section annotations like this require the functions to be grouped
> > together between the start/end markers, and placed according to
> > the linker script. For kprobes we also have NOKPROBE_SYMBOL() which
> > logs the symbol address in a section that kprobes parses and
> > blacklists at boot.
> > 
> > Using NOKPROBE_SYMBOL() instead lets kprobes publish the list of
> > blacklisted symbols, and saves us from having an arm64 specific
> > spelling of __kprobes.
> > 
> > Signed-off-by: James Morse <james.morse@arm.com>
> > Cc: Masami Hiramatsu <mhiramat@kernel.org>
> > 
> > ---
> > (__exception_irq_entry means no-kprobes and optionally in a section
> >  ftrace can use to pretty-print interrupt handler boundaries.)
> > ---
> >  arch/arm64/include/asm/exception.h |  4 ++--
> >  arch/arm64/include/asm/traps.h     | 10 ---------
> >  arch/arm64/kernel/probes/kprobes.c |  4 ----
> >  arch/arm64/kernel/traps.c          | 10 ++++++---
> >  arch/arm64/kernel/vmlinux.lds.S    |  3 ---
> >  arch/arm64/mm/fault.c              | 34 +++++++++++++++---------------
> >  6 files changed, 26 insertions(+), 39 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
> > index a17393ff6677..b0b3ba56e919 100644
> > --- a/arch/arm64/include/asm/exception.h
> > +++ b/arch/arm64/include/asm/exception.h
> 
> [...]
> 
> > -asmlinkage void __exception do_debug_exception(unsigned long addr_if_watchpoint,
> > -					       unsigned int esr,
> > -					       struct pt_regs *regs)
> > +asmlinkage void do_debug_exception(unsigned long addr_if_watchpoint,
> > +				   unsigned int esr, struct pt_regs *regs)
> >  {
> >  	const struct fault_info *inf = esr_to_debug_fault_info(esr);
> >  	unsigned long pc = instruction_pointer(regs);
> 
> I assume you meant to add NOKPROBE_SYMBOL(do_debug_exception) here.
> 
> Assuming so, and with that fixed up:
> 
> Acked-by: Mark Rutland <mark.rutland@arm.com>

Good catch, if so, this looks good to me too.
with that fixed up:

Acked-by: Masami Hiramatsu <mhiramat@kernel.org>

Thanks!
James Morse Oct. 4, 2019, 4:08 p.m. UTC | #4
Hi guys,

On 04/10/2019 15:10, Masami Hiramatsu wrote:
> On Fri, 4 Oct 2019 11:17:17 +0100
> Mark Rutland <mark.rutland@arm.com> wrote:
>> On Thu, Oct 03, 2019 at 06:16:36PM +0100, James Morse wrote:
>>> Since commit 732674980139 ("arm64: unwind: reference pt_regs via embedded
>>> stack frame") arm64 has has not used the __exception annotation to dump
>>> the pt_regs during stack tracing. in_exception_text() has no callers.
>>>
>>> This annotation is only used to blacklist kprobes, it means the same as
>>> __kprobes.
>>>
>>> Section annotations like this require the functions to be grouped
>>> together between the start/end markers, and placed according to
>>> the linker script. For kprobes we also have NOKPROBE_SYMBOL() which
>>> logs the symbol address in a section that kprobes parses and
>>> blacklists at boot.
>>>
>>> Using NOKPROBE_SYMBOL() instead lets kprobes publish the list of
>>> blacklisted symbols, and saves us from having an arm64 specific
>>> spelling of __kprobes.

>>> diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
>>> index a17393ff6677..b0b3ba56e919 100644
>>> --- a/arch/arm64/include/asm/exception.h
>>> +++ b/arch/arm64/include/asm/exception.h
>>
>> [...]
>>
>>> -asmlinkage void __exception do_debug_exception(unsigned long addr_if_watchpoint,
>>> -					       unsigned int esr,
>>> -					       struct pt_regs *regs)
>>> +asmlinkage void do_debug_exception(unsigned long addr_if_watchpoint,
>>> +				   unsigned int esr, struct pt_regs *regs)
>>>  {
>>>  	const struct fault_info *inf = esr_to_debug_fault_info(esr);
>>>  	unsigned long pc = instruction_pointer(regs);
>>
>> I assume you meant to add NOKPROBE_SYMBOL(do_debug_exception) here.
>>
>> Assuming so, and with that fixed up:
>>
>> Acked-by: Mark Rutland <mark.rutland@arm.com>
> 
> Good catch, if so, this looks good to me too.

I should have noted it in the commit message, but the NOKPROBE_SYMBOL(do_debug_exception)
is already there! Added by commit 2dd0e8d2d2a15 ("arm64: Kprobes with single stepping
support").

(kprobing the debug handler is so bad, we blacklist it twice!)

I'll fix the commit message.


> with that fixed up:
> 
> Acked-by: Masami Hiramatsu <mhiramat@kernel.org>

I assume you're both happy for me to apply these tags.


Thanks,

James
James Morse Oct. 4, 2019, 4:08 p.m. UTC | #5
On 04/10/2019 14:03, Marc Gonzalez wrote:
> On 03/10/2019 19:16, James Morse wrote:
> 
>> Since commit 732674980139 ("arm64: unwind: reference pt_regs via embedded
>> stack frame") arm64 has has not used the __exception annotation to dump
> 
> s/has has not/has not/  ?

oops!


Thanks,

James
Mark Rutland Oct. 4, 2019, 4:34 p.m. UTC | #6
On Fri, Oct 04, 2019 at 05:08:11PM +0100, James Morse wrote:
> On 04/10/2019 15:10, Masami Hiramatsu wrote:
> > On Fri, 4 Oct 2019 11:17:17 +0100
> > Mark Rutland <mark.rutland@arm.com> wrote:
> >> On Thu, Oct 03, 2019 at 06:16:36PM +0100, James Morse wrote:
> >>> Since commit 732674980139 ("arm64: unwind: reference pt_regs via embedded
> >>> stack frame") arm64 has has not used the __exception annotation to dump
> >>> the pt_regs during stack tracing. in_exception_text() has no callers.
> >>>
> >>> This annotation is only used to blacklist kprobes, it means the same as
> >>> __kprobes.
> >>>
> >>> Section annotations like this require the functions to be grouped
> >>> together between the start/end markers, and placed according to
> >>> the linker script. For kprobes we also have NOKPROBE_SYMBOL() which
> >>> logs the symbol address in a section that kprobes parses and
> >>> blacklists at boot.
> >>>
> >>> Using NOKPROBE_SYMBOL() instead lets kprobes publish the list of
> >>> blacklisted symbols, and saves us from having an arm64 specific
> >>> spelling of __kprobes.
> 
> >>> diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
> >>> index a17393ff6677..b0b3ba56e919 100644
> >>> --- a/arch/arm64/include/asm/exception.h
> >>> +++ b/arch/arm64/include/asm/exception.h
> >>
> >> [...]
> >>
> >>> -asmlinkage void __exception do_debug_exception(unsigned long addr_if_watchpoint,
> >>> -					       unsigned int esr,
> >>> -					       struct pt_regs *regs)
> >>> +asmlinkage void do_debug_exception(unsigned long addr_if_watchpoint,
> >>> +				   unsigned int esr, struct pt_regs *regs)
> >>>  {
> >>>  	const struct fault_info *inf = esr_to_debug_fault_info(esr);
> >>>  	unsigned long pc = instruction_pointer(regs);
> >>
> >> I assume you meant to add NOKPROBE_SYMBOL(do_debug_exception) here.
> >>
> >> Assuming so, and with that fixed up:
> >>
> >> Acked-by: Mark Rutland <mark.rutland@arm.com>
> > 
> > Good catch, if so, this looks good to me too.
> 
> I should have noted it in the commit message, but the NOKPROBE_SYMBOL(do_debug_exception)
> is already there! Added by commit 2dd0e8d2d2a15 ("arm64: Kprobes with single stepping
> support").
> 
> (kprobing the debug handler is so bad, we blacklist it twice!)

Ah; neat!

> I'll fix the commit message.
> 
> 
> > with that fixed up:
> > 
> > Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
> 
> I assume you're both happy for me to apply these tags.

Certainly!

Mark.
diff mbox series

Patch

diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index a17393ff6677..b0b3ba56e919 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -8,14 +8,14 @@ 
 #define __ASM_EXCEPTION_H
 
 #include <asm/esr.h>
+#include <asm/kprobes.h>
 
 #include <linux/interrupt.h>
 
-#define __exception	__attribute__((section(".exception.text")))
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 #define __exception_irq_entry	__irq_entry
 #else
-#define __exception_irq_entry	__exception
+#define __exception_irq_entry	__kprobes
 #endif
 
 static inline u32 disr_to_esr(u64 disr)
diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h
index 59690613ac31..cee5928e1b7d 100644
--- a/arch/arm64/include/asm/traps.h
+++ b/arch/arm64/include/asm/traps.h
@@ -42,16 +42,6 @@  static inline int __in_irqentry_text(unsigned long ptr)
 	       ptr < (unsigned long)&__irqentry_text_end;
 }
 
-static inline int in_exception_text(unsigned long ptr)
-{
-	int in;
-
-	in = ptr >= (unsigned long)&__exception_text_start &&
-	     ptr < (unsigned long)&__exception_text_end;
-
-	return in ? : __in_irqentry_text(ptr);
-}
-
 static inline int in_entry_text(unsigned long ptr)
 {
 	return ptr >= (unsigned long)&__entry_text_start &&
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
index c4452827419b..d1c95dcf1d78 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -455,10 +455,6 @@  int __init arch_populate_kprobe_blacklist(void)
 					(unsigned long)__irqentry_text_end);
 	if (ret)
 		return ret;
-	ret = kprobe_add_area_blacklist((unsigned long)__exception_text_start,
-					(unsigned long)__exception_text_end);
-	if (ret)
-		return ret;
 	ret = kprobe_add_area_blacklist((unsigned long)__idmap_text_start,
 					(unsigned long)__idmap_text_end);
 	if (ret)
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 34739e80211b..ba1a571a7774 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -35,6 +35,7 @@ 
 #include <asm/debug-monitors.h>
 #include <asm/esr.h>
 #include <asm/insn.h>
+#include <asm/kprobes.h>
 #include <asm/traps.h>
 #include <asm/smp.h>
 #include <asm/stack_pointer.h>
@@ -393,7 +394,7 @@  void arm64_notify_segfault(unsigned long addr)
 	force_signal_inject(SIGSEGV, code, addr);
 }
 
-asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
+asmlinkage void do_undefinstr(struct pt_regs *regs)
 {
 	/* check for AArch32 breakpoint instructions */
 	if (!aarch32_break_handler(regs))
@@ -405,6 +406,7 @@  asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
 	BUG_ON(!user_mode(regs));
 	force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc);
 }
+NOKPROBE_SYMBOL(do_undefinstr);
 
 #define __user_cache_maint(insn, address, res)			\
 	if (address >= user_addr_max()) {			\
@@ -667,7 +669,7 @@  static const struct sys64_hook cp15_64_hooks[] = {
 	{},
 };
 
-asmlinkage void __exception do_cp15instr(unsigned int esr, struct pt_regs *regs)
+asmlinkage void do_cp15instr(unsigned int esr, struct pt_regs *regs)
 {
 	const struct sys64_hook *hook, *hook_base;
 
@@ -705,9 +707,10 @@  asmlinkage void __exception do_cp15instr(unsigned int esr, struct pt_regs *regs)
 	 */
 	do_undefinstr(regs);
 }
+NOKPROBE_SYMBOL(do_cp15instr);
 #endif
 
-asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
+asmlinkage void do_sysinstr(unsigned int esr, struct pt_regs *regs)
 {
 	const struct sys64_hook *hook;
 
@@ -724,6 +727,7 @@  asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
 	 */
 	do_undefinstr(regs);
 }
+NOKPROBE_SYMBOL(do_sysinstr);
 
 static const char *esr_class_str[] = {
 	[0 ... ESR_ELx_EC_MAX]		= "UNRECOGNIZED EC",
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index aa76f7259668..009057517bdd 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -111,9 +111,6 @@  SECTIONS
 	}
 	.text : {			/* Real text segment		*/
 		_stext = .;		/* Text and read-only data	*/
-			__exception_text_start = .;
-			*(.exception.text)
-			__exception_text_end = .;
 			IRQENTRY_TEXT
 			SOFTIRQENTRY_TEXT
 			ENTRY_TEXT
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 115d7a0e4b08..ba62098de920 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -33,6 +33,7 @@ 
 #include <asm/debug-monitors.h>
 #include <asm/esr.h>
 #include <asm/kasan.h>
+#include <asm/kprobes.h>
 #include <asm/sysreg.h>
 #include <asm/system_misc.h>
 #include <asm/pgtable.h>
@@ -723,8 +724,8 @@  static const struct fault_info fault_info[] = {
 	{ do_bad,		SIGKILL, SI_KERNEL,	"unknown 63"			},
 };
 
-asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
-					 struct pt_regs *regs)
+asmlinkage void do_mem_abort(unsigned long addr, unsigned int esr,
+			     struct pt_regs *regs)
 {
 	const struct fault_info *inf = esr_to_fault_info(esr);
 
@@ -740,16 +741,17 @@  asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
 	arm64_notify_die(inf->name, regs,
 			 inf->sig, inf->code, (void __user *)addr, esr);
 }
+NOKPROBE_SYMBOL(do_mem_abort);
 
-asmlinkage void __exception do_el0_irq_bp_hardening(void)
+asmlinkage void do_el0_irq_bp_hardening(void)
 {
 	/* PC has already been checked in entry.S */
 	arm64_apply_bp_hardening();
 }
+NOKPROBE_SYMBOL(do_el0_irq_bp_hardening);
 
-asmlinkage void __exception do_el0_ia_bp_hardening(unsigned long addr,
-						   unsigned int esr,
-						   struct pt_regs *regs)
+asmlinkage void do_el0_ia_bp_hardening(unsigned long addr,  unsigned int esr,
+				       struct pt_regs *regs)
 {
 	/*
 	 * We've taken an instruction abort from userspace and not yet
@@ -762,11 +764,10 @@  asmlinkage void __exception do_el0_ia_bp_hardening(unsigned long addr,
 	local_daif_restore(DAIF_PROCCTX);
 	do_mem_abort(addr, esr, regs);
 }
+NOKPROBE_SYMBOL(do_el0_ia_bp_hardening);
 
-
-asmlinkage void __exception do_sp_pc_abort(unsigned long addr,
-					   unsigned int esr,
-					   struct pt_regs *regs)
+asmlinkage void do_sp_pc_abort(unsigned long addr, unsigned int esr,
+			       struct pt_regs *regs)
 {
 	if (user_mode(regs)) {
 		if (!is_ttbr0_addr(instruction_pointer(regs)))
@@ -777,6 +778,7 @@  asmlinkage void __exception do_sp_pc_abort(unsigned long addr,
 	arm64_notify_die("SP/PC alignment exception", regs,
 			 SIGBUS, BUS_ADRALN, (void __user *)addr, esr);
 }
+NOKPROBE_SYMBOL(do_sp_pc_abort);
 
 int __init early_brk64(unsigned long addr, unsigned int esr,
 		       struct pt_regs *regs);
@@ -859,8 +861,7 @@  NOKPROBE_SYMBOL(debug_exception_exit);
 #ifdef CONFIG_ARM64_ERRATUM_1463225
 DECLARE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa);
 
-static int __exception
-cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
+static int cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
 {
 	if (user_mode(regs))
 		return 0;
@@ -879,16 +880,15 @@  cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
 	return 1;
 }
 #else
-static int __exception
-cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
+static int cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
 {
 	return 0;
 }
 #endif /* CONFIG_ARM64_ERRATUM_1463225 */
+NOKPROBE_SYMBOL(cortex_a76_erratum_1463225_debug_handler);
 
-asmlinkage void __exception do_debug_exception(unsigned long addr_if_watchpoint,
-					       unsigned int esr,
-					       struct pt_regs *regs)
+asmlinkage void do_debug_exception(unsigned long addr_if_watchpoint,
+				   unsigned int esr, struct pt_regs *regs)
 {
 	const struct fault_info *inf = esr_to_debug_fault_info(esr);
 	unsigned long pc = instruction_pointer(regs);