Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
eceb1383
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
eceb1383
编写于
10月 12, 2008
作者:
I
Ingo Molnar
浏览文件
操作
浏览文件
下载
差异文件
Merge branches 'core/signal' and 'x86/spinlocks' into x86/xen
Conflicts: include/asm-x86/spinlock.h
上级
365d46dc
84e9c95a
4c7145a1
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
339 addition
and
274 deletion
+339
-274
arch/ia64/include/asm/siginfo.h
arch/ia64/include/asm/siginfo.h
+0
-5
arch/powerpc/include/asm/siginfo.h
arch/powerpc/include/asm/siginfo.h
+0
-5
arch/x86/ia32/ia32_signal.c
arch/x86/ia32/ia32_signal.c
+27
-41
arch/x86/kernel/process_64.c
arch/x86/kernel/process_64.c
+2
-2
arch/x86/kernel/ptrace.c
arch/x86/kernel/ptrace.c
+4
-3
arch/x86/kernel/signal_32.c
arch/x86/kernel/signal_32.c
+134
-88
arch/x86/kernel/signal_64.c
arch/x86/kernel/signal_64.c
+124
-83
arch/x86/kernel/traps_32.c
arch/x86/kernel/traps_32.c
+3
-1
arch/x86/kernel/traps_64.c
arch/x86/kernel/traps_64.c
+1
-1
arch/x86/kernel/vmlinux_64.lds.S
arch/x86/kernel/vmlinux_64.lds.S
+1
-1
arch/x86/mm/ioremap.c
arch/x86/mm/ioremap.c
+1
-1
include/asm-generic/siginfo.h
include/asm-generic/siginfo.h
+2
-0
include/asm-parisc/siginfo.h
include/asm-parisc/siginfo.h
+0
-5
include/asm-x86/ptrace.h
include/asm-x86/ptrace.h
+3
-3
include/asm-x86/spinlock.h
include/asm-x86/spinlock.h
+25
-35
include/asm-x86/traps.h
include/asm-x86/traps.h
+12
-0
未找到文件。
arch/ia64/include/asm/siginfo.h
浏览文件 @
eceb1383
...
...
@@ -113,11 +113,6 @@ typedef struct siginfo {
#undef NSIGSEGV
#define NSIGSEGV 3
/*
* SIGTRAP si_codes
*/
#define TRAP_BRANCH (__SI_FAULT|3)
/* process taken branch trap */
#define TRAP_HWBKPT (__SI_FAULT|4)
/* hardware breakpoint or watchpoint */
#undef NSIGTRAP
#define NSIGTRAP 4
...
...
arch/powerpc/include/asm/siginfo.h
浏览文件 @
eceb1383
...
...
@@ -15,11 +15,6 @@
#include <asm-generic/siginfo.h>
/*
* SIGTRAP si_codes
*/
#define TRAP_BRANCH (__SI_FAULT|3)
/* process taken branch trap */
#define TRAP_HWBKPT (__SI_FAULT|4)
/* hardware breakpoint or watchpoint */
#undef NSIGTRAP
#define NSIGTRAP 4
...
...
arch/x86/ia32/ia32_signal.c
浏览文件 @
eceb1383
...
...
@@ -351,31 +351,28 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
savesegment
(
es
,
tmp
);
err
|=
__put_user
(
tmp
,
(
unsigned
int
__user
*
)
&
sc
->
es
);
err
|=
__put_user
(
(
u32
)
regs
->
di
,
&
sc
->
di
);
err
|=
__put_user
(
(
u32
)
regs
->
si
,
&
sc
->
si
);
err
|=
__put_user
(
(
u32
)
regs
->
bp
,
&
sc
->
bp
);
err
|=
__put_user
(
(
u32
)
regs
->
sp
,
&
sc
->
sp
);
err
|=
__put_user
(
(
u32
)
regs
->
bx
,
&
sc
->
bx
);
err
|=
__put_user
(
(
u32
)
regs
->
dx
,
&
sc
->
dx
);
err
|=
__put_user
(
(
u32
)
regs
->
cx
,
&
sc
->
cx
);
err
|=
__put_user
(
(
u32
)
regs
->
ax
,
&
sc
->
ax
);
err
|=
__put_user
(
(
u32
)
regs
->
cs
,
&
sc
->
cs
);
err
|=
__put_user
(
(
u32
)
regs
->
ss
,
&
sc
->
ss
);
err
|=
__put_user
(
regs
->
di
,
&
sc
->
di
);
err
|=
__put_user
(
regs
->
si
,
&
sc
->
si
);
err
|=
__put_user
(
regs
->
bp
,
&
sc
->
bp
);
err
|=
__put_user
(
regs
->
sp
,
&
sc
->
sp
);
err
|=
__put_user
(
regs
->
bx
,
&
sc
->
bx
);
err
|=
__put_user
(
regs
->
dx
,
&
sc
->
dx
);
err
|=
__put_user
(
regs
->
cx
,
&
sc
->
cx
);
err
|=
__put_user
(
regs
->
ax
,
&
sc
->
ax
);
err
|=
__put_user
(
regs
->
cs
,
&
sc
->
cs
);
err
|=
__put_user
(
regs
->
ss
,
&
sc
->
ss
);
err
|=
__put_user
(
current
->
thread
.
trap_no
,
&
sc
->
trapno
);
err
|=
__put_user
(
current
->
thread
.
error_code
,
&
sc
->
err
);
err
|=
__put_user
(
(
u32
)
regs
->
ip
,
&
sc
->
ip
);
err
|=
__put_user
(
(
u32
)
regs
->
flags
,
&
sc
->
flags
);
err
|=
__put_user
(
(
u32
)
regs
->
sp
,
&
sc
->
sp_at_signal
);
err
|=
__put_user
(
regs
->
ip
,
&
sc
->
ip
);
err
|=
__put_user
(
regs
->
flags
,
&
sc
->
flags
);
err
|=
__put_user
(
regs
->
sp
,
&
sc
->
sp_at_signal
);
tmp
=
save_i387_xstate_ia32
(
fpstate
);
if
(
tmp
<
0
)
err
=
-
EFAULT
;
else
{
clear_used_math
();
stts
();
else
err
|=
__put_user
(
ptr_to_compat
(
tmp
?
fpstate
:
NULL
),
&
sc
->
fpstate
);
}
/* non-iBCS2 extensions.. */
err
|=
__put_user
(
mask
,
&
sc
->
oldmask
);
...
...
@@ -444,21 +441,18 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
frame
=
get_sigframe
(
ka
,
regs
,
sizeof
(
*
frame
),
&
fpstate
);
if
(
!
access_ok
(
VERIFY_WRITE
,
frame
,
sizeof
(
*
frame
)))
goto
give_sigsegv
;
return
-
EFAULT
;
err
|=
__put_user
(
sig
,
&
frame
->
sig
);
if
(
err
)
goto
give_sigsegv
;
if
(
__put_user
(
sig
,
&
frame
->
sig
))
return
-
EFAULT
;
err
|=
ia32_setup_sigcontext
(
&
frame
->
sc
,
fpstate
,
regs
,
set
->
sig
[
0
]);
if
(
err
)
goto
give_sigsegv
;
if
(
ia32_setup_sigcontext
(
&
frame
->
sc
,
fpstate
,
regs
,
set
->
sig
[
0
]))
return
-
EFAULT
;
if
(
_COMPAT_NSIG_WORDS
>
1
)
{
err
|=
__copy_to_user
(
frame
->
extramask
,
&
set
->
sig
[
1
],
sizeof
(
frame
->
extramask
));
if
(
err
)
goto
give_sigsegv
;
if
(
__copy_to_user
(
frame
->
extramask
,
&
set
->
sig
[
1
],
sizeof
(
frame
->
extramask
)))
return
-
EFAULT
;
}
if
(
ka
->
sa
.
sa_flags
&
SA_RESTORER
)
{
...
...
@@ -479,7 +473,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
*/
err
|=
__copy_to_user
(
frame
->
retcode
,
&
code
,
8
);
if
(
err
)
goto
give_sigsegv
;
return
-
EFAULT
;
/* Set up registers for signal handler */
regs
->
sp
=
(
unsigned
long
)
frame
;
...
...
@@ -502,10 +496,6 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
#endif
return
0
;
give_sigsegv:
force_sigsegv
(
sig
,
current
);
return
-
EFAULT
;
}
int
ia32_setup_rt_frame
(
int
sig
,
struct
k_sigaction
*
ka
,
siginfo_t
*
info
,
...
...
@@ -533,14 +523,14 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
frame
=
get_sigframe
(
ka
,
regs
,
sizeof
(
*
frame
),
&
fpstate
);
if
(
!
access_ok
(
VERIFY_WRITE
,
frame
,
sizeof
(
*
frame
)))
goto
give_sigsegv
;
return
-
EFAULT
;
err
|=
__put_user
(
sig
,
&
frame
->
sig
);
err
|=
__put_user
(
ptr_to_compat
(
&
frame
->
info
),
&
frame
->
pinfo
);
err
|=
__put_user
(
ptr_to_compat
(
&
frame
->
uc
),
&
frame
->
puc
);
err
|=
copy_siginfo_to_user32
(
&
frame
->
info
,
info
);
if
(
err
)
goto
give_sigsegv
;
return
-
EFAULT
;
/* Create the ucontext. */
if
(
cpu_has_xsave
)
...
...
@@ -556,7 +546,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs
,
set
->
sig
[
0
]);
err
|=
__copy_to_user
(
&
frame
->
uc
.
uc_sigmask
,
set
,
sizeof
(
*
set
));
if
(
err
)
goto
give_sigsegv
;
return
-
EFAULT
;
if
(
ka
->
sa
.
sa_flags
&
SA_RESTORER
)
restorer
=
ka
->
sa
.
sa_restorer
;
...
...
@@ -571,7 +561,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
*/
err
|=
__copy_to_user
(
frame
->
retcode
,
&
code
,
8
);
if
(
err
)
goto
give_sigsegv
;
return
-
EFAULT
;
/* Set up registers for signal handler */
regs
->
sp
=
(
unsigned
long
)
frame
;
...
...
@@ -599,8 +589,4 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
#endif
return
0
;
give_sigsegv:
force_sigsegv
(
sig
,
current
);
return
-
EFAULT
;
}
arch/x86/kernel/process_64.c
浏览文件 @
eceb1383
...
...
@@ -736,12 +736,12 @@ unsigned long get_wchan(struct task_struct *p)
if
(
!
p
||
p
==
current
||
p
->
state
==
TASK_RUNNING
)
return
0
;
stack
=
(
unsigned
long
)
task_stack_page
(
p
);
if
(
p
->
thread
.
sp
<
stack
||
p
->
thread
.
sp
>
stack
+
THREAD_SIZE
)
if
(
p
->
thread
.
sp
<
stack
||
p
->
thread
.
sp
>
=
stack
+
THREAD_SIZE
)
return
0
;
fp
=
*
(
u64
*
)(
p
->
thread
.
sp
);
do
{
if
(
fp
<
(
unsigned
long
)
stack
||
fp
>
(
unsigned
long
)
stack
+
THREAD_SIZE
)
fp
>
=
(
unsigned
long
)
stack
+
THREAD_SIZE
)
return
0
;
ip
=
*
(
u64
*
)(
fp
+
8
);
if
(
!
in_sched_functions
(
ip
))
...
...
arch/x86/kernel/ptrace.c
浏览文件 @
eceb1383
...
...
@@ -1452,7 +1452,8 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
#endif
}
void
send_sigtrap
(
struct
task_struct
*
tsk
,
struct
pt_regs
*
regs
,
int
error_code
)
void
send_sigtrap
(
struct
task_struct
*
tsk
,
struct
pt_regs
*
regs
,
int
error_code
,
int
si_code
)
{
struct
siginfo
info
;
...
...
@@ -1461,7 +1462,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
memset
(
&
info
,
0
,
sizeof
(
info
));
info
.
si_signo
=
SIGTRAP
;
info
.
si_code
=
TRAP_BRKPT
;
info
.
si_code
=
si_code
;
/* User-mode ip? */
info
.
si_addr
=
user_mode_vm
(
regs
)
?
(
void
__user
*
)
regs
->
ip
:
NULL
;
...
...
@@ -1548,5 +1549,5 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
*/
if
(
test_thread_flag
(
TIF_SINGLESTEP
)
&&
tracehook_consider_fatal_signal
(
current
,
SIGTRAP
,
SIG_DFL
))
send_sigtrap
(
current
,
regs
,
0
);
send_sigtrap
(
current
,
regs
,
0
,
TRAP_BRKPT
);
}
arch/x86/kernel/signal_32.c
浏览文件 @
eceb1383
...
...
@@ -27,6 +27,7 @@
#include <asm/uaccess.h>
#include <asm/i387.h>
#include <asm/vdso.h>
#include <asm/syscall.h>
#include <asm/syscalls.h>
#include "sigframe.h"
...
...
@@ -112,6 +113,27 @@ asmlinkage int sys_sigaltstack(unsigned long bx)
return
do_sigaltstack
(
uss
,
uoss
,
regs
->
sp
);
}
#define COPY(x) { \
err |= __get_user(regs->x, &sc->x); \
}
#define COPY_SEG(seg) { \
unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
regs->seg = tmp; \
}
#define COPY_SEG_STRICT(seg) { \
unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
regs->seg = tmp | 3; \
}
#define GET_SEG(seg) { \
unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
loadsegment(seg, tmp); \
}
/*
* Do a signal return; undo the signal stack.
...
...
@@ -120,28 +142,13 @@ static int
restore_sigcontext
(
struct
pt_regs
*
regs
,
struct
sigcontext
__user
*
sc
,
unsigned
long
*
pax
)
{
void
__user
*
buf
;
unsigned
int
tmpflags
;
unsigned
int
err
=
0
;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info
()
->
restart_block
.
fn
=
do_no_restart_syscall
;
#define COPY(x) err |= __get_user(regs->x, &sc->x)
#define COPY_SEG(seg) \
{ unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
regs->seg = tmp; }
#define COPY_SEG_STRICT(seg) \
{ unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
regs->seg = tmp|3; }
#define GET_SEG(seg) \
{ unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
loadsegment(seg, tmp); }
GET_SEG
(
gs
);
COPY_SEG
(
fs
);
COPY_SEG
(
es
);
...
...
@@ -151,21 +158,12 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
COPY_SEG_STRICT
(
cs
);
COPY_SEG_STRICT
(
ss
);
{
unsigned
int
tmpflags
;
err
|=
__get_user
(
tmpflags
,
&
sc
->
flags
);
regs
->
flags
=
(
regs
->
flags
&
~
FIX_EFLAGS
)
|
(
tmpflags
&
FIX_EFLAGS
);
regs
->
orig_ax
=
-
1
;
/* disable syscall checks */
}
{
void
__user
*
buf
;
err
|=
__get_user
(
tmpflags
,
&
sc
->
flags
);
regs
->
flags
=
(
regs
->
flags
&
~
FIX_EFLAGS
)
|
(
tmpflags
&
FIX_EFLAGS
);
regs
->
orig_ax
=
-
1
;
/* disable syscall checks */
err
|=
__get_user
(
buf
,
&
sc
->
fpstate
);
err
|=
restore_i387_xstate
(
buf
);
}
err
|=
__get_user
(
buf
,
&
sc
->
fpstate
);
err
|=
restore_i387_xstate
(
buf
);
err
|=
__get_user
(
*
pax
,
&
sc
->
ax
);
return
err
;
...
...
@@ -214,9 +212,8 @@ asmlinkage unsigned long sys_sigreturn(unsigned long __unused)
return
0
;
}
asmlinkage
int
sys_rt_sigreturn
(
unsigned
long
__unused
)
static
long
do_rt_sigreturn
(
struct
pt_regs
*
regs
)
{
struct
pt_regs
*
regs
=
(
struct
pt_regs
*
)
&
__unused
;
struct
rt_sigframe
__user
*
frame
;
unsigned
long
ax
;
sigset_t
set
;
...
...
@@ -242,10 +239,17 @@ asmlinkage int sys_rt_sigreturn(unsigned long __unused)
return
ax
;
badframe:
force_sig
(
SIGSEGV
,
current
);
signal_fault
(
regs
,
frame
,
"rt_sigreturn"
);
return
0
;
}
asmlinkage
int
sys_rt_sigreturn
(
unsigned
long
__unused
)
{
struct
pt_regs
*
regs
=
(
struct
pt_regs
*
)
&
__unused
;
return
do_rt_sigreturn
(
regs
);
}
/*
* Set up a signal frame.
*/
...
...
@@ -337,39 +341,29 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
}
static
int
setup_frame
(
int
sig
,
struct
k_sigaction
*
ka
,
sigset_t
*
set
,
struct
pt_regs
*
regs
)
__
setup_frame
(
int
sig
,
struct
k_sigaction
*
ka
,
sigset_t
*
set
,
struct
pt_regs
*
regs
)
{
struct
sigframe
__user
*
frame
;
void
__user
*
restorer
;
int
err
=
0
;
int
usig
;
void
__user
*
fpstate
=
NULL
;
frame
=
get_sigframe
(
ka
,
regs
,
sizeof
(
*
frame
),
&
fpstate
);
if
(
!
access_ok
(
VERIFY_WRITE
,
frame
,
sizeof
(
*
frame
)))
goto
give_sigsegv
;
return
-
EFAULT
;
usig
=
current_thread_info
()
->
exec_domain
&&
current_thread_info
()
->
exec_domain
->
signal_invmap
&&
sig
<
32
?
current_thread_info
()
->
exec_domain
->
signal_invmap
[
sig
]
:
sig
;
if
(
__put_user
(
sig
,
&
frame
->
sig
))
return
-
EFAULT
;
err
=
__put_user
(
usig
,
&
frame
->
sig
);
if
(
err
)
goto
give_sigsegv
;
err
=
setup_sigcontext
(
&
frame
->
sc
,
fpstate
,
regs
,
set
->
sig
[
0
]);
if
(
err
)
goto
give_sigsegv
;
if
(
setup_sigcontext
(
&
frame
->
sc
,
fpstate
,
regs
,
set
->
sig
[
0
]))
return
-
EFAULT
;
if
(
_NSIG_WORDS
>
1
)
{
err
=
__copy_to_user
(
&
frame
->
extramask
,
&
set
->
sig
[
1
],
sizeof
(
frame
->
extramask
));
if
(
err
)
goto
give_sigsegv
;
if
(
__copy_to_user
(
&
frame
->
extramask
,
&
set
->
sig
[
1
],
sizeof
(
frame
->
extramask
)))
return
-
EFAULT
;
}
if
(
current
->
mm
->
context
.
vdso
)
...
...
@@ -394,7 +388,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
err
|=
__put_user
(
0x80cd
,
(
short
__user
*
)(
frame
->
retcode
+
6
));
if
(
err
)
goto
give_sigsegv
;
return
-
EFAULT
;
/* Set up registers for signal handler */
regs
->
sp
=
(
unsigned
long
)
frame
;
...
...
@@ -409,38 +403,27 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
regs
->
cs
=
__USER_CS
;
return
0
;
give_sigsegv:
force_sigsegv
(
sig
,
current
);
return
-
EFAULT
;
}
static
int
setup_rt_frame
(
int
sig
,
struct
k_sigaction
*
ka
,
siginfo_t
*
info
,
sigset_t
*
set
,
struct
pt_regs
*
regs
)
static
int
__
setup_rt_frame
(
int
sig
,
struct
k_sigaction
*
ka
,
siginfo_t
*
info
,
sigset_t
*
set
,
struct
pt_regs
*
regs
)
{
struct
rt_sigframe
__user
*
frame
;
void
__user
*
restorer
;
int
err
=
0
;
int
usig
;
void
__user
*
fpstate
=
NULL
;
frame
=
get_sigframe
(
ka
,
regs
,
sizeof
(
*
frame
),
&
fpstate
);
if
(
!
access_ok
(
VERIFY_WRITE
,
frame
,
sizeof
(
*
frame
)))
goto
give_sigsegv
;
usig
=
current_thread_info
()
->
exec_domain
&&
current_thread_info
()
->
exec_domain
->
signal_invmap
&&
sig
<
32
?
current_thread_info
()
->
exec_domain
->
signal_invmap
[
sig
]
:
sig
;
return
-
EFAULT
;
err
|=
__put_user
(
u
sig
,
&
frame
->
sig
);
err
|=
__put_user
(
sig
,
&
frame
->
sig
);
err
|=
__put_user
(
&
frame
->
info
,
&
frame
->
pinfo
);
err
|=
__put_user
(
&
frame
->
uc
,
&
frame
->
puc
);
err
|=
copy_siginfo_to_user
(
&
frame
->
info
,
info
);
if
(
err
)
goto
give_sigsegv
;
return
-
EFAULT
;
/* Create the ucontext. */
if
(
cpu_has_xsave
)
...
...
@@ -456,7 +439,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs
,
set
->
sig
[
0
]);
err
|=
__copy_to_user
(
&
frame
->
uc
.
uc_sigmask
,
set
,
sizeof
(
*
set
));
if
(
err
)
goto
give_sigsegv
;
return
-
EFAULT
;
/* Set up to return from userspace. */
restorer
=
VDSO32_SYMBOL
(
current
->
mm
->
context
.
vdso
,
rt_sigreturn
);
...
...
@@ -476,12 +459,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err
|=
__put_user
(
0x80cd
,
(
short
__user
*
)(
frame
->
retcode
+
5
));
if
(
err
)
goto
give_sigsegv
;
return
-
EFAULT
;
/* Set up registers for signal handler */
regs
->
sp
=
(
unsigned
long
)
frame
;
regs
->
ip
=
(
unsigned
long
)
ka
->
sa
.
sa_handler
;
regs
->
ax
=
(
unsigned
long
)
u
sig
;
regs
->
ax
=
(
unsigned
long
)
sig
;
regs
->
dx
=
(
unsigned
long
)
&
frame
->
info
;
regs
->
cx
=
(
unsigned
long
)
&
frame
->
uc
;
...
...
@@ -491,15 +474,48 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs
->
cs
=
__USER_CS
;
return
0
;
give_sigsegv:
force_sigsegv
(
sig
,
current
);
return
-
EFAULT
;
}
/*
* OK, we're invoking a handler:
*/
static
int
signr_convert
(
int
sig
)
{
struct
thread_info
*
info
=
current_thread_info
();
if
(
info
->
exec_domain
&&
info
->
exec_domain
->
signal_invmap
&&
sig
<
32
)
return
info
->
exec_domain
->
signal_invmap
[
sig
];
return
sig
;
}
#define is_ia32 1
#define ia32_setup_frame __setup_frame
#define ia32_setup_rt_frame __setup_rt_frame
static
int
setup_rt_frame
(
int
sig
,
struct
k_sigaction
*
ka
,
siginfo_t
*
info
,
sigset_t
*
set
,
struct
pt_regs
*
regs
)
{
int
usig
=
signr_convert
(
sig
);
int
ret
;
/* Set up the stack frame */
if
(
is_ia32
)
{
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
ret
=
ia32_setup_rt_frame
(
usig
,
ka
,
info
,
set
,
regs
);
else
ret
=
ia32_setup_frame
(
usig
,
ka
,
set
,
regs
);
}
else
ret
=
__setup_rt_frame
(
sig
,
ka
,
info
,
set
,
regs
);
if
(
ret
)
{
force_sigsegv
(
sig
,
current
);
return
-
EFAULT
;
}
return
ret
;
}
static
int
handle_signal
(
unsigned
long
sig
,
siginfo_t
*
info
,
struct
k_sigaction
*
ka
,
sigset_t
*
oldset
,
struct
pt_regs
*
regs
)
...
...
@@ -507,9 +523,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
int
ret
;
/* Are we from a system call? */
if
(
(
long
)
regs
->
orig_ax
>=
0
)
{
if
(
syscall_get_nr
(
current
,
regs
)
>=
0
)
{
/* If so, check system call restarting.. */
switch
(
regs
->
ax
)
{
switch
(
syscall_get_error
(
current
,
regs
)
)
{
case
-
ERESTART_RESTARTBLOCK
:
case
-
ERESTARTNOHAND
:
regs
->
ax
=
-
EINTR
;
...
...
@@ -536,15 +552,20 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
likely
(
test_and_clear_thread_flag
(
TIF_FORCED_TF
)))
regs
->
flags
&=
~
X86_EFLAGS_TF
;
/* Set up the stack frame */
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
ret
=
setup_rt_frame
(
sig
,
ka
,
info
,
oldset
,
regs
);
else
ret
=
setup_frame
(
sig
,
ka
,
oldset
,
regs
);
ret
=
setup_rt_frame
(
sig
,
ka
,
info
,
oldset
,
regs
);
if
(
ret
)
return
ret
;
#ifdef CONFIG_X86_64
/*
* This has nothing to do with segment registers,
* despite the name. This magic affects uaccess.h
* macros' behavior. Reset it to the normal setting.
*/
set_fs
(
USER_DS
);
#endif
/*
* Clear the direction flag as per the ABI for function entry.
*/
...
...
@@ -571,6 +592,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
return
0
;
}
#define NR_restart_syscall __NR_restart_syscall
/*
* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by
...
...
@@ -623,9 +645,9 @@ static void do_signal(struct pt_regs *regs)
}
/* Did we come from a system call? */
if
(
(
long
)
regs
->
orig_ax
>=
0
)
{
if
(
syscall_get_nr
(
current
,
regs
)
>=
0
)
{
/* Restart the system call - no handlers present */
switch
(
regs
->
ax
)
{
switch
(
syscall_get_error
(
current
,
regs
)
)
{
case
-
ERESTARTNOHAND
:
case
-
ERESTARTSYS
:
case
-
ERESTARTNOINTR
:
...
...
@@ -634,7 +656,7 @@ static void do_signal(struct pt_regs *regs)
break
;
case
-
ERESTART_RESTARTBLOCK
:
regs
->
ax
=
__
NR_restart_syscall
;
regs
->
ax
=
NR_restart_syscall
;
regs
->
ip
-=
2
;
break
;
}
...
...
@@ -657,6 +679,12 @@ static void do_signal(struct pt_regs *regs)
void
do_notify_resume
(
struct
pt_regs
*
regs
,
void
*
unused
,
__u32
thread_info_flags
)
{
#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE)
/* notify userspace of pending MCEs */
if
(
thread_info_flags
&
_TIF_MCE_NOTIFY
)
mce_notify_user
();
#endif
/* CONFIG_X86_64 && CONFIG_X86_MCE */
/* deal with pending signal delivery */
if
(
thread_info_flags
&
_TIF_SIGPENDING
)
do_signal
(
regs
);
...
...
@@ -666,5 +694,23 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
tracehook_notify_resume
(
regs
);
}
#ifdef CONFIG_X86_32
clear_thread_flag
(
TIF_IRET
);
#endif
/* CONFIG_X86_32 */
}
void
signal_fault
(
struct
pt_regs
*
regs
,
void
__user
*
frame
,
char
*
where
)
{
struct
task_struct
*
me
=
current
;
if
(
show_unhandled_signals
&&
printk_ratelimit
())
{
printk
(
KERN_INFO
"%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx"
,
me
->
comm
,
me
->
pid
,
where
,
frame
,
regs
->
ip
,
regs
->
sp
,
regs
->
orig_ax
);
print_vma_addr
(
" in "
,
regs
->
ip
);
printk
(
KERN_CONT
"
\n
"
);
}
force_sig
(
SIGSEGV
,
me
);
}
arch/x86/kernel/signal_64.c
浏览文件 @
eceb1383
...
...
@@ -52,6 +52,16 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
return
do_sigaltstack
(
uss
,
uoss
,
regs
->
sp
);
}
#define COPY(x) { \
err |= __get_user(regs->x, &sc->x); \
}
#define COPY_SEG_STRICT(seg) { \
unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
regs->seg = tmp | 3; \
}
/*
* Do a signal return; undo the signal stack.
*/
...
...
@@ -59,13 +69,13 @@ static int
restore_sigcontext
(
struct
pt_regs
*
regs
,
struct
sigcontext
__user
*
sc
,
unsigned
long
*
pax
)
{
void
__user
*
buf
;
unsigned
int
tmpflags
;
unsigned
int
err
=
0
;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info
()
->
restart_block
.
fn
=
do_no_restart_syscall
;
#define COPY(x) (err |= __get_user(regs->x, &sc->x))
COPY
(
di
);
COPY
(
si
);
COPY
(
bp
);
COPY
(
sp
);
COPY
(
bx
);
COPY
(
dx
);
COPY
(
cx
);
COPY
(
ip
);
COPY
(
r8
);
...
...
@@ -80,34 +90,24 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
/* Kernel saves and restores only the CS segment register on signals,
* which is the bare minimum needed to allow mixed 32/64-bit code.
* App's signal handler can save/restore other segments if needed. */
{
unsigned
cs
;
err
|=
__get_user
(
cs
,
&
sc
->
cs
);
regs
->
cs
=
cs
|
3
;
/* Force into user mode */
}
COPY_SEG_STRICT
(
cs
);
{
unsigned
int
tmpflags
;
err
|=
__get_user
(
tmpflags
,
&
sc
->
flags
);
regs
->
flags
=
(
regs
->
flags
&
~
FIX_EFLAGS
)
|
(
tmpflags
&
FIX_EFLAGS
);
regs
->
orig_ax
=
-
1
;
/* disable syscall checks */
}
err
|=
__get_user
(
tmpflags
,
&
sc
->
flags
);
regs
->
flags
=
(
regs
->
flags
&
~
FIX_EFLAGS
)
|
(
tmpflags
&
FIX_EFLAGS
);
regs
->
orig_ax
=
-
1
;
/* disable syscall checks */
{
struct
_fpstate
__user
*
buf
;
err
|=
__get_user
(
buf
,
&
sc
->
fpstate
);
err
|=
restore_i387_xstate
(
buf
);
}
err
|=
__get_user
(
buf
,
&
sc
->
fpstate
);
err
|=
restore_i387_xstate
(
buf
);
err
|=
__get_user
(
*
pax
,
&
sc
->
ax
);
return
err
;
}
asmlinkage
long
sys
_rt_sigreturn
(
struct
pt_regs
*
regs
)
static
long
do
_rt_sigreturn
(
struct
pt_regs
*
regs
)
{
struct
rt_sigframe
__user
*
frame
;
sigset_t
set
;
unsigned
long
ax
;
sigset_t
set
;
frame
=
(
struct
rt_sigframe
__user
*
)(
regs
->
sp
-
sizeof
(
long
));
if
(
!
access_ok
(
VERIFY_READ
,
frame
,
sizeof
(
*
frame
)))
...
...
@@ -130,10 +130,15 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
return
ax
;
badframe:
signal_fault
(
regs
,
frame
,
"sigreturn"
);
signal_fault
(
regs
,
frame
,
"
rt_
sigreturn"
);
return
0
;
}
asmlinkage
long
sys_rt_sigreturn
(
struct
pt_regs
*
regs
)
{
return
do_rt_sigreturn
(
regs
);
}
/*
* Set up a signal frame.
*/
...
...
@@ -195,8 +200,8 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
return
(
void
__user
*
)
round_down
(
sp
-
size
,
64
);
}
static
int
setup_rt_frame
(
int
sig
,
struct
k_sigaction
*
ka
,
siginfo_t
*
info
,
sigset_t
*
set
,
struct
pt_regs
*
regs
)
static
int
__
setup_rt_frame
(
int
sig
,
struct
k_sigaction
*
ka
,
siginfo_t
*
info
,
sigset_t
*
set
,
struct
pt_regs
*
regs
)
{
struct
rt_sigframe
__user
*
frame
;
void
__user
*
fp
=
NULL
;
...
...
@@ -209,17 +214,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
(
unsigned
long
)
fp
-
sizeof
(
struct
rt_sigframe
),
16
)
-
8
;
if
(
save_i387_xstate
(
fp
)
<
0
)
err
|=
-
1
;
return
-
EFAULT
;
}
else
frame
=
get_stack
(
ka
,
regs
,
sizeof
(
struct
rt_sigframe
))
-
8
;
if
(
!
access_ok
(
VERIFY_WRITE
,
frame
,
sizeof
(
*
frame
)))
goto
give_sigsegv
;
return
-
EFAULT
;
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
{
err
|=
copy_siginfo_to_user
(
&
frame
->
info
,
info
);
if
(
err
)
goto
give_sigsegv
;
if
(
copy_siginfo_to_user
(
&
frame
->
info
,
info
))
return
-
EFAULT
;
}
/* Create the ucontext. */
...
...
@@ -247,11 +251,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err
|=
__put_user
(
ka
->
sa
.
sa_restorer
,
&
frame
->
pretcode
);
}
else
{
/* could use a vstub here */
goto
give_sigsegv
;
return
-
EFAULT
;
}
if
(
err
)
goto
give_sigsegv
;
return
-
EFAULT
;
/* Set up registers for signal handler */
regs
->
di
=
sig
;
...
...
@@ -271,15 +275,45 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs
->
cs
=
__USER_CS
;
return
0
;
give_sigsegv:
force_sigsegv
(
sig
,
current
);
return
-
EFAULT
;
}
/*
* OK, we're invoking a handler
*/
static
int
signr_convert
(
int
sig
)
{
return
sig
;
}
#ifdef CONFIG_IA32_EMULATION
#define is_ia32 test_thread_flag(TIF_IA32)
#else
#define is_ia32 0
#endif
static
int
setup_rt_frame
(
int
sig
,
struct
k_sigaction
*
ka
,
siginfo_t
*
info
,
sigset_t
*
set
,
struct
pt_regs
*
regs
)
{
int
usig
=
signr_convert
(
sig
);
int
ret
;
/* Set up the stack frame */
if
(
is_ia32
)
{
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
ret
=
ia32_setup_rt_frame
(
usig
,
ka
,
info
,
set
,
regs
);
else
ret
=
ia32_setup_frame
(
usig
,
ka
,
set
,
regs
);
}
else
ret
=
__setup_rt_frame
(
sig
,
ka
,
info
,
set
,
regs
);
if
(
ret
)
{
force_sigsegv
(
sig
,
current
);
return
-
EFAULT
;
}
return
ret
;
}
static
int
handle_signal
(
unsigned
long
sig
,
siginfo_t
*
info
,
struct
k_sigaction
*
ka
,
...
...
@@ -317,51 +351,48 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
likely
(
test_and_clear_thread_flag
(
TIF_FORCED_TF
)))
regs
->
flags
&=
~
X86_EFLAGS_TF
;
#ifdef CONFIG_IA32_EMULATION
if
(
test_thread_flag
(
TIF_IA32
))
{
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
ret
=
ia32_setup_rt_frame
(
sig
,
ka
,
info
,
oldset
,
regs
);
else
ret
=
ia32_setup_frame
(
sig
,
ka
,
oldset
,
regs
);
}
else
#endif
ret
=
setup_rt_frame
(
sig
,
ka
,
info
,
oldset
,
regs
);
if
(
ret
==
0
)
{
/*
* This has nothing to do with segment registers,
* despite the name. This magic affects uaccess.h
* macros' behavior. Reset it to the normal setting.
*/
set_fs
(
USER_DS
);
if
(
ret
)
return
ret
;
/*
* Clear the direction flag as per the ABI for function entry.
*/
regs
->
flags
&=
~
X86_EFLAGS_DF
;
#ifdef CONFIG_X86_64
/*
* This has nothing to do with segment registers,
* despite the name. This magic affects uaccess.h
* macros' behavior. Reset it to the normal setting.
*/
set_fs
(
USER_DS
);
#endif
/*
* Clear TF when entering the signal handler, but
* notify any tracer that was single-stepping it.
* The tracer may want to single-step inside the
* handler too.
*/
regs
->
flags
&=
~
X86_EFLAGS_TF
;
/*
* Clear the direction flag as per the ABI for function entry.
*/
regs
->
flags
&=
~
X86_EFLAGS_DF
;
spin_lock_irq
(
&
current
->
sighand
->
siglock
);
sigorsets
(
&
current
->
blocked
,
&
current
->
blocked
,
&
ka
->
sa
.
sa_mask
);
if
(
!
(
ka
->
sa
.
sa_flags
&
SA_NODEFER
))
sigaddset
(
&
current
->
blocked
,
sig
);
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sighand
->
siglock
);
/*
* Clear TF when entering the signal handler, but
* notify any tracer that was single-stepping it.
* The tracer may want to single-step inside the
* handler too.
*/
regs
->
flags
&=
~
X86_EFLAGS_TF
;
tracehook_signal_handler
(
sig
,
info
,
ka
,
regs
,
test_thread_flag
(
TIF_SINGLESTEP
));
}
spin_lock_irq
(
&
current
->
sighand
->
siglock
);
sigorsets
(
&
current
->
blocked
,
&
current
->
blocked
,
&
ka
->
sa
.
sa_mask
);
if
(
!
(
ka
->
sa
.
sa_flags
&
SA_NODEFER
))
sigaddset
(
&
current
->
blocked
,
sig
);
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sighand
->
siglock
);
return
ret
;
tracehook_signal_handler
(
sig
,
info
,
ka
,
regs
,
test_thread_flag
(
TIF_SINGLESTEP
));
return
0
;
}
#define NR_restart_syscall \
test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall
/*
* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by
...
...
@@ -391,7 +422,8 @@ static void do_signal(struct pt_regs *regs)
signr
=
get_signal_to_deliver
(
&
info
,
&
ka
,
regs
,
NULL
);
if
(
signr
>
0
)
{
/* Re-enable any watchpoints before delivering the
/*
* Re-enable any watchpoints before delivering the
* signal to user space. The processor register will
* have been cleared if the watchpoint triggered
* inside the kernel.
...
...
@@ -399,7 +431,7 @@ static void do_signal(struct pt_regs *regs)
if
(
current
->
thread
.
debugreg7
)
set_debugreg
(
current
->
thread
.
debugreg7
,
7
);
/* Whee!
Actually deliver the signal. */
/* Whee! Actually deliver the signal. */
if
(
handle_signal
(
signr
,
&
info
,
&
ka
,
oldset
,
regs
)
==
0
)
{
/*
* A signal was successfully delivered; the saved
...
...
@@ -422,10 +454,9 @@ static void do_signal(struct pt_regs *regs)
regs
->
ax
=
regs
->
orig_ax
;
regs
->
ip
-=
2
;
break
;
case
-
ERESTART_RESTARTBLOCK
:
regs
->
ax
=
test_thread_flag
(
TIF_IA32
)
?
__NR_ia32_restart_syscall
:
__NR_restart_syscall
;
regs
->
ax
=
NR_restart_syscall
;
regs
->
ip
-=
2
;
break
;
}
...
...
@@ -441,14 +472,18 @@ static void do_signal(struct pt_regs *regs)
}
}
void
do_notify_resume
(
struct
pt_regs
*
regs
,
void
*
unused
,
__u32
thread_info_flags
)
/*
* notification of userspace execution resumption
* - triggered by the TIF_WORK_MASK flags
*/
void
do_notify_resume
(
struct
pt_regs
*
regs
,
void
*
unused
,
__u32
thread_info_flags
)
{
#if
def CONFIG_X86_MCE
#if
defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE)
/* notify userspace of pending MCEs */
if
(
thread_info_flags
&
_TIF_MCE_NOTIFY
)
mce_notify_user
();
#endif
/* CONFIG_X86_MCE */
#endif
/* CONFIG_X86_
64 && CONFIG_X86_
MCE */
/* deal with pending signal delivery */
if
(
thread_info_flags
&
_TIF_SIGPENDING
)
...
...
@@ -458,17 +493,23 @@ void do_notify_resume(struct pt_regs *regs, void *unused,
clear_thread_flag
(
TIF_NOTIFY_RESUME
);
tracehook_notify_resume
(
regs
);
}
#ifdef CONFIG_X86_32
clear_thread_flag
(
TIF_IRET
);
#endif
/* CONFIG_X86_32 */
}
void
signal_fault
(
struct
pt_regs
*
regs
,
void
__user
*
frame
,
char
*
where
)
{
struct
task_struct
*
me
=
current
;
if
(
show_unhandled_signals
&&
printk_ratelimit
())
{
printk
(
"%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx"
,
me
->
comm
,
me
->
pid
,
where
,
frame
,
regs
->
ip
,
regs
->
sp
,
regs
->
orig_ax
);
printk
(
KERN_INFO
"%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx"
,
me
->
comm
,
me
->
pid
,
where
,
frame
,
regs
->
ip
,
regs
->
sp
,
regs
->
orig_ax
);
print_vma_addr
(
" in "
,
regs
->
ip
);
printk
(
"
\n
"
);
printk
(
KERN_CONT
"
\n
"
);
}
force_sig
(
SIGSEGV
,
me
);
...
...
arch/x86/kernel/traps_32.c
浏览文件 @
eceb1383
...
...
@@ -891,6 +891,7 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code)
{
struct
task_struct
*
tsk
=
current
;
unsigned
int
condition
;
int
si_code
;
trace_hardirqs_fixup
();
...
...
@@ -935,8 +936,9 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code)
goto
clear_TF_reenable
;
}
si_code
=
get_si_code
((
unsigned
long
)
condition
);
/* Ok, finally something we can handle */
send_sigtrap
(
tsk
,
regs
,
error_code
);
send_sigtrap
(
tsk
,
regs
,
error_code
,
si_code
);
/*
* Disable additional traps. They'll be re-enabled when
...
...
arch/x86/kernel/traps_64.c
浏览文件 @
eceb1383
...
...
@@ -940,7 +940,7 @@ asmlinkage void __kprobes do_debug(struct pt_regs *regs,
tsk
->
thread
.
error_code
=
error_code
;
info
.
si_signo
=
SIGTRAP
;
info
.
si_errno
=
0
;
info
.
si_code
=
TRAP_BRKPT
;
info
.
si_code
=
get_si_code
(
condition
)
;
info
.
si_addr
=
user_mode
(
regs
)
?
(
void
__user
*
)
regs
->
ip
:
NULL
;
force_sig_info
(
SIGTRAP
,
&
info
,
tsk
);
...
...
arch/x86/kernel/vmlinux_64.lds.S
浏览文件 @
eceb1383
...
...
@@ -172,8 +172,8 @@ SECTIONS
.
x86_cpu_dev
.
init
:
AT
(
ADDR
(
.
x86_cpu_dev
.
init
)
-
LOAD_OFFSET
)
{
*(.
x86_cpu_dev
.
init
)
}
SECURITY_INIT
__x86_cpu_dev_end
=
.
;
SECURITY_INIT
.
=
ALIGN
(
8
)
;
.
parainstructions
:
AT
(
ADDR
(
.
parainstructions
)
-
LOAD_OFFSET
)
{
...
...
arch/x86/mm/ioremap.c
浏览文件 @
eceb1383
...
...
@@ -614,7 +614,7 @@ void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
*/
offset
=
phys_addr
&
~
PAGE_MASK
;
phys_addr
&=
PAGE_MASK
;
size
=
PAGE_ALIGN
(
last_addr
)
-
phys_addr
;
size
=
PAGE_ALIGN
(
last_addr
+
1
)
-
phys_addr
;
/*
* Mappings have to fit in the FIX_BTMAP area.
...
...
include/asm-generic/siginfo.h
浏览文件 @
eceb1383
...
...
@@ -199,6 +199,8 @@ typedef struct siginfo {
*/
#define TRAP_BRKPT (__SI_FAULT|1)
/* process breakpoint */
#define TRAP_TRACE (__SI_FAULT|2)
/* process trace trap */
#define TRAP_BRANCH (__SI_FAULT|3)
/* process taken branch trap */
#define TRAP_HWBKPT (__SI_FAULT|4)
/* hardware breakpoint/watchpoint */
#define NSIGTRAP 2
/*
...
...
include/asm-parisc/siginfo.h
浏览文件 @
eceb1383
...
...
@@ -3,11 +3,6 @@
#include <asm-generic/siginfo.h>
/*
* SIGTRAP si_codes
*/
#define TRAP_BRANCH (__SI_FAULT|3)
/* process taken branch trap */
#define TRAP_HWBKPT (__SI_FAULT|4)
/* hardware breakpoint or watchpoint */
#undef NSIGTRAP
#define NSIGTRAP 4
...
...
include/asm-x86/ptrace.h
浏览文件 @
eceb1383
...
...
@@ -177,11 +177,11 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);
#ifdef CONFIG_X86_32
extern
void
send_sigtrap
(
struct
task_struct
*
tsk
,
struct
pt_regs
*
regs
,
int
error_code
);
#else
void
signal_fault
(
struct
pt_regs
*
regs
,
void
__user
*
frame
,
char
*
where
);
int
error_code
,
int
si_code
);
#endif
void
signal_fault
(
struct
pt_regs
*
regs
,
void
__user
*
frame
,
char
*
where
);
extern
long
syscall_trace_enter
(
struct
pt_regs
*
);
extern
void
syscall_trace_leave
(
struct
pt_regs
*
);
...
...
include/asm-x86/spinlock.h
浏览文件 @
eceb1383
...
...
@@ -21,8 +21,10 @@
#ifdef CONFIG_X86_32
# define LOCK_PTR_REG "a"
# define REG_PTR_MODE "k"
#else
# define LOCK_PTR_REG "D"
# define REG_PTR_MODE "q"
#endif
#if defined(CONFIG_X86_32) && \
...
...
@@ -54,19 +56,7 @@
* much between them in performance though, especially as locks are out of line.
*/
#if (NR_CPUS < 256)
static
inline
int
__ticket_spin_is_locked
(
raw_spinlock_t
*
lock
)
{
int
tmp
=
ACCESS_ONCE
(
lock
->
slock
);
return
(((
tmp
>>
8
)
&
0xff
)
!=
(
tmp
&
0xff
));
}
static
inline
int
__ticket_spin_is_contended
(
raw_spinlock_t
*
lock
)
{
int
tmp
=
ACCESS_ONCE
(
lock
->
slock
);
return
(((
tmp
>>
8
)
-
tmp
)
&
0xff
)
>
1
;
}
#define TICKET_SHIFT 8
static
__always_inline
void
__ticket_spin_lock
(
raw_spinlock_t
*
lock
)
{
...
...
@@ -89,19 +79,17 @@ static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
static
__always_inline
int
__ticket_spin_trylock
(
raw_spinlock_t
*
lock
)
{
int
tmp
;
short
new
;
int
tmp
,
new
;
asm
volatile
(
"mov
w %2,%w
0
\n\t
"
asm
volatile
(
"mov
zwl %2, %
0
\n\t
"
"cmpb %h0,%b0
\n\t
"
"leal 0x100(%"
REG_PTR_MODE
"0), %1
\n\t
"
"jne 1f
\n\t
"
"movw %w0,%w1
\n\t
"
"incb %h1
\n\t
"
LOCK_PREFIX
"cmpxchgw %w1,%2
\n\t
"
"1:"
"sete %b1
\n\t
"
"movzbl %b1,%0
\n\t
"
:
"=&a"
(
tmp
),
"=
Q
"
(
new
),
"+m"
(
lock
->
slock
)
:
"=&a"
(
tmp
),
"=
&q
"
(
new
),
"+m"
(
lock
->
slock
)
:
:
"memory"
,
"cc"
);
...
...
@@ -116,19 +104,7 @@ static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock)
:
"memory"
,
"cc"
);
}
#else
static
inline
int
__ticket_spin_is_locked
(
raw_spinlock_t
*
lock
)
{
int
tmp
=
ACCESS_ONCE
(
lock
->
slock
);
return
(((
tmp
>>
16
)
&
0xffff
)
!=
(
tmp
&
0xffff
));
}
static
inline
int
__ticket_spin_is_contended
(
raw_spinlock_t
*
lock
)
{
int
tmp
=
ACCESS_ONCE
(
lock
->
slock
);
return
(((
tmp
>>
16
)
-
tmp
)
&
0xffff
)
>
1
;
}
#define TICKET_SHIFT 16
static
__always_inline
void
__ticket_spin_lock
(
raw_spinlock_t
*
lock
)
{
...
...
@@ -146,7 +122,7 @@ static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
/* don't need lfence here, because loads are in-order */
"jmp 1b
\n
"
"2:"
:
"+
Q"
(
inc
),
"+m"
(
lock
->
slock
),
"=
r"
(
tmp
)
:
"+
r"
(
inc
),
"+m"
(
lock
->
slock
),
"=&
r"
(
tmp
)
:
:
"memory"
,
"cc"
);
}
...
...
@@ -160,13 +136,13 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
"movl %0,%1
\n\t
"
"roll $16, %0
\n\t
"
"cmpl %0,%1
\n\t
"
"leal 0x00010000(%"
REG_PTR_MODE
"0), %1
\n\t
"
"jne 1f
\n\t
"
"addl $0x00010000, %1
\n\t
"
LOCK_PREFIX
"cmpxchgl %1,%2
\n\t
"
"1:"
"sete %b1
\n\t
"
"movzbl %b1,%0
\n\t
"
:
"=&a"
(
tmp
),
"=
r
"
(
new
),
"+m"
(
lock
->
slock
)
:
"=&a"
(
tmp
),
"=
&q
"
(
new
),
"+m"
(
lock
->
slock
)
:
:
"memory"
,
"cc"
);
...
...
@@ -182,6 +158,20 @@ static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock)
}
#endif
static
inline
int
__ticket_spin_is_locked
(
raw_spinlock_t
*
lock
)
{
int
tmp
=
ACCESS_ONCE
(
lock
->
slock
);
return
!!
(((
tmp
>>
TICKET_SHIFT
)
^
tmp
)
&
((
1
<<
TICKET_SHIFT
)
-
1
));
}
static
inline
int
__ticket_spin_is_contended
(
raw_spinlock_t
*
lock
)
{
int
tmp
=
ACCESS_ONCE
(
lock
->
slock
);
return
(((
tmp
>>
TICKET_SHIFT
)
-
tmp
)
&
((
1
<<
TICKET_SHIFT
)
-
1
))
>
1
;
}
#ifdef CONFIG_PARAVIRT
/*
* Define virtualization-friendly old-style lock byte lock, for use in
...
...
include/asm-x86/traps.h
浏览文件 @
eceb1383
#ifndef ASM_X86__TRAPS_H
#define ASM_X86__TRAPS_H
#include <asm/debugreg.h>
/* Common in X86_32 and X86_64 */
asmlinkage
void
divide_error
(
void
);
asmlinkage
void
debug
(
void
);
...
...
@@ -36,6 +38,16 @@ void do_invalid_op(struct pt_regs *, long);
void
do_general_protection
(
struct
pt_regs
*
,
long
);
void
do_nmi
(
struct
pt_regs
*
,
long
);
static
inline
int
get_si_code
(
unsigned
long
condition
)
{
if
(
condition
&
DR_STEP
)
return
TRAP_TRACE
;
else
if
(
condition
&
(
DR_TRAP0
|
DR_TRAP1
|
DR_TRAP2
|
DR_TRAP3
))
return
TRAP_HWBKPT
;
else
return
TRAP_BRKPT
;
}
extern
int
panic_on_unrecovered_nmi
;
extern
int
kstack_depth_to_print
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录