• Home
  • Raw
  • Download

Lines Matching +full:a +full:- +full:f

1 // SPDX-License-Identifier: GPL-2.0
3 * Architecture-specific unaligned trap handling.
5 * Copyright (C) 1999-2002, 2004 Hewlett-Packard Co
7 * David Mosberger-Tang <davidm@hpl.hp.com>
9 * 2002/12/09 Fix rotating register handling (off-by-1 error, missing fr-rotation). Fix
10 * get_rse_reg() to not leak kernel bits to user-level (reading an out-of-frame
11 * stacked register returns an undefined value; it does NOT trigger a
36 # define DPRINT(a...) do { printk("%s %u: ", __func__, __LINE__); printk (a); } while (0) argument
51 # define DPRINT(a...) argument
69 * For M-unit:
72 * --------|------|---------|
73 * [40-37] | [36] | [35:30] |
74 * --------|------|---------|
76 * --------------------------
80 * checking the m-bit until later in the load/store emulation.
86 * Table C-28 Integer Load/Store
108 * Table C-29 Integer Load +Reg
110 * we use the ld->m (bit [36:36]) field to determine whether or not we have
111 * a load/store of this form.
115 * Table C-30 Integer Load/Store +Imm
137 * Table C-32 Floating-point Load/Store
150 * Table C-33 Floating-point Load +Reg
152 * we use the ld->m (bit [36:36]) field to determine whether or not we have
153 * a load/store of this form.
157 * Table C-34 Floating-point Load/Store +Imm
194 * A 2-byte value should be enough to hold any kind of offset
197 * simply use RSW instead of RPT or vice-versa.
200 #define RPO(x) ((size_t) &((struct pt_regs *)0)->x)
201 #define RSO(x) ((size_t) &((struct switch_stack *)0)->x)
213 0, /* r0 is read-only : WE SHOULD NEVER GET THIS */
248 # define F(reg) case reg: ia64_invala_gr(reg); break in invala_gr() macro
251 F( 0); F( 1); F( 2); F( 3); F( 4); F( 5); F( 6); F( 7); in invala_gr()
252 F( 8); F( 9); F( 10); F( 11); F( 12); F( 13); F( 14); F( 15); in invala_gr()
253 F( 16); F( 17); F( 18); F( 19); F( 20); F( 21); F( 22); F( 23); in invala_gr()
254 F( 24); F( 25); F( 26); F( 27); F( 28); F( 29); F( 30); F( 31); in invala_gr()
255 F( 32); F( 33); F( 34); F( 35); F( 36); F( 37); F( 38); F( 39); in invala_gr()
256 F( 40); F( 41); F( 42); F( 43); F( 44); F( 45); F( 46); F( 47); in invala_gr()
257 F( 48); F( 49); F( 50); F( 51); F( 52); F( 53); F( 54); F( 55); in invala_gr()
258 F( 56); F( 57); F( 58); F( 59); F( 60); F( 61); F( 62); F( 63); in invala_gr()
259 F( 64); F( 65); F( 66); F( 67); F( 68); F( 69); F( 70); F( 71); in invala_gr()
260 F( 72); F( 73); F( 74); F( 75); F( 76); F( 77); F( 78); F( 79); in invala_gr()
261 F( 80); F( 81); F( 82); F( 83); F( 84); F( 85); F( 86); F( 87); in invala_gr()
262 F( 88); F( 89); F( 90); F( 91); F( 92); F( 93); F( 94); F( 95); in invala_gr()
263 F( 96); F( 97); F( 98); F( 99); F(100); F(101); F(102); F(103); in invala_gr()
264 F(104); F(105); F(106); F(107); F(108); F(109); F(110); F(111); in invala_gr()
265 F(112); F(113); F(114); F(115); F(116); F(117); F(118); F(119); in invala_gr()
266 F(120); F(121); F(122); F(123); F(124); F(125); F(126); F(127); in invala_gr()
268 # undef F in invala_gr()
271 /* Invalidate ALAT entry for floating-point register REGNO. */
275 # define F(reg) case reg: ia64_invala_fr(reg); break in invala_fr() macro
278 F( 0); F( 1); F( 2); F( 3); F( 4); F( 5); F( 6); F( 7); in invala_fr()
279 F( 8); F( 9); F( 10); F( 11); F( 12); F( 13); F( 14); F( 15); in invala_fr()
280 F( 16); F( 17); F( 18); F( 19); F( 20); F( 21); F( 22); F( 23); in invala_fr()
281 F( 24); F( 25); F( 26); F( 27); F( 28); F( 29); F( 30); F( 31); in invala_fr()
282 F( 32); F( 33); F( 34); F( 35); F( 36); F( 37); F( 38); F( 39); in invala_fr()
283 F( 40); F( 41); F( 42); F( 43); F( 44); F( 45); F( 46); F( 47); in invala_fr()
284 F( 48); F( 49); F( 50); F( 51); F( 52); F( 53); F( 54); F( 55); in invala_fr()
285 F( 56); F( 57); F( 58); F( 59); F( 60); F( 61); F( 62); F( 63); in invala_fr()
286 F( 64); F( 65); F( 66); F( 67); F( 68); F( 69); F( 70); F( 71); in invala_fr()
287 F( 72); F( 73); F( 74); F( 75); F( 76); F( 77); F( 78); F( 79); in invala_fr()
288 F( 80); F( 81); F( 82); F( 83); F( 84); F( 85); F( 86); F( 87); in invala_fr()
289 F( 88); F( 89); F( 90); F( 91); F( 92); F( 93); F( 94); F( 95); in invala_fr()
290 F( 96); F( 97); F( 98); F( 99); F(100); F(101); F(102); F(103); in invala_fr()
291 F(104); F(105); F(106); F(107); F(108); F(109); F(110); F(111); in invala_fr()
292 F(112); F(113); F(114); F(115); F(116); F(117); F(118); F(119); in invala_fr()
293 F(120); F(121); F(122); F(123); F(124); F(125); F(126); F(127); in invala_fr()
295 # undef F in invala_fr()
303 reg -= sor; in rotate_reg()
310 struct switch_stack *sw = (struct switch_stack *) regs - 1; in set_rse_reg()
315 long sof = (regs->cr_ifs) & 0x7f; in set_rse_reg()
316 long sor = 8 * ((regs->cr_ifs >> 14) & 0xf); in set_rse_reg()
317 long rrb_gr = (regs->cr_ifs >> 18) & 0x7f; in set_rse_reg()
318 long ridx = r1 - 32; in set_rse_reg()
330 r1, sw->ar_bspstore, regs->ar_bspstore, sof, (regs->cr_ifs >> 7) & 0x7f, ridx); in set_rse_reg()
332 on_kbs = ia64_rse_num_regs(kbs, (unsigned long *) sw->ar_bspstore); in set_rse_reg()
333 addr = ia64_rse_skip_regs((unsigned long *) sw->ar_bspstore, -sof + ridx); in set_rse_reg()
337 if ((unsigned long) rnat_addr >= sw->ar_bspstore) in set_rse_reg()
338 rnat_addr = &sw->ar_rnat; in set_rse_reg()
354 bspstore = (unsigned long *)regs->ar_bspstore; in set_rse_reg()
356 bsp = ia64_rse_skip_regs(ubs_end, -sof); in set_rse_reg()
383 struct switch_stack *sw = (struct switch_stack *) regs - 1; in get_rse_reg()
388 long sof = (regs->cr_ifs) & 0x7f; in get_rse_reg()
389 long sor = 8 * ((regs->cr_ifs >> 14) & 0xf); in get_rse_reg()
390 long rrb_gr = (regs->cr_ifs >> 18) & 0x7f; in get_rse_reg()
391 long ridx = r1 - 32; in get_rse_reg()
394 /* read of out-of-frame register returns an undefined value; 0 in our case. */ in get_rse_reg()
403 r1, sw->ar_bspstore, regs->ar_bspstore, sof, (regs->cr_ifs >> 7) & 0x7f, ridx); in get_rse_reg()
405 on_kbs = ia64_rse_num_regs(kbs, (unsigned long *) sw->ar_bspstore); in get_rse_reg()
406 addr = ia64_rse_skip_regs((unsigned long *) sw->ar_bspstore, -sof + ridx); in get_rse_reg()
412 if ((unsigned long) rnat_addr >= sw->ar_bspstore) in get_rse_reg()
413 rnat_addr = &sw->ar_rnat; in get_rse_reg()
425 bspstore = (unsigned long *)regs->ar_bspstore; in get_rse_reg()
427 bsp = ia64_rse_skip_regs(ubs_end, -sof); in get_rse_reg()
456 struct switch_stack *sw = (struct switch_stack *) regs - 1; in setreg()
470 * Using r0 as a target raises a General Exception fault which has higher priority in setreg()
475 * Now look at registers in [0-31] range and init correct UNAT in setreg()
479 unat = &sw->ar_unat; in setreg()
482 unat = &sw->caller_unat; in setreg()
485 addr, unat==&sw->ar_unat ? "yes":"no", GR_OFFS(regnum)); in setreg()
496 * UNAT bit_pos = GR[r3]{8:3} form EAS-2.4 in setreg()
510 * range from 32-127, result is in the range from 0-95.
515 unsigned long rrb_fr = (regs->cr_ifs >> 25) & 0x7f; in fph_index()
516 return rotate_reg(96, rrb_fr, (regnum - IA64_FIRST_ROTATING_FR)); in fph_index()
522 struct switch_stack *sw = (struct switch_stack *)regs - 1; in setfpreg()
526 * From EAS-2.5: FPDisableFault has higher priority than Unaligned in setfpreg()
528 * To update f32-f127, there are three choices: in setfpreg()
530 * (1) save f32-f127 to thread.fph and update the values there in setfpreg()
531 * (2) use a gigantic switch statement to directly access the registers in setfpreg()
538 current->thread.fph[fph_index(regs, regnum)] = *fpval; in setfpreg()
560 regs->cr_ipsr |= IA64_PSR_MFL; in setfpreg()
583 struct switch_stack *sw = (struct switch_stack *) regs - 1; in getfpreg()
587 * From EAS-2.5: FPDisableFault has higher priority than in getfpreg()
591 * When regnum > 31, the register is still live and we need to force a save in getfpreg()
592 * to current->thread.fph to get access to it. See discussion in setfpreg() in getfpreg()
597 *fpval = current->thread.fph[fph_index(regs, regnum)]; in getfpreg()
630 struct switch_stack *sw = (struct switch_stack *) regs - 1; in getreg()
639 * take care of r0 (read-only always evaluate to 0) in getreg()
649 * Now look at registers in [0-31] range and init correct UNAT in getreg()
653 unat = &sw->ar_unat; in getreg()
656 unat = &sw->caller_unat; in getreg()
726 * Note: that we update r3 even in the case of ldfX.a in emulate_load_updates()
736 * never reach this code when trying to do a ldX.s. in emulate_load_updates()
744 * propagate Nat r2 -> r3 in emulate_load_updates()
784 * ldX.a we will emulate load and also invalidate the ALAT entry. in emulate_load_int()
785 * See comment below for explanation on how we handle ldX.a in emulate_load_int()
790 return -1; in emulate_load_int()
792 /* this assumes little-endian byte-order: */ in emulate_load_int()
794 return -1; in emulate_load_int()
807 * - acquire semantics would have been used, so force fence instead. in emulate_load_int()
810 * - if we get to this handler, it's because the entry was not in the ALAT. in emulate_load_int()
811 * Therefore the operation reverts to a normal load in emulate_load_int()
814 * - same as previous one in emulate_load_int()
817 * - same as above for c.clr part. The load needs to have acquire semantics. So in emulate_load_int()
820 * ldX.a (advanced load): in emulate_load_int()
821 * - suppose ldX.a r1=[r3]. If we get to the unaligned trap it's because the in emulate_load_int()
825 * The load part can be handled just like a normal load, however the difficult in emulate_load_int()
827 * in the base address of the load & size. To do that, a ld.a must be executed, in emulate_load_int()
828 * clearly any address can be pushed into the table by using ld1.a r1=[r3]. Now in emulate_load_int()
829 * if we use the same target register, we will be okay for the check.a instruction. in emulate_load_int()
830 * If we look at the store, basically a stX [r3]=r1 checks the ALAT for any entry in emulate_load_int()
835 * ld4.a r1=[r3] in emulate_load_int()
838 * ld1.a r1=[r3],1 in emulate_load_int()
840 * ld1.a r1=[r3],1 in emulate_load_int()
842 * ld1.a r1=[r3],1 in emulate_load_int()
844 * ld1.a r1=[r3] in emulate_load_int()
851 * execute exactly the same kind of load. You could do it from a aligned in emulate_load_int()
857 * We will always convert ld.a into a normal load with ALAT invalidated. This in emulate_load_int()
858 * will enable compiler to do optimization where certain code path after ld.a in emulate_load_int()
859 * is not required to have ld.c/chk.a, e.g., code path with no intervening stores. in emulate_load_int()
861 * If there is a store after the advanced load, one must either do a ld.c.* or in emulate_load_int()
862 * chk.a.* to reuse the value stored in the ALAT. Both can "fail" (meaning no in emulate_load_int()
865 * - ld.c.*, if the entry is not present a normal load is executed in emulate_load_int()
866 * - chk.a.*, if the entry is not present, execution jumps to recovery code in emulate_load_int()
870 * ALAT must be invalidated for the register (so that chk.a or ld.c don't pick in emulate_load_int()
871 * up a stale entry later). The register base update MUST also be performed. in emulate_load_int()
911 * a single switch/case. in emulate_store_int()
917 return -1; in emulate_store_int()
920 /* this assumes little-endian byte-order: */ in emulate_store_int()
922 return -1; in emulate_store_int()
953 * to do the complete flush :-<< in emulate_store_int()
1062 * ldfpX.a: we don't try to emulate anything but we must in emulate_load_floatpair()
1067 * This assumes little-endian byte-order. Note that there is no "ldfpe" in emulate_load_floatpair()
1072 return -1; in emulate_load_floatpair()
1102 * A possible optimization would be to drop fpr_final and directly in emulate_load_floatpair()
1124 * as long as we don't come here with a ldfpX.s. in emulate_load_floatpair()
1168 * ldfX.a we don't try to emulate anything but we must in emulate_load_float()
1174 return -1; in emulate_load_float()
1199 * A possible optimization would be to drop fpr_final and directly in emulate_load_float()
1267 return -1; in emulate_store_float()
1299 * to do the complete flush :-<< in emulate_store_float()
1324 int ret = -1; in ia64_handle_unaligned()
1327 if (ia64_psr(regs)->be) { in ia64_handle_unaligned()
1328 /* we don't support big-endian accesses */ in ia64_handle_unaligned()
1329 if (die_if_kernel("big-endian unaligned accesses are not supported", regs, 0)) in ia64_handle_unaligned()
1336 * user-level unaligned accesses. Otherwise, a clever program could trick this in ia64_handle_unaligned()
1340 eh = search_exception_tables(regs->cr_iip + ia64_psr(regs)->ri); in ia64_handle_unaligned()
1342 if ((current->thread.flags & IA64_THREAD_UAC_SIGBUS) != 0) in ia64_handle_unaligned()
1346 !(current->thread.flags & IA64_THREAD_UAC_NOPRINT) && in ia64_handle_unaligned()
1353 "ip=0x%016lx\n\r", current->comm, in ia64_handle_unaligned()
1355 ifa, regs->cr_iip + ipsr->ri); in ia64_handle_unaligned()
1365 buf[len-1] = '\0'; /* drop '\r' */ in ia64_handle_unaligned()
1377 "echo 0 > /proc/sys/kernel/ignore-" in ia64_handle_unaligned()
1378 "unaligned-usertrap to re-enable\n", in ia64_handle_unaligned()
1379 current->comm, task_pid_nr(current)); in ia64_handle_unaligned()
1385 ifa, regs->cr_iip + ipsr->ri); in ia64_handle_unaligned()
1393 regs->cr_iip, ifa, regs->cr_ipsr, ipsr->ri, ipsr->it); in ia64_handle_unaligned()
1395 if (emulate_load(bundle, regs->cr_iip, 16, kernel_mode)) in ia64_handle_unaligned()
1401 switch (ipsr->ri) { in ia64_handle_unaligned()
1418 * is WRONG to try and emulate. Here is a list of instruction we don't emulate i.e., in ia64_handle_unaligned()
1419 * the program will get a signal and die: in ia64_handle_unaligned()
1422 * - ldX.spill in ia64_handle_unaligned()
1423 * - stX.spill in ia64_handle_unaligned()
1425 * - ld16 in ia64_handle_unaligned()
1426 * - st16 in ia64_handle_unaligned()
1427 * Reason: ld16 and st16 are supposed to occur in a single in ia64_handle_unaligned()
1431 * - cmpxchg in ia64_handle_unaligned()
1432 * - fetchadd in ia64_handle_unaligned()
1433 * - xchg in ia64_handle_unaligned()
1438 * - ldX.sZ in ia64_handle_unaligned()
1441 * --------------------------------------------------------------------------------- in ia64_handle_unaligned()
1451 /* oops, really a semaphore op (cmpxchg, etc) */ in ia64_handle_unaligned()
1468 regs->cr_ipsr |= IA64_PSR_ED; in ia64_handle_unaligned()
1479 /* oops, really a semaphore op (cmpxchg, etc) */ in ia64_handle_unaligned()
1495 /* oops, really a semaphore op (cmpxchg, etc) */ in ia64_handle_unaligned()
1532 if (ipsr->ri == 2) in ia64_handle_unaligned()
1534 * given today's architecture this case is not likely to happen because a in ia64_handle_unaligned()
1535 * memory access instruction (M) can never be in the last slot of a in ia64_handle_unaligned()
1538 regs->cr_iip += 16; in ia64_handle_unaligned()
1539 ipsr->ri = (ipsr->ri + 1) & 0x3; in ia64_handle_unaligned()
1541 DPRINT("ipsr->ri=%d iip=%lx\n", ipsr->ri, regs->cr_iip); in ia64_handle_unaligned()