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
1d4b4b29
Commit
1d4b4b29
authored
Oct 22, 2012
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
x86, um: switch to generic fork/vfork/clone
Signed-off-by:
Al Viro
<
viro@zeniv.linux.org.uk
>
parent
71613c3b
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
52 additions
and
117 deletions
+52
-117
arch/um/kernel/syscall.c
arch/um/kernel/syscall.c
+0
-19
arch/x86/Kconfig
arch/x86/Kconfig
+1
-0
arch/x86/ia32/ia32entry.S
arch/x86/ia32/ia32entry.S
+6
-1
arch/x86/ia32/sys_ia32.c
arch/x86/ia32/sys_ia32.c
+0
-11
arch/x86/include/asm/sys_ia32.h
arch/x86/include/asm/sys_ia32.h
+0
-2
arch/x86/include/asm/syscalls.h
arch/x86/include/asm/syscalls.h
+9
-4
arch/x86/include/asm/unistd.h
arch/x86/include/asm/unistd.h
+3
-0
arch/x86/kernel/entry_32.S
arch/x86/kernel/entry_32.S
+0
-18
arch/x86/kernel/entry_64.S
arch/x86/kernel/entry_64.S
+19
-3
arch/x86/kernel/process.c
arch/x86/kernel/process.c
+0
-30
arch/x86/kernel/process_32.c
arch/x86/kernel/process_32.c
+6
-5
arch/x86/kernel/process_64.c
arch/x86/kernel/process_64.c
+4
-3
arch/x86/syscalls/syscall_32.tbl
arch/x86/syscalls/syscall_32.tbl
+3
-3
arch/x86/um/Kconfig
arch/x86/um/Kconfig
+1
-0
arch/x86/um/sys_call_table_32.c
arch/x86/um/sys_call_table_32.c
+0
-3
arch/x86/um/syscalls_32.c
arch/x86/um/syscalls_32.c
+0
-15
No files found.
arch/um/kernel/syscall.c
View file @
1d4b4b29
...
...
@@ -14,25 +14,6 @@
#include <asm/uaccess.h>
#include <asm/unistd.h>
long
sys_fork
(
void
)
{
return
do_fork
(
SIGCHLD
,
0
,
&
current
->
thread
.
regs
,
0
,
NULL
,
NULL
);
}
long
sys_vfork
(
void
)
{
return
do_fork
(
CLONE_VFORK
|
CLONE_VM
|
SIGCHLD
,
0
,
&
current
->
thread
.
regs
,
0
,
NULL
,
NULL
);
}
long
sys_clone
(
unsigned
long
clone_flags
,
unsigned
long
newsp
,
void
__user
*
parent_tid
,
void
__user
*
child_tid
)
{
return
do_fork
(
clone_flags
,
newsp
,
&
current
->
thread
.
regs
,
0
,
parent_tid
,
child_tid
);
}
long
old_mmap
(
unsigned
long
addr
,
unsigned
long
len
,
unsigned
long
prot
,
unsigned
long
flags
,
unsigned
long
fd
,
unsigned
long
offset
)
...
...
arch/x86/Kconfig
View file @
1d4b4b29
...
...
@@ -112,6 +112,7 @@ config X86
select GENERIC_KERNEL_EXECVE
select MODULES_USE_ELF_REL if X86_32
select MODULES_USE_ELF_RELA if X86_64
select CLONE_BACKWARDS if X86_32
config INSTRUCTION_DECODER
def_bool y
...
...
arch/x86/ia32/ia32entry.S
View file @
1d4b4b29
...
...
@@ -467,10 +467,15 @@ GLOBAL(\label)
PTREGSCALL
stub32_sigaltstack
,
sys32_sigaltstack
,
%
rdx
PTREGSCALL
stub32_execve
,
compat_sys_execve
,
%
rcx
PTREGSCALL
stub32_fork
,
sys_fork
,
%
rdi
PTREGSCALL
stub32_clone
,
sys32_clone
,
%
rdx
PTREGSCALL
stub32_vfork
,
sys_vfork
,
%
rdi
PTREGSCALL
stub32_iopl
,
sys_iopl
,
%
rsi
ALIGN
GLOBAL
(
stub32_clone
)
leaq
sys_clone
(%
rip
),%
rax
mov
%
r8
,
%
rcx
jmp
ia32_ptregs_common
ALIGN
ia32_ptregs_common
:
popq
%
r11
...
...
arch/x86/ia32/sys_ia32.c
View file @
1d4b4b29
...
...
@@ -385,17 +385,6 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd,
return
ret
;
}
asmlinkage
long
sys32_clone
(
unsigned
int
clone_flags
,
unsigned
int
newsp
,
struct
pt_regs
*
regs
)
{
void
__user
*
parent_tid
=
(
void
__user
*
)
regs
->
dx
;
void
__user
*
child_tid
=
(
void
__user
*
)
regs
->
di
;
if
(
!
newsp
)
newsp
=
regs
->
sp
;
return
do_fork
(
clone_flags
,
newsp
,
regs
,
0
,
parent_tid
,
child_tid
);
}
/*
* Some system calls that need sign extended arguments. This could be
* done by a generic wrapper.
...
...
arch/x86/include/asm/sys_ia32.h
View file @
1d4b4b29
...
...
@@ -54,8 +54,6 @@ asmlinkage long sys32_pwrite(unsigned int, const char __user *, u32, u32, u32);
asmlinkage
long
sys32_personality
(
unsigned
long
);
asmlinkage
long
sys32_sendfile
(
int
,
int
,
compat_off_t
__user
*
,
s32
);
asmlinkage
long
sys32_clone
(
unsigned
int
,
unsigned
int
,
struct
pt_regs
*
);
long
sys32_lseek
(
unsigned
int
,
int
,
unsigned
int
);
long
sys32_kill
(
int
,
int
);
long
sys32_fadvise64_64
(
int
,
__u32
,
__u32
,
__u32
,
__u32
,
int
);
...
...
arch/x86/include/asm/syscalls.h
View file @
1d4b4b29
...
...
@@ -21,10 +21,15 @@ asmlinkage long sys_ioperm(unsigned long, unsigned long, int);
long
sys_iopl
(
unsigned
int
,
struct
pt_regs
*
);
/* kernel/process.c */
int
sys_fork
(
struct
pt_regs
*
);
int
sys_vfork
(
struct
pt_regs
*
);
long
sys_clone
(
unsigned
long
,
unsigned
long
,
void
__user
*
,
void
__user
*
,
struct
pt_regs
*
);
asmlinkage
long
sys_fork
(
void
);
asmlinkage
long
sys_vfork
(
void
);
#ifdef CONFIG_CLONE_BACKWARDS
asmlinkage
long
sys_clone
(
unsigned
long
,
unsigned
long
,
void
__user
*
,
int
,
void
__user
*
);
#else
asmlinkage
long
sys_clone
(
unsigned
long
,
unsigned
long
,
void
__user
*
,
void
__user
*
,
int
);
#endif
/* kernel/ldt.c */
asmlinkage
int
sys_modify_ldt
(
int
,
void
__user
*
,
unsigned
long
);
...
...
arch/x86/include/asm/unistd.h
View file @
1d4b4b29
...
...
@@ -51,6 +51,9 @@
# define __ARCH_WANT_SYS_UTIME
# define __ARCH_WANT_SYS_WAITPID
# define __ARCH_WANT_SYS_EXECVE
# define __ARCH_WANT_SYS_FORK
# define __ARCH_WANT_SYS_VFORK
# define __ARCH_WANT_SYS_CLONE
/*
* "Conditional" syscalls
...
...
arch/x86/kernel/entry_32.S
View file @
1d4b4b29
...
...
@@ -739,30 +739,12 @@ ENTRY(ptregs_##name) ; \
ENDPROC
(
ptregs_
##
name
)
PTREGSCALL1
(
iopl
)
PTREGSCALL0
(
fork
)
PTREGSCALL0
(
vfork
)
PTREGSCALL2
(
sigaltstack
)
PTREGSCALL0
(
sigreturn
)
PTREGSCALL0
(
rt_sigreturn
)
PTREGSCALL2
(
vm86
)
PTREGSCALL1
(
vm86old
)
/*
Clone
is
an
oddball
.
The
4
th
arg
is
in
%
edi
*/
ENTRY
(
ptregs_clone
)
CFI_STARTPROC
leal
4
(%
esp
),%
eax
pushl_cfi
%
eax
pushl_cfi
PT_EDI
(%
eax
)
movl
PT_EDX
(%
eax
),%
ecx
movl
PT_ECX
(%
eax
),%
edx
movl
PT_EBX
(%
eax
),%
eax
call
sys_clone
addl
$
8
,%
esp
CFI_ADJUST_CFA_OFFSET
-
8
ret
CFI_ENDPROC
ENDPROC
(
ptregs_clone
)
.
macro
FIXUP_ESPFIX_STACK
/*
*
Switch
back
for
ESPFIX
stack
to
the
normal
zerobased
stack
...
...
arch/x86/kernel/entry_64.S
View file @
1d4b4b29
...
...
@@ -845,9 +845,25 @@ ENTRY(\label)
END
(\
label
)
.
endm
PTREGSCALL
stub_clone
,
sys_clone
,
%
r8
PTREGSCALL
stub_fork
,
sys_fork
,
%
rdi
PTREGSCALL
stub_vfork
,
sys_vfork
,
%
rdi
.
macro
FORK_LIKE
func
ENTRY
(
stub_
\
func
)
CFI_STARTPROC
popq
%
r11
/*
save
return
address
*/
PARTIAL_FRAME
0
SAVE_REST
pushq
%
r11
/*
put
it
back
on
stack
*/
FIXUP_TOP_OF_STACK
%
r11
,
8
DEFAULT_FRAME
0
8
/*
offset
8
:
return
address
*/
call
sys_
\
func
RESTORE_TOP_OF_STACK
%
r11
,
8
ret
$REST_SKIP
/*
pop
extended
registers
*/
CFI_ENDPROC
END
(
stub_
\
func
)
.
endm
FORK_LIKE
clone
FORK_LIKE
fork
FORK_LIKE
vfork
PTREGSCALL
stub_sigaltstack
,
sys_sigaltstack
,
%
rdx
PTREGSCALL
stub_iopl
,
sys_iopl
,
%
rsi
...
...
arch/x86/kernel/process.c
View file @
1d4b4b29
...
...
@@ -262,36 +262,6 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
propagate_user_return_notify
(
prev_p
,
next_p
);
}
int
sys_fork
(
struct
pt_regs
*
regs
)
{
return
do_fork
(
SIGCHLD
,
regs
->
sp
,
regs
,
0
,
NULL
,
NULL
);
}
/*
* 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.
*/
int
sys_vfork
(
struct
pt_regs
*
regs
)
{
return
do_fork
(
CLONE_VFORK
|
CLONE_VM
|
SIGCHLD
,
regs
->
sp
,
regs
,
0
,
NULL
,
NULL
);
}
long
sys_clone
(
unsigned
long
clone_flags
,
unsigned
long
newsp
,
void
__user
*
parent_tid
,
void
__user
*
child_tid
,
struct
pt_regs
*
regs
)
{
if
(
!
newsp
)
newsp
=
regs
->
sp
;
return
do_fork
(
clone_flags
,
newsp
,
regs
,
0
,
parent_tid
,
child_tid
);
}
/*
* Idle related variables and functions
*/
...
...
arch/x86/kernel/process_32.c
View file @
1d4b4b29
...
...
@@ -129,7 +129,7 @@ void release_thread(struct task_struct *dead_task)
int
copy_thread
(
unsigned
long
clone_flags
,
unsigned
long
sp
,
unsigned
long
arg
,
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
struct
task_struct
*
p
,
struct
pt_regs
*
unused
)
{
struct
pt_regs
*
childregs
=
task_pt_regs
(
p
);
struct
task_struct
*
tsk
;
...
...
@@ -138,7 +138,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
p
->
thread
.
sp
=
(
unsigned
long
)
childregs
;
p
->
thread
.
sp0
=
(
unsigned
long
)
(
childregs
+
1
);
if
(
unlikely
(
!
regs
))
{
if
(
unlikely
(
p
->
flags
&
PF_KTHREAD
))
{
/* kernel thread */
memset
(
childregs
,
0
,
sizeof
(
struct
pt_regs
));
p
->
thread
.
ip
=
(
unsigned
long
)
ret_from_kernel_thread
;
...
...
@@ -156,12 +156,13 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
memset
(
p
->
thread
.
ptrace_bps
,
0
,
sizeof
(
p
->
thread
.
ptrace_bps
));
return
0
;
}
*
childregs
=
*
regs
;
*
childregs
=
*
current_pt_regs
()
;
childregs
->
ax
=
0
;
if
(
sp
)
childregs
->
sp
=
sp
;
p
->
thread
.
ip
=
(
unsigned
long
)
ret_from_fork
;
task_user_gs
(
p
)
=
get_user_gs
(
regs
);
task_user_gs
(
p
)
=
get_user_gs
(
current_pt_regs
()
);
p
->
fpu_counter
=
0
;
p
->
thread
.
io_bitmap_ptr
=
NULL
;
...
...
arch/x86/kernel/process_64.c
View file @
1d4b4b29
...
...
@@ -169,7 +169,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
savesegment
(
ds
,
p
->
thread
.
ds
);
memset
(
p
->
thread
.
ptrace_bps
,
0
,
sizeof
(
p
->
thread
.
ptrace_bps
));
if
(
unlikely
(
!
regs
))
{
if
(
unlikely
(
p
->
flags
&
PF_KTHREAD
))
{
/* kernel thread */
memset
(
childregs
,
0
,
sizeof
(
struct
pt_regs
));
childregs
->
sp
=
(
unsigned
long
)
childregs
;
...
...
@@ -181,9 +181,10 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
childregs
->
flags
=
X86_EFLAGS_IF
|
X86_EFLAGS_BIT1
;
return
0
;
}
*
childregs
=
*
regs
;
*
childregs
=
*
current_pt_regs
()
;
childregs
->
ax
=
0
;
if
(
sp
)
childregs
->
sp
=
sp
;
err
=
-
ENOMEM
;
...
...
arch/x86/syscalls/syscall_32.tbl
View file @
1d4b4b29
...
...
@@ -8,7 +8,7 @@
#
0 i386 restart_syscall sys_restart_syscall
1 i386 exit sys_exit
2 i386 fork
ptreg
s_fork stub32_fork
2 i386 fork
sy
s_fork stub32_fork
3 i386 read sys_read
4 i386 write sys_write
5 i386 open sys_open compat_sys_open
...
...
@@ -126,7 +126,7 @@
117 i386 ipc sys_ipc sys32_ipc
118 i386 fsync sys_fsync
119 i386 sigreturn ptregs_sigreturn stub32_sigreturn
120 i386 clone
ptreg
s_clone stub32_clone
120 i386 clone
sy
s_clone stub32_clone
121 i386 setdomainname sys_setdomainname
122 i386 uname sys_newuname
123 i386 modify_ldt sys_modify_ldt
...
...
@@ -196,7 +196,7 @@
187 i386 sendfile sys_sendfile sys32_sendfile
188 i386 getpmsg
189 i386 putpmsg
190 i386 vfork
ptreg
s_vfork stub32_vfork
190 i386 vfork
sy
s_vfork stub32_vfork
191 i386 ugetrlimit sys_getrlimit compat_sys_getrlimit
192 i386 mmap2 sys_mmap_pgoff
193 i386 truncate64 sys_truncate64 sys32_truncate64
...
...
arch/x86/um/Kconfig
View file @
1d4b4b29
...
...
@@ -25,6 +25,7 @@ config X86_32
select HAVE_AOUT
select ARCH_WANT_IPC_PARSE_VERSION
select MODULES_USE_ELF_REL
select CLONE_BACKWARDS
config X86_64
def_bool 64BIT
...
...
arch/x86/um/sys_call_table_32.c
View file @
1d4b4b29
...
...
@@ -24,13 +24,10 @@
#define old_mmap sys_old_mmap
#define ptregs_fork sys_fork
#define ptregs_iopl sys_iopl
#define ptregs_vm86old sys_vm86old
#define ptregs_clone i386_clone
#define ptregs_vm86 sys_vm86
#define ptregs_sigaltstack sys_sigaltstack
#define ptregs_vfork sys_vfork
#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage void sym(void) ;
#include <asm/syscalls_32.h>
...
...
arch/x86/um/syscalls_32.c
View file @
1d4b4b29
...
...
@@ -6,21 +6,6 @@
#include <linux/syscalls.h>
#include <sysdep/syscalls.h>
/*
* The prototype on i386 is:
*
* int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls
*
* and the "newtls" arg. on i386 is read by copy_thread directly from the
* register saved on the stack.
*/
long
i386_clone
(
unsigned
long
clone_flags
,
unsigned
long
newsp
,
int
__user
*
parent_tid
,
void
*
newtls
,
int
__user
*
child_tid
)
{
return
sys_clone
(
clone_flags
,
newsp
,
parent_tid
,
child_tid
);
}
long
sys_sigaction
(
int
sig
,
const
struct
old_sigaction
__user
*
act
,
struct
old_sigaction
__user
*
oact
)
{
...
...
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