Re: [RFC PATCH v2 1/4] arm64/entry: Make debug_exception_enter/exit() noinstr

Masami Hiramatsu (Google) <[email protected]>
Newsgroups org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On Thu, 13 Aug 2026 06:49:27 +0000
Hongyan Xia <[email protected]> wrote:

> From: Hongyan Xia <[email protected]>
> 
> Commit 879a6754d3d11e30af24b7dc486f561510d62641 ran into a crash because
> debug_exception_enter/exit() triggered page faults caused by perf dwarf
> call graph tracing. That patch was a band-aid on top.
> 
> Instead of trying to band-aid all possible paths that can happen during
> instrumentation or perf tracing, simply force-inline these functions and
> use the notrace variant of preempt handling to avoid all the complexity.
> 
> Drop the RCU_LOCKDEP_WARN(): arm64_enter_el1_dbg() runs first and
> enters NMI context via ct_nmi_enter(), so RCU is always watching by the
> time debug_exception_enter() runs.
> 
> Also mark __preempt_count_add/sub() __always_inline so the preempt
> count updates fold into the noinstr callers instead of becoming
> outlined calls to instrumentable text.

Looks good to me as a kprobe maintainer.

Reviewed-by: Masami Hiramatsu (Google) <[email protected]>

Thanks,

> 
> Signed-off-by: Hongyan Xia <[email protected]>
> ---
>  arch/arm64/include/asm/preempt.h |  4 ++--
>  arch/arm64/kernel/entry-common.c | 13 ++++---------
>  2 files changed, 6 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/preempt.h b/arch/arm64/include/asm/preempt.h
> index 932ea4b62042..326f221c3f56 100644
> --- a/arch/arm64/include/asm/preempt.h
> +++ b/arch/arm64/include/asm/preempt.h
> @@ -41,14 +41,14 @@ static inline bool test_preempt_need_resched(void)
>  	return !current_thread_info()->preempt.need_resched;
>  }
>  
> -static inline void __preempt_count_add(int val)
> +static __always_inline void __preempt_count_add(int val)
>  {
>  	u32 pc = READ_ONCE(current_thread_info()->preempt.count);
>  	pc += val;
>  	WRITE_ONCE(current_thread_info()->preempt.count, pc);
>  }
>  
> -static inline void __preempt_count_sub(int val)
> +static __always_inline void __preempt_count_sub(int val)
>  {
>  	u32 pc = READ_ONCE(current_thread_info()->preempt.count);
>  	pc -= val;
> diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
> index ceb4eb11232a..d5c1d6defe29 100644
> --- a/arch/arm64/kernel/entry-common.c
> +++ b/arch/arm64/kernel/entry-common.c
> @@ -292,20 +292,15 @@ static __always_inline void fpsimd_syscall_exit(void)
>   * accidentally schedule in exception context and it will force a warning
>   * if we somehow manage to schedule by accident.
>   */
> -static void debug_exception_enter(struct pt_regs *regs)
> +static __always_inline void debug_exception_enter(struct pt_regs *regs)
>  {
> -	preempt_disable();
> -
> -	/* This code is a bit fragile.  Test it. */
> -	RCU_LOCKDEP_WARN(!rcu_is_watching(), "exception_enter didn't work");
> +	preempt_disable_notrace();
>  }
> -NOKPROBE_SYMBOL(debug_exception_enter);
>  
> -static void debug_exception_exit(struct pt_regs *regs)
> +static __always_inline void debug_exception_exit(struct pt_regs *regs)
>  {
> -	preempt_enable_no_resched();
> +	preempt_enable_no_resched_notrace();
>  }
> -NOKPROBE_SYMBOL(debug_exception_exit);
>  
>  UNHANDLED(el1t, 64, sync)
>  UNHANDLED(el1t, 64, irq)
> -- 
> 2.47.3
> 


-- 
Masami Hiramatsu (Google) <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.