dsemul.c (9a64e8e0ace51b309fdcff4b4754b3649250382a) | dsemul.c (102cedc32a6e3cd537374a3678d407591d5a6fab) |
---|---|
1#include <linux/compiler.h> 2#include <linux/mm.h> 3#include <linux/signal.h> 4#include <linux/smp.h> 5 6#include <asm/asm.h> 7#include <asm/bootinfo.h> 8#include <asm/byteorder.h> --- 41 unchanged lines hidden (view full) --- 50}; 51 52int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) 53{ 54 extern asmlinkage void handle_dsemulret(void); 55 struct emuframe __user *fr; 56 int err; 57 | 1#include <linux/compiler.h> 2#include <linux/mm.h> 3#include <linux/signal.h> 4#include <linux/smp.h> 5 6#include <asm/asm.h> 7#include <asm/bootinfo.h> 8#include <asm/byteorder.h> --- 41 unchanged lines hidden (view full) --- 50}; 51 52int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) 53{ 54 extern asmlinkage void handle_dsemulret(void); 55 struct emuframe __user *fr; 56 int err; 57 |
58 if (ir == 0) { /* a nop is easy */ | 58 if ((get_isa16_mode(regs->cp0_epc) && ((ir >> 16) == MM_NOP16)) || 59 (ir == 0)) { 60 /* NOP is easy */ |
59 regs->cp0_epc = cpc; 60 regs->cp0_cause &= ~CAUSEF_BD; 61 return 0; 62 } 63#ifdef DSEMUL_TRACE 64 printk("dsemul %lx %lx\n", regs->cp0_epc, cpc); 65 66#endif --- 19 unchanged lines hidden (view full) --- 86 /* Ensure that the two instructions are in the same cache line */ 87 fr = (struct emuframe __user *) 88 ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7); 89 90 /* Verify that the stack pointer is not competely insane */ 91 if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe)))) 92 return SIGBUS; 93 | 61 regs->cp0_epc = cpc; 62 regs->cp0_cause &= ~CAUSEF_BD; 63 return 0; 64 } 65#ifdef DSEMUL_TRACE 66 printk("dsemul %lx %lx\n", regs->cp0_epc, cpc); 67 68#endif --- 19 unchanged lines hidden (view full) --- 88 /* Ensure that the two instructions are in the same cache line */ 89 fr = (struct emuframe __user *) 90 ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7); 91 92 /* Verify that the stack pointer is not competely insane */ 93 if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe)))) 94 return SIGBUS; 95 |
94 err = __put_user(ir, &fr->emul); 95 err |= __put_user((mips_instruction)BREAK_MATH, &fr->badinst); | 96 if (get_isa16_mode(regs->cp0_epc)) { 97 err = __put_user(ir >> 16, (u16 __user *)(&fr->emul)); 98 err |= __put_user(ir & 0xffff, (u16 __user *)((long)(&fr->emul) + 2)); 99 err |= __put_user(BREAK_MATH >> 16, (u16 __user *)(&fr->badinst)); 100 err |= __put_user(BREAK_MATH & 0xffff, (u16 __user *)((long)(&fr->badinst) + 2)); 101 } else { 102 err = __put_user(ir, &fr->emul); 103 err |= __put_user((mips_instruction)BREAK_MATH, &fr->badinst); 104 } 105 |
96 err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie); 97 err |= __put_user(cpc, &fr->epc); 98 99 if (unlikely(err)) { 100 MIPS_FPU_EMU_INC_STATS(errors); 101 return SIGBUS; 102 } 103 | 106 err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie); 107 err |= __put_user(cpc, &fr->epc); 108 109 if (unlikely(err)) { 110 MIPS_FPU_EMU_INC_STATS(errors); 111 return SIGBUS; 112 } 113 |
104 regs->cp0_epc = (unsigned long) &fr->emul; | 114 regs->cp0_epc = ((unsigned long) &fr->emul) | 115 get_isa16_mode(regs->cp0_epc); |
105 106 flush_cache_sigtramp((unsigned long)&fr->badinst); 107 108 return SIGILL; /* force out of emulation loop */ 109} 110 111int do_dsemulret(struct pt_regs *xcp) 112{ 113 struct emuframe __user *fr; 114 unsigned long epc; 115 u32 insn, cookie; 116 int err = 0; | 116 117 flush_cache_sigtramp((unsigned long)&fr->badinst); 118 119 return SIGILL; /* force out of emulation loop */ 120} 121 122int do_dsemulret(struct pt_regs *xcp) 123{ 124 struct emuframe __user *fr; 125 unsigned long epc; 126 u32 insn, cookie; 127 int err = 0; |
128 u16 instr[2]; |
|
117 118 fr = (struct emuframe __user *) | 129 130 fr = (struct emuframe __user *) |
119 (xcp->cp0_epc - sizeof(mips_instruction)); | 131 (msk_isa16_mode(xcp->cp0_epc) - sizeof(mips_instruction)); |
120 121 /* 122 * If we can't even access the area, something is very wrong, but we'll 123 * leave that to the default handling 124 */ 125 if (!access_ok(VERIFY_READ, fr, sizeof(struct emuframe))) 126 return 0; 127 128 /* 129 * Do some sanity checking on the stackframe: 130 * 131 * - Is the instruction pointed to by the EPC an BREAK_MATH? 132 * - Is the following memory word the BD_COOKIE? 133 */ | 132 133 /* 134 * If we can't even access the area, something is very wrong, but we'll 135 * leave that to the default handling 136 */ 137 if (!access_ok(VERIFY_READ, fr, sizeof(struct emuframe))) 138 return 0; 139 140 /* 141 * Do some sanity checking on the stackframe: 142 * 143 * - Is the instruction pointed to by the EPC an BREAK_MATH? 144 * - Is the following memory word the BD_COOKIE? 145 */ |
134 err = __get_user(insn, &fr->badinst); | 146 if (get_isa16_mode(xcp->cp0_epc)) { 147 err = __get_user(instr[0], (u16 __user *)(&fr->badinst)); 148 err |= __get_user(instr[1], (u16 __user *)((long)(&fr->badinst) + 2)); 149 insn = (instr[0] << 16) | instr[1]; 150 } else { 151 err = __get_user(insn, &fr->badinst); 152 } |
135 err |= __get_user(cookie, &fr->cookie); 136 137 if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) { 138 MIPS_FPU_EMU_INC_STATS(errors); 139 return 0; 140 } 141 142 /* --- 24 unchanged lines hidden --- | 153 err |= __get_user(cookie, &fr->cookie); 154 155 if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) { 156 MIPS_FPU_EMU_INC_STATS(errors); 157 return 0; 158 } 159 160 /* --- 24 unchanged lines hidden --- |