Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xcap
xcap-capability-linux
Commits
e50c0a8f
Commit
e50c0a8f
authored
May 31, 2005
by
Ralf Baechle
Browse files
Support the MIPS32 / MIPS64 DSP ASE.
Signed-off-by:
Ralf Baechle
<
ralf@linux-mips.org
>
parent
10f650db
Changes
34
Hide whitespace changes
Inline
Side-by-side
arch/mips/kernel/asm-offsets.c
View file @
e50c0a8f
...
...
@@ -95,7 +95,7 @@ void output_thread_info_defines(void)
offset
(
"#define TI_PRE_COUNT "
,
struct
thread_info
,
preempt_count
);
offset
(
"#define TI_ADDR_LIMIT "
,
struct
thread_info
,
addr_limit
);
offset
(
"#define TI_RESTART_BLOCK "
,
struct
thread_info
,
restart_block
);
offset
(
"#define TI_TP_VALUE
"
,
struct
thread_info
,
tp_value
);
offset
(
"#define TI_TP_VALUE
"
,
struct
thread_info
,
tp_value
);
constant
(
"#define _THREAD_SIZE_ORDER "
,
THREAD_SIZE_ORDER
);
constant
(
"#define _THREAD_SIZE "
,
THREAD_SIZE
);
constant
(
"#define _THREAD_MASK "
,
THREAD_MASK
);
...
...
@@ -241,6 +241,7 @@ void output_mm_defines(void)
linefeed
;
}
#ifdef CONFIG_32BIT
void
output_sc_defines
(
void
)
{
text
(
"/* Linux sigcontext offsets. */"
);
...
...
@@ -252,10 +253,29 @@ void output_sc_defines(void)
offset
(
"#define SC_STATUS "
,
struct
sigcontext
,
sc_status
);
offset
(
"#define SC_FPC_CSR "
,
struct
sigcontext
,
sc_fpc_csr
);
offset
(
"#define SC_FPC_EIR "
,
struct
sigcontext
,
sc_fpc_eir
);
offset
(
"#define SC_CAUSE "
,
struct
sigcontext
,
sc_cause
);
offset
(
"#define SC_BADVADDR "
,
struct
sigcontext
,
sc_badvaddr
);
offset
(
"#define SC_HI1 "
,
struct
sigcontext
,
sc_hi1
);
offset
(
"#define SC_LO1 "
,
struct
sigcontext
,
sc_lo1
);
offset
(
"#define SC_HI2 "
,
struct
sigcontext
,
sc_hi2
);
offset
(
"#define SC_LO2 "
,
struct
sigcontext
,
sc_lo2
);
offset
(
"#define SC_HI3 "
,
struct
sigcontext
,
sc_hi3
);
offset
(
"#define SC_LO3 "
,
struct
sigcontext
,
sc_lo3
);
linefeed
;
}
#endif
#ifdef CONFIG_64BIT
void
output_sc_defines
(
void
)
{
text
(
"/* Linux sigcontext offsets. */"
);
offset
(
"#define SC_REGS "
,
struct
sigcontext
,
sc_regs
);
offset
(
"#define SC_FPREGS "
,
struct
sigcontext
,
sc_fpregs
);
offset
(
"#define SC_MDHI "
,
struct
sigcontext
,
sc_hi
);
offset
(
"#define SC_MDLO "
,
struct
sigcontext
,
sc_lo
);
offset
(
"#define SC_PC "
,
struct
sigcontext
,
sc_pc
);
offset
(
"#define SC_FPC_CSR "
,
struct
sigcontext
,
sc_fpc_csr
);
linefeed
;
}
#endif
#ifdef CONFIG_MIPS32_COMPAT
void
output_sc32_defines
(
void
)
...
...
arch/mips/kernel/branch.c
View file @
e50c0a8f
...
...
@@ -22,7 +22,7 @@
*/
int
__compute_return_epc
(
struct
pt_regs
*
regs
)
{
unsigned
int
*
addr
,
bit
,
fcr31
;
unsigned
int
*
addr
,
bit
,
fcr31
,
dspcontrol
;
long
epc
;
union
mips_instruction
insn
;
...
...
@@ -99,6 +99,18 @@ int __compute_return_epc(struct pt_regs *regs)
epc
+=
8
;
regs
->
cp0_epc
=
epc
;
break
;
case
bposge32_op
:
if
(
!
cpu_has_dsp
)
goto
sigill
;
dspcontrol
=
rddsp
(
0x01
);
if
(
dspcontrol
>=
32
)
{
epc
=
epc
+
4
+
(
insn
.
i_format
.
simmediate
<<
2
);
}
else
epc
+=
8
;
regs
->
cp0_epc
=
epc
;
break
;
}
break
;
...
...
@@ -200,4 +212,9 @@ unaligned:
printk
(
"%s: unaligned epc - sending SIGBUS.
\n
"
,
current
->
comm
);
force_sig
(
SIGBUS
,
current
);
return
-
EFAULT
;
sigill:
printk
(
"%s: DSP branch but not DSP ASE - sending SIGBUS.
\n
"
,
current
->
comm
);
force_sig
(
SIGBUS
,
current
);
return
-
EFAULT
;
}
arch/mips/kernel/cpu-probe.c
View file @
e50c0a8f
...
...
@@ -482,6 +482,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
if
(
config3
&
MIPS_CONF3_SM
)
c
->
ases
|=
MIPS_ASE_SMARTMIPS
;
if
(
config3
&
MIPS_CONF3_DSP
)
c
->
ases
|=
MIPS_ASE_DSP
;
return
config3
&
MIPS_CONF_M
;
}
...
...
@@ -529,6 +531,7 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c)
c
->
cputype
=
CPU_20KC
;
break
;
case
PRID_IMP_24K
:
case
PRID_IMP_24KE
:
c
->
cputype
=
CPU_24K
;
break
;
case
PRID_IMP_25KF
:
...
...
arch/mips/kernel/genex.S
View file @
e50c0a8f
...
...
@@ -291,6 +291,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
BUILD_HANDLER
mdmx
mdmx
sti
silent
/*
#
22
*/
BUILD_HANDLER
watch
watch
sti
verbose
/*
#
23
*/
BUILD_HANDLER
mcheck
mcheck
cli
verbose
/*
#
24
*/
BUILD_HANDLER
dsp
dsp
sti
silent
/*
#
26
*/
BUILD_HANDLER
reserved
reserved
sti
verbose
/*
others
*/
#ifdef CONFIG_64BIT
...
...
arch/mips/kernel/process.c
View file @
e50c0a8f
...
...
@@ -25,8 +25,10 @@
#include
<linux/init.h>
#include
<linux/completion.h>
#include
<asm/abi.h>
#include
<asm/bootinfo.h>
#include
<asm/cpu.h>
#include
<asm/dsp.h>
#include
<asm/fpu.h>
#include
<asm/pgtable.h>
#include
<asm/system.h>
...
...
@@ -54,6 +56,54 @@ ATTRIB_NORET void cpu_idle(void)
}
}
extern
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
);
extern
int
do_signal32
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
);
/*
* Native o32 and N64 ABI without DSP ASE
*/
extern
void
setup_frame
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signr
,
sigset_t
*
set
);
extern
void
setup_rt_frame
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signr
,
sigset_t
*
set
,
siginfo_t
*
info
);
struct
mips_abi
mips_abi
=
{
.
do_signal
=
do_signal
,
#ifdef CONFIG_TRAD_SIGNALS
.
setup_frame
=
setup_frame
,
#endif
.
setup_rt_frame
=
setup_rt_frame
};
#ifdef CONFIG_MIPS32_O32
/*
* o32 compatibility on 64-bit kernels, without DSP ASE
*/
extern
void
setup_frame_32
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signr
,
sigset_t
*
set
);
extern
void
setup_rt_frame_32
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signr
,
sigset_t
*
set
,
siginfo_t
*
info
);
struct
mips_abi
mips_abi_32
=
{
.
do_signal
=
do_signal32
,
.
setup_frame
=
setup_frame_32
,
.
setup_rt_frame
=
setup_rt_frame_32
};
#endif
/* CONFIG_MIPS32_O32 */
#ifdef CONFIG_MIPS32_N32
/*
* N32 on 64-bit kernels, without DSP ASE
*/
extern
void
setup_rt_frame_n32
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signr
,
sigset_t
*
set
,
siginfo_t
*
info
);
struct
mips_abi
mips_abi_n32
=
{
.
do_signal
=
do_signal
,
.
setup_rt_frame
=
setup_rt_frame_n32
};
#endif
/* CONFIG_MIPS32_N32 */
asmlinkage
void
ret_from_fork
(
void
);
void
start_thread
(
struct
pt_regs
*
regs
,
unsigned
long
pc
,
unsigned
long
sp
)
...
...
@@ -70,6 +120,8 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
regs
->
cp0_status
=
status
;
clear_used_math
();
lose_fpu
();
if
(
cpu_has_dsp
)
__init_dsp
();
regs
->
cp0_epc
=
pc
;
regs
->
regs
[
29
]
=
sp
;
current_thread_info
()
->
addr_limit
=
USER_DS
;
...
...
@@ -95,9 +147,11 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
preempt_disable
();
if
(
is_fpu_owner
())
{
if
(
is_fpu_owner
())
save_fp
(
p
);
}
if
(
cpu_has_dsp
)
save_dsp
(
p
);
preempt_enable
();
...
...
arch/mips/kernel/ptrace.c
View file @
e50c0a8f
...
...
@@ -30,6 +30,7 @@
#include
<asm/byteorder.h>
#include
<asm/cpu.h>
#include
<asm/dsp.h>
#include
<asm/fpu.h>
#include
<asm/mipsregs.h>
#include
<asm/pgtable.h>
...
...
@@ -176,6 +177,27 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
write_c0_status
(
flags
);
break
;
}
case
DSP_BASE
...
DSP_BASE
+
5
:
if
(
!
cpu_has_dsp
)
{
tmp
=
0
;
ret
=
-
EIO
;
goto
out_tsk
;
}
if
(
child
->
thread
.
dsp
.
used_dsp
)
{
dspreg_t
*
dregs
=
__get_dsp_regs
(
child
);
tmp
=
(
unsigned
long
)
(
dregs
[
addr
-
DSP_BASE
]);
}
else
{
tmp
=
-
1
;
/* DSP registers yet used */
}
break
;
case
DSP_CONTROL
:
if
(
!
cpu_has_dsp
)
{
tmp
=
0
;
ret
=
-
EIO
;
goto
out_tsk
;
}
tmp
=
child
->
thread
.
dsp
.
dspcontrol
;
break
;
default:
tmp
=
0
;
ret
=
-
EIO
;
...
...
@@ -248,6 +270,22 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
else
child
->
thread
.
fpu
.
soft
.
fcr31
=
data
;
break
;
case
DSP_BASE
...
DSP_BASE
+
5
:
if
(
!
cpu_has_dsp
)
{
ret
=
-
EIO
;
break
;
}
dspreg_t
*
dregs
=
__get_dsp_regs
(
child
);
dregs
[
addr
-
DSP_BASE
]
=
data
;
break
;
case
DSP_CONTROL
:
if
(
!
cpu_has_dsp
)
{
ret
=
-
EIO
;
break
;
}
child
->
thread
.
dsp
.
dspcontrol
=
data
;
break
;
default:
/* The rest are not allowed. */
ret
=
-
EIO
;
...
...
arch/mips/kernel/ptrace32.c
View file @
e50c0a8f
...
...
@@ -26,6 +26,7 @@
#include
<linux/security.h>
#include
<asm/cpu.h>
#include
<asm/dsp.h>
#include
<asm/fpu.h>
#include
<asm/mipsregs.h>
#include
<asm/pgtable.h>
...
...
@@ -161,6 +162,27 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
write_c0_status
(
flags
);
break
;
}
case
DSP_BASE
...
DSP_BASE
+
5
:
if
(
!
cpu_has_dsp
)
{
tmp
=
0
;
ret
=
-
EIO
;
goto
out_tsk
;
}
if
(
child
->
thread
.
dsp
.
used_dsp
)
{
dspreg_t
*
dregs
=
__get_dsp_regs
(
child
);
tmp
=
(
unsigned
long
)
(
dregs
[
addr
-
DSP_BASE
]);
}
else
{
tmp
=
-
1
;
/* DSP registers yet used */
}
break
;
case
DSP_CONTROL
:
if
(
!
cpu_has_dsp
)
{
tmp
=
0
;
ret
=
-
EIO
;
goto
out_tsk
;
}
tmp
=
child
->
thread
.
dsp
.
dspcontrol
;
break
;
default:
tmp
=
0
;
ret
=
-
EIO
;
...
...
@@ -230,6 +252,22 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
else
child
->
thread
.
fpu
.
soft
.
fcr31
=
data
;
break
;
case
DSP_BASE
...
DSP_BASE
+
5
:
if
(
!
cpu_has_dsp
)
{
ret
=
-
EIO
;
break
;
}
dspreg_t
*
dregs
=
__get_dsp_regs
(
child
);
dregs
[
addr
-
DSP_BASE
]
=
data
;
break
;
case
DSP_CONTROL
:
if
(
!
cpu_has_dsp
)
{
ret
=
-
EIO
;
break
;
}
child
->
thread
.
dsp
.
dspcontrol
=
data
;
break
;
default:
/* The rest are not allowed. */
ret
=
-
EIO
;
...
...
arch/mips/kernel/r4k_fpu.S
View file @
e50c0a8f
...
...
@@ -32,7 +32,7 @@
.
set
noreorder
.
set
mips3
/
*
Save
floating
point
context
*/
LEAF
(
_save_fp_context
)
cfc1
t1
,
fcr31
...
...
@@ -74,9 +74,6 @@ LEAF(_save_fp_context)
EX
sdc1
$f28
,
SC_FPREGS
+
224
(
a0
)
EX
sdc1
$f30
,
SC_FPREGS
+
240
(
a0
)
EX
sw
t1
,
SC_FPC_CSR
(
a0
)
cfc1
t0
,
$
0
#
implementation
/
version
EX
sw
t0
,
SC_FPC_EIR
(
a0
)
jr
ra
li
v0
,
0
#
success
END
(
_save_fp_context
)
...
...
arch/mips/kernel/scall32-o32.S
View file @
e50c0a8f
...
...
@@ -620,7 +620,7 @@ einval: li v0, -EINVAL
sys
sys_ni_syscall
0
/*
sys_vserver
*/
sys
sys_waitid
5
sys
sys_ni_syscall
0
/*
available
,
was
setaltroot
*/
sys
sys_add_key
5
sys
sys_add_key
5
/*
4280
*/
sys
sys_request_key
4
sys
sys_keyctl
5
sys
sys_set_thread_area
1
...
...
arch/mips/kernel/setup.c
View file @
e50c0a8f
...
...
@@ -549,3 +549,12 @@ int __init fpu_disable(char *s)
}
__setup
(
"nofpu"
,
fpu_disable
);
int
__init
dsp_disable
(
char
*
s
)
{
cpu_data
[
0
].
ases
&=
~
MIPS_ASE_DSP
;
return
1
;
}
__setup
(
"nodsp"
,
dsp_disable
);
arch/mips/kernel/signal-common.h
View file @
e50c0a8f
...
...
@@ -8,13 +8,14 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#include
<linux/config.h>
static
inline
int
setup_sigcontext
(
struct
pt_regs
*
regs
,
struct
sigcontext
*
sc
)
{
int
err
=
0
;
err
|=
__put_user
(
regs
->
cp0_epc
,
&
sc
->
sc_pc
);
err
|=
__put_user
(
regs
->
cp0_status
,
&
sc
->
sc_status
);
#define save_gp_reg(i) do { \
err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \
...
...
@@ -30,10 +31,32 @@ setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
save_gp_reg
(
31
);
#undef save_gp_reg
#ifdef CONFIG_32BIT
err
|=
__put_user
(
regs
->
hi
,
&
sc
->
sc_mdhi
);
err
|=
__put_user
(
regs
->
lo
,
&
sc
->
sc_mdlo
);
err
|=
__put_user
(
regs
->
cp0_cause
,
&
sc
->
sc_cause
);
err
|=
__put_user
(
regs
->
cp0_badvaddr
,
&
sc
->
sc_badvaddr
);
if
(
cpu_has_dsp
)
{
err
|=
__put_user
(
mfhi1
(),
&
sc
->
sc_hi1
);
err
|=
__put_user
(
mflo1
(),
&
sc
->
sc_lo1
);
err
|=
__put_user
(
mfhi2
(),
&
sc
->
sc_hi2
);
err
|=
__put_user
(
mflo2
(),
&
sc
->
sc_lo2
);
err
|=
__put_user
(
mfhi3
(),
&
sc
->
sc_hi3
);
err
|=
__put_user
(
mflo3
(),
&
sc
->
sc_lo3
);
err
|=
__put_user
(
rddsp
(
DSP_MASK
),
&
sc
->
sc_dsp
);
}
#endif
#ifdef CONFIG_64BIT
err
|=
__put_user
(
regs
->
hi
,
&
sc
->
sc_hi
[
0
]);
err
|=
__put_user
(
regs
->
lo
,
&
sc
->
sc_lo
[
0
]);
if
(
cpu_has_dsp
)
{
err
|=
__put_user
(
mfhi1
(),
&
sc
->
sc_hi
[
1
]);
err
|=
__put_user
(
mflo1
(),
&
sc
->
sc_lo
[
1
]);
err
|=
__put_user
(
mfhi2
(),
&
sc
->
sc_hi
[
2
]);
err
|=
__put_user
(
mflo2
(),
&
sc
->
sc_lo
[
2
]);
err
|=
__put_user
(
mfhi3
(),
&
sc
->
sc_hi
[
3
]);
err
|=
__put_user
(
mflo3
(),
&
sc
->
sc_lo
[
3
]);
err
|=
__put_user
(
rddsp
(
DSP_MASK
),
&
sc
->
sc_dsp
);
}
#endif
err
|=
__put_user
(
!!
used_math
(),
&
sc
->
sc_used_math
);
...
...
@@ -61,15 +84,40 @@ out:
static
inline
int
restore_sigcontext
(
struct
pt_regs
*
regs
,
struct
sigcontext
*
sc
)
{
int
err
=
0
;
unsigned
int
used_math
;
unsigned
long
treg
;
int
err
=
0
;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info
()
->
restart_block
.
fn
=
do_no_restart_syscall
;
err
|=
__get_user
(
regs
->
cp0_epc
,
&
sc
->
sc_pc
);
#ifdef CONFIG_32BIT
err
|=
__get_user
(
regs
->
hi
,
&
sc
->
sc_mdhi
);
err
|=
__get_user
(
regs
->
lo
,
&
sc
->
sc_mdlo
);
if
(
cpu_has_dsp
)
{
err
|=
__get_user
(
treg
,
&
sc
->
sc_hi1
);
mthi1
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_lo1
);
mtlo1
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_hi2
);
mthi2
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_lo2
);
mtlo2
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_hi3
);
mthi3
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_lo3
);
mtlo3
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_dsp
);
wrdsp
(
treg
,
DSP_MASK
);
}
#endif
#ifdef CONFIG_64BIT
err
|=
__get_user
(
regs
->
hi
,
&
sc
->
sc_hi
[
0
]);
err
|=
__get_user
(
regs
->
lo
,
&
sc
->
sc_lo
[
0
]);
if
(
cpu_has_dsp
)
{
err
|=
__get_user
(
treg
,
&
sc
->
sc_hi
[
1
]);
mthi1
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_lo
[
1
]);
mthi1
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_hi
[
2
]);
mthi2
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_lo
[
2
]);
mthi2
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_hi
[
3
]);
mthi3
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_lo
[
3
]);
mthi3
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_dsp
);
wrdsp
(
treg
,
DSP_MASK
);
}
#endif
#define restore_gp_reg(i) do { \
err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \
...
...
arch/mips/kernel/signal.c
View file @
e50c0a8f
...
...
@@ -21,6 +21,7 @@
#include
<linux/unistd.h>
#include
<linux/compiler.h>
#include
<asm/abi.h>
#include
<asm/asm.h>
#include
<linux/bitops.h>
#include
<asm/cacheflush.h>
...
...
@@ -36,7 +37,7 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
static
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
);
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
);
/*
* Atomically swap in the new signal mask, and wait for a signal.
...
...
@@ -216,7 +217,7 @@ _sys_sigreturn(nabi_no_regargs struct pt_regs regs)
badframe:
force_sig
(
SIGSEGV
,
current
);
}
#endif
#endif
/* CONFIG_TRAD_SIGNALS */
save_static_function
(
sys_rt_sigreturn
);
__attribute_used__
noinline
static
void
...
...
@@ -262,7 +263,7 @@ badframe:
}
#ifdef CONFIG_TRAD_SIGNALS
static
void
inline
setup_frame
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
void
setup_frame
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signr
,
sigset_t
*
set
)
{
struct
sigframe
*
frame
;
...
...
@@ -318,7 +319,7 @@ give_sigsegv:
}
#endif
static
void
inline
setup_rt_frame
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
void
setup_rt_frame
(
struct
k_sigaction
*
ka
,
struct
pt_regs
*
regs
,
int
signr
,
sigset_t
*
set
,
siginfo_t
*
info
)
{
struct
rt_sigframe
*
frame
;
...
...
@@ -410,22 +411,10 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
regs
->
regs
[
0
]
=
0
;
/* Don't deal with this again. */
#ifdef CONFIG_TRAD_SIGNALS
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
{
#else
if
(
1
)
{
#endif
#ifdef CONFIG_MIPS32_N32
if
((
current
->
thread
.
mflags
&
MF_ABI_MASK
)
==
MF_N32
)
setup_rt_frame_n32
(
ka
,
regs
,
sig
,
oldset
,
info
);
else
#endif
setup_rt_frame
(
ka
,
regs
,
sig
,
oldset
,
info
);
}
#ifdef CONFIG_TRAD_SIGNALS
if
(
sig_uses_siginfo
(
ka
))
current
->
thread
.
abi
->
setup_rt_frame
(
ka
,
regs
,
sig
,
oldset
,
info
);
else
setup_frame
(
ka
,
regs
,
sig
,
oldset
);
#endif
current
->
thread
.
abi
->
setup_frame
(
ka
,
regs
,
sig
,
oldset
);
spin_lock_irq
(
&
current
->
sighand
->
siglock
);
sigorsets
(
&
current
->
blocked
,
&
current
->
blocked
,
&
ka
->
sa
.
sa_mask
);
...
...
@@ -435,21 +424,12 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info,
spin_unlock_irq
(
&
current
->
sighand
->
siglock
);
}
extern
int
do_signal32
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
);
extern
int
do_irix_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
);
static
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
)
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
)
{
struct
k_sigaction
ka
;
siginfo_t
info
;
int
signr
;
#ifdef CONFIG_BINFMT_ELF32
if
((
current
->
thread
.
mflags
&
MF_ABI_MASK
)
==
MF_O32
)
{
return
do_signal32
(
oldset
,
regs
);
}
#endif
/*
* We want the common case to go fast, which is why we may in certain
* cases get here from kernel mode. Just return without doing anything
...
...
@@ -501,18 +481,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
{
/* deal with pending signal delivery */
if
(
thread_info_flags
&
_TIF_SIGPENDING
)
{
#ifdef CONFIG_BINFMT_ELF32
if
(
likely
((
current
->
thread
.
mflags
&
MF_ABI_MASK
)
==
MF_O32
))
{
do_signal32
(
oldset
,
regs
);
return
;
}
#endif
#ifdef CONFIG_BINFMT_IRIX
if
(
unlikely
(
current
->
personality
!=
PER_LINUX
))
{
do_irix_signal
(
oldset
,
regs
);
return
;
}
#endif
do_signal
(
oldset
,
regs
);
current
->
thread
.
abi
->
do_signal
(
oldset
,
regs
);
}
}
arch/mips/kernel/signal32.c
View file @
e50c0a8f
...
...
@@ -21,6 +21,7 @@
#include
<linux/suspend.h>
#include
<linux/compiler.h>
#include
<asm/abi.h>
#include
<asm/asm.h>
#include
<linux/bitops.h>
#include
<asm/cacheflush.h>
...
...
@@ -334,8 +335,9 @@ asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
static
int
restore_sigcontext32
(
struct
pt_regs
*
regs
,
struct
sigcontext32
*
sc
)
{
u32
used_math
;
int
err
=
0
;
__u32
used_math
;
s32
treg
;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info
()
->
restart_block
.
fn
=
do_no_restart_syscall
;
...
...
@@ -343,6 +345,15 @@ static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
err
|=
__get_user
(
regs
->
cp0_epc
,
&
sc
->
sc_pc
);
err
|=
__get_user
(
regs
->
hi
,
&
sc
->
sc_mdhi
);
err
|=
__get_user
(
regs
->
lo
,
&
sc
->
sc_mdlo
);
if
(
cpu_has_dsp
)
{
err
|=
__get_user
(
treg
,
&
sc
->
sc_hi1
);
mthi1
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_lo1
);
mtlo1
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_hi2
);
mthi2
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_lo2
);
mtlo2
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_hi3
);
mthi3
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_lo3
);
mtlo3
(
treg
);
err
|=
__get_user
(
treg
,
&
sc
->
sc_dsp
);
wrdsp
(
treg
,
DSP_MASK
);
}
#define restore_gp_reg(i) do { \
err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \
...
...
@@ -562,8 +573,15 @@ static inline int setup_sigcontext32(struct pt_regs *regs,
err
|=
__put_user
(
regs
->
hi
,
&
sc
->
sc_mdhi
);
err
|=
__put_user
(
regs
->
lo
,
&
sc
->
sc_mdlo
);
err
|=
__put_user
(
regs
->
cp0_cause
,
&
sc
->
sc_cause
);
err
|=
__put_user
(
regs
->
cp0_badvaddr
,
&
sc
->
sc_badvaddr
);
if
(
cpu_has_dsp
)
{
err
|=
__put_user
(
rddsp
(
DSP_MASK
),
&
sc
->
sc_hi1
);
err
|=
__put_user
(
mfhi1
(),
&
sc
->
sc_hi1
);
err
|=
__put_user
(
mflo1
(),
&
sc
->
sc_lo1
);
err
|=
__put_user
(
mfhi2
(),
&
sc
->
sc_hi2
);
err
|=
__put_user
(
mflo2
(),
&
sc
->
sc_lo2
);
err
|=
__put_user
(
mfhi3
(),
&
sc
->
sc_hi3
);
err
|=
__put_user
(
mflo3
(),
&
sc
->
sc_lo3
);
}