1 // SPDX-License-Identifier: GPL-2.0-only 2 /* ptrace.c: Sparc process tracing support. 3 * 4 * Copyright (C) 1996, 2008 David S. Miller (davem@davemloft.net) 5 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 6 * 7 * Based upon code written by Ross Biro, Linus Torvalds, Bob Manson, 8 * and David Mosberger. 9 * 10 * Added Linux support -miguel (weird, eh?, the original code was meant 11 * to emulate SunOS). 12 */ 13 14 #include <linux/kernel.h> 15 #include <linux/sched.h> 16 #include <linux/sched/task_stack.h> 17 #include <linux/mm.h> 18 #include <linux/errno.h> 19 #include <linux/export.h> 20 #include <linux/ptrace.h> 21 #include <linux/user.h> 22 #include <linux/smp.h> 23 #include <linux/security.h> 24 #include <linux/seccomp.h> 25 #include <linux/audit.h> 26 #include <linux/signal.h> 27 #include <linux/regset.h> 28 #include <linux/tracehook.h> 29 #include <trace/syscall.h> 30 #include <linux/compat.h> 31 #include <linux/elf.h> 32 #include <linux/context_tracking.h> 33 34 #include <asm/asi.h> 35 #include <asm/pgtable.h> 36 #include <linux/uaccess.h> 37 #include <asm/psrcompat.h> 38 #include <asm/visasm.h> 39 #include <asm/spitfire.h> 40 #include <asm/page.h> 41 #include <asm/cpudata.h> 42 #include <asm/cacheflush.h> 43 44 #define CREATE_TRACE_POINTS 45 #include <trace/events/syscalls.h> 46 47 #include "entry.h" 48 49 /* #define ALLOW_INIT_TRACING */ 50 51 struct pt_regs_offset { 52 const char *name; 53 int offset; 54 }; 55 56 #define REG_OFFSET_NAME(n, r) \ 57 {.name = n, .offset = (PT_V9_##r)} 58 #define REG_OFFSET_END {.name = NULL, .offset = 0} 59 60 static const struct pt_regs_offset regoffset_table[] = { 61 REG_OFFSET_NAME("g0", G0), 62 REG_OFFSET_NAME("g1", G1), 63 REG_OFFSET_NAME("g2", G2), 64 REG_OFFSET_NAME("g3", G3), 65 REG_OFFSET_NAME("g4", G4), 66 REG_OFFSET_NAME("g5", G5), 67 REG_OFFSET_NAME("g6", G6), 68 REG_OFFSET_NAME("g7", G7), 69 70 REG_OFFSET_NAME("i0", I0), 71 REG_OFFSET_NAME("i1", I1), 72 REG_OFFSET_NAME("i2", I2), 73 REG_OFFSET_NAME("i3", I3), 74 REG_OFFSET_NAME("i4", I4), 75 REG_OFFSET_NAME("i5", I5), 76 REG_OFFSET_NAME("i6", I6), 77 REG_OFFSET_NAME("i7", I7), 78 79 REG_OFFSET_NAME("tstate", TSTATE), 80 REG_OFFSET_NAME("pc", TPC), 81 REG_OFFSET_NAME("npc", TNPC), 82 REG_OFFSET_NAME("y", Y), 83 REG_OFFSET_NAME("lr", I7), 84 85 REG_OFFSET_END, 86 }; 87 88 /* 89 * Called by kernel/ptrace.c when detaching.. 90 * 91 * Make sure single step bits etc are not set. 92 */ 93 void ptrace_disable(struct task_struct *child) 94 { 95 /* nothing to do */ 96 } 97 98 /* To get the necessary page struct, access_process_vm() first calls 99 * get_user_pages(). This has done a flush_dcache_page() on the 100 * accessed page. Then our caller (copy_{to,from}_user_page()) did 101 * to memcpy to read/write the data from that page. 102 * 103 * Now, the only thing we have to do is: 104 * 1) flush the D-cache if it's possible than an illegal alias 105 * has been created 106 * 2) flush the I-cache if this is pre-cheetah and we did a write 107 */ 108 void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, 109 unsigned long uaddr, void *kaddr, 110 unsigned long len, int write) 111 { 112 BUG_ON(len > PAGE_SIZE); 113 114 if (tlb_type == hypervisor) 115 return; 116 117 preempt_disable(); 118 119 #ifdef DCACHE_ALIASING_POSSIBLE 120 /* If bit 13 of the kernel address we used to access the 121 * user page is the same as the virtual address that page 122 * is mapped to in the user's address space, we can skip the 123 * D-cache flush. 124 */ 125 if ((uaddr ^ (unsigned long) kaddr) & (1UL << 13)) { 126 unsigned long start = __pa(kaddr); 127 unsigned long end = start + len; 128 unsigned long dcache_line_size; 129 130 dcache_line_size = local_cpu_data().dcache_line_size; 131 132 if (tlb_type == spitfire) { 133 for (; start < end; start += dcache_line_size) 134 spitfire_put_dcache_tag(start & 0x3fe0, 0x0); 135 } else { 136 start &= ~(dcache_line_size - 1); 137 for (; start < end; start += dcache_line_size) 138 __asm__ __volatile__( 139 "stxa %%g0, [%0] %1\n\t" 140 "membar #Sync" 141 : /* no outputs */ 142 : "r" (start), 143 "i" (ASI_DCACHE_INVALIDATE)); 144 } 145 } 146 #endif 147 if (write && tlb_type == spitfire) { 148 unsigned long start = (unsigned long) kaddr; 149 unsigned long end = start + len; 150 unsigned long icache_line_size; 151 152 icache_line_size = local_cpu_data().icache_line_size; 153 154 for (; start < end; start += icache_line_size) 155 flushi(start); 156 } 157 158 preempt_enable(); 159 } 160 EXPORT_SYMBOL_GPL(flush_ptrace_access); 161 162 static int get_from_target(struct task_struct *target, unsigned long uaddr, 163 void *kbuf, int len) 164 { 165 if (target == current) { 166 if (copy_from_user(kbuf, (void __user *) uaddr, len)) 167 return -EFAULT; 168 } else { 169 int len2 = access_process_vm(target, uaddr, kbuf, len, 170 FOLL_FORCE); 171 if (len2 != len) 172 return -EFAULT; 173 } 174 return 0; 175 } 176 177 static int set_to_target(struct task_struct *target, unsigned long uaddr, 178 void *kbuf, int len) 179 { 180 if (target == current) { 181 if (copy_to_user((void __user *) uaddr, kbuf, len)) 182 return -EFAULT; 183 } else { 184 int len2 = access_process_vm(target, uaddr, kbuf, len, 185 FOLL_FORCE | FOLL_WRITE); 186 if (len2 != len) 187 return -EFAULT; 188 } 189 return 0; 190 } 191 192 static int regwindow64_get(struct task_struct *target, 193 const struct pt_regs *regs, 194 struct reg_window *wbuf) 195 { 196 unsigned long rw_addr = regs->u_regs[UREG_I6]; 197 198 if (!test_thread_64bit_stack(rw_addr)) { 199 struct reg_window32 win32; 200 int i; 201 202 if (get_from_target(target, rw_addr, &win32, sizeof(win32))) 203 return -EFAULT; 204 for (i = 0; i < 8; i++) 205 wbuf->locals[i] = win32.locals[i]; 206 for (i = 0; i < 8; i++) 207 wbuf->ins[i] = win32.ins[i]; 208 } else { 209 rw_addr += STACK_BIAS; 210 if (get_from_target(target, rw_addr, wbuf, sizeof(*wbuf))) 211 return -EFAULT; 212 } 213 214 return 0; 215 } 216 217 static int regwindow64_set(struct task_struct *target, 218 const struct pt_regs *regs, 219 struct reg_window *wbuf) 220 { 221 unsigned long rw_addr = regs->u_regs[UREG_I6]; 222 223 if (!test_thread_64bit_stack(rw_addr)) { 224 struct reg_window32 win32; 225 int i; 226 227 for (i = 0; i < 8; i++) 228 win32.locals[i] = wbuf->locals[i]; 229 for (i = 0; i < 8; i++) 230 win32.ins[i] = wbuf->ins[i]; 231 232 if (set_to_target(target, rw_addr, &win32, sizeof(win32))) 233 return -EFAULT; 234 } else { 235 rw_addr += STACK_BIAS; 236 if (set_to_target(target, rw_addr, wbuf, sizeof(*wbuf))) 237 return -EFAULT; 238 } 239 240 return 0; 241 } 242 243 enum sparc_regset { 244 REGSET_GENERAL, 245 REGSET_FP, 246 }; 247 248 static int genregs64_get(struct task_struct *target, 249 const struct user_regset *regset, 250 unsigned int pos, unsigned int count, 251 void *kbuf, void __user *ubuf) 252 { 253 const struct pt_regs *regs = task_pt_regs(target); 254 int ret; 255 256 if (target == current) 257 flushw_user(); 258 259 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 260 regs->u_regs, 261 0, 16 * sizeof(u64)); 262 if (!ret && count && pos < (32 * sizeof(u64))) { 263 struct reg_window window; 264 265 if (regwindow64_get(target, regs, &window)) 266 return -EFAULT; 267 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 268 &window, 269 16 * sizeof(u64), 270 32 * sizeof(u64)); 271 } 272 273 if (!ret) { 274 /* TSTATE, TPC, TNPC */ 275 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 276 ®s->tstate, 277 32 * sizeof(u64), 278 35 * sizeof(u64)); 279 } 280 281 if (!ret) { 282 unsigned long y = regs->y; 283 284 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 285 &y, 286 35 * sizeof(u64), 287 36 * sizeof(u64)); 288 } 289 290 if (!ret) { 291 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 292 36 * sizeof(u64), -1); 293 294 } 295 return ret; 296 } 297 298 static int genregs64_set(struct task_struct *target, 299 const struct user_regset *regset, 300 unsigned int pos, unsigned int count, 301 const void *kbuf, const void __user *ubuf) 302 { 303 struct pt_regs *regs = task_pt_regs(target); 304 int ret; 305 306 if (target == current) 307 flushw_user(); 308 309 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 310 regs->u_regs, 311 0, 16 * sizeof(u64)); 312 if (!ret && count && pos < (32 * sizeof(u64))) { 313 struct reg_window window; 314 315 if (regwindow64_get(target, regs, &window)) 316 return -EFAULT; 317 318 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 319 &window, 320 16 * sizeof(u64), 321 32 * sizeof(u64)); 322 323 if (!ret && 324 regwindow64_set(target, regs, &window)) 325 return -EFAULT; 326 } 327 328 if (!ret && count > 0) { 329 unsigned long tstate; 330 331 /* TSTATE */ 332 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 333 &tstate, 334 32 * sizeof(u64), 335 33 * sizeof(u64)); 336 if (!ret) { 337 /* Only the condition codes and the "in syscall" 338 * state can be modified in the %tstate register. 339 */ 340 tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL); 341 regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL); 342 regs->tstate |= tstate; 343 } 344 } 345 346 if (!ret) { 347 /* TPC, TNPC */ 348 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 349 ®s->tpc, 350 33 * sizeof(u64), 351 35 * sizeof(u64)); 352 } 353 354 if (!ret) { 355 unsigned long y = regs->y; 356 357 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 358 &y, 359 35 * sizeof(u64), 360 36 * sizeof(u64)); 361 if (!ret) 362 regs->y = y; 363 } 364 365 if (!ret) 366 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 367 36 * sizeof(u64), -1); 368 369 return ret; 370 } 371 372 static int fpregs64_get(struct task_struct *target, 373 const struct user_regset *regset, 374 unsigned int pos, unsigned int count, 375 void *kbuf, void __user *ubuf) 376 { 377 const unsigned long *fpregs = task_thread_info(target)->fpregs; 378 unsigned long fprs, fsr, gsr; 379 int ret; 380 381 if (target == current) 382 save_and_clear_fpu(); 383 384 fprs = task_thread_info(target)->fpsaved[0]; 385 386 if (fprs & FPRS_DL) 387 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 388 fpregs, 389 0, 16 * sizeof(u64)); 390 else 391 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 392 0, 393 16 * sizeof(u64)); 394 395 if (!ret) { 396 if (fprs & FPRS_DU) 397 ret = user_regset_copyout(&pos, &count, 398 &kbuf, &ubuf, 399 fpregs + 16, 400 16 * sizeof(u64), 401 32 * sizeof(u64)); 402 else 403 ret = user_regset_copyout_zero(&pos, &count, 404 &kbuf, &ubuf, 405 16 * sizeof(u64), 406 32 * sizeof(u64)); 407 } 408 409 if (fprs & FPRS_FEF) { 410 fsr = task_thread_info(target)->xfsr[0]; 411 gsr = task_thread_info(target)->gsr[0]; 412 } else { 413 fsr = gsr = 0; 414 } 415 416 if (!ret) 417 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 418 &fsr, 419 32 * sizeof(u64), 420 33 * sizeof(u64)); 421 if (!ret) 422 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 423 &gsr, 424 33 * sizeof(u64), 425 34 * sizeof(u64)); 426 if (!ret) 427 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 428 &fprs, 429 34 * sizeof(u64), 430 35 * sizeof(u64)); 431 432 if (!ret) 433 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 434 35 * sizeof(u64), -1); 435 436 return ret; 437 } 438 439 static int fpregs64_set(struct task_struct *target, 440 const struct user_regset *regset, 441 unsigned int pos, unsigned int count, 442 const void *kbuf, const void __user *ubuf) 443 { 444 unsigned long *fpregs = task_thread_info(target)->fpregs; 445 unsigned long fprs; 446 int ret; 447 448 if (target == current) 449 save_and_clear_fpu(); 450 451 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 452 fpregs, 453 0, 32 * sizeof(u64)); 454 if (!ret) 455 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 456 task_thread_info(target)->xfsr, 457 32 * sizeof(u64), 458 33 * sizeof(u64)); 459 if (!ret) 460 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 461 task_thread_info(target)->gsr, 462 33 * sizeof(u64), 463 34 * sizeof(u64)); 464 465 fprs = task_thread_info(target)->fpsaved[0]; 466 if (!ret && count > 0) { 467 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 468 &fprs, 469 34 * sizeof(u64), 470 35 * sizeof(u64)); 471 } 472 473 fprs |= (FPRS_FEF | FPRS_DL | FPRS_DU); 474 task_thread_info(target)->fpsaved[0] = fprs; 475 476 if (!ret) 477 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 478 35 * sizeof(u64), -1); 479 return ret; 480 } 481 482 static const struct user_regset sparc64_regsets[] = { 483 /* Format is: 484 * G0 --> G7 485 * O0 --> O7 486 * L0 --> L7 487 * I0 --> I7 488 * TSTATE, TPC, TNPC, Y 489 */ 490 [REGSET_GENERAL] = { 491 .core_note_type = NT_PRSTATUS, 492 .n = 36, 493 .size = sizeof(u64), .align = sizeof(u64), 494 .get = genregs64_get, .set = genregs64_set 495 }, 496 /* Format is: 497 * F0 --> F63 498 * FSR 499 * GSR 500 * FPRS 501 */ 502 [REGSET_FP] = { 503 .core_note_type = NT_PRFPREG, 504 .n = 35, 505 .size = sizeof(u64), .align = sizeof(u64), 506 .get = fpregs64_get, .set = fpregs64_set 507 }, 508 }; 509 510 static const struct user_regset_view user_sparc64_view = { 511 .name = "sparc64", .e_machine = EM_SPARCV9, 512 .regsets = sparc64_regsets, .n = ARRAY_SIZE(sparc64_regsets) 513 }; 514 515 #ifdef CONFIG_COMPAT 516 static int genregs32_get(struct task_struct *target, 517 const struct user_regset *regset, 518 unsigned int pos, unsigned int count, 519 void *kbuf, void __user *ubuf) 520 { 521 const struct pt_regs *regs = task_pt_regs(target); 522 compat_ulong_t __user *reg_window; 523 compat_ulong_t *k = kbuf; 524 compat_ulong_t __user *u = ubuf; 525 compat_ulong_t reg; 526 527 if (target == current) 528 flushw_user(); 529 530 pos /= sizeof(reg); 531 count /= sizeof(reg); 532 533 if (kbuf) { 534 for (; count > 0 && pos < 16; count--) 535 *k++ = regs->u_regs[pos++]; 536 537 reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6]; 538 reg_window -= 16; 539 if (target == current) { 540 for (; count > 0 && pos < 32; count--) { 541 if (get_user(*k++, ®_window[pos++])) 542 return -EFAULT; 543 } 544 } else { 545 for (; count > 0 && pos < 32; count--) { 546 if (access_process_vm(target, 547 (unsigned long) 548 ®_window[pos], 549 k, sizeof(*k), 550 FOLL_FORCE) 551 != sizeof(*k)) 552 return -EFAULT; 553 k++; 554 pos++; 555 } 556 } 557 } else { 558 for (; count > 0 && pos < 16; count--) { 559 if (put_user((compat_ulong_t) regs->u_regs[pos++], u++)) 560 return -EFAULT; 561 } 562 563 reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6]; 564 reg_window -= 16; 565 if (target == current) { 566 for (; count > 0 && pos < 32; count--) { 567 if (get_user(reg, ®_window[pos++]) || 568 put_user(reg, u++)) 569 return -EFAULT; 570 } 571 } else { 572 for (; count > 0 && pos < 32; count--) { 573 if (access_process_vm(target, 574 (unsigned long) 575 ®_window[pos], 576 ®, sizeof(reg), 577 FOLL_FORCE) 578 != sizeof(reg)) 579 return -EFAULT; 580 if (access_process_vm(target, 581 (unsigned long) u, 582 ®, sizeof(reg), 583 FOLL_FORCE | FOLL_WRITE) 584 != sizeof(reg)) 585 return -EFAULT; 586 pos++; 587 u++; 588 } 589 } 590 } 591 while (count > 0) { 592 switch (pos) { 593 case 32: /* PSR */ 594 reg = tstate_to_psr(regs->tstate); 595 break; 596 case 33: /* PC */ 597 reg = regs->tpc; 598 break; 599 case 34: /* NPC */ 600 reg = regs->tnpc; 601 break; 602 case 35: /* Y */ 603 reg = regs->y; 604 break; 605 case 36: /* WIM */ 606 case 37: /* TBR */ 607 reg = 0; 608 break; 609 default: 610 goto finish; 611 } 612 613 if (kbuf) 614 *k++ = reg; 615 else if (put_user(reg, u++)) 616 return -EFAULT; 617 pos++; 618 count--; 619 } 620 finish: 621 pos *= sizeof(reg); 622 count *= sizeof(reg); 623 624 return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 625 38 * sizeof(reg), -1); 626 } 627 628 static int genregs32_set(struct task_struct *target, 629 const struct user_regset *regset, 630 unsigned int pos, unsigned int count, 631 const void *kbuf, const void __user *ubuf) 632 { 633 struct pt_regs *regs = task_pt_regs(target); 634 compat_ulong_t __user *reg_window; 635 const compat_ulong_t *k = kbuf; 636 const compat_ulong_t __user *u = ubuf; 637 compat_ulong_t reg; 638 639 if (target == current) 640 flushw_user(); 641 642 pos /= sizeof(reg); 643 count /= sizeof(reg); 644 645 if (kbuf) { 646 for (; count > 0 && pos < 16; count--) 647 regs->u_regs[pos++] = *k++; 648 649 reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6]; 650 reg_window -= 16; 651 if (target == current) { 652 for (; count > 0 && pos < 32; count--) { 653 if (put_user(*k++, ®_window[pos++])) 654 return -EFAULT; 655 } 656 } else { 657 for (; count > 0 && pos < 32; count--) { 658 if (access_process_vm(target, 659 (unsigned long) 660 ®_window[pos], 661 (void *) k, 662 sizeof(*k), 663 FOLL_FORCE | FOLL_WRITE) 664 != sizeof(*k)) 665 return -EFAULT; 666 k++; 667 pos++; 668 } 669 } 670 } else { 671 for (; count > 0 && pos < 16; count--) { 672 if (get_user(reg, u++)) 673 return -EFAULT; 674 regs->u_regs[pos++] = reg; 675 } 676 677 reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6]; 678 reg_window -= 16; 679 if (target == current) { 680 for (; count > 0 && pos < 32; count--) { 681 if (get_user(reg, u++) || 682 put_user(reg, ®_window[pos++])) 683 return -EFAULT; 684 } 685 } else { 686 for (; count > 0 && pos < 32; count--) { 687 if (access_process_vm(target, 688 (unsigned long) 689 u, 690 ®, sizeof(reg), 691 FOLL_FORCE) 692 != sizeof(reg)) 693 return -EFAULT; 694 if (access_process_vm(target, 695 (unsigned long) 696 ®_window[pos], 697 ®, sizeof(reg), 698 FOLL_FORCE | FOLL_WRITE) 699 != sizeof(reg)) 700 return -EFAULT; 701 pos++; 702 u++; 703 } 704 } 705 } 706 while (count > 0) { 707 unsigned long tstate; 708 709 if (kbuf) 710 reg = *k++; 711 else if (get_user(reg, u++)) 712 return -EFAULT; 713 714 switch (pos) { 715 case 32: /* PSR */ 716 tstate = regs->tstate; 717 tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL); 718 tstate |= psr_to_tstate_icc(reg); 719 if (reg & PSR_SYSCALL) 720 tstate |= TSTATE_SYSCALL; 721 regs->tstate = tstate; 722 break; 723 case 33: /* PC */ 724 regs->tpc = reg; 725 break; 726 case 34: /* NPC */ 727 regs->tnpc = reg; 728 break; 729 case 35: /* Y */ 730 regs->y = reg; 731 break; 732 case 36: /* WIM */ 733 case 37: /* TBR */ 734 break; 735 default: 736 goto finish; 737 } 738 739 pos++; 740 count--; 741 } 742 finish: 743 pos *= sizeof(reg); 744 count *= sizeof(reg); 745 746 return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 747 38 * sizeof(reg), -1); 748 } 749 750 static int fpregs32_get(struct task_struct *target, 751 const struct user_regset *regset, 752 unsigned int pos, unsigned int count, 753 void *kbuf, void __user *ubuf) 754 { 755 const unsigned long *fpregs = task_thread_info(target)->fpregs; 756 compat_ulong_t enabled; 757 unsigned long fprs; 758 compat_ulong_t fsr; 759 int ret = 0; 760 761 if (target == current) 762 save_and_clear_fpu(); 763 764 fprs = task_thread_info(target)->fpsaved[0]; 765 if (fprs & FPRS_FEF) { 766 fsr = task_thread_info(target)->xfsr[0]; 767 enabled = 1; 768 } else { 769 fsr = 0; 770 enabled = 0; 771 } 772 773 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 774 fpregs, 775 0, 32 * sizeof(u32)); 776 777 if (!ret) 778 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 779 32 * sizeof(u32), 780 33 * sizeof(u32)); 781 if (!ret) 782 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 783 &fsr, 784 33 * sizeof(u32), 785 34 * sizeof(u32)); 786 787 if (!ret) { 788 compat_ulong_t val; 789 790 val = (enabled << 8) | (8 << 16); 791 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 792 &val, 793 34 * sizeof(u32), 794 35 * sizeof(u32)); 795 } 796 797 if (!ret) 798 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 799 35 * sizeof(u32), -1); 800 801 return ret; 802 } 803 804 static int fpregs32_set(struct task_struct *target, 805 const struct user_regset *regset, 806 unsigned int pos, unsigned int count, 807 const void *kbuf, const void __user *ubuf) 808 { 809 unsigned long *fpregs = task_thread_info(target)->fpregs; 810 unsigned long fprs; 811 int ret; 812 813 if (target == current) 814 save_and_clear_fpu(); 815 816 fprs = task_thread_info(target)->fpsaved[0]; 817 818 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 819 fpregs, 820 0, 32 * sizeof(u32)); 821 if (!ret) 822 user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 823 32 * sizeof(u32), 824 33 * sizeof(u32)); 825 if (!ret && count > 0) { 826 compat_ulong_t fsr; 827 unsigned long val; 828 829 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 830 &fsr, 831 33 * sizeof(u32), 832 34 * sizeof(u32)); 833 if (!ret) { 834 val = task_thread_info(target)->xfsr[0]; 835 val &= 0xffffffff00000000UL; 836 val |= fsr; 837 task_thread_info(target)->xfsr[0] = val; 838 } 839 } 840 841 fprs |= (FPRS_FEF | FPRS_DL); 842 task_thread_info(target)->fpsaved[0] = fprs; 843 844 if (!ret) 845 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 846 34 * sizeof(u32), -1); 847 return ret; 848 } 849 850 static const struct user_regset sparc32_regsets[] = { 851 /* Format is: 852 * G0 --> G7 853 * O0 --> O7 854 * L0 --> L7 855 * I0 --> I7 856 * PSR, PC, nPC, Y, WIM, TBR 857 */ 858 [REGSET_GENERAL] = { 859 .core_note_type = NT_PRSTATUS, 860 .n = 38, 861 .size = sizeof(u32), .align = sizeof(u32), 862 .get = genregs32_get, .set = genregs32_set 863 }, 864 /* Format is: 865 * F0 --> F31 866 * empty 32-bit word 867 * FSR (32--bit word) 868 * FPU QUEUE COUNT (8-bit char) 869 * FPU QUEUE ENTRYSIZE (8-bit char) 870 * FPU ENABLED (8-bit char) 871 * empty 8-bit char 872 * FPU QUEUE (64 32-bit ints) 873 */ 874 [REGSET_FP] = { 875 .core_note_type = NT_PRFPREG, 876 .n = 99, 877 .size = sizeof(u32), .align = sizeof(u32), 878 .get = fpregs32_get, .set = fpregs32_set 879 }, 880 }; 881 882 static const struct user_regset_view user_sparc32_view = { 883 .name = "sparc", .e_machine = EM_SPARC, 884 .regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets) 885 }; 886 #endif /* CONFIG_COMPAT */ 887 888 const struct user_regset_view *task_user_regset_view(struct task_struct *task) 889 { 890 #ifdef CONFIG_COMPAT 891 if (test_tsk_thread_flag(task, TIF_32BIT)) 892 return &user_sparc32_view; 893 #endif 894 return &user_sparc64_view; 895 } 896 897 #ifdef CONFIG_COMPAT 898 struct compat_fps { 899 unsigned int regs[32]; 900 unsigned int fsr; 901 unsigned int flags; 902 unsigned int extra; 903 unsigned int fpqd; 904 struct compat_fq { 905 unsigned int insnaddr; 906 unsigned int insn; 907 } fpq[16]; 908 }; 909 910 long compat_arch_ptrace(struct task_struct *child, compat_long_t request, 911 compat_ulong_t caddr, compat_ulong_t cdata) 912 { 913 const struct user_regset_view *view = task_user_regset_view(current); 914 compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4]; 915 struct pt_regs32 __user *pregs; 916 struct compat_fps __user *fps; 917 unsigned long addr2 = caddr2; 918 unsigned long addr = caddr; 919 unsigned long data = cdata; 920 int ret; 921 922 pregs = (struct pt_regs32 __user *) addr; 923 fps = (struct compat_fps __user *) addr; 924 925 switch (request) { 926 case PTRACE_PEEKUSR: 927 ret = (addr != 0) ? -EIO : 0; 928 break; 929 930 case PTRACE_GETREGS: 931 ret = copy_regset_to_user(child, view, REGSET_GENERAL, 932 32 * sizeof(u32), 933 4 * sizeof(u32), 934 &pregs->psr); 935 if (!ret) 936 ret = copy_regset_to_user(child, view, REGSET_GENERAL, 937 1 * sizeof(u32), 938 15 * sizeof(u32), 939 &pregs->u_regs[0]); 940 break; 941 942 case PTRACE_SETREGS: 943 ret = copy_regset_from_user(child, view, REGSET_GENERAL, 944 32 * sizeof(u32), 945 4 * sizeof(u32), 946 &pregs->psr); 947 if (!ret) 948 ret = copy_regset_from_user(child, view, REGSET_GENERAL, 949 1 * sizeof(u32), 950 15 * sizeof(u32), 951 &pregs->u_regs[0]); 952 break; 953 954 case PTRACE_GETFPREGS: 955 ret = copy_regset_to_user(child, view, REGSET_FP, 956 0 * sizeof(u32), 957 32 * sizeof(u32), 958 &fps->regs[0]); 959 if (!ret) 960 ret = copy_regset_to_user(child, view, REGSET_FP, 961 33 * sizeof(u32), 962 1 * sizeof(u32), 963 &fps->fsr); 964 if (!ret) { 965 if (__put_user(0, &fps->flags) || 966 __put_user(0, &fps->extra) || 967 __put_user(0, &fps->fpqd) || 968 clear_user(&fps->fpq[0], 32 * sizeof(unsigned int))) 969 ret = -EFAULT; 970 } 971 break; 972 973 case PTRACE_SETFPREGS: 974 ret = copy_regset_from_user(child, view, REGSET_FP, 975 0 * sizeof(u32), 976 32 * sizeof(u32), 977 &fps->regs[0]); 978 if (!ret) 979 ret = copy_regset_from_user(child, view, REGSET_FP, 980 33 * sizeof(u32), 981 1 * sizeof(u32), 982 &fps->fsr); 983 break; 984 985 case PTRACE_READTEXT: 986 case PTRACE_READDATA: 987 ret = ptrace_readdata(child, addr, 988 (char __user *)addr2, data); 989 if (ret == data) 990 ret = 0; 991 else if (ret >= 0) 992 ret = -EIO; 993 break; 994 995 case PTRACE_WRITETEXT: 996 case PTRACE_WRITEDATA: 997 ret = ptrace_writedata(child, (char __user *) addr2, 998 addr, data); 999 if (ret == data) 1000 ret = 0; 1001 else if (ret >= 0) 1002 ret = -EIO; 1003 break; 1004 1005 default: 1006 if (request == PTRACE_SPARC_DETACH) 1007 request = PTRACE_DETACH; 1008 ret = compat_ptrace_request(child, request, addr, data); 1009 break; 1010 } 1011 1012 return ret; 1013 } 1014 #endif /* CONFIG_COMPAT */ 1015 1016 struct fps { 1017 unsigned int regs[64]; 1018 unsigned long fsr; 1019 }; 1020 1021 long arch_ptrace(struct task_struct *child, long request, 1022 unsigned long addr, unsigned long data) 1023 { 1024 const struct user_regset_view *view = task_user_regset_view(current); 1025 unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4]; 1026 struct pt_regs __user *pregs; 1027 struct fps __user *fps; 1028 void __user *addr2p; 1029 int ret; 1030 1031 pregs = (struct pt_regs __user *) addr; 1032 fps = (struct fps __user *) addr; 1033 addr2p = (void __user *) addr2; 1034 1035 switch (request) { 1036 case PTRACE_PEEKUSR: 1037 ret = (addr != 0) ? -EIO : 0; 1038 break; 1039 1040 case PTRACE_GETREGS64: 1041 ret = copy_regset_to_user(child, view, REGSET_GENERAL, 1042 1 * sizeof(u64), 1043 15 * sizeof(u64), 1044 &pregs->u_regs[0]); 1045 if (!ret) { 1046 /* XXX doesn't handle 'y' register correctly XXX */ 1047 ret = copy_regset_to_user(child, view, REGSET_GENERAL, 1048 32 * sizeof(u64), 1049 4 * sizeof(u64), 1050 &pregs->tstate); 1051 } 1052 break; 1053 1054 case PTRACE_SETREGS64: 1055 ret = copy_regset_from_user(child, view, REGSET_GENERAL, 1056 1 * sizeof(u64), 1057 15 * sizeof(u64), 1058 &pregs->u_regs[0]); 1059 if (!ret) { 1060 /* XXX doesn't handle 'y' register correctly XXX */ 1061 ret = copy_regset_from_user(child, view, REGSET_GENERAL, 1062 32 * sizeof(u64), 1063 4 * sizeof(u64), 1064 &pregs->tstate); 1065 } 1066 break; 1067 1068 case PTRACE_GETFPREGS64: 1069 ret = copy_regset_to_user(child, view, REGSET_FP, 1070 0 * sizeof(u64), 1071 33 * sizeof(u64), 1072 fps); 1073 break; 1074 1075 case PTRACE_SETFPREGS64: 1076 ret = copy_regset_from_user(child, view, REGSET_FP, 1077 0 * sizeof(u64), 1078 33 * sizeof(u64), 1079 fps); 1080 break; 1081 1082 case PTRACE_READTEXT: 1083 case PTRACE_READDATA: 1084 ret = ptrace_readdata(child, addr, addr2p, data); 1085 if (ret == data) 1086 ret = 0; 1087 else if (ret >= 0) 1088 ret = -EIO; 1089 break; 1090 1091 case PTRACE_WRITETEXT: 1092 case PTRACE_WRITEDATA: 1093 ret = ptrace_writedata(child, addr2p, addr, data); 1094 if (ret == data) 1095 ret = 0; 1096 else if (ret >= 0) 1097 ret = -EIO; 1098 break; 1099 1100 default: 1101 if (request == PTRACE_SPARC_DETACH) 1102 request = PTRACE_DETACH; 1103 ret = ptrace_request(child, request, addr, data); 1104 break; 1105 } 1106 1107 return ret; 1108 } 1109 1110 asmlinkage int syscall_trace_enter(struct pt_regs *regs) 1111 { 1112 int ret = 0; 1113 1114 /* do the secure computing check first */ 1115 secure_computing_strict(regs->u_regs[UREG_G1]); 1116 1117 if (test_thread_flag(TIF_NOHZ)) 1118 user_exit(); 1119 1120 if (test_thread_flag(TIF_SYSCALL_TRACE)) 1121 ret = tracehook_report_syscall_entry(regs); 1122 1123 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) 1124 trace_sys_enter(regs, regs->u_regs[UREG_G1]); 1125 1126 audit_syscall_entry(regs->u_regs[UREG_G1], regs->u_regs[UREG_I0], 1127 regs->u_regs[UREG_I1], regs->u_regs[UREG_I2], 1128 regs->u_regs[UREG_I3]); 1129 1130 return ret; 1131 } 1132 1133 asmlinkage void syscall_trace_leave(struct pt_regs *regs) 1134 { 1135 if (test_thread_flag(TIF_NOHZ)) 1136 user_exit(); 1137 1138 audit_syscall_exit(regs); 1139 1140 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) 1141 trace_sys_exit(regs, regs->u_regs[UREG_I0]); 1142 1143 if (test_thread_flag(TIF_SYSCALL_TRACE)) 1144 tracehook_report_syscall_exit(regs, 0); 1145 1146 if (test_thread_flag(TIF_NOHZ)) 1147 user_enter(); 1148 } 1149 1150 /** 1151 * regs_query_register_offset() - query register offset from its name 1152 * @name: the name of a register 1153 * 1154 * regs_query_register_offset() returns the offset of a register in struct 1155 * pt_regs from its name. If the name is invalid, this returns -EINVAL; 1156 */ 1157 int regs_query_register_offset(const char *name) 1158 { 1159 const struct pt_regs_offset *roff; 1160 1161 for (roff = regoffset_table; roff->name != NULL; roff++) 1162 if (!strcmp(roff->name, name)) 1163 return roff->offset; 1164 return -EINVAL; 1165 } 1166 1167 /** 1168 * regs_within_kernel_stack() - check the address in the stack 1169 * @regs: pt_regs which contains kernel stack pointer. 1170 * @addr: address which is checked. 1171 * 1172 * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). 1173 * If @addr is within the kernel stack, it returns true. If not, returns false. 1174 */ 1175 static inline int regs_within_kernel_stack(struct pt_regs *regs, 1176 unsigned long addr) 1177 { 1178 unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS; 1179 return ((addr & ~(THREAD_SIZE - 1)) == 1180 (ksp & ~(THREAD_SIZE - 1))); 1181 } 1182 1183 /** 1184 * regs_get_kernel_stack_nth() - get Nth entry of the stack 1185 * @regs: pt_regs which contains kernel stack pointer. 1186 * @n: stack entry number. 1187 * 1188 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which 1189 * is specified by @regs. If the @n th entry is NOT in the kernel stack, 1190 * this returns 0. 1191 */ 1192 unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) 1193 { 1194 unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS; 1195 unsigned long *addr = (unsigned long *)ksp; 1196 addr += n; 1197 if (regs_within_kernel_stack(regs, (unsigned long)addr)) 1198 return *addr; 1199 else 1200 return 0; 1201 } 1202