.. | .. |
---|
242 | 242 | [INSTR_RRF_U0FF] = { F_24, U4_16, F_28, 0, 0, 0 }, |
---|
243 | 243 | [INSTR_RRF_U0RF] = { R_24, U4_16, F_28, 0, 0, 0 }, |
---|
244 | 244 | [INSTR_RRF_U0RR] = { R_24, R_28, U4_16, 0, 0, 0 }, |
---|
| 245 | + [INSTR_RRF_URR] = { R_24, R_28, U8_16, 0, 0, 0 }, |
---|
245 | 246 | [INSTR_RRF_UUFF] = { F_24, U4_16, F_28, U4_20, 0, 0 }, |
---|
246 | 247 | [INSTR_RRF_UUFR] = { F_24, U4_16, R_28, U4_20, 0, 0 }, |
---|
247 | 248 | [INSTR_RRF_UURF] = { R_24, U4_16, F_28, U4_20, 0, 0 }, |
---|
.. | .. |
---|
306 | 307 | [INSTR_VRI_VVV0UU2] = { V_8, V_12, V_16, U8_28, U4_24, 0 }, |
---|
307 | 308 | [INSTR_VRR_0V] = { V_12, 0, 0, 0, 0, 0 }, |
---|
308 | 309 | [INSTR_VRR_0VV0U] = { V_12, V_16, U4_24, 0, 0, 0 }, |
---|
309 | | - [INSTR_VRR_RV0U] = { R_8, V_12, U4_24, 0, 0, 0 }, |
---|
| 310 | + [INSTR_VRR_RV0UU] = { R_8, V_12, U4_24, U4_28, 0, 0 }, |
---|
310 | 311 | [INSTR_VRR_VRR] = { V_8, R_12, R_16, 0, 0, 0 }, |
---|
311 | 312 | [INSTR_VRR_VV] = { V_8, V_12, 0, 0, 0, 0 }, |
---|
312 | 313 | [INSTR_VRR_VV0U] = { V_8, V_12, U4_32, 0, 0, 0 }, |
---|
.. | .. |
---|
326 | 327 | [INSTR_VRS_RVRDU] = { R_8, V_12, D_20, B_16, U4_32, 0 }, |
---|
327 | 328 | [INSTR_VRS_VRRD] = { V_8, R_12, D_20, B_16, 0, 0 }, |
---|
328 | 329 | [INSTR_VRS_VRRDU] = { V_8, R_12, D_20, B_16, U4_32, 0 }, |
---|
329 | | - [INSTR_VRS_VVRD] = { V_8, V_12, D_20, B_16, 0, 0 }, |
---|
330 | 330 | [INSTR_VRS_VVRDU] = { V_8, V_12, D_20, B_16, U4_32, 0 }, |
---|
331 | 331 | [INSTR_VRV_VVXRDU] = { V_8, D_20, VX_12, B_16, U4_32, 0 }, |
---|
332 | | - [INSTR_VRX_VRRD] = { V_8, D_20, X_12, B_16, 0, 0 }, |
---|
333 | 332 | [INSTR_VRX_VRRDU] = { V_8, D_20, X_12, B_16, U4_32, 0 }, |
---|
334 | 333 | [INSTR_VRX_VV] = { V_8, V_12, 0, 0, 0, 0 }, |
---|
335 | 334 | [INSTR_VSI_URDV] = { V_32, D_20, B_16, U8_8, 0, 0 }, |
---|
.. | .. |
---|
483 | 482 | return (int) (ptr - buffer); |
---|
484 | 483 | } |
---|
485 | 484 | |
---|
| 485 | +static int copy_from_regs(struct pt_regs *regs, void *dst, void *src, int len) |
---|
| 486 | +{ |
---|
| 487 | + if (user_mode(regs)) { |
---|
| 488 | + if (copy_from_user(dst, (char __user *)src, len)) |
---|
| 489 | + return -EFAULT; |
---|
| 490 | + } else { |
---|
| 491 | + if (copy_from_kernel_nofault(dst, src, len)) |
---|
| 492 | + return -EFAULT; |
---|
| 493 | + } |
---|
| 494 | + return 0; |
---|
| 495 | +} |
---|
| 496 | + |
---|
486 | 497 | void show_code(struct pt_regs *regs) |
---|
487 | 498 | { |
---|
488 | 499 | char *mode = user_mode(regs) ? "User" : "Krnl"; |
---|
489 | 500 | unsigned char code[64]; |
---|
490 | 501 | char buffer[128], *ptr; |
---|
491 | | - mm_segment_t old_fs; |
---|
492 | 502 | unsigned long addr; |
---|
493 | 503 | int start, end, opsize, hops, i; |
---|
494 | 504 | |
---|
495 | 505 | /* Get a snapshot of the 64 bytes surrounding the fault address. */ |
---|
496 | | - old_fs = get_fs(); |
---|
497 | | - set_fs(user_mode(regs) ? USER_DS : KERNEL_DS); |
---|
498 | 506 | for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) { |
---|
499 | 507 | addr = regs->psw.addr - 34 + start; |
---|
500 | | - if (__copy_from_user(code + start - 2, |
---|
501 | | - (char __user *) addr, 2)) |
---|
| 508 | + if (copy_from_regs(regs, code + start - 2, (void *)addr, 2)) |
---|
502 | 509 | break; |
---|
503 | 510 | } |
---|
504 | 511 | for (end = 32; end < 64; end += 2) { |
---|
505 | 512 | addr = regs->psw.addr + end - 32; |
---|
506 | | - if (__copy_from_user(code + end, |
---|
507 | | - (char __user *) addr, 2)) |
---|
| 513 | + if (copy_from_regs(regs, code + end, (void *)addr, 2)) |
---|
508 | 514 | break; |
---|
509 | 515 | } |
---|
510 | | - set_fs(old_fs); |
---|
511 | 516 | /* Code snapshot useable ? */ |
---|
512 | 517 | if ((regs->psw.addr & 1) || start >= end) { |
---|
513 | 518 | printk("%s Code: Bad PSW.\n", mode); |
---|