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