Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
FengXiao2002
Linux Imx
提交
7076aada
L
Linux Imx
项目概览
FengXiao2002
/
Linux Imx
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
Linux Imx
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
7076aada
编写于
9月 10, 2012
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
x86: split ret_from_fork
Signed-off-by:
N
Al Viro
<
viro@zeniv.linux.org.uk
>
上级
44f4b56b
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
67 addition
and
85 deletion
+67
-85
arch/x86/Kconfig
arch/x86/Kconfig
+1
-0
arch/x86/include/asm/processor.h
arch/x86/include/asm/processor.h
+0
-5
arch/x86/kernel/entry_32.S
arch/x86/kernel/entry_32.S
+10
-5
arch/x86/kernel/entry_64.S
arch/x86/kernel/entry_64.S
+11
-16
arch/x86/kernel/process.c
arch/x86/kernel/process.c
+0
-38
arch/x86/kernel/process_32.c
arch/x86/kernel/process_32.c
+24
-7
arch/x86/kernel/process_64.c
arch/x86/kernel/process_64.c
+21
-14
未找到文件。
arch/x86/Kconfig
浏览文件 @
7076aada
...
...
@@ -97,6 +97,7 @@ config X86
select KTIME_SCALAR if X86_32
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
select GENERIC_KERNEL_THREAD
config INSTRUCTION_DECODER
def_bool (KPROBES || PERF_EVENTS || UPROBES)
...
...
arch/x86/include/asm/processor.h
浏览文件 @
7076aada
...
...
@@ -589,11 +589,6 @@ typedef struct {
}
mm_segment_t
;
/*
* create a kernel thread without removing it from tasklists
*/
extern
int
kernel_thread
(
int
(
*
fn
)(
void
*
),
void
*
arg
,
unsigned
long
flags
);
/* Free all resources held by a thread. */
extern
void
release_thread
(
struct
task_struct
*
);
...
...
arch/x86/kernel/entry_32.S
浏览文件 @
7076aada
...
...
@@ -994,15 +994,20 @@ END(spurious_interrupt_bug)
*/
.
popsection
ENTRY
(
kernel_thread_helper
)
pushl
$
0
#
fake
return
address
for
unwinder
ENTRY
(
ret_from_kernel_thread
)
CFI_STARTPROC
movl
%
edi
,%
eax
call
*%
esi
pushl_cfi
%
eax
call
schedule_tail
GET_THREAD_INFO
(%
ebp
)
popl_cfi
%
eax
pushl_cfi
$
0x0202
#
Reset
kernel
eflags
popfl_cfi
movl
PT_EBP
(%
esp
),%
eax
call
*
PT_EBX
(%
esp
)
call
do_exit
ud2
#
padding
for
call
trace
CFI_ENDPROC
ENDPROC
(
kernel_thread_helper
)
ENDPROC
(
ret_from_kernel_thread
)
#ifdef CONFIG_XEN
/*
Xen
doesn
't set %esp to be precisely what the normal sysenter
...
...
arch/x86/kernel/entry_64.S
浏览文件 @
7076aada
...
...
@@ -450,7 +450,7 @@ ENTRY(ret_from_fork)
RESTORE_REST
testl
$
3
,
CS
-
ARGOFFSET
(%
rsp
)
#
from
kernel_thread
?
jz
retint_restore_args
jz
1
f
testl
$
_TIF_IA32
,
TI_flags
(%
rcx
)
#
32
-
bit
compat
task
needs
IRET
jnz
int_ret_from_sys_call
...
...
@@ -458,6 +458,16 @@ ENTRY(ret_from_fork)
RESTORE_TOP_OF_STACK
%
rdi
,
-
ARGOFFSET
jmp
ret_from_sys_call
#
go
to
the
SYSRET
fastpath
1
:
subq
$REST_SKIP
,
%
rsp
#
move
the
stack
pointer
back
CFI_ADJUST_CFA_OFFSET
REST_SKIP
movq
%
rbp
,
%
rdi
call
*%
rbx
#
exit
mov
%
eax
,
%
edi
call
do_exit
ud2
#
padding
for
call
trace
CFI_ENDPROC
END
(
ret_from_fork
)
...
...
@@ -1206,21 +1216,6 @@ bad_gs:
jmp
2
b
.
previous
ENTRY
(
kernel_thread_helper
)
pushq
$
0
#
fake
return
address
CFI_STARTPROC
/
*
*
Here
we
are
in
the
child
and
the
registers
are
set
as
they
were
*
at
kernel_thread
()
invocation
in
the
parent
.
*/
call
*%
rsi
#
exit
mov
%
eax
,
%
edi
call
do_exit
ud2
#
padding
for
call
trace
CFI_ENDPROC
END
(
kernel_thread_helper
)
/*
*
execve
()
.
This
function
needs
to
use
IRET
,
not
SYSRET
,
to
set
up
all
state
properly
.
*
...
...
arch/x86/kernel/process.c
浏览文件 @
7076aada
...
...
@@ -298,44 +298,6 @@ sys_clone(unsigned long clone_flags, unsigned long newsp,
return
do_fork
(
clone_flags
,
newsp
,
regs
,
0
,
parent_tid
,
child_tid
);
}
/*
* This gets run with %si containing the
* function to call, and %di containing
* the "args".
*/
extern
void
kernel_thread_helper
(
void
);
/*
* Create a kernel thread
*/
int
kernel_thread
(
int
(
*
fn
)(
void
*
),
void
*
arg
,
unsigned
long
flags
)
{
struct
pt_regs
regs
;
memset
(
&
regs
,
0
,
sizeof
(
regs
));
regs
.
si
=
(
unsigned
long
)
fn
;
regs
.
di
=
(
unsigned
long
)
arg
;
#ifdef CONFIG_X86_32
regs
.
ds
=
__USER_DS
;
regs
.
es
=
__USER_DS
;
regs
.
fs
=
__KERNEL_PERCPU
;
regs
.
gs
=
__KERNEL_STACK_CANARY
;
#else
regs
.
ss
=
__KERNEL_DS
;
#endif
regs
.
orig_ax
=
-
1
;
regs
.
ip
=
(
unsigned
long
)
kernel_thread_helper
;
regs
.
cs
=
__KERNEL_CS
|
get_kernel_rpl
();
regs
.
flags
=
X86_EFLAGS_IF
|
X86_EFLAGS_BIT1
;
/* Ok, create the new process.. */
return
do_fork
(
flags
|
CLONE_VM
|
CLONE_UNTRACED
,
0
,
&
regs
,
0
,
NULL
,
NULL
);
}
EXPORT_SYMBOL
(
kernel_thread
);
/*
* sys_execve() executes a new program.
*/
...
...
arch/x86/kernel/process_32.c
浏览文件 @
7076aada
...
...
@@ -57,6 +57,7 @@
#include <asm/switch_to.h>
asmlinkage
void
ret_from_fork
(
void
)
__asm__
(
"ret_from_fork"
);
asmlinkage
void
ret_from_kernel_thread
(
void
)
__asm__
(
"ret_from_kernel_thread"
);
/*
* Return saved PC of a blocked thread.
...
...
@@ -127,23 +128,39 @@ void release_thread(struct task_struct *dead_task)
}
int
copy_thread
(
unsigned
long
clone_flags
,
unsigned
long
sp
,
unsigned
long
unused
,
unsigned
long
arg
,
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
{
struct
pt_regs
*
childregs
;
struct
pt_regs
*
childregs
=
task_pt_regs
(
p
)
;
struct
task_struct
*
tsk
;
int
err
;
childregs
=
task_pt_regs
(
p
);
p
->
thread
.
sp
=
(
unsigned
long
)
childregs
;
p
->
thread
.
sp0
=
(
unsigned
long
)
(
childregs
+
1
);
if
(
unlikely
(
!
regs
))
{
/* kernel thread */
memset
(
childregs
,
0
,
sizeof
(
struct
pt_regs
));
p
->
thread
.
ip
=
(
unsigned
long
)
ret_from_kernel_thread
;
task_user_gs
(
p
)
=
__KERNEL_STACK_CANARY
;
childregs
->
ds
=
__USER_DS
;
childregs
->
es
=
__USER_DS
;
childregs
->
fs
=
__KERNEL_PERCPU
;
childregs
->
bx
=
sp
;
/* function */
childregs
->
bp
=
arg
;
childregs
->
orig_ax
=
-
1
;
childregs
->
cs
=
__KERNEL_CS
|
get_kernel_rpl
();
childregs
->
flags
=
X86_EFLAGS_IF
|
X86_EFLAGS_BIT1
;
p
->
fpu_counter
=
0
;
p
->
thread
.
io_bitmap_ptr
=
NULL
;
memset
(
p
->
thread
.
ptrace_bps
,
0
,
sizeof
(
p
->
thread
.
ptrace_bps
));
return
0
;
}
*
childregs
=
*
regs
;
childregs
->
ax
=
0
;
childregs
->
sp
=
sp
;
p
->
thread
.
sp
=
(
unsigned
long
)
childregs
;
p
->
thread
.
sp0
=
(
unsigned
long
)
(
childregs
+
1
);
p
->
thread
.
ip
=
(
unsigned
long
)
ret_from_fork
;
task_user_gs
(
p
)
=
get_user_gs
(
regs
);
p
->
fpu_counter
=
0
;
...
...
arch/x86/kernel/process_64.c
浏览文件 @
7076aada
...
...
@@ -146,29 +146,18 @@ static inline u32 read_32bit_tls(struct task_struct *t, int tls)
}
int
copy_thread
(
unsigned
long
clone_flags
,
unsigned
long
sp
,
unsigned
long
unused
,
unsigned
long
arg
,
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
{
int
err
;
struct
pt_regs
*
childregs
;
struct
task_struct
*
me
=
current
;
childregs
=
((
struct
pt_regs
*
)
(
THREAD_SIZE
+
task_stack_page
(
p
)))
-
1
;
*
childregs
=
*
regs
;
childregs
->
ax
=
0
;
if
(
user_mode
(
regs
))
childregs
->
sp
=
sp
;
else
childregs
->
sp
=
(
unsigned
long
)
childregs
;
p
->
thread
.
sp0
=
(
unsigned
long
)
task_stack_page
(
p
)
+
THREAD_SIZE
;
childregs
=
task_pt_regs
(
p
);
p
->
thread
.
sp
=
(
unsigned
long
)
childregs
;
p
->
thread
.
sp0
=
(
unsigned
long
)
(
childregs
+
1
);
p
->
thread
.
usersp
=
me
->
thread
.
usersp
;
set_tsk_thread_flag
(
p
,
TIF_FORK
);
p
->
fpu_counter
=
0
;
p
->
thread
.
io_bitmap_ptr
=
NULL
;
...
...
@@ -178,6 +167,24 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
p
->
thread
.
fs
=
p
->
thread
.
fsindex
?
0
:
me
->
thread
.
fs
;
savesegment
(
es
,
p
->
thread
.
es
);
savesegment
(
ds
,
p
->
thread
.
ds
);
memset
(
p
->
thread
.
ptrace_bps
,
0
,
sizeof
(
p
->
thread
.
ptrace_bps
));
if
(
unlikely
(
!
regs
))
{
/* kernel thread */
memset
(
childregs
,
0
,
sizeof
(
struct
pt_regs
));
childregs
->
sp
=
(
unsigned
long
)
childregs
;
childregs
->
ss
=
__KERNEL_DS
;
childregs
->
bx
=
sp
;
/* function */
childregs
->
bp
=
arg
;
childregs
->
orig_ax
=
-
1
;
childregs
->
cs
=
__KERNEL_CS
|
get_kernel_rpl
();
childregs
->
flags
=
X86_EFLAGS_IF
|
X86_EFLAGS_BIT1
;
return
0
;
}
*
childregs
=
*
regs
;
childregs
->
ax
=
0
;
childregs
->
sp
=
sp
;
err
=
-
ENOMEM
;
memset
(
p
->
thread
.
ptrace_bps
,
0
,
sizeof
(
p
->
thread
.
ptrace_bps
));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录