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