Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
1918c7f5
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
1918c7f5
编写于
10月 05, 2012
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
sparc64: switch to generic kernel_thread()
Signed-off-by:
N
Al Viro
<
viro@zeniv.linux.org.uk
>
上级
dff933da
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
42 addition
and
82 deletion
+42
-82
arch/sparc/Kconfig
arch/sparc/Kconfig
+1
-0
arch/sparc/include/asm/processor_64.h
arch/sparc/include/asm/processor_64.h
+0
-2
arch/sparc/include/asm/ptrace.h
arch/sparc/include/asm/ptrace.h
+3
-0
arch/sparc/kernel/process_64.c
arch/sparc/kernel/process_64.c
+30
-77
arch/sparc/kernel/syscalls.S
arch/sparc/kernel/syscalls.S
+8
-3
未找到文件。
arch/sparc/Kconfig
浏览文件 @
1918c7f5
...
...
@@ -74,6 +74,7 @@ config SPARC64
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select HAVE_C_RECORDMCOUNT
select NO_BOOTMEM
select GENERIC_KERNEL_THREAD
config ARCH_DEFCONFIG
string
...
...
arch/sparc/include/asm/processor_64.h
浏览文件 @
1918c7f5
...
...
@@ -188,8 +188,6 @@ do { \
/* Free all resources held by a thread. */
#define release_thread(tsk) do { } while (0)
extern
pid_t
kernel_thread
(
int
(
*
fn
)(
void
*
),
void
*
arg
,
unsigned
long
flags
);
extern
unsigned
long
get_wchan
(
struct
task_struct
*
task
);
#define task_pt_regs(tsk) (task_thread_info(tsk)->kregs)
...
...
arch/sparc/include/asm/ptrace.h
浏览文件 @
1918c7f5
...
...
@@ -32,6 +32,9 @@ static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
#define arch_ptrace_stop(exit_code, info) \
synchronize_user_stack()
#define current_pt_regs() \
((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1)
struct
global_reg_snapshot
{
unsigned
long
tstate
;
unsigned
long
tpc
;
...
...
arch/sparc/kernel/process_64.c
浏览文件 @
1918c7f5
...
...
@@ -538,64 +538,56 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags,
* Child --> %o0 == parents pid, %o1 == 1
*/
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
thread_info
*
t
=
task_thread_info
(
p
);
struct
sparc_stackf
*
parent_sf
;
unsigned
long
child_stack_sz
;
char
*
child_trap_frame
;
int
kernel_thread
;
kernel_thread
=
(
regs
->
tstate
&
TSTATE_PRIV
)
?
1
:
0
;
parent_sf
=
((
struct
sparc_stackf
*
)
regs
)
-
1
;
/* Calculate offset to stack_frame & pt_regs */
child_stack_sz
=
((
STACKFRAME_SZ
+
TRACEREG_SZ
)
+
(
kernel_thread
?
STACKFRAME_SZ
:
0
));
child_stack_sz
=
(
STACKFRAME_SZ
+
TRACEREG_SZ
);
child_trap_frame
=
(
task_stack_page
(
p
)
+
(
THREAD_SIZE
-
child_stack_sz
));
memcpy
(
child_trap_frame
,
parent_sf
,
child_stack_sz
);
__thread_flag_byte_ptr
(
t
)[
TI_FLAG_BYTE_CWP
]
=
(
regs
->
tstate
+
1
)
&
TSTATE_CWP
;
t
->
new_child
=
1
;
t
->
ksp
=
((
unsigned
long
)
child_trap_frame
)
-
STACK_BIAS
;
t
->
kregs
=
(
struct
pt_regs
*
)
(
child_trap_frame
+
sizeof
(
struct
sparc_stackf
));
t
->
fpsaved
[
0
]
=
0
;
if
(
kernel_thread
)
{
struct
sparc_stackf
*
child_sf
=
(
struct
sparc_stackf
*
)
(
child_trap_frame
+
(
STACKFRAME_SZ
+
TRACEREG_SZ
));
/* Zero terminate the stack backtrace. */
child_sf
->
fp
=
NULL
;
t
->
kregs
->
u_regs
[
UREG_FP
]
=
((
unsigned
long
)
child_sf
)
-
STACK_BIAS
;
if
(
unlikely
(
p
->
flags
&
PF_KTHREAD
))
{
memset
(
child_trap_frame
,
0
,
child_stack_sz
);
__thread_flag_byte_ptr
(
t
)[
TI_FLAG_BYTE_CWP
]
=
(
current_pt_regs
()
->
tstate
+
1
)
&
TSTATE_CWP
;
t
->
current_ds
=
ASI_P
;
t
->
kregs
->
u_regs
[
UREG_G6
]
=
(
unsigned
long
)
t
;
t
->
kregs
->
u_regs
[
UREG_G4
]
=
(
unsigned
long
)
t
->
task
;
}
else
{
if
(
t
->
flags
&
_TIF_32BIT
)
{
sp
&=
0x00000000ffffffffUL
;
regs
->
u_regs
[
UREG_FP
]
&=
0x00000000ffffffffUL
;
}
t
->
kregs
->
u_regs
[
UREG_FP
]
=
sp
;
t
->
current_ds
=
ASI_AIUS
;
if
(
sp
!=
regs
->
u_regs
[
UREG_FP
])
{
unsigned
long
csp
;
csp
=
clone_stackframe
(
sp
,
regs
->
u_regs
[
UREG_FP
]);
if
(
!
csp
)
return
-
EFAULT
;
t
->
kregs
->
u_regs
[
UREG_FP
]
=
csp
;
}
if
(
t
->
utraps
)
t
->
utraps
[
0
]
++
;
t
->
kregs
->
u_regs
[
UREG_G1
]
=
sp
;
/* function */
t
->
kregs
->
u_regs
[
UREG_G2
]
=
arg
;
return
0
;
}
parent_sf
=
((
struct
sparc_stackf
*
)
regs
)
-
1
;
memcpy
(
child_trap_frame
,
parent_sf
,
child_stack_sz
);
if
(
t
->
flags
&
_TIF_32BIT
)
{
sp
&=
0x00000000ffffffffUL
;
regs
->
u_regs
[
UREG_FP
]
&=
0x00000000ffffffffUL
;
}
t
->
kregs
->
u_regs
[
UREG_FP
]
=
sp
;
__thread_flag_byte_ptr
(
t
)[
TI_FLAG_BYTE_CWP
]
=
(
regs
->
tstate
+
1
)
&
TSTATE_CWP
;
t
->
current_ds
=
ASI_AIUS
;
if
(
sp
!=
regs
->
u_regs
[
UREG_FP
])
{
unsigned
long
csp
;
csp
=
clone_stackframe
(
sp
,
regs
->
u_regs
[
UREG_FP
]);
if
(
!
csp
)
return
-
EFAULT
;
t
->
kregs
->
u_regs
[
UREG_FP
]
=
csp
;
}
if
(
t
->
utraps
)
t
->
utraps
[
0
]
++
;
/* Set the return value for the child. */
t
->
kregs
->
u_regs
[
UREG_I0
]
=
current
->
pid
;
t
->
kregs
->
u_regs
[
UREG_I1
]
=
1
;
...
...
@@ -609,45 +601,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
return
0
;
}
/*
* This is the mechanism for creating a new kernel thread.
*
* NOTE! Only a kernel-only process(ie the swapper or direct descendants
* who haven't done an "execve()") should use this: it will work within
* a system call from a "real" process, but the process memory space will
* not be freed until both the parent and the child have exited.
*/
pid_t
kernel_thread
(
int
(
*
fn
)(
void
*
),
void
*
arg
,
unsigned
long
flags
)
{
long
retval
;
/* If the parent runs before fn(arg) is called by the child,
* the input registers of this function can be clobbered.
* So we stash 'fn' and 'arg' into global registers which
* will not be modified by the parent.
*/
__asm__
__volatile__
(
"mov %4, %%g2
\n\t
"
/* Save FN into global */
"mov %5, %%g3
\n\t
"
/* Save ARG into global */
"mov %1, %%g1
\n\t
"
/* Clone syscall nr. */
"mov %2, %%o0
\n\t
"
/* Clone flags. */
"mov 0, %%o1
\n\t
"
/* usp arg == 0 */
"t 0x6d
\n\t
"
/* Linux/Sparc clone(). */
"brz,a,pn %%o1, 1f
\n\t
"
/* Parent, just return. */
" mov %%o0, %0
\n\t
"
"jmpl %%g2, %%o7
\n\t
"
/* Call the function. */
" mov %%g3, %%o0
\n\t
"
/* Set arg in delay. */
"mov %3, %%g1
\n\t
"
"t 0x6d
\n\t
"
/* Linux/Sparc exit(). */
/* Notreached by child. */
"1:"
:
"=r"
(
retval
)
:
"i"
(
__NR_clone
),
"r"
(
flags
|
CLONE_VM
|
CLONE_UNTRACED
),
"i"
(
__NR_exit
),
"r"
(
fn
),
"r"
(
arg
)
:
"g1"
,
"g2"
,
"g3"
,
"o0"
,
"o1"
,
"memory"
,
"cc"
);
return
retval
;
}
EXPORT_SYMBOL
(
kernel_thread
);
typedef
struct
{
union
{
unsigned
int
pr_regs
[
32
];
...
...
arch/sparc/kernel/syscalls.S
浏览文件 @
1918c7f5
...
...
@@ -112,11 +112,16 @@ sys_clone:
ret_from_syscall
:
/
*
Clear
current_thread_info
()->
new_child
.
*/
stb
%
g0
,
[%
g6
+
TI_NEW_CHILD
]
ldx
[%
g6
+
TI_FLAGS
],
%
l0
call
schedule_tail
mov
%
g7
,
%
o0
ba
,
pt
%
xcc
,
ret_sys_call
ldx
[%
sp
+
PTREGS_OFF
+
PT_V9_I0
],
%
o0
ldx
[%
sp
+
PTREGS_OFF
+
PT_V9_I0
],
%
o0
brnz
,
a
,
pt
%
o0
,
ret_sys_call
ldx
[%
g6
+
TI_FLAGS
],
%
l0
ldx
[%
sp
+
PTREGS_OFF
+
PT_V9_G1
],
%
l0
call
%
l0
ldx
[%
sp
+
PTREGS_OFF
+
PT_V9_G2
],
%
o0
call
do_exit
!
will
not
return
mov
0
,%
o0
.
globl
sparc_exit
.
type
sparc_exit
,#
function
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录