@@ -98,25 +98,6 @@ void cpu_idle(void)
98
98
99
99
extern void __kprobes kernel_thread_starter (void );
100
100
101
- int kernel_thread (int (* fn )(void * ), void * arg , unsigned long flags )
102
- {
103
- struct pt_regs regs ;
104
-
105
- memset (& regs , 0 , sizeof (regs ));
106
- regs .psw .mask = psw_kernel_bits |
107
- PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK ;
108
- regs .psw .addr = (unsigned long ) kernel_thread_starter | PSW_ADDR_AMODE ;
109
- regs .gprs [9 ] = (unsigned long ) fn ;
110
- regs .gprs [10 ] = (unsigned long ) arg ;
111
- regs .gprs [11 ] = (unsigned long ) do_exit ;
112
- regs .orig_gpr2 = -1 ;
113
-
114
- /* Ok, create the new process.. */
115
- return do_fork (flags | CLONE_VM | CLONE_UNTRACED ,
116
- 0 , & regs , 0 , NULL , NULL );
117
- }
118
- EXPORT_SYMBOL (kernel_thread );
119
-
120
101
/*
121
102
* Free current thread data structures etc..
122
103
*/
@@ -133,7 +114,7 @@ void release_thread(struct task_struct *dead_task)
133
114
}
134
115
135
116
int copy_thread (unsigned long clone_flags , unsigned long new_stackp ,
136
- unsigned long unused ,
117
+ unsigned long arg ,
137
118
struct task_struct * p , struct pt_regs * regs )
138
119
{
139
120
struct thread_info * ti ;
@@ -145,20 +126,44 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
145
126
146
127
frame = container_of (task_pt_regs (p ), struct fake_frame , childregs );
147
128
p -> thread .ksp = (unsigned long ) frame ;
148
- /* Store access registers to kernel stack of new process. */
149
- frame -> childregs = * regs ;
150
- frame -> childregs .gprs [2 ] = 0 ; /* child returns 0 on fork. */
151
- frame -> childregs .gprs [15 ] = new_stackp ;
152
- frame -> sf .back_chain = 0 ;
129
+ /* Save access registers to new thread structure. */
130
+ save_access_regs (& p -> thread .acrs [0 ]);
131
+ /* start new process with ar4 pointing to the correct address space */
132
+ p -> thread .mm_segment = get_fs ();
133
+ /* Don't copy debug registers */
134
+ memset (& p -> thread .per_user , 0 , sizeof (p -> thread .per_user ));
135
+ memset (& p -> thread .per_event , 0 , sizeof (p -> thread .per_event ));
136
+ clear_tsk_thread_flag (p , TIF_SINGLE_STEP );
137
+ clear_tsk_thread_flag (p , TIF_PER_TRAP );
138
+ /* Initialize per thread user and system timer values */
139
+ ti = task_thread_info (p );
140
+ ti -> user_timer = 0 ;
141
+ ti -> system_timer = 0 ;
153
142
143
+ frame -> sf .back_chain = 0 ;
154
144
/* new return point is ret_from_fork */
155
145
frame -> sf .gprs [8 ] = (unsigned long ) ret_from_fork ;
156
-
157
146
/* fake return stack for resume(), don't go back to schedule */
158
147
frame -> sf .gprs [9 ] = (unsigned long ) frame ;
159
148
160
- /* Save access registers to new thread structure. */
161
- save_access_regs (& p -> thread .acrs [0 ]);
149
+ /* Store access registers to kernel stack of new process. */
150
+ if (unlikely (!regs )) {
151
+ /* kernel thread */
152
+ memset (& frame -> childregs , 0 , sizeof (struct pt_regs ));
153
+ frame -> childregs .psw .mask = psw_kernel_bits | PSW_MASK_DAT |
154
+ PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK ;
155
+ frame -> childregs .psw .addr = PSW_ADDR_AMODE |
156
+ (unsigned long ) kernel_thread_starter ;
157
+ frame -> childregs .gprs [9 ] = new_stackp ; /* function */
158
+ frame -> childregs .gprs [10 ] = arg ;
159
+ frame -> childregs .gprs [11 ] = (unsigned long ) do_exit ;
160
+ frame -> childregs .orig_gpr2 = -1 ;
161
+
162
+ return 0 ;
163
+ }
164
+ frame -> childregs = * regs ;
165
+ frame -> childregs .gprs [2 ] = 0 ; /* child returns 0 on fork. */
166
+ frame -> childregs .gprs [15 ] = new_stackp ;
162
167
163
168
#ifndef CONFIG_64BIT
164
169
/*
@@ -184,17 +189,6 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
184
189
}
185
190
}
186
191
#endif /* CONFIG_64BIT */
187
- /* start new process with ar4 pointing to the correct address space */
188
- p -> thread .mm_segment = get_fs ();
189
- /* Don't copy debug registers */
190
- memset (& p -> thread .per_user , 0 , sizeof (p -> thread .per_user ));
191
- memset (& p -> thread .per_event , 0 , sizeof (p -> thread .per_event ));
192
- clear_tsk_thread_flag (p , TIF_SINGLE_STEP );
193
- clear_tsk_thread_flag (p , TIF_PER_TRAP );
194
- /* Initialize per thread user and system timer values */
195
- ti = task_thread_info (p );
196
- ti -> user_timer = 0 ;
197
- ti -> system_timer = 0 ;
198
192
return 0 ;
199
193
}
200
194
0 commit comments