Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
32360cdf
Commit
32360cdf
authored
May 31, 2004
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SPARC]: First stage of sparc32 sparse work.
parent
5cea1125
Changes
20
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
313 additions
and
266 deletions
+313
-266
arch/sparc/kernel/apc.c
arch/sparc/kernel/apc.c
+34
-37
arch/sparc/kernel/ebus.c
arch/sparc/kernel/ebus.c
+2
-2
arch/sparc/kernel/irq.c
arch/sparc/kernel/irq.c
+2
-1
arch/sparc/kernel/muldiv.c
arch/sparc/kernel/muldiv.c
+28
-21
arch/sparc/kernel/process.c
arch/sparc/kernel/process.c
+49
-38
arch/sparc/kernel/ptrace.c
arch/sparc/kernel/ptrace.c
+14
-8
arch/sparc/kernel/signal.c
arch/sparc/kernel/signal.c
+20
-9
arch/sparc/kernel/sunos_ioctl.c
arch/sparc/kernel/sunos_ioctl.c
+18
-17
arch/sparc/kernel/sys_sparc.c
arch/sparc/kernel/sys_sparc.c
+7
-3
arch/sparc/kernel/sys_sunos.c
arch/sparc/kernel/sys_sunos.c
+81
-74
arch/sparc/kernel/unaligned.c
arch/sparc/kernel/unaligned.c
+16
-13
arch/sparc/kernel/windows.c
arch/sparc/kernel/windows.c
+5
-4
arch/sparc/math-emu/math.c
arch/sparc/math-emu/math.c
+12
-12
arch/sparc/mm/fault.c
arch/sparc/mm/fault.c
+3
-3
include/asm-sparc/hardirq.h
include/asm-sparc/hardirq.h
+0
-9
include/asm-sparc/ipc.h
include/asm-sparc/ipc.h
+1
-1
include/asm-sparc/semaphore.h
include/asm-sparc/semaphore.h
+7
-7
include/asm-sparc/signal.h
include/asm-sparc/signal.h
+2
-2
include/asm-sparc/thread_info.h
include/asm-sparc/thread_info.h
+1
-0
include/asm-sparc/uaccess.h
include/asm-sparc/uaccess.h
+11
-5
No files found.
arch/sparc/kernel/apc.c
View file @
32360cdf
...
...
@@ -84,47 +84,44 @@ static int apc_release(struct inode *inode, struct file *f)
}
static
int
apc_ioctl
(
struct
inode
*
inode
,
struct
file
*
f
,
unsigned
int
cmd
,
unsigned
long
arg
)
unsigned
int
cmd
,
unsigned
long
__
arg
)
{
__u8
inarg
;
__u8
inarg
,
__user
*
arg
;
arg
=
(
__u8
__user
*
)
__arg
;
switch
(
cmd
)
{
case
APCIOCGFANCTL
:
if
(
put_user
(
apc_readb
(
APC_FANCTL_REG
)
&
APC_REGMASK
,
(
__u8
*
)
arg
))
{
case
APCIOCGFANCTL
:
if
(
put_user
(
apc_readb
(
APC_FANCTL_REG
)
&
APC_REGMASK
,
arg
))
return
-
EFAULT
;
}
break
;
case
APCIOCGCPWR
:
if
(
put_user
(
apc_readb
(
APC_CPOWER_REG
)
&
APC_REGMASK
,
(
__u8
*
)
arg
))
{
return
-
EFAULT
;
}
break
;
case
APCIOCGBPORT
:
if
(
put_user
(
apc_readb
(
APC_BPORT_REG
)
&
APC_BPMASK
,
(
__u8
*
)
arg
))
{
return
-
EFAULT
;
}
break
;
case
APCIOCSFANCTL
:
if
(
get_user
(
inarg
,
(
__u8
*
)
arg
))
{
return
-
EFAULT
;
}
apc_writeb
(
inarg
&
APC_REGMASK
,
APC_FANCTL_REG
);
break
;
case
APCIOCSCPWR
:
if
(
get_user
(
inarg
,
(
__u8
*
)
arg
))
{
return
-
EFAULT
;
}
apc_writeb
(
inarg
&
APC_REGMASK
,
APC_CPOWER_REG
);
break
;
case
APCIOCSBPORT
:
if
(
get_user
(
inarg
,
(
__u8
*
)
arg
))
{
return
-
EFAULT
;
}
apc_writeb
(
inarg
&
APC_BPMASK
,
APC_BPORT_REG
);
break
;
default:
return
-
EINVAL
;
break
;
case
APCIOCGCPWR
:
if
(
put_user
(
apc_readb
(
APC_CPOWER_REG
)
&
APC_REGMASK
,
arg
))
return
-
EFAULT
;
break
;
case
APCIOCGBPORT
:
if
(
put_user
(
apc_readb
(
APC_BPORT_REG
)
&
APC_BPMASK
,
arg
))
return
-
EFAULT
;
break
;
case
APCIOCSFANCTL
:
if
(
get_user
(
inarg
,
arg
))
return
-
EFAULT
;
apc_writeb
(
inarg
&
APC_REGMASK
,
APC_FANCTL_REG
);
break
;
case
APCIOCSCPWR
:
if
(
get_user
(
inarg
,
arg
))
return
-
EFAULT
;
apc_writeb
(
inarg
&
APC_REGMASK
,
APC_CPOWER_REG
);
break
;
case
APCIOCSBPORT
:
if
(
get_user
(
inarg
,
arg
))
return
-
EFAULT
;
apc_writeb
(
inarg
&
APC_BPMASK
,
APC_BPORT_REG
);
break
;
default:
return
-
EINVAL
;
};
return
0
;
...
...
arch/sparc/kernel/ebus.c
View file @
32360cdf
...
...
@@ -238,7 +238,7 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
child
->
bus
=
dev
->
bus
;
fill_ebus_child
(
node
,
&
regs
[
0
],
child
);
while
((
node
=
prom_getsibling
(
node
)))
{
while
((
node
=
prom_getsibling
(
node
))
!=
0
)
{
child
->
next
=
(
struct
linux_ebus_child
*
)
ebus_alloc
(
sizeof
(
struct
linux_ebus_child
));
...
...
@@ -330,7 +330,7 @@ void __init ebus_init(void)
dev
->
bus
=
ebus
;
fill_ebus_device
(
nd
,
dev
);
while
((
nd
=
prom_getsibling
(
nd
)))
{
while
((
nd
=
prom_getsibling
(
nd
))
!=
0
)
{
dev
->
next
=
(
struct
linux_ebus_device
*
)
ebus_alloc
(
sizeof
(
struct
linux_ebus_device
));
...
...
arch/sparc/kernel/irq.c
View file @
32360cdf
...
...
@@ -216,7 +216,8 @@ void free_irq(unsigned int irq, void *dev_id)
if
(
sparc_cpu_model
==
sun4d
)
{
extern
void
sun4d_free_irq
(
unsigned
int
,
void
*
);
return
sun4d_free_irq
(
irq
,
dev_id
);
sun4d_free_irq
(
irq
,
dev_id
);
return
;
}
cpu_irq
=
irq
&
(
NR_IRQS
-
1
);
if
(
cpu_irq
>
14
)
{
/* 14 irq levels on the sparc */
...
...
arch/sparc/kernel/muldiv.c
View file @
32360cdf
...
...
@@ -54,25 +54,25 @@ static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2,
}
}
#define fetch_reg(reg, regs) ({
\
struct reg_window
*win;
\
register unsigned long ret;
\
\
if (!(reg)) ret = 0;
\
else if
((reg) < 16) {
\
ret = regs->u_regs[(reg)];
\
} else {
\
/* Ho hum, the slightly complicated case. */
\
win = (struct reg_window
*)regs->u_regs[UREG_FP];
\
if (get_user (ret, &win->locals[(reg) - 16])) return -1;
\
}
\
ret;
\
#define fetch_reg(reg, regs) ({ \
struct reg_window
__user *win;
\
register unsigned long ret; \
\
if (!(reg)) ret = 0; \
else if
((reg) < 16) {
\
ret = regs->u_regs[(reg)]; \
} else { \
/* Ho hum, the slightly complicated case. */
\
win = (struct reg_window
__user *)regs->u_regs[UREG_FP];
\
if (get_user (ret, &win->locals[(reg) - 16])) return -1;\
} \
ret; \
})
static
inline
int
store_reg
(
unsigned
int
result
,
unsigned
int
reg
,
struct
pt_regs
*
regs
)
{
struct
reg_window
*
win
;
struct
reg_window
__user
*
win
;
if
(
!
reg
)
return
0
;
...
...
@@ -81,7 +81,7 @@ store_reg(unsigned int result, unsigned int reg, struct pt_regs *regs)
return
0
;
}
else
{
/* need to use put_user() in this case: */
win
=
(
struct
reg_window
*
)
regs
->
u_regs
[
UREG_FP
];
win
=
(
struct
reg_window
__user
*
)
regs
->
u_regs
[
UREG_FP
];
return
(
put_user
(
result
,
&
win
->
locals
[
reg
-
16
]));
}
}
...
...
@@ -89,23 +89,30 @@ store_reg(unsigned int result, unsigned int reg, struct pt_regs *regs)
extern
void
handle_hw_divzero
(
struct
pt_regs
*
regs
,
unsigned
long
pc
,
unsigned
long
npc
,
unsigned
long
psr
);
/* Should return 0 if mul/div emulation succeeded and SIGILL should not be issued */
/* Should return 0 if mul/div emulation succeeded and SIGILL should
* not be issued.
*/
int
do_user_muldiv
(
struct
pt_regs
*
regs
,
unsigned
long
pc
)
{
unsigned
int
insn
;
int
inst
;
unsigned
int
rs1
,
rs2
,
rdv
;
if
(
!
pc
)
return
-
1
;
/* This happens to often, I think */
if
(
get_user
(
insn
,
(
unsigned
int
*
)
pc
))
return
-
1
;
if
((
insn
&
0xc1400000
)
!=
0x80400000
)
return
-
1
;
if
(
!
pc
)
return
-
1
;
/* This happens to often, I think */
if
(
get_user
(
insn
,
(
unsigned
int
__user
*
)
pc
))
return
-
1
;
if
((
insn
&
0xc1400000
)
!=
0x80400000
)
return
-
1
;
inst
=
((
insn
>>
19
)
&
0xf
);
if
((
inst
&
0xe
)
!=
10
&&
(
inst
&
0xe
)
!=
14
)
return
-
1
;
if
((
inst
&
0xe
)
!=
10
&&
(
inst
&
0xe
)
!=
14
)
return
-
1
;
/* Now we know we have to do something with umul, smul, udiv or sdiv */
rs1
=
(
insn
>>
14
)
&
0x1f
;
rs2
=
insn
&
0x1f
;
rdv
=
(
insn
>>
25
)
&
0x1f
;
if
(
has_imm13
(
insn
))
{
if
(
has_imm13
(
insn
))
{
maybe_flush_windows
(
rs1
,
0
,
rdv
);
rs2
=
sign_extend_imm13
(
insn
);
}
else
{
...
...
arch/sparc/kernel/process.c
View file @
32360cdf
...
...
@@ -400,23 +400,30 @@ void flush_thread(void)
}
}
static
__inline__
struct
sparc_stackf
*
clone_stackframe
(
struct
sparc_stackf
*
dst
,
struct
sparc_stackf
*
src
)
static
__inline__
struct
sparc_stackf
__user
*
clone_stackframe
(
struct
sparc_stackf
__user
*
dst
,
struct
sparc_stackf
__user
*
src
)
{
unsigned
long
size
;
struct
sparc_stackf
*
sp
;
unsigned
long
size
,
fp
;
struct
sparc_stackf
*
tmp
;
struct
sparc_stackf
__user
*
sp
;
if
(
get_user
(
tmp
,
&
src
->
fp
))
return
NULL
;
size
=
((
unsigned
long
)
src
->
fp
)
-
((
unsigned
long
)
src
);
sp
=
(
struct
sparc_stackf
*
)(((
unsigned
long
)
dst
)
-
size
);
fp
=
(
unsigned
long
)
tmp
;
size
=
(
fp
-
((
unsigned
long
)
src
));
fp
=
(
unsigned
long
)
dst
;
sp
=
(
struct
sparc_stackf
__user
*
)(
fp
-
size
);
/* do_fork() grabs the parent semaphore, we must release it
* temporarily so we can build the child clone stack frame
* without deadlocking.
*/
if
(
copy_to
_user
(
sp
,
src
,
size
))
sp
=
(
struct
sparc_stackf
*
)
0
;
else
if
(
put_user
(
dst
,
&
sp
->
fp
))
sp
=
(
struct
sparc_stackf
*
)
0
;
if
(
__copy
_user
(
sp
,
src
,
size
))
sp
=
NULL
;
else
if
(
put_user
(
fp
,
&
sp
->
fp
))
sp
=
NULL
;
return
sp
;
}
...
...
@@ -435,8 +442,8 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags,
return
do_fork
(
clone_flags
,
stack_start
,
regs
,
stack_size
,
(
int
*
)
parent_tid_ptr
,
(
int
*
)
child_tid_ptr
);
(
int
__user
*
)
parent_tid_ptr
,
(
int
__user
*
)
child_tid_ptr
);
}
/* Copy a Sparc thread. The fork() return value conventions
...
...
@@ -519,15 +526,17 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
p
->
thread
.
current_ds
=
USER_DS
;
if
(
sp
!=
regs
->
u_regs
[
UREG_FP
])
{
struct
sparc_stackf
*
childstack
;
struct
sparc_stackf
*
parentstack
;
struct
sparc_stackf
__user
*
childstack
;
struct
sparc_stackf
__user
*
parentstack
;
/*
* This is a clone() call with supplied user stack.
* Set some valid stack frames to give to the child.
*/
childstack
=
(
struct
sparc_stackf
*
)
(
sp
&
~
0x7UL
);
parentstack
=
(
struct
sparc_stackf
*
)
regs
->
u_regs
[
UREG_FP
];
childstack
=
(
struct
sparc_stackf
__user
*
)
(
sp
&
~
0x7UL
);
parentstack
=
(
struct
sparc_stackf
__user
*
)
regs
->
u_regs
[
UREG_FP
];
#if 0
printk("clone: parent stack:\n");
...
...
@@ -654,12 +663,14 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
if
(
regs
->
u_regs
[
UREG_G1
]
==
0
)
base
=
1
;
filename
=
getname
((
char
*
)
regs
->
u_regs
[
base
+
UREG_I0
]);
filename
=
getname
((
char
__user
*
)
regs
->
u_regs
[
base
+
UREG_I0
]);
error
=
PTR_ERR
(
filename
);
if
(
IS_ERR
(
filename
))
goto
out
;
error
=
do_execve
(
filename
,
(
char
**
)
regs
->
u_regs
[
base
+
UREG_I1
],
(
char
**
)
regs
->
u_regs
[
base
+
UREG_I2
],
regs
);
error
=
do_execve
(
filename
,
(
char
__user
*
__user
*
)
regs
->
u_regs
[
base
+
UREG_I1
],
(
char
__user
*
__user
*
)
regs
->
u_regs
[
base
+
UREG_I2
],
regs
);
putname
(
filename
);
if
(
error
==
0
)
current
->
ptrace
&=
~
PT_DTRACE
;
...
...
@@ -679,25 +690,25 @@ pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
long
retval
;
__asm__
__volatile
(
"mov %4, %%g2
\n\t
"
/* Set aside fn ptr... */
"mov %5, %%g3
\n\t
"
/* and arg. */
"mov %1, %%g1
\n\t
"
"mov %2, %%o0
\n\t
"
/* Clone flags. */
"mov 0, %%o1
\n\t
"
/* usp arg == 0 */
"t 0x10
\n\t
"
/* Linux/Sparc clone(). */
"cmp %%o1, 0
\n\t
"
"be 1f
\n\t
"
/* The parent, just return. */
" nop
\n\t
"
/* Delay slot. */
"jmpl %%g2, %%o7
\n\t
"
/* Call the function. */
" mov %%g3, %%o0
\n\t
"
/* Get back the arg in delay. */
"mov %3, %%g1
\n\t
"
"t 0x10
\n\t
"
/* Linux/Sparc exit(). */
/* Notreached by child. */
"1: mov %%o0, %0
\n\t
"
:
"=r"
(
retval
)
:
"i"
(
__NR_clone
),
"r"
(
flags
|
CLONE_VM
|
CLONE_UNTRACED
),
"i"
(
__NR_exit
),
"r"
(
fn
),
"r"
(
arg
)
:
"g1"
,
"g2"
,
"g3"
,
"o0"
,
"o1"
,
"memory"
,
"cc"
);
__asm__
__volatile
__
(
"mov %4, %%g2
\n\t
"
/* Set aside fn ptr... */
"mov %5, %%g3
\n\t
"
/* and arg. */
"mov %1, %%g1
\n\t
"
"mov %2, %%o0
\n\t
"
/* Clone flags. */
"mov 0, %%o1
\n\t
"
/* usp arg == 0 */
"t 0x10
\n\t
"
/* Linux/Sparc clone(). */
"cmp %%o1, 0
\n\t
"
"be 1f
\n\t
"
/* The parent, just return. */
" nop
\n\t
"
/* Delay slot. */
"jmpl %%g2, %%o7
\n\t
"
/* Call the function. */
" mov %%g3, %%o0
\n\t
"
/* Get back the arg in delay. */
"mov %3, %%g1
\n\t
"
"t 0x10
\n\t
"
/* Linux/Sparc exit(). */
/* Notreached by child. */
"1: mov %%o0, %0
\n\t
"
:
"=r"
(
retval
)
:
"i"
(
__NR_clone
),
"r"
(
flags
|
CLONE_VM
|
CLONE_UNTRACED
),
"i"
(
__NR_exit
),
"r"
(
fn
),
"r"
(
arg
)
:
"g1"
,
"g2"
,
"g3"
,
"o0"
,
"o1"
,
"memory"
,
"cc"
);
return
retval
;
}
...
...
arch/sparc/kernel/ptrace.c
View file @
32360cdf
...
...
@@ -50,8 +50,10 @@ static inline void pt_succ_return(struct pt_regs *regs, unsigned long value)
static
void
pt_succ_return_linux
(
struct
pt_regs
*
regs
,
unsigned
long
value
,
long
*
addr
)
{
if
(
put_user
(
value
,
addr
))
return
pt_error_return
(
regs
,
EFAULT
);
if
(
put_user
(
value
,
(
long
__user
*
)
addr
))
{
pt_error_return
(
regs
,
EFAULT
);
return
;
}
regs
->
u_regs
[
UREG_I0
]
=
0
;
regs
->
psr
&=
~
PSR_C
;
regs
->
pc
=
regs
->
npc
;
...
...
@@ -368,7 +370,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
case
PTRACE_GETREGS
:
{
struct
pt_regs
*
pregs
=
(
struct
pt_regs
*
)
addr
;
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
child
->
thread
.
kregs
;
int
rval
;
...
...
@@ -391,7 +393,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
case
PTRACE_SETREGS
:
{
struct
pt_regs
*
pregs
=
(
struct
pt_regs
*
)
addr
;
struct
pt_regs
__user
*
pregs
=
(
struct
pt_regs
__user
*
)
addr
;
struct
pt_regs
*
cregs
=
child
->
thread
.
kregs
;
unsigned
long
psr
,
pc
,
npc
,
y
;
int
i
;
...
...
@@ -433,7 +435,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
unsigned
long
*
insnaddr
;
unsigned
long
insn
;
}
fpq
[
16
];
}
*
fps
=
(
struct
fps
*
)
addr
;
};
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
int
i
;
i
=
verify_area
(
VERIFY_WRITE
,
fps
,
sizeof
(
struct
fps
));
...
...
@@ -467,7 +470,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
unsigned
long
*
insnaddr
;
unsigned
long
insn
;
}
fpq
[
16
];
}
*
fps
=
(
struct
fps
*
)
addr
;
};
struct
fps
__user
*
fps
=
(
struct
fps
__user
*
)
addr
;
int
i
;
i
=
verify_area
(
VERIFY_READ
,
fps
,
sizeof
(
struct
fps
));
...
...
@@ -489,7 +493,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
case
PTRACE_READTEXT
:
case
PTRACE_READDATA
:
{
int
res
=
ptrace_readdata
(
child
,
addr
,
(
void
*
)
addr2
,
data
);
int
res
=
ptrace_readdata
(
child
,
addr
,
(
void
__user
*
)
addr2
,
data
);
if
(
res
==
data
)
{
pt_succ_return
(
regs
,
0
);
...
...
@@ -504,7 +509,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
case
PTRACE_WRITETEXT
:
case
PTRACE_WRITEDATA
:
{
int
res
=
ptrace_writedata
(
child
,
(
void
*
)
addr2
,
addr
,
data
);
int
res
=
ptrace_writedata
(
child
,
(
void
__user
*
)
addr2
,
addr
,
data
);
if
(
res
==
data
)
{
pt_succ_return
(
regs
,
0
);
...
...
arch/sparc/kernel/signal.c
View file @
32360cdf
...
...
@@ -234,7 +234,7 @@ static inline void do_new_sigreturn (struct pt_regs *regs)
if
(
verify_area
(
VERIFY_READ
,
sf
,
sizeof
(
*
sf
)))
goto
segv_and_exit
;
if
(((
u
int
)
sf
)
&
3
)
if
(((
u
nsigned
long
)
sf
)
&
3
)
goto
segv_and_exit
;
err
=
__get_user
(
pc
,
&
sf
->
info
.
si_regs
.
pc
);
...
...
@@ -289,8 +289,10 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
synchronize_user_stack
();
if
(
current
->
thread
.
new_signal
)
return
do_new_sigreturn
(
regs
);
if
(
current
->
thread
.
new_signal
)
{
do_new_sigreturn
(
regs
);
return
;
}
scptr
=
(
struct
sigcontext
__user
*
)
regs
->
u_regs
[
UREG_I0
];
...
...
@@ -347,6 +349,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
struct
rt_signal_frame
__user
*
sf
;
unsigned
int
psr
,
pc
,
npc
;
__siginfo_fpu_t
__user
*
fpu_save
;
mm_segment_t
old_fs
;
sigset_t
set
;
stack_t
st
;
int
err
;
...
...
@@ -386,7 +389,10 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
/* It is more difficult to avoid calling this function than to
* call it and ignore errors.
*/
do_sigaltstack
(
&
st
,
NULL
,
(
unsigned
long
)
sf
);
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
do_sigaltstack
((
const
stack_t
__user
*
)
&
st
,
NULL
,
(
unsigned
long
)
sf
);
set_fs
(
old_fs
);
sigdelsetmask
(
&
set
,
~
_BLOCKABLE
);
spin_lock_irq
(
&
current
->
sighand
->
siglock
);
...
...
@@ -849,7 +855,7 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
/* Arguments passed to signal handler */
if
(
regs
->
u_regs
[
14
]){
struct
reg_window
*
rw
=
(
struct
reg_window
__user
*
)
struct
reg_window
__user
*
rw
=
(
struct
reg_window
__user
*
)
regs
->
u_regs
[
14
];
err
|=
__put_user
(
signr
,
&
rw
->
ins
[
0
]);
...
...
@@ -860,8 +866,8 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
goto
sigsegv
;
regs
->
u_regs
[
UREG_I0
]
=
signr
;
regs
->
u_regs
[
UREG_I1
]
=
(
u
int
)
si
;
regs
->
u_regs
[
UREG_I2
]
=
(
u
int
)
uc
;
regs
->
u_regs
[
UREG_I1
]
=
(
u
nsigned
long
)
si
;
regs
->
u_regs
[
UREG_I2
]
=
(
u
nsigned
long
)
uc
;
}
return
;
...
...
@@ -932,6 +938,7 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
{
svr4_gregset_t
__user
*
gr
;
unsigned
long
pc
,
npc
,
psr
;
mm_segment_t
old_fs
;
sigset_t
set
;
svr4_sigset_t
setv
;
int
err
;
...
...
@@ -945,7 +952,7 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
if
(
current_thread_info
()
->
w_saved
)
goto
sigsegv_and_return
;
if
(((
u
int
)
c
)
&
3
)
if
(((
u
nsigned
long
)
c
)
&
3
)
goto
sigsegv_and_return
;
if
(
!
__access_ok
((
unsigned
long
)
c
,
sizeof
(
*
c
)))
...
...
@@ -977,7 +984,11 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
do_sigaltstack
(
&
st
,
NULL
,
regs
->
u_regs
[
UREG_I6
]);
old_fs
=
get_fs
();
set_fs
(
KERNEL_DS
);
do_sigaltstack
((
const
stack_t
__user
*
)
&
st
,
NULL
,
regs
->
u_regs
[
UREG_I6
]);
set_fs
(
old_fs
);
set
.
sig
[
0
]
=
setv
.
sigbits
[
0
];
set
.
sig
[
1
]
=
setv
.
sigbits
[
1
];
...
...
arch/sparc/kernel/sunos_ioctl.c
View file @
32360cdf
...
...
@@ -41,18 +41,19 @@ asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
goto
out
;
/* First handle an easy compat. case for tty ldisc. */
if
(
cmd
==
TIOCSETD
)
{
int
*
p
,
ntty
=
N_TTY
,
tmp
;
if
(
cmd
==
TIOCSETD
)
{
int
__user
*
p
;
int
ntty
=
N_TTY
,
tmp
;
mm_segment_t
oldfs
;
p
=
(
int
*
)
arg
;
p
=
(
int
__user
*
)
arg
;
ret
=
-
EFAULT
;
if
(
get_user
(
tmp
,
p
))
if
(
get_user
(
tmp
,
p
))
goto
out
;
if
(
tmp
==
2
)
{
if
(
tmp
==
2
)
{
oldfs
=
get_fs
();
set_fs
(
KERNEL_DS
);
ret
=
sys_ioctl
(
fd
,
cmd
,
(
int
)
&
ntty
);
ret
=
sys_ioctl
(
fd
,
cmd
,
(
unsigned
long
)
&
ntty
);
set_fs
(
oldfs
);
ret
=
(
ret
==
-
EINVAL
?
-
EOPNOTSUPP
:
ret
);
goto
out
;
...
...
@@ -60,7 +61,7 @@ asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
}
/* Binary compatibility is good American knowhow fuckin' up. */
if
(
cmd
==
TIOCNOTTY
)
{
if
(
cmd
==
TIOCNOTTY
)
{
ret
=
sys_setsid
();
goto
out
;
}
...
...
@@ -176,39 +177,39 @@ asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
goto
out
;
/* Non posix grp */
case
_IOW
(
't'
,
118
,
int
):
{
int
oldval
,
newval
,
*
ptr
;
int
oldval
,
newval
,
__user
*
ptr
;
cmd
=
TIOCSPGRP
;
ptr
=
(
int
*
)
arg
;
ptr
=
(
int
__user
*
)
arg
;
ret
=
-
EFAULT
;
if
(
get_user
(
oldval
,
ptr
))
if
(
get_user
(
oldval
,
ptr
))
goto
out
;
ret
=
sys_ioctl
(
fd
,
cmd
,
arg
);
__get_user
(
newval
,
ptr
);
if
(
newval
==
-
1
)
{
if
(
newval
==
-
1
)
{
__put_user
(
oldval
,
ptr
);
ret
=
-
EIO
;
}
if
(
ret
==
-
ENOTTY
)
if
(
ret
==
-
ENOTTY
)
ret
=
-
EIO
;
goto
out
;
}
case
_IOR
(
't'
,
119
,
int
):
{
int
oldval
,
newval
,
*
ptr
;
int
oldval
,
newval
,
__user
*
ptr
;
cmd
=
TIOCGPGRP
;
ptr
=
(
int
*
)
arg
;
ptr
=
(
int
__user
*
)
arg
;
ret
=
-
EFAULT
;
if
(
get_user
(
oldval
,
ptr
))
if
(
get_user
(
oldval
,
ptr
))
goto
out
;
ret
=
sys_ioctl
(
fd
,
cmd
,
arg
);
__get_user
(
newval
,
ptr
);
if
(
newval
==
-
1
)
{
if
(
newval
==
-
1
)
{
__put_user
(
oldval
,
ptr
);
ret
=
-
EIO
;
}
if
(
ret
==
-
ENOTTY
)
if
(
ret
==
-
ENOTTY
)
ret
=
-
EIO
;
goto
out
;
}
...
...
arch/sparc/kernel/sys_sparc.c
View file @
32360cdf
...
...
@@ -136,7 +136,8 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user
if
(
!
ptr
)
goto
out
;
err
=
-
EFAULT
;
if
(
get_user
(
fourth
.
__pad
,
(
void
__user
**
)
ptr
))
if
(
get_user
(
fourth
.
__pad
,
(
void
__user
*
__user
*
)
ptr
))
goto
out
;
err
=
sys_semctl
(
first
,
second
,
third
,
fourth
);
goto
out
;
...
...
@@ -165,7 +166,9 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user
goto
out
;
}
case
1
:
default
:
err
=
sys_msgrcv
(
first
,
(
struct
msgbuf
*
)
ptr
,
second
,
fifth
,
third
);
err
=
sys_msgrcv
(
first
,
(
struct
msgbuf
__user
*
)
ptr
,
second
,
fifth
,
third
);
goto
out
;
}
case
MSGGET
:
...
...
@@ -194,7 +197,8 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user
goto
out
;
}
case
1
:
/* iBCS2 emulator entry point */
err
=
do_shmat
(
first
,
(
char
__user
*
)
ptr
,
second
,
(
ulong
__user
*
)
third
);
err
=
do_shmat
(
first
,
(
char
__user
*
)
ptr
,
second
,
(
ulong
*
)
third
);
goto
out
;
}
case
SHMDT
:
...
...
arch/sparc/kernel/sys_sunos.c
View file @
32360cdf
This diff is collapsed.
Click to expand it.
arch/sparc/kernel/unaligned.c
View file @
32360cdf
...
...
@@ -109,14 +109,14 @@ static inline unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
static
inline
unsigned
long
safe_fetch_reg
(
unsigned
int
reg
,
struct
pt_regs
*
regs
)
{
struct
reg_window
*
win
;
struct
reg_window
__user
*
win
;
unsigned
long
ret
;
if
(
reg
<
16
)
if
(
reg
<
16
)
return
(
!
reg
?
0
:
regs
->
u_regs
[
reg
]);
/* Ho hum, the slightly complicated case. */
win
=
(
struct
reg_window
*
)
regs
->
u_regs
[
UREG_FP
];
win
=
(
struct
reg_window
__user
*
)
regs
->
u_regs
[
UREG_FP
];
if
((
unsigned
long
)
win
&
3
)
return
-
1
;
...
...
@@ -431,29 +431,32 @@ static inline int ok_for_user(struct pt_regs *regs, unsigned int insn,
int
retval
,
check
=
(
dir
==
load
)
?
VERIFY_READ
:
VERIFY_WRITE
;
int
size
=
((
insn
>>
19
)
&
3
)
==
3
?
8
:
4
;
if
((
regs
->
pc
|
regs
->
npc
)
&
3
)
if
((
regs
->
pc
|
regs
->
npc
)
&
3
)
return
0
;
/* Must verify_area() in all the necessary places. */
#define WINREG_ADDR(regnum) ((void *)(((unsigned long *)regs->u_regs[UREG_FP])+(regnum)))
#define WINREG_ADDR(regnum) \
((void __user *)(((unsigned long *)regs->u_regs[UREG_FP])+(regnum)))
retval
=
0
;
reg
=
(
insn
>>
25
)
&
0x1f
;
if
(
reg
>=
16
)
{
if
(
reg
>=
16
)
{
retval
=
verify_area
(
check
,
WINREG_ADDR
(
reg
-
16
),
size
);
if
(
retval
)
if
(
retval
)
return
retval
;
}
reg
=
(
insn
>>
14
)
&
0x1f
;
if
(
reg
>=
16
)
{
if
(
reg
>=
16
)
{
retval
=
verify_area
(
check
,
WINREG_ADDR
(
reg
-
16
),
size
);
if
(
retval
)
if
(
retval
)
return
retval
;
}
if
(
!
(
insn
&
0x2000
))
{
if
(
!
(
insn
&
0x2000
))
{
reg
=
(
insn
&
0x1f
);
if
(
reg
>=
16
)
{
retval
=
verify_area
(
check
,
WINREG_ADDR
(
reg
-
16
),
size
);
if
(
retval
)
if
(
reg
>=
16
)
{
retval
=
verify_area
(
check
,
WINREG_ADDR
(
reg
-
16
),
size
);
if
(
retval
)
return
retval
;
}
}
...
...
arch/sparc/kernel/windows.c
View file @
32360cdf
...
...
@@ -69,8 +69,8 @@ void synchronize_user_stack(void)
unsigned
long
sp
=
tp
->
rwbuf_stkptrs
[
window
];
/* Ok, let it rip. */
if
(
copy_to_user
((
cha
r
*
)
sp
,
&
tp
->
reg_window
[
window
],
sizeof
(
struct
reg_window
)))
if
(
copy_to_user
((
char
__use
r
*
)
sp
,
&
tp
->
reg_window
[
window
],
sizeof
(
struct
reg_window
)))
continue
;
shift_window_buffer
(
window
,
tp
->
w_saved
-
1
,
tp
);
...
...
@@ -117,8 +117,9 @@ void try_to_clear_window_buffer(struct pt_regs *regs, int who)
for
(
window
=
0
;
window
<
tp
->
w_saved
;
window
++
)
{
unsigned
long
sp
=
tp
->
rwbuf_stkptrs
[
window
];
if
((
sp
&
7
)
||
copy_to_user
((
char
*
)
sp
,
&
tp
->
reg_window
[
window
],
sizeof
(
struct
reg_window
)))
if
((
sp
&
7
)
||
copy_to_user
((
char
__user
*
)
sp
,
&
tp
->
reg_window
[
window
],
sizeof
(
struct
reg_window
)))
do_exit
(
SIGILL
);
}
tp
->
w_saved
=
0
;
...
...
arch/sparc/math-emu/math.c
View file @
32360cdf
...
...
@@ -175,7 +175,7 @@ int do_mathemu(struct pt_regs *regs, struct task_struct *fpt)
#ifdef DEBUG_MATHEMU
printk
(
"precise trap at %08lx
\n
"
,
regs
->
pc
);
#endif
if
(
!
get_user
(
insn
,
(
u32
*
)
regs
->
pc
))
{
if
(
!
get_user
(
insn
,
(
u32
__user
*
)
regs
->
pc
))
{
retcode
=
do_one_mathemu
(
insn
,
&
fpt
->
thread
.
fsr
,
fpt
->
thread
.
float_regs
);
if
(
retcode
)
{
/* in this case we need to fix up PC & nPC */
...
...
@@ -193,7 +193,7 @@ int do_mathemu(struct pt_regs *regs, struct task_struct *fpt)
break
;
}
/* Now empty the queue and clear the queue_not_empty flag */
if
(
retcode
)
if
(
retcode
)
fpt
->
thread
.
fsr
&=
~
(
0x3000
|
FSR_CEXC_MASK
);
else
fpt
->
thread
.
fsr
&=
~
0x3000
;
...
...
@@ -219,18 +219,18 @@ static inline int record_exception(unsigned long *pfsr, int eflag)
would_trap
=
(
fsr
&
((
long
)
eflag
<<
FSR_TEM_SHIFT
))
!=
0UL
;
/* If trapping, we only want to signal one bit. */
if
(
would_trap
!=
0
)
{
if
(
would_trap
!=
0
)
{
eflag
&=
((
fsr
&
FSR_TEM_MASK
)
>>
FSR_TEM_SHIFT
);
if
((
eflag
&
(
eflag
-
1
))
!=
0
)
{
if
(
eflag
&
FP_EX_INVALID
)
if
((
eflag
&
(
eflag
-
1
))
!=
0
)
{
if
(
eflag
&
FP_EX_INVALID
)
eflag
=
FP_EX_INVALID
;
else
if
(
eflag
&
FP_EX_OVERFLOW
)
else
if
(
eflag
&
FP_EX_OVERFLOW
)
eflag
=
FP_EX_OVERFLOW
;
else
if
(
eflag
&
FP_EX_UNDERFLOW
)
else
if
(
eflag
&
FP_EX_UNDERFLOW
)
eflag
=
FP_EX_UNDERFLOW
;
else
if
(
eflag
&
FP_EX_DIVZERO
)
else
if
(
eflag
&
FP_EX_DIVZERO
)
eflag
=
FP_EX_DIVZERO
;
else
if
(
eflag
&
FP_EX_INEXACT
)
else
if
(
eflag
&
FP_EX_INEXACT
)
eflag
=
FP_EX_INEXACT
;
}
}
...
...
@@ -250,11 +250,11 @@ static inline int record_exception(unsigned long *pfsr, int eflag)
* CEXC just generated is OR'd into the
* existing value of AEXC.
*/
if
(
would_trap
==
0
)
if
(
would_trap
==
0
)
fsr
|=
((
long
)
eflag
<<
FSR_AEXC_SHIFT
);
/* If trapping, indicate fault trap type IEEE. */
if
(
would_trap
!=
0
)
if
(
would_trap
!=
0
)
fsr
|=
(
1UL
<<
14
);
*
pfsr
=
fsr
;
...
...
@@ -515,7 +515,7 @@ static int do_one_mathemu(u32 insn, unsigned long *pfsr, unsigned long *fregs)
case
7
:
FP_PACK_QP
(
rd
,
QR
);
break
;
}
}
if
(
_fex
==
0
)
if
(
_fex
==
0
)
return
1
;
/* success! */
return
record_exception
(
pfsr
,
_fex
);
}
arch/sparc/mm/fault.c
View file @
32360cdf
...
...
@@ -412,10 +412,10 @@ asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
address
=
regs
->
pc
;
}
else
if
(
!
write
&&
!
(
regs
->
psr
&
PSR_PS
))
{
unsigned
int
insn
,
*
ip
;
unsigned
int
insn
,
__user
*
ip
;
ip
=
(
unsigned
int
*
)
regs
->
pc
;
if
(
!
get_user
(
insn
,
ip
))
{
ip
=
(
unsigned
int
__user
*
)
regs
->
pc
;
if
(
!
get_user
(
insn
,
ip
))
{
if
((
insn
&
0xc1680000
)
==
0xc0680000
)
write
=
1
;
}
...
...
include/asm-sparc/hardirq.h
View file @
32360cdf
...
...
@@ -56,15 +56,6 @@ typedef struct {
#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT)
#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT)
/*
* The hardirq mask has to be large enough to have
* space for potentially all IRQ sources in the system
* nesting on a single CPU:
*/
#if (1 << HARDIRQ_BITS) < NR_IRQS
# error HARDIRQ_BITS is too low!
#endif
/*
* Are we doing bottom half or hardware interrupt processing?
* Are we in a softirq context? Interrupt context?
...
...
include/asm-sparc/ipc.h
View file @
32360cdf
...
...
@@ -7,7 +7,7 @@
* See arch/sparc/kernel/sys_sparc.c for ugly details..
*/
struct
ipc_kludge
{
struct
msgbuf
*
msgp
;
struct
msgbuf
__user
*
msgp
;
long
msgtyp
;
};
...
...
include/asm-sparc/semaphore.h
View file @
32360cdf
...
...
@@ -13,12 +13,12 @@ struct semaphore {
atomic24_t
count
;
int
sleepers
;
wait_queue_head_t
wait
;
#if WAITQUEUE_DEBUG
#if
def
WAITQUEUE_DEBUG
long
__magic
;
#endif
};
#if WAITQUEUE_DEBUG
#if
def
WAITQUEUE_DEBUG
# define __SEM_DEBUG_INIT(name) \
, (long)&(name).__magic
#else
...
...
@@ -43,7 +43,7 @@ static inline void sema_init (struct semaphore *sem, int val)
atomic24_set
(
&
sem
->
count
,
val
);
sem
->
sleepers
=
0
;
init_waitqueue_head
(
&
sem
->
wait
);
#if WAITQUEUE_DEBUG
#if
def
WAITQUEUE_DEBUG
sem
->
__magic
=
(
long
)
&
sem
->
__magic
;
#endif
}
...
...
@@ -68,7 +68,7 @@ static inline void down(struct semaphore * sem)
register
volatile
int
*
ptr
asm
(
"g1"
);
register
int
increment
asm
(
"g2"
);
#if WAITQUEUE_DEBUG
#if
def
WAITQUEUE_DEBUG
CHECK_MAGIC
(
sem
->
__magic
);
#endif
might_sleep
();
...
...
@@ -105,7 +105,7 @@ static inline int down_interruptible(struct semaphore * sem)
register
volatile
int
*
ptr
asm
(
"g1"
);
register
int
increment
asm
(
"g2"
);
#if WAITQUEUE_DEBUG
#if
def
WAITQUEUE_DEBUG
CHECK_MAGIC
(
sem
->
__magic
);
#endif
might_sleep
();
...
...
@@ -145,7 +145,7 @@ static inline int down_trylock(struct semaphore * sem)
register
volatile
int
*
ptr
asm
(
"g1"
);
register
int
increment
asm
(
"g2"
);
#if WAITQUEUE_DEBUG
#if
def
WAITQUEUE_DEBUG
CHECK_MAGIC
(
sem
->
__magic
);
#endif
...
...
@@ -184,7 +184,7 @@ static inline void up(struct semaphore * sem)
register
volatile
int
*
ptr
asm
(
"g1"
);
register
int
increment
asm
(
"g2"
);
#if WAITQUEUE_DEBUG
#if
def
WAITQUEUE_DEBUG
CHECK_MAGIC
(
sem
->
__magic
);
#endif
...
...
include/asm-sparc/signal.h
View file @
32360cdf
...
...
@@ -199,7 +199,7 @@ struct __new_sigaction {
#ifdef __KERNEL__
struct
k_sigaction
{
struct
__new_sigaction
sa
;
void
*
ka_restorer
;
void
__user
*
ka_restorer
;
};
#endif
...
...
@@ -211,7 +211,7 @@ struct __old_sigaction {
};
typedef
struct
sigaltstack
{
void
*
ss_sp
;
void
__user
*
ss_sp
;
int
ss_flags
;
size_t
ss_size
;
}
stack_t
;
...
...
include/asm-sparc/thread_info.h
View file @
32360cdf
...
...
@@ -17,6 +17,7 @@
#include <asm/btfixup.h>
#include <asm/ptrace.h>
#include <asm/page.h>
/*
* Low level task data.
...
...
include/asm-sparc/uaccess.h
View file @
32360cdf
...
...
@@ -83,6 +83,10 @@ extern unsigned long search_extables_range(unsigned long addr, unsigned long *g2
extern
void
__ret_efault
(
void
);
extern
long
not_a_user_address
;
#define check_user_ptr(x) \
(void) ({ void __user * __userptr = (__typeof__(*(x)) *)¬_a_user_address; __userptr; })
/* Uh, these should become the main single-value transfer routines..
* They automatically use the right size if we just have the right
* pointer type..
...
...
@@ -94,10 +98,12 @@ extern void __ret_efault(void);
*/
#define put_user(x,ptr) ({ \
unsigned long __pu_addr = (unsigned long)(ptr); \
check_user_ptr(ptr); \
__put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
#define get_user(x,ptr) ({ \
unsigned long __gu_addr = (unsigned long)(ptr); \
check_user_ptr(ptr); \
__get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
/*
...
...
@@ -292,32 +298,32 @@ __asm__ __volatile__( \
extern
int
__get_user_bad
(
void
);
extern
unsigned
long
__copy_user
(
void
*
to
,
const
void
*
from
,
unsigned
long
size
);
extern
unsigned
long
__copy_user
(
void
__user
*
to
,
const
void
__user
*
from
,
unsigned
long
size
);
static
inline
unsigned
long
copy_to_user
(
void
__user
*
to
,
const
void
*
from
,
unsigned
long
n
)
{
if
(
n
&&
__access_ok
((
unsigned
long
)
to
,
n
))
return
__copy_user
(
(
void
*
)
to
,
from
,
n
);
return
__copy_user
(
to
,
(
void
__user
*
)
from
,
n
);
else
return
n
;
}
static
inline
unsigned
long
__copy_to_user
(
void
__user
*
to
,
const
void
*
from
,
unsigned
long
n
)
{
return
__copy_user
(
(
void
*
)
to
,
from
,
n
);
return
__copy_user
(
to
,
(
void
__user
*
)
from
,
n
);
}
static
inline
unsigned
long
copy_from_user
(
void
*
to
,
const
void
__user
*
from
,
unsigned
long
n
)
{
if
(
n
&&
__access_ok
((
unsigned
long
)
from
,
n
))
return
__copy_user
(
to
,
(
void
*
)
from
,
n
);
return
__copy_user
(
(
void
__user
*
)
to
,
from
,
n
);
else
return
n
;
}
static
inline
unsigned
long
__copy_from_user
(
void
*
to
,
const
void
__user
*
from
,
unsigned
long
n
)
{
return
__copy_user
(
to
,
(
void
*
)
from
,
n
);
return
__copy_user
(
(
void
__user
*
)
to
,
from
,
n
);
}
static
inline
unsigned
long
__clear_user
(
void
__user
*
addr
,
unsigned
long
size
)
...
...
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