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
4627c87c
Commit
4627c87c
authored
Sep 13, 2002
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SPARC]: Catchup with signal infrastructure changes.
parent
2f752fa9
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
108 additions
and
392 deletions
+108
-392
arch/sparc/kernel/init_task.c
arch/sparc/kernel/init_task.c
+1
-1
arch/sparc/kernel/signal.c
arch/sparc/kernel/signal.c
+28
-120
arch/sparc64/kernel/init_task.c
arch/sparc64/kernel/init_task.c
+1
-1
arch/sparc64/kernel/signal.c
arch/sparc64/kernel/signal.c
+20
-97
arch/sparc64/kernel/signal32.c
arch/sparc64/kernel/signal32.c
+29
-156
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/sys_sparc32.c
+29
-17
No files found.
arch/sparc/kernel/init_task.c
View file @
4627c87c
...
...
@@ -7,7 +7,7 @@
static
struct
fs_struct
init_fs
=
INIT_FS
;
static
struct
files_struct
init_files
=
INIT_FILES
;
static
struct
signal_struct
init_signals
=
INIT_SIGNALS
;
static
struct
signal_struct
init_signals
=
INIT_SIGNALS
(
init_signals
)
;
struct
mm_struct
init_mm
=
INIT_MM
(
init_mm
);
struct
task_struct
init_task
=
INIT_TASK
(
init_task
);
...
...
arch/sparc/kernel/signal.c
View file @
4627c87c
...
...
@@ -38,11 +38,6 @@ extern void fpload(unsigned long *fpregs, unsigned long *fsr);
asmlinkage
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
,
unsigned
long
orig_o0
,
int
restart_syscall
);
/* This turned off for production... */
/* #define DEBUG_SIGNALS 1 */
/* #define DEBUG_SIGNALS_TRACE 1 */
/* #define DEBUG_SIGNALS_MAPS 1 */
/* Signal frames: the original one (compatible with SunOS):
*
* Set up a signal frame... Make the stack look the way SunOS
...
...
@@ -470,12 +465,6 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
synchronize_user_stack
();
sframep
=
(
struct
signal_sframe
*
)
get_sigframe
(
sa
,
regs
,
SF_ALIGNEDSZ
);
if
(
invalid_frame_pointer
(
sframep
,
sizeof
(
*
sframep
))){
#ifdef DEBUG_SIGNALS
/* fills up the console logs during crashme runs, yuck... */
printk
(
"%s [%d]: User has trashed signal stack
\n
"
,
current
->
comm
,
current
->
pid
);
printk
(
"Sigstack ptr %p handler at pc<%08lx> for sig<%d>
\n
"
,
sframep
,
pc
,
signr
);
#endif
/* Don't change signal code and address, so that
* post mortem debuggers can have a look.
*/
...
...
@@ -635,13 +624,8 @@ new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
goto
sigill_and_return
;
if
(
current
->
thread
.
w_saved
!=
0
)
{
#ifdef DEBUG_SIGNALS
printk
(
"%s [%d]: Invalid user stack frame for "
"signal delivery.
\n
"
,
current
->
comm
,
current
->
pid
);
#endif
if
(
current
->
thread
.
w_saved
!=
0
)
goto
sigill_and_return
;
}
/* 2. Save the current process state */
err
=
__copy_to_user
(
&
sf
->
info
.
si_regs
,
regs
,
sizeof
(
struct
pt_regs
));
...
...
@@ -795,12 +779,8 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
synchronize_user_stack
();
sfp
=
(
svr4_signal_frame_t
*
)
get_sigframe
(
sa
,
regs
,
SVR4_SF_ALIGNED
+
REGWIN_SZ
);
if
(
invalid_frame_pointer
(
sfp
,
sizeof
(
*
sfp
))){
#ifdef DEBUG_SIGNALS
printk
(
"Invalid stack frame
\n
"
);
#endif
if
(
invalid_frame_pointer
(
sfp
,
sizeof
(
*
sfp
)))
goto
sigill_and_return
;
}
/* Start with a clean frame pointer and fill it */
err
=
__clear_user
(
sfp
,
sizeof
(
*
sfp
));
...
...
@@ -883,9 +863,6 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs
->
pc
=
(
unsigned
long
)
sa
->
sa_handler
;
regs
->
npc
=
(
regs
->
pc
+
4
);
#ifdef DEBUG_SIGNALS
printk
(
"Solaris-frame: %x %x
\n
"
,
(
int
)
regs
->
pc
,
(
int
)
regs
->
npc
);
#endif
/* Arguments passed to signal handler */
if
(
regs
->
u_regs
[
14
]){
struct
reg_window
*
rw
=
(
struct
reg_window
*
)
regs
->
u_regs
[
14
];
...
...
@@ -1090,61 +1067,6 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
}
}
#ifdef DEBUG_SIGNALS_MAPS
#define MAPS_LINE_FORMAT "%08lx-%08lx %s %08lx %02x:%02x %lu "
static
inline
void
read_maps
(
void
)
{
struct
vm_area_struct
*
map
,
*
next
;
char
*
buffer
;
ssize_t
i
;
buffer
=
(
char
*
)
__get_free_page
(
GFP_KERNEL
);
if
(
!
buffer
)
return
;
for
(
map
=
current
->
mm
->
mmap
;
map
;
map
=
next
)
{
/* produce the next line */
char
*
line
;
char
str
[
5
],
*
cp
=
str
;
int
flags
;
dev_t
dev
;
unsigned
long
ino
;
/*
* Get the next vma now (but it won't be used if we sleep).
*/
next
=
map
->
vm_next
;
flags
=
map
->
vm_flags
;
*
cp
++
=
flags
&
VM_READ
?
'r'
:
'-'
;
*
cp
++
=
flags
&
VM_WRITE
?
'w'
:
'-'
;
*
cp
++
=
flags
&
VM_EXEC
?
'x'
:
'-'
;
*
cp
++
=
flags
&
VM_MAYSHARE
?
's'
:
'p'
;
*
cp
++
=
0
;
dev
=
0
;
ino
=
0
;
if
(
map
->
vm_file
!=
NULL
)
{
dev
=
map
->
vm_file
->
f_dentry
->
d_inode
->
i_dev
;
ino
=
map
->
vm_file
->
f_dentry
->
d_inode
->
i_ino
;
line
=
d_path
(
map
->
vm_file
->
f_dentry
,
map
->
vm_file
->
f_vfsmnt
,
buffer
,
PAGE_SIZE
);
}
printk
(
MAPS_LINE_FORMAT
,
map
->
vm_start
,
map
->
vm_end
,
str
,
map
->
vm_pgoff
<<
PAGE_SHIFT
,
MAJOR
(
dev
),
MINOR
(
dev
),
ino
);
if
(
map
->
vm_file
!=
NULL
)
printk
(
"%s
\n
"
,
line
);
else
printk
(
"
\n
"
);
}
free_page
((
unsigned
long
)
buffer
);
return
;
}
#endif
/* 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
* mistake.
...
...
@@ -1152,7 +1074,6 @@ static inline void read_maps (void)
asmlinkage
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
,
unsigned
long
orig_i0
,
int
restart_syscall
)
{
unsigned
long
signr
;
struct
k_sigaction
*
ka
;
siginfo_t
info
;
...
...
@@ -1171,9 +1092,21 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
oldset
=
&
current
->
blocked
;
for
(;;)
{
spin_lock_irq
(
&
current
->
sigmask_lock
);
signr
=
dequeue_signal
(
&
current
->
blocked
,
&
info
);
spin_unlock_irq
(
&
current
->
sigmask_lock
);
sigset_t
*
mask
=
&
current
->
blocked
;
unsigned
long
signr
=
0
;
local_irq_disable
();
if
(
current
->
sig
->
shared_pending
.
head
)
{
spin_lock
(
&
current
->
sig
->
siglock
);
signr
=
dequeue_signal
(
&
current
->
sig
->
shared_pending
,
mask
,
&
info
);
spin_unlock
(
&
current
->
sig
->
siglock
);
}
if
(
!
signr
)
{
spin_lock
(
&
current
->
sigmask_lock
);
signr
=
dequeue_signal
(
&
current
->
pending
,
mask
,
&
info
);
spin_unlock
(
&
current
->
sigmask_lock
);
}
local_irq_enable
();
if
(
!
signr
)
break
;
...
...
@@ -1193,7 +1126,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
restart_syscall
=
0
;
}
current
->
exit_code
=
signr
;
current
->
state
=
TASK_STOPPED
;
set_current_state
(
TASK_STOPPED
)
;
/* This happens to be SMP safe so no need to
* grab master kernel lock even in this case.
...
...
@@ -1254,52 +1187,27 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
if
(
is_orphaned_pgrp
(
current
->
pgrp
))
continue
;
case
SIGSTOP
:
if
(
current
->
ptrace
&
PT_PTRACED
)
continue
;
current
->
state
=
TASK_STOPPED
;
case
SIGSTOP
:
{
struct
signal_struct
*
sig
;
set_current_state
(
TASK_STOPPED
);
current
->
exit_code
=
signr
;
/* notify_parent() is SMP safe */
if
(
!
(
current
->
parent
->
sig
->
action
[
SIGCHLD
-
1
].
sa
.
sa_flags
&
SA_NOCLDSTOP
))
sig
=
current
->
parent
->
sig
;
if
(
sig
&&
!
(
sig
->
action
[
SIGCHLD
-
1
].
sa
.
sa_flags
&
SA_NOCLDSTOP
))
notify_parent
(
current
,
SIGCHLD
);
schedule
();
continue
;
}
case
SIGQUIT
:
case
SIGILL
:
case
SIGTRAP
:
case
SIGABRT
:
case
SIGFPE
:
case
SIGSEGV
:
case
SIGBUS
:
case
SIGSYS
:
case
SIGXCPU
:
case
SIGXFSZ
:
if
(
do_coredump
(
signr
,
regs
))
exit_code
|=
0x80
;
#ifdef DEBUG_SIGNALS
/* Very useful to debug dynamic linker problems */
printk
(
"Sig %ld going for %s[%d]...
\n
"
,
signr
,
current
->
comm
,
current
->
pid
);
show_regs
(
regs
);
#ifdef DEBUG_SIGNALS_TRACE
{
struct
reg_window
*
rw
=
(
struct
reg_window
*
)
regs
->
u_regs
[
UREG_FP
];
unsigned
int
ins
[
8
];
while
(
rw
&&
!
(((
unsigned
long
)
rw
)
&
0x3
))
{
copy_from_user
(
ins
,
&
rw
->
ins
[
0
],
sizeof
(
ins
));
printk
(
"Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)
\n
"
,
ins
[
7
],
ins
[
0
],
ins
[
1
],
ins
[
2
],
ins
[
3
],
ins
[
4
],
ins
[
5
]);
rw
=
(
struct
reg_window
*
)(
unsigned
long
)
ins
[
6
];
}
}
#endif
#ifdef DEBUG_SIGNALS_MAPS
printk
(
"Maps:
\n
"
);
read_maps
();
#endif
#endif
/* fall through */
/* FALLTHRU */
default:
sigaddset
(
&
current
->
pending
.
signal
,
signr
);
recalc_sigpending
();
current
->
flags
|=
PF_SIGNALED
;
do_exit
(
exit_code
);
sig_exit
(
signr
,
exit_code
,
&
info
);
/* NOT REACHED */
}
}
...
...
arch/sparc64/kernel/init_task.c
View file @
4627c87c
...
...
@@ -8,7 +8,7 @@
static
struct
fs_struct
init_fs
=
INIT_FS
;
static
struct
files_struct
init_files
=
INIT_FILES
;
static
struct
signal_struct
init_signals
=
INIT_SIGNALS
;
static
struct
signal_struct
init_signals
=
INIT_SIGNALS
(
init_signals
)
;
struct
mm_struct
init_mm
=
INIT_MM
(
init_mm
);
/* .text section in head.S is aligned at 2 page boundry and this gets linked
...
...
arch/sparc64/kernel/signal.c
View file @
4627c87c
...
...
@@ -36,11 +36,6 @@
static
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
,
unsigned
long
orig_o0
,
int
ret_from_syscall
);
/* This turned off for production... */
/* #define DEBUG_SIGNALS 1 */
/* #define DEBUG_SIGNALS_TRACE 1 */
/* #define DEBUG_SIGNALS_MAPS 1 */
int
copy_siginfo_to_user
(
siginfo_t
*
to
,
siginfo_t
*
from
)
{
if
(
!
access_ok
(
VERIFY_WRITE
,
to
,
sizeof
(
siginfo_t
)))
...
...
@@ -535,13 +530,8 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
goto
sigill
;
if
(
get_thread_wsaved
()
!=
0
)
{
#ifdef DEBUG_SIGNALS
printk
(
"%s[%d]: Invalid user stack frame for "
"signal delivery.
\n
"
,
current
->
comm
,
current
->
pid
);
#endif
if
(
get_thread_wsaved
()
!=
0
)
goto
sigill
;
}
/* 2. Save the current process state */
err
=
copy_to_user
(
&
sf
->
regs
,
regs
,
sizeof
(
*
regs
));
...
...
@@ -631,62 +621,6 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
}
}
#ifdef DEBUG_SIGNALS_MAPS
#define MAPS_LINE_FORMAT "%016lx-%016lx %s %016lx %02x:%02x %lu "
static
inline
void
read_maps
(
void
)
{
struct
vm_area_struct
*
map
,
*
next
;
char
*
buffer
;
ssize_t
i
;
buffer
=
(
char
*
)
__get_free_page
(
GFP_KERNEL
);
if
(
!
buffer
)
return
;
for
(
map
=
current
->
mm
->
mmap
;
map
;
map
=
next
)
{
/* produce the next line */
char
*
line
;
char
str
[
5
],
*
cp
=
str
;
int
flags
;
dev_t
dev
;
unsigned
long
ino
;
/*
* Get the next vma now (but it won't be used if we sleep).
*/
next
=
map
->
vm_next
;
flags
=
map
->
vm_flags
;
*
cp
++
=
flags
&
VM_READ
?
'r'
:
'-'
;
*
cp
++
=
flags
&
VM_WRITE
?
'w'
:
'-'
;
*
cp
++
=
flags
&
VM_EXEC
?
'x'
:
'-'
;
*
cp
++
=
flags
&
VM_MAYSHARE
?
's'
:
'p'
;
*
cp
++
=
0
;
dev
=
0
;
ino
=
0
;
if
(
map
->
vm_file
!=
NULL
)
{
dev
=
map
->
vm_file
->
f_dentry
->
d_inode
->
i_dev
;
ino
=
map
->
vm_file
->
f_dentry
->
d_inode
->
i_ino
;
line
=
d_path
(
map
->
vm_file
->
f_dentry
,
map
->
vm_file
->
f_vfsmnt
,
buffer
,
PAGE_SIZE
);
}
printk
(
MAPS_LINE_FORMAT
,
map
->
vm_start
,
map
->
vm_end
,
str
,
map
->
vm_pgoff
<<
PAGE_SHIFT
,
MAJOR
(
dev
),
MINOR
(
dev
),
ino
);
if
(
map
->
vm_file
!=
NULL
)
printk
(
"%s
\n
"
,
line
);
else
printk
(
"
\n
"
);
}
free_page
((
unsigned
long
)
buffer
);
return
;
}
#endif
/* 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
* mistake.
...
...
@@ -694,7 +628,6 @@ static inline void read_maps (void)
static
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
,
unsigned
long
orig_i0
,
int
restart_syscall
)
{
unsigned
long
signr
;
siginfo_t
info
;
struct
k_sigaction
*
ka
;
...
...
@@ -709,9 +642,21 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
}
#endif
for
(;;)
{
spin_lock_irq
(
&
current
->
sigmask_lock
);
signr
=
dequeue_signal
(
&
current
->
blocked
,
&
info
);
spin_unlock_irq
(
&
current
->
sigmask_lock
);
sigset_t
*
mask
=
&
current
->
blocked
;
unsigned
long
signr
=
0
;
local_irq_disable
();
if
(
current
->
sig
->
shared_pending
.
head
)
{
spin_lock
(
&
current
->
sig
->
siglock
);
signr
=
dequeue_signal
(
&
current
->
sig
->
shared_pending
,
mask
,
&
info
);
spin_unlock
(
&
current
->
sig
->
siglock
);
}
if
(
!
signr
)
{
spin_lock
(
&
current
->
sigmask_lock
);
signr
=
dequeue_signal
(
&
current
->
pending
,
mask
,
&
info
);
spin_unlock
(
&
current
->
sigmask_lock
);
}
local_irq_enable
();
if
(
!
signr
)
break
;
...
...
@@ -732,7 +677,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
}
current
->
exit_code
=
signr
;
current
->
state
=
TASK_STOPPED
;
set_current_state
(
TASK_STOPPED
)
;
notify_parent
(
current
,
SIGCHLD
);
schedule
();
if
(
!
(
signr
=
current
->
exit_code
))
...
...
@@ -787,8 +732,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
case
SIGSTOP
:
{
struct
signal_struct
*
sig
;
current
->
state
=
TASK_STOPPED
;
set_current_state
(
TASK_STOPPED
);
current
->
exit_code
=
signr
;
sig
=
current
->
parent
->
sig
;
if
(
sig
&&
!
(
sig
->
action
[
SIGCHLD
-
1
].
sa
.
sa_flags
&
...
...
@@ -803,29 +747,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
case
SIGBUS
:
case
SIGSYS
:
case
SIGXCPU
:
case
SIGXFSZ
:
if
(
do_coredump
(
signr
,
regs
))
exit_code
|=
0x80
;
#ifdef DEBUG_SIGNALS
/* Very useful to debug the dynamic linker */
printk
(
"Sig %d going...
\n
"
,
(
int
)
signr
);
show_regs
(
regs
);
#ifdef DEBUG_SIGNALS_TRACE
{
struct
reg_window
*
rw
=
(
struct
reg_window
*
)(
regs
->
u_regs
[
UREG_FP
]
+
STACK_BIAS
);
unsigned
long
ins
[
8
];
while
(
rw
&&
!
(((
unsigned
long
)
rw
)
&
0x3
))
{
copy_from_user
(
ins
,
&
rw
->
ins
[
0
],
sizeof
(
ins
));
printk
(
"Caller[%016lx](%016lx,%016lx,%016lx,%016lx,%016lx,%016lx)
\n
"
,
ins
[
7
],
ins
[
0
],
ins
[
1
],
ins
[
2
],
ins
[
3
],
ins
[
4
],
ins
[
5
]);
rw
=
(
struct
reg_window
*
)(
unsigned
long
)(
ins
[
6
]
+
STACK_BIAS
);
}
}
#endif
#ifdef DEBUG_SIGNALS_MAPS
printk
(
"Maps:
\n
"
);
read_maps
();
#endif
#endif
/* fall through */
/* FALLTHRU */
default:
sig_exit
(
signr
,
exit_code
,
&
info
);
/* NOT REACHED */
...
...
arch/sparc64/kernel/signal32.c
View file @
4627c87c
...
...
@@ -34,12 +34,6 @@
int
do_signal32
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
,
unsigned
long
orig_o0
,
int
ret_from_syscall
);
/* This turned off for production... */
/* #define DEBUG_SIGNALS 1 */
/* #define DEBUG_SIGNALS_TRACE 1 */
/* #define DEBUG_SIGNALS_MAPS 1 */
/* #define DEBUG_SIGNALS_TLB 1 */
/* Signal frames: the original one (compatible with SunOS):
*
* Set up a signal frame... Make the stack look the way SunOS
...
...
@@ -525,12 +519,6 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
sframep
=
(
struct
signal_sframe32
*
)
get_sigframe
(
sa
,
regs
,
SF_ALIGNEDSZ
);
if
(
invalid_frame_pointer
(
sframep
,
sizeof
(
*
sframep
))){
#ifdef DEBUG_SIGNALS
/* fills up the console logs during crashme runs, yuck... */
printk
(
"%s [%d]: User has trashed signal stack
\n
"
,
current
->
comm
,
current
->
pid
);
printk
(
"Sigstack ptr %p handler at pc<%016lx> for sig<%d>
\n
"
,
sframep
,
pc
,
signr
);
#endif
/* Don't change signal code and address, so that
* post mortem debuggers can have a look.
*/
...
...
@@ -696,21 +684,11 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg
sf
=
(
struct
new_signal_frame32
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
{
#ifdef DEBUG_SIGNALS
printk
(
"new_setup_frame32(%s:%d): invalid_frame_pointer(%p, %d)
\n
"
,
current
->
comm
,
current
->
pid
,
sf
,
sigframe_size
);
#endif
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
goto
sigill
;
}
if
(
get_thread_wsaved
()
!=
0
)
{
#ifdef DEBUG_SIGNALS
printk
(
"%s[%d]: Invalid user stack frame for "
"signal delivery.
\n
"
,
current
->
comm
,
current
->
pid
);
#endif
if
(
get_thread_wsaved
()
!=
0
)
goto
sigill
;
}
/* 2. Save the current process state */
if
(
test_thread_flag
(
TIF_32BIT
))
{
...
...
@@ -835,12 +813,8 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs
->
u_regs
[
UREG_FP
]
&=
0x00000000ffffffffUL
;
sfp
=
(
svr4_signal_frame_t
*
)
get_sigframe
(
sa
,
regs
,
REGWIN_SZ
+
SVR4_SF_ALIGNED
);
if
(
invalid_frame_pointer
(
sfp
,
sizeof
(
*
sfp
))){
#ifdef DEBUG_SIGNALS
printk
(
"Invalid stack frame
\n
"
);
#endif
if
(
invalid_frame_pointer
(
sfp
,
sizeof
(
*
sfp
)))
do_exit
(
SIGILL
);
}
/* Start with a clean frame pointer and fill it */
err
=
clear_user
(
sfp
,
sizeof
(
*
sfp
));
...
...
@@ -939,9 +913,6 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs
->
tnpc
&=
0xffffffff
;
}
#ifdef DEBUG_SIGNALS
printk
(
"Solaris-frame: %x %x
\n
"
,
(
int
)
regs
->
tpc
,
(
int
)
regs
->
tnpc
);
#endif
/* Arguments passed to signal handler */
if
(
regs
->
u_regs
[
14
]){
struct
reg_window32
*
rw
=
(
struct
reg_window32
*
)
...
...
@@ -975,12 +946,9 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs)
synchronize_user_stack
();
save_and_clear_fpu
();
if
(
get_thread_wsaved
())
{
#ifdef DEBUG_SIGNALS
printk
(
"Uh oh, w_saved is not zero (%d)
\n
"
,
(
int
)
get_thread_wsaved
());
#endif
if
(
get_thread_wsaved
())
do_exit
(
SIGSEGV
);
}
err
=
clear_user
(
uc
,
sizeof
(
*
uc
));
/* Setup convenience variables */
...
...
@@ -1047,12 +1015,9 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
*/
flush_user_windows
();
if
(
get_thread_wsaved
())
{
#ifdef DEBUG_SIGNALS
printk
(
"Uh oh, w_saved is: 0x%x
\n
"
,
get_thread_wsaved
());
#endif
if
(
get_thread_wsaved
())
goto
sigsegv
;
}
if
(((
unsigned
long
)
c
)
&
3
){
printk
(
"Unaligned structure passed
\n
"
);
goto
sigsegv
;
...
...
@@ -1067,12 +1032,8 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
gr
=
&
c
->
mcontext
.
greg
;
err
=
__get_user
(
pc
,
&
((
*
gr
)[
SVR4_PC
]));
err
|=
__get_user
(
npc
,
&
((
*
gr
)[
SVR4_NPC
]));
if
((
pc
|
npc
)
&
3
)
{
#ifdef DEBUG_SIGNALS
printk
(
"setcontext, PC or nPC were bogus
\n
"
);
#endif
if
((
pc
|
npc
)
&
3
)
goto
sigsegv
;
}
/* Retrieve information from passed ucontext */
/* note that nPC is ored a 1, this is used to inform entry.S */
...
...
@@ -1148,21 +1109,11 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs
sf
=
(
struct
rt_signal_frame32
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
{
#ifdef DEBUG_SIGNALS
printk
(
"rt_setup_frame32(%s:%d): invalid_frame_pointer(%p, %d)
\n
"
,
current
->
comm
,
current
->
pid
,
sf
,
sigframe_size
);
#endif
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
goto
sigill
;
}
if
(
get_thread_wsaved
()
!=
0
)
{
#ifdef DEBUG_SIGNALS
printk
(
"%s[%d]: Invalid user stack frame for "
"signal delivery.
\n
"
,
current
->
comm
,
current
->
pid
);
#endif
if
(
get_thread_wsaved
()
!=
0
)
goto
sigill
;
}
/* 2. Save the current process state */
if
(
test_thread_flag
(
TIF_32BIT
))
{
...
...
@@ -1317,62 +1268,6 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
}
}
#ifdef DEBUG_SIGNALS_MAPS
#define MAPS_LINE_FORMAT "%016lx-%016lx %s %016lx %02x:%02x %lu "
static
inline
void
read_maps
(
void
)
{
struct
vm_area_struct
*
map
,
*
next
;
char
*
buffer
;
ssize_t
i
;
buffer
=
(
char
*
)
__get_free_page
(
GFP_KERNEL
);
if
(
!
buffer
)
return
;
for
(
map
=
current
->
mm
->
mmap
;
map
;
map
=
next
)
{
/* produce the next line */
char
*
line
;
char
str
[
5
],
*
cp
=
str
;
int
flags
;
dev_t
dev
;
unsigned
long
ino
;
/*
* Get the next vma now (but it won't be used if we sleep).
*/
next
=
map
->
vm_next
;
flags
=
map
->
vm_flags
;
*
cp
++
=
flags
&
VM_READ
?
'r'
:
'-'
;
*
cp
++
=
flags
&
VM_WRITE
?
'w'
:
'-'
;
*
cp
++
=
flags
&
VM_EXEC
?
'x'
:
'-'
;
*
cp
++
=
flags
&
VM_MAYSHARE
?
's'
:
'p'
;
*
cp
++
=
0
;
dev
=
0
;
ino
=
0
;
if
(
map
->
vm_file
!=
NULL
)
{
dev
=
map
->
vm_file
->
f_dentry
->
d_inode
->
i_dev
;
ino
=
map
->
vm_file
->
f_dentry
->
d_inode
->
i_ino
;
line
=
d_path
(
map
->
vm_file
->
f_dentry
,
map
->
vm_file
->
f_vfsmnt
,
buffer
,
PAGE_SIZE
);
}
printk
(
MAPS_LINE_FORMAT
,
map
->
vm_start
,
map
->
vm_end
,
str
,
map
->
vm_pgoff
<<
PAGE_SHIFT
,
MAJOR
(
dev
),
MINOR
(
dev
),
ino
);
if
(
map
->
vm_file
!=
NULL
)
printk
(
"%s
\n
"
,
line
);
else
printk
(
"
\n
"
);
}
free_page
((
unsigned
long
)
buffer
);
return
;
}
#endif
/* 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
* mistake.
...
...
@@ -1380,16 +1275,27 @@ static inline void read_maps (void)
int
do_signal32
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
,
unsigned
long
orig_i0
,
int
restart_syscall
)
{
unsigned
long
signr
;
struct
k_sigaction
*
ka
;
siginfo_t
info
;
int
svr4_signal
=
current
->
personality
==
PER_SVR4
;
for
(;;)
{
spin_lock_irq
(
&
current
->
sigmask_lock
);
signr
=
dequeue_signal
(
&
current
->
blocked
,
&
info
);
spin_unlock_irq
(
&
current
->
sigmask_lock
);
sigset_t
*
mask
=
&
current
->
blocked
;
unsigned
long
signr
=
0
;
local_irq_disable
();
if
(
current
->
sig
->
shared_pending
.
head
)
{
spin_lock
(
&
current
->
sig
->
siglock
);
signr
=
dequeue_signal
(
&
current
->
sig
->
shared_pending
,
mask
,
&
info
);
spin_unlock
(
&
current
->
sig
->
siglock
);
}
if
(
!
signr
)
{
spin_lock
(
&
current
->
sigmask_lock
);
signr
=
dequeue_signal
(
&
current
->
pending
,
mask
,
&
info
);
spin_unlock
(
&
current
->
sigmask_lock
);
}
local_irq_enable
();
if
(
!
signr
)
break
;
...
...
@@ -1410,7 +1316,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
}
current
->
exit_code
=
signr
;
current
->
state
=
TASK_STOPPED
;
set_current_state
(
TASK_STOPPED
)
;
notify_parent
(
current
,
SIGCHLD
);
schedule
();
if
(
!
(
signr
=
current
->
exit_code
))
...
...
@@ -1465,8 +1371,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
case
SIGSTOP
:
{
struct
signal_struct
*
sig
;
current
->
state
=
TASK_STOPPED
;
set_current_state
(
TASK_STOPPED
);
current
->
exit_code
=
signr
;
sig
=
current
->
parent
->
sig
;
if
(
sig
&&
!
(
sig
->
action
[
SIGCHLD
-
1
].
sa
.
sa_flags
&
...
...
@@ -1480,40 +1385,8 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
case
SIGBUS
:
case
SIGSYS
:
case
SIGXCPU
:
case
SIGXFSZ
:
if
(
do_coredump
(
signr
,
regs
))
exit_code
|=
0x80
;
#ifdef DEBUG_SIGNALS
/* Very useful to debug dynamic linker problems */
printk
(
"Sig %ld going for %s[%d]...
\n
"
,
signr
,
current
->
comm
,
current
->
pid
);
/* On SMP we are only interested in the current
* CPU's registers.
*/
__show_regs
(
regs
);
#ifdef DEBUG_SIGNALS_TLB
do
{
extern
void
sparc_ultra_dump_itlb
(
void
);
extern
void
sparc_ultra_dump_dtlb
(
void
);
sparc_ultra_dump_dtlb
();
sparc_ultra_dump_itlb
();
}
while
(
0
);
#endif
#ifdef DEBUG_SIGNALS_TRACE
{
struct
reg_window32
*
rw
=
(
struct
reg_window32
*
)(
regs
->
u_regs
[
UREG_FP
]
&
0xffffffff
);
unsigned
int
ins
[
8
];
while
(
rw
&&
!
(((
unsigned
long
)
rw
)
&
0x3
))
{
copy_from_user
(
ins
,
&
rw
->
ins
[
0
],
sizeof
(
ins
));
printk
(
"Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)
\n
"
,
ins
[
7
],
ins
[
0
],
ins
[
1
],
ins
[
2
],
ins
[
3
],
ins
[
4
],
ins
[
5
]);
rw
=
(
struct
reg_window32
*
)(
unsigned
long
)
ins
[
6
];
}
}
#endif
#ifdef DEBUG_SIGNALS_MAPS
printk
(
"Maps:
\n
"
);
read_maps
();
#endif
#endif
/* fall through */
/* FALLTHRU */
default:
sig_exit
(
signr
,
exit_code
,
&
info
);
/* NOT REACHED */
...
...
arch/sparc64/kernel/sys_sparc32.c
View file @
4627c87c
...
...
@@ -1921,30 +1921,42 @@ sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
return
-
EINVAL
;
}
spin_lock_irq
(
&
current
->
sigmask_lock
);
sig
=
dequeue_signal
(
&
these
,
&
info
);
spin_lock_irq
(
&
current
->
sig
->
siglock
);
spin_lock
(
&
current
->
sigmask_lock
);
sig
=
dequeue_signal
(
&
current
->
sig
->
shared_pending
,
&
these
,
&
info
);
if
(
!
sig
)
sig
=
dequeue_signal
(
&
current
->
pending
,
&
these
,
&
info
);
if
(
!
sig
)
{
/* None ready -- temporarily unblock those we're interested
in so that we'll be awakened when they arrive. */
sigset_t
oldblocked
=
current
->
blocked
;
sigandsets
(
&
current
->
blocked
,
&
current
->
blocked
,
&
these
);
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sigmask_lock
);
timeout
=
MAX_SCHEDULE_TIMEOUT
;
if
(
uts
)
timeout
=
(
timespec_to_jiffies
(
&
ts
)
+
(
ts
.
tv_sec
||
ts
.
tv_nsec
));
current
->
state
=
TASK_INTERRUPTIBLE
;
timeout
=
schedule_timeout
(
timeout
);
spin_lock_irq
(
&
current
->
sigmask_lock
);
sig
=
dequeue_signal
(
&
these
,
&
info
);
current
->
blocked
=
oldblocked
;
recalc_sigpending
();
if
(
timeout
)
{
/* None ready -- temporarily unblock those we're
* interested while we are sleeping in so that we'll
* be awakened when they arrive. */
current
->
real_blocked
=
current
->
blocked
;
sigandsets
(
&
current
->
blocked
,
&
current
->
blocked
,
&
these
);
recalc_sigpending
();
spin_unlock
(
&
current
->
sigmask_lock
);
spin_unlock_irq
(
&
current
->
sig
->
siglock
);
current
->
state
=
TASK_INTERRUPTIBLE
;
timeout
=
schedule_timeout
(
timeout
);
spin_lock_irq
(
&
current
->
sig
->
siglock
);
spin_lock
(
&
current
->
sigmask_lock
);
sig
=
dequeue_signal
(
&
current
->
sig
->
shared_pending
,
&
these
,
&
info
);
if
(
!
sig
)
sig
=
dequeue_signal
(
&
current
->
pending
,
&
these
,
&
info
);
current
->
blocked
=
current
->
real_blocked
;
siginitset
(
&
current
->
real_blocked
,
0
);
recalc_sigpending
();
}
}
spin_unlock_irq
(
&
current
->
sigmask_lock
);
spin_unlock
(
&
current
->
sigmask_lock
);
spin_unlock_irq
(
&
current
->
sig
->
siglock
);
if
(
sig
)
{
ret
=
sig
;
...
...
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