Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
69b58a67
Commit
69b58a67
authored
Oct 03, 2012
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cris: switch to generic kernel_thread()
Signed-off-by:
Al Viro
<
viro@zeniv.linux.org.uk
>
parent
ddffeb8c
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
69 additions
and
115 deletions
+69
-115
arch/cris/Kconfig
arch/cris/Kconfig
+1
-0
arch/cris/arch-v10/kernel/entry.S
arch/cris/arch-v10/kernel/entry.S
+9
-1
arch/cris/arch-v10/kernel/process.c
arch/cris/arch-v10/kernel/process.c
+24
-59
arch/cris/arch-v32/kernel/entry.S
arch/cris/arch-v32/kernel/entry.S
+13
-0
arch/cris/arch-v32/kernel/process.c
arch/cris/arch-v32/kernel/process.c
+22
-52
arch/cris/include/asm/processor.h
arch/cris/include/asm/processor.h
+0
-2
arch/cris/kernel/crisksyms.c
arch/cris/kernel/crisksyms.c
+0
-1
No files found.
arch/cris/Kconfig
View file @
69b58a67
...
...
@@ -49,6 +49,7 @@ config CRIS
select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32
select GENERIC_CMOS_UPDATE
select MODULES_USE_ELF_RELA
select GENERIC_KERNEL_THREAD
config HZ
int
...
...
arch/cris/arch-v10/kernel/entry.S
View file @
69b58a67
...
...
@@ -35,6 +35,7 @@
.
globl
system_call
.
globl
ret_from_intr
.
globl
ret_from_fork
.
globl
ret_from_kernel_thread
.
globl
resume
.
globl
multiple_interrupt
.
globl
hwbreakpoint
...
...
@@ -82,6 +83,13 @@ ret_from_fork:
ba
ret_from_sys_call
nop
ret_from_kernel_thread
:
jsr
schedule_tail
move.d
$r2
,
$r10
; argument is here
jsr
$r1
; call the payload
moveq
0
,
$r10
jsr
sys_exit
; never returns
ret_from_intr
:
;; check for resched if preemptive kernel or if we're going back to user-mode
;; this test matches the user_regs(regs) macro
...
...
arch/cris/arch-v10/kernel/process.c
View file @
69b58a67
...
...
@@ -17,6 +17,7 @@
#include <arch/svinto.h>
#include <linux/init.h>
#include <arch/system.h>
#include <asm/ptrace.h>
#ifdef CONFIG_ETRAX_GPIO
void
etrax_gpio_wake_up_check
(
void
);
/* drivers/gpio.c */
...
...
@@ -81,31 +82,6 @@ unsigned long thread_saved_pc(struct task_struct *t)
return
task_pt_regs
(
t
)
->
irp
;
}
static
void
kernel_thread_helper
(
void
*
dummy
,
int
(
*
fn
)(
void
*
),
void
*
arg
)
{
fn
(
arg
);
do_exit
(
-
1
);
/* Should never be called, return bad exit value */
}
/*
* Create a kernel thread
*/
int
kernel_thread
(
int
(
*
fn
)(
void
*
),
void
*
arg
,
unsigned
long
flags
)
{
struct
pt_regs
regs
;
memset
(
&
regs
,
0
,
sizeof
(
regs
));
/* Don't use r10 since that is set to 0 in copy_thread */
regs
.
r11
=
(
unsigned
long
)
fn
;
regs
.
r12
=
(
unsigned
long
)
arg
;
regs
.
irp
=
(
unsigned
long
)
kernel_thread_helper
;
regs
.
dccr
=
1
<<
I_DCCR_BITNR
;
/* Ok, create the new process.. */
return
do_fork
(
flags
|
CLONE_VM
|
CLONE_UNTRACED
,
0
,
&
regs
,
0
,
NULL
,
NULL
);
}
/* setup the child's kernel stack with a pt_regs and switch_stack on it.
* it will be un-nested during _resume and _ret_from_sys_call when the
* new thread is scheduled.
...
...
@@ -115,30 +91,36 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
*
*/
asmlinkage
void
ret_from_fork
(
void
);
asmlinkage
void
ret_from_kernel_thread
(
void
);
int
copy_thread
(
unsigned
long
clone_flags
,
unsigned
long
usp
,
unsigned
long
unused
,
unsigned
long
arg
,
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
{
struct
pt_regs
*
childregs
;
struct
switch_stack
*
swstack
;
struct
pt_regs
*
childregs
=
task_pt_regs
(
p
)
;
struct
switch_stack
*
swstack
=
((
struct
switch_stack
*
)
childregs
)
-
1
;
/* put the pt_regs structure at the end of the new kernel stack page and fix it up
* remember that the task_struct doubles as the kernel stack for the task
*/
childregs
=
task_pt_regs
(
p
);
if
(
unlikely
(
p
->
flags
&
PF_KTHREAD
))
{
memset
(
swstack
,
0
,
sizeof
(
struct
switch_stack
)
+
sizeof
(
struct
pt_regs
));
swstack
->
r1
=
usp
;
swstack
->
r2
=
arg
;
childregs
->
dccr
=
1
<<
I_DCCR_BITNR
;
swstack
->
return_ip
=
(
unsigned
long
)
ret_from_kernel_thread
;
p
->
thread
.
ksp
=
(
unsigned
long
)
swstack
;
p
->
thread
.
usp
=
0
;
return
0
;
}
*
childregs
=
*
regs
;
/* struct copy of pt_regs */
p
->
set_child_tid
=
p
->
clear_child_tid
=
NULL
;
childregs
->
r10
=
0
;
/* child returns 0 after a fork/clone */
/* put the switch stack right below the pt_regs */
swstack
=
((
struct
switch_stack
*
)
childregs
)
-
1
;
swstack
->
r9
=
0
;
/* parameter to ret_from_sys_call, 0 == dont restart the syscall */
/* we want to return into ret_from_sys_call after the _resume */
...
...
@@ -161,45 +143,28 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
return
0
;
}
/*
* Be aware of the "magic" 7th argument in the four system-calls below.
* They need the latest stackframe, which is put as the 7th argument by
* entry.S. The previous arguments are dummies or actually used, but need
* to be defined to reach the 7th argument.
*
* N.B.: Another method to get the stackframe is to use current_regs(). But
* it returns the latest stack-frame stacked when going from _user mode_ and
* some of these (at least sys_clone) are called from kernel-mode sometimes
* (for example during kernel_thread, above) and thus cannot use it. Thus,
* to be sure not to get any surprises, we use the method for the other calls
* as well.
*/
asmlinkage
int
sys_fork
(
long
r10
,
long
r11
,
long
r12
,
long
r13
,
long
mof
,
long
srp
,
struct
pt_regs
*
regs
)
asmlinkage
int
sys_fork
(
void
)
{
return
do_fork
(
SIGCHLD
,
rdusp
(),
regs
,
0
,
NULL
,
NULL
);
return
do_fork
(
SIGCHLD
,
rdusp
(),
current_pt_regs
()
,
0
,
NULL
,
NULL
);
}
/* if newusp is 0, we just grab the old usp */
/* FIXME: Is parent_tid/child_tid really third/fourth argument? Update lib? */
asmlinkage
int
sys_clone
(
unsigned
long
newusp
,
unsigned
long
flags
,
int
*
parent_tid
,
int
*
child_tid
,
long
mof
,
long
srp
,
struct
pt_regs
*
regs
)
int
*
parent_tid
,
int
*
child_tid
)
{
if
(
!
newusp
)
newusp
=
rdusp
();
return
do_fork
(
flags
,
newusp
,
regs
,
0
,
parent_tid
,
child_tid
);
return
do_fork
(
flags
,
newusp
,
current_pt_regs
()
,
0
,
parent_tid
,
child_tid
);
}
/* vfork is a system call in i386 because of register-pressure - maybe
* we can remove it and handle it in libc but we put it here until then.
*/
asmlinkage
int
sys_vfork
(
long
r10
,
long
r11
,
long
r12
,
long
r13
,
long
mof
,
long
srp
,
struct
pt_regs
*
regs
)
asmlinkage
int
sys_vfork
(
void
)
{
return
do_fork
(
CLONE_VFORK
|
CLONE_VM
|
SIGCHLD
,
rdusp
(),
regs
,
0
,
NULL
,
NULL
);
return
do_fork
(
CLONE_VFORK
|
CLONE_VM
|
SIGCHLD
,
rdusp
(),
current_pt_regs
()
,
0
,
NULL
,
NULL
);
}
/*
...
...
arch/cris/arch-v32/kernel/entry.S
View file @
69b58a67
...
...
@@ -31,6 +31,7 @@
.
globl
system_call
.
globl
ret_from_intr
.
globl
ret_from_fork
.
globl
ret_from_kernel_thread
.
globl
resume
.
globl
multiple_interrupt
.
globl
nmi_interrupt
...
...
@@ -84,6 +85,18 @@ ret_from_fork:
nop
.
size
ret_from_fork
,
.
-
ret_from_fork
.
type
ret_from_kernel_thread
,
@
function
ret_from_kernel_thread
:
jsr
schedule_tail
nop
move.d
$r2
,
$r10
jsr
$r1
nop
moveq
0
,
$r10
jsr
sys_exit
nop
.
size
ret_from_kernel_thread
,
.
-
ret_from_kernel_thread
.
type
ret_from_intr
,
@
function
ret_from_intr
:
;; Check for resched if preemptive kernel, or if we're going back to
...
...
arch/cris/arch-v32/kernel/process.c
View file @
69b58a67
...
...
@@ -16,6 +16,7 @@
#include <hwregs/reg_map.h>
#include <hwregs/timer_defs.h>
#include <hwregs/intr_vect_defs.h>
#include <asm/ptrace.h>
extern
void
stop_watchdog
(
void
);
...
...
@@ -94,31 +95,6 @@ unsigned long thread_saved_pc(struct task_struct *t)
return
task_pt_regs
(
t
)
->
erp
;
}
static
void
kernel_thread_helper
(
void
*
dummy
,
int
(
*
fn
)(
void
*
),
void
*
arg
)
{
fn
(
arg
);
do_exit
(
-
1
);
/* Should never be called, return bad exit value. */
}
/* Create a kernel thread. */
int
kernel_thread
(
int
(
*
fn
)(
void
*
),
void
*
arg
,
unsigned
long
flags
)
{
struct
pt_regs
regs
;
memset
(
&
regs
,
0
,
sizeof
(
regs
));
/* Don't use r10 since that is set to 0 in copy_thread. */
regs
.
r11
=
(
unsigned
long
)
fn
;
regs
.
r12
=
(
unsigned
long
)
arg
;
regs
.
erp
=
(
unsigned
long
)
kernel_thread_helper
;
regs
.
ccs
=
1
<<
(
I_CCS_BITNR
+
CCS_SHIFT
);
/* Create the new process. */
return
do_fork
(
flags
|
CLONE_VM
|
CLONE_UNTRACED
,
0
,
&
regs
,
0
,
NULL
,
NULL
);
}
/*
* Setup the child's kernel stack with a pt_regs and call switch_stack() on it.
* It will be unnested during _resume and _ret_from_sys_call when the new thread
...
...
@@ -129,23 +105,33 @@ kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
*/
extern
asmlinkage
void
ret_from_fork
(
void
);
extern
asmlinkage
void
ret_from_kernel_thread
(
void
);
int
copy_thread
(
unsigned
long
clone_flags
,
unsigned
long
usp
,
unsigned
long
unused
,
unsigned
long
arg
,
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
{
struct
pt_regs
*
childregs
;
struct
switch_stack
*
swstack
;
struct
pt_regs
*
childregs
=
task_pt_regs
(
p
)
;
struct
switch_stack
*
swstack
=
((
struct
switch_stack
*
)
childregs
)
-
1
;
/*
* Put the pt_regs structure at the end of the new kernel stack page and
* fix it up. Note: the task_struct doubles as the kernel stack for the
* task.
*/
childregs
=
task_pt_regs
(
p
);
if
(
unlikely
(
p
->
flags
&
PF_KTHREAD
))
{
memset
(
swstack
,
0
,
sizeof
(
struct
switch_stack
)
+
sizeof
(
struct
pt_regs
));
swstack
->
r1
=
usp
;
swstack
->
r2
=
arg
;
childregs
->
ccs
=
1
<<
(
I_CCS_BITNR
+
CCS_SHIFT
);
swstack
->
return_ip
=
(
unsigned
long
)
ret_from_kernel_thread
;
p
->
thread
.
ksp
=
(
unsigned
long
)
swstack
;
p
->
thread
.
usp
=
0
;
return
0
;
}
*
childregs
=
*
regs
;
/* Struct copy of pt_regs. */
p
->
set_child_tid
=
p
->
clear_child_tid
=
NULL
;
childregs
->
r10
=
0
;
/* Child returns 0 after a fork/clone. */
/* Set a new TLS ?
...
...
@@ -156,7 +142,6 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
}
/* Put the switch stack right below the pt_regs. */
swstack
=
((
struct
switch_stack
*
)
childregs
)
-
1
;
/* Parameter to ret_from_sys_call. 0 is don't restart the syscall. */
swstack
->
r9
=
0
;
...
...
@@ -174,35 +159,21 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
return
0
;
}
/*
* Be aware of the "magic" 7th argument in the four system-calls below.
* They need the latest stackframe, which is put as the 7th argument by
* entry.S. The previous arguments are dummies or actually used, but need
* to be defined to reach the 7th argument.
*
* N.B.: Another method to get the stackframe is to use current_regs(). But
* it returns the latest stack-frame stacked when going from _user mode_ and
* some of these (at least sys_clone) are called from kernel-mode sometimes
* (for example during kernel_thread, above) and thus cannot use it. Thus,
* to be sure not to get any surprises, we use the method for the other calls
* as well.
*/
asmlinkage
int
sys_fork
(
long
r10
,
long
r11
,
long
r12
,
long
r13
,
long
mof
,
long
srp
,
struct
pt_regs
*
regs
)
sys_fork
(
void
)
{
return
do_fork
(
SIGCHLD
,
rdusp
(),
regs
,
0
,
NULL
,
NULL
);
return
do_fork
(
SIGCHLD
,
rdusp
(),
current_pt_regs
()
,
0
,
NULL
,
NULL
);
}
/* FIXME: Is parent_tid/child_tid really third/fourth argument? Update lib? */
asmlinkage
int
sys_clone
(
unsigned
long
newusp
,
unsigned
long
flags
,
int
*
parent_tid
,
int
*
child_tid
,
unsigned
long
tls
,
long
srp
,
struct
pt_regs
*
regs
)
unsigned
long
tls
)
{
if
(
!
newusp
)
newusp
=
rdusp
();
return
do_fork
(
flags
,
newusp
,
regs
,
0
,
parent_tid
,
child_tid
);
return
do_fork
(
flags
,
newusp
,
current_pt_regs
()
,
0
,
parent_tid
,
child_tid
);
}
/*
...
...
@@ -210,10 +181,9 @@ sys_clone(unsigned long newusp, unsigned long flags, int *parent_tid, int *child
* we can remove it and handle it in libc but we put it here until then.
*/
asmlinkage
int
sys_vfork
(
long
r10
,
long
r11
,
long
r12
,
long
r13
,
long
mof
,
long
srp
,
struct
pt_regs
*
regs
)
sys_vfork
(
void
)
{
return
do_fork
(
CLONE_VFORK
|
CLONE_VM
|
SIGCHLD
,
rdusp
(),
regs
,
0
,
NULL
,
NULL
);
return
do_fork
(
CLONE_VFORK
|
CLONE_VM
|
SIGCHLD
,
rdusp
(),
current_pt_regs
()
,
0
,
NULL
,
NULL
);
}
/* sys_execve() executes a new program. */
...
...
arch/cris/include/asm/processor.h
View file @
69b58a67
...
...
@@ -49,8 +49,6 @@ struct task_struct;
#define task_pt_regs(task) user_regs(task_thread_info(task))
#define current_regs() task_pt_regs(current)
extern
int
kernel_thread
(
int
(
*
fn
)(
void
*
),
void
*
arg
,
unsigned
long
flags
);
unsigned
long
get_wchan
(
struct
task_struct
*
p
);
#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp)
...
...
arch/cris/kernel/crisksyms.c
View file @
69b58a67
...
...
@@ -30,7 +30,6 @@ extern void __negdi2(void);
extern
void
iounmap
(
volatile
void
*
__iomem
);
/* Platform dependent support */
EXPORT_SYMBOL
(
kernel_thread
);
EXPORT_SYMBOL
(
get_cmos_time
);
EXPORT_SYMBOL
(
loops_per_usec
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment