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
eceb1383
Commit
eceb1383
authored
Oct 12, 2008
by
Ingo Molnar
Browse files
Options
Browse Files
Download
Plain Diff
Merge branches 'core/signal' and 'x86/spinlocks' into x86/xen
Conflicts: include/asm-x86/spinlock.h
parents
365d46dc
84e9c95a
4c7145a1
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
339 additions
and
274 deletions
+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
No files found.
arch/ia64/include/asm/siginfo.h
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
;
...
...
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