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
Kirill Smelkov
linux
Commits
87f1ca8f
Commit
87f1ca8f
authored
Oct 21, 2012
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
s390: switch to generic fork/vfork/clone
Signed-off-by:
Al Viro
<
viro@zeniv.linux.org.uk
>
parent
f3268edb
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
14 additions
and
42 deletions
+14
-42
arch/s390/Kconfig
arch/s390/Kconfig
+1
-0
arch/s390/include/asm/unistd.h
arch/s390/include/asm/unistd.h
+3
-0
arch/s390/kernel/process.c
arch/s390/kernel/process.c
+10
-42
No files found.
arch/s390/Kconfig
View file @
87f1ca8f
...
@@ -141,6 +141,7 @@ config S390
...
@@ -141,6 +141,7 @@ config S390
select GENERIC_KERNEL_EXECVE
select GENERIC_KERNEL_EXECVE
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_MOD_ARCH_SPECIFIC
select MODULES_USE_ELF_RELA
select MODULES_USE_ELF_RELA
select CLONE_BACKWARDS2
config SCHED_OMIT_FRAME_POINTER
config SCHED_OMIT_FRAME_POINTER
def_bool y
def_bool y
...
...
arch/s390/include/asm/unistd.h
View file @
87f1ca8f
...
@@ -54,6 +54,9 @@
...
@@ -54,6 +54,9 @@
# define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
# define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
# endif
# endif
#define __ARCH_WANT_SYS_EXECVE
#define __ARCH_WANT_SYS_EXECVE
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_VFORK
#define __ARCH_WANT_SYS_CLONE
/*
/*
* "Conditional" syscalls
* "Conditional" syscalls
...
...
arch/s390/kernel/process.c
View file @
87f1ca8f
...
@@ -118,7 +118,7 @@ void release_thread(struct task_struct *dead_task)
...
@@ -118,7 +118,7 @@ void release_thread(struct task_struct *dead_task)
int
copy_thread
(
unsigned
long
clone_flags
,
unsigned
long
new_stackp
,
int
copy_thread
(
unsigned
long
clone_flags
,
unsigned
long
new_stackp
,
unsigned
long
arg
,
unsigned
long
arg
,
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
struct
task_struct
*
p
,
struct
pt_regs
*
unused
)
{
{
struct
thread_info
*
ti
;
struct
thread_info
*
ti
;
struct
fake_frame
struct
fake_frame
...
@@ -150,7 +150,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
...
@@ -150,7 +150,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
frame
->
sf
.
gprs
[
9
]
=
(
unsigned
long
)
frame
;
frame
->
sf
.
gprs
[
9
]
=
(
unsigned
long
)
frame
;
/* Store access registers to kernel stack of new process. */
/* Store access registers to kernel stack of new process. */
if
(
unlikely
(
!
regs
))
{
if
(
unlikely
(
p
->
flags
&
PF_KTHREAD
))
{
/* kernel thread */
/* kernel thread */
memset
(
&
frame
->
childregs
,
0
,
sizeof
(
struct
pt_regs
));
memset
(
&
frame
->
childregs
,
0
,
sizeof
(
struct
pt_regs
));
frame
->
childregs
.
psw
.
mask
=
psw_kernel_bits
|
PSW_MASK_DAT
|
frame
->
childregs
.
psw
.
mask
=
psw_kernel_bits
|
PSW_MASK_DAT
|
...
@@ -164,9 +164,10 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
...
@@ -164,9 +164,10 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
return
0
;
return
0
;
}
}
frame
->
childregs
=
*
regs
;
frame
->
childregs
=
*
current_pt_regs
()
;
frame
->
childregs
.
gprs
[
2
]
=
0
;
/* child returns 0 on fork. */
frame
->
childregs
.
gprs
[
2
]
=
0
;
/* child returns 0 on fork. */
frame
->
childregs
.
gprs
[
15
]
=
new_stackp
;
if
(
new_stackp
)
frame
->
childregs
.
gprs
[
15
]
=
new_stackp
;
/* Don't copy runtime instrumentation info */
/* Don't copy runtime instrumentation info */
p
->
thread
.
ri_cb
=
NULL
;
p
->
thread
.
ri_cb
=
NULL
;
...
@@ -183,57 +184,24 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
...
@@ -183,57 +184,24 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
sizeof
(
s390_fp_regs
));
sizeof
(
s390_fp_regs
));
/* Set a new TLS ? */
/* Set a new TLS ? */
if
(
clone_flags
&
CLONE_SETTLS
)
if
(
clone_flags
&
CLONE_SETTLS
)
p
->
thread
.
acrs
[
0
]
=
regs
->
gprs
[
6
];
p
->
thread
.
acrs
[
0
]
=
frame
->
childregs
.
gprs
[
6
];
#else
/* CONFIG_64BIT */
#else
/* CONFIG_64BIT */
/* Save the fpu registers to new thread structure. */
/* Save the fpu registers to new thread structure. */
save_fp_regs
(
&
p
->
thread
.
fp_regs
);
save_fp_regs
(
&
p
->
thread
.
fp_regs
);
/* Set a new TLS ? */
/* Set a new TLS ? */
if
(
clone_flags
&
CLONE_SETTLS
)
{
if
(
clone_flags
&
CLONE_SETTLS
)
{
unsigned
long
tls
=
frame
->
childregs
.
gprs
[
6
];
if
(
is_compat_task
())
{
if
(
is_compat_task
())
{
p
->
thread
.
acrs
[
0
]
=
(
unsigned
int
)
regs
->
gprs
[
6
]
;
p
->
thread
.
acrs
[
0
]
=
(
unsigned
int
)
tls
;
}
else
{
}
else
{
p
->
thread
.
acrs
[
0
]
=
(
unsigned
int
)(
regs
->
gprs
[
6
]
>>
32
);
p
->
thread
.
acrs
[
0
]
=
(
unsigned
int
)(
tls
>>
32
);
p
->
thread
.
acrs
[
1
]
=
(
unsigned
int
)
regs
->
gprs
[
6
]
;
p
->
thread
.
acrs
[
1
]
=
(
unsigned
int
)
tls
;
}
}
}
}
#endif
/* CONFIG_64BIT */
#endif
/* CONFIG_64BIT */
return
0
;
return
0
;
}
}
SYSCALL_DEFINE0
(
fork
)
{
struct
pt_regs
*
regs
=
task_pt_regs
(
current
);
return
do_fork
(
SIGCHLD
,
regs
->
gprs
[
15
],
regs
,
0
,
NULL
,
NULL
);
}
SYSCALL_DEFINE4
(
clone
,
unsigned
long
,
newsp
,
unsigned
long
,
clone_flags
,
int
__user
*
,
parent_tidptr
,
int
__user
*
,
child_tidptr
)
{
struct
pt_regs
*
regs
=
task_pt_regs
(
current
);
if
(
!
newsp
)
newsp
=
regs
->
gprs
[
15
];
return
do_fork
(
clone_flags
,
newsp
,
regs
,
0
,
parent_tidptr
,
child_tidptr
);
}
/*
* This is trivial, and on the face of it looks like it
* could equally well be done in user mode.
*
* Not so, for quite unobvious reasons - register pressure.
* In user mode vfork() cannot have a stack frame, and if
* done by calling the "clone()" system call directly, you
* do not have enough call-clobbered registers to hold all
* the information you need.
*/
SYSCALL_DEFINE0
(
vfork
)
{
struct
pt_regs
*
regs
=
task_pt_regs
(
current
);
return
do_fork
(
CLONE_VFORK
|
CLONE_VM
|
SIGCHLD
,
regs
->
gprs
[
15
],
regs
,
0
,
NULL
,
NULL
);
}
asmlinkage
void
execve_tail
(
void
)
asmlinkage
void
execve_tail
(
void
)
{
{
current
->
thread
.
fp_regs
.
fpc
=
0
;
current
->
thread
.
fp_regs
.
fpc
=
0
;
...
...
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