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
nexedi
linux
Commits
a0e3315d
Commit
a0e3315d
authored
Apr 09, 2003
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge nuts.ninka.net:/home/davem/src/BK/sparcwork-2.5
into nuts.ninka.net:/home/davem/src/BK/sparc-2.5
parents
898df34c
35ecc0e9
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
553 additions
and
563 deletions
+553
-563
arch/sparc/kernel/signal.c
arch/sparc/kernel/signal.c
+135
-118
arch/sparc/kernel/sys_sparc.c
arch/sparc/kernel/sys_sparc.c
+26
-21
arch/sparc64/kernel/ioctl32.c
arch/sparc64/kernel/ioctl32.c
+101
-104
arch/sparc64/kernel/process.c
arch/sparc64/kernel/process.c
+1
-1
arch/sparc64/kernel/signal.c
arch/sparc64/kernel/signal.c
+29
-27
arch/sparc64/kernel/signal32.c
arch/sparc64/kernel/signal32.c
+136
-163
arch/sparc64/kernel/sys_sparc.c
arch/sparc64/kernel/sys_sparc.c
+15
-11
include/asm-sparc/signal.h
include/asm-sparc/signal.h
+9
-9
include/asm-sparc/uaccess.h
include/asm-sparc/uaccess.h
+73
-72
include/asm-sparc64/signal.h
include/asm-sparc64/signal.h
+9
-9
include/asm-sparc64/uaccess.h
include/asm-sparc64/uaccess.h
+19
-28
No files found.
arch/sparc/kernel/signal.c
View file @
a0e3315d
...
...
@@ -56,7 +56,7 @@ struct signal_sframe {
struct
reg_window
sig_window
;
int
sig_num
;
int
sig_code
;
struct
sigcontext
*
sig_scptr
;
struct
sigcontext
__user
*
sig_scptr
;
int
sig_address
;
struct
sigcontext
sig_context
;
unsigned
int
extramask
[
_NSIG_WORDS
-
1
];
...
...
@@ -71,8 +71,8 @@ struct signal_sframe {
struct
new_signal_frame
{
struct
sparc_stackf
ss
;
__siginfo_t
info
;
__siginfo_fpu_t
*
fpu_save
;
unsigned
long
insns
[
2
]
__attribute__
((
aligned
(
8
)));
__siginfo_fpu_t
__user
*
fpu_save
;
unsigned
long
insns
[
2
]
__attribute__
((
aligned
(
8
)));
unsigned
int
extramask
[
_NSIG_WORDS
-
1
];
unsigned
int
extra_size
;
/* Should be 0 */
__siginfo_fpu_t
fpu_state
;
...
...
@@ -83,8 +83,8 @@ struct rt_signal_frame {
siginfo_t
info
;
struct
pt_regs
regs
;
sigset_t
mask
;
__siginfo_fpu_t
*
fpu_save
;
unsigned
int
insns
[
2
];
__siginfo_fpu_t
__user
*
fpu_save
;
unsigned
int
insns
[
2
];
stack_t
stack
;
unsigned
int
extra_size
;
/* Should be 0 */
__siginfo_fpu_t
fpu_state
;
...
...
@@ -142,7 +142,7 @@ asmlinkage void do_sigsuspend (struct pt_regs *regs)
_sigpause_common
(
regs
->
u_regs
[
UREG_I0
],
regs
);
}
asmlinkage
void
do_rt_sigsuspend
(
sigset_t
*
uset
,
size_t
sigsetsize
,
asmlinkage
void
do_rt_sigsuspend
(
sigset_t
__user
*
uset
,
size_t
sigsetsize
,
struct
pt_regs
*
regs
)
{
sigset_t
oldset
,
set
;
...
...
@@ -190,7 +190,7 @@ asmlinkage void do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize,
}
static
inline
int
restore_fpu_state
(
struct
pt_regs
*
regs
,
__siginfo_fpu_t
*
fpu
)
restore_fpu_state
(
struct
pt_regs
*
regs
,
__siginfo_fpu_t
__user
*
fpu
)
{
int
err
;
#ifdef CONFIG_SMP
...
...
@@ -205,7 +205,7 @@ restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
current
->
used_math
=
1
;
clear_tsk_thread_flag
(
current
,
TIF_USEDFPU
);
if
(
verify_area
(
VERIFY_READ
,
fpu
,
sizeof
(
*
fpu
)))
if
(
verify_area
(
VERIFY_READ
,
fpu
,
sizeof
(
*
fpu
)))
return
-
EFAULT
;
err
=
__copy_from_user
(
&
current
->
thread
.
float_regs
[
0
],
&
fpu
->
si_float_regs
[
0
],
...
...
@@ -222,16 +222,16 @@ restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
static
inline
void
do_new_sigreturn
(
struct
pt_regs
*
regs
)
{
struct
new_signal_frame
*
sf
;
struct
new_signal_frame
__user
*
sf
;
unsigned
long
up_psr
,
pc
,
npc
;
sigset_t
set
;
__siginfo_fpu_t
*
fpu_save
;
__siginfo_fpu_t
__user
*
fpu_save
;
int
err
;
sf
=
(
struct
new_signal_frame
*
)
regs
->
u_regs
[
UREG_FP
];
sf
=
(
struct
new_signal_frame
__user
*
)
regs
->
u_regs
[
UREG_FP
];
/* 1. Make sure we are not getting garbage from the user */
if
(
verify_area
(
VERIFY_READ
,
sf
,
sizeof
(
*
sf
)))
if
(
verify_area
(
VERIFY_READ
,
sf
,
sizeof
(
*
sf
)))
goto
segv_and_exit
;
if
(((
uint
)
sf
)
&
3
)
...
...
@@ -245,7 +245,7 @@ static inline void do_new_sigreturn (struct pt_regs *regs)
/* 2. Restore the state */
up_psr
=
regs
->
psr
;
err
|=
__copy_from_user
(
regs
,
&
sf
->
info
.
si_regs
,
sizeof
(
struct
pt_regs
));
err
|=
__copy_from_user
(
regs
,
&
sf
->
info
.
si_regs
,
sizeof
(
struct
pt_regs
));
/* User can only change condition codes and FPU enabling in %psr. */
regs
->
psr
=
(
up_psr
&
~
(
PSR_ICC
|
PSR_EF
))
...
...
@@ -279,7 +279,7 @@ static inline void do_new_sigreturn (struct pt_regs *regs)
asmlinkage
void
do_sigreturn
(
struct
pt_regs
*
regs
)
{
struct
sigcontext
*
scptr
;
struct
sigcontext
__user
*
scptr
;
unsigned
long
pc
,
npc
,
psr
;
sigset_t
set
;
int
err
;
...
...
@@ -287,19 +287,19 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
synchronize_user_stack
();
if
(
current
->
thread
.
new_signal
)
return
do_new_sigreturn
(
regs
);
return
do_new_sigreturn
(
regs
);
scptr
=
(
struct
sigcontext
*
)
regs
->
u_regs
[
UREG_I0
];
scptr
=
(
struct
sigcontext
__user
*
)
regs
->
u_regs
[
UREG_I0
];
/* Check sanity of the user arg. */
if
(
verify_area
(
VERIFY_READ
,
scptr
,
sizeof
(
struct
sigcontext
))
||
(((
unsigned
long
)
scptr
)
&
3
))
if
(
verify_area
(
VERIFY_READ
,
scptr
,
sizeof
(
struct
sigcontext
))
||
(((
unsigned
long
)
scptr
)
&
3
))
goto
segv_and_exit
;
err
=
__get_user
(
pc
,
&
scptr
->
sigc_pc
);
err
|=
__get_user
(
npc
,
&
scptr
->
sigc_npc
);
if
((
pc
|
npc
)
&
3
)
if
((
pc
|
npc
)
&
3
)
goto
segv_and_exit
;
/* This is pretty much atomic, no amount locking would prevent
...
...
@@ -341,17 +341,17 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
asmlinkage
void
do_rt_sigreturn
(
struct
pt_regs
*
regs
)
{
struct
rt_signal_frame
*
sf
;
struct
rt_signal_frame
__user
*
sf
;
unsigned
int
psr
,
pc
,
npc
;
__siginfo_fpu_t
*
fpu_save
;
__siginfo_fpu_t
__user
*
fpu_save
;
sigset_t
set
;
stack_t
st
;
int
err
;
synchronize_user_stack
();
sf
=
(
struct
rt_signal_frame
*
)
regs
->
u_regs
[
UREG_FP
];
if
(
verify_area
(
VERIFY_READ
,
sf
,
sizeof
(
*
sf
))
||
(((
unsigned
long
)
sf
)
&
0x03
))
sf
=
(
struct
rt_signal_frame
__user
*
)
regs
->
u_regs
[
UREG_FP
];
if
(
verify_area
(
VERIFY_READ
,
sf
,
sizeof
(
*
sf
))
||
(((
unsigned
long
)
sf
)
&
0x03
))
goto
segv
;
err
=
__get_user
(
pc
,
&
sf
->
regs
.
pc
);
...
...
@@ -361,13 +361,14 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
err
|=
__get_user
(
regs
->
y
,
&
sf
->
regs
.
y
);
err
|=
__get_user
(
psr
,
&
sf
->
regs
.
psr
);
err
|=
__copy_from_user
(
&
regs
->
u_regs
[
UREG_G1
],
&
sf
->
regs
.
u_regs
[
UREG_G1
],
15
*
sizeof
(
u32
));
err
|=
__copy_from_user
(
&
regs
->
u_regs
[
UREG_G1
],
&
sf
->
regs
.
u_regs
[
UREG_G1
],
15
*
sizeof
(
u32
));
regs
->
psr
=
(
regs
->
psr
&
~
PSR_ICC
)
|
(
psr
&
PSR_ICC
);
err
|=
__get_user
(
fpu_save
,
&
sf
->
fpu_save
);
if
(
fpu_save
)
if
(
fpu_save
)
err
|=
restore_fpu_state
(
regs
,
fpu_save
);
err
|=
__copy_from_user
(
&
set
,
&
sf
->
mask
,
sizeof
(
sigset_t
));
...
...
@@ -380,7 +381,8 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
regs
->
npc
=
npc
;
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
* call it and ignore errors.
*/
do_sigaltstack
(
&
st
,
NULL
,
(
unsigned
long
)
sf
);
sigdelsetmask
(
&
set
,
~
_BLOCKABLE
);
...
...
@@ -394,7 +396,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
}
/* Checks if the fp is valid */
static
inline
int
invalid_frame_pointer
(
void
*
fp
,
int
fplen
)
static
inline
int
invalid_frame_pointer
(
void
__user
*
fp
,
int
fplen
)
{
if
((((
unsigned
long
)
fp
)
&
7
)
||
!
__access_ok
((
unsigned
long
)
fp
,
fplen
)
||
...
...
@@ -405,7 +407,7 @@ static inline int invalid_frame_pointer (void *fp, int fplen)
return
0
;
}
static
inline
void
*
get_sigframe
(
struct
sigaction
*
sa
,
struct
pt_regs
*
regs
,
unsigned
long
framesize
)
static
inline
void
__user
*
get_sigframe
(
struct
sigaction
*
sa
,
struct
pt_regs
*
regs
,
unsigned
long
framesize
)
{
unsigned
long
sp
;
...
...
@@ -416,14 +418,14 @@ static inline void *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
if
(
!
on_sig_stack
(
sp
)
&&
!
((
current
->
sas_ss_sp
+
current
->
sas_ss_size
)
&
7
))
sp
=
current
->
sas_ss_sp
+
current
->
sas_ss_size
;
}
return
(
void
*
)(
sp
-
framesize
);
return
(
void
__user
*
)(
sp
-
framesize
);
}
static
inline
void
setup_frame
(
struct
sigaction
*
sa
,
struct
pt_regs
*
regs
,
int
signr
,
sigset_t
*
oldset
,
siginfo_t
*
info
)
{
struct
signal_sframe
*
sframep
;
struct
sigcontext
*
sc
;
struct
signal_sframe
__user
*
sframep
;
struct
sigcontext
__user
*
sc
;
int
window
=
0
,
err
;
unsigned
long
pc
=
regs
->
pc
;
unsigned
long
npc
=
regs
->
npc
;
...
...
@@ -431,8 +433,9 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
int
sig_code
;
synchronize_user_stack
();
sframep
=
(
struct
signal_sframe
*
)
get_sigframe
(
sa
,
regs
,
SF_ALIGNEDSZ
);
if
(
invalid_frame_pointer
(
sframep
,
sizeof
(
*
sframep
))){
sframep
=
(
struct
signal_sframe
__user
*
)
get_sigframe
(
sa
,
regs
,
SF_ALIGNEDSZ
);
if
(
invalid_frame_pointer
(
sframep
,
sizeof
(
*
sframep
))){
/* Don't change signal code and address, so that
* post mortem debuggers can have a look.
*/
...
...
@@ -454,16 +457,16 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
err
|=
__put_user
(
regs
->
u_regs
[
UREG_G1
],
&
sc
->
sigc_g1
);
err
|=
__put_user
(
regs
->
u_regs
[
UREG_I0
],
&
sc
->
sigc_o0
);
err
|=
__put_user
(
current
->
thread
.
w_saved
,
&
sc
->
sigc_oswins
);
if
(
current
->
thread
.
w_saved
)
for
(
window
=
0
;
window
<
current
->
thread
.
w_saved
;
window
++
)
{
sc
->
sigc_spbuf
[
window
]
=
(
char
*
)
current
->
thread
.
rwbuf_stkptrs
[
window
]
;
if
(
current
->
thread
.
w_saved
)
for
(
window
=
0
;
window
<
current
->
thread
.
w_saved
;
window
++
)
{
put_user
((
char
*
)
current
->
thread
.
rwbuf_stkptrs
[
window
],
&
sc
->
sigc_spbuf
[
window
])
;
err
|=
__copy_to_user
(
&
sc
->
sigc_wbuf
[
window
],
&
current
->
thread
.
reg_window
[
window
],
sizeof
(
struct
reg_window
));
}
else
err
|=
__copy_to_user
(
sframep
,
(
char
*
)
regs
->
u_regs
[
UREG_FP
],
err
|=
__copy_to_user
(
sframep
,
(
char
*
)
regs
->
u_regs
[
UREG_FP
],
sizeof
(
struct
reg_window
));
current
->
thread
.
w_saved
=
0
;
/* So process is allowed to execute. */
...
...
@@ -484,7 +487,7 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
switch
(
info
->
si_code
)
{
case
ILL_ILLOPC
:
sig_code
=
SUBSIG_ILLINST
;
break
;
case
ILL_PRVOPC
:
sig_code
=
SUBSIG_PRIVINST
;
break
;
case
ILL_ILLTRP
:
sig_code
=
SUBSIG_BADTRAP
(
info
->
si_trapno
);
break
;
case
ILL_ILLTRP
:
sig_code
=
SUBSIG_BADTRAP
(
info
->
si_trapno
);
break
;
default:
sig_code
=
SUBSIG_STACK
;
break
;
}
break
;
...
...
@@ -541,7 +544,7 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
static
inline
int
save_fpu_state
(
struct
pt_regs
*
regs
,
__siginfo_fpu_t
*
fpu
)
save_fpu_state
(
struct
pt_regs
*
regs
,
__siginfo_fpu_t
__user
*
fpu
)
{
int
err
=
0
;
#ifdef CONFIG_SMP
...
...
@@ -561,12 +564,14 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
regs
->
psr
&=
~
(
PSR_EF
);
}
#endif
err
|=
__copy_to_user
(
&
fpu
->
si_float_regs
[
0
],
&
current
->
thread
.
float_regs
[
0
],
err
|=
__copy_to_user
(
&
fpu
->
si_float_regs
[
0
],
&
current
->
thread
.
float_regs
[
0
],
(
sizeof
(
unsigned
long
)
*
32
));
err
|=
__put_user
(
current
->
thread
.
fsr
,
&
fpu
->
si_fsr
);
err
|=
__put_user
(
current
->
thread
.
fpqdepth
,
&
fpu
->
si_fpqdepth
);
if
(
current
->
thread
.
fpqdepth
!=
0
)
err
|=
__copy_to_user
(
&
fpu
->
si_fpqueue
[
0
],
&
current
->
thread
.
fpqueue
[
0
],
err
|=
__copy_to_user
(
&
fpu
->
si_fpqueue
[
0
],
&
current
->
thread
.
fpqueue
[
0
],
((
sizeof
(
unsigned
long
)
+
(
sizeof
(
unsigned
long
*
)))
*
16
));
current
->
used_math
=
0
;
...
...
@@ -577,7 +582,7 @@ static inline void
new_setup_frame
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signo
,
sigset_t
*
oldset
)
{
struct
new_signal_frame
*
sf
;
struct
new_signal_frame
__user
*
sf
;
int
sigframe_size
,
err
;
/* 1. Make sure everything is clean */
...
...
@@ -587,16 +592,17 @@ new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
if
(
!
current
->
used_math
)
sigframe_size
-=
sizeof
(
__siginfo_fpu_t
);
sf
=
(
struct
new_signal_frame
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
sf
=
(
struct
new_signal_frame
__user
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
goto
sigill_and_return
;
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
));
err
=
__copy_to_user
(
&
sf
->
info
.
si_regs
,
regs
,
sizeof
(
struct
pt_regs
));
err
|=
__put_user
(
0
,
&
sf
->
extra_size
);
...
...
@@ -610,8 +616,8 @@ new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
err
|=
__put_user
(
oldset
->
sig
[
0
],
&
sf
->
info
.
si_mask
);
err
|=
__copy_to_user
(
sf
->
extramask
,
&
oldset
->
sig
[
1
],
(
_NSIG_WORDS
-
1
)
*
sizeof
(
unsigned
int
));
err
|=
__copy_to_user
(
sf
,
(
char
*
)
regs
->
u_regs
[
UREG_FP
],
sizeof
(
struct
reg_window
));
err
|=
__copy_to_user
(
sf
,
(
char
*
)
regs
->
u_regs
[
UREG_FP
],
sizeof
(
struct
reg_window
));
if
(
err
)
goto
sigsegv
;
...
...
@@ -653,32 +659,33 @@ static inline void
new_setup_rt_frame
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signo
,
sigset_t
*
oldset
,
siginfo_t
*
info
)
{
struct
rt_signal_frame
*
sf
;
struct
rt_signal_frame
__user
*
sf
;
int
sigframe_size
;
unsigned
int
psr
;
int
err
;
synchronize_user_stack
();
sigframe_size
=
RT_ALIGNEDSZ
;
if
(
!
current
->
used_math
)
if
(
!
current
->
used_math
)
sigframe_size
-=
sizeof
(
__siginfo_fpu_t
);
sf
=
(
struct
rt_signal_frame
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
sf
=
(
struct
rt_signal_frame
__user
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
goto
sigill
;
if
(
current
->
thread
.
w_saved
!=
0
)
if
(
current
->
thread
.
w_saved
!=
0
)
goto
sigill
;
err
=
__put_user
(
regs
->
pc
,
&
sf
->
regs
.
pc
);
err
|=
__put_user
(
regs
->
npc
,
&
sf
->
regs
.
npc
);
err
|=
__put_user
(
regs
->
y
,
&
sf
->
regs
.
y
);
psr
=
regs
->
psr
;
if
(
current
->
used_math
)
if
(
current
->
used_math
)
psr
|=
PSR_EF
;
err
|=
__put_user
(
psr
,
&
sf
->
regs
.
psr
);
err
|=
__copy_to_user
(
&
sf
->
regs
.
u_regs
,
regs
->
u_regs
,
sizeof
(
regs
->
u_regs
));
err
|=
__put_user
(
0
,
&
sf
->
extra_size
);
if
(
psr
&
PSR_EF
)
{
if
(
psr
&
PSR_EF
)
{
err
|=
save_fpu_state
(
regs
,
&
sf
->
fpu_state
);
err
|=
__put_user
(
&
sf
->
fpu_state
,
&
sf
->
fpu_save
);
}
else
{
...
...
@@ -691,8 +698,8 @@ new_setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
err
|=
__put_user
(
sas_ss_flags
(
regs
->
u_regs
[
UREG_FP
]),
&
sf
->
stack
.
ss_flags
);
err
|=
__put_user
(
current
->
sas_ss_size
,
&
sf
->
stack
.
ss_size
);
err
|=
__copy_to_user
(
sf
,
(
char
*
)
regs
->
u_regs
[
UREG_FP
],
sizeof
(
struct
reg_window
));
err
|=
__copy_to_user
(
sf
,
(
char
*
)
regs
->
u_regs
[
UREG_FP
],
sizeof
(
struct
reg_window
));
err
|=
copy_siginfo_to_user
(
&
sf
->
info
,
info
);
...
...
@@ -706,7 +713,7 @@ new_setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
regs
->
pc
=
(
unsigned
long
)
ka
->
sa
.
sa_handler
;
regs
->
npc
=
(
regs
->
pc
+
4
);
if
(
ka
->
ka_restorer
)
if
(
ka
->
ka_restorer
)
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)
ka
->
ka_restorer
;
else
{
regs
->
u_regs
[
UREG_I7
]
=
(
unsigned
long
)(
&
(
sf
->
insns
[
0
])
-
2
);
...
...
@@ -735,23 +742,24 @@ static inline void
setup_svr4_frame
(
struct
sigaction
*
sa
,
unsigned
long
pc
,
unsigned
long
npc
,
struct
pt_regs
*
regs
,
int
signr
,
sigset_t
*
oldset
)
{
svr4_signal_frame_t
*
sfp
;
svr4_gregset_t
*
gr
;
svr4_siginfo_t
*
si
;
svr4_mcontext_t
*
mc
;
svr4_gwindows_t
*
gw
;
svr4_ucontext_t
*
uc
;
svr4_signal_frame_t
__user
*
sfp
;
svr4_gregset_t
__user
*
gr
;
svr4_siginfo_t
__user
*
si
;
svr4_mcontext_t
__user
*
mc
;
svr4_gwindows_t
__user
*
gw
;
svr4_ucontext_t
__user
*
uc
;
svr4_sigset_t
setv
;
int
window
=
0
,
err
;
synchronize_user_stack
();
sfp
=
(
svr4_signal_frame_t
*
)
get_sigframe
(
sa
,
regs
,
SVR4_SF_ALIGNED
+
REGWIN_SZ
);
sfp
=
(
svr4_signal_frame_t
__user
*
)
get_sigframe
(
sa
,
regs
,
SVR4_SF_ALIGNED
+
REGWIN_SZ
);
if
(
invalid_frame_pointer
(
sfp
,
sizeof
(
*
sfp
)))
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
));
err
=
__clear_user
(
sfp
,
sizeof
(
*
sfp
));
/* Setup convenience variables */
si
=
&
sfp
->
si
;
...
...
@@ -771,17 +779,20 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
setv
.
sigbits
[
3
]
=
oldset
->
sig
[
3
];
err
|=
__copy_to_user
(
&
uc
->
sigmask
,
&
setv
,
sizeof
(
svr4_sigset_t
));
}
else
err
|=
__copy_to_user
(
&
uc
->
sigmask
,
&
setv
,
2
*
sizeof
(
unsigned
int
));
err
|=
__copy_to_user
(
&
uc
->
sigmask
,
&
setv
,
2
*
sizeof
(
unsigned
int
));
/* Store registers */
err
|=
__put_user
(
regs
->
pc
,
&
((
*
gr
)
[
SVR4_PC
]));
err
|=
__put_user
(
regs
->
npc
,
&
((
*
gr
)
[
SVR4_NPC
]));
err
|=
__put_user
(
regs
->
psr
,
&
((
*
gr
)
[
SVR4_PSR
]));
err
|=
__put_user
(
regs
->
y
,
&
((
*
gr
)
[
SVR4_Y
]));
err
|=
__put_user
(
regs
->
pc
,
&
((
*
gr
)[
SVR4_PC
]));
err
|=
__put_user
(
regs
->
npc
,
&
((
*
gr
)[
SVR4_NPC
]));
err
|=
__put_user
(
regs
->
psr
,
&
((
*
gr
)[
SVR4_PSR
]));
err
|=
__put_user
(
regs
->
y
,
&
((
*
gr
)[
SVR4_Y
]));
/* Copy g [1..7] and o [0..7] registers */
err
|=
__copy_to_user
(
&
(
*
gr
)[
SVR4_G1
],
&
regs
->
u_regs
[
UREG_G1
],
sizeof
(
long
)
*
7
);
err
|=
__copy_to_user
(
&
(
*
gr
)[
SVR4_O0
],
&
regs
->
u_regs
[
UREG_I0
],
sizeof
(
long
)
*
8
);
/* Copy g[1..7] and o[0..7] registers */
err
|=
__copy_to_user
(
&
(
*
gr
)[
SVR4_G1
],
&
regs
->
u_regs
[
UREG_G1
],
sizeof
(
long
)
*
7
);
err
|=
__copy_to_user
(
&
(
*
gr
)[
SVR4_O0
],
&
regs
->
u_regs
[
UREG_I0
],
sizeof
(
long
)
*
8
);
/* Setup sigaltstack */
err
|=
__put_user
(
current
->
sas_ss_sp
,
&
uc
->
stack
.
sp
);
...
...
@@ -793,7 +804,7 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
/* 1. Link sfp->uc->gwins to our windows */
err
|=
__put_user
(
gw
,
&
mc
->
gwin
);
/* 2. Number of windows to restore at setcontext
(): */
/* 2. Number of windows to restore at setcontext(): */
err
|=
__put_user
(
current
->
thread
.
w_saved
,
&
gw
->
count
);
/* 3. Save each valid window
...
...
@@ -807,12 +818,12 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
* These windows are just used in case synchronize_user_stack failed
* to flush the user windows.
*/
for
(
window
=
0
;
window
<
current
->
thread
.
w_saved
;
window
++
)
{
err
|=
__put_user
((
int
*
)
&
(
gw
->
win
[
window
]),
&
gw
->
winptr
[
window
]);
err
|=
__copy_to_user
(
&
gw
->
win
[
window
],
&
current
->
thread
.
reg_window
[
window
],
sizeof
(
svr4_rwindow_t
));
err
|=
__put_user
(
0
,
gw
->
winptr
[
window
]);
for
(
window
=
0
;
window
<
current
->
thread
.
w_saved
;
window
++
)
{
err
|=
__put_user
((
int
*
)
&
(
gw
->
win
[
window
]),
&
gw
->
winptr
[
window
]);
err
|=
__copy_to_user
(
&
gw
->
win
[
window
],
&
current
->
thread
.
reg_window
[
window
],
sizeof
(
svr4_rwindow_t
));
err
|=
__put_user
(
0
,
gw
->
winptr
[
window
]);
}
/* 4. We just pay attention to the gw->count field on setcontext */
...
...
@@ -832,13 +843,14 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs
->
npc
=
(
regs
->
pc
+
4
);
/* Arguments passed to signal handler */
if
(
regs
->
u_regs
[
14
]){
struct
reg_window
*
rw
=
(
struct
reg_window
*
)
regs
->
u_regs
[
14
];
err
|=
__put_user
(
signr
,
&
rw
->
ins
[
0
]);
err
|=
__put_user
(
si
,
&
rw
->
ins
[
1
]);
err
|=
__put_user
(
uc
,
&
rw
->
ins
[
2
]);
err
|=
__put_user
(
sfp
,
&
rw
->
ins
[
6
]);
/* frame pointer */
if
(
regs
->
u_regs
[
14
]){
struct
reg_window
*
rw
=
(
struct
reg_window
__user
*
)
regs
->
u_regs
[
14
];
err
|=
__put_user
(
signr
,
&
rw
->
ins
[
0
]);
err
|=
__put_user
(
si
,
&
rw
->
ins
[
1
]);
err
|=
__put_user
(
uc
,
&
rw
->
ins
[
2
]);
err
|=
__put_user
(
sfp
,
&
rw
->
ins
[
6
]);
/* frame pointer */
if
(
err
)
goto
sigsegv
;
...
...
@@ -854,10 +866,10 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
do_exit
(
SIGSEGV
);
}
asmlinkage
int
svr4_getcontext
(
svr4_ucontext_t
*
uc
,
struct
pt_regs
*
regs
)
asmlinkage
int
svr4_getcontext
(
svr4_ucontext_t
__user
*
uc
,
struct
pt_regs
*
regs
)
{
svr4_gregset_t
*
gr
;
svr4_mcontext_t
*
mc
;
svr4_gregset_t
__user
*
gr
;
svr4_mcontext_t
__user
*
mc
;
svr4_sigset_t
setv
;
int
err
=
0
;
...
...
@@ -866,7 +878,7 @@ asmlinkage int svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs)
if
(
current
->
thread
.
w_saved
)
goto
sigsegv_and_return
;
err
=
clear_user
(
uc
,
sizeof
(
*
uc
));
err
=
clear_user
(
uc
,
sizeof
(
*
uc
));
if
(
err
)
return
-
EFAULT
;
...
...
@@ -881,17 +893,20 @@ asmlinkage int svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs)
setv
.
sigbits
[
3
]
=
current
->
blocked
.
sig
[
3
];
err
|=
__copy_to_user
(
&
uc
->
sigmask
,
&
setv
,
sizeof
(
svr4_sigset_t
));
}
else
err
|=
__copy_to_user
(
&
uc
->
sigmask
,
&
setv
,
2
*
sizeof
(
unsigned
int
));
err
|=
__copy_to_user
(
&
uc
->
sigmask
,
&
setv
,
2
*
sizeof
(
unsigned
int
));
/* Store registers */
err
|=
__put_user
(
regs
->
pc
,
&
uc
->
mcontext
.
greg
[
SVR4_PC
]);
err
|=
__put_user
(
regs
->
npc
,
&
uc
->
mcontext
.
greg
[
SVR4_NPC
]);
err
|=
__put_user
(
regs
->
psr
,
&
uc
->
mcontext
.
greg
[
SVR4_PSR
]);
err
|=
__put_user
(
regs
->
y
,
&
uc
->
mcontext
.
greg
[
SVR4_Y
]);
err
|=
__put_user
(
regs
->
pc
,
&
uc
->
mcontext
.
greg
[
SVR4_PC
]);
err
|=
__put_user
(
regs
->
npc
,
&
uc
->
mcontext
.
greg
[
SVR4_NPC
]);
err
|=
__put_user
(
regs
->
psr
,
&
uc
->
mcontext
.
greg
[
SVR4_PSR
]);
err
|=
__put_user
(
regs
->
y
,
&
uc
->
mcontext
.
greg
[
SVR4_Y
]);
/* Copy g [1..7] and o [0..7] registers */
err
|=
__copy_to_user
(
&
(
*
gr
)[
SVR4_G1
],
&
regs
->
u_regs
[
UREG_G1
],
sizeof
(
uint
)
*
7
);
err
|=
__copy_to_user
(
&
(
*
gr
)[
SVR4_O0
],
&
regs
->
u_regs
[
UREG_I0
],
sizeof
(
uint
)
*
8
);
/* Copy g[1..7] and o[0..7] registers */
err
|=
__copy_to_user
(
&
(
*
gr
)[
SVR4_G1
],
&
regs
->
u_regs
[
UREG_G1
],
sizeof
(
uint
)
*
7
);
err
|=
__copy_to_user
(
&
(
*
gr
)[
SVR4_O0
],
&
regs
->
u_regs
[
UREG_I0
],
sizeof
(
uint
)
*
8
);
/* Setup sigaltstack */
err
|=
__put_user
(
current
->
sas_ss_sp
,
&
uc
->
stack
.
sp
);
...
...
@@ -908,10 +923,10 @@ asmlinkage int svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs)
}
/* Set the context for a svr4 application, this is Solaris way to sigreturn */
asmlinkage
int
svr4_setcontext
(
svr4_ucontext_t
*
c
,
struct
pt_regs
*
regs
)
asmlinkage
int
svr4_setcontext
(
svr4_ucontext_t
__user
*
c
,
struct
pt_regs
*
regs
)
{
struct
thread_struct
*
tp
=
&
current
->
thread
;
svr4_gregset_t
*
gr
;
svr4_gregset_t
__user
*
gr
;
unsigned
long
pc
,
npc
,
psr
;
sigset_t
set
;
svr4_sigset_t
setv
;
...
...
@@ -929,7 +944,7 @@ asmlinkage int svr4_setcontext (svr4_ucontext_t *c, struct pt_regs *regs)
if
(((
uint
)
c
)
&
3
)
goto
sigsegv_and_return
;
if
(
!
__access_ok
((
unsigned
long
)
c
,
sizeof
(
*
c
)))
if
(
!
__access_ok
((
unsigned
long
)
c
,
sizeof
(
*
c
)))
goto
sigsegv_and_return
;
/* Check for valid PC and nPC */
...
...
@@ -937,7 +952,7 @@ asmlinkage int svr4_setcontext (svr4_ucontext_t *c, struct pt_regs *regs)
err
=
__get_user
(
pc
,
&
((
*
gr
)[
SVR4_PC
]));
err
|=
__get_user
(
npc
,
&
((
*
gr
)[
SVR4_NPC
]));
if
((
pc
|
npc
)
&
3
)
if
((
pc
|
npc
)
&
3
)
goto
sigsegv_and_return
;
/* Retrieve information from passed ucontext */
...
...
@@ -973,16 +988,16 @@ asmlinkage int svr4_setcontext (svr4_ucontext_t *c, struct pt_regs *regs)
spin_unlock_irq
(
&
current
->
sighand
->
siglock
);
regs
->
pc
=
pc
;
regs
->
npc
=
npc
|
1
;
err
|=
__get_user
(
regs
->
y
,
&
((
*
gr
)
[
SVR4_Y
]));
err
|=
__get_user
(
psr
,
&
((
*
gr
)
[
SVR4_PSR
]));
err
|=
__get_user
(
regs
->
y
,
&
((
*
gr
)[
SVR4_Y
]));
err
|=
__get_user
(
psr
,
&
((
*
gr
)[
SVR4_PSR
]));
regs
->
psr
&=
~
(
PSR_ICC
);
regs
->
psr
|=
(
psr
&
PSR_ICC
);
/* Restore g[1..7] and o[0..7] registers */
err
|=
__copy_from_user
(
&
regs
->
u_regs
[
UREG_G1
],
&
(
*
gr
)[
SVR4_G1
],
sizeof
(
long
)
*
7
);
err
|=
__copy_from_user
(
&
regs
->
u_regs
[
UREG_I0
],
&
(
*
gr
)[
SVR4_O0
],
sizeof
(
long
)
*
8
);
err
|=
__copy_from_user
(
&
regs
->
u_regs
[
UREG_G1
],
&
(
*
gr
)[
SVR4_G1
],
sizeof
(
long
)
*
7
);
err
|=
__copy_from_user
(
&
regs
->
u_regs
[
UREG_I0
],
&
(
*
gr
)[
SVR4_O0
],
sizeof
(
long
)
*
8
);
return
(
err
?
-
EFAULT
:
0
);
sigsegv_and_return:
...
...
@@ -1000,13 +1015,13 @@ handle_signal(unsigned long signr, struct k_sigaction *ka,
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
new_setup_rt_frame
(
ka
,
regs
,
signr
,
oldset
,
info
);
else
if
(
current
->
thread
.
new_signal
)
new_setup_frame
(
ka
,
regs
,
signr
,
oldset
);
new_setup_frame
(
ka
,
regs
,
signr
,
oldset
);
else
setup_frame
(
&
ka
->
sa
,
regs
,
signr
,
oldset
,
info
);
}
if
(
ka
->
sa
.
sa_flags
&
SA_ONESHOT
)
if
(
ka
->
sa
.
sa_flags
&
SA_ONESHOT
)
ka
->
sa
.
sa_handler
=
SIG_DFL
;
if
(
!
(
ka
->
sa
.
sa_flags
&
SA_NOMASK
))
{
if
(
!
(
ka
->
sa
.
sa_flags
&
SA_NOMASK
))
{
spin_lock_irq
(
&
current
->
sighand
->
siglock
);
sigorsets
(
&
current
->
blocked
,
&
current
->
blocked
,
&
ka
->
sa
.
sa_mask
);
sigaddset
(
&
current
->
blocked
,
signr
);
...
...
@@ -1028,7 +1043,7 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
regs
->
psr
|=
PSR_C
;
break
;
case
ERESTARTSYS
:
if
(
!
(
sa
->
sa_flags
&
SA_RESTART
))
if
(
!
(
sa
->
sa_flags
&
SA_RESTART
))
goto
no_system_call_restart
;
/* fallthrough */
case
ERESTARTNOINTR
:
...
...
@@ -1095,13 +1110,15 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
}
asmlinkage
int
do_sys_sigstack
(
struct
sigstack
*
ssptr
,
struct
sigstack
*
ossptr
,
unsigned
long
sp
)
do_sys_sigstack
(
struct
sigstack
__user
*
ssptr
,
struct
sigstack
__user
*
ossptr
,
unsigned
long
sp
)
{
int
ret
=
-
EFAULT
;
/* First see if old state is wanted. */
if
(
ossptr
)
{
if
(
put_user
(
current
->
sas_ss_sp
+
current
->
sas_ss_size
,
&
ossptr
->
the_stack
)
||
if
(
put_user
(
current
->
sas_ss_sp
+
current
->
sas_ss_size
,
&
ossptr
->
the_stack
)
||
__put_user
(
on_sig_stack
(
sp
),
&
ossptr
->
cur_status
))
goto
out
;
}
...
...
arch/sparc/kernel/sys_sparc.c
View file @
a0e3315d
...
...
@@ -113,7 +113,7 @@ asmlinkage int sparc_pipe(struct pt_regs *regs)
* This is really horribly ugly.
*/
asmlinkage
int
sys_ipc
(
uint
call
,
int
first
,
int
second
,
int
third
,
void
*
ptr
,
long
fifth
)
asmlinkage
int
sys_ipc
(
uint
call
,
int
first
,
int
second
,
int
third
,
void
__user
*
ptr
,
long
fifth
)
{
int
version
,
err
;
...
...
@@ -123,7 +123,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
if
(
call
<=
SEMCTL
)
switch
(
call
)
{
case
SEMOP
:
err
=
sys_semop
(
first
,
(
struct
sembuf
*
)
ptr
,
second
);
err
=
sys_semop
(
first
,
(
struct
sembuf
__user
*
)
ptr
,
second
);
goto
out
;
case
SEMGET
:
err
=
sys_semget
(
first
,
second
,
third
);
...
...
@@ -134,7 +134,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
if
(
!
ptr
)
goto
out
;
err
=
-
EFAULT
;
if
(
get_user
(
fourth
.
__pad
,
(
void
**
)
ptr
))
if
(
get_user
(
fourth
.
__pad
,
(
void
__user
**
)
ptr
))
goto
out
;
err
=
sys_semctl
(
first
,
second
,
third
,
fourth
);
goto
out
;
...
...
@@ -146,7 +146,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
if
(
call
<=
MSGCTL
)
switch
(
call
)
{
case
MSGSND
:
err
=
sys_msgsnd
(
first
,
(
struct
msgbuf
*
)
ptr
,
err
=
sys_msgsnd
(
first
,
(
struct
msgbuf
__user
*
)
ptr
,
second
,
third
);
goto
out
;
case
MSGRCV
:
...
...
@@ -157,7 +157,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
if
(
!
ptr
)
goto
out
;
err
=
-
EFAULT
;
if
(
copy_from_user
(
&
tmp
,(
struct
ipc_kludge
*
)
ptr
,
sizeof
(
tmp
)))
if
(
copy_from_user
(
&
tmp
,
(
struct
ipc_kludge
__user
*
)
ptr
,
sizeof
(
tmp
)))
goto
out
;
err
=
sys_msgrcv
(
first
,
tmp
.
msgp
,
second
,
tmp
.
msgtyp
,
third
);
goto
out
;
...
...
@@ -170,7 +170,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
err
=
sys_msgget
((
key_t
)
first
,
second
);
goto
out
;
case
MSGCTL
:
err
=
sys_msgctl
(
first
,
second
,
(
struct
msqid_ds
*
)
ptr
);
err
=
sys_msgctl
(
first
,
second
,
(
struct
msqid_ds
__user
*
)
ptr
);
goto
out
;
default:
err
=
-
ENOSYS
;
...
...
@@ -182,27 +182,27 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
switch
(
version
)
{
case
0
:
default
:
{
ulong
raddr
;
err
=
sys_shmat
(
first
,
(
char
*
)
ptr
,
second
,
&
raddr
);
err
=
sys_shmat
(
first
,
(
char
__user
*
)
ptr
,
second
,
&
raddr
);
if
(
err
)
goto
out
;
err
=
-
EFAULT
;
if
(
put_user
(
raddr
,
(
ulong
*
)
third
))
if
(
put_user
(
raddr
,
(
ulong
__user
*
)
third
))
goto
out
;
err
=
0
;
goto
out
;
}
case
1
:
/* iBCS2 emulator entry point */
err
=
sys_shmat
(
first
,
(
char
*
)
ptr
,
second
,
(
ulong
*
)
third
);
err
=
sys_shmat
(
first
,
(
char
__user
*
)
ptr
,
second
,
(
ulong
__user
*
)
third
);
goto
out
;
}
case
SHMDT
:
err
=
sys_shmdt
((
char
*
)
ptr
);
err
=
sys_shmdt
((
char
__user
*
)
ptr
);
goto
out
;
case
SHMGET
:
err
=
sys_shmget
(
first
,
second
,
third
);
goto
out
;
case
SHMCTL
:
err
=
sys_shmctl
(
first
,
second
,
(
struct
shmid_ds
*
)
ptr
);
err
=
sys_shmctl
(
first
,
second
,
(
struct
shmid_ds
__user
*
)
ptr
);
goto
out
;
default:
err
=
-
ENOSYS
;
...
...
@@ -344,9 +344,11 @@ asmlinkage unsigned long
c_sys_nis_syscall
(
struct
pt_regs
*
regs
)
{
static
int
count
=
0
;
if
(
count
++
>
5
)
return
-
ENOSYS
;
printk
(
"%s[%d]: Unimplemented SPARC system call %d
\n
"
,
current
->
comm
,
current
->
pid
,
(
int
)
regs
->
u_regs
[
1
]);
if
(
count
++
>
5
)
return
-
ENOSYS
;
printk
(
"%s[%d]: Unimplemented SPARC system call %d
\n
"
,
current
->
comm
,
current
->
pid
,
(
int
)
regs
->
u_regs
[
1
]);
#ifdef DEBUG_UNIMP_SYSCALL
show_regs
(
regs
);
#endif
...
...
@@ -378,8 +380,8 @@ sparc_breakpoint (struct pt_regs *regs)
}
asmlinkage
int
sparc_sigaction
(
int
sig
,
const
struct
old_sigaction
*
act
,
struct
old_sigaction
*
oact
)
sparc_sigaction
(
int
sig
,
const
struct
old_sigaction
__user
*
act
,
struct
old_sigaction
__user
*
oact
)
{
struct
k_sigaction
new_ka
,
old_ka
;
int
ret
;
...
...
@@ -422,8 +424,11 @@ sparc_sigaction (int sig, const struct old_sigaction *act,
}
asmlinkage
int
sys_rt_sigaction
(
int
sig
,
const
struct
sigaction
*
act
,
struct
sigaction
*
oact
,
void
*
restorer
,
size_t
sigsetsize
)
sys_rt_sigaction
(
int
sig
,
const
struct
sigaction
__user
*
act
,
struct
sigaction
__user
*
oact
,
void
__user
*
restorer
,
size_t
sigsetsize
)
{
struct
k_sigaction
new_ka
,
old_ka
;
int
ret
;
...
...
@@ -453,7 +458,7 @@ sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact,
return
ret
;
}
asmlinkage
int
sys_getdomainname
(
char
*
name
,
int
len
)
asmlinkage
int
sys_getdomainname
(
char
__user
*
name
,
int
len
)
{
int
nlen
;
int
err
=
-
EFAULT
;
...
...
@@ -464,9 +469,9 @@ asmlinkage int sys_getdomainname(char *name, int len)
if
(
nlen
<
len
)
len
=
nlen
;
if
(
len
>
__NEW_UTS_LEN
)
if
(
len
>
__NEW_UTS_LEN
)
goto
done
;
if
(
copy_to_user
(
name
,
system_utsname
.
domainname
,
len
))
if
(
copy_to_user
(
name
,
system_utsname
.
domainname
,
len
))
goto
done
;
err
=
0
;
done:
...
...
arch/sparc64/kernel/ioctl32.c
View file @
a0e3315d
...
...
@@ -107,15 +107,9 @@
#include <linux/filter.h>
/* Use this to get at 32-bit user passed pointers.
See sys_sparc32.c for description about these. */
#define A(__x) ((unsigned long)(__x))
#define AA(__x) \
({ unsigned long __ret; \
__asm__ ("srl %0, 0, %0" \
: "=r" (__ret) \
: "0" (__x)); \
__ret; \
})
* See sys_sparc32.c for description about it.
*/
#define A(__x) ((void __user *)(unsigned long)(__x))
/* Aiee. Someone does not find a difference between int and long */
#define EXT2_IOC32_GETFLAGS _IOR('f', 1, int)
...
...
@@ -261,7 +255,7 @@ static void free_kvideo_clips(struct video_window *kp)
static
int
get_video_window32
(
struct
video_window
*
kp
,
struct
video_window32
*
up
)
{
struct
video_clip32
*
ucp
;
struct
video_clip32
__user
*
ucp
;
struct
video_clip
*
kcp
;
int
nclips
,
err
,
i
;
u32
tmp
;
...
...
@@ -275,7 +269,7 @@ static int get_video_window32(struct video_window *kp, struct video_window32 *up
__get_user
(
kp
->
flags
,
&
up
->
flags
);
__get_user
(
kp
->
clipcount
,
&
up
->
clipcount
);
__get_user
(
tmp
,
&
up
->
clips
);
ucp
=
(
struct
video_clip32
*
)
A
(
tmp
);
ucp
=
A
(
tmp
);
kp
->
clips
=
NULL
;
nclips
=
kp
->
clipcount
;
...
...
@@ -487,7 +481,7 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct
ifconf32
ifc32
;
struct
ifconf
ifc
;
struct
ifreq32
*
ifr32
;
struct
ifreq32
__user
*
ifr32
;
struct
ifreq
*
ifr
;
mm_segment_t
old_fs
;
unsigned
int
i
,
j
;
...
...
@@ -508,7 +502,7 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
return
-
ENOMEM
;
}
ifr
=
ifc
.
ifc_req
;
ifr32
=
(
struct
ifreq32
*
)
A
(
ifc32
.
ifcbuf
);
ifr32
=
A
(
ifc32
.
ifcbuf
);
for
(
i
=
0
;
i
<
ifc32
.
ifc_len
;
i
+=
sizeof
(
struct
ifreq32
))
{
if
(
copy_from_user
(
ifr
++
,
ifr32
++
,
sizeof
(
struct
ifreq32
)))
{
kfree
(
ifc
.
ifc_buf
);
...
...
@@ -520,7 +514,7 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
set_fs
(
old_fs
);
if
(
!
err
)
{
ifr
=
ifc
.
ifc_req
;
ifr32
=
(
struct
ifreq32
*
)
A
(
ifc32
.
ifcbuf
);
ifr32
=
A
(
ifc32
.
ifcbuf
);
for
(
i
=
0
,
j
=
0
;
i
<
ifc32
.
ifc_len
&&
j
<
ifc
.
ifc_len
;
i
+=
sizeof
(
struct
ifreq32
),
j
+=
sizeof
(
struct
ifreq
))
{
if
(
copy_to_user
(
ifr32
++
,
ifr
++
,
sizeof
(
struct
ifreq32
)))
{
...
...
@@ -566,7 +560,7 @@ static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
__get_user
(
data
,
&
(((
struct
ifreq32
*
)
arg
)
->
ifr_ifru
.
ifru_data
));
if
(
get_user
(
ethcmd
,
(
u32
*
)
A
(
data
)))
{
if
(
get_user
(
ethcmd
,
(
u32
__user
*
)
A
(
data
)))
{
err
=
-
EFAULT
;
goto
out
;
}
...
...
@@ -577,7 +571,7 @@ static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
case
ETHTOOL_GLINK
:
case
ETHTOOL_NWAY_RST
:
len
=
sizeof
(
struct
ethtool_value
);
break
;
case
ETHTOOL_GREGS
:
{
struct
ethtool_regs
*
regaddr
=
(
struct
ethtool_regs
*
)
A
(
data
);
struct
ethtool_regs
__user
*
regaddr
=
A
(
data
);
/* darned variable size arguments */
if
(
get_user
(
len
,
(
u32
*
)
&
regaddr
->
len
))
{
err
=
-
EFAULT
;
...
...
@@ -593,7 +587,7 @@ static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
goto
out
;
}
if
(
copy_from_user
(
ifr
.
ifr_data
,
(
char
*
)
A
(
data
),
len
))
{
if
(
copy_from_user
(
ifr
.
ifr_data
,
A
(
data
),
len
))
{
err
=
-
EFAULT
;
goto
out
;
}
...
...
@@ -606,7 +600,7 @@ static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
u32
data
;
__get_user
(
data
,
&
(((
struct
ifreq32
*
)
arg
)
->
ifr_ifru
.
ifru_data
));
len
=
copy_to_user
(
(
char
*
)
A
(
data
),
ifr
.
ifr_data
,
len
);
len
=
copy_to_user
(
A
(
data
),
ifr
.
ifr_data
,
len
);
if
(
len
)
err
=
-
EFAULT
;
}
...
...
@@ -648,7 +642,7 @@ static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg)
};
__get_user
(
data
,
&
(((
struct
ifreq32
*
)
arg
)
->
ifr_ifru
.
ifru_data
));
if
(
copy_from_user
(
ifr
.
ifr_data
,
(
char
*
)
A
(
data
),
len
))
{
if
(
copy_from_user
(
ifr
.
ifr_data
,
A
(
data
),
len
))
{
err
=
-
EFAULT
;
goto
out
;
}
...
...
@@ -658,7 +652,7 @@ static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg)
err
=
sys_ioctl
(
fd
,
cmd
,
(
unsigned
long
)
&
ifr
);
set_fs
(
old_fs
);
if
(
!
err
)
{
len
=
copy_to_user
(
(
char
*
)
A
(
data
),
ifr
.
ifr_data
,
len
);
len
=
copy_to_user
(
A
(
data
),
ifr
.
ifr_data
,
len
);
if
(
len
)
err
=
-
EFAULT
;
}
...
...
@@ -684,7 +678,7 @@ static int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long
struct
ifreq
*
u_ifreq64
;
struct
ifreq32
*
u_ifreq32
=
(
struct
ifreq32
*
)
arg
;
char
tmp_buf
[
IFNAMSIZ
];
void
*
data64
;
void
__user
*
data64
;
u32
data32
;
if
(
copy_from_user
(
&
tmp_buf
[
0
],
&
(
u_ifreq32
->
ifr_ifrn
.
ifrn_name
[
0
]),
...
...
@@ -692,7 +686,7 @@ static int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long
return
-
EFAULT
;
if
(
__get_user
(
data32
,
&
u_ifreq32
->
ifr_ifru
.
ifru_data
))
return
-
EFAULT
;
data64
=
(
void
*
)
A
(
data32
);
data64
=
A
(
data32
);
u_ifreq64
=
alloc_user_space
(
sizeof
(
*
u_ifreq64
));
...
...
@@ -829,7 +823,7 @@ static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
ret
|=
__get_user
(
r4
.
rt_irtt
,
&
(((
struct
rtentry32
*
)
arg
)
->
rt_irtt
));
ret
|=
__get_user
(
rtdev
,
&
(((
struct
rtentry32
*
)
arg
)
->
rt_dev
));
if
(
rtdev
)
{
ret
|=
copy_from_user
(
devname
,
(
char
*
)
A
(
rtdev
),
15
);
ret
|=
copy_from_user
(
devname
,
A
(
rtdev
),
15
);
r4
.
rt_dev
=
devname
;
devname
[
15
]
=
0
;
}
else
r4
.
rt_dev
=
0
;
...
...
@@ -932,9 +926,9 @@ static int fbiogetputcmap(unsigned int fd, unsigned int cmd, unsigned long arg)
if
(
f
.
index
+
f
.
count
>
256
)
f
.
count
=
256
-
f
.
index
;
if
(
cmd
==
FBIOPUTCMAP32
)
{
ret
=
copy_from_user
(
red
,
(
char
*
)
A
(
r
),
f
.
count
);
ret
|=
copy_from_user
(
green
,
(
char
*
)
A
(
g
),
f
.
count
);
ret
|=
copy_from_user
(
blue
,
(
char
*
)
A
(
b
),
f
.
count
);
ret
=
copy_from_user
(
red
,
A
(
r
),
f
.
count
);
ret
|=
copy_from_user
(
green
,
A
(
g
),
f
.
count
);
ret
|=
copy_from_user
(
blue
,
A
(
b
),
f
.
count
);
if
(
ret
)
return
-
EFAULT
;
}
...
...
@@ -943,9 +937,9 @@ static int fbiogetputcmap(unsigned int fd, unsigned int cmd, unsigned long arg)
ret
=
sys_ioctl
(
fd
,
(
cmd
==
FBIOPUTCMAP32
)
?
FBIOPUTCMAP_SPARC
:
FBIOGETCMAP_SPARC
,
(
long
)
&
f
);
set_fs
(
old_fs
);
if
(
!
ret
&&
cmd
==
FBIOGETCMAP32
)
{
ret
=
copy_to_user
(
(
char
*
)
A
(
r
),
red
,
f
.
count
);
ret
|=
copy_to_user
(
(
char
*
)
A
(
g
),
green
,
f
.
count
);
ret
|=
copy_to_user
(
(
char
*
)
A
(
b
),
blue
,
f
.
count
);
ret
=
copy_to_user
(
A
(
r
),
red
,
f
.
count
);
ret
|=
copy_to_user
(
A
(
g
),
green
,
f
.
count
);
ret
|=
copy_to_user
(
A
(
b
),
blue
,
f
.
count
);
}
return
ret
?
-
EFAULT
:
0
;
}
...
...
@@ -989,16 +983,16 @@ static int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg)
if
(
f
.
set
&
FB_CUR_SETCMAP
)
{
if
((
uint
)
f
.
size
.
y
>
32
)
return
-
EINVAL
;
ret
=
copy_from_user
(
mask
,
(
char
*
)
A
(
m
),
f
.
size
.
y
*
4
);
ret
|=
copy_from_user
(
image
,
(
char
*
)
A
(
i
),
f
.
size
.
y
*
4
);
ret
=
copy_from_user
(
mask
,
A
(
m
),
f
.
size
.
y
*
4
);
ret
|=
copy_from_user
(
image
,
A
(
i
),
f
.
size
.
y
*
4
);
if
(
ret
)
return
-
EFAULT
;
f
.
image
=
image
;
f
.
mask
=
mask
;
}
if
(
f
.
set
&
FB_CUR_SETCMAP
)
{
ret
=
copy_from_user
(
red
,
(
char
*
)
A
(
r
),
2
);
ret
|=
copy_from_user
(
green
,
(
char
*
)
A
(
g
),
2
);
ret
|=
copy_from_user
(
blue
,
(
char
*
)
A
(
b
),
2
);
ret
=
copy_from_user
(
red
,
A
(
r
),
2
);
ret
|=
copy_from_user
(
green
,
A
(
g
),
2
);
ret
|=
copy_from_user
(
blue
,
A
(
b
),
2
);
if
(
ret
)
return
-
EFAULT
;
f
.
cmap
.
red
=
red
;
f
.
cmap
.
green
=
green
;
f
.
cmap
.
blue
=
blue
;
...
...
@@ -1081,10 +1075,10 @@ static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
if
(
cmd
==
FBIOGETCMAP
)
break
;
err
=
__copy_from_user
(
cmap
.
red
,
(
char
*
)
A
(
red
),
cmap
.
len
*
sizeof
(
__u16
));
err
|=
__copy_from_user
(
cmap
.
green
,
(
char
*
)
A
(
green
),
cmap
.
len
*
sizeof
(
__u16
));
err
|=
__copy_from_user
(
cmap
.
blue
,
(
char
*
)
A
(
blue
),
cmap
.
len
*
sizeof
(
__u16
));
if
(
cmap
.
transp
)
err
|=
__copy_from_user
(
cmap
.
transp
,
(
char
*
)
A
(
transp
),
cmap
.
len
*
sizeof
(
__u16
));
err
=
__copy_from_user
(
cmap
.
red
,
A
(
red
),
cmap
.
len
*
sizeof
(
__u16
));
err
|=
__copy_from_user
(
cmap
.
green
,
A
(
green
),
cmap
.
len
*
sizeof
(
__u16
));
err
|=
__copy_from_user
(
cmap
.
blue
,
A
(
blue
),
cmap
.
len
*
sizeof
(
__u16
));
if
(
cmap
.
transp
)
err
|=
__copy_from_user
(
cmap
.
transp
,
A
(
transp
),
cmap
.
len
*
sizeof
(
__u16
));
if
(
err
)
{
err
=
-
EFAULT
;
goto
out
;
...
...
@@ -1123,11 +1117,11 @@ static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
err
|=
__copy_to_user
((
char
*
)((
struct
fb_fix_screeninfo32
*
)
arg
)
->
reserved
,
(
char
*
)
fix
.
reserved
,
sizeof
(
fix
.
reserved
));
break
;
case
FBIOGETCMAP
:
err
=
__copy_to_user
(
(
char
*
)
A
(
red
),
cmap
.
red
,
cmap
.
len
*
sizeof
(
__u16
));
err
|=
__copy_to_user
(
(
char
*
)
A
(
green
),
cmap
.
blue
,
cmap
.
len
*
sizeof
(
__u16
));
err
|=
__copy_to_user
(
(
char
*
)
A
(
blue
),
cmap
.
blue
,
cmap
.
len
*
sizeof
(
__u16
));
err
=
__copy_to_user
(
A
(
red
),
cmap
.
red
,
cmap
.
len
*
sizeof
(
__u16
));
err
|=
__copy_to_user
(
A
(
green
),
cmap
.
blue
,
cmap
.
len
*
sizeof
(
__u16
));
err
|=
__copy_to_user
(
A
(
blue
),
cmap
.
blue
,
cmap
.
len
*
sizeof
(
__u16
));
if
(
cmap
.
transp
)
err
|=
__copy_to_user
(
(
char
*
)
A
(
transp
),
cmap
.
transp
,
cmap
.
len
*
sizeof
(
__u16
));
err
|=
__copy_to_user
(
A
(
transp
),
cmap
.
transp
,
cmap
.
len
*
sizeof
(
__u16
));
break
;
case
FBIOPUTCMAP
:
break
;
...
...
@@ -1504,7 +1498,7 @@ typedef struct sg_iovec32 {
static
int
alloc_sg_iovec
(
sg_io_hdr_t
*
sgp
,
u32
uptr32
)
{
sg_iovec32_t
*
uiov
=
(
sg_iovec32_t
*
)
A
(
uptr32
);
sg_iovec32_t
__user
*
uiov
=
A
(
uptr32
);
sg_iovec_t
*
kiov
;
int
i
;
...
...
@@ -1526,7 +1520,7 @@ static int alloc_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
if
(
!
kiov
->
iov_base
)
return
-
ENOMEM
;
if
(
copy_from_user
(
kiov
->
iov_base
,
(
void
*
)
A
(
iov_base32
),
A
(
iov_base32
),
kiov
->
iov_len
))
return
-
EFAULT
;
...
...
@@ -1539,7 +1533,7 @@ static int alloc_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
static
int
copy_back_sg_iovec
(
sg_io_hdr_t
*
sgp
,
u32
uptr32
)
{
sg_iovec32_t
*
uiov
=
(
sg_iovec32_t
*
)
A
(
uptr32
);
sg_iovec32_t
__user
*
uiov
=
A
(
uptr32
);
sg_iovec_t
*
kiov
=
(
sg_iovec_t
*
)
sgp
->
dxferp
;
int
i
;
...
...
@@ -1549,7 +1543,7 @@ static int copy_back_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
if
(
__get_user
(
iov_base32
,
&
uiov
->
iov_base
))
return
-
EFAULT
;
if
(
copy_to_user
(
(
void
*
)
A
(
iov_base32
),
if
(
copy_to_user
(
A
(
iov_base32
),
kiov
->
iov_base
,
kiov
->
iov_len
))
return
-
EFAULT
;
...
...
@@ -1607,7 +1601,7 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
goto
out
;
}
if
(
copy_from_user
(
sg_io64
.
cmdp
,
(
void
*
)
A
(
cmdp32
),
A
(
cmdp32
),
sg_io64
.
cmd_len
))
{
err
=
-
EFAULT
;
goto
out
;
...
...
@@ -1620,7 +1614,7 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
goto
out
;
}
if
(
copy_from_user
(
sg_io64
.
sbp
,
(
void
*
)
A
(
sbp32
),
A
(
sbp32
),
sg_io64
.
mx_sb_len
))
{
err
=
-
EFAULT
;
goto
out
;
...
...
@@ -1641,7 +1635,7 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
goto
out
;
}
if
(
copy_from_user
(
sg_io64
.
dxferp
,
(
void
*
)
A
(
dxferp32
),
A
(
dxferp32
),
sg_io64
.
dxfer_len
))
{
err
=
-
EFAULT
;
goto
out
;
...
...
@@ -1672,12 +1666,12 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
err
|=
__put_user
(
sg_io64
.
resid
,
&
sg_io32
->
resid
);
err
|=
__put_user
(
sg_io64
.
duration
,
&
sg_io32
->
duration
);
err
|=
__put_user
(
sg_io64
.
info
,
&
sg_io32
->
info
);
err
|=
copy_to_user
(
(
void
*
)
A
(
sbp32
),
sg_io64
.
sbp
,
sg_io64
.
mx_sb_len
);
err
|=
copy_to_user
(
A
(
sbp32
),
sg_io64
.
sbp
,
sg_io64
.
mx_sb_len
);
if
(
sg_io64
.
dxferp
)
{
if
(
sg_io64
.
iovec_count
)
err
|=
copy_back_sg_iovec
(
&
sg_io64
,
dxferp32
);
else
err
|=
copy_to_user
(
(
void
*
)
A
(
dxferp32
),
err
|=
copy_to_user
(
A
(
dxferp32
),
sg_io64
.
dxferp
,
sg_io64
.
dxfer_len
);
}
...
...
@@ -1711,7 +1705,7 @@ static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd, unsigne
{
struct
sock_fprog32
*
u_fprog32
=
(
struct
sock_fprog32
*
)
arg
;
struct
sock_fprog
*
u_fprog64
=
alloc_user_space
(
sizeof
(
struct
sock_fprog
));
void
*
fptr64
;
void
__user
*
fptr64
;
u32
fptr32
;
u16
flen
;
...
...
@@ -1719,7 +1713,7 @@ static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd, unsigne
get_user
(
fptr32
,
&
u_fprog32
->
filter
))
return
-
EFAULT
;
fptr64
=
(
void
*
)
A
(
fptr32
);
fptr64
=
A
(
fptr32
);
if
(
put_user
(
flen
,
&
u_fprog64
->
len
)
||
put_user
(
fptr64
,
&
u_fprog64
->
filter
))
...
...
@@ -1768,7 +1762,7 @@ static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
data
.
ptr
=
kmalloc
(
data32
.
length
,
GFP_KERNEL
);
if
(
!
data
.
ptr
)
return
-
ENOMEM
;
if
(
copy_from_user
(
data
.
ptr
,
(
__u8
*
)
A
(
data32
.
ptr
),
data32
.
length
))
{
if
(
copy_from_user
(
data
.
ptr
,
A
(
data32
.
ptr
),
data32
.
length
))
{
kfree
(
data
.
ptr
);
return
-
EFAULT
;
}
...
...
@@ -2025,13 +2019,13 @@ static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar
case
CDROMREADMODE1
:
case
CDROMREADRAW
:
case
CDROMREADCOOKED
:
err
=
copy_to_user
(
(
char
*
)
A
(
addr
),
data
,
cdread
.
cdread_buflen
);
err
=
copy_to_user
(
A
(
addr
),
data
,
cdread
.
cdread_buflen
);
break
;
case
CDROMREADAUDIO
:
err
=
copy_to_user
(
(
char
*
)
A
(
addr
),
data
,
cdreadaudio
.
nframes
*
2352
);
err
=
copy_to_user
(
A
(
addr
),
data
,
cdreadaudio
.
nframes
*
2352
);
break
;
case
CDROM_SEND_PACKET
:
err
=
copy_to_user
(
(
char
*
)
A
(
addr
),
data
,
cgc
.
buflen
);
err
=
copy_to_user
(
A
(
addr
),
data
,
cgc
.
buflen
);
break
;
default:
break
;
...
...
@@ -2148,7 +2142,7 @@ static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *us
if
(
copy_from_user
(
&
cfdarg
,
user_cfd
,
sizeof
(
struct
consolefontdesc32
)))
return
-
EFAULT
;
cfdarg
.
chardata
=
(
unsigned
char
*
)
A
(((
struct
consolefontdesc32
*
)
&
cfdarg
)
->
chardata
);
cfdarg
.
chardata
=
A
(((
struct
consolefontdesc32
*
)
&
cfdarg
)
->
chardata
);
switch
(
cmd
)
{
case
PIO_FONTX
:
...
...
@@ -2203,7 +2197,7 @@ static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_f
return
-
EFAULT
;
if
(
!
perm
&&
op
.
op
!=
KD_FONT_OP_GET
)
return
-
EPERM
;
op
.
data
=
(
unsigned
char
*
)
A
(((
struct
console_font_op32
*
)
&
op
)
->
data
);
op
.
data
=
A
(((
struct
console_font_op32
*
)
&
op
)
->
data
);
op
.
flags
|=
KD_FONT_FLAG_OLD
;
vt
=
(
struct
vt_struct
*
)((
struct
tty_struct
*
)
file
->
private_data
)
->
driver_data
;
i
=
con_font_op
(
vt
->
vc_num
,
&
op
);
...
...
@@ -2230,9 +2224,9 @@ static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, struct unimapdesc3
switch
(
cmd
)
{
case
PIO_UNIMAP
:
if
(
!
perm
)
return
-
EPERM
;
return
con_set_unimap
(
fg_console
,
tmp
.
entry_ct
,
(
struct
unipair
*
)
A
(
tmp
.
entries
));
return
con_set_unimap
(
fg_console
,
tmp
.
entry_ct
,
A
(
tmp
.
entries
));
case
GIO_UNIMAP
:
return
con_get_unimap
(
fg_console
,
tmp
.
entry_ct
,
&
(
user_ud
->
entry_ct
),
(
struct
unipair
*
)
A
(
tmp
.
entries
));
return
con_get_unimap
(
fg_console
,
tmp
.
entry_ct
,
&
(
user_ud
->
entry_ct
),
A
(
tmp
.
entries
));
}
return
0
;
}
...
...
@@ -2907,9 +2901,9 @@ static lv_t *get_lv_t(u32 p, int *errp)
int
err
,
i
;
u32
ptr1
,
ptr2
;
size_t
size
;
lv_block_exception32_t
*
lbe32
;
lv_block_exception32_t
__user
*
lbe32
;
lv_block_exception_t
*
lbe
;
lv32_t
*
ul
=
(
lv32_t
*
)
A
(
p
);
lv32_t
__user
*
ul
=
A
(
p
);
lv_t
*
l
=
(
lv_t
*
)
kmalloc
(
sizeof
(
lv_t
),
GFP_KERNEL
);
if
(
!
l
)
{
...
...
@@ -2933,13 +2927,13 @@ static lv_t *get_lv_t(u32 p, int *errp)
size
=
l
->
lv_allocated_le
*
sizeof
(
pe_t
);
l
->
lv_current_pe
=
vmalloc
(
size
);
if
(
l
->
lv_current_pe
)
err
=
copy_from_user
(
l
->
lv_current_pe
,
(
void
*
)
A
(
ptr1
),
size
);
err
=
copy_from_user
(
l
->
lv_current_pe
,
A
(
ptr1
),
size
);
}
if
(
!
err
&&
ptr2
)
{
size
=
l
->
lv_remap_end
*
sizeof
(
lv_block_exception_t
);
l
->
lv_block_exception
=
lbe
=
vmalloc
(
size
);
if
(
l
->
lv_block_exception
)
{
lbe32
=
(
lv_block_exception32_t
*
)
A
(
ptr2
);
lbe32
=
A
(
ptr2
);
memset
(
lbe
,
0
,
size
);
for
(
i
=
0
;
i
<
l
->
lv_remap_end
;
i
++
,
lbe
++
,
lbe32
++
)
{
err
|=
get_user
(
lbe
->
rsector_org
,
&
lbe32
->
rsector_org
);
...
...
@@ -2963,7 +2957,7 @@ static lv_t *get_lv_t(u32 p, int *errp)
static
int
copy_lv_t
(
u32
ptr
,
lv_t
*
l
)
{
int
err
;
lv32_t
*
ul
=
(
lv32_t
*
)
A
(
ptr
);
lv32_t
__user
*
ul
=
A
(
ptr
);
u32
ptr1
;
size_t
size
;
...
...
@@ -2977,7 +2971,7 @@ static int copy_lv_t(u32 ptr, lv_t *l)
((
long
)
&
ul
->
dummy
[
0
])
-
((
long
)
&
ul
->
lv_remap_ptr
));
size
=
l
->
lv_allocated_le
*
sizeof
(
pe_t
);
if
(
ptr1
)
err
|=
__copy_to_user
(
(
void
*
)
A
(
ptr1
),
l
->
lv_current_pe
,
size
);
err
|=
__copy_to_user
(
A
(
ptr1
),
l
->
lv_current_pe
,
size
);
return
err
?
-
EFAULT
:
0
;
}
...
...
@@ -3036,14 +3030,14 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
err
=
-
ENOMEM
;
break
;
}
err
=
copy_from_user
(
v
->
pv
[
i
],
(
void
*
)
A
(
ptr
),
err
=
copy_from_user
(
v
->
pv
[
i
],
A
(
ptr
),
sizeof
(
pv32_t
)
-
8
-
UUID_LEN
+
1
);
if
(
err
)
{
err
=
-
EFAULT
;
break
;
}
err
=
copy_from_user
(
v
->
pv
[
i
]
->
pv_uuid
,
((
pv32_t
*
)
A
(
ptr
))
->
pv_uuid
,
err
=
copy_from_user
(
&
v
->
pv
[
i
]
->
pv_uuid
[
0
]
,
&
((
pv32_t
__user
*
)
A
(
ptr
))
->
pv_uuid
[
0
]
,
UUID_LEN
+
1
);
if
(
err
)
{
err
=
-
EFAULT
;
...
...
@@ -3125,7 +3119,7 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
return
err
;
u
.
pv_status
.
pv
=
&
p
;
if
(
cmd
==
PV_CHANGE
)
{
err
=
copy_from_user
(
&
p
,
(
void
*
)
A
(
ptr
),
err
=
copy_from_user
(
&
p
,
A
(
ptr
),
sizeof
(
pv32_t
)
-
8
-
UUID_LEN
+
1
);
if
(
err
)
return
-
EFAULT
;
...
...
@@ -3195,10 +3189,10 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
case
PV_STATUS
:
if
(
!
err
)
{
err
=
copy_to_user
(
(
void
*
)
A
(
ptr
),
&
p
,
sizeof
(
pv32_t
)
-
8
-
UUID_LEN
+
1
);
err
=
copy_to_user
(
A
(
ptr
),
&
p
,
sizeof
(
pv32_t
)
-
8
-
UUID_LEN
+
1
);
if
(
err
)
return
-
EFAULT
;
err
=
copy_to_user
(
((
pv_t
*
)
A
(
ptr
))
->
pv_uuid
,
p
.
pv_uuid
,
UUID_LEN
+
1
);
err
=
copy_to_user
(
&
((
pv_t
__user
*
)
A
(
ptr
))
->
pv_uuid
[
0
],
&
p
.
pv_uuid
[
0
]
,
UUID_LEN
+
1
);
if
(
err
)
return
-
EFAULT
;
}
...
...
@@ -3229,7 +3223,7 @@ typedef struct drm32_version {
static
int
drm32_version
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm32_version_t
*
uversion
=
(
drm32_version_t
*
)
arg
;
char
*
name_ptr
,
*
date_ptr
,
*
desc_ptr
;
char
__user
*
name_ptr
,
*
date_ptr
,
*
desc_ptr
;
u32
tmp1
,
tmp2
,
tmp3
;
drm_version_t
kversion
;
mm_segment_t
old_fs
;
...
...
@@ -3244,9 +3238,9 @@ static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
get_user
(
tmp3
,
&
uversion
->
desc
))
return
-
EFAULT
;
name_ptr
=
(
char
*
)
A
(
tmp1
);
date_ptr
=
(
char
*
)
A
(
tmp2
);
desc_ptr
=
(
char
*
)
A
(
tmp3
);
name_ptr
=
A
(
tmp1
);
date_ptr
=
A
(
tmp2
);
desc_ptr
=
A
(
tmp3
);
ret
=
-
ENOMEM
;
if
(
kversion
.
name_len
&&
name_ptr
)
{
...
...
@@ -3309,7 +3303,7 @@ static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long a
drm32_unique_t
*
uarg
=
(
drm32_unique_t
*
)
arg
;
drm_unique_t
karg
;
mm_segment_t
old_fs
;
char
*
uptr
;
char
__user
*
uptr
;
u32
tmp
;
int
ret
;
...
...
@@ -3320,7 +3314,7 @@ static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long a
if
(
get_user
(
tmp
,
&
uarg
->
unique
))
return
-
EFAULT
;
uptr
=
(
char
*
)
A
(
tmp
);
uptr
=
A
(
tmp
);
if
(
uptr
)
{
karg
.
unique
=
kmalloc
(
karg
.
unique_len
,
GFP_KERNEL
);
...
...
@@ -3385,7 +3379,7 @@ static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
if
(
ret
)
return
-
EFAULT
;
karg
.
handle
=
(
void
*
)
A
(
tmp
);
karg
.
handle
=
A
(
tmp
);
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
...
...
@@ -3416,7 +3410,7 @@ typedef struct drm32_buf_info {
static
int
drm32_info_bufs
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm32_buf_info_t
*
uarg
=
(
drm32_buf_info_t
*
)
arg
;
drm_buf_desc_t
*
ulist
;
drm_buf_desc_t
__user
*
ulist
;
drm_buf_info_t
karg
;
mm_segment_t
old_fs
;
int
orig_count
,
ret
;
...
...
@@ -3426,7 +3420,7 @@ static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
get_user
(
tmp
,
&
uarg
->
list
))
return
-
EFAULT
;
ulist
=
(
drm_buf_desc_t
*
)
A
(
tmp
);
ulist
=
A
(
tmp
);
orig_count
=
karg
.
count
;
...
...
@@ -3464,7 +3458,7 @@ static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
drm32_buf_free_t
*
uarg
=
(
drm32_buf_free_t
*
)
arg
;
drm_buf_free_t
karg
;
mm_segment_t
old_fs
;
int
*
ulist
;
int
__user
*
ulist
;
int
ret
;
u32
tmp
;
...
...
@@ -3472,7 +3466,7 @@ static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
get_user
(
tmp
,
&
uarg
->
list
))
return
-
EFAULT
;
ulist
=
(
int
*
)
A
(
tmp
);
ulist
=
A
(
tmp
);
karg
.
list
=
kmalloc
(
karg
.
count
*
sizeof
(
int
),
GFP_KERNEL
);
if
(
!
karg
.
list
)
...
...
@@ -3510,7 +3504,7 @@ typedef struct drm32_buf_map {
static
int
drm32_map_bufs
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm32_buf_map_t
*
uarg
=
(
drm32_buf_map_t
*
)
arg
;
drm32_buf_pub_t
*
ulist
;
drm32_buf_pub_t
__user
*
ulist
;
drm_buf_map_t
karg
;
mm_segment_t
old_fs
;
int
orig_count
,
ret
,
i
;
...
...
@@ -3521,8 +3515,8 @@ static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
get_user
(
tmp2
,
&
uarg
->
list
))
return
-
EFAULT
;
karg
.
virtual
=
(
void
*
)
A
(
tmp1
);
ulist
=
(
drm32_buf_pub_t
*
)
A
(
tmp2
);
karg
.
virtual
=
A
(
tmp1
);
ulist
=
A
(
tmp2
);
orig_count
=
karg
.
count
;
...
...
@@ -3538,7 +3532,7 @@ static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
get_user
(
tmp1
,
&
ulist
[
i
].
address
))
goto
out
;
karg
.
list
[
i
].
address
=
(
void
*
)
A
(
tmp1
);
karg
.
list
[
i
].
address
=
A
(
tmp1
);
}
old_fs
=
get_fs
();
...
...
@@ -3589,7 +3583,7 @@ typedef struct drm32_dma {
static
int
drm32_dma
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm32_dma_t
*
uarg
=
(
drm32_dma_t
*
)
arg
;
int
*
u_si
,
*
u_ss
,
*
u_ri
,
*
u_rs
;
int
__user
*
u_si
,
*
u_ss
,
*
u_ri
,
*
u_rs
;
drm_dma_t
karg
;
mm_segment_t
old_fs
;
int
ret
;
...
...
@@ -3610,10 +3604,10 @@ static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
get_user
(
karg
.
granted_count
,
&
uarg
->
granted_count
))
return
-
EFAULT
;
u_si
=
(
int
*
)
A
(
tmp1
);
u_ss
=
(
int
*
)
A
(
tmp2
);
u_ri
=
(
int
*
)
A
(
tmp3
);
u_rs
=
(
int
*
)
A
(
tmp4
);
u_si
=
A
(
tmp1
);
u_ss
=
A
(
tmp2
);
u_ri
=
A
(
tmp3
);
u_rs
=
A
(
tmp4
);
if
(
karg
.
send_count
)
{
karg
.
send_indices
=
kmalloc
(
karg
.
send_count
*
sizeof
(
int
),
GFP_KERNEL
);
...
...
@@ -3699,7 +3693,7 @@ typedef struct drm32_ctx_res {
static
int
drm32_res_ctx
(
unsigned
int
fd
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm32_ctx_res_t
*
uarg
=
(
drm32_ctx_res_t
*
)
arg
;
drm_ctx_t
*
ulist
;
drm_ctx_t
__user
*
ulist
;
drm_ctx_res_t
karg
;
mm_segment_t
old_fs
;
int
orig_count
,
ret
;
...
...
@@ -3710,7 +3704,7 @@ static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
get_user
(
tmp
,
&
uarg
->
contexts
))
return
-
EFAULT
;
ulist
=
(
drm_ctx_t
*
)
A
(
tmp
);
ulist
=
A
(
tmp
);
orig_count
=
karg
.
count
;
if
(
karg
.
count
&&
ulist
)
{
...
...
@@ -3817,7 +3811,8 @@ static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long
struct
usbdevfs_ctrltransfer32
*
uctrl
;
mm_segment_t
old_fs
;
__u32
udata
;
void
*
uptr
,
*
kptr
;
void
__user
*
uptr
;
void
*
kptr
;
int
err
;
uctrl
=
(
struct
usbdevfs_ctrltransfer32
*
)
arg
;
...
...
@@ -3829,7 +3824,7 @@ static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long
if
(
get_user
(
udata
,
&
uctrl
->
data
))
return
-
EFAULT
;
uptr
=
(
void
*
)
A
(
udata
);
uptr
=
A
(
udata
);
/* In usbdevice_fs, it limits the control buffer to a page,
* for simplicity so do we.
...
...
@@ -3878,7 +3873,8 @@ static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg
struct
usbdevfs_bulktransfer32
*
ubulk
;
mm_segment_t
old_fs
;
__u32
udata
;
void
*
uptr
,
*
kptr
;
void
__user
*
uptr
;
void
*
kptr
;
int
err
;
ubulk
=
(
struct
usbdevfs_bulktransfer32
*
)
arg
;
...
...
@@ -3889,7 +3885,7 @@ static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg
get_user
(
udata
,
&
ubulk
->
data
))
return
-
EFAULT
;
uptr
=
(
void
*
)
A
(
udata
);
uptr
=
A
(
udata
);
/* In usbdevice_fs, it limits the control buffer to a page,
* for simplicity so do we.
...
...
@@ -4072,7 +4068,8 @@ static int do_usbdevfs_urb(unsigned int fd, unsigned int cmd, unsigned long arg)
struct usbdevfs_urb32 *uurb;
mm_segment_t old_fs;
__u32 udata;
void *uptr, *kptr;
void __user *uptr;
void *kptr;
unsigned int buflen;
int err;
...
...
@@ -4096,7 +4093,7 @@ static int do_usbdevfs_urb(unsigned int fd, unsigned int cmd, unsigned long arg)
err = -EFAULT;
if (__get_user(udata, &uurb->buffer))
goto out;
uptr =
(void *)
A(udata);
uptr = A(udata);
err = -ENOMEM;
buflen = kurb->buffer_length;
...
...
@@ -4153,7 +4150,7 @@ static int do_usbdevfs_reapurb(unsigned int fd, unsigned int cmd, unsigned long
set_fs
(
old_fs
);
if
(
err
>=
0
&&
put_user
(((
u32
)(
long
)
kptr
),
(
u32
*
)
A
(
arg
)))
put_user
(((
u32
)(
long
)
kptr
),
(
u32
__user
*
)
A
(
arg
)))
err
=
-
EFAULT
;
return
err
;
...
...
@@ -4205,7 +4202,7 @@ static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
struct
mtd_oob_buf32
*
uarg
=
(
struct
mtd_oob_buf32
*
)
arg
;
struct
mtd_oob_buf
karg
;
u32
tmp
;
char
*
ptr
;
char
__user
*
ptr
;
int
ret
;
if
(
get_user
(
karg
.
start
,
&
uarg
->
start
)
||
...
...
@@ -4213,7 +4210,7 @@ static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
get_user
(
tmp
,
&
uarg
->
ptr
))
return
-
EFAULT
;
ptr
=
(
char
*
)
A
(
tmp
);
ptr
=
A
(
tmp
);
if
(
0
>=
karg
.
length
)
return
-
EINVAL
;
...
...
arch/sparc64/kernel/process.c
View file @
a0e3315d
...
...
@@ -473,7 +473,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
distance
=
fp
-
psp
;
rval
=
(
csp
-
distance
);
if
(
copy_in_user
(
rval
,
psp
,
distance
))
if
(
copy_in_user
(
(
void
__user
*
)
rval
,
(
void
__user
*
)
psp
,
distance
))
rval
=
0
;
else
if
(
test_thread_flag
(
TIF_32BIT
))
{
if
(
put_user
(((
u32
)
csp
),
&
(((
struct
reg_window32
*
)
rval
)
->
ins
[
6
])))
...
...
arch/sparc64/kernel/signal.c
View file @
a0e3315d
...
...
@@ -42,8 +42,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
/* {set, get}context() needed for 64-bit SparcLinux userland. */
asmlinkage
void
sparc64_set_context
(
struct
pt_regs
*
regs
)
{
struct
ucontext
*
ucp
=
(
struct
ucontext
*
)
regs
->
u_regs
[
UREG_I0
];
mc_gregset_t
*
grp
;
struct
ucontext
*
ucp
=
(
struct
ucontext
__user
*
)
regs
->
u_regs
[
UREG_I0
];
mc_gregset_t
__user
*
grp
;
unsigned
long
pc
,
npc
,
tstate
;
unsigned
long
fp
,
i7
;
unsigned
char
fenab
;
...
...
@@ -104,9 +104,9 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
err
|=
__get_user
(
fp
,
&
(
ucp
->
uc_mcontext
.
mc_fp
));
err
|=
__get_user
(
i7
,
&
(
ucp
->
uc_mcontext
.
mc_i7
));
err
|=
__put_user
(
fp
,
(
&
(((
struct
reg_window
*
)(
STACK_BIAS
+
regs
->
u_regs
[
UREG_I6
]))
->
ins
[
6
])));
(
&
(((
struct
reg_window
__user
*
)(
STACK_BIAS
+
regs
->
u_regs
[
UREG_I6
]))
->
ins
[
6
])));
err
|=
__put_user
(
i7
,
(
&
(((
struct
reg_window
*
)(
STACK_BIAS
+
regs
->
u_regs
[
UREG_I6
]))
->
ins
[
7
])));
(
&
(((
struct
reg_window
__user
*
)(
STACK_BIAS
+
regs
->
u_regs
[
UREG_I6
]))
->
ins
[
7
])));
err
|=
__get_user
(
fenab
,
&
(
ucp
->
uc_mcontext
.
mc_fpregs
.
mcfpu_enab
));
if
(
fenab
)
{
...
...
@@ -121,7 +121,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
(
sizeof
(
unsigned
int
)
*
32
));
if
(
fprs
&
FPRS_DU
)
err
|=
copy_from_user
(
fpregs
+
16
,
((
unsigned
long
*
)
&
(
ucp
->
uc_mcontext
.
mc_fpregs
.
mcfpu_fregs
))
+
16
,
((
unsigned
long
__user
*
)
&
(
ucp
->
uc_mcontext
.
mc_fpregs
.
mcfpu_fregs
))
+
16
,
(
sizeof
(
unsigned
int
)
*
32
));
err
|=
__get_user
(
current_thread_info
()
->
xfsr
[
0
],
&
(
ucp
->
uc_mcontext
.
mc_fpregs
.
mcfpu_fsr
));
...
...
@@ -139,9 +139,9 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
asmlinkage
void
sparc64_get_context
(
struct
pt_regs
*
regs
)
{
struct
ucontext
*
ucp
=
(
struct
ucontext
*
)
regs
->
u_regs
[
UREG_I0
];
mc_gregset_t
*
grp
;
mcontext_t
*
mcp
;
struct
ucontext
*
ucp
=
(
struct
ucontext
__user
*
)
regs
->
u_regs
[
UREG_I0
];
mc_gregset_t
__user
*
grp
;
mcontext_t
__user
*
mcp
;
unsigned
long
fp
,
i7
;
unsigned
char
fenab
;
int
err
;
...
...
@@ -170,7 +170,7 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs)
err
=
0
;
if
(
_NSIG_WORDS
==
1
)
err
|=
__put_user
(
current
->
blocked
.
sig
[
0
],
(
unsigned
long
*
)
&
ucp
->
uc_sigmask
);
(
unsigned
long
__user
*
)
&
ucp
->
uc_sigmask
);
else
err
|=
__copy_to_user
(
&
ucp
->
uc_sigmask
,
&
current
->
blocked
,
sizeof
(
sigset_t
));
...
...
@@ -196,9 +196,9 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs)
err
|=
__put_user
(
regs
->
u_regs
[
UREG_I7
],
&
((
*
grp
)[
MC_O7
]));
err
|=
__get_user
(
fp
,
(
&
(((
struct
reg_window
*
)(
STACK_BIAS
+
regs
->
u_regs
[
UREG_I6
]))
->
ins
[
6
])));
(
&
(((
struct
reg_window
__user
*
)(
STACK_BIAS
+
regs
->
u_regs
[
UREG_I6
]))
->
ins
[
6
])));
err
|=
__get_user
(
i7
,
(
&
(((
struct
reg_window
*
)(
STACK_BIAS
+
regs
->
u_regs
[
UREG_I6
]))
->
ins
[
7
])));
(
&
(((
struct
reg_window
__user
*
)(
STACK_BIAS
+
regs
->
u_regs
[
UREG_I6
]))
->
ins
[
7
])));
err
|=
__put_user
(
fp
,
&
(
mcp
->
mc_fp
));
err
|=
__put_user
(
i7
,
&
(
mcp
->
mc_i7
));
...
...
@@ -213,7 +213,7 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs)
(
sizeof
(
unsigned
int
)
*
32
));
if
(
fprs
&
FPRS_DU
)
err
|=
copy_to_user
(
((
unsigned
long
*
)
&
(
mcp
->
mc_fpregs
.
mcfpu_fregs
))
+
16
,
fpregs
+
16
,
((
unsigned
long
__user
*
)
&
(
mcp
->
mc_fpregs
.
mcfpu_fregs
))
+
16
,
fpregs
+
16
,
(
sizeof
(
unsigned
int
)
*
32
));
err
|=
__put_user
(
current_thread_info
()
->
xfsr
[
0
],
&
(
mcp
->
mc_fpregs
.
mcfpu_fsr
));
err
|=
__put_user
(
current_thread_info
()
->
gsr
[
0
],
&
(
mcp
->
mc_fpregs
.
mcfpu_gsr
));
...
...
@@ -231,7 +231,7 @@ struct rt_signal_frame {
struct
sparc_stackf
ss
;
siginfo_t
info
;
struct
pt_regs
regs
;
__siginfo_fpu_t
*
fpu_save
;
__siginfo_fpu_t
__user
*
fpu_save
;
stack_t
stack
;
sigset_t
mask
;
__siginfo_fpu_t
fpu_state
;
...
...
@@ -300,7 +300,7 @@ asmlinkage void do_sigsuspend(struct pt_regs *regs)
_sigpause_common
(
regs
->
u_regs
[
UREG_I0
],
regs
);
}
asmlinkage
void
do_rt_sigsuspend
(
sigset_t
*
uset
,
size_t
sigsetsize
,
struct
pt_regs
*
regs
)
asmlinkage
void
do_rt_sigsuspend
(
sigset_t
__user
*
uset
,
size_t
sigsetsize
,
struct
pt_regs
*
regs
)
{
sigset_t
oldset
,
set
;
...
...
@@ -351,7 +351,7 @@ asmlinkage void do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize, struct pt_re
}
static
inline
int
restore_fpu_state
(
struct
pt_regs
*
regs
,
__siginfo_fpu_t
*
fpu
)
restore_fpu_state
(
struct
pt_regs
*
regs
,
__siginfo_fpu_t
__user
*
fpu
)
{
unsigned
long
*
fpregs
=
current_thread_info
()
->
fpregs
;
unsigned
long
fprs
;
...
...
@@ -374,16 +374,16 @@ restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
void
do_rt_sigreturn
(
struct
pt_regs
*
regs
)
{
struct
rt_signal_frame
*
sf
;
struct
rt_signal_frame
__user
*
sf
;
unsigned
long
tpc
,
tnpc
,
tstate
;
__siginfo_fpu_t
*
fpu_save
;
__siginfo_fpu_t
__user
*
fpu_save
;
mm_segment_t
old_fs
;
sigset_t
set
;
stack_t
st
;
int
err
;
synchronize_user_stack
();
sf
=
(
struct
rt_signal_frame
*
)
sf
=
(
struct
rt_signal_frame
__user
*
)
(
regs
->
u_regs
[
UREG_FP
]
+
STACK_BIAS
);
/* 1. Make sure we are not getting garbage from the user */
...
...
@@ -438,7 +438,7 @@ void do_rt_sigreturn(struct pt_regs *regs)
}
/* Checks if the fp is valid */
static
int
invalid_frame_pointer
(
void
*
fp
,
int
fplen
)
static
int
invalid_frame_pointer
(
void
__user
*
fp
,
int
fplen
)
{
if
(((
unsigned
long
)
fp
)
&
7
)
return
1
;
...
...
@@ -446,7 +446,7 @@ static int invalid_frame_pointer(void *fp, int fplen)
}
static
inline
int
save_fpu_state
(
struct
pt_regs
*
regs
,
__siginfo_fpu_t
*
fpu
)
save_fpu_state
(
struct
pt_regs
*
regs
,
__siginfo_fpu_t
__user
*
fpu
)
{
unsigned
long
*
fpregs
=
(
unsigned
long
*
)(
regs
+
1
);
unsigned
long
fprs
;
...
...
@@ -466,7 +466,7 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
return
err
;
}
static
inline
void
*
get_sigframe
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
unsigned
long
framesize
)
static
inline
void
__user
*
get_sigframe
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
unsigned
long
framesize
)
{
unsigned
long
sp
;
...
...
@@ -478,14 +478,14 @@ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, u
!
((
current
->
sas_ss_sp
+
current
->
sas_ss_size
)
&
7
))
sp
=
current
->
sas_ss_sp
+
current
->
sas_ss_size
;
}
return
(
void
*
)(
sp
-
framesize
);
return
(
void
__user
*
)(
sp
-
framesize
);
}
static
inline
void
setup_rt_frame
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signo
,
sigset_t
*
oldset
,
siginfo_t
*
info
)
{
struct
rt_signal_frame
*
sf
;
struct
rt_signal_frame
__user
*
sf
;
int
sigframe_size
,
err
;
/* 1. Make sure everything is clean */
...
...
@@ -496,7 +496,8 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
if
(
!
(
current_thread_info
()
->
fpsaved
[
0
]
&
FPRS_FEF
))
sigframe_size
-=
sizeof
(
__siginfo_fpu_t
);
sf
=
(
struct
rt_signal_frame
*
)
get_sigframe
(
ka
,
regs
,
sigframe_size
);
sf
=
(
struct
rt_signal_frame
__user
*
)
get_sigframe
(
ka
,
regs
,
sigframe_size
);
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
goto
sigill
;
...
...
@@ -521,8 +522,8 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
err
|=
copy_to_user
(
&
sf
->
mask
,
oldset
,
sizeof
(
sigset_t
));
err
|=
copy_in_user
((
u64
*
)
sf
,
(
u64
*
)(
regs
->
u_regs
[
UREG_FP
]
+
STACK_BIAS
),
err
|=
copy_in_user
((
u64
__user
*
)
sf
,
(
u64
__user
*
)(
regs
->
u_regs
[
UREG_FP
]
+
STACK_BIAS
),
sizeof
(
struct
reg_window
));
if
(
info
)
...
...
@@ -560,7 +561,8 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
siginfo_t
*
info
,
sigset_t
*
oldset
,
struct
pt_regs
*
regs
)
{
setup_rt_frame
(
ka
,
regs
,
signr
,
oldset
,
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
?
info
:
NULL
);
setup_rt_frame
(
ka
,
regs
,
signr
,
oldset
,
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
?
info
:
NULL
);
if
(
ka
->
sa
.
sa_flags
&
SA_ONESHOT
)
ka
->
sa
.
sa_handler
=
SIG_DFL
;
if
(
!
(
ka
->
sa
.
sa_flags
&
SA_NOMASK
))
{
...
...
arch/sparc64/kernel/signal32.c
View file @
a0e3315d
...
...
@@ -56,7 +56,7 @@ struct signal_sframe32 {
/* struct sigcontext32 * */
u32
sig_scptr
;
int
sig_address
;
struct
sigcontext32
sig_context
;
unsigned
extramask
[
_COMPAT_NSIG_WORDS
-
1
];
unsigned
int
extramask
[
_COMPAT_NSIG_WORDS
-
1
];
};
/*
...
...
@@ -68,9 +68,9 @@ struct new_signal_frame32 {
struct
sparc_stackf32
ss
;
__siginfo32_t
info
;
/* __siginfo_fpu32_t * */
u32
fpu_save
;
unsigned
int
insns
[
2
];
unsigned
extramask
[
_COMPAT_NSIG_WORDS
-
1
];
unsigned
extra_size
;
/* Should be sizeof(siginfo_extra_v8plus_t) */
unsigned
int
insns
[
2
];
unsigned
int
extramask
[
_COMPAT_NSIG_WORDS
-
1
];
unsigned
int
extra_size
;
/* Should be sizeof(siginfo_extra_v8plus_t) */
/* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
siginfo_extra_v8plus_t
v8plus
;
__siginfo_fpu_t
fpu_state
;
...
...
@@ -82,9 +82,9 @@ struct rt_signal_frame32 {
struct
pt_regs32
regs
;
compat_sigset_t
mask
;
/* __siginfo_fpu32_t * */
u32
fpu_save
;
unsigned
int
insns
[
2
];
unsigned
int
insns
[
2
];
stack_t32
stack
;
unsigned
extra_size
;
/* Should be sizeof(siginfo_extra_v8plus_t) */
unsigned
int
extra_size
;
/* Should be sizeof(siginfo_extra_v8plus_t) */
/* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
siginfo_extra_v8plus_t
v8plus
;
__siginfo_fpu_t
fpu_state
;
...
...
@@ -95,11 +95,11 @@ struct rt_signal_frame32 {
#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame32) + 7) & (~7)))
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
int
copy_siginfo_to_user32
(
siginfo_t32
*
to
,
siginfo_t
*
from
)
int
copy_siginfo_to_user32
(
siginfo_t32
__user
*
to
,
siginfo_t
*
from
)
{
int
err
;
if
(
!
access_ok
(
VERIFY_WRITE
,
to
,
sizeof
(
siginfo_t32
)))
if
(
!
access_ok
(
VERIFY_WRITE
,
to
,
sizeof
(
siginfo_t32
)))
return
-
EFAULT
;
/* If you change siginfo_t structure, please be sure
...
...
@@ -187,7 +187,7 @@ asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *
regs
->
u_regs
[
UREG_I0
]
=
EINVAL
;
return
;
}
if
(
copy_from_user
(
&
set32
,
(
void
*
)(
long
)
uset
,
sizeof
(
set32
)))
{
if
(
copy_from_user
(
&
set32
,
(
void
__user
*
)(
long
)
uset
,
sizeof
(
set32
)))
{
regs
->
tstate
|=
TSTATE_ICARRY
;
regs
->
u_regs
[
UREG_I0
]
=
EFAULT
;
return
;
...
...
@@ -231,7 +231,7 @@ asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *
}
}
static
int
restore_fpu_state32
(
struct
pt_regs
*
regs
,
__siginfo_fpu_t
*
fpu
)
static
int
restore_fpu_state32
(
struct
pt_regs
*
regs
,
__siginfo_fpu_t
__user
*
fpu
)
{
unsigned
long
*
fpregs
=
current_thread_info
()
->
fpregs
;
unsigned
long
fprs
;
...
...
@@ -252,7 +252,7 @@ static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu)
void
do_new_sigreturn32
(
struct
pt_regs
*
regs
)
{
struct
new_signal_frame32
*
sf
;
struct
new_signal_frame32
__user
*
sf
;
unsigned
int
psr
;
unsigned
pc
,
npc
,
fpu_save
;
sigset_t
set
;
...
...
@@ -260,10 +260,10 @@ void do_new_sigreturn32(struct pt_regs *regs)
int
err
,
i
;
regs
->
u_regs
[
UREG_FP
]
&=
0x00000000ffffffffUL
;
sf
=
(
struct
new_signal_frame32
*
)
regs
->
u_regs
[
UREG_FP
];
sf
=
(
struct
new_signal_frame32
__user
*
)
regs
->
u_regs
[
UREG_FP
];
/* 1. Make sure we are not getting garbage from the user */
if
(
verify_area
(
VERIFY_READ
,
sf
,
sizeof
(
*
sf
))
||
if
(
verify_area
(
VERIFY_READ
,
sf
,
sizeof
(
*
sf
))
||
(((
unsigned
long
)
sf
)
&
3
))
goto
segv
;
...
...
@@ -302,7 +302,8 @@ void do_new_sigreturn32(struct pt_regs *regs)
if
(
fpu_save
)
err
|=
restore_fpu_state32
(
regs
,
&
sf
->
fpu_state
);
err
|=
__get_user
(
seta
[
0
],
&
sf
->
info
.
si_mask
);
err
|=
copy_from_user
(
seta
+
1
,
&
sf
->
extramask
,
(
_COMPAT_NSIG_WORDS
-
1
)
*
sizeof
(
unsigned
));
err
|=
copy_from_user
(
seta
+
1
,
&
sf
->
extramask
,
(
_COMPAT_NSIG_WORDS
-
1
)
*
sizeof
(
unsigned
int
));
if
(
err
)
goto
segv
;
switch
(
_NSIG_WORDS
)
{
...
...
@@ -324,17 +325,17 @@ void do_new_sigreturn32(struct pt_regs *regs)
asmlinkage
void
do_sigreturn32
(
struct
pt_regs
*
regs
)
{
struct
sigcontext32
*
scptr
;
unsigned
pc
,
npc
,
psr
;
struct
sigcontext32
__user
*
scptr
;
unsigned
int
pc
,
npc
,
psr
;
sigset_t
set
;
unsigned
seta
[
_COMPAT_NSIG_WORDS
];
unsigned
int
seta
[
_COMPAT_NSIG_WORDS
];
int
err
;
synchronize_user_stack
();
if
(
test_thread_flag
(
TIF_NEWSIGNALS
))
return
do_new_sigreturn32
(
regs
);
scptr
=
(
struct
sigcontext32
*
)
scptr
=
(
struct
sigcontext32
__user
*
)
(
regs
->
u_regs
[
UREG_I0
]
&
0x00000000ffffffffUL
);
/* Check sanity of the user arg. */
if
(
verify_area
(
VERIFY_READ
,
scptr
,
sizeof
(
struct
sigcontext32
))
||
...
...
@@ -349,7 +350,8 @@ asmlinkage void do_sigreturn32(struct pt_regs *regs)
err
|=
__get_user
(
seta
[
0
],
&
scptr
->
sigc_mask
);
/* Note that scptr + 1 points to extramask */
err
|=
copy_from_user
(
seta
+
1
,
scptr
+
1
,
(
_COMPAT_NSIG_WORDS
-
1
)
*
sizeof
(
unsigned
));
err
|=
copy_from_user
(
seta
+
1
,
scptr
+
1
,
(
_COMPAT_NSIG_WORDS
-
1
)
*
sizeof
(
unsigned
int
));
if
(
err
)
goto
segv
;
switch
(
_NSIG_WORDS
)
{
...
...
@@ -388,9 +390,8 @@ asmlinkage void do_sigreturn32(struct pt_regs *regs)
asmlinkage
void
do_rt_sigreturn32
(
struct
pt_regs
*
regs
)
{
struct
rt_signal_frame32
*
sf
;
unsigned
int
psr
;
unsigned
pc
,
npc
,
fpu_save
;
struct
rt_signal_frame32
__user
*
sf
;
unsigned
int
psr
,
pc
,
npc
,
fpu_save
;
mm_segment_t
old_fs
;
sigset_t
set
;
compat_sigset_t
seta
;
...
...
@@ -399,10 +400,10 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
synchronize_user_stack
();
regs
->
u_regs
[
UREG_FP
]
&=
0x00000000ffffffffUL
;
sf
=
(
struct
rt_signal_frame32
*
)
regs
->
u_regs
[
UREG_FP
];
sf
=
(
struct
rt_signal_frame32
__user
*
)
regs
->
u_regs
[
UREG_FP
];
/* 1. Make sure we are not getting garbage from the user */
if
(
verify_area
(
VERIFY_READ
,
sf
,
sizeof
(
*
sf
))
||
if
(
verify_area
(
VERIFY_READ
,
sf
,
sizeof
(
*
sf
))
||
(((
unsigned
long
)
sf
)
&
3
))
goto
segv
;
...
...
@@ -471,14 +472,14 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
}
/* Checks if the fp is valid */
static
int
invalid_frame_pointer
(
void
*
fp
,
int
fplen
)
static
int
invalid_frame_pointer
(
void
__user
*
fp
,
int
fplen
)
{
if
((((
unsigned
long
)
fp
)
&
7
)
||
((
unsigned
long
)
fp
)
>
0x100000000ULL
-
fplen
)
return
1
;
return
0
;
}
static
void
*
get_sigframe
(
struct
sigaction
*
sa
,
struct
pt_regs
*
regs
,
unsigned
long
framesize
)
static
void
__user
*
get_sigframe
(
struct
sigaction
*
sa
,
struct
pt_regs
*
regs
,
unsigned
long
framesize
)
{
unsigned
long
sp
;
...
...
@@ -490,25 +491,21 @@ static void *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned l
if
(
!
on_sig_stack
(
sp
)
&&
!
((
current
->
sas_ss_sp
+
current
->
sas_ss_size
)
&
7
))
sp
=
current
->
sas_ss_sp
+
current
->
sas_ss_size
;
}
return
(
void
*
)(
sp
-
framesize
);
return
(
void
__user
*
)(
sp
-
framesize
);
}
static
void
setup_frame32
(
struct
sigaction
*
sa
,
struct
pt_regs
*
regs
,
int
signr
,
sigset_t
*
oldset
,
siginfo_t
*
info
)
{
struct
signal_sframe32
*
sframep
;
struct
sigcontext32
*
sc
;
unsigned
seta
[
_COMPAT_NSIG_WORDS
];
struct
signal_sframe32
__user
*
sframep
;
struct
sigcontext32
__user
*
sc
;
unsigned
int
seta
[
_COMPAT_NSIG_WORDS
];
int
err
=
0
;
void
*
sig_address
;
int
sig_code
;
unsigned
long
pc
=
regs
->
tpc
;
unsigned
long
npc
=
regs
->
tnpc
;
#if 0
int window = 0;
#endif
unsigned
psr
;
unsigned
int
psr
;
if
(
test_thread_flag
(
TIF_32BIT
))
{
pc
&=
0xffffffff
;
...
...
@@ -518,8 +515,9 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
synchronize_user_stack
();
save_and_clear_fpu
();
sframep
=
(
struct
signal_sframe32
*
)
get_sigframe
(
sa
,
regs
,
SF_ALIGNEDSZ
);
if
(
invalid_frame_pointer
(
sframep
,
sizeof
(
*
sframep
))){
sframep
=
(
struct
signal_sframe32
__user
*
)
get_sigframe
(
sa
,
regs
,
SF_ALIGNEDSZ
);
if
(
invalid_frame_pointer
(
sframep
,
sizeof
(
*
sframep
))){
/* Don't change signal code and address, so that
* post mortem debuggers can have a look.
*/
...
...
@@ -544,32 +542,21 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
}
err
|=
__put_user
(
seta
[
0
],
&
sc
->
sigc_mask
);
err
|=
__copy_to_user
(
sframep
->
extramask
,
seta
+
1
,
(
_COMPAT_NSIG_WORDS
-
1
)
*
sizeof
(
unsigned
));
(
_COMPAT_NSIG_WORDS
-
1
)
*
sizeof
(
unsigned
int
));
err
|=
__put_user
(
regs
->
u_regs
[
UREG_FP
],
&
sc
->
sigc_sp
);
err
|=
__put_user
(
pc
,
&
sc
->
sigc_pc
);
err
|=
__put_user
(
npc
,
&
sc
->
sigc_npc
);
psr
=
tstate_to_psr
(
regs
->
tstate
);
psr
=
tstate_to_psr
(
regs
->
tstate
);
if
(
current_thread_info
()
->
fpsaved
[
0
]
&
FPRS_FEF
)
psr
|=
PSR_EF
;
err
|=
__put_user
(
psr
,
&
sc
->
sigc_psr
);
err
|=
__put_user
(
regs
->
u_regs
[
UREG_G1
],
&
sc
->
sigc_g1
);
err
|=
__put_user
(
regs
->
u_regs
[
UREG_I0
],
&
sc
->
sigc_o0
);
err
|=
__put_user
(
get_thread_wsaved
(),
&
sc
->
sigc_oswins
);
#if 0
/* w_saved is not currently used... */
if (get_thread_wsaved())
for (window = 0; window < get_thread_wsaved(); window++) {
sc->sigc_spbuf[window] =
(char *) current_thread_info()->rwbuf_stkptrs[window];
err |= copy_to_user(&sc->sigc_wbuf[window],
¤t_thread_info()->reg_window[window],
sizeof(struct reg_window));
}
else
#endif
err
|=
copy_in_user
((
u32
*
)
sframep
,
(
u32
*
)(
regs
->
u_regs
[
UREG_FP
]),
sizeof
(
struct
reg_window32
));
err
|=
copy_in_user
((
u32
__user
*
)
sframep
,
(
u32
__user
*
)(
regs
->
u_regs
[
UREG_FP
]),
sizeof
(
struct
reg_window32
));
set_thread_wsaved
(
0
);
/* So process is allowed to execute. */
err
|=
__put_user
(
signr
,
&
sframep
->
sig_num
);
...
...
@@ -588,7 +575,7 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
switch
(
info
->
si_code
)
{
case
ILL_ILLOPC
:
sig_code
=
SUBSIG_ILLINST
;
break
;
case
ILL_PRVOPC
:
sig_code
=
SUBSIG_PRIVINST
;
break
;
case
ILL_ILLTRP
:
sig_code
=
SUBSIG_BADTRAP
(
info
->
si_trapno
);
break
;
case
ILL_ILLTRP
:
sig_code
=
SUBSIG_BADTRAP
(
info
->
si_trapno
);
break
;
default:
sig_code
=
SUBSIG_STACK
;
break
;
}
break
;
...
...
@@ -646,7 +633,7 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
}
static
int
save_fpu_state32
(
struct
pt_regs
*
regs
,
__siginfo_fpu_t
*
fpu
)
static
int
save_fpu_state32
(
struct
pt_regs
*
regs
,
__siginfo_fpu_t
__user
*
fpu
)
{
unsigned
long
*
fpregs
=
current_thread_info
()
->
fpregs
;
unsigned
long
fprs
;
...
...
@@ -669,11 +656,11 @@ static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu)
static
void
new_setup_frame32
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signo
,
sigset_t
*
oldset
)
{
struct
new_signal_frame32
*
sf
;
struct
new_signal_frame32
__user
*
sf
;
int
sigframe_size
;
u32
psr
;
int
i
,
err
;
unsigned
seta
[
_COMPAT_NSIG_WORDS
];
unsigned
int
seta
[
_COMPAT_NSIG_WORDS
];
/* 1. Make sure everything is clean */
synchronize_user_stack
();
...
...
@@ -683,9 +670,10 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
if
(
!
(
current_thread_info
()
->
fpsaved
[
0
]
&
FPRS_FEF
))
sigframe_size
-=
sizeof
(
__siginfo_fpu_t
);
sf
=
(
struct
new_signal_frame32
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
sf
=
(
struct
new_signal_frame32
__user
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
goto
sigill
;
if
(
get_thread_wsaved
()
!=
0
)
...
...
@@ -699,7 +687,7 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
err
=
put_user
(
regs
->
tpc
,
&
sf
->
info
.
si_regs
.
pc
);
err
|=
__put_user
(
regs
->
tnpc
,
&
sf
->
info
.
si_regs
.
npc
);
err
|=
__put_user
(
regs
->
y
,
&
sf
->
info
.
si_regs
.
y
);
psr
=
tstate_to_psr
(
regs
->
tstate
);
psr
=
tstate_to_psr
(
regs
->
tstate
);
if
(
current_thread_info
()
->
fpsaved
[
0
]
&
FPRS_FEF
)
psr
|=
PSR_EF
;
err
|=
__put_user
(
psr
,
&
sf
->
info
.
si_regs
.
psr
);
...
...
@@ -729,10 +717,10 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
}
err
|=
__put_user
(
seta
[
0
],
&
sf
->
info
.
si_mask
);
err
|=
__copy_to_user
(
sf
->
extramask
,
seta
+
1
,
(
_COMPAT_NSIG_WORDS
-
1
)
*
sizeof
(
unsigned
));
(
_COMPAT_NSIG_WORDS
-
1
)
*
sizeof
(
unsigned
int
));
err
|=
copy_in_user
((
u32
*
)
sf
,
(
u32
*
)(
regs
->
u_regs
[
UREG_FP
]),
err
|=
copy_in_user
((
u32
__user
*
)
sf
,
(
u32
__user
*
)(
regs
->
u_regs
[
UREG_FP
]),
sizeof
(
struct
reg_window32
));
if
(
err
)
...
...
@@ -771,7 +759,8 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
preempt_disable
();
ptep
=
pte_offset_map
(
pmdp
,
address
);
if
(
pte_present
(
*
ptep
))
{
unsigned
long
page
=
(
unsigned
long
)
page_address
(
pte_page
(
*
ptep
));
unsigned
long
page
=
(
unsigned
long
)
page_address
(
pte_page
(
*
ptep
));
__asm__
__volatile__
(
" membar #StoreStore
\n
"
...
...
@@ -795,30 +784,29 @@ static void
setup_svr4_frame32
(
struct
sigaction
*
sa
,
unsigned
long
pc
,
unsigned
long
npc
,
struct
pt_regs
*
regs
,
int
signr
,
sigset_t
*
oldset
)
{
svr4_signal_frame_t
*
sfp
;
svr4_gregset_t
*
gr
;
svr4_siginfo_t
*
si
;
svr4_mcontext_t
*
mc
;
svr4_gwindows_t
*
gw
;
svr4_ucontext_t
*
uc
;
svr4_signal_frame_t
__user
*
sfp
;
svr4_gregset_t
__user
*
gr
;
svr4_siginfo_t
__user
*
si
;
svr4_mcontext_t
__user
*
mc
;
svr4_gwindows_t
__user
*
gw
;
svr4_ucontext_t
__user
*
uc
;
svr4_sigset_t
setv
;
#if 0
int window = 0;
#endif
unsigned
psr
;
unsigned
int
psr
;
int
i
,
err
;
synchronize_user_stack
();
save_and_clear_fpu
();
regs
->
u_regs
[
UREG_FP
]
&=
0x00000000ffffffffUL
;
sfp
=
(
svr4_signal_frame_t
*
)
get_sigframe
(
sa
,
regs
,
sizeof
(
struct
reg_window32
)
+
SVR4_SF_ALIGNED
);
sfp
=
(
svr4_signal_frame_t
__user
*
)
get_sigframe
(
sa
,
regs
,
sizeof
(
struct
reg_window32
)
+
SVR4_SF_ALIGNED
);
if
(
invalid_frame_pointer
(
sfp
,
sizeof
(
*
sfp
)))
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
));
err
=
clear_user
(
sfp
,
sizeof
(
*
sfp
));
/* Setup convenience variables */
si
=
&
sfp
->
si
;
...
...
@@ -838,22 +826,23 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
setv
.
sigbits
[
3
]
=
(
oldset
->
sig
[
1
]
>>
32
);
err
|=
__copy_to_user
(
&
uc
->
sigmask
,
&
setv
,
sizeof
(
svr4_sigset_t
));
}
else
err
|=
__copy_to_user
(
&
uc
->
sigmask
,
&
setv
,
2
*
sizeof
(
unsigned
));
err
|=
__copy_to_user
(
&
uc
->
sigmask
,
&
setv
,
2
*
sizeof
(
unsigned
int
));
/* Store registers */
if
(
test_thread_flag
(
TIF_32BIT
))
{
regs
->
tpc
&=
0xffffffff
;
regs
->
tnpc
&=
0xffffffff
;
}
err
|=
__put_user
(
regs
->
tpc
,
&
((
*
gr
)
[
SVR4_PC
]));
err
|=
__put_user
(
regs
->
tnpc
,
&
((
*
gr
)
[
SVR4_NPC
]));
psr
=
tstate_to_psr
(
regs
->
tstate
);
err
|=
__put_user
(
regs
->
tpc
,
&
((
*
gr
)[
SVR4_PC
]));
err
|=
__put_user
(
regs
->
tnpc
,
&
((
*
gr
)[
SVR4_NPC
]));
psr
=
tstate_to_psr
(
regs
->
tstate
);
if
(
current_thread_info
()
->
fpsaved
[
0
]
&
FPRS_FEF
)
psr
|=
PSR_EF
;
err
|=
__put_user
(
psr
,
&
((
*
gr
)
[
SVR4_PSR
]));
err
|=
__put_user
(
regs
->
y
,
&
((
*
gr
)
[
SVR4_Y
]));
err
|=
__put_user
(
psr
,
&
((
*
gr
)[
SVR4_PSR
]));
err
|=
__put_user
(
regs
->
y
,
&
((
*
gr
)[
SVR4_Y
]));
/* Copy g
[1..7] and o
[0..7] registers */
/* Copy g
[1..7] and o
[0..7] registers */
for
(
i
=
0
;
i
<
7
;
i
++
)
err
|=
__put_user
(
regs
->
u_regs
[
UREG_G1
+
i
],
(
&
(
*
gr
)[
SVR4_G1
])
+
i
);
for
(
i
=
0
;
i
<
8
;
i
++
)
...
...
@@ -872,29 +861,7 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
/* 2. Number of windows to restore at setcontext (): */
err
|=
__put_user
(
get_thread_wsaved
(),
&
gw
->
count
);
/* 3. Save each valid window
* Currently, it makes a copy of the windows from the kernel copy.
* David's code for SunOS, makes the copy but keeps the pointer to
* the kernel. My version makes the pointer point to a userland
* copy of those. Mhm, I wonder if I shouldn't just ignore those
* on setcontext and use those that are on the kernel, the signal
* handler should not be modyfing those, mhm.
*
* These windows are just used in case synchronize_user_stack failed
* to flush the user windows.
*/
#if 0
for (window = 0; window < get_thread_wsaved(); window++) {
err |= __put_user((int *) &(gw->win[window]),
(int **) gw->winptr + window);
err |= copy_to_user(&gw->win[window],
¤t_thread_info()->reg_window[window],
sizeof (svr4_rwindow_t));
err |= __put_user(0, (int *) gw->winptr + window);
}
#endif
/* 4. We just pay attention to the gw->count field on setcontext */
/* 3. We just pay attention to the gw->count field on setcontext */
set_thread_wsaved
(
0
);
/* So process is allowed to execute. */
/* Setup the signal information. Solaris expects a bunch of
...
...
@@ -915,14 +882,14 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
}
/* Arguments passed to signal handler */
if
(
regs
->
u_regs
[
14
]){
struct
reg_window32
*
rw
=
(
struct
reg_window32
*
)
(
regs
->
u_regs
[
14
]
&
0x00000000ffffffffUL
);
err
|=
__put_user
(
signr
,
&
rw
->
ins
[
0
]);
err
|=
__put_user
((
u64
)
si
,
&
rw
->
ins
[
1
]);
err
|=
__put_user
((
u64
)
uc
,
&
rw
->
ins
[
2
]);
err
|=
__put_user
((
u64
)
sfp
,
&
rw
->
ins
[
6
]);
/* frame pointer */
if
(
regs
->
u_regs
[
14
]){
struct
reg_window32
__user
*
rw
=
(
struct
reg_window32
__user
*
)
(
regs
->
u_regs
[
14
]
&
0x00000000ffffffffUL
);
err
|=
__put_user
(
signr
,
&
rw
->
ins
[
0
]);
err
|=
__put_user
((
u64
)
si
,
&
rw
->
ins
[
1
]);
err
|=
__put_user
((
u64
)
uc
,
&
rw
->
ins
[
2
]);
err
|=
__put_user
((
u64
)
sfp
,
&
rw
->
ins
[
6
]);
/* frame pointer */
if
(
err
)
goto
sigsegv
;
...
...
@@ -937,20 +904,21 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
}
asmlinkage
int
svr4_getcontext
(
svr4_ucontext_t
*
uc
,
struct
pt_regs
*
regs
)
svr4_getcontext
(
svr4_ucontext_t
__user
*
uc
,
struct
pt_regs
*
regs
)
{
svr4_gregset_t
*
gr
;
svr4_mcontext_t
*
mc
;
svr4_gregset_t
__user
*
gr
;
svr4_mcontext_t
__user
*
mc
;
svr4_sigset_t
setv
;
int
i
,
err
;
u32
psr
;
synchronize_user_stack
();
save_and_clear_fpu
();
if
(
get_thread_wsaved
())
do_exit
(
SIGSEGV
);
do_exit
(
SIGSEGV
);
err
=
clear_user
(
uc
,
sizeof
(
*
uc
));
err
=
clear_user
(
uc
,
sizeof
(
*
uc
));
/* Setup convenience variables */
mc
=
&
uc
->
mcontext
;
...
...
@@ -970,19 +938,17 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs)
regs
->
tpc
&=
0xffffffff
;
regs
->
tnpc
&=
0xffffffff
;
}
err
|=
__put_user
(
regs
->
tpc
,
&
uc
->
mcontext
.
greg
[
SVR4_PC
]);
err
|=
__put_user
(
regs
->
tnpc
,
&
uc
->
mcontext
.
greg
[
SVR4_NPC
]);
#if 1
err
|=
__put_user
(
0
,
&
uc
->
mcontext
.
greg
[
SVR4_PSR
]);
#else
i
=
tstate_to_psr
(
regs
->
tstate
)
&
~
PSR_EF
;
err
|=
__put_user
(
regs
->
tpc
,
&
uc
->
mcontext
.
greg
[
SVR4_PC
]);
err
|=
__put_user
(
regs
->
tnpc
,
&
uc
->
mcontext
.
greg
[
SVR4_NPC
]);
psr
=
tstate_to_psr
(
regs
->
tstate
)
&
~
PSR_EF
;
if
(
current_thread_info
()
->
fpsaved
[
0
]
&
FPRS_FEF
)
i
|=
PSR_EF
;
err
|=
__put_user
(
i
,
&
uc
->
mcontext
.
greg
[
SVR4_PSR
]);
#endif
err
|=
__put_user
(
regs
->
y
,
&
uc
->
mcontext
.
greg
[
SVR4_Y
]);
psr
|=
PSR_EF
;
err
|=
__put_user
(
psr
,
&
uc
->
mcontext
.
greg
[
SVR4_PSR
]);
err
|=
__put_user
(
regs
->
y
,
&
uc
->
mcontext
.
greg
[
SVR4_Y
]);
/* Copy g
[1..7] and o
[0..7] registers */
/* Copy g
[1..7] and o
[0..7] registers */
for
(
i
=
0
;
i
<
7
;
i
++
)
err
|=
__put_user
(
regs
->
u_regs
[
UREG_G1
+
i
],
(
&
(
*
gr
)[
SVR4_G1
])
+
i
);
for
(
i
=
0
;
i
<
8
;
i
++
)
...
...
@@ -1001,9 +967,9 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs)
/* Set the context for a svr4 application, this is Solaris way to sigreturn */
asmlinkage
int
svr4_setcontext
(
svr4_ucontext_t
*
c
,
struct
pt_regs
*
regs
)
asmlinkage
int
svr4_setcontext
(
svr4_ucontext_t
__user
*
c
,
struct
pt_regs
*
regs
)
{
svr4_gregset_t
*
gr
;
svr4_gregset_t
__user
*
gr
;
mm_segment_t
old_fs
;
u32
pc
,
npc
,
psr
;
sigset_t
set
;
...
...
@@ -1020,7 +986,7 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
goto
sigsegv
;
if
(((
unsigned
long
)
c
)
&
3
){
printk
(
"Unaligned structure passed
\n
"
);
printk
(
"Unaligned structure passed
\n
"
);
goto
sigsegv
;
}
...
...
@@ -1040,7 +1006,7 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
/* note that nPC is ored a 1, this is used to inform entry.S */
/* that we don't want it to mess with our PC and nPC */
err
|=
copy_from_user
(
&
setv
,
&
c
->
sigmask
,
sizeof
(
svr4_sigset_t
));
err
|=
copy_from_user
(
&
setv
,
&
c
->
sigmask
,
sizeof
(
svr4_sigset_t
));
set
.
sig
[
0
]
=
setv
.
sigbits
[
0
]
|
(((
long
)
setv
.
sigbits
[
1
])
<<
32
);
if
(
_NSIG_WORDS
>=
2
)
set
.
sig
[
1
]
=
setv
.
sigbits
[
2
]
|
(((
long
)
setv
.
sigbits
[
3
])
<<
32
);
...
...
@@ -1069,14 +1035,11 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
regs
->
tpc
&=
0xffffffff
;
regs
->
tnpc
&=
0xffffffff
;
}
err
|=
__get_user
(
regs
->
y
,
&
((
*
gr
)
[
SVR4_Y
]));
err
|=
__get_user
(
psr
,
&
((
*
gr
)
[
SVR4_PSR
]));
err
|=
__get_user
(
regs
->
y
,
&
((
*
gr
)[
SVR4_Y
]));
err
|=
__get_user
(
psr
,
&
((
*
gr
)[
SVR4_PSR
]));
regs
->
tstate
&=
~
(
TSTATE_ICC
|
TSTATE_XCC
);
regs
->
tstate
|=
psr_to_tstate_icc
(
psr
);
#if 0
if (psr & PSR_EF)
regs->tstate |= TSTATE_PEF;
#endif
/* Restore g[1..7] and o[0..7] registers */
for
(
i
=
0
;
i
<
7
;
i
++
)
err
|=
__get_user
(
regs
->
u_regs
[
UREG_G1
+
i
],
(
&
(
*
gr
)[
SVR4_G1
])
+
i
);
...
...
@@ -1094,7 +1057,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
unsigned
long
signr
,
sigset_t
*
oldset
,
siginfo_t
*
info
)
{
struct
rt_signal_frame32
*
sf
;
struct
rt_signal_frame32
__user
*
sf
;
int
sigframe_size
;
u32
psr
;
int
i
,
err
;
...
...
@@ -1108,9 +1071,10 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
if
(
!
(
current_thread_info
()
->
fpsaved
[
0
]
&
FPRS_FEF
))
sigframe_size
-=
sizeof
(
__siginfo_fpu_t
);
sf
=
(
struct
rt_signal_frame32
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
sf
=
(
struct
rt_signal_frame32
__user
*
)
get_sigframe
(
&
ka
->
sa
,
regs
,
sigframe_size
);
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
if
(
invalid_frame_pointer
(
sf
,
sigframe_size
))
goto
sigill
;
if
(
get_thread_wsaved
()
!=
0
)
...
...
@@ -1124,7 +1088,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
err
=
put_user
(
regs
->
tpc
,
&
sf
->
regs
.
pc
);
err
|=
__put_user
(
regs
->
tnpc
,
&
sf
->
regs
.
npc
);
err
|=
__put_user
(
regs
->
y
,
&
sf
->
regs
.
y
);
psr
=
tstate_to_psr
(
regs
->
tstate
);
psr
=
tstate_to_psr
(
regs
->
tstate
);
if
(
current_thread_info
()
->
fpsaved
[
0
]
&
FPRS_FEF
)
psr
|=
PSR_EF
;
err
|=
__put_user
(
psr
,
&
sf
->
regs
.
psr
);
...
...
@@ -1133,7 +1097,8 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
err
|=
__put_user
(
sizeof
(
siginfo_extra_v8plus_t
),
&
sf
->
extra_size
);
err
|=
__put_user
(
SIGINFO_EXTRA_V8PLUS_MAGIC
,
&
sf
->
v8plus
.
g_upper
[
0
]);
for
(
i
=
1
;
i
<
16
;
i
++
)
err
|=
__put_user
(((
u32
*
)
regs
->
u_regs
)[
2
*
i
],
&
sf
->
v8plus
.
g_upper
[
i
]);
err
|=
__put_user
(((
u32
*
)
regs
->
u_regs
)[
2
*
i
],
&
sf
->
v8plus
.
g_upper
[
i
]);
if
(
psr
&
PSR_EF
)
{
err
|=
save_fpu_state32
(
regs
,
&
sf
->
fpu_state
);
...
...
@@ -1162,8 +1127,8 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
}
err
|=
__copy_to_user
(
&
sf
->
mask
,
&
seta
,
sizeof
(
compat_sigset_t
));
err
|=
copy_in_user
((
u32
*
)
sf
,
(
u32
*
)(
regs
->
u_regs
[
UREG_FP
]),
err
|=
copy_in_user
((
u32
__user
*
)
sf
,
(
u32
__user
*
)(
regs
->
u_regs
[
UREG_FP
]),
sizeof
(
struct
reg_window32
));
if
(
err
)
goto
sigsegv
;
...
...
@@ -1204,7 +1169,8 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
preempt_disable
();
ptep
=
pte_offset_map
(
pmdp
,
address
);
if
(
pte_present
(
*
ptep
))
{
unsigned
long
page
=
(
unsigned
long
)
page_address
(
pte_page
(
*
ptep
));
unsigned
long
page
=
(
unsigned
long
)
page_address
(
pte_page
(
*
ptep
));
__asm__
__volatile__
(
" membar #StoreStore
\n
"
...
...
@@ -1229,7 +1195,8 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
int
svr4_signal
)
{
if
(
svr4_signal
)
setup_svr4_frame32
(
&
ka
->
sa
,
regs
->
tpc
,
regs
->
tnpc
,
regs
,
signr
,
oldset
);
setup_svr4_frame32
(
&
ka
->
sa
,
regs
->
tpc
,
regs
->
tnpc
,
regs
,
signr
,
oldset
);
else
{
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
setup_rt_frame32
(
ka
,
regs
,
signr
,
oldset
,
info
);
...
...
@@ -1322,13 +1289,16 @@ struct sigstack32 {
asmlinkage
int
do_sys32_sigstack
(
u32
u_ssptr
,
u32
u_ossptr
,
unsigned
long
sp
)
{
struct
sigstack32
*
ssptr
=
(
struct
sigstack32
*
)((
unsigned
long
)(
u_ssptr
));
struct
sigstack32
*
ossptr
=
(
struct
sigstack32
*
)((
unsigned
long
)(
u_ossptr
));
struct
sigstack32
__user
*
ssptr
=
(
struct
sigstack32
__user
*
)((
unsigned
long
)(
u_ssptr
));
struct
sigstack32
__user
*
ossptr
=
(
struct
sigstack32
__user
*
)((
unsigned
long
)(
u_ossptr
));
int
ret
=
-
EFAULT
;
/* First see if old state is wanted. */
if
(
ossptr
)
{
if
(
put_user
(
current
->
sas_ss_sp
+
current
->
sas_ss_size
,
&
ossptr
->
the_stack
)
||
if
(
put_user
(
current
->
sas_ss_sp
+
current
->
sas_ss_size
,
&
ossptr
->
the_stack
)
||
__put_user
(
on_sig_stack
(
sp
),
&
ossptr
->
cur_status
))
goto
out
;
}
...
...
@@ -1339,15 +1309,18 @@ asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
if
(
get_user
((
long
)
ss_sp
,
&
ssptr
->
the_stack
))
goto
out
;
/* If the current stack was set with sigaltstack, don't
swap stacks while we are on it. */
* swap stacks while we are on it.
*/
ret
=
-
EPERM
;
if
(
current
->
sas_ss_sp
&&
on_sig_stack
(
sp
))
goto
out
;
/* Since we don't know the extent of the stack, and we don't
track onstack-ness, but rather calculate it, we must
presume a size. Ho hum this interface is lossy. */
* track onstack-ness, but rather calculate it, we must
* presume a size. Ho hum this interface is lossy.
*/
current
->
sas_ss_sp
=
(
unsigned
long
)
ss_sp
-
SIGSTKSZ
;
current
->
sas_ss_size
=
SIGSTKSZ
;
}
...
...
@@ -1363,17 +1336,17 @@ asmlinkage int do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp)
int
ret
;
mm_segment_t
old_fs
;
if
(
ussa
&&
(
get_user
((
long
)
uss
.
ss_sp
,
&
((
stack_t32
*
)(
long
)
ussa
)
->
ss_sp
)
||
__get_user
(
uss
.
ss_flags
,
&
((
stack_t32
*
)(
long
)
ussa
)
->
ss_flags
)
||
__get_user
(
uss
.
ss_size
,
&
((
stack_t32
*
)(
long
)
ussa
)
->
ss_size
)))
if
(
ussa
&&
(
get_user
((
long
)
uss
.
ss_sp
,
&
((
stack_t32
__user
*
)(
long
)
ussa
)
->
ss_sp
)
||
__get_user
(
uss
.
ss_flags
,
&
((
stack_t32
__user
*
)(
long
)
ussa
)
->
ss_flags
)
||
__get_user
(
uss
.
ss_size
,
&
((
stack_t32
__user
*
)(
long
)
ussa
)
->
ss_size
)))
return
-
EFAULT
;
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
ret
=
do_sigaltstack
(
ussa
?
&
uss
:
NULL
,
uossa
?
&
uoss
:
NULL
,
sp
);
set_fs
(
old_fs
);
if
(
!
ret
&&
uossa
&&
(
put_user
((
long
)
uoss
.
ss_sp
,
&
((
stack_t32
*
)(
long
)
uossa
)
->
ss_sp
)
||
__put_user
(
uoss
.
ss_flags
,
&
((
stack_t32
*
)(
long
)
uossa
)
->
ss_flags
)
||
__put_user
(
uoss
.
ss_size
,
&
((
stack_t32
*
)(
long
)
uossa
)
->
ss_size
)))
if
(
!
ret
&&
uossa
&&
(
put_user
((
long
)
uoss
.
ss_sp
,
&
((
stack_t32
__user
*
)(
long
)
uossa
)
->
ss_sp
)
||
__put_user
(
uoss
.
ss_flags
,
&
((
stack_t32
__user
*
)(
long
)
uossa
)
->
ss_flags
)
||
__put_user
(
uoss
.
ss_size
,
&
((
stack_t32
__user
*
)(
long
)
uossa
)
->
ss_size
)))
return
-
EFAULT
;
return
ret
;
}
arch/sparc64/kernel/sys_sparc.c
View file @
a0e3315d
...
...
@@ -245,9 +245,9 @@ asmlinkage int sys_ipc (unsigned call, int first, int second, unsigned long thir
return
err
;
}
extern
asmlinkage
int
sys_newuname
(
struct
new_utsname
*
name
);
extern
asmlinkage
int
sys_newuname
(
struct
new_utsname
__user
*
name
);
asmlinkage
int
sparc64_newuname
(
struct
new_utsname
*
name
)
asmlinkage
int
sparc64_newuname
(
struct
new_utsname
__user
*
name
)
{
int
ret
=
sys_newuname
(
name
);
...
...
@@ -421,7 +421,7 @@ sparc_breakpoint (struct pt_regs *regs)
extern
void
check_pending
(
int
signum
);
asmlinkage
int
sys_getdomainname
(
char
*
name
,
int
len
)
asmlinkage
int
sys_getdomainname
(
char
__user
*
name
,
int
len
)
{
int
nlen
;
int
err
=
-
EFAULT
;
...
...
@@ -432,9 +432,9 @@ asmlinkage int sys_getdomainname(char *name, int len)
if
(
nlen
<
len
)
len
=
nlen
;
if
(
len
>
__NEW_UTS_LEN
)
if
(
len
>
__NEW_UTS_LEN
)
goto
done
;
if
(
copy_to_user
(
name
,
system_utsname
.
domainname
,
len
))
if
(
copy_to_user
(
name
,
system_utsname
.
domainname
,
len
))
goto
done
;
err
=
0
;
done:
...
...
@@ -458,7 +458,7 @@ asmlinkage int solaris_syscall(struct pt_regs *regs)
regs
->
tpc
&=
0xffffffff
;
regs
->
tnpc
&=
0xffffffff
;
}
if
(
++
count
<=
5
)
{
if
(
++
count
<=
5
)
{
printk
(
"For Solaris binary emulation you need solaris module loaded
\n
"
);
show_regs
(
regs
);
}
...
...
@@ -478,7 +478,7 @@ asmlinkage int sunos_syscall(struct pt_regs *regs)
regs
->
tpc
&=
0xffffffff
;
regs
->
tnpc
&=
0xffffffff
;
}
if
(
++
count
<=
20
)
if
(
++
count
<=
20
)
printk
(
"SunOS binary emulation not compiled in
\n
"
);
force_sig
(
SIGSEGV
,
current
);
...
...
@@ -486,9 +486,11 @@ asmlinkage int sunos_syscall(struct pt_regs *regs)
}
#endif
asmlinkage
int
sys_utrap_install
(
utrap_entry_t
type
,
utrap_handler_t
new_p
,
asmlinkage
int
sys_utrap_install
(
utrap_entry_t
type
,
utrap_handler_t
new_p
,
utrap_handler_t
new_d
,
utrap_handler_t
*
old_p
,
utrap_handler_t
*
old_d
)
utrap_handler_t
__user
*
old_p
,
utrap_handler_t
__user
*
old_d
)
{
if
(
type
<
UT_INSTRUCTION_EXCEPTION
||
type
>
UT_TRAP_INSTRUCTION_31
)
return
-
EINVAL
;
...
...
@@ -511,9 +513,11 @@ asmlinkage int sys_utrap_install(utrap_entry_t type, utrap_handler_t new_p,
if
(
!
current_thread_info
()
->
utraps
)
{
current_thread_info
()
->
utraps
=
kmalloc
((
UT_TRAP_INSTRUCTION_31
+
1
)
*
sizeof
(
long
),
GFP_KERNEL
);
if
(
!
current_thread_info
()
->
utraps
)
return
-
ENOMEM
;
if
(
!
current_thread_info
()
->
utraps
)
return
-
ENOMEM
;
current_thread_info
()
->
utraps
[
0
]
=
1
;
memset
(
current_thread_info
()
->
utraps
+
1
,
0
,
UT_TRAP_INSTRUCTION_31
*
sizeof
(
long
));
memset
(
current_thread_info
()
->
utraps
+
1
,
0
,
UT_TRAP_INSTRUCTION_31
*
sizeof
(
long
));
}
else
{
if
((
utrap_handler_t
)
current_thread_info
()
->
utraps
[
type
]
!=
new_p
&&
current_thread_info
()
->
utraps
[
0
]
>
1
)
{
...
...
include/asm-sparc/signal.h
View file @
a0e3315d
...
...
@@ -118,10 +118,10 @@ struct sigstack {
};
/* Sigvec flags */
#define SV_SSTACK 1
/* This signal handler should use sig-stack */
#define SV_INTR 2
/* Sig return should not restart system call */
#define SV_RESET 4
/* Set handler to SIG_DFL upon taken signal */
#define SV_IGNCHILD 8
/* Do not send SIGCHLD */
#define SV_SSTACK 1
u
/* This signal handler should use sig-stack */
#define SV_INTR 2
u
/* Sig return should not restart system call */
#define SV_RESET 4
u
/* Set handler to SIG_DFL upon taken signal */
#define SV_IGNCHILD 8
u
/* Do not send SIGCHLD */
/*
* sa_flags values: SA_STACK is not currently supported, but will allow the
...
...
@@ -137,11 +137,11 @@ struct sigstack {
#define SA_ONSTACK SV_SSTACK
#define SA_RESTART SV_INTR
#define SA_ONESHOT SV_RESET
#define SA_INTERRUPT 0x10
#define SA_NOMASK 0x20
#define SA_SHIRQ 0x40
#define SA_NOCLDWAIT 0x100
#define SA_SIGINFO 0x200
#define SA_INTERRUPT 0x10
u
#define SA_NOMASK 0x20
u
#define SA_SHIRQ 0x40
u
#define SA_NOCLDWAIT 0x100
u
#define SA_SIGINFO 0x200
u
#define SIG_BLOCK 0x01
/* for blocking signals */
#define SIG_UNBLOCK 0x02
/* for unblocking signals */
...
...
include/asm-sparc/uaccess.h
View file @
a0e3315d
...
...
@@ -8,6 +8,7 @@
#define _ASM_UACCESS_H
#ifdef __KERNEL__
#include <linux/compiler.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
...
...
@@ -45,7 +46,7 @@
#define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
extern
inline
int
verify_area
(
int
type
,
const
void
*
addr
,
unsigned
long
size
)
static
inline
int
verify_area
(
int
type
,
const
void
__user
*
addr
,
unsigned
long
size
)
{
return
access_ok
(
type
,
addr
,
size
)
?
0
:-
EFAULT
;
}
...
...
@@ -291,87 +292,87 @@ __asm__ __volatile__( \
extern
int
__get_user_bad
(
void
);
extern
__kernel_size_t
__copy_user
(
void
*
to
,
void
*
from
,
__kernel_size_t
size
);
#define copy_to_user(to,from,n) ({ \
void *__copy_to = (void *) (to); \
__kernel_size_t __copy_size = (__kernel_size_t) (n); \
__kernel_size_t __copy_res; \
if(__copy_size && __access_ok((unsigned long)__copy_to, __copy_size)) { \
__copy_res = __copy_user(__copy_to, (void *) (from), __copy_size); \
} else __copy_res = __copy_size; \
__copy_res; })
#define __copy_to_user(to,from,n) \
__copy_user((void *)(to), \
(void *)(from), n)
#define copy_from_user(to,from,n) ({ \
void *__copy_to = (void *) (to); \
void *__copy_from = (void *) (from); \
__kernel_size_t __copy_size = (__kernel_size_t) (n); \
__kernel_size_t __copy_res; \
if(__copy_size && __access_ok((unsigned long)__copy_from, __copy_size)) { \
__copy_res = __copy_user(__copy_to, __copy_from, __copy_size); \
} else __copy_res = __copy_size; \
__copy_res; })
#define __copy_from_user(to,from,n) \
__copy_user((void *)(to), \
(void *)(from), n)
extern
__inline__
__kernel_size_t
__clear_user
(
void
*
addr
,
__kernel_size_t
size
)
extern
unsigned
long
__copy_user
(
void
*
to
,
void
*
from
,
unsigned
long
size
);
static
inline
unsigned
long
copy_to_user
(
void
__user
*
to
,
void
*
from
,
unsigned
long
n
)
{
__kernel_size_t
ret
;
__asm__
__volatile__
(
".section __ex_table,#alloc
\n\t
"
".align 4
\n\t
"
".word 1f,3
\n\t
"
".previous
\n\t
"
"mov %2, %%o1
\n
"
"1:
\n\t
"
"call __bzero
\n\t
"
" mov %1, %%o0
\n\t
"
"mov %%o0, %0
\n
"
:
"=r"
(
ret
)
:
"r"
(
addr
),
"r"
(
size
)
:
"o0"
,
"o1"
,
"o2"
,
"o3"
,
"o4"
,
"o5"
,
"o7"
,
"g1"
,
"g2"
,
"g3"
,
"g4"
,
"g5"
,
"g7"
,
"cc"
);
return
ret
;
if
(
n
&&
__access_ok
((
unsigned
long
)
to
,
n
))
return
__copy_user
((
void
*
)
to
,
from
,
n
);
else
return
n
;
}
#define clear_user(addr,n) ({ \
void *__clear_addr = (void *) (addr); \
__kernel_size_t __clear_size = (__kernel_size_t) (n); \
__kernel_size_t __clear_res; \
if(__clear_size && __access_ok((unsigned long)__clear_addr, __clear_size)) { \
__clear_res = __clear_user(__clear_addr, __clear_size); \
} else __clear_res = __clear_size; \
__clear_res; })
extern
int
__strncpy_from_user
(
unsigned
long
dest
,
unsigned
long
src
,
int
count
);
#define strncpy_from_user(dest,src,count) ({ \
unsigned long __sfu_src = (unsigned long) (src); \
int __sfu_count = (int) (count); \
long __sfu_res = -EFAULT; \
if(__access_ok(__sfu_src, __sfu_count)) { \
__sfu_res = __strncpy_from_user((unsigned long) (dest), __sfu_src, __sfu_count); \
} __sfu_res; })
extern
int
__strlen_user
(
const
char
*
);
extern
int
__strnlen_user
(
const
char
*
,
long
len
);
extern
__inline__
int
strlen_user
(
const
char
*
str
)
static
inline
unsigned
long
__copy_to_user
(
void
__user
*
to
,
void
*
from
,
unsigned
long
n
)
{
return
__copy_user
((
void
*
)
to
,
from
,
n
);
}
static
inline
unsigned
long
copy_from_user
(
void
*
to
,
void
__user
*
from
,
unsigned
long
n
)
{
if
(
n
&&
__access_ok
((
unsigned
long
)
from
,
n
))
return
__copy_user
(
to
,
(
void
*
)
from
,
n
);
else
return
n
;
}
static
inline
unsigned
long
__copy_from_user
(
void
*
to
,
void
__user
*
from
,
unsigned
long
n
)
{
return
__copy_user
(
to
,
(
void
*
)
from
,
n
);
}
static
inline
unsigned
long
__clear_user
(
void
__user
*
addr
,
unsigned
long
size
)
{
unsigned
long
ret
;
__asm__
__volatile__
(
".section __ex_table,#alloc
\n\t
"
".align 4
\n\t
"
".word 1f,3
\n\t
"
".previous
\n\t
"
"mov %2, %%o1
\n
"
"1:
\n\t
"
"call __bzero
\n\t
"
" mov %1, %%o0
\n\t
"
"mov %%o0, %0
\n
"
:
"=r"
(
ret
)
:
"r"
(
addr
),
"r"
(
size
)
:
"o0"
,
"o1"
,
"o2"
,
"o3"
,
"o4"
,
"o5"
,
"o7"
,
"g1"
,
"g2"
,
"g3"
,
"g4"
,
"g5"
,
"g7"
,
"cc"
);
return
ret
;
}
static
inline
unsigned
long
clear_user
(
void
__user
*
addr
,
unsigned
long
n
)
{
if
(
n
&&
__access_ok
((
unsigned
long
)
addr
,
n
))
{
return
__clear_user
(
addr
,
n
);
else
return
n
;
}
extern
long
__strncpy_from_user
(
char
*
dest
,
const
char
__user
*
src
,
long
count
);
static
inline
long
strncpy_from_user
(
char
*
dest
,
const
char
__user
*
src
,
long
count
)
{
if
(
__access_ok
((
unsigned
long
)
src
,
count
))
return
__strncpy_from_user
(
dest
,
src
,
count
);
else
return
-
EFAULT
;
}
extern
long
__strlen_user
(
const
char
__user
*
);
extern
long
__strnlen_user
(
const
char
__user
*
,
long
len
);
static
inline
long
strlen_user
(
const
char
__user
*
str
)
{
if
(
!
access_ok
(
VERIFY_READ
,
str
,
0
))
if
(
!
access_ok
(
VERIFY_READ
,
str
,
0
))
return
0
;
else
return
__strlen_user
(
str
);
}
extern
__inline__
int
strnlen_user
(
const
cha
r
*
str
,
long
len
)
static
inline
long
strnlen_user
(
const
char
__use
r
*
str
,
long
len
)
{
if
(
!
access_ok
(
VERIFY_READ
,
str
,
0
))
if
(
!
access_ok
(
VERIFY_READ
,
str
,
0
))
return
0
;
else
return
__strnlen_user
(
str
,
len
);
...
...
include/asm-sparc64/signal.h
View file @
a0e3315d
...
...
@@ -123,10 +123,10 @@ struct sigstack {
};
/* Sigvec flags */
#define SV_SSTACK 1
/* This signal handler should use sig-stack */
#define SV_INTR 2
/* Sig return should not restart system call */
#define SV_RESET 4
/* Set handler to SIG_DFL upon taken signal */
#define SV_IGNCHILD 8
/* Do not send SIGCHLD */
#define SV_SSTACK 1
u
/* This signal handler should use sig-stack */
#define SV_INTR 2
u
/* Sig return should not restart system call */
#define SV_RESET 4
u
/* Set handler to SIG_DFL upon taken signal */
#define SV_IGNCHILD 8
u
/* Do not send SIGCHLD */
/*
* sa_flags values: SA_STACK is not currently supported, but will allow the
...
...
@@ -142,11 +142,11 @@ struct sigstack {
#define SA_ONSTACK SV_SSTACK
#define SA_RESTART SV_INTR
#define SA_ONESHOT SV_RESET
#define SA_INTERRUPT 0x10
#define SA_NOMASK 0x20
#define SA_SHIRQ 0x40
#define SA_NOCLDWAIT 0x100
#define SA_SIGINFO 0x200
#define SA_INTERRUPT 0x10
u
#define SA_NOMASK 0x20
u
#define SA_SHIRQ 0x40
u
#define SA_NOCLDWAIT 0x100
u
#define SA_SIGINFO 0x200
u
#define SIG_BLOCK 0x01
/* for blocking signals */
...
...
include/asm-sparc64/uaccess.h
View file @
a0e3315d
...
...
@@ -7,6 +7,7 @@
*/
#ifdef __KERNEL__
#include <linux/compiler.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <asm/a.out.h>
...
...
@@ -52,7 +53,7 @@ do { \
#define __access_ok(addr,size) 1
#define access_ok(type,addr,size) 1
static
inline
int
verify_area
(
int
type
,
const
void
*
addr
,
unsigned
long
size
)
static
inline
int
verify_area
(
int
type
,
const
void
__user
*
addr
,
unsigned
long
size
)
{
return
0
;
}
...
...
@@ -249,44 +250,34 @@ __asm__ __volatile__( \
extern
int
__get_user_bad
(
void
);
extern
__kernel_size_t
__copy_from_user
(
void
*
to
,
const
void
*
from
,
__kernel_size_t
size
);
extern
unsigned
long
__copy_from_user
(
void
*
to
,
const
void
__user
*
from
,
unsigned
long
size
);
extern
__kernel_size_t
__copy_to_user
(
void
*
to
,
const
void
*
from
,
__kernel_size_t
size
);
extern
unsigned
long
__copy_to_user
(
void
__user
*
to
,
const
void
*
from
,
unsigned
long
size
);
extern
__kernel_size_t
__copy_in_user
(
void
*
to
,
const
void
*
from
,
__kernel_size_t
size
);
extern
unsigned
long
__copy_in_user
(
void
__user
*
to
,
const
void
__user
*
from
,
unsigned
long
size
);
#define copy_from_user
(to,from,n) \
__copy_from_user((void *)(to), \
(void *)(from), (__kernel_size_t)(n))
#define copy_from_user
__copy_from_user
#define copy_to_user __copy_to_user
#define copy_in_user __copy_in_user
#define copy_to_user(to,from,n) \
__copy_to_user((void *)(to), \
(void *) (from), (__kernel_size_t)(n))
#define copy_in_user(to,from,n) \
__copy_in_user((void *)(to), \
(void *) (from), (__kernel_size_t)(n))
static
__inline__
__kernel_size_t
__clear_user
(
void
*
addr
,
__kernel_size_t
size
)
static
inline
unsigned
long
__clear_user
(
void
__user
*
addr
,
unsigned
long
size
)
{
extern
__kernel_size_t
__bzero_noasi
(
void
*
addr
,
__kernel_size_t
size
);
extern
unsigned
long
__bzero_noasi
(
void
*
addr
,
unsigned
long
size
);
return
__bzero_noasi
(
addr
,
size
);
return
__bzero_noasi
(
(
void
*
)
addr
,
size
);
}
#define clear_user(addr,n) \
__clear_user((void *)(addr), (__kernel_size_t)(n))
#define clear_user __clear_user
extern
int
__strncpy_from_user
(
unsigned
long
dest
,
unsigned
long
src
,
int
count
);
extern
long
__strncpy_from_user
(
char
*
dest
,
const
char
__user
*
src
,
long
count
);
#define strncpy_from_user(dest,src,count) \
__strncpy_from_user((unsigned long)(dest), (unsigned long)(src), (int)(count))
#define strncpy_from_user __strncpy_from_user
extern
int
__strlen_user
(
const
cha
r
*
);
extern
int
__strnlen_user
(
const
cha
r
*
,
long
len
);
extern
long
__strlen_user
(
const
char
__use
r
*
);
extern
long
__strnlen_user
(
const
char
__use
r
*
,
long
len
);
#define strlen_user __strlen_user
#define strnlen_user __strnlen_user
...
...
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