Skip to content

Commit 5bd2e97

Browse files
committed
fork: Generalize PF_IO_WORKER handling
Add fn and fn_arg members into struct kernel_clone_args and test for them in copy_thread (instead of testing for PF_KTHREAD | PF_IO_WORKER). This allows any task that wants to be a user space task that only runs in kernel mode to use this functionality. The code on x86 is an exception and still retains a PF_KTHREAD test because x86 unlikely everything else handles kthreads slightly differently than user space tasks that start with a function. The functions that created tasks that start with a function have been updated to set ".fn" and ".fn_arg" instead of ".stack" and ".stack_size". These functions are fork_idle(), create_io_thread(), kernel_thread(), and user_mode_thread(). Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: "Eric W. Biederman" <[email protected]>
1 parent 36cb0e1 commit 5bd2e97

File tree

28 files changed

+95
-116
lines changed

28 files changed

+95
-116
lines changed

arch/alpha/kernel/process.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
237237
{
238238
unsigned long clone_flags = args->flags;
239239
unsigned long usp = args->stack;
240-
unsigned long kthread_arg = args->stack_size;
241240
unsigned long tls = args->tls;
242241
extern void ret_from_fork(void);
243242
extern void ret_from_kernel_thread(void);
@@ -251,13 +250,13 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
251250
childti->pcb.ksp = (unsigned long) childstack;
252251
childti->pcb.flags = 1; /* set FEN, clear everything else */
253252

254-
if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
253+
if (unlikely(args->fn)) {
255254
/* kernel thread */
256255
memset(childstack, 0,
257256
sizeof(struct switch_stack) + sizeof(struct pt_regs));
258257
childstack->r26 = (unsigned long) ret_from_kernel_thread;
259-
childstack->r9 = usp; /* function */
260-
childstack->r10 = kthread_arg;
258+
childstack->r9 = (unsigned long) args->fn;
259+
childstack->r10 = (unsigned long) args->fn_arg;
261260
childregs->hae = alpha_mv.hae_cache;
262261
childti->pcb.usp = 0;
263262
return 0;

arch/arc/kernel/process.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
166166
{
167167
unsigned long clone_flags = args->flags;
168168
unsigned long usp = args->stack;
169-
unsigned long kthread_arg = args->stack_size;
170169
unsigned long tls = args->tls;
171170
struct pt_regs *c_regs; /* child's pt_regs */
172171
unsigned long *childksp; /* to unwind out of __switch_to() */
@@ -193,11 +192,11 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
193192
childksp[0] = 0; /* fp */
194193
childksp[1] = (unsigned long)ret_from_fork; /* blink */
195194

196-
if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
195+
if (unlikely(args->fn)) {
197196
memset(c_regs, 0, sizeof(struct pt_regs));
198197

199-
c_callee->r13 = kthread_arg;
200-
c_callee->r14 = usp; /* function */
198+
c_callee->r13 = (unsigned long)args->fn_arg;
199+
c_callee->r14 = (unsigned long)args->fn;
201200

202201
return 0;
203202
}

arch/arm/kernel/process.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
242242
{
243243
unsigned long clone_flags = args->flags;
244244
unsigned long stack_start = args->stack;
245-
unsigned long stk_sz = args->stack_size;
246245
unsigned long tls = args->tls;
247246
struct thread_info *thread = task_thread_info(p);
248247
struct pt_regs *childregs = task_pt_regs(p);
@@ -259,15 +258,15 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
259258
thread->cpu_domain = get_domain();
260259
#endif
261260

262-
if (likely(!(p->flags & (PF_KTHREAD | PF_IO_WORKER)))) {
261+
if (likely(!args->fn)) {
263262
*childregs = *current_pt_regs();
264263
childregs->ARM_r0 = 0;
265264
if (stack_start)
266265
childregs->ARM_sp = stack_start;
267266
} else {
268267
memset(childregs, 0, sizeof(struct pt_regs));
269-
thread->cpu_context.r4 = stk_sz;
270-
thread->cpu_context.r5 = stack_start;
268+
thread->cpu_context.r4 = (unsigned long)args->fn_arg;
269+
thread->cpu_context.r5 = (unsigned long)args->fn;
271270
childregs->ARM_cpsr = SVC_MODE;
272271
}
273272
thread->cpu_context.pc = (unsigned long)ret_from_fork;

arch/arm64/kernel/process.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
320320
{
321321
unsigned long clone_flags = args->flags;
322322
unsigned long stack_start = args->stack;
323-
unsigned long stk_sz = args->stack_size;
324323
unsigned long tls = args->tls;
325324
struct pt_regs *childregs = task_pt_regs(p);
326325

@@ -337,7 +336,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
337336

338337
ptrauth_thread_init_kernel(p);
339338

340-
if (likely(!(p->flags & (PF_KTHREAD | PF_IO_WORKER)))) {
339+
if (likely(!args->fn)) {
341340
*childregs = *current_pt_regs();
342341
childregs->regs[0] = 0;
343342

@@ -371,8 +370,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
371370
memset(childregs, 0, sizeof(struct pt_regs));
372371
childregs->pstate = PSR_MODE_EL1h | PSR_IL_BIT;
373372

374-
p->thread.cpu_context.x19 = stack_start;
375-
p->thread.cpu_context.x20 = stk_sz;
373+
p->thread.cpu_context.x19 = (unsigned long)args->fn;
374+
p->thread.cpu_context.x20 = (unsigned long)args->fn_arg;
376375
}
377376
p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
378377
p->thread.cpu_context.sp = (unsigned long)childregs;

arch/csky/kernel/process.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
3434
{
3535
unsigned long clone_flags = args->flags;
3636
unsigned long usp = args->stack;
37-
unsigned long kthread_arg = args->stack_size;
3837
unsigned long tls = args->tls;
3938
struct switch_stack *childstack;
4039
struct pt_regs *childregs = task_pt_regs(p);
@@ -49,11 +48,11 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
4948
/* setup thread.sp for switch_to !!! */
5049
p->thread.sp = (unsigned long)childstack;
5150

52-
if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
51+
if (unlikely(args->fn)) {
5352
memset(childregs, 0, sizeof(struct pt_regs));
5453
childstack->r15 = (unsigned long) ret_from_kernel_thread;
55-
childstack->r10 = kthread_arg;
56-
childstack->r9 = usp;
54+
childstack->r10 = (unsigned long) args->fn_arg;
55+
childstack->r9 = (unsigned long) args->fn;
5756
childregs->sr = mfcr("psr");
5857
} else {
5958
*childregs = *(current_pt_regs());

arch/h8300/kernel/process.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,15 @@ void flush_thread(void)
108108
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
109109
{
110110
unsigned long usp = args->stack;
111-
unsigned long topstk = args->stack_size;
112111
struct pt_regs *childregs;
113112

114113
childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1;
115114

116-
if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
115+
if (unlikely(args->fn)) {
117116
memset(childregs, 0, sizeof(struct pt_regs));
118117
childregs->retpc = (unsigned long) ret_from_kernel_thread;
119-
childregs->er4 = topstk; /* arg */
120-
childregs->er5 = usp; /* fn */
118+
childregs->er4 = (unsigned long) args->fn_arg;
119+
childregs->er5 = (unsigned long) args->fn;
121120
} else {
122121
*childregs = *current_pt_regs();
123122
childregs->er0 = 0;

arch/hexagon/kernel/process.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
5454
{
5555
unsigned long clone_flags = args->flags;
5656
unsigned long usp = args->stack;
57-
unsigned long arg = args->stack_size;
5857
unsigned long tls = args->tls;
5958
struct thread_info *ti = task_thread_info(p);
6059
struct hexagon_switch_stack *ss;
@@ -76,11 +75,11 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
7675
sizeof(*ss));
7776
ss->lr = (unsigned long)ret_from_fork;
7877
p->thread.switch_sp = ss;
79-
if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
78+
if (unlikely(args->fn)) {
8079
memset(childregs, 0, sizeof(struct pt_regs));
8180
/* r24 <- fn, r25 <- arg */
82-
ss->r24 = usp;
83-
ss->r25 = arg;
81+
ss->r24 = (unsigned long)args->fn;
82+
ss->r25 = (unsigned long)args->fn_arg;
8483
pt_set_kmode(childregs);
8584
return 0;
8685
}

arch/ia64/kernel/process.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,14 +341,14 @@ copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
341341

342342
ia64_drop_fpu(p); /* don't pick up stale state from a CPU's fph */
343343

344-
if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
344+
if (unlikely(args->fn)) {
345345
if (unlikely(args->idle)) {
346346
/* fork_idle() called us */
347347
return 0;
348348
}
349349
memset(child_stack, 0, sizeof(*child_ptregs) + sizeof(*child_stack));
350-
child_stack->r4 = user_stack_base; /* payload */
351-
child_stack->r5 = user_stack_size; /* argument */
350+
child_stack->r4 = (unsigned long) args->fn;
351+
child_stack->r5 = (unsigned long) args->fn_arg;
352352
/*
353353
* Preserve PSR bits, except for bits 32-34 and 37-45,
354354
* which we can't read.

arch/m68k/kernel/process.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
142142
{
143143
unsigned long clone_flags = args->flags;
144144
unsigned long usp = args->stack;
145-
unsigned long arg = args->stack_size;
146145
unsigned long tls = args->tls;
147146
struct fork_frame {
148147
struct switch_stack sw;
@@ -160,12 +159,12 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
160159
*/
161160
p->thread.fc = USER_DATA;
162161

163-
if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
162+
if (unlikely(args->fn)) {
164163
/* kernel thread */
165164
memset(frame, 0, sizeof(struct fork_frame));
166165
frame->regs.sr = PS_S;
167-
frame->sw.a3 = usp; /* function */
168-
frame->sw.d7 = arg;
166+
frame->sw.a3 = (unsigned long)args->fn;
167+
frame->sw.d7 = (unsigned long)args->fn_arg;
169168
frame->sw.retpc = (unsigned long)ret_from_kernel_thread;
170169
p->thread.usp = 0;
171170
return 0;

arch/microblaze/kernel/process.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,18 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
5656
{
5757
unsigned long clone_flags = args->flags;
5858
unsigned long usp = args->stack;
59-
unsigned long arg = args->stack_size;
6059
unsigned long tls = args->tls;
6160
struct pt_regs *childregs = task_pt_regs(p);
6261
struct thread_info *ti = task_thread_info(p);
6362

64-
if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
63+
if (unlikely(args->fn)) {
6564
/* if we're creating a new kernel thread then just zeroing all
6665
* the registers. That's OK for a brand new thread.*/
6766
memset(childregs, 0, sizeof(struct pt_regs));
6867
memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
6968
ti->cpu_context.r1 = (unsigned long)childregs;
70-
ti->cpu_context.r20 = (unsigned long)usp; /* fn */
71-
ti->cpu_context.r19 = (unsigned long)arg;
69+
ti->cpu_context.r20 = (unsigned long)args->fn;
70+
ti->cpu_context.r19 = (unsigned long)args->fn_arg;
7271
childregs->pt_mode = 1;
7372
local_save_flags(childregs->msr);
7473
ti->cpu_context.msr = childregs->msr & ~MSR_IE;

0 commit comments

Comments
 (0)