Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
08f73957
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看板
提交
08f73957
编写于
11月 07, 2012
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
sparc: convert to ksignal
Signed-off-by:
N
Al Viro
<
viro@zeniv.linux.org.uk
>
上级
7e243643
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
164 addition
and
254 deletion
+164
-254
arch/sparc/kernel/signal32.c
arch/sparc/kernel/signal32.c
+62
-92
arch/sparc/kernel/signal_32.c
arch/sparc/kernel/signal_32.c
+59
-87
arch/sparc/kernel/signal_64.c
arch/sparc/kernel/signal_64.c
+43
-75
未找到文件。
arch/sparc/kernel/signal32.c
浏览文件 @
08f73957
...
...
@@ -323,7 +323,7 @@ static int invalid_frame_pointer(void __user *fp, int fplen)
return
0
;
}
static
void
__user
*
get_sigframe
(
struct
sigaction
*
sa
,
struct
pt_regs
*
regs
,
unsigned
long
framesize
)
static
void
__user
*
get_sigframe
(
struct
ksignal
*
ksig
,
struct
pt_regs
*
regs
,
unsigned
long
framesize
)
{
unsigned
long
sp
;
...
...
@@ -338,12 +338,7 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
return
(
void
__user
*
)
-
1L
;
/* This is the X/Open sanctioned signal stack switching. */
if
(
sa
->
sa_flags
&
SA_ONSTACK
)
{
if
(
sas_ss_flags
(
sp
)
==
0
)
sp
=
current
->
sas_ss_sp
+
current
->
sas_ss_size
;
}
sp
-=
framesize
;
sp
=
sigsp
(
sp
,
ksig
)
-
framesize
;
/* Always align the stack frame. This handles two cases. First,
* sigaltstack need not be mindful of platform specific stack
...
...
@@ -414,8 +409,8 @@ static void flush_signal_insns(unsigned long address)
}
static
int
setup_frame32
(
struct
k
_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signo
,
sigset_t
*
oldset
)
static
int
setup_frame32
(
struct
k
signal
*
ksig
,
struct
pt_regs
*
regs
,
sigset_t
*
oldset
)
{
struct
signal_frame32
__user
*
sf
;
int
i
,
err
,
wsaved
;
...
...
@@ -437,10 +432,12 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
sigframe_size
+=
sizeof
(
__siginfo_rwin_t
);
sf
=
(
struct
signal_frame32
__user
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
get_sigframe
(
ksig
,
regs
,
sigframe_size
);
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
goto
sigill
;
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
{
do_exit
(
SIGILL
);
return
-
EINVAL
;
}
tail
=
(
sf
+
1
);
...
...
@@ -514,16 +511,16 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
err
|=
__put_user
(
rp
->
ins
[
7
],
&
sf
->
ss
.
callers_pc
);
}
if
(
err
)
goto
sigsegv
;
return
err
;
/* 3. signal handler back-trampoline and parameters */
regs
->
u_regs
[
UREG_FP
]
=
(
unsigned
long
)
sf
;
regs
->
u_regs
[
UREG_I0
]
=
signo
;
regs
->
u_regs
[
UREG_I0
]
=
ksig
->
sig
;
regs
->
u_regs
[
UREG_I1
]
=
(
unsigned
long
)
&
sf
->
info
;
regs
->
u_regs
[
UREG_I2
]
=
(
unsigned
long
)
&
sf
->
info
;
/* 4. signal handler */
regs
->
tpc
=
(
unsigned
long
)
k
a
->
sa
.
sa_handler
;
regs
->
tpc
=
(
unsigned
long
)
k
sig
->
ka
.
sa
.
sa_handler
;
regs
->
tnpc
=
(
regs
->
tpc
+
4
);
if
(
test_thread_flag
(
TIF_32BIT
))
{
regs
->
tpc
&=
0xffffffff
;
...
...
@@ -531,8 +528,8 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
}
/* 5. return to kernel instructions */
if
(
k
a
->
ka_restorer
)
{
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)
k
a
->
ka_restorer
;
if
(
k
sig
->
ka
.
ka_restorer
)
{
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)
k
sig
->
ka
.
ka_restorer
;
}
else
{
unsigned
long
address
=
((
unsigned
long
)
&
(
sf
->
insns
[
0
]));
...
...
@@ -541,23 +538,14 @@ static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
err
=
__put_user
(
0x821020d8
,
&
sf
->
insns
[
0
]);
/*mov __NR_sigreturn, %g1*/
err
|=
__put_user
(
0x91d02010
,
&
sf
->
insns
[
1
]);
/*t 0x10*/
if
(
err
)
goto
sigsegv
;
return
err
;
flush_signal_insns
(
address
);
}
return
0
;
sigill:
do_exit
(
SIGILL
);
return
-
EINVAL
;
sigsegv:
force_sigsegv
(
signo
,
current
);
return
-
EFAULT
;
}
static
int
setup_rt_frame32
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
unsigned
long
signr
,
sigset_t
*
oldset
,
siginfo_t
*
info
)
static
int
setup_rt_frame32
(
struct
ksignal
*
ksig
,
struct
pt_regs
*
regs
,
sigset_t
*
oldset
)
{
struct
rt_signal_frame32
__user
*
sf
;
int
i
,
err
,
wsaved
;
...
...
@@ -579,10 +567,12 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
sigframe_size
+=
sizeof
(
__siginfo_rwin_t
);
sf
=
(
struct
rt_signal_frame32
__user
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
get_sigframe
(
ksig
,
regs
,
sigframe_size
);
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
goto
sigill
;
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
{
do_exit
(
SIGILL
);
return
-
EINVAL
;
}
tail
=
(
sf
+
1
);
...
...
@@ -627,7 +617,7 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
}
/* Update the siginfo structure. */
err
|=
copy_siginfo_to_user32
(
&
sf
->
info
,
info
);
err
|=
copy_siginfo_to_user32
(
&
sf
->
info
,
&
ksig
->
info
);
/* Setup sigaltstack */
err
|=
__compat_save_altstack
(
&
sf
->
stack
,
regs
->
u_regs
[
UREG_FP
]);
...
...
@@ -660,16 +650,16 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
err
|=
__put_user
(
rp
->
ins
[
7
],
&
sf
->
ss
.
callers_pc
);
}
if
(
err
)
goto
sigsegv
;
return
err
;
/* 3. signal handler back-trampoline and parameters */
regs
->
u_regs
[
UREG_FP
]
=
(
unsigned
long
)
sf
;
regs
->
u_regs
[
UREG_I0
]
=
signr
;
regs
->
u_regs
[
UREG_I0
]
=
ksig
->
sig
;
regs
->
u_regs
[
UREG_I1
]
=
(
unsigned
long
)
&
sf
->
info
;
regs
->
u_regs
[
UREG_I2
]
=
(
unsigned
long
)
&
sf
->
regs
;
/* 4. signal handler */
regs
->
tpc
=
(
unsigned
long
)
k
a
->
sa
.
sa_handler
;
regs
->
tpc
=
(
unsigned
long
)
k
sig
->
ka
.
sa
.
sa_handler
;
regs
->
tnpc
=
(
regs
->
tpc
+
4
);
if
(
test_thread_flag
(
TIF_32BIT
))
{
regs
->
tpc
&=
0xffffffff
;
...
...
@@ -677,8 +667,8 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
}
/* 5. return to kernel instructions */
if
(
k
a
->
ka_restorer
)
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)
k
a
->
ka_restorer
;
if
(
k
sig
->
ka
.
ka_restorer
)
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)
k
sig
->
ka
.
ka_restorer
;
else
{
unsigned
long
address
=
((
unsigned
long
)
&
(
sf
->
insns
[
0
]));
...
...
@@ -690,36 +680,25 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
/* t 0x10 */
err
|=
__put_user
(
0x91d02010
,
&
sf
->
insns
[
1
]);
if
(
err
)
goto
sigsegv
;
return
err
;
flush_signal_insns
(
address
);
}
return
0
;
sigill:
do_exit
(
SIGILL
);
return
-
EINVAL
;
sigsegv:
force_sigsegv
(
signr
,
current
);
return
-
EFAULT
;
}
static
inline
void
handle_signal32
(
unsigned
long
signr
,
struct
k_sigaction
*
ka
,
siginfo_t
*
info
,
sigset_t
*
oldset
,
struct
pt_regs
*
regs
)
static
inline
void
handle_signal32
(
struct
ksignal
*
ksig
,
struct
pt_regs
*
regs
)
{
sigset_t
*
oldset
=
sigmask_to_save
();
int
err
;
if
(
k
a
->
sa
.
sa_flags
&
SA_SIGINFO
)
err
=
setup_rt_frame32
(
k
a
,
regs
,
signr
,
oldset
,
info
);
if
(
k
sig
->
ka
.
sa
.
sa_flags
&
SA_SIGINFO
)
err
=
setup_rt_frame32
(
k
sig
,
regs
,
oldset
);
else
err
=
setup_frame32
(
k
a
,
regs
,
signr
,
oldset
);
err
=
setup_frame32
(
k
sig
,
regs
,
oldset
);
if
(
err
)
return
;
signal_delivered
(
signr
,
info
,
ka
,
regs
,
0
);
signal_setup_done
(
err
,
ksig
,
0
);
}
static
inline
void
syscall_restart32
(
unsigned
long
orig_i0
,
struct
pt_regs
*
regs
,
...
...
@@ -749,50 +728,41 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
*/
void
do_signal32
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
)
{
struct
k_sigaction
ka
;
unsigned
long
orig_i0
;
int
restart_syscall
;
siginfo_t
info
;
int
signr
;
signr
=
get_signal_to_deliver
(
&
info
,
&
ka
,
regs
,
NULL
);
struct
ksignal
ksig
;
unsigned
long
orig_i0
=
0
;
int
restart_syscall
=
0
;
bool
has_handler
=
get_signal
(
&
ksig
);
restart_syscall
=
0
;
orig_i0
=
0
;
if
(
pt_regs_is_syscall
(
regs
)
&&
(
regs
->
tstate
&
(
TSTATE_XCARRY
|
TSTATE_ICARRY
)))
{
restart_syscall
=
1
;
orig_i0
=
regs
->
u_regs
[
UREG_G6
];
}
if
(
signr
>
0
)
{
if
(
has_handler
)
{
if
(
restart_syscall
)
syscall_restart32
(
orig_i0
,
regs
,
&
ka
.
sa
);
handle_signal32
(
signr
,
&
ka
,
&
info
,
oldset
,
regs
);
return
;
}
if
(
restart_syscall
&&
(
regs
->
u_regs
[
UREG_I0
]
==
ERESTARTNOHAND
||
regs
->
u_regs
[
UREG_I0
]
==
ERESTARTSYS
||
regs
->
u_regs
[
UREG_I0
]
==
ERESTARTNOINTR
))
{
/* replay the system call when we are done */
regs
->
u_regs
[
UREG_I0
]
=
orig_i0
;
regs
->
tpc
-=
4
;
regs
->
tnpc
-=
4
;
pt_regs_clear_syscall
(
regs
);
}
if
(
restart_syscall
&&
regs
->
u_regs
[
UREG_I0
]
==
ERESTART_RESTARTBLOCK
)
{
regs
->
u_regs
[
UREG_G1
]
=
__NR_restart_syscall
;
regs
->
tpc
-=
4
;
regs
->
tnpc
-=
4
;
pt_regs_clear_syscall
(
regs
);
syscall_restart32
(
orig_i0
,
regs
,
&
ksig
.
ka
.
sa
);
handle_signal32
(
&
ksig
,
regs
);
}
else
{
if
(
restart_syscall
)
{
switch
(
regs
->
u_regs
[
UREG_I0
])
{
case
ERESTARTNOHAND
:
case
ERESTARTSYS
:
case
ERESTARTNOINTR
:
/* replay the system call when we are done */
regs
->
u_regs
[
UREG_I0
]
=
orig_i0
;
regs
->
tpc
-=
4
;
regs
->
tnpc
-=
4
;
pt_regs_clear_syscall
(
regs
);
case
ERESTART_RESTARTBLOCK
:
regs
->
u_regs
[
UREG_G1
]
=
__NR_restart_syscall
;
regs
->
tpc
-=
4
;
regs
->
tnpc
-=
4
;
pt_regs_clear_syscall
(
regs
);
}
}
restore_saved_sigmask
();
}
/* If there's no signal to deliver, we just put the saved sigmask
* back
*/
restore_saved_sigmask
();
}
struct
sigstack32
{
...
...
arch/sparc/kernel/signal_32.c
浏览文件 @
08f73957
...
...
@@ -186,7 +186,7 @@ static inline int invalid_frame_pointer(void __user *fp, int fplen)
return
0
;
}
static
inline
void
__user
*
get_sigframe
(
struct
sigaction
*
sa
,
struct
pt_regs
*
regs
,
unsigned
long
framesize
)
static
inline
void
__user
*
get_sigframe
(
struct
ksignal
*
ksig
,
struct
pt_regs
*
regs
,
unsigned
long
framesize
)
{
unsigned
long
sp
=
regs
->
u_regs
[
UREG_FP
];
...
...
@@ -198,12 +198,7 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re
return
(
void
__user
*
)
-
1L
;
/* This is the X/Open sanctioned signal stack switching. */
if
(
sa
->
sa_flags
&
SA_ONSTACK
)
{
if
(
sas_ss_flags
(
sp
)
==
0
)
sp
=
current
->
sas_ss_sp
+
current
->
sas_ss_size
;
}
sp
-=
framesize
;
sp
=
sigsp
(
sp
,
ksig
)
-
framesize
;
/* Always align the stack frame. This handles two cases. First,
* sigaltstack need not be mindful of platform specific stack
...
...
@@ -216,8 +211,8 @@ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *re
return
(
void
__user
*
)
sp
;
}
static
int
setup_frame
(
struct
k
_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signo
,
sigset_t
*
oldset
)
static
int
setup_frame
(
struct
k
signal
*
ksig
,
struct
pt_regs
*
regs
,
sigset_t
*
oldset
)
{
struct
signal_frame
__user
*
sf
;
int
sigframe_size
,
err
,
wsaved
;
...
...
@@ -235,10 +230,12 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
sigframe_size
+=
sizeof
(
__siginfo_rwin_t
);
sf
=
(
struct
signal_frame
__user
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
get_sigframe
(
ksig
,
regs
,
sigframe_size
);
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
goto
sigill_and_return
;
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
{
do_exit
(
SIGILL
);
return
-
EINVAL
;
}
tail
=
sf
+
1
;
...
...
@@ -277,21 +274,21 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
err
|=
__copy_to_user
(
sf
,
rp
,
sizeof
(
struct
reg_window32
));
}
if
(
err
)
goto
sigsegv
;
return
err
;
/* 3. signal handler back-trampoline and parameters */
regs
->
u_regs
[
UREG_FP
]
=
(
unsigned
long
)
sf
;
regs
->
u_regs
[
UREG_I0
]
=
signo
;
regs
->
u_regs
[
UREG_I0
]
=
ksig
->
sig
;
regs
->
u_regs
[
UREG_I1
]
=
(
unsigned
long
)
&
sf
->
info
;
regs
->
u_regs
[
UREG_I2
]
=
(
unsigned
long
)
&
sf
->
info
;
/* 4. signal handler */
regs
->
pc
=
(
unsigned
long
)
k
a
->
sa
.
sa_handler
;
regs
->
pc
=
(
unsigned
long
)
k
sig
->
ka
.
sa
.
sa_handler
;
regs
->
npc
=
(
regs
->
pc
+
4
);
/* 5. return to kernel instructions */
if
(
k
a
->
ka_restorer
)
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)
k
a
->
ka_restorer
;
if
(
k
sig
->
ka
.
ka_restorer
)
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)
k
sig
->
ka
.
ka_restorer
;
else
{
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)(
&
(
sf
->
insns
[
0
])
-
2
);
...
...
@@ -301,24 +298,16 @@ static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
/* t 0x10 */
err
|=
__put_user
(
0x91d02010
,
&
sf
->
insns
[
1
]);
if
(
err
)
goto
sigsegv
;
return
err
;
/* Flush instruction space. */
flush_sig_insns
(
current
->
mm
,
(
unsigned
long
)
&
(
sf
->
insns
[
0
]));
}
return
0
;
sigill_and_return:
do_exit
(
SIGILL
);
return
-
EINVAL
;
sigsegv:
force_sigsegv
(
signo
,
current
);
return
-
EFAULT
;
}
static
int
setup_rt_frame
(
struct
k
_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signo
,
sigset_t
*
oldset
,
siginfo_t
*
info
)
static
int
setup_rt_frame
(
struct
k
signal
*
ksig
,
struct
pt_regs
*
regs
,
sigset_t
*
oldset
)
{
struct
rt_signal_frame
__user
*
sf
;
int
sigframe_size
,
wsaved
;
...
...
@@ -334,9 +323,11 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
if
(
wsaved
)
sigframe_size
+=
sizeof
(
__siginfo_rwin_t
);
sf
=
(
struct
rt_signal_frame
__user
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
goto
sigill
;
get_sigframe
(
ksig
,
regs
,
sigframe_size
);
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
{
do_exit
(
SIGILL
);
return
-
EINVAL
;
}
tail
=
sf
+
1
;
err
=
__put_user
(
regs
->
pc
,
&
sf
->
regs
.
pc
);
...
...
@@ -380,21 +371,21 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
err
|=
__copy_to_user
(
sf
,
rp
,
sizeof
(
struct
reg_window32
));
}
err
|=
copy_siginfo_to_user
(
&
sf
->
info
,
info
);
err
|=
copy_siginfo_to_user
(
&
sf
->
info
,
&
ksig
->
info
);
if
(
err
)
goto
sigsegv
;
return
err
;
regs
->
u_regs
[
UREG_FP
]
=
(
unsigned
long
)
sf
;
regs
->
u_regs
[
UREG_I0
]
=
signo
;
regs
->
u_regs
[
UREG_I0
]
=
ksig
->
sig
;
regs
->
u_regs
[
UREG_I1
]
=
(
unsigned
long
)
&
sf
->
info
;
regs
->
u_regs
[
UREG_I2
]
=
(
unsigned
long
)
&
sf
->
regs
;
regs
->
pc
=
(
unsigned
long
)
k
a
->
sa
.
sa_handler
;
regs
->
pc
=
(
unsigned
long
)
k
sig
->
ka
.
sa
.
sa_handler
;
regs
->
npc
=
(
regs
->
pc
+
4
);
if
(
k
a
->
ka_restorer
)
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)
k
a
->
ka_restorer
;
if
(
k
sig
->
ka
.
ka_restorer
)
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)
k
sig
->
ka
.
ka_restorer
;
else
{
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)(
&
(
sf
->
insns
[
0
])
-
2
);
...
...
@@ -404,38 +395,25 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
/* t 0x10 */
err
|=
__put_user
(
0x91d02010
,
&
sf
->
insns
[
1
]);
if
(
err
)
goto
sigsegv
;
return
err
;
/* Flush instruction space. */
flush_sig_insns
(
current
->
mm
,
(
unsigned
long
)
&
(
sf
->
insns
[
0
]));
}
return
0
;
sigill:
do_exit
(
SIGILL
);
return
-
EINVAL
;
sigsegv:
force_sigsegv
(
signo
,
current
);
return
-
EFAULT
;
}
static
inline
void
handle_signal
(
unsigned
long
signr
,
struct
k_sigaction
*
ka
,
siginfo_t
*
info
,
struct
pt_regs
*
regs
)
handle_signal
(
struct
ksignal
*
ksig
,
struct
pt_regs
*
regs
)
{
sigset_t
*
oldset
=
sigmask_to_save
();
int
err
;
if
(
k
a
->
sa
.
sa_flags
&
SA_SIGINFO
)
err
=
setup_rt_frame
(
k
a
,
regs
,
signr
,
oldset
,
info
);
if
(
k
sig
->
ka
.
sa
.
sa_flags
&
SA_SIGINFO
)
err
=
setup_rt_frame
(
k
sig
,
regs
,
oldset
);
else
err
=
setup_frame
(
ka
,
regs
,
signr
,
oldset
);
if
(
err
)
return
;
signal_delivered
(
signr
,
info
,
ka
,
regs
,
0
);
err
=
setup_frame
(
ksig
,
regs
,
oldset
);
signal_setup_done
(
err
,
ksig
,
0
);
}
static
inline
void
syscall_restart
(
unsigned
long
orig_i0
,
struct
pt_regs
*
regs
,
...
...
@@ -465,10 +443,9 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
*/
static
void
do_signal
(
struct
pt_regs
*
regs
,
unsigned
long
orig_i0
)
{
struct
k
_sigaction
ka
;
struct
k
signal
ksig
;
int
restart_syscall
;
siginfo_t
info
;
int
signr
;
bool
has_handler
;
/* It's a lot of work and synchronization to add a new ptrace
* register for GDB to save and restore in order to get
...
...
@@ -491,7 +468,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
if
(
pt_regs_is_syscall
(
regs
)
&&
(
regs
->
psr
&
PSR_C
))
regs
->
u_regs
[
UREG_G6
]
=
orig_i0
;
signr
=
get_signal_to_deliver
(
&
info
,
&
ka
,
regs
,
NULL
);
has_handler
=
get_signal
(
&
ksig
);
/* If the debugger messes with the program counter, it clears
* the software "in syscall" bit, directing us to not perform
...
...
@@ -503,35 +480,30 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
orig_i0
=
regs
->
u_regs
[
UREG_G6
];
}
if
(
signr
>
0
)
{
if
(
has_handler
)
{
if
(
restart_syscall
)
syscall_restart
(
orig_i0
,
regs
,
&
ka
.
sa
);
handle_signal
(
signr
,
&
ka
,
&
info
,
regs
);
return
;
}
if
(
restart_syscall
&&
(
regs
->
u_regs
[
UREG_I0
]
==
ERESTARTNOHAND
||
regs
->
u_regs
[
UREG_I0
]
==
ERESTARTSYS
||
regs
->
u_regs
[
UREG_I0
]
==
ERESTARTNOINTR
))
{
/* replay the system call when we are done */
regs
->
u_regs
[
UREG_I0
]
=
orig_i0
;
regs
->
pc
-=
4
;
regs
->
npc
-=
4
;
pt_regs_clear_syscall
(
regs
);
}
if
(
restart_syscall
&&
regs
->
u_regs
[
UREG_I0
]
==
ERESTART_RESTARTBLOCK
)
{
regs
->
u_regs
[
UREG_G1
]
=
__NR_restart_syscall
;
regs
->
pc
-=
4
;
regs
->
npc
-=
4
;
pt_regs_clear_syscall
(
regs
);
syscall_restart
(
orig_i0
,
regs
,
&
ksig
.
ka
.
sa
);
handle_signal
(
&
ksig
,
regs
);
}
else
{
if
(
restart_syscall
)
{
switch
(
regs
->
u_regs
[
UREG_I0
])
{
case
ERESTARTNOHAND
:
case
ERESTARTSYS
:
case
ERESTARTNOINTR
:
/* replay the system call when we are done */
regs
->
u_regs
[
UREG_I0
]
=
orig_i0
;
regs
->
pc
-=
4
;
regs
->
npc
-=
4
;
pt_regs_clear_syscall
(
regs
);
case
ERESTART_RESTARTBLOCK
:
regs
->
u_regs
[
UREG_G1
]
=
__NR_restart_syscall
;
regs
->
pc
-=
4
;
regs
->
npc
-=
4
;
pt_regs_clear_syscall
(
regs
);
}
}
restore_saved_sigmask
();
}
/* if there's no signal to deliver, we just put the saved sigmask
* back
*/
restore_saved_sigmask
();
}
void
do_notify_resume
(
struct
pt_regs
*
regs
,
unsigned
long
orig_i0
,
...
...
arch/sparc/kernel/signal_64.c
浏览文件 @
08f73957
...
...
@@ -308,7 +308,7 @@ static int invalid_frame_pointer(void __user *fp)
return
0
;
}
static
inline
void
__user
*
get_sigframe
(
struct
k
_sigaction
*
ka
,
struct
pt_regs
*
regs
,
unsigned
long
framesize
)
static
inline
void
__user
*
get_sigframe
(
struct
k
signal
*
ksig
,
struct
pt_regs
*
regs
,
unsigned
long
framesize
)
{
unsigned
long
sp
=
regs
->
u_regs
[
UREG_FP
]
+
STACK_BIAS
;
...
...
@@ -320,12 +320,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *
return
(
void
__user
*
)
-
1L
;
/* This is the X/Open sanctioned signal stack switching. */
if
(
ka
->
sa
.
sa_flags
&
SA_ONSTACK
)
{
if
(
sas_ss_flags
(
sp
)
==
0
)
sp
=
current
->
sas_ss_sp
+
current
->
sas_ss_size
;
}
sp
-=
framesize
;
sp
=
sigsp
(
sp
,
ksig
)
-
framesize
;
/* Always align the stack frame. This handles two cases. First,
* sigaltstack need not be mindful of platform specific stack
...
...
@@ -339,8 +334,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *
}
static
inline
int
setup_rt_frame
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signo
,
sigset_t
*
oldset
,
siginfo_t
*
info
)
setup_rt_frame
(
struct
ksignal
*
ksig
,
struct
pt_regs
*
regs
)
{
struct
rt_signal_frame
__user
*
sf
;
int
wsaved
,
err
,
sf_size
;
...
...
@@ -358,10 +352,12 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
if
(
wsaved
)
sf_size
+=
sizeof
(
__siginfo_rwin_t
);
sf
=
(
struct
rt_signal_frame
__user
*
)
get_sigframe
(
k
a
,
regs
,
sf_size
);
get_sigframe
(
k
sig
,
regs
,
sf_size
);
if
(
invalid_frame_pointer
(
sf
))
goto
sigill
;
if
(
invalid_frame_pointer
(
sf
))
{
do_exit
(
SIGILL
);
/* won't return, actually */
return
-
EINVAL
;
}
tail
=
(
sf
+
1
);
...
...
@@ -389,7 +385,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
/* Setup sigaltstack */
err
|=
__save_altstack
(
&
sf
->
stack
,
regs
->
u_regs
[
UREG_FP
]);
err
|=
copy_to_user
(
&
sf
->
mask
,
oldset
,
sizeof
(
sigset_t
));
err
|=
copy_to_user
(
&
sf
->
mask
,
sigmask_to_save
()
,
sizeof
(
sigset_t
));
if
(
!
wsaved
)
{
err
|=
copy_in_user
((
u64
__user
*
)
sf
,
...
...
@@ -402,18 +398,18 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
rp
=
&
current_thread_info
()
->
reg_window
[
wsaved
-
1
];
err
|=
copy_to_user
(
sf
,
rp
,
sizeof
(
struct
reg_window
));
}
if
(
info
)
err
|=
copy_siginfo_to_user
(
&
sf
->
info
,
info
);
if
(
ksig
->
ka
.
sa
.
sa_flags
&
SA_SIGINFO
)
err
|=
copy_siginfo_to_user
(
&
sf
->
info
,
&
ksig
->
info
);
else
{
err
|=
__put_user
(
signo
,
&
sf
->
info
.
si_signo
);
err
|=
__put_user
(
ksig
->
sig
,
&
sf
->
info
.
si_signo
);
err
|=
__put_user
(
SI_NOINFO
,
&
sf
->
info
.
si_code
);
}
if
(
err
)
goto
sigsegv
;
return
err
;
/* 3. signal handler back-trampoline and parameters */
regs
->
u_regs
[
UREG_FP
]
=
((
unsigned
long
)
sf
)
-
STACK_BIAS
;
regs
->
u_regs
[
UREG_I0
]
=
signo
;
regs
->
u_regs
[
UREG_I0
]
=
ksig
->
sig
;
regs
->
u_regs
[
UREG_I1
]
=
(
unsigned
long
)
&
sf
->
info
;
/* The sigcontext is passed in this way because of how it
...
...
@@ -423,37 +419,15 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
regs
->
u_regs
[
UREG_I2
]
=
(
unsigned
long
)
&
sf
->
info
;
/* 5. signal handler */
regs
->
tpc
=
(
unsigned
long
)
k
a
->
sa
.
sa_handler
;
regs
->
tpc
=
(
unsigned
long
)
k
sig
->
ka
.
sa
.
sa_handler
;
regs
->
tnpc
=
(
regs
->
tpc
+
4
);
if
(
test_thread_flag
(
TIF_32BIT
))
{
regs
->
tpc
&=
0xffffffff
;
regs
->
tnpc
&=
0xffffffff
;
}
/* 4. return to kernel instructions */
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)
k
a
->
ka_restorer
;
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)
k
sig
->
ka
.
ka_restorer
;
return
0
;
sigill:
do_exit
(
SIGILL
);
return
-
EINVAL
;
sigsegv:
force_sigsegv
(
signo
,
current
);
return
-
EFAULT
;
}
static
inline
void
handle_signal
(
unsigned
long
signr
,
struct
k_sigaction
*
ka
,
siginfo_t
*
info
,
sigset_t
*
oldset
,
struct
pt_regs
*
regs
)
{
int
err
;
err
=
setup_rt_frame
(
ka
,
regs
,
signr
,
oldset
,
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
?
info
:
NULL
);
if
(
err
)
return
;
signal_delivered
(
signr
,
info
,
ka
,
regs
,
0
);
}
static
inline
void
syscall_restart
(
unsigned
long
orig_i0
,
struct
pt_regs
*
regs
,
...
...
@@ -483,11 +457,9 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
*/
static
void
do_signal
(
struct
pt_regs
*
regs
,
unsigned
long
orig_i0
)
{
struct
k
_sigaction
ka
;
struct
k
signal
ksig
;
int
restart_syscall
;
sigset_t
*
oldset
=
sigmask_to_save
();
siginfo_t
info
;
int
signr
;
bool
has_handler
;
/* It's a lot of work and synchronization to add a new ptrace
* register for GDB to save and restore in order to get
...
...
@@ -513,13 +485,13 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
#ifdef CONFIG_COMPAT
if
(
test_thread_flag
(
TIF_32BIT
))
{
extern
void
do_signal32
(
s
igset_t
*
,
s
truct
pt_regs
*
);
do_signal32
(
oldset
,
regs
);
extern
void
do_signal32
(
struct
pt_regs
*
);
do_signal32
(
regs
);
return
;
}
#endif
signr
=
get_signal_to_deliver
(
&
info
,
&
ka
,
regs
,
NULL
);
has_handler
=
get_signal
(
&
ksig
);
restart_syscall
=
0
;
if
(
pt_regs_is_syscall
(
regs
)
&&
...
...
@@ -528,34 +500,30 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
orig_i0
=
regs
->
u_regs
[
UREG_G6
];
}
if
(
signr
>
0
)
{
if
(
has_handler
)
{
if
(
restart_syscall
)
syscall_restart
(
orig_i0
,
regs
,
&
ka
.
sa
);
handle_signal
(
signr
,
&
ka
,
&
info
,
oldset
,
regs
);
return
;
}
if
(
restart_syscall
&&
(
regs
->
u_regs
[
UREG_I0
]
==
ERESTARTNOHAND
||
regs
->
u_regs
[
UREG_I0
]
==
ERESTARTSYS
||
regs
->
u_regs
[
UREG_I0
]
==
ERESTARTNOINTR
))
{
/* replay the system call when we are done */
regs
->
u_regs
[
UREG_I0
]
=
orig_i0
;
regs
->
tpc
-=
4
;
regs
->
tnpc
-=
4
;
pt_regs_clear_syscall
(
regs
);
}
if
(
restart_syscall
&&
regs
->
u_regs
[
UREG_I0
]
==
ERESTART_RESTARTBLOCK
)
{
regs
->
u_regs
[
UREG_G1
]
=
__NR_restart_syscall
;
regs
->
tpc
-=
4
;
regs
->
tnpc
-=
4
;
pt_regs_clear_syscall
(
regs
);
syscall_restart
(
orig_i0
,
regs
,
&
ksig
.
ka
.
sa
);
signal_setup_done
(
setup_rt_frame
(
&
ksig
,
regs
),
&
ksig
,
0
);
}
else
{
if
(
restart_syscall
)
{
switch
(
regs
->
u_regs
[
UREG_I0
])
{
case
ERESTARTNOHAND
:
case
ERESTARTSYS
:
case
ERESTARTNOINTR
:
/* replay the system call when we are done */
regs
->
u_regs
[
UREG_I0
]
=
orig_i0
;
regs
->
tpc
-=
4
;
regs
->
tnpc
-=
4
;
pt_regs_clear_syscall
(
regs
);
case
ERESTART_RESTARTBLOCK
:
regs
->
u_regs
[
UREG_G1
]
=
__NR_restart_syscall
;
regs
->
tpc
-=
4
;
regs
->
tnpc
-=
4
;
pt_regs_clear_syscall
(
regs
);
}
}
restore_saved_sigmask
();
}
/* If there's no signal to deliver, we just put the saved sigmask
* back
*/
restore_saved_sigmask
();
}
void
do_notify_resume
(
struct
pt_regs
*
regs
,
unsigned
long
orig_i0
,
unsigned
long
thread_info_flags
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录