[PATCH 2/3] arm64: Move do_notify_resume() to entry-common.c

Liao, Chang liaochang1 at huawei.com
Mon Feb 26 19:25:32 PST 2024


Hi, Mark

在 2024/2/6 20:38, Mark Rutland 写道:
> Currently do_notify_resume() lives in arch/arm64/kernel/signal.c, but it would
> make more sense for it to live in entry-common.c as it handles more than
> signals, and is coupled with the rest of the return-to-userspace sequence (e.g.
> with unusual DAIF masking that matches the exception return requirements).
> 
> Move do_notify_resume() to entry-common.c.
> 
> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: James Morse <james.morse at arm.com>
> Cc: Mark Brown <broonie at kernel.org>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/include/asm/exception.h |  2 +-
>  arch/arm64/kernel/entry-common.c   | 32 +++++++++++++++++++++++++++
>  arch/arm64/kernel/signal.c         | 35 ++----------------------------
>  3 files changed, 35 insertions(+), 34 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
> index ad688e157c9be..f296662590c7f 100644
> --- a/arch/arm64/include/asm/exception.h
> +++ b/arch/arm64/include/asm/exception.h
> @@ -74,7 +74,7 @@ void do_el0_fpac(struct pt_regs *regs, unsigned long esr);
>  void do_el1_fpac(struct pt_regs *regs, unsigned long esr);
>  void do_el0_mops(struct pt_regs *regs, unsigned long esr);
>  void do_serror(struct pt_regs *regs, unsigned long esr);
> -void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags);
> +void do_signal(struct pt_regs *regs);
>  
>  void __noreturn panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far);
>  #endif	/* __ASM_EXCEPTION_H */
> diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
> index 0fc94207e69a8..3c849ad03bf83 100644
> --- a/arch/arm64/kernel/entry-common.c
> +++ b/arch/arm64/kernel/entry-common.c
> @@ -10,6 +10,7 @@
>  #include <linux/linkage.h>
>  #include <linux/lockdep.h>
>  #include <linux/ptrace.h>
> +#include <linux/resume_user_mode.h>
>  #include <linux/sched.h>
>  #include <linux/sched/debug.h>
>  #include <linux/thread_info.h>
> @@ -126,6 +127,37 @@ static __always_inline void __exit_to_user_mode(void)
>  	lockdep_hardirqs_on(CALLER_ADDR0);
>  }
>  
> +static void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
> +{
> +	do {
> +		local_daif_restore(DAIF_PROCCTX);
> +
> +		if (thread_flags & _TIF_NEED_RESCHED)
> +			schedule();
> +
> +		if (thread_flags & _TIF_UPROBE)
> +			uprobe_notify_resume(regs);
> +
> +		if (thread_flags & _TIF_MTE_ASYNC_FAULT) {
> +			clear_thread_flag(TIF_MTE_ASYNC_FAULT);
> +			send_sig_fault(SIGSEGV, SEGV_MTEAERR,
> +				       (void __user *)NULL, current);
> +		}
> +
> +		if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
> +			do_signal(regs);
> +
> +		if (thread_flags & _TIF_NOTIFY_RESUME)
> +			resume_user_mode_work(regs);
> +
> +		if (thread_flags & _TIF_FOREIGN_FPSTATE)
> +			fpsimd_restore_current_state();
> +
> +		local_daif_mask();
> +		thread_flags = read_thread_flags();
> +	} while (thread_flags & _TIF_WORK_MASK);
> +}

What about moving load_daif_restore() and load_daif_mask() outside of the do-while loop?
Invoking them repeatedlly within the loop is redundant, right?

Thanks.

> +
>  static __always_inline void exit_to_user_mode_prepare(struct pt_regs *regs)
>  {
>  	unsigned long flags;
> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> index 50e108741599d..c08e6465e0f49 100644
> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -16,8 +16,8 @@
>  #include <linux/uaccess.h>
>  #include <linux/sizes.h>
>  #include <linux/string.h>
> -#include <linux/resume_user_mode.h>
>  #include <linux/ratelimit.h>
> +#include <linux/rseq.h>
>  #include <linux/syscalls.h>
>  
>  #include <asm/daifflags.h>
> @@ -1207,7 +1207,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
>   * the kernel can handle, and then we build all the user-level signal handling
>   * stack-frames in one go after that.
>   */
> -static void do_signal(struct pt_regs *regs)
> +void do_signal(struct pt_regs *regs)
>  {
>  	unsigned long continue_addr = 0, restart_addr = 0;
>  	int retval = 0;
> @@ -1278,37 +1278,6 @@ static void do_signal(struct pt_regs *regs)
>  	restore_saved_sigmask();
>  }
>  
> -void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
> -{
> -	do {
> -		local_daif_restore(DAIF_PROCCTX);
> -
> -		if (thread_flags & _TIF_NEED_RESCHED)
> -			schedule();
> -
> -		if (thread_flags & _TIF_UPROBE)
> -			uprobe_notify_resume(regs);
> -
> -		if (thread_flags & _TIF_MTE_ASYNC_FAULT) {
> -			clear_thread_flag(TIF_MTE_ASYNC_FAULT);
> -			send_sig_fault(SIGSEGV, SEGV_MTEAERR,
> -				       (void __user *)NULL, current);
> -		}
> -
> -		if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
> -			do_signal(regs);
> -
> -		if (thread_flags & _TIF_NOTIFY_RESUME)
> -			resume_user_mode_work(regs);
> -
> -		if (thread_flags & _TIF_FOREIGN_FPSTATE)
> -			fpsimd_restore_current_state();
> -
> -		local_daif_mask();
> -		thread_flags = read_thread_flags();
> -	} while (thread_flags & _TIF_WORK_MASK);
> -}
> -
>  unsigned long __ro_after_init signal_minsigstksz;
>  
>  /*

-- 
BR
Liao, Chang



More information about the linux-arm-kernel mailing list