0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/sched/signal.h>
0011 #include <linux/signal.h>
0012 #include <linux/export.h>
0013 #include <asm/branch.h>
0014 #include <asm/cpu.h>
0015 #include <asm/cpu-features.h>
0016 #include <asm/fpu.h>
0017 #include <asm/fpu_emulator.h>
0018 #include <asm/inst.h>
0019 #include <asm/mips-r2-to-r6-emul.h>
0020 #include <asm/ptrace.h>
0021 #include <linux/uaccess.h>
0022
0023 #include "probes-common.h"
0024
0025
0026
0027
0028
0029 int __isa_exception_epc(struct pt_regs *regs)
0030 {
0031 unsigned short inst;
0032 long epc = regs->cp0_epc;
0033
0034
0035 if (__get_user(inst, (u16 __user *) msk_isa16_mode(epc))) {
0036
0037 force_sig(SIGSEGV);
0038 return epc;
0039 }
0040 if (cpu_has_mips16) {
0041 union mips16e_instruction inst_mips16e;
0042
0043 inst_mips16e.full = inst;
0044 if (inst_mips16e.ri.opcode == MIPS16e_jal_op)
0045 epc += 4;
0046 else
0047 epc += 2;
0048 } else if (mm_insn_16bit(inst))
0049 epc += 2;
0050 else
0051 epc += 4;
0052
0053 return epc;
0054 }
0055
0056
0057 static const unsigned int reg16to32map[8] = {16, 17, 2, 3, 4, 5, 6, 7};
0058
0059 int __mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
0060 unsigned long *contpc)
0061 {
0062 union mips_instruction insn = (union mips_instruction)dec_insn.insn;
0063 int __maybe_unused bc_false = 0;
0064
0065 if (!cpu_has_mmips)
0066 return 0;
0067
0068 switch (insn.mm_i_format.opcode) {
0069 case mm_pool32a_op:
0070 if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) ==
0071 mm_pool32axf_op) {
0072 switch (insn.mm_i_format.simmediate >>
0073 MM_POOL32A_MINOR_SHIFT) {
0074 case mm_jalr_op:
0075 case mm_jalrhb_op:
0076 case mm_jalrs_op:
0077 case mm_jalrshb_op:
0078 if (insn.mm_i_format.rt != 0)
0079 regs->regs[insn.mm_i_format.rt] =
0080 regs->cp0_epc +
0081 dec_insn.pc_inc +
0082 dec_insn.next_pc_inc;
0083 *contpc = regs->regs[insn.mm_i_format.rs];
0084 return 1;
0085 }
0086 }
0087 break;
0088 case mm_pool32i_op:
0089 switch (insn.mm_i_format.rt) {
0090 case mm_bltzals_op:
0091 case mm_bltzal_op:
0092 regs->regs[31] = regs->cp0_epc +
0093 dec_insn.pc_inc +
0094 dec_insn.next_pc_inc;
0095 fallthrough;
0096 case mm_bltz_op:
0097 if ((long)regs->regs[insn.mm_i_format.rs] < 0)
0098 *contpc = regs->cp0_epc +
0099 dec_insn.pc_inc +
0100 (insn.mm_i_format.simmediate << 1);
0101 else
0102 *contpc = regs->cp0_epc +
0103 dec_insn.pc_inc +
0104 dec_insn.next_pc_inc;
0105 return 1;
0106 case mm_bgezals_op:
0107 case mm_bgezal_op:
0108 regs->regs[31] = regs->cp0_epc +
0109 dec_insn.pc_inc +
0110 dec_insn.next_pc_inc;
0111 fallthrough;
0112 case mm_bgez_op:
0113 if ((long)regs->regs[insn.mm_i_format.rs] >= 0)
0114 *contpc = regs->cp0_epc +
0115 dec_insn.pc_inc +
0116 (insn.mm_i_format.simmediate << 1);
0117 else
0118 *contpc = regs->cp0_epc +
0119 dec_insn.pc_inc +
0120 dec_insn.next_pc_inc;
0121 return 1;
0122 case mm_blez_op:
0123 if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
0124 *contpc = regs->cp0_epc +
0125 dec_insn.pc_inc +
0126 (insn.mm_i_format.simmediate << 1);
0127 else
0128 *contpc = regs->cp0_epc +
0129 dec_insn.pc_inc +
0130 dec_insn.next_pc_inc;
0131 return 1;
0132 case mm_bgtz_op:
0133 if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
0134 *contpc = regs->cp0_epc +
0135 dec_insn.pc_inc +
0136 (insn.mm_i_format.simmediate << 1);
0137 else
0138 *contpc = regs->cp0_epc +
0139 dec_insn.pc_inc +
0140 dec_insn.next_pc_inc;
0141 return 1;
0142 #ifdef CONFIG_MIPS_FP_SUPPORT
0143 case mm_bc2f_op:
0144 case mm_bc1f_op: {
0145 unsigned int fcr31;
0146 unsigned int bit;
0147
0148 bc_false = 1;
0149 fallthrough;
0150 case mm_bc2t_op:
0151 case mm_bc1t_op:
0152 preempt_disable();
0153 if (is_fpu_owner())
0154 fcr31 = read_32bit_cp1_register(CP1_STATUS);
0155 else
0156 fcr31 = current->thread.fpu.fcr31;
0157 preempt_enable();
0158
0159 if (bc_false)
0160 fcr31 = ~fcr31;
0161
0162 bit = (insn.mm_i_format.rs >> 2);
0163 bit += (bit != 0);
0164 bit += 23;
0165 if (fcr31 & (1 << bit))
0166 *contpc = regs->cp0_epc +
0167 dec_insn.pc_inc +
0168 (insn.mm_i_format.simmediate << 1);
0169 else
0170 *contpc = regs->cp0_epc +
0171 dec_insn.pc_inc + dec_insn.next_pc_inc;
0172 return 1;
0173 }
0174 #endif
0175 }
0176 break;
0177 case mm_pool16c_op:
0178 switch (insn.mm_i_format.rt) {
0179 case mm_jalr16_op:
0180 case mm_jalrs16_op:
0181 regs->regs[31] = regs->cp0_epc +
0182 dec_insn.pc_inc + dec_insn.next_pc_inc;
0183 fallthrough;
0184 case mm_jr16_op:
0185 *contpc = regs->regs[insn.mm_i_format.rs];
0186 return 1;
0187 }
0188 break;
0189 case mm_beqz16_op:
0190 if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] == 0)
0191 *contpc = regs->cp0_epc +
0192 dec_insn.pc_inc +
0193 (insn.mm_b1_format.simmediate << 1);
0194 else
0195 *contpc = regs->cp0_epc +
0196 dec_insn.pc_inc + dec_insn.next_pc_inc;
0197 return 1;
0198 case mm_bnez16_op:
0199 if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] != 0)
0200 *contpc = regs->cp0_epc +
0201 dec_insn.pc_inc +
0202 (insn.mm_b1_format.simmediate << 1);
0203 else
0204 *contpc = regs->cp0_epc +
0205 dec_insn.pc_inc + dec_insn.next_pc_inc;
0206 return 1;
0207 case mm_b16_op:
0208 *contpc = regs->cp0_epc + dec_insn.pc_inc +
0209 (insn.mm_b0_format.simmediate << 1);
0210 return 1;
0211 case mm_beq32_op:
0212 if (regs->regs[insn.mm_i_format.rs] ==
0213 regs->regs[insn.mm_i_format.rt])
0214 *contpc = regs->cp0_epc +
0215 dec_insn.pc_inc +
0216 (insn.mm_i_format.simmediate << 1);
0217 else
0218 *contpc = regs->cp0_epc +
0219 dec_insn.pc_inc +
0220 dec_insn.next_pc_inc;
0221 return 1;
0222 case mm_bne32_op:
0223 if (regs->regs[insn.mm_i_format.rs] !=
0224 regs->regs[insn.mm_i_format.rt])
0225 *contpc = regs->cp0_epc +
0226 dec_insn.pc_inc +
0227 (insn.mm_i_format.simmediate << 1);
0228 else
0229 *contpc = regs->cp0_epc +
0230 dec_insn.pc_inc + dec_insn.next_pc_inc;
0231 return 1;
0232 case mm_jalx32_op:
0233 regs->regs[31] = regs->cp0_epc +
0234 dec_insn.pc_inc + dec_insn.next_pc_inc;
0235 *contpc = regs->cp0_epc + dec_insn.pc_inc;
0236 *contpc >>= 28;
0237 *contpc <<= 28;
0238 *contpc |= (insn.j_format.target << 2);
0239 return 1;
0240 case mm_jals32_op:
0241 case mm_jal32_op:
0242 regs->regs[31] = regs->cp0_epc +
0243 dec_insn.pc_inc + dec_insn.next_pc_inc;
0244 fallthrough;
0245 case mm_j32_op:
0246 *contpc = regs->cp0_epc + dec_insn.pc_inc;
0247 *contpc >>= 27;
0248 *contpc <<= 27;
0249 *contpc |= (insn.j_format.target << 1);
0250 set_isa16_mode(*contpc);
0251 return 1;
0252 }
0253 return 0;
0254 }
0255
0256
0257
0258
0259
0260
0261
0262 int __microMIPS_compute_return_epc(struct pt_regs *regs)
0263 {
0264 u16 __user *pc16;
0265 u16 halfword;
0266 unsigned int word;
0267 unsigned long contpc;
0268 struct mm_decoded_insn mminsn = { 0 };
0269
0270 mminsn.micro_mips_mode = 1;
0271
0272
0273 pc16 = (unsigned short __user *)msk_isa16_mode(regs->cp0_epc);
0274 __get_user(halfword, pc16);
0275 pc16++;
0276 contpc = regs->cp0_epc + 2;
0277 word = ((unsigned int)halfword << 16);
0278 mminsn.pc_inc = 2;
0279
0280 if (!mm_insn_16bit(halfword)) {
0281 __get_user(halfword, pc16);
0282 pc16++;
0283 contpc = regs->cp0_epc + 4;
0284 mminsn.pc_inc = 4;
0285 word |= halfword;
0286 }
0287 mminsn.insn = word;
0288
0289 if (get_user(halfword, pc16))
0290 goto sigsegv;
0291 mminsn.next_pc_inc = 2;
0292 word = ((unsigned int)halfword << 16);
0293
0294 if (!mm_insn_16bit(halfword)) {
0295 pc16++;
0296 if (get_user(halfword, pc16))
0297 goto sigsegv;
0298 mminsn.next_pc_inc = 4;
0299 word |= halfword;
0300 }
0301 mminsn.next_insn = word;
0302
0303 mm_isBranchInstr(regs, mminsn, &contpc);
0304
0305 regs->cp0_epc = contpc;
0306
0307 return 0;
0308
0309 sigsegv:
0310 force_sig(SIGSEGV);
0311 return -EFAULT;
0312 }
0313
0314
0315
0316
0317
0318
0319
0320 int __MIPS16e_compute_return_epc(struct pt_regs *regs)
0321 {
0322 u16 __user *addr;
0323 union mips16e_instruction inst;
0324 u16 inst2;
0325 u32 fullinst;
0326 long epc;
0327
0328 epc = regs->cp0_epc;
0329
0330
0331 addr = (u16 __user *)msk_isa16_mode(epc);
0332 if (__get_user(inst.full, addr)) {
0333 force_sig(SIGSEGV);
0334 return -EFAULT;
0335 }
0336
0337 switch (inst.ri.opcode) {
0338 case MIPS16e_extend_op:
0339 regs->cp0_epc += 4;
0340 return 0;
0341
0342
0343
0344
0345 case MIPS16e_jal_op:
0346 addr += 1;
0347 if (__get_user(inst2, addr)) {
0348 force_sig(SIGSEGV);
0349 return -EFAULT;
0350 }
0351 fullinst = ((unsigned)inst.full << 16) | inst2;
0352 regs->regs[31] = epc + 6;
0353 epc += 4;
0354 epc >>= 28;
0355 epc <<= 28;
0356
0357
0358
0359
0360
0361
0362 epc |=
0363 ((fullinst & 0xffff) << 2) | ((fullinst & 0x3e00000) >> 3) |
0364 ((fullinst & 0x1f0000) << 7);
0365 if (!inst.jal.x)
0366 set_isa16_mode(epc);
0367 regs->cp0_epc = epc;
0368 return 0;
0369
0370
0371
0372
0373 case MIPS16e_rr_op:
0374 if (inst.rr.func == MIPS16e_jr_func) {
0375
0376 if (inst.rr.ra)
0377 regs->cp0_epc = regs->regs[31];
0378 else
0379 regs->cp0_epc =
0380 regs->regs[reg16to32[inst.rr.rx]];
0381
0382 if (inst.rr.l) {
0383 if (inst.rr.nd)
0384 regs->regs[31] = epc + 2;
0385 else
0386 regs->regs[31] = epc + 4;
0387 }
0388 return 0;
0389 }
0390 break;
0391 }
0392
0393
0394
0395
0396
0397 regs->cp0_epc += 2;
0398
0399 return 0;
0400 }
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422 int __compute_return_epc_for_insn(struct pt_regs *regs,
0423 union mips_instruction insn)
0424 {
0425 long epc = regs->cp0_epc;
0426 unsigned int dspcontrol;
0427 int ret = 0;
0428
0429 switch (insn.i_format.opcode) {
0430
0431
0432
0433 case spec_op:
0434 switch (insn.r_format.func) {
0435 case jalr_op:
0436 regs->regs[insn.r_format.rd] = epc + 8;
0437 fallthrough;
0438 case jr_op:
0439 if (NO_R6EMU && insn.r_format.func == jr_op)
0440 goto sigill_r2r6;
0441 regs->cp0_epc = regs->regs[insn.r_format.rs];
0442 break;
0443 }
0444 break;
0445
0446
0447
0448
0449
0450
0451 case bcond_op:
0452 switch (insn.i_format.rt) {
0453 case bltzl_op:
0454 if (NO_R6EMU)
0455 goto sigill_r2r6;
0456 fallthrough;
0457 case bltz_op:
0458 if ((long)regs->regs[insn.i_format.rs] < 0) {
0459 epc = epc + 4 + (insn.i_format.simmediate << 2);
0460 if (insn.i_format.rt == bltzl_op)
0461 ret = BRANCH_LIKELY_TAKEN;
0462 } else
0463 epc += 8;
0464 regs->cp0_epc = epc;
0465 break;
0466
0467 case bgezl_op:
0468 if (NO_R6EMU)
0469 goto sigill_r2r6;
0470 fallthrough;
0471 case bgez_op:
0472 if ((long)regs->regs[insn.i_format.rs] >= 0) {
0473 epc = epc + 4 + (insn.i_format.simmediate << 2);
0474 if (insn.i_format.rt == bgezl_op)
0475 ret = BRANCH_LIKELY_TAKEN;
0476 } else
0477 epc += 8;
0478 regs->cp0_epc = epc;
0479 break;
0480
0481 case bltzal_op:
0482 case bltzall_op:
0483 if (NO_R6EMU && (insn.i_format.rs ||
0484 insn.i_format.rt == bltzall_op))
0485 goto sigill_r2r6;
0486 regs->regs[31] = epc + 8;
0487
0488
0489
0490
0491
0492
0493 if (!insn.i_format.rs) {
0494
0495
0496
0497
0498
0499 regs->cp0_epc += 4 +
0500 (insn.i_format.simmediate << 2);
0501 break;
0502 }
0503
0504 if ((long)regs->regs[insn.i_format.rs] < 0) {
0505 epc = epc + 4 + (insn.i_format.simmediate << 2);
0506 if (insn.i_format.rt == bltzall_op)
0507 ret = BRANCH_LIKELY_TAKEN;
0508 } else
0509 epc += 8;
0510 regs->cp0_epc = epc;
0511 break;
0512
0513 case bgezal_op:
0514 case bgezall_op:
0515 if (NO_R6EMU && (insn.i_format.rs ||
0516 insn.i_format.rt == bgezall_op))
0517 goto sigill_r2r6;
0518 regs->regs[31] = epc + 8;
0519
0520
0521
0522
0523
0524
0525 if (!insn.i_format.rs) {
0526
0527
0528
0529
0530
0531 regs->cp0_epc += 4 +
0532 (insn.i_format.simmediate << 2);
0533 break;
0534 }
0535
0536 if ((long)regs->regs[insn.i_format.rs] >= 0) {
0537 epc = epc + 4 + (insn.i_format.simmediate << 2);
0538 if (insn.i_format.rt == bgezall_op)
0539 ret = BRANCH_LIKELY_TAKEN;
0540 } else
0541 epc += 8;
0542 regs->cp0_epc = epc;
0543 break;
0544
0545 case bposge32_op:
0546 if (!cpu_has_dsp)
0547 goto sigill_dsp;
0548
0549 dspcontrol = rddsp(0x01);
0550
0551 if (dspcontrol >= 32) {
0552 epc = epc + 4 + (insn.i_format.simmediate << 2);
0553 } else
0554 epc += 8;
0555 regs->cp0_epc = epc;
0556 break;
0557 }
0558 break;
0559
0560
0561
0562
0563 case jalx_op:
0564 case jal_op:
0565 regs->regs[31] = regs->cp0_epc + 8;
0566 fallthrough;
0567 case j_op:
0568 epc += 4;
0569 epc >>= 28;
0570 epc <<= 28;
0571 epc |= (insn.j_format.target << 2);
0572 regs->cp0_epc = epc;
0573 if (insn.i_format.opcode == jalx_op)
0574 set_isa16_mode(regs->cp0_epc);
0575 break;
0576
0577
0578
0579
0580 case beql_op:
0581 if (NO_R6EMU)
0582 goto sigill_r2r6;
0583 fallthrough;
0584 case beq_op:
0585 if (regs->regs[insn.i_format.rs] ==
0586 regs->regs[insn.i_format.rt]) {
0587 epc = epc + 4 + (insn.i_format.simmediate << 2);
0588 if (insn.i_format.opcode == beql_op)
0589 ret = BRANCH_LIKELY_TAKEN;
0590 } else
0591 epc += 8;
0592 regs->cp0_epc = epc;
0593 break;
0594
0595 case bnel_op:
0596 if (NO_R6EMU)
0597 goto sigill_r2r6;
0598 fallthrough;
0599 case bne_op:
0600 if (regs->regs[insn.i_format.rs] !=
0601 regs->regs[insn.i_format.rt]) {
0602 epc = epc + 4 + (insn.i_format.simmediate << 2);
0603 if (insn.i_format.opcode == bnel_op)
0604 ret = BRANCH_LIKELY_TAKEN;
0605 } else
0606 epc += 8;
0607 regs->cp0_epc = epc;
0608 break;
0609
0610 case blezl_op:
0611 if (!insn.i_format.rt && NO_R6EMU)
0612 goto sigill_r2r6;
0613 fallthrough;
0614 case blez_op:
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628 if (cpu_has_mips_r6 && insn.i_format.rt) {
0629 if ((insn.i_format.opcode == blez_op) &&
0630 ((!insn.i_format.rs && insn.i_format.rt) ||
0631 (insn.i_format.rs == insn.i_format.rt)))
0632 regs->regs[31] = epc + 4;
0633 regs->cp0_epc += 8;
0634 break;
0635 }
0636
0637 if ((long)regs->regs[insn.i_format.rs] <= 0) {
0638 epc = epc + 4 + (insn.i_format.simmediate << 2);
0639 if (insn.i_format.opcode == blezl_op)
0640 ret = BRANCH_LIKELY_TAKEN;
0641 } else
0642 epc += 8;
0643 regs->cp0_epc = epc;
0644 break;
0645
0646 case bgtzl_op:
0647 if (!insn.i_format.rt && NO_R6EMU)
0648 goto sigill_r2r6;
0649 fallthrough;
0650 case bgtz_op:
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664 if (cpu_has_mips_r6 && insn.i_format.rt) {
0665 if ((insn.i_format.opcode == blez_op) &&
0666 ((!insn.i_format.rs && insn.i_format.rt) ||
0667 (insn.i_format.rs == insn.i_format.rt)))
0668 regs->regs[31] = epc + 4;
0669 regs->cp0_epc += 8;
0670 break;
0671 }
0672
0673
0674 if ((long)regs->regs[insn.i_format.rs] > 0) {
0675 epc = epc + 4 + (insn.i_format.simmediate << 2);
0676 if (insn.i_format.opcode == bgtzl_op)
0677 ret = BRANCH_LIKELY_TAKEN;
0678 } else
0679 epc += 8;
0680 regs->cp0_epc = epc;
0681 break;
0682
0683 #ifdef CONFIG_MIPS_FP_SUPPORT
0684
0685
0686
0687 case cop1_op: {
0688 unsigned int bit, fcr31, reg;
0689
0690 if (cpu_has_mips_r6 &&
0691 ((insn.i_format.rs == bc1eqz_op) ||
0692 (insn.i_format.rs == bc1nez_op))) {
0693 if (!init_fp_ctx(current))
0694 lose_fpu(1);
0695 reg = insn.i_format.rt;
0696 bit = get_fpr32(¤t->thread.fpu.fpr[reg], 0) & 0x1;
0697 if (insn.i_format.rs == bc1eqz_op)
0698 bit = !bit;
0699 own_fpu(1);
0700 if (bit)
0701 epc = epc + 4 +
0702 (insn.i_format.simmediate << 2);
0703 else
0704 epc += 8;
0705 regs->cp0_epc = epc;
0706
0707 break;
0708 } else {
0709
0710 preempt_disable();
0711 if (is_fpu_owner())
0712 fcr31 = read_32bit_cp1_register(CP1_STATUS);
0713 else
0714 fcr31 = current->thread.fpu.fcr31;
0715 preempt_enable();
0716
0717 bit = (insn.i_format.rt >> 2);
0718 bit += (bit != 0);
0719 bit += 23;
0720 switch (insn.i_format.rt & 3) {
0721 case 0:
0722 case 2:
0723 if (~fcr31 & (1 << bit)) {
0724 epc = epc + 4 +
0725 (insn.i_format.simmediate << 2);
0726 if (insn.i_format.rt == 2)
0727 ret = BRANCH_LIKELY_TAKEN;
0728 } else
0729 epc += 8;
0730 regs->cp0_epc = epc;
0731 break;
0732
0733 case 1:
0734 case 3:
0735 if (fcr31 & (1 << bit)) {
0736 epc = epc + 4 +
0737 (insn.i_format.simmediate << 2);
0738 if (insn.i_format.rt == 3)
0739 ret = BRANCH_LIKELY_TAKEN;
0740 } else
0741 epc += 8;
0742 regs->cp0_epc = epc;
0743 break;
0744 }
0745 break;
0746 }
0747 }
0748 #endif
0749
0750 #ifdef CONFIG_CPU_CAVIUM_OCTEON
0751 case lwc2_op:
0752 if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
0753 == 0)
0754 epc = epc + 4 + (insn.i_format.simmediate << 2);
0755 else
0756 epc += 8;
0757 regs->cp0_epc = epc;
0758 break;
0759 case ldc2_op:
0760 if ((regs->regs[insn.i_format.rs] &
0761 (1ull<<(insn.i_format.rt+32))) == 0)
0762 epc = epc + 4 + (insn.i_format.simmediate << 2);
0763 else
0764 epc += 8;
0765 regs->cp0_epc = epc;
0766 break;
0767 case swc2_op:
0768 if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
0769 epc = epc + 4 + (insn.i_format.simmediate << 2);
0770 else
0771 epc += 8;
0772 regs->cp0_epc = epc;
0773 break;
0774 case sdc2_op:
0775 if (regs->regs[insn.i_format.rs] &
0776 (1ull<<(insn.i_format.rt+32)))
0777 epc = epc + 4 + (insn.i_format.simmediate << 2);
0778 else
0779 epc += 8;
0780 regs->cp0_epc = epc;
0781 break;
0782 #else
0783 case bc6_op:
0784
0785 if (!cpu_has_mips_r6)
0786 goto sigill_r6;
0787 regs->cp0_epc += 8;
0788 break;
0789 case balc6_op:
0790 if (!cpu_has_mips_r6)
0791 goto sigill_r6;
0792
0793 regs->regs[31] = epc + 4;
0794 epc += 4 + (insn.i_format.simmediate << 2);
0795 regs->cp0_epc = epc;
0796 break;
0797 case pop66_op:
0798 if (!cpu_has_mips_r6)
0799 goto sigill_r6;
0800
0801 regs->cp0_epc += 8;
0802 break;
0803 case pop76_op:
0804 if (!cpu_has_mips_r6)
0805 goto sigill_r6;
0806
0807 if (!insn.i_format.rs) {
0808
0809 regs->regs[31] = epc + 4;
0810 }
0811 regs->cp0_epc += 8;
0812 break;
0813 #endif
0814 case pop10_op:
0815 case pop30_op:
0816
0817 if (!cpu_has_mips_r6)
0818 goto sigill_r6;
0819
0820
0821
0822
0823 if (insn.i_format.rt && !insn.i_format.rs)
0824 regs->regs[31] = epc + 4;
0825 regs->cp0_epc += 8;
0826 break;
0827 }
0828
0829 return ret;
0830
0831 sigill_dsp:
0832 pr_debug("%s: DSP branch but not DSP ASE - sending SIGILL.\n",
0833 current->comm);
0834 force_sig(SIGILL);
0835 return -EFAULT;
0836 sigill_r2r6:
0837 pr_debug("%s: R2 branch but r2-to-r6 emulator is not present - sending SIGILL.\n",
0838 current->comm);
0839 force_sig(SIGILL);
0840 return -EFAULT;
0841 sigill_r6:
0842 pr_debug("%s: R6 branch but no MIPSr6 ISA support - sending SIGILL.\n",
0843 current->comm);
0844 force_sig(SIGILL);
0845 return -EFAULT;
0846 }
0847 EXPORT_SYMBOL_GPL(__compute_return_epc_for_insn);
0848
0849 int __compute_return_epc(struct pt_regs *regs)
0850 {
0851 unsigned int __user *addr;
0852 long epc;
0853 union mips_instruction insn;
0854
0855 epc = regs->cp0_epc;
0856 if (epc & 3)
0857 goto unaligned;
0858
0859
0860
0861
0862 addr = (unsigned int __user *) epc;
0863 if (__get_user(insn.word, addr)) {
0864 force_sig(SIGSEGV);
0865 return -EFAULT;
0866 }
0867
0868 return __compute_return_epc_for_insn(regs, insn);
0869
0870 unaligned:
0871 printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
0872 force_sig(SIGBUS);
0873 return -EFAULT;
0874 }
0875
0876 #if (defined CONFIG_KPROBES) || (defined CONFIG_UPROBES)
0877
0878 int __insn_is_compact_branch(union mips_instruction insn)
0879 {
0880 if (!cpu_has_mips_r6)
0881 return 0;
0882
0883 switch (insn.i_format.opcode) {
0884 case blezl_op:
0885 case bgtzl_op:
0886 case blez_op:
0887 case bgtz_op:
0888
0889
0890
0891
0892 if (insn.i_format.rt)
0893 return 1;
0894 break;
0895 case bc6_op:
0896 case balc6_op:
0897 case pop10_op:
0898 case pop30_op:
0899 case pop66_op:
0900 case pop76_op:
0901 return 1;
0902 }
0903
0904 return 0;
0905 }
0906 EXPORT_SYMBOL_GPL(__insn_is_compact_branch);
0907
0908 #endif