| .. | .. |
|---|
| 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); |
|---|