diff options
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/include/asm/break.h | 1 | ||||
-rw-r--r-- | arch/mips/include/asm/fpu_emulator.h | 17 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 16 | ||||
-rw-r--r-- | arch/mips/kernel/unaligned.c | 12 | ||||
-rw-r--r-- | arch/mips/math-emu/cp1emu.c | 4 | ||||
-rw-r--r-- | arch/mips/math-emu/dsemul.c | 7 | ||||
-rw-r--r-- | arch/mips/math-emu/dsemul.h | 17 |
7 files changed, 37 insertions, 37 deletions
diff --git a/arch/mips/include/asm/break.h b/arch/mips/include/asm/break.h index 25b980c91e7e..44437ed765e8 100644 --- a/arch/mips/include/asm/break.h +++ b/arch/mips/include/asm/break.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */ | 29 | #define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */ |
30 | #define BRK_BUG 512 /* Used by BUG() */ | 30 | #define BRK_BUG 512 /* Used by BUG() */ |
31 | #define BRK_KDB 513 /* Used in KDB_ENTER() */ | 31 | #define BRK_KDB 513 /* Used in KDB_ENTER() */ |
32 | #define BRK_MEMU 514 /* Used by FPU emulator */ | ||
32 | #define BRK_MULOVF 1023 /* Multiply overflow */ | 33 | #define BRK_MULOVF 1023 /* Multiply overflow */ |
33 | 34 | ||
34 | #endif /* __ASM_BREAK_H */ | 35 | #endif /* __ASM_BREAK_H */ |
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h index 2731c38bd7ae..e5189572956c 100644 --- a/arch/mips/include/asm/fpu_emulator.h +++ b/arch/mips/include/asm/fpu_emulator.h | |||
@@ -23,6 +23,9 @@ | |||
23 | #ifndef _ASM_FPU_EMULATOR_H | 23 | #ifndef _ASM_FPU_EMULATOR_H |
24 | #define _ASM_FPU_EMULATOR_H | 24 | #define _ASM_FPU_EMULATOR_H |
25 | 25 | ||
26 | #include <asm/break.h> | ||
27 | #include <asm/inst.h> | ||
28 | |||
26 | struct mips_fpu_emulator_stats { | 29 | struct mips_fpu_emulator_stats { |
27 | unsigned int emulated; | 30 | unsigned int emulated; |
28 | unsigned int loads; | 31 | unsigned int loads; |
@@ -34,4 +37,18 @@ struct mips_fpu_emulator_stats { | |||
34 | 37 | ||
35 | extern struct mips_fpu_emulator_stats fpuemustats; | 38 | extern struct mips_fpu_emulator_stats fpuemustats; |
36 | 39 | ||
40 | extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir, | ||
41 | unsigned long cpc); | ||
42 | extern int do_dsemulret(struct pt_regs *xcp); | ||
43 | |||
44 | /* | ||
45 | * Instruction inserted following the badinst to further tag the sequence | ||
46 | */ | ||
47 | #define BD_COOKIE 0x0000bd36 /* tne $0, $0 with baggage */ | ||
48 | |||
49 | /* | ||
50 | * Break instruction with special math emu break code set | ||
51 | */ | ||
52 | #define BREAK_MATH (0x0000000d | (BRK_MEMU << 16)) | ||
53 | |||
37 | #endif /* _ASM_FPU_EMULATOR_H */ | 54 | #endif /* _ASM_FPU_EMULATOR_H */ |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 3f6de76d485d..353056110f2b 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <asm/cpu.h> | 32 | #include <asm/cpu.h> |
33 | #include <asm/dsp.h> | 33 | #include <asm/dsp.h> |
34 | #include <asm/fpu.h> | 34 | #include <asm/fpu.h> |
35 | #include <asm/fpu_emulator.h> | ||
35 | #include <asm/mipsregs.h> | 36 | #include <asm/mipsregs.h> |
36 | #include <asm/mipsmtregs.h> | 37 | #include <asm/mipsmtregs.h> |
37 | #include <asm/module.h> | 38 | #include <asm/module.h> |
@@ -722,6 +723,21 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, | |||
722 | die_if_kernel("Kernel bug detected", regs); | 723 | die_if_kernel("Kernel bug detected", regs); |
723 | force_sig(SIGTRAP, current); | 724 | force_sig(SIGTRAP, current); |
724 | break; | 725 | break; |
726 | case BRK_MEMU: | ||
727 | /* | ||
728 | * Address errors may be deliberately induced by the FPU | ||
729 | * emulator to retake control of the CPU after executing the | ||
730 | * instruction in the delay slot of an emulated branch. | ||
731 | * | ||
732 | * Terminate if exception was recognized as a delay slot return | ||
733 | * otherwise handle as normal. | ||
734 | */ | ||
735 | if (do_dsemulret(regs)) | ||
736 | return; | ||
737 | |||
738 | die_if_kernel("Math emu break/trap", regs); | ||
739 | force_sig(SIGTRAP, current); | ||
740 | break; | ||
725 | default: | 741 | default: |
726 | scnprintf(b, sizeof(b), "%s instruction in kernel code", str); | 742 | scnprintf(b, sizeof(b), "%s instruction in kernel code", str); |
727 | die_if_kernel(b, regs); | 743 | die_if_kernel(b, regs); |
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 20709669e592..bf4c4a979abb 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c | |||
@@ -499,22 +499,10 @@ sigill: | |||
499 | 499 | ||
500 | asmlinkage void do_ade(struct pt_regs *regs) | 500 | asmlinkage void do_ade(struct pt_regs *regs) |
501 | { | 501 | { |
502 | extern int do_dsemulret(struct pt_regs *); | ||
503 | unsigned int __user *pc; | 502 | unsigned int __user *pc; |
504 | mm_segment_t seg; | 503 | mm_segment_t seg; |
505 | 504 | ||
506 | /* | 505 | /* |
507 | * Address errors may be deliberately induced by the FPU emulator to | ||
508 | * retake control of the CPU after executing the instruction in the | ||
509 | * delay slot of an emulated branch. | ||
510 | */ | ||
511 | /* Terminate if exception was recognized as a delay slot return */ | ||
512 | if (do_dsemulret(regs)) | ||
513 | return; | ||
514 | |||
515 | /* Otherwise handle as normal */ | ||
516 | |||
517 | /* | ||
518 | * Did we catch a fault trying to load an instruction? | 506 | * Did we catch a fault trying to load an instruction? |
519 | * Or are we running in MIPS16 mode? | 507 | * Or are we running in MIPS16 mode? |
520 | */ | 508 | */ |
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index 7ec0b217dfd3..890f77927d62 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include <asm/branch.h> | 48 | #include <asm/branch.h> |
49 | 49 | ||
50 | #include "ieee754.h" | 50 | #include "ieee754.h" |
51 | #include "dsemul.h" | ||
52 | 51 | ||
53 | /* Strap kernel emulator for full MIPS IV emulation */ | 52 | /* Strap kernel emulator for full MIPS IV emulation */ |
54 | 53 | ||
@@ -346,9 +345,6 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
346 | /* cop control register rd -> gpr[rt] */ | 345 | /* cop control register rd -> gpr[rt] */ |
347 | u32 value; | 346 | u32 value; |
348 | 347 | ||
349 | if (ir == CP1UNDEF) { | ||
350 | return do_dsemulret(xcp); | ||
351 | } | ||
352 | if (MIPSInst_RD(ir) == FPCREG_CSR) { | 348 | if (MIPSInst_RD(ir) == FPCREG_CSR) { |
353 | value = ctx->fcr31; | 349 | value = ctx->fcr31; |
354 | value = (value & ~0x3) | mips_rm[value & 0x3]; | 350 | value = (value & ~0x3) | mips_rm[value & 0x3]; |
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c index 653e325849e4..df7b9d928efc 100644 --- a/arch/mips/math-emu/dsemul.c +++ b/arch/mips/math-emu/dsemul.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <asm/fpu_emulator.h> | 18 | #include <asm/fpu_emulator.h> |
19 | 19 | ||
20 | #include "ieee754.h" | 20 | #include "ieee754.h" |
21 | #include "dsemul.h" | ||
22 | 21 | ||
23 | /* Strap kernel emulator for full MIPS IV emulation */ | 22 | /* Strap kernel emulator for full MIPS IV emulation */ |
24 | 23 | ||
@@ -94,7 +93,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) | |||
94 | return SIGBUS; | 93 | return SIGBUS; |
95 | 94 | ||
96 | err = __put_user(ir, &fr->emul); | 95 | err = __put_user(ir, &fr->emul); |
97 | err |= __put_user((mips_instruction)BADINST, &fr->badinst); | 96 | err |= __put_user((mips_instruction)BREAK_MATH, &fr->badinst); |
98 | err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie); | 97 | err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie); |
99 | err |= __put_user(cpc, &fr->epc); | 98 | err |= __put_user(cpc, &fr->epc); |
100 | 99 | ||
@@ -130,13 +129,13 @@ int do_dsemulret(struct pt_regs *xcp) | |||
130 | /* | 129 | /* |
131 | * Do some sanity checking on the stackframe: | 130 | * Do some sanity checking on the stackframe: |
132 | * | 131 | * |
133 | * - Is the instruction pointed to by the EPC an BADINST? | 132 | * - Is the instruction pointed to by the EPC an BREAK_MATH? |
134 | * - Is the following memory word the BD_COOKIE? | 133 | * - Is the following memory word the BD_COOKIE? |
135 | */ | 134 | */ |
136 | err = __get_user(insn, &fr->badinst); | 135 | err = __get_user(insn, &fr->badinst); |
137 | err |= __get_user(cookie, &fr->cookie); | 136 | err |= __get_user(cookie, &fr->cookie); |
138 | 137 | ||
139 | if (unlikely(err || (insn != BADINST) || (cookie != BD_COOKIE))) { | 138 | if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) { |
140 | fpuemustats.errors++; | 139 | fpuemustats.errors++; |
141 | return 0; | 140 | return 0; |
142 | } | 141 | } |
diff --git a/arch/mips/math-emu/dsemul.h b/arch/mips/math-emu/dsemul.h deleted file mode 100644 index 091f0e76730f..000000000000 --- a/arch/mips/math-emu/dsemul.h +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc); | ||
2 | extern int do_dsemulret(struct pt_regs *xcp); | ||
3 | |||
4 | /* Instruction which will always cause an address error */ | ||
5 | #define AdELOAD 0x8c000001 /* lw $0,1($0) */ | ||
6 | /* Instruction which will plainly cause a CP1 exception when FPU is disabled */ | ||
7 | #define CP1UNDEF 0x44400001 /* cfc1 $0,$0 undef */ | ||
8 | |||
9 | /* Instruction inserted following the badinst to further tag the sequence */ | ||
10 | #define BD_COOKIE 0x0000bd36 /* tne $0,$0 with baggage */ | ||
11 | |||
12 | /* Setup which instruction to use for trampoline */ | ||
13 | #ifdef STANDALONE_EMULATOR | ||
14 | #define BADINST CP1UNDEF | ||
15 | #else | ||
16 | #define BADINST AdELOAD | ||
17 | #endif | ||