Re: [RFC PATCH 9/9] arm64/debug: Mark debug exception helpers __always_inline
From: Mark Rutland
Date: Fri Jul 31 2026 - 12:24:29 EST
On Mon, Jul 27, 2026 at 12:25:48PM +0000, Hongyan Xia wrote:
> From: Hongyan Xia <hongyan.xia@xxxxxxxxxxxxx>
>
> Static inline should be enough to actually inline functions for most
> compilers, but my Clang-19 somehow thinks it's better to outline them.
> These tiny helpers then live in normal .text sections instead of
> .noinstr sections, violating noinstr.
>
> Mark them __always_inline so the compiler can never outline them.
>
> Signed-off-by: Hongyan Xia <hongyan.xia@xxxxxxxxxxxxx>
> ---
> arch/arm64/include/asm/esr.h | 2 +-
> arch/arm64/include/asm/percpu.h | 2 +-
> arch/arm64/include/asm/preempt.h | 4 ++--
> arch/arm64/include/asm/ptrace.h | 4 ++--
> arch/arm64/kernel/debug-monitors.c | 2 +-
> include/linux/kprobes.h | 8 ++++----
> 6 files changed, 11 insertions(+), 11 deletions(-)
I think this should be split into separate patches. In particular, the
preempt count helpers are used in mane other places than debug
exceptions, and if those are used in noinstr code today, we need to
backport those as fixes.
Mark.
> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> index f816f5d77f1a..a75bfdb7e5fe 100644
> --- a/arch/arm64/include/asm/esr.h
> +++ b/arch/arm64/include/asm/esr.h
> @@ -437,7 +437,7 @@
> #ifndef __ASSEMBLER__
> #include <asm/types.h>
>
> -static inline unsigned long esr_brk_comment(unsigned long esr)
> +static __always_inline unsigned long esr_brk_comment(unsigned long esr)
> {
> return esr & ESR_ELx_BRK64_ISS_COMMENT_MASK;
> }
> diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h
> index b57b2bb00967..d4cae47fde8c 100644
> --- a/arch/arm64/include/asm/percpu.h
> +++ b/arch/arm64/include/asm/percpu.h
> @@ -29,7 +29,7 @@ static inline unsigned long __hyp_my_cpu_offset(void)
> return read_sysreg(tpidr_el2);
> }
>
> -static inline unsigned long __kern_my_cpu_offset(void)
> +static __always_inline unsigned long __kern_my_cpu_offset(void)
> {
> unsigned long off;
>
> 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/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
> index 39582511ad72..460726224299 100644
> --- a/arch/arm64/include/asm/ptrace.h
> +++ b/arch/arm64/include/asm/ptrace.h
> @@ -336,11 +336,11 @@ static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs,
> struct task_struct;
> int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task);
>
> -static inline unsigned long instruction_pointer(struct pt_regs *regs)
> +static __always_inline unsigned long instruction_pointer(struct pt_regs *regs)
> {
> return regs->pc;
> }
> -static inline void instruction_pointer_set(struct pt_regs *regs,
> +static __always_inline void instruction_pointer_set(struct pt_regs *regs,
> unsigned long val)
> {
> regs->pc = val;
> diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
> index a970ab6327cd..66cb8151f5df 100644
> --- a/arch/arm64/kernel/debug-monitors.c
> +++ b/arch/arm64/kernel/debug-monitors.c
> @@ -146,7 +146,7 @@ postcore_initcall(debug_monitors_init);
> /*
> * Single step API and exception handling.
> */
> -static void set_user_regs_spsr_ss(struct user_pt_regs *regs)
> +static __always_inline void set_user_regs_spsr_ss(struct user_pt_regs *regs)
> {
> regs->pstate |= DBG_SPSR_SS;
> }
> diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
> index 8c4f3bb24429..5880445ed0f0 100644
> --- a/include/linux/kprobes.h
> +++ b/include/linux/kprobes.h
> @@ -384,17 +384,17 @@ static inline void kprobe_ftrace_kill(void) {}
> struct kprobe *get_kprobe(void *addr);
>
> /* kprobe_running() will just return the current_kprobe on this CPU */
> -static inline struct kprobe *kprobe_running(void)
> +static __always_inline struct kprobe *kprobe_running(void)
> {
> return __this_cpu_read(current_kprobe);
> }
>
> -static inline void reset_current_kprobe(void)
> +static __always_inline void reset_current_kprobe(void)
> {
> __this_cpu_write(current_kprobe, NULL);
> }
>
> -static inline struct kprobe_ctlblk *get_kprobe_ctlblk(void)
> +static __always_inline struct kprobe_ctlblk *get_kprobe_ctlblk(void)
> {
> return this_cpu_ptr(&kprobe_ctlblk);
> }
> @@ -449,7 +449,7 @@ static inline struct kprobe *get_kprobe(void *addr)
> {
> return NULL;
> }
> -static inline struct kprobe *kprobe_running(void)
> +static __always_inline struct kprobe *kprobe_running(void)
> {
> return NULL;
> }
> --
> 2.47.3
>