1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1992 Ross Biro 7 * Copyright (C) Linus Torvalds 8 * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle 9 * Copyright (C) 1996 David S. Miller 10 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com 11 * Copyright (C) 1999 MIPS Technologies, Inc. 12 * Copyright (C) 2000 Ulf Carlsson 13 * 14 * At this time Linux/MIPS64 only supports syscall tracing, even for 32-bit 15 * binaries. 16 */ 17 #include <linux/compiler.h> 18 #include <linux/context_tracking.h> 19 #include <linux/elf.h> 20 #include <linux/kernel.h> 21 #include <linux/sched.h> 22 #include <linux/mm.h> 23 #include <linux/errno.h> 24 #include <linux/ptrace.h> 25 #include <linux/regset.h> 26 #include <linux/smp.h> 27 #include <linux/security.h> 28 #include <linux/tracehook.h> 29 #include <linux/audit.h> 30 #include <linux/seccomp.h> 31 #include <linux/ftrace.h> 32 33 #include <asm/byteorder.h> 34 #include <asm/cpu.h> 35 #include <asm/dsp.h> 36 #include <asm/fpu.h> 37 #include <asm/mipsregs.h> 38 #include <asm/mipsmtregs.h> 39 #include <asm/pgtable.h> 40 #include <asm/page.h> 41 #include <asm/syscall.h> 42 #include <asm/uaccess.h> 43 #include <asm/bootinfo.h> 44 #include <asm/reg.h> 45 46 #define CREATE_TRACE_POINTS 47 #include <trace/events/syscalls.h> 48 49 static void init_fp_ctx(struct task_struct *target) 50 { 51 /* If FP has been used then the target already has context */ 52 if (tsk_used_math(target)) 53 return; 54 55 /* Begin with data registers set to all 1s... */ 56 memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr)); 57 58 /* ...and FCSR zeroed */ 59 target->thread.fpu.fcr31 = 0; 60 61 /* 62 * Record that the target has "used" math, such that the context 63 * just initialised, and any modifications made by the caller, 64 * aren't discarded. 65 */ 66 set_stopped_child_used_math(target); 67 } 68 69 /* 70 * Called by kernel/ptrace.c when detaching.. 71 * 72 * Make sure single step bits etc are not set. 73 */ 74 void ptrace_disable(struct task_struct *child) 75 { 76 /* Don't load the watchpoint registers for the ex-child. */ 77 clear_tsk_thread_flag(child, TIF_LOAD_WATCH); 78 } 79 80 /* 81 * Read a general register set. We always use the 64-bit format, even 82 * for 32-bit kernels and for 32-bit processes on a 64-bit kernel. 83 * Registers are sign extended to fill the available space. 84 */ 85 int ptrace_getregs(struct task_struct *child, struct user_pt_regs __user *data) 86 { 87 struct pt_regs *regs; 88 int i; 89 90 if (!access_ok(VERIFY_WRITE, data, 38 * 8)) 91 return -EIO; 92 93 regs = task_pt_regs(child); 94 95 for (i = 0; i < 32; i++) 96 __put_user((long)regs->regs[i], (__s64 __user *)&data->regs[i]); 97 __put_user((long)regs->lo, (__s64 __user *)&data->lo); 98 __put_user((long)regs->hi, (__s64 __user *)&data->hi); 99 __put_user((long)regs->cp0_epc, (__s64 __user *)&data->cp0_epc); 100 __put_user((long)regs->cp0_badvaddr, (__s64 __user *)&data->cp0_badvaddr); 101 __put_user((long)regs->cp0_status, (__s64 __user *)&data->cp0_status); 102 __put_user((long)regs->cp0_cause, (__s64 __user *)&data->cp0_cause); 103 104 return 0; 105 } 106 107 /* 108 * Write a general register set. As for PTRACE_GETREGS, we always use 109 * the 64-bit format. On a 32-bit kernel only the lower order half 110 * (according to endianness) will be used. 111 */ 112 int ptrace_setregs(struct task_struct *child, struct user_pt_regs __user *data) 113 { 114 struct pt_regs *regs; 115 int i; 116 117 if (!access_ok(VERIFY_READ, data, 38 * 8)) 118 return -EIO; 119 120 regs = task_pt_regs(child); 121 122 for (i = 0; i < 32; i++) 123 __get_user(regs->regs[i], (__s64 __user *)&data->regs[i]); 124 __get_user(regs->lo, (__s64 __user *)&data->lo); 125 __get_user(regs->hi, (__s64 __user *)&data->hi); 126 __get_user(regs->cp0_epc, (__s64 __user *)&data->cp0_epc); 127 128 /* badvaddr, status, and cause may not be written. */ 129 130 return 0; 131 } 132 133 int ptrace_getfpregs(struct task_struct *child, __u32 __user *data) 134 { 135 int i; 136 137 if (!access_ok(VERIFY_WRITE, data, 33 * 8)) 138 return -EIO; 139 140 if (tsk_used_math(child)) { 141 union fpureg *fregs = get_fpu_regs(child); 142 for (i = 0; i < 32; i++) 143 __put_user(get_fpr64(&fregs[i], 0), 144 i + (__u64 __user *)data); 145 } else { 146 for (i = 0; i < 32; i++) 147 __put_user((__u64) -1, i + (__u64 __user *) data); 148 } 149 150 __put_user(child->thread.fpu.fcr31, data + 64); 151 __put_user(boot_cpu_data.fpu_id, data + 65); 152 153 return 0; 154 } 155 156 int ptrace_setfpregs(struct task_struct *child, __u32 __user *data) 157 { 158 union fpureg *fregs; 159 u64 fpr_val; 160 int i; 161 162 if (!access_ok(VERIFY_READ, data, 33 * 8)) 163 return -EIO; 164 165 init_fp_ctx(child); 166 fregs = get_fpu_regs(child); 167 168 for (i = 0; i < 32; i++) { 169 __get_user(fpr_val, i + (__u64 __user *)data); 170 set_fpr64(&fregs[i], 0, fpr_val); 171 } 172 173 __get_user(child->thread.fpu.fcr31, data + 64); 174 child->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X; 175 176 /* FIR may not be written. */ 177 178 return 0; 179 } 180 181 int ptrace_get_watch_regs(struct task_struct *child, 182 struct pt_watch_regs __user *addr) 183 { 184 enum pt_watch_style style; 185 int i; 186 187 if (!cpu_has_watch || boot_cpu_data.watch_reg_use_cnt == 0) 188 return -EIO; 189 if (!access_ok(VERIFY_WRITE, addr, sizeof(struct pt_watch_regs))) 190 return -EIO; 191 192 #ifdef CONFIG_32BIT 193 style = pt_watch_style_mips32; 194 #define WATCH_STYLE mips32 195 #else 196 style = pt_watch_style_mips64; 197 #define WATCH_STYLE mips64 198 #endif 199 200 __put_user(style, &addr->style); 201 __put_user(boot_cpu_data.watch_reg_use_cnt, 202 &addr->WATCH_STYLE.num_valid); 203 for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) { 204 __put_user(child->thread.watch.mips3264.watchlo[i], 205 &addr->WATCH_STYLE.watchlo[i]); 206 __put_user(child->thread.watch.mips3264.watchhi[i] & 0xfff, 207 &addr->WATCH_STYLE.watchhi[i]); 208 __put_user(boot_cpu_data.watch_reg_masks[i], 209 &addr->WATCH_STYLE.watch_masks[i]); 210 } 211 for (; i < 8; i++) { 212 __put_user(0, &addr->WATCH_STYLE.watchlo[i]); 213 __put_user(0, &addr->WATCH_STYLE.watchhi[i]); 214 __put_user(0, &addr->WATCH_STYLE.watch_masks[i]); 215 } 216 217 return 0; 218 } 219 220 int ptrace_set_watch_regs(struct task_struct *child, 221 struct pt_watch_regs __user *addr) 222 { 223 int i; 224 int watch_active = 0; 225 unsigned long lt[NUM_WATCH_REGS]; 226 u16 ht[NUM_WATCH_REGS]; 227 228 if (!cpu_has_watch || boot_cpu_data.watch_reg_use_cnt == 0) 229 return -EIO; 230 if (!access_ok(VERIFY_READ, addr, sizeof(struct pt_watch_regs))) 231 return -EIO; 232 /* Check the values. */ 233 for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) { 234 __get_user(lt[i], &addr->WATCH_STYLE.watchlo[i]); 235 #ifdef CONFIG_32BIT 236 if (lt[i] & __UA_LIMIT) 237 return -EINVAL; 238 #else 239 if (test_tsk_thread_flag(child, TIF_32BIT_ADDR)) { 240 if (lt[i] & 0xffffffff80000000UL) 241 return -EINVAL; 242 } else { 243 if (lt[i] & __UA_LIMIT) 244 return -EINVAL; 245 } 246 #endif 247 __get_user(ht[i], &addr->WATCH_STYLE.watchhi[i]); 248 if (ht[i] & ~0xff8) 249 return -EINVAL; 250 } 251 /* Install them. */ 252 for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) { 253 if (lt[i] & 7) 254 watch_active = 1; 255 child->thread.watch.mips3264.watchlo[i] = lt[i]; 256 /* Set the G bit. */ 257 child->thread.watch.mips3264.watchhi[i] = ht[i]; 258 } 259 260 if (watch_active) 261 set_tsk_thread_flag(child, TIF_LOAD_WATCH); 262 else 263 clear_tsk_thread_flag(child, TIF_LOAD_WATCH); 264 265 return 0; 266 } 267 268 /* regset get/set implementations */ 269 270 #if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32) 271 272 static int gpr32_get(struct task_struct *target, 273 const struct user_regset *regset, 274 unsigned int pos, unsigned int count, 275 void *kbuf, void __user *ubuf) 276 { 277 struct pt_regs *regs = task_pt_regs(target); 278 u32 uregs[ELF_NGREG] = {}; 279 unsigned i; 280 281 for (i = MIPS32_EF_R1; i <= MIPS32_EF_R31; i++) { 282 /* k0/k1 are copied as zero. */ 283 if (i == MIPS32_EF_R26 || i == MIPS32_EF_R27) 284 continue; 285 286 uregs[i] = regs->regs[i - MIPS32_EF_R0]; 287 } 288 289 uregs[MIPS32_EF_LO] = regs->lo; 290 uregs[MIPS32_EF_HI] = regs->hi; 291 uregs[MIPS32_EF_CP0_EPC] = regs->cp0_epc; 292 uregs[MIPS32_EF_CP0_BADVADDR] = regs->cp0_badvaddr; 293 uregs[MIPS32_EF_CP0_STATUS] = regs->cp0_status; 294 uregs[MIPS32_EF_CP0_CAUSE] = regs->cp0_cause; 295 296 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, 297 sizeof(uregs)); 298 } 299 300 static int gpr32_set(struct task_struct *target, 301 const struct user_regset *regset, 302 unsigned int pos, unsigned int count, 303 const void *kbuf, const void __user *ubuf) 304 { 305 struct pt_regs *regs = task_pt_regs(target); 306 u32 uregs[ELF_NGREG]; 307 unsigned start, num_regs, i; 308 int err; 309 310 start = pos / sizeof(u32); 311 num_regs = count / sizeof(u32); 312 313 if (start + num_regs > ELF_NGREG) 314 return -EIO; 315 316 err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0, 317 sizeof(uregs)); 318 if (err) 319 return err; 320 321 for (i = start; i < num_regs; i++) { 322 /* 323 * Cast all values to signed here so that if this is a 64-bit 324 * kernel, the supplied 32-bit values will be sign extended. 325 */ 326 switch (i) { 327 case MIPS32_EF_R1 ... MIPS32_EF_R25: 328 /* k0/k1 are ignored. */ 329 case MIPS32_EF_R28 ... MIPS32_EF_R31: 330 regs->regs[i - MIPS32_EF_R0] = (s32)uregs[i]; 331 break; 332 case MIPS32_EF_LO: 333 regs->lo = (s32)uregs[i]; 334 break; 335 case MIPS32_EF_HI: 336 regs->hi = (s32)uregs[i]; 337 break; 338 case MIPS32_EF_CP0_EPC: 339 regs->cp0_epc = (s32)uregs[i]; 340 break; 341 } 342 } 343 344 return 0; 345 } 346 347 #endif /* CONFIG_32BIT || CONFIG_MIPS32_O32 */ 348 349 #ifdef CONFIG_64BIT 350 351 static int gpr64_get(struct task_struct *target, 352 const struct user_regset *regset, 353 unsigned int pos, unsigned int count, 354 void *kbuf, void __user *ubuf) 355 { 356 struct pt_regs *regs = task_pt_regs(target); 357 u64 uregs[ELF_NGREG] = {}; 358 unsigned i; 359 360 for (i = MIPS64_EF_R1; i <= MIPS64_EF_R31; i++) { 361 /* k0/k1 are copied as zero. */ 362 if (i == MIPS64_EF_R26 || i == MIPS64_EF_R27) 363 continue; 364 365 uregs[i] = regs->regs[i - MIPS64_EF_R0]; 366 } 367 368 uregs[MIPS64_EF_LO] = regs->lo; 369 uregs[MIPS64_EF_HI] = regs->hi; 370 uregs[MIPS64_EF_CP0_EPC] = regs->cp0_epc; 371 uregs[MIPS64_EF_CP0_BADVADDR] = regs->cp0_badvaddr; 372 uregs[MIPS64_EF_CP0_STATUS] = regs->cp0_status; 373 uregs[MIPS64_EF_CP0_CAUSE] = regs->cp0_cause; 374 375 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, 376 sizeof(uregs)); 377 } 378 379 static int gpr64_set(struct task_struct *target, 380 const struct user_regset *regset, 381 unsigned int pos, unsigned int count, 382 const void *kbuf, const void __user *ubuf) 383 { 384 struct pt_regs *regs = task_pt_regs(target); 385 u64 uregs[ELF_NGREG]; 386 unsigned start, num_regs, i; 387 int err; 388 389 start = pos / sizeof(u64); 390 num_regs = count / sizeof(u64); 391 392 if (start + num_regs > ELF_NGREG) 393 return -EIO; 394 395 err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0, 396 sizeof(uregs)); 397 if (err) 398 return err; 399 400 for (i = start; i < num_regs; i++) { 401 switch (i) { 402 case MIPS64_EF_R1 ... MIPS64_EF_R25: 403 /* k0/k1 are ignored. */ 404 case MIPS64_EF_R28 ... MIPS64_EF_R31: 405 regs->regs[i - MIPS64_EF_R0] = uregs[i]; 406 break; 407 case MIPS64_EF_LO: 408 regs->lo = uregs[i]; 409 break; 410 case MIPS64_EF_HI: 411 regs->hi = uregs[i]; 412 break; 413 case MIPS64_EF_CP0_EPC: 414 regs->cp0_epc = uregs[i]; 415 break; 416 } 417 } 418 419 return 0; 420 } 421 422 #endif /* CONFIG_64BIT */ 423 424 static int fpr_get(struct task_struct *target, 425 const struct user_regset *regset, 426 unsigned int pos, unsigned int count, 427 void *kbuf, void __user *ubuf) 428 { 429 unsigned i; 430 int err; 431 u64 fpr_val; 432 433 /* XXX fcr31 */ 434 435 if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t)) 436 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, 437 &target->thread.fpu, 438 0, sizeof(elf_fpregset_t)); 439 440 for (i = 0; i < NUM_FPU_REGS; i++) { 441 fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0); 442 err = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 443 &fpr_val, i * sizeof(elf_fpreg_t), 444 (i + 1) * sizeof(elf_fpreg_t)); 445 if (err) 446 return err; 447 } 448 449 return 0; 450 } 451 452 static int fpr_set(struct task_struct *target, 453 const struct user_regset *regset, 454 unsigned int pos, unsigned int count, 455 const void *kbuf, const void __user *ubuf) 456 { 457 unsigned i; 458 int err; 459 u64 fpr_val; 460 461 /* XXX fcr31 */ 462 463 init_fp_ctx(target); 464 465 if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t)) 466 return user_regset_copyin(&pos, &count, &kbuf, &ubuf, 467 &target->thread.fpu, 468 0, sizeof(elf_fpregset_t)); 469 470 for (i = 0; i < NUM_FPU_REGS; i++) { 471 err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 472 &fpr_val, i * sizeof(elf_fpreg_t), 473 (i + 1) * sizeof(elf_fpreg_t)); 474 if (err) 475 return err; 476 set_fpr64(&target->thread.fpu.fpr[i], 0, fpr_val); 477 } 478 479 return 0; 480 } 481 482 enum mips_regset { 483 REGSET_GPR, 484 REGSET_FPR, 485 }; 486 487 #if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32) 488 489 static const struct user_regset mips_regsets[] = { 490 [REGSET_GPR] = { 491 .core_note_type = NT_PRSTATUS, 492 .n = ELF_NGREG, 493 .size = sizeof(unsigned int), 494 .align = sizeof(unsigned int), 495 .get = gpr32_get, 496 .set = gpr32_set, 497 }, 498 [REGSET_FPR] = { 499 .core_note_type = NT_PRFPREG, 500 .n = ELF_NFPREG, 501 .size = sizeof(elf_fpreg_t), 502 .align = sizeof(elf_fpreg_t), 503 .get = fpr_get, 504 .set = fpr_set, 505 }, 506 }; 507 508 static const struct user_regset_view user_mips_view = { 509 .name = "mips", 510 .e_machine = ELF_ARCH, 511 .ei_osabi = ELF_OSABI, 512 .regsets = mips_regsets, 513 .n = ARRAY_SIZE(mips_regsets), 514 }; 515 516 #endif /* CONFIG_32BIT || CONFIG_MIPS32_O32 */ 517 518 #ifdef CONFIG_64BIT 519 520 static const struct user_regset mips64_regsets[] = { 521 [REGSET_GPR] = { 522 .core_note_type = NT_PRSTATUS, 523 .n = ELF_NGREG, 524 .size = sizeof(unsigned long), 525 .align = sizeof(unsigned long), 526 .get = gpr64_get, 527 .set = gpr64_set, 528 }, 529 [REGSET_FPR] = { 530 .core_note_type = NT_PRFPREG, 531 .n = ELF_NFPREG, 532 .size = sizeof(elf_fpreg_t), 533 .align = sizeof(elf_fpreg_t), 534 .get = fpr_get, 535 .set = fpr_set, 536 }, 537 }; 538 539 static const struct user_regset_view user_mips64_view = { 540 .name = "mips64", 541 .e_machine = ELF_ARCH, 542 .ei_osabi = ELF_OSABI, 543 .regsets = mips64_regsets, 544 .n = ARRAY_SIZE(mips64_regsets), 545 }; 546 547 #endif /* CONFIG_64BIT */ 548 549 const struct user_regset_view *task_user_regset_view(struct task_struct *task) 550 { 551 #ifdef CONFIG_32BIT 552 return &user_mips_view; 553 #else 554 #ifdef CONFIG_MIPS32_O32 555 if (test_tsk_thread_flag(task, TIF_32BIT_REGS)) 556 return &user_mips_view; 557 #endif 558 return &user_mips64_view; 559 #endif 560 } 561 562 long arch_ptrace(struct task_struct *child, long request, 563 unsigned long addr, unsigned long data) 564 { 565 int ret; 566 void __user *addrp = (void __user *) addr; 567 void __user *datavp = (void __user *) data; 568 unsigned long __user *datalp = (void __user *) data; 569 570 switch (request) { 571 /* when I and D space are separate, these will need to be fixed. */ 572 case PTRACE_PEEKTEXT: /* read word at location addr. */ 573 case PTRACE_PEEKDATA: 574 ret = generic_ptrace_peekdata(child, addr, data); 575 break; 576 577 /* Read the word at location addr in the USER area. */ 578 case PTRACE_PEEKUSR: { 579 struct pt_regs *regs; 580 union fpureg *fregs; 581 unsigned long tmp = 0; 582 583 regs = task_pt_regs(child); 584 ret = 0; /* Default return value. */ 585 586 switch (addr) { 587 case 0 ... 31: 588 tmp = regs->regs[addr]; 589 break; 590 case FPR_BASE ... FPR_BASE + 31: 591 if (!tsk_used_math(child)) { 592 /* FP not yet used */ 593 tmp = -1; 594 break; 595 } 596 fregs = get_fpu_regs(child); 597 598 #ifdef CONFIG_32BIT 599 if (test_thread_flag(TIF_32BIT_FPREGS)) { 600 /* 601 * The odd registers are actually the high 602 * order bits of the values stored in the even 603 * registers - unless we're using r2k_switch.S. 604 */ 605 tmp = get_fpr32(&fregs[(addr & ~1) - FPR_BASE], 606 addr & 1); 607 break; 608 } 609 #endif 610 tmp = get_fpr32(&fregs[addr - FPR_BASE], 0); 611 break; 612 case PC: 613 tmp = regs->cp0_epc; 614 break; 615 case CAUSE: 616 tmp = regs->cp0_cause; 617 break; 618 case BADVADDR: 619 tmp = regs->cp0_badvaddr; 620 break; 621 case MMHI: 622 tmp = regs->hi; 623 break; 624 case MMLO: 625 tmp = regs->lo; 626 break; 627 #ifdef CONFIG_CPU_HAS_SMARTMIPS 628 case ACX: 629 tmp = regs->acx; 630 break; 631 #endif 632 case FPC_CSR: 633 tmp = child->thread.fpu.fcr31; 634 break; 635 case FPC_EIR: 636 /* implementation / version register */ 637 tmp = boot_cpu_data.fpu_id; 638 break; 639 case DSP_BASE ... DSP_BASE + 5: { 640 dspreg_t *dregs; 641 642 if (!cpu_has_dsp) { 643 tmp = 0; 644 ret = -EIO; 645 goto out; 646 } 647 dregs = __get_dsp_regs(child); 648 tmp = (unsigned long) (dregs[addr - DSP_BASE]); 649 break; 650 } 651 case DSP_CONTROL: 652 if (!cpu_has_dsp) { 653 tmp = 0; 654 ret = -EIO; 655 goto out; 656 } 657 tmp = child->thread.dsp.dspcontrol; 658 break; 659 default: 660 tmp = 0; 661 ret = -EIO; 662 goto out; 663 } 664 ret = put_user(tmp, datalp); 665 break; 666 } 667 668 /* when I and D space are separate, this will have to be fixed. */ 669 case PTRACE_POKETEXT: /* write the word at location addr. */ 670 case PTRACE_POKEDATA: 671 ret = generic_ptrace_pokedata(child, addr, data); 672 break; 673 674 case PTRACE_POKEUSR: { 675 struct pt_regs *regs; 676 ret = 0; 677 regs = task_pt_regs(child); 678 679 switch (addr) { 680 case 0 ... 31: 681 regs->regs[addr] = data; 682 break; 683 case FPR_BASE ... FPR_BASE + 31: { 684 union fpureg *fregs = get_fpu_regs(child); 685 686 init_fp_ctx(child); 687 #ifdef CONFIG_32BIT 688 if (test_thread_flag(TIF_32BIT_FPREGS)) { 689 /* 690 * The odd registers are actually the high 691 * order bits of the values stored in the even 692 * registers - unless we're using r2k_switch.S. 693 */ 694 set_fpr32(&fregs[(addr & ~1) - FPR_BASE], 695 addr & 1, data); 696 break; 697 } 698 #endif 699 set_fpr64(&fregs[addr - FPR_BASE], 0, data); 700 break; 701 } 702 case PC: 703 regs->cp0_epc = data; 704 break; 705 case MMHI: 706 regs->hi = data; 707 break; 708 case MMLO: 709 regs->lo = data; 710 break; 711 #ifdef CONFIG_CPU_HAS_SMARTMIPS 712 case ACX: 713 regs->acx = data; 714 break; 715 #endif 716 case FPC_CSR: 717 child->thread.fpu.fcr31 = data & ~FPU_CSR_ALL_X; 718 break; 719 case DSP_BASE ... DSP_BASE + 5: { 720 dspreg_t *dregs; 721 722 if (!cpu_has_dsp) { 723 ret = -EIO; 724 break; 725 } 726 727 dregs = __get_dsp_regs(child); 728 dregs[addr - DSP_BASE] = data; 729 break; 730 } 731 case DSP_CONTROL: 732 if (!cpu_has_dsp) { 733 ret = -EIO; 734 break; 735 } 736 child->thread.dsp.dspcontrol = data; 737 break; 738 default: 739 /* The rest are not allowed. */ 740 ret = -EIO; 741 break; 742 } 743 break; 744 } 745 746 case PTRACE_GETREGS: 747 ret = ptrace_getregs(child, datavp); 748 break; 749 750 case PTRACE_SETREGS: 751 ret = ptrace_setregs(child, datavp); 752 break; 753 754 case PTRACE_GETFPREGS: 755 ret = ptrace_getfpregs(child, datavp); 756 break; 757 758 case PTRACE_SETFPREGS: 759 ret = ptrace_setfpregs(child, datavp); 760 break; 761 762 case PTRACE_GET_THREAD_AREA: 763 ret = put_user(task_thread_info(child)->tp_value, datalp); 764 break; 765 766 case PTRACE_GET_WATCH_REGS: 767 ret = ptrace_get_watch_regs(child, addrp); 768 break; 769 770 case PTRACE_SET_WATCH_REGS: 771 ret = ptrace_set_watch_regs(child, addrp); 772 break; 773 774 default: 775 ret = ptrace_request(child, request, addr, data); 776 break; 777 } 778 out: 779 return ret; 780 } 781 782 /* 783 * Notification of system call entry/exit 784 * - triggered by current->work.syscall_trace 785 */ 786 asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall) 787 { 788 long ret = 0; 789 user_exit(); 790 791 current_thread_info()->syscall = syscall; 792 793 if (secure_computing() == -1) 794 return -1; 795 796 if (test_thread_flag(TIF_SYSCALL_TRACE) && 797 tracehook_report_syscall_entry(regs)) 798 ret = -1; 799 800 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) 801 trace_sys_enter(regs, regs->regs[2]); 802 803 audit_syscall_entry(syscall, regs->regs[4], regs->regs[5], 804 regs->regs[6], regs->regs[7]); 805 return syscall; 806 } 807 808 /* 809 * Notification of system call entry/exit 810 * - triggered by current->work.syscall_trace 811 */ 812 asmlinkage void syscall_trace_leave(struct pt_regs *regs) 813 { 814 /* 815 * We may come here right after calling schedule_user() 816 * or do_notify_resume(), in which case we can be in RCU 817 * user mode. 818 */ 819 user_exit(); 820 821 audit_syscall_exit(regs); 822 823 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) 824 trace_sys_exit(regs, regs->regs[2]); 825 826 if (test_thread_flag(TIF_SYSCALL_TRACE)) 827 tracehook_report_syscall_exit(regs, 0); 828 829 user_enter(); 830 } 831