~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/kernel/branch.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * This file is subject to the terms and conditions of the GNU General Public
  3  * License.  See the file "COPYING" in the main directory of this archive
  4  * for more details.
  5  *
  6  * Copyright (C) 1996, 97, 2000, 2001 by Ralf Baechle
  7  * Copyright (C) 2001 MIPS Technologies, Inc.
  8  */
  9 #include <linux/kernel.h>
 10 #include <linux/sched/signal.h>
 11 #include <linux/signal.h>
 12 #include <linux/export.h>
 13 #include <asm/branch.h>
 14 #include <asm/cpu.h>
 15 #include <asm/cpu-features.h>
 16 #include <asm/fpu.h>
 17 #include <asm/fpu_emulator.h>
 18 #include <asm/inst.h>
 19 #include <asm/mips-r2-to-r6-emul.h>
 20 #include <asm/ptrace.h>
 21 #include <linux/uaccess.h>
 22 
 23 #include "probes-common.h"
 24 
 25 /*
 26  * Calculate and return exception PC in case of branch delay slot
 27  * for microMIPS and MIPS16e. It does not clear the ISA mode bit.
 28  */
 29 int __isa_exception_epc(struct pt_regs *regs)
 30 {
 31         unsigned short inst;
 32         long epc = regs->cp0_epc;
 33 
 34         /* Calculate exception PC in branch delay slot. */
 35         if (__get_user(inst, (u16 __user *) msk_isa16_mode(epc))) {
 36                 /* This should never happen because delay slot was checked. */
 37                 force_sig(SIGSEGV);
 38                 return epc;
 39         }
 40         if (cpu_has_mips16) {
 41                 union mips16e_instruction inst_mips16e;
 42 
 43                 inst_mips16e.full = inst;
 44                 if (inst_mips16e.ri.opcode == MIPS16e_jal_op)
 45                         epc += 4;
 46                 else
 47                         epc += 2;
 48         } else if (mm_insn_16bit(inst))
 49                 epc += 2;
 50         else
 51                 epc += 4;
 52 
 53         return epc;
 54 }
 55 
 56 /* (microMIPS) Convert 16-bit register encoding to 32-bit register encoding. */
 57 static const unsigned int reg16to32map[8] = {16, 17, 2, 3, 4, 5, 6, 7};
 58 
 59 int __mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 60                        unsigned long *contpc)
 61 {
 62         union mips_instruction insn = (union mips_instruction)dec_insn.insn;
 63         int __maybe_unused bc_false = 0;
 64 
 65         if (!cpu_has_mmips)
 66                 return 0;
 67 
 68         switch (insn.mm_i_format.opcode) {
 69         case mm_pool32a_op:
 70                 if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) ==
 71                     mm_pool32axf_op) {
 72                         switch (insn.mm_i_format.simmediate >>
 73                                 MM_POOL32A_MINOR_SHIFT) {
 74                         case mm_jalr_op:
 75                         case mm_jalrhb_op:
 76                         case mm_jalrs_op:
 77                         case mm_jalrshb_op:
 78                                 if (insn.mm_i_format.rt != 0)   /* Not mm_jr */
 79                                         regs->regs[insn.mm_i_format.rt] =
 80                                                 regs->cp0_epc +
 81                                                 dec_insn.pc_inc +
 82                                                 dec_insn.next_pc_inc;
 83                                 *contpc = regs->regs[insn.mm_i_format.rs];
 84                                 return 1;
 85                         }
 86                 }
 87                 break;
 88         case mm_pool32i_op:
 89                 switch (insn.mm_i_format.rt) {
 90                 case mm_bltzals_op:
 91                 case mm_bltzal_op:
 92                         regs->regs[31] = regs->cp0_epc +
 93                                 dec_insn.pc_inc +
 94                                 dec_insn.next_pc_inc;
 95                         fallthrough;
 96                 case mm_bltz_op:
 97                         if ((long)regs->regs[insn.mm_i_format.rs] < 0)
 98                                 *contpc = regs->cp0_epc +
 99                                         dec_insn.pc_inc +
100                                         (insn.mm_i_format.simmediate << 1);
101                         else
102                                 *contpc = regs->cp0_epc +
103                                         dec_insn.pc_inc +
104                                         dec_insn.next_pc_inc;
105                         return 1;
106                 case mm_bgezals_op:
107                 case mm_bgezal_op:
108                         regs->regs[31] = regs->cp0_epc +
109                                         dec_insn.pc_inc +
110                                         dec_insn.next_pc_inc;
111                         fallthrough;
112                 case mm_bgez_op:
113                         if ((long)regs->regs[insn.mm_i_format.rs] >= 0)
114                                 *contpc = regs->cp0_epc +
115                                         dec_insn.pc_inc +
116                                         (insn.mm_i_format.simmediate << 1);
117                         else
118                                 *contpc = regs->cp0_epc +
119                                         dec_insn.pc_inc +
120                                         dec_insn.next_pc_inc;
121                         return 1;
122                 case mm_blez_op:
123                         if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
124                                 *contpc = regs->cp0_epc +
125                                         dec_insn.pc_inc +
126                                         (insn.mm_i_format.simmediate << 1);
127                         else
128                                 *contpc = regs->cp0_epc +
129                                         dec_insn.pc_inc +
130                                         dec_insn.next_pc_inc;
131                         return 1;
132                 case mm_bgtz_op:
133                         if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
134                                 *contpc = regs->cp0_epc +
135                                         dec_insn.pc_inc +
136                                         (insn.mm_i_format.simmediate << 1);
137                         else
138                                 *contpc = regs->cp0_epc +
139                                         dec_insn.pc_inc +
140                                         dec_insn.next_pc_inc;
141                         return 1;
142 #ifdef CONFIG_MIPS_FP_SUPPORT
143                 case mm_bc2f_op:
144                 case mm_bc1f_op: {
145                         unsigned int fcr31;
146                         unsigned int bit;
147 
148                         bc_false = 1;
149                         fallthrough;
150                 case mm_bc2t_op:
151                 case mm_bc1t_op:
152                         preempt_disable();
153                         if (is_fpu_owner())
154                                 fcr31 = read_32bit_cp1_register(CP1_STATUS);
155                         else
156                                 fcr31 = current->thread.fpu.fcr31;
157                         preempt_enable();
158 
159                         if (bc_false)
160                                 fcr31 = ~fcr31;
161 
162                         bit = (insn.mm_i_format.rs >> 2);
163                         bit += (bit != 0);
164                         bit += 23;
165                         if (fcr31 & (1 << bit))
166                                 *contpc = regs->cp0_epc +
167                                         dec_insn.pc_inc +
168                                         (insn.mm_i_format.simmediate << 1);
169                         else
170                                 *contpc = regs->cp0_epc +
171                                         dec_insn.pc_inc + dec_insn.next_pc_inc;
172                         return 1;
173                 }
174 #endif /* CONFIG_MIPS_FP_SUPPORT */
175                 }
176                 break;
177         case mm_pool16c_op:
178                 switch (insn.mm_i_format.rt) {
179                 case mm_jalr16_op:
180                 case mm_jalrs16_op:
181                         regs->regs[31] = regs->cp0_epc +
182                                 dec_insn.pc_inc + dec_insn.next_pc_inc;
183                         fallthrough;
184                 case mm_jr16_op:
185                         *contpc = regs->regs[insn.mm_i_format.rs];
186                         return 1;
187                 }
188                 break;
189         case mm_beqz16_op:
190                 if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] == 0)
191                         *contpc = regs->cp0_epc +
192                                 dec_insn.pc_inc +
193                                 (insn.mm_b1_format.simmediate << 1);
194                 else
195                         *contpc = regs->cp0_epc +
196                                 dec_insn.pc_inc + dec_insn.next_pc_inc;
197                 return 1;
198         case mm_bnez16_op:
199                 if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] != 0)
200                         *contpc = regs->cp0_epc +
201                                 dec_insn.pc_inc +
202                                 (insn.mm_b1_format.simmediate << 1);
203                 else
204                         *contpc = regs->cp0_epc +
205                                 dec_insn.pc_inc + dec_insn.next_pc_inc;
206                 return 1;
207         case mm_b16_op:
208                 *contpc = regs->cp0_epc + dec_insn.pc_inc +
209                          (insn.mm_b0_format.simmediate << 1);
210                 return 1;
211         case mm_beq32_op:
212                 if (regs->regs[insn.mm_i_format.rs] ==
213                     regs->regs[insn.mm_i_format.rt])
214                         *contpc = regs->cp0_epc +
215                                 dec_insn.pc_inc +
216                                 (insn.mm_i_format.simmediate << 1);
217                 else
218                         *contpc = regs->cp0_epc +
219                                 dec_insn.pc_inc +
220                                 dec_insn.next_pc_inc;
221                 return 1;
222         case mm_bne32_op:
223                 if (regs->regs[insn.mm_i_format.rs] !=
224                     regs->regs[insn.mm_i_format.rt])
225                         *contpc = regs->cp0_epc +
226                                 dec_insn.pc_inc +
227                                 (insn.mm_i_format.simmediate << 1);
228                 else
229                         *contpc = regs->cp0_epc +
230                                 dec_insn.pc_inc + dec_insn.next_pc_inc;
231                 return 1;
232         case mm_jalx32_op:
233                 regs->regs[31] = regs->cp0_epc +
234                         dec_insn.pc_inc + dec_insn.next_pc_inc;
235                 *contpc = regs->cp0_epc + dec_insn.pc_inc;
236                 *contpc >>= 28;
237                 *contpc <<= 28;
238                 *contpc |= (insn.j_format.target << 2);
239                 return 1;
240         case mm_jals32_op:
241         case mm_jal32_op:
242                 regs->regs[31] = regs->cp0_epc +
243                         dec_insn.pc_inc + dec_insn.next_pc_inc;
244                 fallthrough;
245         case mm_j32_op:
246                 *contpc = regs->cp0_epc + dec_insn.pc_inc;
247                 *contpc >>= 27;
248                 *contpc <<= 27;
249                 *contpc |= (insn.j_format.target << 1);
250                 set_isa16_mode(*contpc);
251                 return 1;
252         }
253         return 0;
254 }
255 
256 /*
257  * Compute return address and emulate branch in microMIPS mode after an
258  * exception only. It does not handle compact branches/jumps and cannot
259  * be used in interrupt context. (Compact branches/jumps do not cause
260  * exceptions.)
261  */
262 int __microMIPS_compute_return_epc(struct pt_regs *regs)
263 {
264         u16 __user *pc16;
265         u16 halfword;
266         unsigned int word;
267         unsigned long contpc;
268         struct mm_decoded_insn mminsn = { 0 };
269 
270         mminsn.micro_mips_mode = 1;
271 
272         /* This load never faults. */
273         pc16 = (unsigned short __user *)msk_isa16_mode(regs->cp0_epc);
274         __get_user(halfword, pc16);
275         pc16++;
276         contpc = regs->cp0_epc + 2;
277         word = ((unsigned int)halfword << 16);
278         mminsn.pc_inc = 2;
279 
280         if (!mm_insn_16bit(halfword)) {
281                 __get_user(halfword, pc16);
282                 pc16++;
283                 contpc = regs->cp0_epc + 4;
284                 mminsn.pc_inc = 4;
285                 word |= halfword;
286         }
287         mminsn.insn = word;
288 
289         if (get_user(halfword, pc16))
290                 goto sigsegv;
291         mminsn.next_pc_inc = 2;
292         word = ((unsigned int)halfword << 16);
293 
294         if (!mm_insn_16bit(halfword)) {
295                 pc16++;
296                 if (get_user(halfword, pc16))
297                         goto sigsegv;
298                 mminsn.next_pc_inc = 4;
299                 word |= halfword;
300         }
301         mminsn.next_insn = word;
302 
303         mm_isBranchInstr(regs, mminsn, &contpc);
304 
305         regs->cp0_epc = contpc;
306 
307         return 0;
308 
309 sigsegv:
310         force_sig(SIGSEGV);
311         return -EFAULT;
312 }
313 
314 /*
315  * Compute return address and emulate branch in MIPS16e mode after an
316  * exception only. It does not handle compact branches/jumps and cannot
317  * be used in interrupt context. (Compact branches/jumps do not cause
318  * exceptions.)
319  */
320 int __MIPS16e_compute_return_epc(struct pt_regs *regs)
321 {
322         u16 __user *addr;
323         union mips16e_instruction inst;
324         u16 inst2;
325         u32 fullinst;
326         long epc;
327 
328         epc = regs->cp0_epc;
329 
330         /* Read the instruction. */
331         addr = (u16 __user *)msk_isa16_mode(epc);
332         if (__get_user(inst.full, addr)) {
333                 force_sig(SIGSEGV);
334                 return -EFAULT;
335         }
336 
337         switch (inst.ri.opcode) {
338         case MIPS16e_extend_op:
339                 regs->cp0_epc += 4;
340                 return 0;
341 
342                 /*
343                  *  JAL and JALX in MIPS16e mode
344                  */
345         case MIPS16e_jal_op:
346                 addr += 1;
347                 if (__get_user(inst2, addr)) {
348                         force_sig(SIGSEGV);
349                         return -EFAULT;
350                 }
351                 fullinst = ((unsigned)inst.full << 16) | inst2;
352                 regs->regs[31] = epc + 6;
353                 epc += 4;
354                 epc >>= 28;
355                 epc <<= 28;
356                 /*
357                  * JAL:5 X:1 TARGET[20-16]:5 TARGET[25:21]:5 TARGET[15:0]:16
358                  *
359                  * ......TARGET[15:0].................TARGET[20:16]...........
360                  * ......TARGET[25:21]
361                  */
362                 epc |=
363                     ((fullinst & 0xffff) << 2) | ((fullinst & 0x3e00000) >> 3) |
364                     ((fullinst & 0x1f0000) << 7);
365                 if (!inst.jal.x)
366                         set_isa16_mode(epc);    /* Set ISA mode bit. */
367                 regs->cp0_epc = epc;
368                 return 0;
369 
370                 /*
371                  *  J(AL)R(C)
372                  */
373         case MIPS16e_rr_op:
374                 if (inst.rr.func == MIPS16e_jr_func) {
375 
376                         if (inst.rr.ra)
377                                 regs->cp0_epc = regs->regs[31];
378                         else
379                                 regs->cp0_epc =
380                                     regs->regs[reg16to32[inst.rr.rx]];
381 
382                         if (inst.rr.l) {
383                                 if (inst.rr.nd)
384                                         regs->regs[31] = epc + 2;
385                                 else
386                                         regs->regs[31] = epc + 4;
387                         }
388                         return 0;
389                 }
390                 break;
391         }
392 
393         /*
394          * All other cases have no branch delay slot and are 16-bits.
395          * Branches do not cause an exception.
396          */
397         regs->cp0_epc += 2;
398 
399         return 0;
400 }
401 
402 /**
403  * __compute_return_epc_for_insn - Computes the return address and do emulate
404  *                                  branch simulation, if required.
405  *
406  * @regs:       Pointer to pt_regs
407  * @insn:       branch instruction to decode
408  * Return:      -EFAULT on error and forces SIGILL, and on success
409  *              returns 0 or BRANCH_LIKELY_TAKEN as appropriate after
410  *              evaluating the branch.
411  *
412  * MIPS R6 Compact branches and forbidden slots:
413  *      Compact branches do not throw exceptions because they do
414  *      not have delay slots. The forbidden slot instruction ($PC+4)
415  *      is only executed if the branch was not taken. Otherwise the
416  *      forbidden slot is skipped entirely. This means that the
417  *      only possible reason to be here because of a MIPS R6 compact
418  *      branch instruction is that the forbidden slot has thrown one.
419  *      In that case the branch was not taken, so the EPC can be safely
420  *      set to EPC + 8.
421  */
422 int __compute_return_epc_for_insn(struct pt_regs *regs,
423                                    union mips_instruction insn)
424 {
425         long epc = regs->cp0_epc;
426         unsigned int dspcontrol;
427         int ret = 0;
428 
429         switch (insn.i_format.opcode) {
430         /*
431          * jr and jalr are in r_format format.
432          */
433         case spec_op:
434                 switch (insn.r_format.func) {
435                 case jalr_op:
436                         regs->regs[insn.r_format.rd] = epc + 8;
437                         fallthrough;
438                 case jr_op:
439                         if (NO_R6EMU && insn.r_format.func == jr_op)
440                                 goto sigill_r2r6;
441                         regs->cp0_epc = regs->regs[insn.r_format.rs];
442                         break;
443                 }
444                 break;
445 
446         /*
447          * This group contains:
448          * bltz_op, bgez_op, bltzl_op, bgezl_op,
449          * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
450          */
451         case bcond_op:
452                 switch (insn.i_format.rt) {
453                 case bltzl_op:
454                         if (NO_R6EMU)
455                                 goto sigill_r2r6;
456                         fallthrough;
457                 case bltz_op:
458                         if ((long)regs->regs[insn.i_format.rs] < 0) {
459                                 epc = epc + 4 + (insn.i_format.simmediate << 2);
460                                 if (insn.i_format.rt == bltzl_op)
461                                         ret = BRANCH_LIKELY_TAKEN;
462                         } else
463                                 epc += 8;
464                         regs->cp0_epc = epc;
465                         break;
466 
467                 case bgezl_op:
468                         if (NO_R6EMU)
469                                 goto sigill_r2r6;
470                         fallthrough;
471                 case bgez_op:
472                         if ((long)regs->regs[insn.i_format.rs] >= 0) {
473                                 epc = epc + 4 + (insn.i_format.simmediate << 2);
474                                 if (insn.i_format.rt == bgezl_op)
475                                         ret = BRANCH_LIKELY_TAKEN;
476                         } else
477                                 epc += 8;
478                         regs->cp0_epc = epc;
479                         break;
480 
481                 case bltzal_op:
482                 case bltzall_op:
483                         if (NO_R6EMU && (insn.i_format.rs ||
484                             insn.i_format.rt == bltzall_op))
485                                 goto sigill_r2r6;
486                         regs->regs[31] = epc + 8;
487                         /*
488                          * OK we are here either because we hit a NAL
489                          * instruction or because we are emulating an
490                          * old bltzal{,l} one. Let's figure out what the
491                          * case really is.
492                          */
493                         if (!insn.i_format.rs) {
494                                 /*
495                                  * NAL or BLTZAL with rs == 0
496                                  * Doesn't matter if we are R6 or not. The
497                                  * result is the same
498                                  */
499                                 regs->cp0_epc += 4 +
500                                         (insn.i_format.simmediate << 2);
501                                 break;
502                         }
503                         /* Now do the real thing for non-R6 BLTZAL{,L} */
504                         if ((long)regs->regs[insn.i_format.rs] < 0) {
505                                 epc = epc + 4 + (insn.i_format.simmediate << 2);
506                                 if (insn.i_format.rt == bltzall_op)
507                                         ret = BRANCH_LIKELY_TAKEN;
508                         } else
509                                 epc += 8;
510                         regs->cp0_epc = epc;
511                         break;
512 
513                 case bgezal_op:
514                 case bgezall_op:
515                         if (NO_R6EMU && (insn.i_format.rs ||
516                             insn.i_format.rt == bgezall_op))
517                                 goto sigill_r2r6;
518                         regs->regs[31] = epc + 8;
519                         /*
520                          * OK we are here either because we hit a BAL
521                          * instruction or because we are emulating an
522                          * old bgezal{,l} one. Let's figure out what the
523                          * case really is.
524                          */
525                         if (!insn.i_format.rs) {
526                                 /*
527                                  * BAL or BGEZAL with rs == 0
528                                  * Doesn't matter if we are R6 or not. The
529                                  * result is the same
530                                  */
531                                 regs->cp0_epc += 4 +
532                                         (insn.i_format.simmediate << 2);
533                                 break;
534                         }
535                         /* Now do the real thing for non-R6 BGEZAL{,L} */
536                         if ((long)regs->regs[insn.i_format.rs] >= 0) {
537                                 epc = epc + 4 + (insn.i_format.simmediate << 2);
538                                 if (insn.i_format.rt == bgezall_op)
539                                         ret = BRANCH_LIKELY_TAKEN;
540                         } else
541                                 epc += 8;
542                         regs->cp0_epc = epc;
543                         break;
544 
545                 case bposge32_op:
546                         if (!cpu_has_dsp)
547                                 goto sigill_dsp;
548 
549                         dspcontrol = rddsp(0x01);
550 
551                         if (dspcontrol >= 32) {
552                                 epc = epc + 4 + (insn.i_format.simmediate << 2);
553                         } else
554                                 epc += 8;
555                         regs->cp0_epc = epc;
556                         break;
557                 }
558                 break;
559 
560         /*
561          * These are unconditional and in j_format.
562          */
563         case jalx_op:
564         case jal_op:
565                 regs->regs[31] = regs->cp0_epc + 8;
566                 fallthrough;
567         case j_op:
568                 epc += 4;
569                 epc >>= 28;
570                 epc <<= 28;
571                 epc |= (insn.j_format.target << 2);
572                 regs->cp0_epc = epc;
573                 if (insn.i_format.opcode == jalx_op)
574                         set_isa16_mode(regs->cp0_epc);
575                 break;
576 
577         /*
578          * These are conditional and in i_format.
579          */
580         case beql_op:
581                 if (NO_R6EMU)
582                         goto sigill_r2r6;
583                 fallthrough;
584         case beq_op:
585                 if (regs->regs[insn.i_format.rs] ==
586                     regs->regs[insn.i_format.rt]) {
587                         epc = epc + 4 + (insn.i_format.simmediate << 2);
588                         if (insn.i_format.opcode == beql_op)
589                                 ret = BRANCH_LIKELY_TAKEN;
590                 } else
591                         epc += 8;
592                 regs->cp0_epc = epc;
593                 break;
594 
595         case bnel_op:
596                 if (NO_R6EMU)
597                         goto sigill_r2r6;
598                 fallthrough;
599         case bne_op:
600                 if (regs->regs[insn.i_format.rs] !=
601                     regs->regs[insn.i_format.rt]) {
602                         epc = epc + 4 + (insn.i_format.simmediate << 2);
603                         if (insn.i_format.opcode == bnel_op)
604                                 ret = BRANCH_LIKELY_TAKEN;
605                 } else
606                         epc += 8;
607                 regs->cp0_epc = epc;
608                 break;
609 
610         case blezl_op: /* not really i_format */
611                 if (!insn.i_format.rt && NO_R6EMU)
612                         goto sigill_r2r6;
613                 fallthrough;
614         case blez_op:
615                 /*
616                  * Compact branches for R6 for the
617                  * blez and blezl opcodes.
618                  * BLEZ  | rs = 0 | rt != 0  == BLEZALC
619                  * BLEZ  | rs = rt != 0      == BGEZALC
620                  * BLEZ  | rs != 0 | rt != 0 == BGEUC
621                  * BLEZL | rs = 0 | rt != 0  == BLEZC
622                  * BLEZL | rs = rt != 0      == BGEZC
623                  * BLEZL | rs != 0 | rt != 0 == BGEC
624                  *
625                  * For real BLEZ{,L}, rt is always 0.
626                  */
627 
628                 if (cpu_has_mips_r6 && insn.i_format.rt) {
629                         if ((insn.i_format.opcode == blez_op) &&
630                             ((!insn.i_format.rs && insn.i_format.rt) ||
631                              (insn.i_format.rs == insn.i_format.rt)))
632                                 regs->regs[31] = epc + 4;
633                         regs->cp0_epc += 8;
634                         break;
635                 }
636                 /* rt field assumed to be zero */
637                 if ((long)regs->regs[insn.i_format.rs] <= 0) {
638                         epc = epc + 4 + (insn.i_format.simmediate << 2);
639                         if (insn.i_format.opcode == blezl_op)
640                                 ret = BRANCH_LIKELY_TAKEN;
641                 } else
642                         epc += 8;
643                 regs->cp0_epc = epc;
644                 break;
645 
646         case bgtzl_op:
647                 if (!insn.i_format.rt && NO_R6EMU)
648                         goto sigill_r2r6;
649                 fallthrough;
650         case bgtz_op:
651                 /*
652                  * Compact branches for R6 for the
653                  * bgtz and bgtzl opcodes.
654                  * BGTZ  | rs = 0 | rt != 0  == BGTZALC
655                  * BGTZ  | rs = rt != 0      == BLTZALC
656                  * BGTZ  | rs != 0 | rt != 0 == BLTUC
657                  * BGTZL | rs = 0 | rt != 0  == BGTZC
658                  * BGTZL | rs = rt != 0      == BLTZC
659                  * BGTZL | rs != 0 | rt != 0 == BLTC
660                  *
661                  * *ZALC varint for BGTZ &&& rt != 0
662                  * For real GTZ{,L}, rt is always 0.
663                  */
664                 if (cpu_has_mips_r6 && insn.i_format.rt) {
665                         if ((insn.i_format.opcode == blez_op) &&
666                             ((!insn.i_format.rs && insn.i_format.rt) ||
667                             (insn.i_format.rs == insn.i_format.rt)))
668                                 regs->regs[31] = epc + 4;
669                         regs->cp0_epc += 8;
670                         break;
671                 }
672 
673                 /* rt field assumed to be zero */
674                 if ((long)regs->regs[insn.i_format.rs] > 0) {
675                         epc = epc + 4 + (insn.i_format.simmediate << 2);
676                         if (insn.i_format.opcode == bgtzl_op)
677                                 ret = BRANCH_LIKELY_TAKEN;
678                 } else
679                         epc += 8;
680                 regs->cp0_epc = epc;
681                 break;
682 
683 #ifdef CONFIG_MIPS_FP_SUPPORT
684         /*
685          * And now the FPA/cp1 branch instructions.
686          */
687         case cop1_op: {
688                 unsigned int bit, fcr31, reg;
689 
690                 if (cpu_has_mips_r6 &&
691                     ((insn.i_format.rs == bc1eqz_op) ||
692                      (insn.i_format.rs == bc1nez_op))) {
693                         if (!init_fp_ctx(current))
694                                 lose_fpu(1);
695                         reg = insn.i_format.rt;
696                         bit = get_fpr32(&current->thread.fpu.fpr[reg], 0) & 0x1;
697                         if (insn.i_format.rs == bc1eqz_op)
698                                 bit = !bit;
699                         own_fpu(1);
700                         if (bit)
701                                 epc = epc + 4 +
702                                         (insn.i_format.simmediate << 2);
703                         else
704                                 epc += 8;
705                         regs->cp0_epc = epc;
706 
707                         break;
708                 } else {
709 
710                         preempt_disable();
711                         if (is_fpu_owner())
712                                 fcr31 = read_32bit_cp1_register(CP1_STATUS);
713                         else
714                                 fcr31 = current->thread.fpu.fcr31;
715                         preempt_enable();
716 
717                         bit = (insn.i_format.rt >> 2);
718                         bit += (bit != 0);
719                         bit += 23;
720                         switch (insn.i_format.rt & 3) {
721                         case 0: /* bc1f */
722                         case 2: /* bc1fl */
723                                 if (~fcr31 & (1 << bit)) {
724                                         epc = epc + 4 +
725                                                 (insn.i_format.simmediate << 2);
726                                         if (insn.i_format.rt == 2)
727                                                 ret = BRANCH_LIKELY_TAKEN;
728                                 } else
729                                         epc += 8;
730                                 regs->cp0_epc = epc;
731                                 break;
732 
733                         case 1: /* bc1t */
734                         case 3: /* bc1tl */
735                                 if (fcr31 & (1 << bit)) {
736                                         epc = epc + 4 +
737                                                 (insn.i_format.simmediate << 2);
738                                         if (insn.i_format.rt == 3)
739                                                 ret = BRANCH_LIKELY_TAKEN;
740                                 } else
741                                         epc += 8;
742                                 regs->cp0_epc = epc;
743                                 break;
744                         }
745                         break;
746                 }
747         }
748 #endif /* CONFIG_MIPS_FP_SUPPORT */
749 
750 #ifdef CONFIG_CPU_CAVIUM_OCTEON
751         case lwc2_op: /* This is bbit0 on Octeon */
752                 if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
753                      == 0)
754                         epc = epc + 4 + (insn.i_format.simmediate << 2);
755                 else
756                         epc += 8;
757                 regs->cp0_epc = epc;
758                 break;
759         case ldc2_op: /* This is bbit032 on Octeon */
760                 if ((regs->regs[insn.i_format.rs] &
761                     (1ull<<(insn.i_format.rt+32))) == 0)
762                         epc = epc + 4 + (insn.i_format.simmediate << 2);
763                 else
764                         epc += 8;
765                 regs->cp0_epc = epc;
766                 break;
767         case swc2_op: /* This is bbit1 on Octeon */
768                 if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
769                         epc = epc + 4 + (insn.i_format.simmediate << 2);
770                 else
771                         epc += 8;
772                 regs->cp0_epc = epc;
773                 break;
774         case sdc2_op: /* This is bbit132 on Octeon */
775                 if (regs->regs[insn.i_format.rs] &
776                     (1ull<<(insn.i_format.rt+32)))
777                         epc = epc + 4 + (insn.i_format.simmediate << 2);
778                 else
779                         epc += 8;
780                 regs->cp0_epc = epc;
781                 break;
782 #else
783         case bc6_op:
784                 /* Only valid for MIPS R6 */
785                 if (!cpu_has_mips_r6)
786                         goto sigill_r6;
787                 regs->cp0_epc += 8;
788                 break;
789         case balc6_op:
790                 if (!cpu_has_mips_r6)
791                         goto sigill_r6;
792                 /* Compact branch: BALC */
793                 regs->regs[31] = epc + 4;
794                 epc += 4 + (insn.i_format.simmediate << 2);
795                 regs->cp0_epc = epc;
796                 break;
797         case pop66_op:
798                 if (!cpu_has_mips_r6)
799                         goto sigill_r6;
800                 /* Compact branch: BEQZC || JIC */
801                 regs->cp0_epc += 8;
802                 break;
803         case pop76_op:
804                 if (!cpu_has_mips_r6)
805                         goto sigill_r6;
806                 /* Compact branch: BNEZC || JIALC */
807                 if (!insn.i_format.rs) {
808                         /* JIALC: set $31/ra */
809                         regs->regs[31] = epc + 4;
810                 }
811                 regs->cp0_epc += 8;
812                 break;
813 #endif
814         case pop10_op:
815         case pop30_op:
816                 /* Only valid for MIPS R6 */
817                 if (!cpu_has_mips_r6)
818                         goto sigill_r6;
819                 /*
820                  * Compact branches:
821                  * bovc, beqc, beqzalc, bnvc, bnec, bnezlac
822                  */
823                 if (insn.i_format.rt && !insn.i_format.rs)
824                         regs->regs[31] = epc + 4;
825                 regs->cp0_epc += 8;
826                 break;
827         }
828 
829         return ret;
830 
831 sigill_dsp:
832         pr_debug("%s: DSP branch but not DSP ASE - sending SIGILL.\n",
833                  current->comm);
834         force_sig(SIGILL);
835         return -EFAULT;
836 sigill_r2r6:
837         pr_debug("%s: R2 branch but r2-to-r6 emulator is not present - sending SIGILL.\n",
838                  current->comm);
839         force_sig(SIGILL);
840         return -EFAULT;
841 sigill_r6:
842         pr_debug("%s: R6 branch but no MIPSr6 ISA support - sending SIGILL.\n",
843                  current->comm);
844         force_sig(SIGILL);
845         return -EFAULT;
846 }
847 EXPORT_SYMBOL_GPL(__compute_return_epc_for_insn);
848 
849 int __compute_return_epc(struct pt_regs *regs)
850 {
851         unsigned int __user *addr;
852         long epc;
853         union mips_instruction insn;
854 
855         epc = regs->cp0_epc;
856         if (epc & 3)
857                 goto unaligned;
858 
859         /*
860          * Read the instruction
861          */
862         addr = (unsigned int __user *) epc;
863         if (__get_user(insn.word, addr)) {
864                 force_sig(SIGSEGV);
865                 return -EFAULT;
866         }
867 
868         return __compute_return_epc_for_insn(regs, insn);
869 
870 unaligned:
871         printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
872         force_sig(SIGBUS);
873         return -EFAULT;
874 }
875 
876 #if (defined CONFIG_KPROBES) || (defined CONFIG_UPROBES)
877 
878 int __insn_is_compact_branch(union mips_instruction insn)
879 {
880         if (!cpu_has_mips_r6)
881                 return 0;
882 
883         switch (insn.i_format.opcode) {
884         case blezl_op:
885         case bgtzl_op:
886         case blez_op:
887         case bgtz_op:
888                 /*
889                  * blez[l] and bgtz[l] opcodes with non-zero rt
890                  * are MIPS R6 compact branches
891                  */
892                 if (insn.i_format.rt)
893                         return 1;
894                 break;
895         case bc6_op:
896         case balc6_op:
897         case pop10_op:
898         case pop30_op:
899         case pop66_op:
900         case pop76_op:
901                 return 1;
902         }
903 
904         return 0;
905 }
906 EXPORT_SYMBOL_GPL(__insn_is_compact_branch);
907 
908 #endif  /* CONFIG_KPROBES || CONFIG_UPROBES */
909 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php