Re: [PATCH v2 1/2] syscall_user_dispatch: Make it configurable in Kconfig
From: Randy Dunlap
Date: Tue Jul 07 2026 - 20:35:00 EST
On 7/3/26 6:58 PM, Gregory Price wrote:
> Syscall User Dispatch is presently built under CONFIG_GENERIC_SYSCALL
> and cannot be disabled independently.
>
> Add CONFIG_SYSCALL_USER_DISPATCH to make it an optional feature.
>
> Signed-off-by: Gregory Price <gourry@xxxxxxxxxx>
> ---
> arch/Kconfig | 11 ++++++++
> include/linux/entry-common.h | 6 ++---
> include/linux/syscall_user_dispatch.h | 28 +++++++++++++++++++--
> include/linux/syscall_user_dispatch_types.h | 2 +-
> kernel/entry/Makefile | 3 ++-
> 5 files changed, 42 insertions(+), 8 deletions(-)
>
> diff --git a/arch/Kconfig b/arch/Kconfig
> index fa7507ac8e13..192b9d8abb5f 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -114,6 +114,17 @@ config GENERIC_ENTRY
> select GENERIC_IRQ_ENTRY
> select GENERIC_SYSCALL
>
> +config SYSCALL_USER_DISPATCH
> + bool "Syscall User Dispatch"
> + depends on GENERIC_ENTRY
> + default y
> + help
> + Syscall User Dispatch lets a thread have its own system calls outside
> + an allowed IP address range to be intercepted and redirected to a
> + userspace signal handler.
If it hasn't already been mentioned and repaired, the help text lines should
all be indented with one tab + 2 spaces.
> +
> + If unsure, say Y.
> +
> config KPROBES
> bool "Kprobes"
> depends on HAVE_KPROBES
> diff --git a/include/linux/entry-common.h b/include/linux/entry-common.h
> index 416a3352261f..9336516430a1 100644
> --- a/include/linux/entry-common.h
> +++ b/include/linux/entry-common.h
> @@ -9,6 +9,7 @@
> #include <linux/resume_user_mode.h>
> #include <linux/seccomp.h>
> #include <linux/sched.h>
> +#include <linux/syscall_user_dispatch.h>
>
> #include <asm/entry-common.h>
> #include <asm/syscall.h>
> @@ -55,7 +56,6 @@ static __always_inline int arch_ptrace_report_syscall_entry(struct pt_regs *regs
> }
> #endif
>
> -bool syscall_user_dispatch(struct pt_regs *regs);
> long trace_syscall_enter(struct pt_regs *regs, long syscall);
> void trace_syscall_exit(struct pt_regs *regs, long ret);
>
> @@ -232,10 +232,8 @@ static __always_inline void syscall_exit_work(struct pt_regs *regs, unsigned lon
> * of these syscalls is unknown.
> */
> if (work & SYSCALL_WORK_SYSCALL_USER_DISPATCH) {
> - if (unlikely(current->syscall_dispatch.on_dispatch)) {
> - current->syscall_dispatch.on_dispatch = false;
> + if (syscall_user_dispatch_clear_on_dispatch())
> return;
> - }
> }
>
> audit_syscall_exit(regs);
> diff --git a/include/linux/syscall_user_dispatch.h b/include/linux/syscall_user_dispatch.h
> index 3858a6ffdd5c..c466af02da36 100644
> --- a/include/linux/syscall_user_dispatch.h
> +++ b/include/linux/syscall_user_dispatch.h
> @@ -7,8 +7,22 @@
>
> #include <linux/thread_info.h>
> #include <linux/syscall_user_dispatch_types.h>
> +#include <linux/sched.h>
>
> -#ifdef CONFIG_GENERIC_ENTRY
> +struct pt_regs;
> +
> +#ifdef CONFIG_SYSCALL_USER_DISPATCH
> +
> +bool syscall_user_dispatch(struct pt_regs *regs);
> +
> +static __always_inline bool syscall_user_dispatch_clear_on_dispatch(void)
> +{
> + if (likely(!current->syscall_dispatch.on_dispatch))
> + return false;
> +
> + current->syscall_dispatch.on_dispatch = false;
> + return true;
> +}
>
> int set_syscall_user_dispatch(unsigned long mode, unsigned long offset,
> unsigned long len, char __user *selector);
> @@ -24,6 +38,16 @@ int syscall_user_dispatch_set_config(struct task_struct *task, unsigned long siz
>
> #else
>
> +static inline bool syscall_user_dispatch(struct pt_regs *regs)
> +{
> + return false;
> +}
> +
> +static inline bool syscall_user_dispatch_clear_on_dispatch(void)
> +{
> + return false;
> +}
> +
> static inline int set_syscall_user_dispatch(unsigned long mode, unsigned long offset,
> unsigned long len, char __user *selector)
> {
> @@ -46,6 +70,6 @@ static inline int syscall_user_dispatch_set_config(struct task_struct *task,
> return -EINVAL;
> }
>
> -#endif /* CONFIG_GENERIC_ENTRY */
> +#endif /* CONFIG_SYSCALL_USER_DISPATCH */
>
> #endif /* _SYSCALL_USER_DISPATCH_H */
> diff --git a/include/linux/syscall_user_dispatch_types.h b/include/linux/syscall_user_dispatch_types.h
> index 3be36b06c7d7..c0bdd4f760d3 100644
> --- a/include/linux/syscall_user_dispatch_types.h
> +++ b/include/linux/syscall_user_dispatch_types.h
> @@ -4,7 +4,7 @@
>
> #include <linux/types.h>
>
> -#ifdef CONFIG_GENERIC_ENTRY
> +#ifdef CONFIG_SYSCALL_USER_DISPATCH
>
> struct syscall_user_dispatch {
> char __user *selector;
> diff --git a/kernel/entry/Makefile b/kernel/entry/Makefile
> index 2333d70802e4..f220bae86b12 100644
> --- a/kernel/entry/Makefile
> +++ b/kernel/entry/Makefile
> @@ -13,5 +13,6 @@ CFLAGS_REMOVE_common.o = -fstack-protector -fstack-protector-strong
> CFLAGS_common.o += -fno-stack-protector
>
> obj-$(CONFIG_GENERIC_IRQ_ENTRY) += common.o
> -obj-$(CONFIG_GENERIC_SYSCALL) += syscall-common.o syscall_user_dispatch.o
> +obj-$(CONFIG_GENERIC_SYSCALL) += syscall-common.o
> +obj-$(CONFIG_SYSCALL_USER_DISPATCH) += syscall_user_dispatch.o
> obj-$(CONFIG_VIRT_XFER_TO_GUEST_WORK) += virt.o
--
~Randy