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
eef61347
Commit
eef61347
authored
Jun 04, 2002
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ppc64: 64 and 32 bit signal cleanups from Stephen Rothwell
parent
ecfb7062
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
143 additions
and
180 deletions
+143
-180
arch/ppc64/kernel/signal.c
arch/ppc64/kernel/signal.c
+80
-78
arch/ppc64/kernel/signal32.c
arch/ppc64/kernel/signal32.c
+63
-102
No files found.
arch/ppc64/kernel/signal.c
View file @
eef61347
...
...
@@ -26,8 +26,6 @@
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/elf.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
#include <asm/ppc32.h>
#include <asm/sigcontext.h>
#include <asm/ucontext.h>
...
...
@@ -59,9 +57,36 @@
*/
#define MSR_USERCHANGE (MSR_FE0 | MSR_FE1)
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
);
extern
long
sys_wait4
(
pid_t
pid
,
unsigned
int
*
stat_addr
,
int
options
,
/*unsigned long*/
struct
rusage
*
ru
);
/*
* When we have signals to deliver, we set up on the
* user stack, going down from the original stack pointer:
* a sigregs struct
* one or more sigcontext structs with
* a gap of __SIGNAL_FRAMESIZE bytes
*
* Each of these things must be a multiple of 16 bytes in size.
*
*/
struct
sigregs
{
elf_gregset_t
gp_regs
;
double
fp_regs
[
ELF_NFPREG
];
unsigned
int
tramp
[
2
];
/* 64 bit API allows for 288 bytes below sp before
decrementing it. */
int
abigap
[
72
];
};
struct
rt_sigframe
{
unsigned
long
_unused
[
2
];
struct
siginfo
*
pinfo
;
void
*
puc
;
struct
siginfo
info
;
struct
ucontext
uc
;
};
extern
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
);
/*
* Atomically swap in the new signal mask, and wait for a signal.
...
...
@@ -127,7 +152,7 @@ long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int
long
sys_sigaltstack
(
const
stack_t
*
uss
,
stack_t
*
uoss
)
{
struct
pt_regs
*
regs
=
(
struct
pt_regs
*
)
&
uss
;
struct
pt_regs
*
regs
=
(
struct
pt_regs
*
)
&
uss
;
return
do_sigaltstack
(
uss
,
uoss
,
regs
->
gpr
[
1
]);
}
...
...
@@ -139,6 +164,7 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
if
(
act
)
{
old_sigset_t
mask
;
if
(
verify_area
(
VERIFY_READ
,
act
,
sizeof
(
*
act
))
||
__get_user
(
new_ka
.
sa
.
sa_handler
,
&
act
->
sa_handler
)
||
__get_user
(
new_ka
.
sa
.
sa_restorer
,
&
act
->
sa_restorer
))
...
...
@@ -148,8 +174,7 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
siginitset
(
&
new_ka
.
sa
.
sa_mask
,
mask
);
}
ret
=
do_sigaction
(
sig
,
(
act
?
&
new_ka
:
NULL
),
(
oact
?
&
old_ka
:
NULL
));
ret
=
do_sigaction
(
sig
,
act
?
&
new_ka
:
NULL
,
oact
?
&
old_ka
:
NULL
);
if
(
!
ret
&&
oact
)
{
if
(
verify_area
(
VERIFY_WRITE
,
oact
,
sizeof
(
*
oact
))
||
__put_user
(
old_ka
.
sa
.
sa_handler
,
&
oact
->
sa_handler
)
||
...
...
@@ -162,35 +187,6 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
return
ret
;
}
/*
* When we have signals to deliver, we set up on the
* user stack, going down from the original stack pointer:
* a sigregs struct
* one or more sigcontext structs with
* a gap of __SIGNAL_FRAMESIZE bytes
*
* Each of these things must be a multiple of 16 bytes in size.
*
*/
struct
sigregs
{
elf_gregset_t
gp_regs
;
double
fp_regs
[
ELF_NFPREG
];
unsigned
int
tramp
[
2
];
/* 64 bit API allows for 288 bytes below sp before
decrementing it. */
int
abigap
[
72
];
};
struct
rt_sigframe
{
unsigned
long
_unused
[
2
];
struct
siginfo
*
pinfo
;
void
*
puc
;
struct
siginfo
info
;
struct
ucontext
uc
;
};
/*
* When we have rt signals to deliver, we set up on the
* user stack, going down from the original stack pointer:
...
...
@@ -231,7 +227,7 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
* preamble frame (where registers are stored)
* see handle_signal()
*/
sr
=
(
struct
sigregs
*
)
sigctx
.
regs
;
sr
=
(
struct
sigregs
*
)
sigctx
.
regs
;
if
(
copy_from_user
(
saved_regs
,
&
sr
->
gp_regs
,
sizeof
(
sr
->
gp_regs
)))
goto
badframe
;
saved_regs
[
PT_MSR
]
=
(
regs
->
msr
&
~
MSR_USERCHANGE
)
...
...
@@ -251,11 +247,10 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
do_exit
(
SIGSEGV
);
}
static
void
setup_rt_frame
(
struct
pt_regs
*
regs
,
struct
sigregs
*
frame
,
static
void
setup_rt_frame
(
struct
pt_regs
*
regs
,
struct
sigregs
*
frame
,
signed
long
newsp
)
{
struct
rt_sigframe
*
rt_sf
=
(
struct
rt_sigframe
*
)
newsp
;
struct
rt_sigframe
*
rt_sf
=
(
struct
rt_sigframe
*
)
newsp
;
/* Handler is *really* a pointer to the function descriptor for
* the signal routine. The first entry in the function
* descriptor is the entry address of signal and the second
...
...
@@ -277,11 +272,13 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
if
(
__copy_to_user
(
&
frame
->
gp_regs
,
regs
,
GP_REGS_SIZE
)
||
__copy_to_user
(
&
frame
->
fp_regs
,
current
->
thread
.
fpr
,
ELF_NFPREG
*
sizeof
(
double
))
||
__put_user
(
0x38000000UL
+
__NR_rt_sigreturn
,
&
frame
->
tramp
[
0
])
/* li r0, __NR_rt_sigreturn */
||
__put_user
(
0x44000002UL
,
&
frame
->
tramp
[
1
]))
/* sc */
/* li r0, __NR_rt_sigreturn */
||
__put_user
(
0x38000000UL
+
__NR_rt_sigreturn
,
&
frame
->
tramp
[
0
])
/* sc */
||
__put_user
(
0x44000002UL
,
&
frame
->
tramp
[
1
]))
goto
badframe
;
flush_icache_range
((
unsigned
long
)
&
frame
->
tramp
[
0
],
(
unsigned
long
)
&
frame
->
tramp
[
2
]);
flush_icache_range
((
unsigned
long
)
&
frame
->
tramp
[
0
],
(
unsigned
long
)
&
frame
->
tramp
[
2
]);
current
->
thread
.
fpscr
=
0
;
/* turn off all fp exceptions */
/* Retrieve rt_sigframe from stack and
...
...
@@ -289,11 +286,11 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
*/
newsp
-=
__SIGNAL_FRAMESIZE
;
if
(
get_user
(
temp_ptr
,
&
rt_sf
->
uc
.
uc_mcontext
.
handler
))
{
if
(
get_user
(
temp_ptr
,
&
rt_sf
->
uc
.
uc_mcontext
.
handler
))
{
goto
badframe
;
}
funct_desc_ptr
=
(
struct
funct_descr_entry
*
)
temp_ptr
;
funct_desc_ptr
=
(
struct
funct_descr_entry
*
)
temp_ptr
;
if
(
put_user
(
regs
->
gpr
[
1
],
(
unsigned
long
*
)
newsp
)
||
get_user
(
regs
->
nip
,
&
funct_desc_ptr
->
entry
)
...
...
@@ -304,8 +301,8 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
goto
badframe
;
regs
->
gpr
[
1
]
=
newsp
;
regs
->
gpr
[
6
]
=
(
unsigned
long
)
rt_sf
;
regs
->
link
=
(
unsigned
long
)
frame
->
tramp
;
regs
->
gpr
[
6
]
=
(
unsigned
long
)
rt_sf
;
regs
->
link
=
(
unsigned
long
)
frame
->
tramp
;
return
;
...
...
@@ -342,11 +339,11 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
current
->
blocked
=
set
;
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sigmask_lock
);
if
(
regs
->
msr
&
MSR_FP
)
if
(
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
current
);
/* restore registers */
sr
=
(
struct
sigregs
*
)
sigctx
.
regs
;
sr
=
(
struct
sigregs
*
)
sigctx
.
regs
;
if
(
copy_from_user
(
saved_regs
,
&
sr
->
gp_regs
,
sizeof
(
sr
->
gp_regs
)))
goto
badframe
;
saved_regs
[
PT_MSR
]
=
(
regs
->
msr
&
~
MSR_USERCHANGE
)
...
...
@@ -367,8 +364,7 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
/*
* Set up a signal frame.
*/
static
void
setup_frame
(
struct
pt_regs
*
regs
,
struct
sigregs
*
frame
,
static
void
setup_frame
(
struct
pt_regs
*
regs
,
struct
sigregs
*
frame
,
unsigned
long
newsp
)
{
...
...
@@ -385,7 +381,7 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame,
struct
funct_descr_entry
*
funct_desc_ptr
;
unsigned
long
temp_ptr
;
struct
sigcontext_struct
*
sc
=
(
struct
sigcontext_struct
*
)
newsp
;
struct
sigcontext_struct
*
sc
=
(
struct
sigcontext_struct
*
)
newsp
;
if
(
verify_area
(
VERIFY_WRITE
,
frame
,
sizeof
(
*
frame
)))
goto
badframe
;
...
...
@@ -394,27 +390,29 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame,
if
(
__copy_to_user
(
&
frame
->
gp_regs
,
regs
,
GP_REGS_SIZE
)
||
__copy_to_user
(
&
frame
->
fp_regs
,
current
->
thread
.
fpr
,
ELF_NFPREG
*
sizeof
(
double
))
||
__put_user
(
0x38000000UL
+
__NR_sigreturn
,
&
frame
->
tramp
[
0
])
/* li r0, __NR_sigreturn */
||
__put_user
(
0x44000002UL
,
&
frame
->
tramp
[
1
]))
/* sc */
/* li r0, __NR_sigreturn */
||
__put_user
(
0x38000000UL
+
__NR_sigreturn
,
&
frame
->
tramp
[
0
])
/* sc */
||
__put_user
(
0x44000002UL
,
&
frame
->
tramp
[
1
]))
goto
badframe
;
flush_icache_range
((
unsigned
long
)
&
frame
->
tramp
[
0
],
(
unsigned
long
)
&
frame
->
tramp
[
2
]);
flush_icache_range
((
unsigned
long
)
&
frame
->
tramp
[
0
],
(
unsigned
long
)
&
frame
->
tramp
[
2
]);
current
->
thread
.
fpscr
=
0
;
/* turn off all fp exceptions */
newsp
-=
__SIGNAL_FRAMESIZE
;
if
(
get_user
(
temp_ptr
,
&
sc
->
handler
))
if
(
get_user
(
temp_ptr
,
&
sc
->
handler
))
goto
badframe
;
funct_desc_ptr
=
(
struct
funct_descr_entry
*
)
temp_ptr
;
funct_desc_ptr
=
(
struct
funct_descr_entry
*
)
temp_ptr
;
if
(
put_user
(
regs
->
gpr
[
1
],
(
unsigned
long
*
)
newsp
)
||
get_user
(
regs
->
nip
,
&
funct_desc_ptr
->
entry
)
||
get_user
(
regs
->
gpr
[
2
],
&
funct_desc_ptr
->
toc
)
||
get_user
(
regs
->
nip
,
&
funct_desc_ptr
->
entry
)
||
get_user
(
regs
->
gpr
[
2
],
&
funct_desc_ptr
->
toc
)
||
get_user
(
regs
->
gpr
[
3
],
&
sc
->
signal
))
goto
badframe
;
regs
->
gpr
[
1
]
=
newsp
;
regs
->
gpr
[
4
]
=
(
unsigned
long
)
sc
;
regs
->
link
=
(
unsigned
long
)
frame
->
tramp
;
regs
->
gpr
[
4
]
=
(
unsigned
long
)
sc
;
regs
->
link
=
(
unsigned
long
)
frame
->
tramp
;
return
;
...
...
@@ -429,8 +427,7 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame,
/*
* OK, we're invoking a handler
*/
static
void
handle_signal
(
unsigned
long
sig
,
siginfo_t
*
info
,
sigset_t
*
oldset
,
static
void
handle_signal
(
unsigned
long
sig
,
siginfo_t
*
info
,
sigset_t
*
oldset
,
struct
pt_regs
*
regs
,
unsigned
long
*
newspp
,
unsigned
long
frame
)
{
struct
sigcontext_struct
*
sc
;
...
...
@@ -447,11 +444,12 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
{
/* Put a Real Time Context onto stack */
*
newspp
-=
sizeof
(
*
rt_sf
);
rt_sf
=
(
struct
rt_sigframe
*
)
*
newspp
;
rt_sf
=
(
struct
rt_sigframe
*
)
*
newspp
;
if
(
verify_area
(
VERIFY_WRITE
,
rt_sf
,
sizeof
(
*
rt_sf
)))
goto
badframe
;
if
(
__put_user
((
unsigned
long
)
ka
->
sa
.
sa_handler
,
&
rt_sf
->
uc
.
uc_mcontext
.
handler
)
if
(
__put_user
((
unsigned
long
)
ka
->
sa
.
sa_handler
,
&
rt_sf
->
uc
.
uc_mcontext
.
handler
)
||
__put_user
(
&
rt_sf
->
info
,
&
rt_sf
->
pinfo
)
||
__put_user
(
&
rt_sf
->
uc
,
&
rt_sf
->
puc
)
/* Put the siginfo */
...
...
@@ -462,8 +460,10 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
||
__put_user
(
current
->
sas_ss_sp
,
&
rt_sf
->
uc
.
uc_stack
.
ss_sp
)
||
__put_user
(
sas_ss_flags
(
regs
->
gpr
[
1
]),
&
rt_sf
->
uc
.
uc_stack
.
ss_flags
)
||
__put_user
(
current
->
sas_ss_size
,
&
rt_sf
->
uc
.
uc_stack
.
ss_size
)
||
__copy_to_user
(
&
rt_sf
->
uc
.
uc_sigmask
,
oldset
,
sizeof
(
*
oldset
))
||
__put_user
(
current
->
sas_ss_size
,
&
rt_sf
->
uc
.
uc_stack
.
ss_size
)
||
__copy_to_user
(
&
rt_sf
->
uc
.
uc_sigmask
,
oldset
,
sizeof
(
*
oldset
))
/* mcontext.regs points to preamble register frame */
||
__put_user
((
struct
pt_regs
*
)
frame
,
&
rt_sf
->
uc
.
uc_mcontext
.
regs
)
||
__put_user
(
sig
,
&
rt_sf
->
uc
.
uc_mcontext
.
signal
))
...
...
@@ -471,11 +471,11 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
}
else
{
/* Put a sigcontext on the stack */
*
newspp
-=
sizeof
(
*
sc
);
sc
=
(
struct
sigcontext_struct
*
)
*
newspp
;
sc
=
(
struct
sigcontext_struct
*
)
*
newspp
;
if
(
verify_area
(
VERIFY_WRITE
,
sc
,
sizeof
(
*
sc
)))
goto
badframe
;
if
(
__put_user
((
unsigned
long
)
ka
->
sa
.
sa_handler
,
&
sc
->
handler
)
if
(
__put_user
((
unsigned
long
)
ka
->
sa
.
sa_handler
,
&
sc
->
handler
)
||
__put_user
(
oldset
->
sig
[
0
],
&
sc
->
oldmask
)
#if _NSIG_WORDS > 1
||
__put_user
(
oldset
->
sig
[
1
],
&
sc
->
_unused
[
3
])
...
...
@@ -512,6 +512,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
* mistake.
*/
extern
int
do_signal32
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
);
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
)
{
siginfo_t
info
;
...
...
@@ -534,8 +535,8 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
signr
=
get_signal_to_deliver
(
&
info
,
regs
);
if
(
signr
>
0
)
{
ka
=
&
current
->
sig
->
action
[
signr
-
1
];
if
(
(
ka
->
sa
.
sa_flags
&
SA_ONSTACK
)
&&
(
!
on_sig_stack
(
regs
->
gpr
[
1
])))
if
((
ka
->
sa
.
sa_flags
&
SA_ONSTACK
)
&&
(
!
on_sig_stack
(
regs
->
gpr
[
1
])))
newsp
=
(
current
->
sas_ss_sp
+
current
->
sas_ss_size
);
else
newsp
=
regs
->
gpr
[
1
];
...
...
@@ -557,9 +558,10 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
if
(
newsp
==
frame
)
return
0
;
/* no signals delivered */
/* Invoke correct stack setup routine */
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
setup_rt_frame
(
regs
,
(
struct
sigregs
*
)
frame
,
newsp
);
setup_rt_frame
(
regs
,
(
struct
sigregs
*
)
frame
,
newsp
);
else
setup_frame
(
regs
,
(
struct
sigregs
*
)
frame
,
newsp
);
setup_frame
(
regs
,
(
struct
sigregs
*
)
frame
,
newsp
);
return
1
;
}
arch/ppc64/kernel/signal32.c
View file @
eef61347
...
...
@@ -14,43 +14,19 @@
* 2 of the License, or (at your option) any later version.
*/
#include <asm/ptrace.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/signal.h>
#include <linux/utime.h>
#include <linux/resource.h>
#include <linux/times.h>
#include <linux/utsname.h>
#include <linux/timex.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/slab.h>
#include <linux/uio.h>
#include <linux/nfs_fs.h>
#include <linux/smb_fs.h>
#include <linux/smb_mount.h>
#include <linux/ncp_fs.h>
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/personality.h>
#include <linux/stat.h>
#include <linux/filter.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/elf.h>
#include <asm/types.h>
#include <asm/ipc.h>
#include <asm/uaccess.h>
#include <asm/ppc32.h>
#include <asm/uaccess.h>
#include <asm/ppcdebug.h>
#include <asm/unistd.h>
#include <asm/cacheflush.h>
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
/*
...
...
@@ -112,9 +88,6 @@ struct rt_sigframe_32 {
};
extern
asmlinkage
long
sys_wait4
(
pid_t
pid
,
unsigned
int
*
stat_addr
,
int
options
,
struct
rusage
*
ru
);
/*
* Start of nonRT signal support
...
...
@@ -133,7 +106,7 @@ extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr,
* setup_frame32
*/
asmlinkage
long
sys32_sigaction
(
int
sig
,
struct
old_sigaction32
*
act
,
long
sys32_sigaction
(
int
sig
,
struct
old_sigaction32
*
act
,
struct
old_sigaction32
*
oact
)
{
struct
k_sigaction
new_ka
,
old_ka
;
...
...
@@ -145,32 +118,30 @@ asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 *act,
if
(
act
)
{
old_sigset_t32
mask
;
ret
=
get_user
((
long
)
new_ka
.
sa
.
sa_handler
,
&
act
->
sa_handler
);
ret
|=
__get_user
((
long
)
new_ka
.
sa
.
sa_restorer
,
&
act
->
sa_restorer
);
ret
|=
__get_user
(
new_ka
.
sa
.
sa_flags
,
&
act
->
sa_flags
);
ret
|=
__get_user
(
mask
,
&
act
->
sa_mask
);
if
(
ret
)
return
ret
;
if
(
get_user
((
long
)
new_ka
.
sa
.
sa_handler
,
&
act
->
sa_handler
)
||
__get_user
((
long
)
new_ka
.
sa
.
sa_restorer
,
&
act
->
sa_restorer
)
||
__get_user
(
new_ka
.
sa
.
sa_flags
,
&
act
->
sa_flags
)
||
__get_user
(
mask
,
&
act
->
sa_mask
))
return
-
EFAULT
;
siginitset
(
&
new_ka
.
sa
.
sa_mask
,
mask
);
}
ret
=
do_sigaction
(
sig
,
act
?
&
new_ka
:
NULL
,
oact
?
&
old_ka
:
NULL
);
if
(
!
ret
&&
oact
)
{
ret
=
put_user
((
long
)
old_ka
.
sa
.
sa_handler
,
&
oact
->
sa_handler
);
ret
|=
__put_user
((
long
)
old_ka
.
sa
.
sa_restorer
,
&
oact
->
sa_restorer
);
ret
|=
__put_user
(
old_ka
.
sa
.
sa_flags
,
&
oact
->
sa_flags
);
ret
|=
__put_user
(
old_ka
.
sa
.
sa_mask
.
sig
[
0
],
&
oact
->
sa_mask
);
if
(
put_user
((
long
)
old_ka
.
sa
.
sa_handler
,
&
oact
->
sa_handler
)
||
__put_user
((
long
)
old_ka
.
sa
.
sa_restorer
,
&
oact
->
sa_restorer
)
||
__put_user
(
old_ka
.
sa
.
sa_flags
,
&
oact
->
sa_flags
)
||
__put_user
(
old_ka
.
sa
.
sa_mask
.
sig
[
0
],
&
oact
->
sa_mask
))
return
-
EFAULT
;
}
return
ret
;
}
extern
long
sys_sigpending
(
old_sigset_t
*
set
);
extern
asmlinkage
long
sys_sigpending
(
old_sigset_t
*
set
);
asmlinkage
long
sys32_sigpending
(
old_sigset_t32
*
set
)
long
sys32_sigpending
(
old_sigset_t32
*
set
)
{
old_sigset_t
s
;
int
ret
;
...
...
@@ -185,9 +156,7 @@ asmlinkage long sys32_sigpending(old_sigset_t32 *set)
}
extern
asmlinkage
long
sys_sigprocmask
(
int
how
,
old_sigset_t
*
set
,
extern
long
sys_sigprocmask
(
int
how
,
old_sigset_t
*
set
,
old_sigset_t
*
oset
);
/*
...
...
@@ -197,7 +166,7 @@ extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set,
* of a signed int (msr in 32-bit mode) and the register representation
* of a signed int (msr in 64-bit mode) is performed.
*/
asmlinkage
long
sys32_sigprocmask
(
u32
how
,
old_sigset_t32
*
set
,
long
sys32_sigprocmask
(
u32
how
,
old_sigset_t32
*
set
,
old_sigset_t32
*
oset
)
{
old_sigset_t
s
;
...
...
@@ -252,23 +221,21 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
* Note that PPC32 puts the upper 32 bits of the sigmask in the
* unused part of the signal stackframe
*/
set
.
sig
[
0
]
=
sigctx
.
oldmask
+
((
long
)(
sigctx
.
_unused
[
3
])
<<
32
);
set
.
sig
[
0
]
=
sigctx
.
oldmask
+
((
long
)(
sigctx
.
_unused
[
3
])
<<
32
);
sigdelsetmask
(
&
set
,
~
_BLOCKABLE
);
spin_lock_irq
(
&
current
->
sigmask_lock
);
current
->
blocked
=
set
;
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sigmask_lock
);
/* Last stacked signal - restore registers */
sr
=
(
struct
sigregs32
*
)(
u64
)
sigctx
.
regs
;
if
(
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
current
);
/* Last stacked signal - restore registers */
sr
=
(
struct
sigregs32
*
)(
u64
)
sigctx
.
regs
;
/*
* copy the 32 bit register values off the user stack
* into the 32 bit register area
*/
if
(
copy_from_user
(
saved_regs
,
&
sr
->
gp_regs
,
sizeof
(
sr
->
gp_regs
)))
if
(
copy_from_user
(
saved_regs
,
&
sr
->
gp_regs
,
sizeof
(
sr
->
gp_regs
)))
goto
badframe
;
/*
* The saved reg structure in the frame is an elf_grepset_t32,
...
...
@@ -323,7 +290,6 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
goto
badframe
;
ret
=
regs
->
result
;
return
ret
;
badframe:
...
...
@@ -387,12 +353,13 @@ static void setup_frame32(struct pt_regs *regs, struct sigregs32 *frame,
*/
if
(
__copy_to_user
(
&
frame
->
fp_regs
,
current
->
thread
.
fpr
,
ELF_NFPREG
*
sizeof
(
double
))
||
__put_user
(
0x38000000U
+
__NR_sigreturn
,
&
frame
->
tramp
[
0
])
/* li r0, __NR_sigreturn */
||
__put_user
(
0x44000002U
,
&
frame
->
tramp
[
1
]))
/* sc */
/* li r0, __NR_sigreturn */
||
__put_user
(
0x38000000U
+
__NR_sigreturn
,
&
frame
->
tramp
[
0
])
/* sc */
||
__put_user
(
0x44000002U
,
&
frame
->
tramp
[
1
]))
goto
badframe
;
flush_icache_range
((
unsigned
long
)
&
frame
->
tramp
[
0
],
(
unsigned
long
)
&
frame
->
tramp
[
2
]);
flush_icache_range
((
unsigned
long
)
&
frame
->
tramp
[
0
],
(
unsigned
long
)
&
frame
->
tramp
[
2
]);
current
->
thread
.
fpscr
=
0
;
/* turn off all fp exceptions */
newsp
-=
__SIGNAL_FRAMESIZE32
;
...
...
@@ -451,50 +418,45 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned
long
r6
,
unsigned
long
r7
,
unsigned
long
r8
,
struct
pt_regs
*
regs
)
{
struct
rt_sigframe_32
*
rt_s
tack_frame
;
struct
rt_sigframe_32
*
rt_s
f
;
struct
sigcontext32_struct
sigctx
;
struct
sigregs32
*
s
ignalregs
;
struct
sigregs32
*
s
r
;
int
ret
;
elf_gregset_t32
saved_regs
;
/* an array of 32 bit register values */
sigset_t
s
ignal_s
et
;
stack_t
st
ack
;
sigset_t
set
;
stack_t
st
;
int
i
;
ret
=
0
;
/* Adjust the inputted reg1 to point to the first rt signal frame */
rt_s
tack_frame
=
(
struct
rt_sigframe_32
*
)(
regs
->
gpr
[
1
]
+
__SIGNAL_FRAMESIZE32
);
rt_s
f
=
(
struct
rt_sigframe_32
*
)(
regs
->
gpr
[
1
]
+
__SIGNAL_FRAMESIZE32
);
/* Copy the information from the user stack */
if
(
copy_from_user
(
&
sigctx
,
&
rt_stack_frame
->
uc
.
uc_mcontext
,
sizeof
(
sigctx
))
||
copy_from_user
(
&
signal_set
,
&
rt_stack_frame
->
uc
.
uc_sigmask
,
sizeof
(
signal_set
))
||
copy_from_user
(
&
stack
,
&
rt_stack_frame
->
uc
.
uc_stack
,
sizeof
(
stack
)))
if
(
copy_from_user
(
&
sigctx
,
&
rt_sf
->
uc
.
uc_mcontext
,
sizeof
(
sigctx
))
||
copy_from_user
(
&
set
,
&
rt_sf
->
uc
.
uc_sigmask
,
sizeof
(
set
))
||
copy_from_user
(
&
st
,
&
rt_sf
->
uc
.
uc_stack
,
sizeof
(
st
)))
goto
badframe
;
/*
* Unblock the signal that was processed
* After a signal handler runs -
* if the signal is blockable - the signal will be unblocked
* (
sigkill and sigstop are not blockable)
* (sigkill and sigstop are not blockable)
*/
sigdelsetmask
(
&
s
ignal_s
et
,
~
_BLOCKABLE
);
sigdelsetmask
(
&
set
,
~
_BLOCKABLE
);
/* update the current based on the sigmask found in the rt_stackframe */
spin_lock_irq
(
&
current
->
sigmask_lock
);
current
->
blocked
=
s
ignal_s
et
;
current
->
blocked
=
set
;
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sigmask_lock
);
/* If currently owning the floating point - give them up */
if
(
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
current
);
/*
* Set to point to the next rt_sigframe - this is used to
* determine whether this is the last signal to process
*/
signalregs
=
(
struct
sigregs32
*
)
(
u64
)
sigctx
.
regs
;
/* If currently owning the floating point - give them up */
if
(
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
current
);
if
(
copy_from_user
(
saved_regs
,
&
signalregs
->
gp_regs
,
sizeof
(
signalregs
->
gp_regs
)))
sr
=
(
struct
sigregs32
*
)(
u64
)
sigctx
.
regs
;
if
(
copy_from_user
(
saved_regs
,
&
sr
->
gp_regs
,
sizeof
(
sr
->
gp_regs
)))
goto
badframe
;
/*
* The saved reg structure in the frame is an elf_grepset_t32,
...
...
@@ -544,7 +506,7 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
asmlinkage
long
sys32_rt_sigaction
(
int
sig
,
const
struct
sigaction32
*
act
,
long
sys32_rt_sigaction
(
int
sig
,
const
struct
sigaction32
*
act
,
struct
sigaction32
*
oact
,
size_t
sigsetsize
)
{
struct
k_sigaction
new_ka
,
old_ka
;
...
...
@@ -599,7 +561,7 @@ asmlinkage long sys32_rt_sigaction(int sig, const struct sigaction32 *act,
}
extern
asmlinkage
long
sys_rt_sigprocmask
(
int
how
,
sigset_t
*
set
,
extern
long
sys_rt_sigprocmask
(
int
how
,
sigset_t
*
set
,
sigset_t
*
oset
,
size_t
sigsetsize
);
/*
...
...
@@ -609,7 +571,7 @@ extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set,
* of a signed int (msr in 32-bit mode) and the register representation
* of a signed int (msr in 64-bit mode) is performed.
*/
asmlinkage
long
sys32_rt_sigprocmask
(
u32
how
,
sigset32_t
*
set
,
long
sys32_rt_sigprocmask
(
u32
how
,
sigset32_t
*
set
,
sigset32_t
*
oset
,
size_t
sigsetsize
)
{
sigset_t
s
;
...
...
@@ -649,10 +611,10 @@ asmlinkage long sys32_rt_sigprocmask(u32 how, sigset32_t *set,
}
extern
asmlinkage
long
sys_rt_sigpending
(
sigset_t
*
set
,
size_t
sigsetsize
);
extern
long
sys_rt_sigpending
(
sigset_t
*
set
,
size_t
sigsetsize
);
asmlinkage
long
sys32_rt_sigpending
(
sigset32_t
*
set
,
long
sys32_rt_sigpending
(
sigset32_t
*
set
,
__kernel_size_t32
sigsetsize
)
{
sigset_t
s
;
...
...
@@ -716,11 +678,12 @@ siginfo_t32 *siginfo64to32(siginfo_t32 *d, siginfo_t *s)
return
d
;
}
extern
asmlinkage
long
sys_rt_sigtimedwait
(
const
sigset_t
*
uthese
,
extern
long
sys_rt_sigtimedwait
(
const
sigset_t
*
uthese
,
siginfo_t
*
uinfo
,
const
struct
timespec
*
uts
,
size_t
sigsetsize
);
asmlinkage
long
sys32_rt_sigtimedwait
(
sigset32_t
*
uthese
,
siginfo_t32
*
uinfo
,
long
sys32_rt_sigtimedwait
(
sigset32_t
*
uthese
,
siginfo_t32
*
uinfo
,
struct
timespec32
*
uts
,
__kernel_size_t32
sigsetsize
)
{
sigset_t
s
;
...
...
@@ -800,7 +763,7 @@ siginfo_t * siginfo32to64(siginfo_t *d, siginfo_t32 *s)
}
extern
asmlinkage
long
sys_rt_sigqueueinfo
(
int
pid
,
int
sig
,
siginfo_t
*
uinfo
);
extern
long
sys_rt_sigqueueinfo
(
int
pid
,
int
sig
,
siginfo_t
*
uinfo
);
/*
* Note: it is necessary to treat pid and sig as unsigned ints, with the
...
...
@@ -809,7 +772,7 @@ extern asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
* (msr in 32-bit mode) and the register representation of a signed int
* (msr in 64-bit mode) is performed.
*/
asmlinkage
long
sys32_rt_sigqueueinfo
(
u32
pid
,
u32
sig
,
siginfo_t32
*
uinfo
)
long
sys32_rt_sigqueueinfo
(
u32
pid
,
u32
sig
,
siginfo_t32
*
uinfo
)
{
siginfo_t
info
;
siginfo_t32
info32
;
...
...
@@ -986,7 +949,7 @@ static void handle_signal32(unsigned long sig, siginfo_t *info,
/*
* Set up the signal frame
* Determine if a
n real time frame - siginfo
required
* Determine if a
real time frame and a siginfo is
required
*/
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
{
siginfo64to32
(
&
siginfo32bit
,
info
);
...
...
@@ -1048,7 +1011,6 @@ static void handle_signal32(unsigned long sig, siginfo_t *info,
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sigmask_lock
);
}
return
;
badframe:
...
...
@@ -1068,7 +1030,7 @@ static void handle_signal32(unsigned long sig, siginfo_t *info,
* sigaltatck sys32_sigaltstack
*/
asmlinkage
int
sys32_sigaltstack
(
u32
newstack
,
u32
oldstack
,
int
p3
,
int
sys32_sigaltstack
(
u32
newstack
,
u32
oldstack
,
int
p3
,
int
p4
,
int
p6
,
int
p7
,
struct
pt_regs
*
regs
)
{
stack_t
uss
,
uoss
;
...
...
@@ -1114,7 +1076,7 @@ asmlinkage int sys32_sigaltstack(u32 newstack, u32 oldstack, int p3,
/*
* Start of do_signal32 routine
*
* This routine gets control when a pe
m
ding signal needs to be processed
* This routine gets control when a pe
n
ding signal needs to be processed
* in the 32 bit target thread -
*
* It handles both rt and non-rt signals
...
...
@@ -1141,13 +1103,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
signr
=
get_signal_to_deliver
(
&
info
,
regs
);
if
(
signr
>
0
)
{
ka
=
&
current
->
sig
->
action
[
signr
-
1
];
if
((
ka
->
sa
.
sa_flags
&
SA_ONSTACK
)
&&
(
!
on_sig_stack
(
regs
->
gpr
[
1
])))
if
((
ka
->
sa
.
sa_flags
&
SA_ONSTACK
)
&&
(
!
on_sig_stack
(
regs
->
gpr
[
1
])))
newsp
=
(
current
->
sas_ss_sp
+
current
->
sas_ss_size
);
else
newsp
=
regs
->
gpr
[
1
];
newsp
=
frame
=
newsp
-
sizeof
(
struct
sigregs32
);
/* Whee! Actually deliver the signal. */
handle_signal32
(
signr
,
&
info
,
oldset
,
regs
,
&
newsp
,
frame
);
}
...
...
@@ -1169,6 +1131,5 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
setup_rt_frame32
(
regs
,
(
struct
sigregs32
*
)(
u64
)
frame
,
newsp
);
else
setup_frame32
(
regs
,
(
struct
sigregs32
*
)(
u64
)
frame
,
newsp
);
return
1
;
}
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