From: Simon Schuster <schuster.simon@siemens-energy.com>
With the introduction of clone3 in commit 7f192e3cd316 ("fork: add
clone3") the effective bit width of clone_flags on all architectures was
increased from 32-bit to 64-bit, with a new type of u64 for the flags.
However, for most consumers of clone_flags the interface was not
changed from the previous type of unsigned long.
While this works fine as long as none of the new 64-bit flag bits
(CLONE_CLEAR_SIGHAND and CLONE_INTO_CGROUP) are evaluated, this is still
undesirable in terms of the principle of least surprise.
Thus, this commit fixes all relevant interfaces of the copy_thread
function that is called from copy_process to consistently pass
clone_flags as u64, so that no truncation to 32-bit integers occurs on
32-bit architectures.
Signed-off-by: Simon Schuster <schuster.simon@siemens-energy.com>
---
arch/alpha/kernel/process.c | 2 +-
arch/arc/kernel/process.c | 2 +-
arch/arm/kernel/process.c | 2 +-
arch/arm64/kernel/process.c | 2 +-
arch/csky/kernel/process.c | 2 +-
arch/hexagon/kernel/process.c | 2 +-
arch/loongarch/kernel/process.c | 2 +-
arch/m68k/kernel/process.c | 2 +-
arch/microblaze/kernel/process.c | 2 +-
arch/mips/kernel/process.c | 2 +-
arch/nios2/kernel/process.c | 2 +-
arch/openrisc/kernel/process.c | 2 +-
arch/parisc/kernel/process.c | 2 +-
arch/powerpc/kernel/process.c | 2 +-
arch/riscv/kernel/process.c | 2 +-
arch/s390/kernel/process.c | 2 +-
arch/sh/kernel/process_32.c | 2 +-
arch/sparc/kernel/process_32.c | 2 +-
arch/sparc/kernel/process_64.c | 2 +-
arch/um/kernel/process.c | 2 +-
arch/x86/include/asm/fpu/sched.h | 2 +-
arch/x86/include/asm/shstk.h | 4 ++--
arch/x86/kernel/fpu/core.c | 2 +-
arch/x86/kernel/process.c | 2 +-
arch/x86/kernel/shstk.c | 2 +-
arch/xtensa/kernel/process.c | 2 +-
26 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 582d96548385..06522451f018 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -231,7 +231,7 @@ flush_thread(void)
*/
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp = args->stack;
unsigned long tls = args->tls;
extern void ret_from_fork(void);
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c
index 186ceab661eb..8166d0908713 100644
--- a/arch/arc/kernel/process.c
+++ b/arch/arc/kernel/process.c
@@ -166,7 +166,7 @@ asmlinkage void ret_from_fork(void);
*/
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp = args->stack;
unsigned long tls = args->tls;
struct pt_regs *c_regs; /* child's pt_regs */
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index e16ed102960c..d7aa95225c70 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -234,7 +234,7 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long stack_start = args->stack;
unsigned long tls = args->tls;
struct thread_info *thread = task_thread_info(p);
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 96482a1412c6..fba7ca102a8c 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -409,7 +409,7 @@ asmlinkage void ret_from_fork(void) asm("ret_from_fork");
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long stack_start = args->stack;
unsigned long tls = args->tls;
struct pt_regs *childregs = task_pt_regs(p);
diff --git a/arch/csky/kernel/process.c b/arch/csky/kernel/process.c
index 0c6e4b17fe00..a7a90340042a 100644
--- a/arch/csky/kernel/process.c
+++ b/arch/csky/kernel/process.c
@@ -32,7 +32,7 @@ void flush_thread(void){}
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp = args->stack;
unsigned long tls = args->tls;
struct switch_stack *childstack;
diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c
index 2a77bfd75694..15b4992bfa29 100644
--- a/arch/hexagon/kernel/process.c
+++ b/arch/hexagon/kernel/process.c
@@ -52,7 +52,7 @@ void arch_cpu_idle(void)
*/
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp = args->stack;
unsigned long tls = args->tls;
struct thread_info *ti = task_thread_info(p);
diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c
index 3582f591bab2..efd9edf65603 100644
--- a/arch/loongarch/kernel/process.c
+++ b/arch/loongarch/kernel/process.c
@@ -167,7 +167,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
unsigned long childksp;
unsigned long tls = args->tls;
unsigned long usp = args->stack;
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
struct pt_regs *childregs, *regs = current_pt_regs();
childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index fda7eac23f87..f5a07a70e938 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -141,7 +141,7 @@ asmlinkage int m68k_clone3(struct pt_regs *regs)
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp = args->stack;
unsigned long tls = args->tls;
struct fork_frame {
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 56342e11442d..6cbf642d7b80 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -54,7 +54,7 @@ void flush_thread(void)
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp = args->stack;
unsigned long tls = args->tls;
struct pt_regs *childregs = task_pt_regs(p);
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 02aa6a04a21d..29191fa1801e 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -107,7 +107,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
*/
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp = args->stack;
unsigned long tls = args->tls;
struct thread_info *ti = task_thread_info(p);
diff --git a/arch/nios2/kernel/process.c b/arch/nios2/kernel/process.c
index f84021303f6a..151404139085 100644
--- a/arch/nios2/kernel/process.c
+++ b/arch/nios2/kernel/process.c
@@ -101,7 +101,7 @@ void flush_thread(void)
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp = args->stack;
unsigned long tls = args->tls;
struct pt_regs *childregs = task_pt_regs(p);
diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c
index eef99fee2110..73ffb9fa3118 100644
--- a/arch/openrisc/kernel/process.c
+++ b/arch/openrisc/kernel/process.c
@@ -165,7 +165,7 @@ extern asmlinkage void ret_from_fork(void);
int
copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp = args->stack;
unsigned long tls = args->tls;
struct pt_regs *userregs;
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index ed93bd8c1545..e64ab5d2a40d 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -201,7 +201,7 @@ arch_initcall(parisc_idle_init);
int
copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp = args->stack;
unsigned long tls = args->tls;
struct pt_regs *cregs = &(p->thread.regs);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 855e09886503..eb23966ac0a9 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1805,7 +1805,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
f = ret_from_kernel_user_thread;
} else {
struct pt_regs *regs = current_pt_regs();
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp = args->stack;
/* Copy registers */
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index a0a40889d79a..31a392993cb4 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -223,7 +223,7 @@ asmlinkage void ret_from_fork_user(struct pt_regs *regs)
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp = args->stack;
unsigned long tls = args->tls;
struct pt_regs *childregs = task_pt_regs(p);
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index f55f09cda6f8..b107dbca4ed7 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -106,7 +106,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long new_stackp = args->stack;
unsigned long tls = args->tls;
struct fake_frame
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 92b6649d4929..62f753a85b89 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -89,7 +89,7 @@ asmlinkage void ret_from_kernel_thread(void);
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp = args->stack;
unsigned long tls = args->tls;
struct thread_info *ti = task_thread_info(p);
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index 9c7c662cb565..5a28c0e91bf1 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -260,7 +260,7 @@ extern void ret_from_kernel_thread(void);
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long sp = args->stack;
unsigned long tls = args->tls;
struct thread_info *ti = task_thread_info(p);
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index 529adfecd58c..25781923788a 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -567,7 +567,7 @@ void fault_in_user_windows(struct pt_regs *regs)
*/
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long sp = args->stack;
unsigned long tls = args->tls;
struct thread_info *t = task_thread_info(p);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 1be644de9e41..9c9c66dc45f0 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -143,7 +143,7 @@ static void fork_handler(void)
int copy_thread(struct task_struct * p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long sp = args->stack;
unsigned long tls = args->tls;
void (*handler)(void);
diff --git a/arch/x86/include/asm/fpu/sched.h b/arch/x86/include/asm/fpu/sched.h
index c060549c6c94..89004f4ca208 100644
--- a/arch/x86/include/asm/fpu/sched.h
+++ b/arch/x86/include/asm/fpu/sched.h
@@ -11,7 +11,7 @@
extern void save_fpregs_to_fpstate(struct fpu *fpu);
extern void fpu__drop(struct task_struct *tsk);
-extern int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal,
+extern int fpu_clone(struct task_struct *dst, u64 clone_flags, bool minimal,
unsigned long shstk_addr);
extern void fpu_flush_thread(void);
diff --git a/arch/x86/include/asm/shstk.h b/arch/x86/include/asm/shstk.h
index ba6f2fe43848..0f50e0125943 100644
--- a/arch/x86/include/asm/shstk.h
+++ b/arch/x86/include/asm/shstk.h
@@ -16,7 +16,7 @@ struct thread_shstk {
long shstk_prctl(struct task_struct *task, int option, unsigned long arg2);
void reset_thread_features(void);
-unsigned long shstk_alloc_thread_stack(struct task_struct *p, unsigned long clone_flags,
+unsigned long shstk_alloc_thread_stack(struct task_struct *p, u64 clone_flags,
unsigned long stack_size);
void shstk_free(struct task_struct *p);
int setup_signal_shadow_stack(struct ksignal *ksig);
@@ -28,7 +28,7 @@ static inline long shstk_prctl(struct task_struct *task, int option,
unsigned long arg2) { return -EINVAL; }
static inline void reset_thread_features(void) {}
static inline unsigned long shstk_alloc_thread_stack(struct task_struct *p,
- unsigned long clone_flags,
+ u64 clone_flags,
unsigned long stack_size) { return 0; }
static inline void shstk_free(struct task_struct *p) {}
static inline int setup_signal_shadow_stack(struct ksignal *ksig) { return 0; }
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index aefd412a23dc..1f71cc135e9a 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -631,7 +631,7 @@ static int update_fpu_shstk(struct task_struct *dst, unsigned long ssp)
}
/* Clone current's FPU state on fork */
-int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal,
+int fpu_clone(struct task_struct *dst, u64 clone_flags, bool minimal,
unsigned long ssp)
{
/*
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 1b7960cf6eb0..e3a3987b0c4f 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -159,7 +159,7 @@ __visible void ret_from_fork(struct task_struct *prev, struct pt_regs *regs,
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long sp = args->stack;
unsigned long tls = args->tls;
struct inactive_task_frame *frame;
diff --git a/arch/x86/kernel/shstk.c b/arch/x86/kernel/shstk.c
index 2ddf23387c7e..5eba6c5a6775 100644
--- a/arch/x86/kernel/shstk.c
+++ b/arch/x86/kernel/shstk.c
@@ -191,7 +191,7 @@ void reset_thread_features(void)
current->thread.features_locked = 0;
}
-unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, unsigned long clone_flags,
+unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, u64 clone_flags,
unsigned long stack_size)
{
struct thread_shstk *shstk = &tsk->thread.shstk;
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 7bd66677f7b6..94d43f44be13 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -267,7 +267,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
- unsigned long clone_flags = args->flags;
+ u64 clone_flags = args->flags;
unsigned long usp_thread_fn = args->stack;
unsigned long tls = args->tls;
struct pt_regs *childregs = task_pt_regs(p);
--
2.39.5
On Mon, 1 Sep 2025, Simon Schuster via B4 Relay wrote: > From: Simon Schuster <schuster.simon@siemens-energy.com> > > With the introduction of clone3 in commit 7f192e3cd316 ("fork: add > clone3") the effective bit width of clone_flags on all architectures was > increased from 32-bit to 64-bit, with a new type of u64 for the flags. > However, for most consumers of clone_flags the interface was not > changed from the previous type of unsigned long. > > While this works fine as long as none of the new 64-bit flag bits > (CLONE_CLEAR_SIGHAND and CLONE_INTO_CGROUP) are evaluated, this is still > undesirable in terms of the principle of least surprise. > > Thus, this commit fixes all relevant interfaces of the copy_thread > function that is called from copy_process to consistently pass > clone_flags as u64, so that no truncation to 32-bit integers occurs on > 32-bit architectures. > > Signed-off-by: Simon Schuster <schuster.simon@siemens-energy.com> Acked-by: Paul Walmsley <pjw@kernel.org> # for RISC-V Thanks! - Paul
On Mon, Sep 1, 2025 at 9:10 PM Simon Schuster via B4 Relay <devnull+schuster.simon.siemens-energy.com@kernel.org> wrote: > > From: Simon Schuster <schuster.simon@siemens-energy.com> > > With the introduction of clone3 in commit 7f192e3cd316 ("fork: add > clone3") the effective bit width of clone_flags on all architectures was > increased from 32-bit to 64-bit, with a new type of u64 for the flags. > However, for most consumers of clone_flags the interface was not > changed from the previous type of unsigned long. > > While this works fine as long as none of the new 64-bit flag bits > (CLONE_CLEAR_SIGHAND and CLONE_INTO_CGROUP) are evaluated, this is still > undesirable in terms of the principle of least surprise. > > Thus, this commit fixes all relevant interfaces of the copy_thread > function that is called from copy_process to consistently pass > clone_flags as u64, so that no truncation to 32-bit integers occurs on > 32-bit architectures. > > Signed-off-by: Simon Schuster <schuster.simon@siemens-energy.com> > --- > arch/alpha/kernel/process.c | 2 +- > arch/arc/kernel/process.c | 2 +- > arch/arm/kernel/process.c | 2 +- > arch/arm64/kernel/process.c | 2 +- > arch/csky/kernel/process.c | 2 +- > arch/hexagon/kernel/process.c | 2 +- > arch/loongarch/kernel/process.c | 2 +- > arch/m68k/kernel/process.c | 2 +- > arch/microblaze/kernel/process.c | 2 +- > arch/mips/kernel/process.c | 2 +- > arch/nios2/kernel/process.c | 2 +- > arch/openrisc/kernel/process.c | 2 +- > arch/parisc/kernel/process.c | 2 +- > arch/powerpc/kernel/process.c | 2 +- > arch/riscv/kernel/process.c | 2 +- > arch/s390/kernel/process.c | 2 +- > arch/sh/kernel/process_32.c | 2 +- > arch/sparc/kernel/process_32.c | 2 +- > arch/sparc/kernel/process_64.c | 2 +- > arch/um/kernel/process.c | 2 +- > arch/x86/include/asm/fpu/sched.h | 2 +- > arch/x86/include/asm/shstk.h | 4 ++-- > arch/x86/kernel/fpu/core.c | 2 +- > arch/x86/kernel/process.c | 2 +- > arch/x86/kernel/shstk.c | 2 +- > arch/xtensa/kernel/process.c | 2 +- > 26 files changed, 27 insertions(+), 27 deletions(-) > > diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c > index 582d96548385..06522451f018 100644 > --- a/arch/alpha/kernel/process.c > +++ b/arch/alpha/kernel/process.c > @@ -231,7 +231,7 @@ flush_thread(void) > */ > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long usp = args->stack; > unsigned long tls = args->tls; > extern void ret_from_fork(void); > diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c > index 186ceab661eb..8166d0908713 100644 > --- a/arch/arc/kernel/process.c > +++ b/arch/arc/kernel/process.c > @@ -166,7 +166,7 @@ asmlinkage void ret_from_fork(void); > */ > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long usp = args->stack; > unsigned long tls = args->tls; > struct pt_regs *c_regs; /* child's pt_regs */ > diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c > index e16ed102960c..d7aa95225c70 100644 > --- a/arch/arm/kernel/process.c > +++ b/arch/arm/kernel/process.c > @@ -234,7 +234,7 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); > > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long stack_start = args->stack; > unsigned long tls = args->tls; > struct thread_info *thread = task_thread_info(p); > diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c > index 96482a1412c6..fba7ca102a8c 100644 > --- a/arch/arm64/kernel/process.c > +++ b/arch/arm64/kernel/process.c > @@ -409,7 +409,7 @@ asmlinkage void ret_from_fork(void) asm("ret_from_fork"); > > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long stack_start = args->stack; > unsigned long tls = args->tls; > struct pt_regs *childregs = task_pt_regs(p); > diff --git a/arch/csky/kernel/process.c b/arch/csky/kernel/process.c > index 0c6e4b17fe00..a7a90340042a 100644 > --- a/arch/csky/kernel/process.c > +++ b/arch/csky/kernel/process.c > @@ -32,7 +32,7 @@ void flush_thread(void){} > > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; Acked-by: Guo Ren (Alibaba Damo Academy) <guoren@kernel.org> > unsigned long usp = args->stack; > unsigned long tls = args->tls; > struct switch_stack *childstack; > diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c > index 2a77bfd75694..15b4992bfa29 100644 > --- a/arch/hexagon/kernel/process.c > +++ b/arch/hexagon/kernel/process.c > @@ -52,7 +52,7 @@ void arch_cpu_idle(void) > */ > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long usp = args->stack; > unsigned long tls = args->tls; > struct thread_info *ti = task_thread_info(p); > diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c > index 3582f591bab2..efd9edf65603 100644 > --- a/arch/loongarch/kernel/process.c > +++ b/arch/loongarch/kernel/process.c > @@ -167,7 +167,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > unsigned long childksp; > unsigned long tls = args->tls; > unsigned long usp = args->stack; > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > struct pt_regs *childregs, *regs = current_pt_regs(); > > childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE; > diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c > index fda7eac23f87..f5a07a70e938 100644 > --- a/arch/m68k/kernel/process.c > +++ b/arch/m68k/kernel/process.c > @@ -141,7 +141,7 @@ asmlinkage int m68k_clone3(struct pt_regs *regs) > > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long usp = args->stack; > unsigned long tls = args->tls; > struct fork_frame { > diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c > index 56342e11442d..6cbf642d7b80 100644 > --- a/arch/microblaze/kernel/process.c > +++ b/arch/microblaze/kernel/process.c > @@ -54,7 +54,7 @@ void flush_thread(void) > > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long usp = args->stack; > unsigned long tls = args->tls; > struct pt_regs *childregs = task_pt_regs(p); > diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c > index 02aa6a04a21d..29191fa1801e 100644 > --- a/arch/mips/kernel/process.c > +++ b/arch/mips/kernel/process.c > @@ -107,7 +107,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) > */ > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long usp = args->stack; > unsigned long tls = args->tls; > struct thread_info *ti = task_thread_info(p); > diff --git a/arch/nios2/kernel/process.c b/arch/nios2/kernel/process.c > index f84021303f6a..151404139085 100644 > --- a/arch/nios2/kernel/process.c > +++ b/arch/nios2/kernel/process.c > @@ -101,7 +101,7 @@ void flush_thread(void) > > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long usp = args->stack; > unsigned long tls = args->tls; > struct pt_regs *childregs = task_pt_regs(p); > diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c > index eef99fee2110..73ffb9fa3118 100644 > --- a/arch/openrisc/kernel/process.c > +++ b/arch/openrisc/kernel/process.c > @@ -165,7 +165,7 @@ extern asmlinkage void ret_from_fork(void); > int > copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long usp = args->stack; > unsigned long tls = args->tls; > struct pt_regs *userregs; > diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c > index ed93bd8c1545..e64ab5d2a40d 100644 > --- a/arch/parisc/kernel/process.c > +++ b/arch/parisc/kernel/process.c > @@ -201,7 +201,7 @@ arch_initcall(parisc_idle_init); > int > copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long usp = args->stack; > unsigned long tls = args->tls; > struct pt_regs *cregs = &(p->thread.regs); > diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c > index 855e09886503..eb23966ac0a9 100644 > --- a/arch/powerpc/kernel/process.c > +++ b/arch/powerpc/kernel/process.c > @@ -1805,7 +1805,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > f = ret_from_kernel_user_thread; > } else { > struct pt_regs *regs = current_pt_regs(); > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long usp = args->stack; > > /* Copy registers */ > diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c > index a0a40889d79a..31a392993cb4 100644 > --- a/arch/riscv/kernel/process.c > +++ b/arch/riscv/kernel/process.c > @@ -223,7 +223,7 @@ asmlinkage void ret_from_fork_user(struct pt_regs *regs) > > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long usp = args->stack; > unsigned long tls = args->tls; > struct pt_regs *childregs = task_pt_regs(p); > diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c > index f55f09cda6f8..b107dbca4ed7 100644 > --- a/arch/s390/kernel/process.c > +++ b/arch/s390/kernel/process.c > @@ -106,7 +106,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) > > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long new_stackp = args->stack; > unsigned long tls = args->tls; > struct fake_frame > diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c > index 92b6649d4929..62f753a85b89 100644 > --- a/arch/sh/kernel/process_32.c > +++ b/arch/sh/kernel/process_32.c > @@ -89,7 +89,7 @@ asmlinkage void ret_from_kernel_thread(void); > > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long usp = args->stack; > unsigned long tls = args->tls; > struct thread_info *ti = task_thread_info(p); > diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c > index 9c7c662cb565..5a28c0e91bf1 100644 > --- a/arch/sparc/kernel/process_32.c > +++ b/arch/sparc/kernel/process_32.c > @@ -260,7 +260,7 @@ extern void ret_from_kernel_thread(void); > > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long sp = args->stack; > unsigned long tls = args->tls; > struct thread_info *ti = task_thread_info(p); > diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c > index 529adfecd58c..25781923788a 100644 > --- a/arch/sparc/kernel/process_64.c > +++ b/arch/sparc/kernel/process_64.c > @@ -567,7 +567,7 @@ void fault_in_user_windows(struct pt_regs *regs) > */ > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long sp = args->stack; > unsigned long tls = args->tls; > struct thread_info *t = task_thread_info(p); > diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c > index 1be644de9e41..9c9c66dc45f0 100644 > --- a/arch/um/kernel/process.c > +++ b/arch/um/kernel/process.c > @@ -143,7 +143,7 @@ static void fork_handler(void) > > int copy_thread(struct task_struct * p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long sp = args->stack; > unsigned long tls = args->tls; > void (*handler)(void); > diff --git a/arch/x86/include/asm/fpu/sched.h b/arch/x86/include/asm/fpu/sched.h > index c060549c6c94..89004f4ca208 100644 > --- a/arch/x86/include/asm/fpu/sched.h > +++ b/arch/x86/include/asm/fpu/sched.h > @@ -11,7 +11,7 @@ > > extern void save_fpregs_to_fpstate(struct fpu *fpu); > extern void fpu__drop(struct task_struct *tsk); > -extern int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal, > +extern int fpu_clone(struct task_struct *dst, u64 clone_flags, bool minimal, > unsigned long shstk_addr); > extern void fpu_flush_thread(void); > > diff --git a/arch/x86/include/asm/shstk.h b/arch/x86/include/asm/shstk.h > index ba6f2fe43848..0f50e0125943 100644 > --- a/arch/x86/include/asm/shstk.h > +++ b/arch/x86/include/asm/shstk.h > @@ -16,7 +16,7 @@ struct thread_shstk { > > long shstk_prctl(struct task_struct *task, int option, unsigned long arg2); > void reset_thread_features(void); > -unsigned long shstk_alloc_thread_stack(struct task_struct *p, unsigned long clone_flags, > +unsigned long shstk_alloc_thread_stack(struct task_struct *p, u64 clone_flags, > unsigned long stack_size); > void shstk_free(struct task_struct *p); > int setup_signal_shadow_stack(struct ksignal *ksig); > @@ -28,7 +28,7 @@ static inline long shstk_prctl(struct task_struct *task, int option, > unsigned long arg2) { return -EINVAL; } > static inline void reset_thread_features(void) {} > static inline unsigned long shstk_alloc_thread_stack(struct task_struct *p, > - unsigned long clone_flags, > + u64 clone_flags, > unsigned long stack_size) { return 0; } > static inline void shstk_free(struct task_struct *p) {} > static inline int setup_signal_shadow_stack(struct ksignal *ksig) { return 0; } > diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c > index aefd412a23dc..1f71cc135e9a 100644 > --- a/arch/x86/kernel/fpu/core.c > +++ b/arch/x86/kernel/fpu/core.c > @@ -631,7 +631,7 @@ static int update_fpu_shstk(struct task_struct *dst, unsigned long ssp) > } > > /* Clone current's FPU state on fork */ > -int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal, > +int fpu_clone(struct task_struct *dst, u64 clone_flags, bool minimal, > unsigned long ssp) > { > /* > diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c > index 1b7960cf6eb0..e3a3987b0c4f 100644 > --- a/arch/x86/kernel/process.c > +++ b/arch/x86/kernel/process.c > @@ -159,7 +159,7 @@ __visible void ret_from_fork(struct task_struct *prev, struct pt_regs *regs, > > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long sp = args->stack; > unsigned long tls = args->tls; > struct inactive_task_frame *frame; > diff --git a/arch/x86/kernel/shstk.c b/arch/x86/kernel/shstk.c > index 2ddf23387c7e..5eba6c5a6775 100644 > --- a/arch/x86/kernel/shstk.c > +++ b/arch/x86/kernel/shstk.c > @@ -191,7 +191,7 @@ void reset_thread_features(void) > current->thread.features_locked = 0; > } > > -unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, unsigned long clone_flags, > +unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, u64 clone_flags, > unsigned long stack_size) > { > struct thread_shstk *shstk = &tsk->thread.shstk; > diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c > index 7bd66677f7b6..94d43f44be13 100644 > --- a/arch/xtensa/kernel/process.c > +++ b/arch/xtensa/kernel/process.c > @@ -267,7 +267,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) > > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long usp_thread_fn = args->stack; > unsigned long tls = args->tls; > struct pt_regs *childregs = task_pt_regs(p); > > -- > 2.39.5 > > -- Best Regards Guo Ren
On 2025-09-01 15:09, Simon Schuster via B4 Relay wrote: > From: Simon Schuster <schuster.simon@siemens-energy.com> > > With the introduction of clone3 in commit 7f192e3cd316 ("fork: add > clone3") the effective bit width of clone_flags on all architectures was > increased from 32-bit to 64-bit, with a new type of u64 for the flags. > However, for most consumers of clone_flags the interface was not > changed from the previous type of unsigned long. > > While this works fine as long as none of the new 64-bit flag bits > (CLONE_CLEAR_SIGHAND and CLONE_INTO_CGROUP) are evaluated, this is still > undesirable in terms of the principle of least surprise. > > Thus, this commit fixes all relevant interfaces of the copy_thread > function that is called from copy_process to consistently pass > clone_flags as u64, so that no truncation to 32-bit integers occurs on > 32-bit architectures. > > Signed-off-by: Simon Schuster <schuster.simon@siemens-energy.com> > --- Thanks for this and for the whole series! Needed foundation for a sparc32 clone3 implementation as well. > arch/sparc/kernel/process_32.c | 2 +- > arch/sparc/kernel/process_64.c | 2 +- Acked-by: Andreas Larsson <andreas@gaisler.com> # sparc Cheers, Andreas
Hi Andreas, On Tue, 2025-09-02 at 09:02 +0200, Andreas Larsson wrote: > On 2025-09-01 15:09, Simon Schuster via B4 Relay wrote: > > From: Simon Schuster <schuster.simon@siemens-energy.com> > > > > With the introduction of clone3 in commit 7f192e3cd316 ("fork: add > > clone3") the effective bit width of clone_flags on all architectures was > > increased from 32-bit to 64-bit, with a new type of u64 for the flags. > > However, for most consumers of clone_flags the interface was not > > changed from the previous type of unsigned long. > > > > While this works fine as long as none of the new 64-bit flag bits > > (CLONE_CLEAR_SIGHAND and CLONE_INTO_CGROUP) are evaluated, this is still > > undesirable in terms of the principle of least surprise. > > > > Thus, this commit fixes all relevant interfaces of the copy_thread > > function that is called from copy_process to consistently pass > > clone_flags as u64, so that no truncation to 32-bit integers occurs on > > 32-bit architectures. > > > > Signed-off-by: Simon Schuster <schuster.simon@siemens-energy.com> > > --- > > Thanks for this and for the whole series! Needed foundation for a > sparc32 clone3 implementation as well. Can you implement clone3 for sparc64 as well? Adrian -- .''`. John Paul Adrian Glaubitz : :' : Debian Developer `. `' Physicist `- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
On 2025-09-02 09:15, John Paul Adrian Glaubitz wrote: >> Thanks for this and for the whole series! Needed foundation for a >> sparc32 clone3 implementation as well. > > Can you implement clone3 for sparc64 as well? (heavily pairing down the to list) We'll take a look at that as well. Cheers, Andreas
On Mon, 1 Sept 2025 at 15:10, Simon Schuster via B4 Relay <devnull+schuster.simon.siemens-energy.com@kernel.org> wrote: > From: Simon Schuster <schuster.simon@siemens-energy.com> > > With the introduction of clone3 in commit 7f192e3cd316 ("fork: add > clone3") the effective bit width of clone_flags on all architectures was > increased from 32-bit to 64-bit, with a new type of u64 for the flags. > However, for most consumers of clone_flags the interface was not > changed from the previous type of unsigned long. > > While this works fine as long as none of the new 64-bit flag bits > (CLONE_CLEAR_SIGHAND and CLONE_INTO_CGROUP) are evaluated, this is still > undesirable in terms of the principle of least surprise. > > Thus, this commit fixes all relevant interfaces of the copy_thread > function that is called from copy_process to consistently pass > clone_flags as u64, so that no truncation to 32-bit integers occurs on > 32-bit architectures. > > Signed-off-by: Simon Schuster <schuster.simon@siemens-energy.com> Fixes: c5febea0956fd387 ("fork: Pass struct kernel_clone_args into copy_thread") > arch/m68k/kernel/process.c | 2 +- Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> # m68k Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
On Mon, Sep 01, 2025 at 03:09:52PM +0200, Simon Schuster via B4 Relay wrote: > diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c > index e16ed102960c..d7aa95225c70 100644 > --- a/arch/arm/kernel/process.c > +++ b/arch/arm/kernel/process.c > @@ -234,7 +234,7 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); > > int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) > { > - unsigned long clone_flags = args->flags; > + u64 clone_flags = args->flags; > unsigned long stack_start = args->stack; > unsigned long tls = args->tls; > struct thread_info *thread = task_thread_info(p); We only have one user of clone_flags in this function, which is: if (clone_flags & CLONE_SETTLS) I would much rather clone_flags was removed, and this changed to: if (args->flags & CLONE_SETTLS) Thanks. -- RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
On 01.09.25 15:09, Simon Schuster via B4 Relay wrote: > From: Simon Schuster <schuster.simon@siemens-energy.com> > > With the introduction of clone3 in commit 7f192e3cd316 ("fork: add > clone3") the effective bit width of clone_flags on all architectures was > increased from 32-bit to 64-bit, with a new type of u64 for the flags. > However, for most consumers of clone_flags the interface was not > changed from the previous type of unsigned long. > > While this works fine as long as none of the new 64-bit flag bits > (CLONE_CLEAR_SIGHAND and CLONE_INTO_CGROUP) are evaluated, this is still > undesirable in terms of the principle of least surprise. > > Thus, this commit fixes all relevant interfaces of the copy_thread > function that is called from copy_process to consistently pass > clone_flags as u64, so that no truncation to 32-bit integers occurs on > 32-bit architectures. > > Signed-off-by: Simon Schuster <schuster.simon@siemens-energy.com> > --- > arch/alpha/kernel/process.c | 2 +- > arch/arc/kernel/process.c | 2 +- > arch/arm/kernel/process.c | 2 +- > arch/arm64/kernel/process.c | 2 +- > arch/csky/kernel/process.c | 2 +- > arch/hexagon/kernel/process.c | 2 +- > arch/loongarch/kernel/process.c | 2 +- > arch/m68k/kernel/process.c | 2 +- > arch/microblaze/kernel/process.c | 2 +- > arch/mips/kernel/process.c | 2 +- > arch/nios2/kernel/process.c | 2 +- > arch/openrisc/kernel/process.c | 2 +- > arch/parisc/kernel/process.c | 2 +- > arch/powerpc/kernel/process.c | 2 +- > arch/riscv/kernel/process.c | 2 +- > arch/s390/kernel/process.c | 2 +- > arch/sh/kernel/process_32.c | 2 +- > arch/sparc/kernel/process_32.c | 2 +- > arch/sparc/kernel/process_64.c | 2 +- > arch/um/kernel/process.c | 2 +- > arch/x86/include/asm/fpu/sched.h | 2 +- > arch/x86/include/asm/shstk.h | 4 ++-- > arch/x86/kernel/fpu/core.c | 2 +- > arch/x86/kernel/process.c | 2 +- > arch/x86/kernel/shstk.c | 2 +- > arch/xtensa/kernel/process.c | 2 +- > 26 files changed, 27 insertions(+), 27 deletions(-) > (Adjust To: list) Thanks! Acked-by: David Hildenbrand <david@redhat.com> -- Cheers David / dhildenb
© 2016 - 2025 Red Hat, Inc.