1 // SPDX-License-Identifier: GPL-2.0 !! 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/sched/task_stack.h> >> 23 #include <linux/mm.h> >> 24 #include <linux/errno.h> 2 #include <linux/ptrace.h> 25 #include <linux/ptrace.h> >> 26 #include <linux/regset.h> >> 27 #include <linux/smp.h> >> 28 #include <linux/security.h> >> 29 #include <linux/stddef.h> >> 30 #include <linux/audit.h> >> 31 #include <linux/seccomp.h> >> 32 #include <linux/ftrace.h> >> 33 >> 34 #include <asm/branch.h> >> 35 #include <asm/byteorder.h> >> 36 #include <asm/cpu.h> >> 37 #include <asm/cpu-info.h> >> 38 #include <asm/dsp.h> >> 39 #include <asm/fpu.h> >> 40 #include <asm/mipsregs.h> >> 41 #include <asm/mipsmtregs.h> >> 42 #include <asm/page.h> >> 43 #include <asm/processor.h> >> 44 #include <asm/syscall.h> >> 45 #include <linux/uaccess.h> >> 46 #include <asm/bootinfo.h> >> 47 #include <asm/reg.h> >> 48 >> 49 #define CREATE_TRACE_POINTS >> 50 #include <trace/events/syscalls.h> >> 51 >> 52 unsigned long exception_ip(struct pt_regs *regs) >> 53 { >> 54 return exception_epc(regs); >> 55 } >> 56 EXPORT_SYMBOL(exception_ip); >> 57 >> 58 /* >> 59 * Called by kernel/ptrace.c when detaching.. >> 60 * >> 61 * Make sure single step bits etc are not set. >> 62 */ >> 63 void ptrace_disable(struct task_struct *child) >> 64 { >> 65 /* Don't load the watchpoint registers for the ex-child. */ >> 66 clear_tsk_thread_flag(child, TIF_LOAD_WATCH); >> 67 } >> 68 >> 69 /* >> 70 * Read a general register set. We always use the 64-bit format, even >> 71 * for 32-bit kernels and for 32-bit processes on a 64-bit kernel. >> 72 * Registers are sign extended to fill the available space. >> 73 */ >> 74 int ptrace_getregs(struct task_struct *child, struct user_pt_regs __user *data) >> 75 { >> 76 struct pt_regs *regs; >> 77 int i; >> 78 >> 79 if (!access_ok(data, 38 * 8)) >> 80 return -EIO; >> 81 >> 82 regs = task_pt_regs(child); >> 83 >> 84 for (i = 0; i < 32; i++) >> 85 __put_user((long)regs->regs[i], (__s64 __user *)&data->regs[i]); >> 86 __put_user((long)regs->lo, (__s64 __user *)&data->lo); >> 87 __put_user((long)regs->hi, (__s64 __user *)&data->hi); >> 88 __put_user((long)regs->cp0_epc, (__s64 __user *)&data->cp0_epc); >> 89 __put_user((long)regs->cp0_badvaddr, (__s64 __user *)&data->cp0_badvaddr); >> 90 __put_user((long)regs->cp0_status, (__s64 __user *)&data->cp0_status); >> 91 __put_user((long)regs->cp0_cause, (__s64 __user *)&data->cp0_cause); >> 92 >> 93 return 0; >> 94 } >> 95 >> 96 /* >> 97 * Write a general register set. As for PTRACE_GETREGS, we always use >> 98 * the 64-bit format. On a 32-bit kernel only the lower order half >> 99 * (according to endianness) will be used. >> 100 */ >> 101 int ptrace_setregs(struct task_struct *child, struct user_pt_regs __user *data) >> 102 { >> 103 struct pt_regs *regs; >> 104 int i; >> 105 >> 106 if (!access_ok(data, 38 * 8)) >> 107 return -EIO; >> 108 >> 109 regs = task_pt_regs(child); >> 110 >> 111 for (i = 0; i < 32; i++) >> 112 __get_user(regs->regs[i], (__s64 __user *)&data->regs[i]); >> 113 __get_user(regs->lo, (__s64 __user *)&data->lo); >> 114 __get_user(regs->hi, (__s64 __user *)&data->hi); >> 115 __get_user(regs->cp0_epc, (__s64 __user *)&data->cp0_epc); >> 116 >> 117 /* badvaddr, status, and cause may not be written. */ >> 118 >> 119 /* System call number may have been changed */ >> 120 mips_syscall_update_nr(child, regs); >> 121 >> 122 return 0; >> 123 } >> 124 >> 125 int ptrace_get_watch_regs(struct task_struct *child, >> 126 struct pt_watch_regs __user *addr) >> 127 { >> 128 enum pt_watch_style style; >> 129 int i; >> 130 >> 131 if (!cpu_has_watch || boot_cpu_data.watch_reg_use_cnt == 0) >> 132 return -EIO; >> 133 if (!access_ok(addr, sizeof(struct pt_watch_regs))) >> 134 return -EIO; >> 135 >> 136 #ifdef CONFIG_32BIT >> 137 style = pt_watch_style_mips32; >> 138 #define WATCH_STYLE mips32 >> 139 #else >> 140 style = pt_watch_style_mips64; >> 141 #define WATCH_STYLE mips64 >> 142 #endif >> 143 >> 144 __put_user(style, &addr->style); >> 145 __put_user(boot_cpu_data.watch_reg_use_cnt, >> 146 &addr->WATCH_STYLE.num_valid); >> 147 for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) { >> 148 __put_user(child->thread.watch.mips3264.watchlo[i], >> 149 &addr->WATCH_STYLE.watchlo[i]); >> 150 __put_user(child->thread.watch.mips3264.watchhi[i] & >> 151 (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW), >> 152 &addr->WATCH_STYLE.watchhi[i]); >> 153 __put_user(boot_cpu_data.watch_reg_masks[i], >> 154 &addr->WATCH_STYLE.watch_masks[i]); >> 155 } >> 156 for (; i < 8; i++) { >> 157 __put_user(0, &addr->WATCH_STYLE.watchlo[i]); >> 158 __put_user(0, &addr->WATCH_STYLE.watchhi[i]); >> 159 __put_user(0, &addr->WATCH_STYLE.watch_masks[i]); >> 160 } >> 161 >> 162 return 0; >> 163 } >> 164 >> 165 int ptrace_set_watch_regs(struct task_struct *child, >> 166 struct pt_watch_regs __user *addr) >> 167 { >> 168 int i; >> 169 int watch_active = 0; >> 170 unsigned long lt[NUM_WATCH_REGS]; >> 171 u16 ht[NUM_WATCH_REGS]; >> 172 >> 173 if (!cpu_has_watch || boot_cpu_data.watch_reg_use_cnt == 0) >> 174 return -EIO; >> 175 if (!access_ok(addr, sizeof(struct pt_watch_regs))) >> 176 return -EIO; >> 177 /* Check the values. */ >> 178 for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) { >> 179 __get_user(lt[i], &addr->WATCH_STYLE.watchlo[i]); >> 180 #ifdef CONFIG_32BIT >> 181 if (lt[i] & __UA_LIMIT) >> 182 return -EINVAL; >> 183 #else >> 184 if (test_tsk_thread_flag(child, TIF_32BIT_ADDR)) { >> 185 if (lt[i] & 0xffffffff80000000UL) >> 186 return -EINVAL; >> 187 } else { >> 188 if (lt[i] & __UA_LIMIT) >> 189 return -EINVAL; >> 190 } >> 191 #endif >> 192 __get_user(ht[i], &addr->WATCH_STYLE.watchhi[i]); >> 193 if (ht[i] & ~MIPS_WATCHHI_MASK) >> 194 return -EINVAL; >> 195 } >> 196 /* Install them. */ >> 197 for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) { >> 198 if (lt[i] & MIPS_WATCHLO_IRW) >> 199 watch_active = 1; >> 200 child->thread.watch.mips3264.watchlo[i] = lt[i]; >> 201 /* Set the G bit. */ >> 202 child->thread.watch.mips3264.watchhi[i] = ht[i]; >> 203 } >> 204 >> 205 if (watch_active) >> 206 set_tsk_thread_flag(child, TIF_LOAD_WATCH); >> 207 else >> 208 clear_tsk_thread_flag(child, TIF_LOAD_WATCH); >> 209 >> 210 return 0; >> 211 } >> 212 >> 213 /* regset get/set implementations */ >> 214 >> 215 #if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32) >> 216 >> 217 static int gpr32_get(struct task_struct *target, >> 218 const struct user_regset *regset, >> 219 struct membuf to) >> 220 { >> 221 struct pt_regs *regs = task_pt_regs(target); >> 222 u32 uregs[ELF_NGREG] = {}; >> 223 >> 224 mips_dump_regs32(uregs, regs); >> 225 return membuf_write(&to, uregs, sizeof(uregs)); >> 226 } >> 227 >> 228 static int gpr32_set(struct task_struct *target, >> 229 const struct user_regset *regset, >> 230 unsigned int pos, unsigned int count, >> 231 const void *kbuf, const void __user *ubuf) >> 232 { >> 233 struct pt_regs *regs = task_pt_regs(target); >> 234 u32 uregs[ELF_NGREG]; >> 235 unsigned start, num_regs, i; >> 236 int err; >> 237 >> 238 start = pos / sizeof(u32); >> 239 num_regs = count / sizeof(u32); >> 240 >> 241 if (start + num_regs > ELF_NGREG) >> 242 return -EIO; >> 243 >> 244 err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0, >> 245 sizeof(uregs)); >> 246 if (err) >> 247 return err; >> 248 >> 249 for (i = start; i < num_regs; i++) { >> 250 /* >> 251 * Cast all values to signed here so that if this is a 64-bit >> 252 * kernel, the supplied 32-bit values will be sign extended. >> 253 */ >> 254 switch (i) { >> 255 case MIPS32_EF_R1 ... MIPS32_EF_R25: >> 256 /* k0/k1 are ignored. */ >> 257 case MIPS32_EF_R28 ... MIPS32_EF_R31: >> 258 regs->regs[i - MIPS32_EF_R0] = (s32)uregs[i]; >> 259 break; >> 260 case MIPS32_EF_LO: >> 261 regs->lo = (s32)uregs[i]; >> 262 break; >> 263 case MIPS32_EF_HI: >> 264 regs->hi = (s32)uregs[i]; >> 265 break; >> 266 case MIPS32_EF_CP0_EPC: >> 267 regs->cp0_epc = (s32)uregs[i]; >> 268 break; >> 269 } >> 270 } >> 271 >> 272 /* System call number may have been changed */ >> 273 mips_syscall_update_nr(target, regs); >> 274 >> 275 return 0; >> 276 } >> 277 >> 278 #endif /* CONFIG_32BIT || CONFIG_MIPS32_O32 */ >> 279 >> 280 #ifdef CONFIG_64BIT >> 281 >> 282 static int gpr64_get(struct task_struct *target, >> 283 const struct user_regset *regset, >> 284 struct membuf to) >> 285 { >> 286 struct pt_regs *regs = task_pt_regs(target); >> 287 u64 uregs[ELF_NGREG] = {}; >> 288 >> 289 mips_dump_regs64(uregs, regs); >> 290 return membuf_write(&to, uregs, sizeof(uregs)); >> 291 } >> 292 >> 293 static int gpr64_set(struct task_struct *target, >> 294 const struct user_regset *regset, >> 295 unsigned int pos, unsigned int count, >> 296 const void *kbuf, const void __user *ubuf) >> 297 { >> 298 struct pt_regs *regs = task_pt_regs(target); >> 299 u64 uregs[ELF_NGREG]; >> 300 unsigned start, num_regs, i; >> 301 int err; >> 302 >> 303 start = pos / sizeof(u64); >> 304 num_regs = count / sizeof(u64); >> 305 >> 306 if (start + num_regs > ELF_NGREG) >> 307 return -EIO; >> 308 >> 309 err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0, >> 310 sizeof(uregs)); >> 311 if (err) >> 312 return err; >> 313 >> 314 for (i = start; i < num_regs; i++) { >> 315 switch (i) { >> 316 case MIPS64_EF_R1 ... MIPS64_EF_R25: >> 317 /* k0/k1 are ignored. */ >> 318 case MIPS64_EF_R28 ... MIPS64_EF_R31: >> 319 regs->regs[i - MIPS64_EF_R0] = uregs[i]; >> 320 break; >> 321 case MIPS64_EF_LO: >> 322 regs->lo = uregs[i]; >> 323 break; >> 324 case MIPS64_EF_HI: >> 325 regs->hi = uregs[i]; >> 326 break; >> 327 case MIPS64_EF_CP0_EPC: >> 328 regs->cp0_epc = uregs[i]; >> 329 break; >> 330 } >> 331 } >> 332 >> 333 /* System call number may have been changed */ >> 334 mips_syscall_update_nr(target, regs); >> 335 >> 336 return 0; >> 337 } >> 338 >> 339 #endif /* CONFIG_64BIT */ >> 340 >> 341 >> 342 #ifdef CONFIG_MIPS_FP_SUPPORT >> 343 >> 344 /* >> 345 * Poke at FCSR according to its mask. Set the Cause bits even >> 346 * if a corresponding Enable bit is set. This will be noticed at >> 347 * the time the thread is switched to and SIGFPE thrown accordingly. >> 348 */ >> 349 static void ptrace_setfcr31(struct task_struct *child, u32 value) >> 350 { >> 351 u32 fcr31; >> 352 u32 mask; >> 353 >> 354 fcr31 = child->thread.fpu.fcr31; >> 355 mask = boot_cpu_data.fpu_msk31; >> 356 child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask); >> 357 } >> 358 >> 359 int ptrace_getfpregs(struct task_struct *child, __u32 __user *data) >> 360 { >> 361 int i; >> 362 >> 363 if (!access_ok(data, 33 * 8)) >> 364 return -EIO; >> 365 >> 366 if (tsk_used_math(child)) { >> 367 union fpureg *fregs = get_fpu_regs(child); >> 368 for (i = 0; i < 32; i++) >> 369 __put_user(get_fpr64(&fregs[i], 0), >> 370 i + (__u64 __user *)data); >> 371 } else { >> 372 for (i = 0; i < 32; i++) >> 373 __put_user((__u64) -1, i + (__u64 __user *) data); >> 374 } >> 375 >> 376 __put_user(child->thread.fpu.fcr31, data + 64); >> 377 __put_user(boot_cpu_data.fpu_id, data + 65); >> 378 >> 379 return 0; >> 380 } >> 381 >> 382 int ptrace_setfpregs(struct task_struct *child, __u32 __user *data) >> 383 { >> 384 union fpureg *fregs; >> 385 u64 fpr_val; >> 386 u32 value; >> 387 int i; >> 388 >> 389 if (!access_ok(data, 33 * 8)) >> 390 return -EIO; >> 391 >> 392 init_fp_ctx(child); >> 393 fregs = get_fpu_regs(child); >> 394 >> 395 for (i = 0; i < 32; i++) { >> 396 __get_user(fpr_val, i + (__u64 __user *)data); >> 397 set_fpr64(&fregs[i], 0, fpr_val); >> 398 } >> 399 >> 400 __get_user(value, data + 64); >> 401 ptrace_setfcr31(child, value); >> 402 >> 403 /* FIR may not be written. */ >> 404 >> 405 return 0; >> 406 } >> 407 >> 408 /* >> 409 * Copy the floating-point context to the supplied NT_PRFPREG buffer, >> 410 * !CONFIG_CPU_HAS_MSA variant. FP context's general register slots >> 411 * correspond 1:1 to buffer slots. Only general registers are copied. >> 412 */ >> 413 static void fpr_get_fpa(struct task_struct *target, >> 414 struct membuf *to) >> 415 { >> 416 membuf_write(to, &target->thread.fpu, >> 417 NUM_FPU_REGS * sizeof(elf_fpreg_t)); >> 418 } >> 419 >> 420 /* >> 421 * Copy the floating-point context to the supplied NT_PRFPREG buffer, >> 422 * CONFIG_CPU_HAS_MSA variant. Only lower 64 bits of FP context's >> 423 * general register slots are copied to buffer slots. Only general >> 424 * registers are copied. >> 425 */ >> 426 static void fpr_get_msa(struct task_struct *target, struct membuf *to) >> 427 { >> 428 unsigned int i; >> 429 >> 430 BUILD_BUG_ON(sizeof(u64) != sizeof(elf_fpreg_t)); >> 431 for (i = 0; i < NUM_FPU_REGS; i++) >> 432 membuf_store(to, get_fpr64(&target->thread.fpu.fpr[i], 0)); >> 433 } >> 434 >> 435 /* >> 436 * Copy the floating-point context to the supplied NT_PRFPREG buffer. >> 437 * Choose the appropriate helper for general registers, and then copy >> 438 * the FCSR and FIR registers separately. >> 439 */ >> 440 static int fpr_get(struct task_struct *target, >> 441 const struct user_regset *regset, >> 442 struct membuf to) >> 443 { >> 444 if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t)) >> 445 fpr_get_fpa(target, &to); >> 446 else >> 447 fpr_get_msa(target, &to); >> 448 >> 449 membuf_write(&to, &target->thread.fpu.fcr31, sizeof(u32)); >> 450 membuf_write(&to, &boot_cpu_data.fpu_id, sizeof(u32)); >> 451 return 0; >> 452 } >> 453 >> 454 /* >> 455 * Copy the supplied NT_PRFPREG buffer to the floating-point context, >> 456 * !CONFIG_CPU_HAS_MSA variant. Buffer slots correspond 1:1 to FP >> 457 * context's general register slots. Only general registers are copied. >> 458 */ >> 459 static int fpr_set_fpa(struct task_struct *target, >> 460 unsigned int *pos, unsigned int *count, >> 461 const void **kbuf, const void __user **ubuf) >> 462 { >> 463 return user_regset_copyin(pos, count, kbuf, ubuf, >> 464 &target->thread.fpu, >> 465 0, NUM_FPU_REGS * sizeof(elf_fpreg_t)); >> 466 } >> 467 >> 468 /* >> 469 * Copy the supplied NT_PRFPREG buffer to the floating-point context, >> 470 * CONFIG_CPU_HAS_MSA variant. Buffer slots are copied to lower 64 >> 471 * bits only of FP context's general register slots. Only general >> 472 * registers are copied. >> 473 */ >> 474 static int fpr_set_msa(struct task_struct *target, >> 475 unsigned int *pos, unsigned int *count, >> 476 const void **kbuf, const void __user **ubuf) >> 477 { >> 478 unsigned int i; >> 479 u64 fpr_val; >> 480 int err; >> 481 >> 482 BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t)); >> 483 for (i = 0; i < NUM_FPU_REGS && *count > 0; i++) { >> 484 err = user_regset_copyin(pos, count, kbuf, ubuf, >> 485 &fpr_val, i * sizeof(elf_fpreg_t), >> 486 (i + 1) * sizeof(elf_fpreg_t)); >> 487 if (err) >> 488 return err; >> 489 set_fpr64(&target->thread.fpu.fpr[i], 0, fpr_val); >> 490 } >> 491 >> 492 return 0; >> 493 } >> 494 >> 495 /* >> 496 * Copy the supplied NT_PRFPREG buffer to the floating-point context. >> 497 * Choose the appropriate helper for general registers, and then copy >> 498 * the FCSR register separately. Ignore the incoming FIR register >> 499 * contents though, as the register is read-only. >> 500 * >> 501 * We optimize for the case where `count % sizeof(elf_fpreg_t) == 0', >> 502 * which is supposed to have been guaranteed by the kernel before >> 503 * calling us, e.g. in `ptrace_regset'. We enforce that requirement, >> 504 * so that we can safely avoid preinitializing temporaries for >> 505 * partial register writes. >> 506 */ >> 507 static int fpr_set(struct task_struct *target, >> 508 const struct user_regset *regset, >> 509 unsigned int pos, unsigned int count, >> 510 const void *kbuf, const void __user *ubuf) >> 511 { >> 512 const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t); >> 513 const int fir_pos = fcr31_pos + sizeof(u32); >> 514 u32 fcr31; >> 515 int err; >> 516 >> 517 BUG_ON(count % sizeof(elf_fpreg_t)); >> 518 >> 519 if (pos + count > sizeof(elf_fpregset_t)) >> 520 return -EIO; >> 521 >> 522 init_fp_ctx(target); >> 523 >> 524 if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t)) >> 525 err = fpr_set_fpa(target, &pos, &count, &kbuf, &ubuf); >> 526 else >> 527 err = fpr_set_msa(target, &pos, &count, &kbuf, &ubuf); >> 528 if (err) >> 529 return err; >> 530 >> 531 if (count > 0) { >> 532 err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, >> 533 &fcr31, >> 534 fcr31_pos, fcr31_pos + sizeof(u32)); >> 535 if (err) >> 536 return err; >> 537 >> 538 ptrace_setfcr31(target, fcr31); >> 539 } >> 540 >> 541 if (count > 0) { >> 542 user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, >> 543 fir_pos, fir_pos + sizeof(u32)); >> 544 return 0; >> 545 } >> 546 >> 547 return err; >> 548 } >> 549 >> 550 /* Copy the FP mode setting to the supplied NT_MIPS_FP_MODE buffer. */ >> 551 static int fp_mode_get(struct task_struct *target, >> 552 const struct user_regset *regset, >> 553 struct membuf to) >> 554 { >> 555 return membuf_store(&to, (int)mips_get_process_fp_mode(target)); >> 556 } >> 557 >> 558 /* >> 559 * Copy the supplied NT_MIPS_FP_MODE buffer to the FP mode setting. >> 560 * >> 561 * We optimize for the case where `count % sizeof(int) == 0', which >> 562 * is supposed to have been guaranteed by the kernel before calling >> 563 * us, e.g. in `ptrace_regset'. We enforce that requirement, so >> 564 * that we can safely avoid preinitializing temporaries for partial >> 565 * mode writes. >> 566 */ >> 567 static int fp_mode_set(struct task_struct *target, >> 568 const struct user_regset *regset, >> 569 unsigned int pos, unsigned int count, >> 570 const void *kbuf, const void __user *ubuf) >> 571 { >> 572 int fp_mode; >> 573 int err; >> 574 >> 575 BUG_ON(count % sizeof(int)); >> 576 >> 577 if (pos + count > sizeof(fp_mode)) >> 578 return -EIO; >> 579 >> 580 err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fp_mode, 0, >> 581 sizeof(fp_mode)); >> 582 if (err) >> 583 return err; >> 584 >> 585 if (count > 0) >> 586 err = mips_set_process_fp_mode(target, fp_mode); >> 587 >> 588 return err; >> 589 } >> 590 >> 591 #endif /* CONFIG_MIPS_FP_SUPPORT */ >> 592 >> 593 #ifdef CONFIG_CPU_HAS_MSA >> 594 >> 595 struct msa_control_regs { >> 596 unsigned int fir; >> 597 unsigned int fcsr; >> 598 unsigned int msair; >> 599 unsigned int msacsr; >> 600 }; >> 601 >> 602 static void copy_pad_fprs(struct task_struct *target, >> 603 const struct user_regset *regset, >> 604 struct membuf *to, >> 605 unsigned int live_sz) >> 606 { >> 607 int i, j; >> 608 unsigned long long fill = ~0ull; >> 609 unsigned int cp_sz, pad_sz; >> 610 >> 611 cp_sz = min(regset->size, live_sz); >> 612 pad_sz = regset->size - cp_sz; >> 613 WARN_ON(pad_sz % sizeof(fill)); >> 614 >> 615 for (i = 0; i < NUM_FPU_REGS; i++) { >> 616 membuf_write(to, &target->thread.fpu.fpr[i], cp_sz); >> 617 for (j = 0; j < (pad_sz / sizeof(fill)); j++) >> 618 membuf_store(to, fill); >> 619 } >> 620 } >> 621 >> 622 static int msa_get(struct task_struct *target, >> 623 const struct user_regset *regset, >> 624 struct membuf to) >> 625 { >> 626 const unsigned int wr_size = NUM_FPU_REGS * regset->size; >> 627 const struct msa_control_regs ctrl_regs = { >> 628 .fir = boot_cpu_data.fpu_id, >> 629 .fcsr = target->thread.fpu.fcr31, >> 630 .msair = boot_cpu_data.msa_id, >> 631 .msacsr = target->thread.fpu.msacsr, >> 632 }; >> 633 >> 634 if (!tsk_used_math(target)) { >> 635 /* The task hasn't used FP or MSA, fill with 0xff */ >> 636 copy_pad_fprs(target, regset, &to, 0); >> 637 } else if (!test_tsk_thread_flag(target, TIF_MSA_CTX_LIVE)) { >> 638 /* Copy scalar FP context, fill the rest with 0xff */ >> 639 copy_pad_fprs(target, regset, &to, 8); >> 640 } else if (sizeof(target->thread.fpu.fpr[0]) == regset->size) { >> 641 /* Trivially copy the vector registers */ >> 642 membuf_write(&to, &target->thread.fpu.fpr, wr_size); >> 643 } else { >> 644 /* Copy as much context as possible, fill the rest with 0xff */ >> 645 copy_pad_fprs(target, regset, &to, >> 646 sizeof(target->thread.fpu.fpr[0])); >> 647 } >> 648 >> 649 return membuf_write(&to, &ctrl_regs, sizeof(ctrl_regs)); >> 650 } >> 651 >> 652 static int msa_set(struct task_struct *target, >> 653 const struct user_regset *regset, >> 654 unsigned int pos, unsigned int count, >> 655 const void *kbuf, const void __user *ubuf) >> 656 { >> 657 const unsigned int wr_size = NUM_FPU_REGS * regset->size; >> 658 struct msa_control_regs ctrl_regs; >> 659 unsigned int cp_sz; >> 660 int i, err, start; >> 661 >> 662 init_fp_ctx(target); >> 663 >> 664 if (sizeof(target->thread.fpu.fpr[0]) == regset->size) { >> 665 /* Trivially copy the vector registers */ >> 666 err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, >> 667 &target->thread.fpu.fpr, >> 668 0, wr_size); >> 669 } else { >> 670 /* Copy as much context as possible */ >> 671 cp_sz = min_t(unsigned int, regset->size, >> 672 sizeof(target->thread.fpu.fpr[0])); >> 673 >> 674 i = start = err = 0; >> 675 for (; i < NUM_FPU_REGS; i++, start += regset->size) { >> 676 err |= user_regset_copyin(&pos, &count, &kbuf, &ubuf, >> 677 &target->thread.fpu.fpr[i], >> 678 start, start + cp_sz); >> 679 } >> 680 } >> 681 >> 682 if (!err) >> 683 err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl_regs, >> 684 wr_size, wr_size + sizeof(ctrl_regs)); >> 685 if (!err) { >> 686 target->thread.fpu.fcr31 = ctrl_regs.fcsr & ~FPU_CSR_ALL_X; >> 687 target->thread.fpu.msacsr = ctrl_regs.msacsr & ~MSA_CSR_CAUSEF; >> 688 } >> 689 >> 690 return err; >> 691 } >> 692 >> 693 #endif /* CONFIG_CPU_HAS_MSA */ >> 694 >> 695 #if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32) >> 696 >> 697 /* >> 698 * Copy the DSP context to the supplied 32-bit NT_MIPS_DSP buffer. >> 699 */ >> 700 static int dsp32_get(struct task_struct *target, >> 701 const struct user_regset *regset, >> 702 struct membuf to) >> 703 { >> 704 u32 dspregs[NUM_DSP_REGS + 1]; >> 705 unsigned int i; >> 706 >> 707 BUG_ON(to.left % sizeof(u32)); >> 708 >> 709 if (!cpu_has_dsp) >> 710 return -EIO; >> 711 >> 712 for (i = 0; i < NUM_DSP_REGS; i++) >> 713 dspregs[i] = target->thread.dsp.dspr[i]; >> 714 dspregs[NUM_DSP_REGS] = target->thread.dsp.dspcontrol; >> 715 return membuf_write(&to, dspregs, sizeof(dspregs)); >> 716 } >> 717 >> 718 /* >> 719 * Copy the supplied 32-bit NT_MIPS_DSP buffer to the DSP context. >> 720 */ >> 721 static int dsp32_set(struct task_struct *target, >> 722 const struct user_regset *regset, >> 723 unsigned int pos, unsigned int count, >> 724 const void *kbuf, const void __user *ubuf) >> 725 { >> 726 unsigned int start, num_regs, i; >> 727 u32 dspregs[NUM_DSP_REGS + 1]; >> 728 int err; >> 729 >> 730 BUG_ON(count % sizeof(u32)); >> 731 >> 732 if (!cpu_has_dsp) >> 733 return -EIO; >> 734 >> 735 start = pos / sizeof(u32); >> 736 num_regs = count / sizeof(u32); >> 737 >> 738 if (start + num_regs > NUM_DSP_REGS + 1) >> 739 return -EIO; >> 740 >> 741 err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, dspregs, 0, >> 742 sizeof(dspregs)); >> 743 if (err) >> 744 return err; >> 745 >> 746 for (i = start; i < num_regs; i++) >> 747 switch (i) { >> 748 case 0 ... NUM_DSP_REGS - 1: >> 749 target->thread.dsp.dspr[i] = (s32)dspregs[i]; >> 750 break; >> 751 case NUM_DSP_REGS: >> 752 target->thread.dsp.dspcontrol = (s32)dspregs[i]; >> 753 break; >> 754 } >> 755 >> 756 return 0; >> 757 } >> 758 >> 759 #endif /* CONFIG_32BIT || CONFIG_MIPS32_O32 */ >> 760 >> 761 #ifdef CONFIG_64BIT >> 762 >> 763 /* >> 764 * Copy the DSP context to the supplied 64-bit NT_MIPS_DSP buffer. >> 765 */ >> 766 static int dsp64_get(struct task_struct *target, >> 767 const struct user_regset *regset, >> 768 struct membuf to) >> 769 { >> 770 u64 dspregs[NUM_DSP_REGS + 1]; >> 771 unsigned int i; >> 772 >> 773 BUG_ON(to.left % sizeof(u64)); >> 774 >> 775 if (!cpu_has_dsp) >> 776 return -EIO; >> 777 >> 778 for (i = 0; i < NUM_DSP_REGS; i++) >> 779 dspregs[i] = target->thread.dsp.dspr[i]; >> 780 dspregs[NUM_DSP_REGS] = target->thread.dsp.dspcontrol; >> 781 return membuf_write(&to, dspregs, sizeof(dspregs)); >> 782 } >> 783 >> 784 /* >> 785 * Copy the supplied 64-bit NT_MIPS_DSP buffer to the DSP context. >> 786 */ >> 787 static int dsp64_set(struct task_struct *target, >> 788 const struct user_regset *regset, >> 789 unsigned int pos, unsigned int count, >> 790 const void *kbuf, const void __user *ubuf) >> 791 { >> 792 unsigned int start, num_regs, i; >> 793 u64 dspregs[NUM_DSP_REGS + 1]; >> 794 int err; >> 795 >> 796 BUG_ON(count % sizeof(u64)); >> 797 >> 798 if (!cpu_has_dsp) >> 799 return -EIO; >> 800 >> 801 start = pos / sizeof(u64); >> 802 num_regs = count / sizeof(u64); >> 803 >> 804 if (start + num_regs > NUM_DSP_REGS + 1) >> 805 return -EIO; >> 806 >> 807 err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, dspregs, 0, >> 808 sizeof(dspregs)); >> 809 if (err) >> 810 return err; >> 811 >> 812 for (i = start; i < num_regs; i++) >> 813 switch (i) { >> 814 case 0 ... NUM_DSP_REGS - 1: >> 815 target->thread.dsp.dspr[i] = dspregs[i]; >> 816 break; >> 817 case NUM_DSP_REGS: >> 818 target->thread.dsp.dspcontrol = dspregs[i]; >> 819 break; >> 820 } >> 821 >> 822 return 0; >> 823 } >> 824 >> 825 #endif /* CONFIG_64BIT */ >> 826 >> 827 /* >> 828 * Determine whether the DSP context is present. >> 829 */ >> 830 static int dsp_active(struct task_struct *target, >> 831 const struct user_regset *regset) >> 832 { >> 833 return cpu_has_dsp ? NUM_DSP_REGS + 1 : -ENODEV; >> 834 } >> 835 >> 836 enum mips_regset { >> 837 REGSET_GPR, >> 838 REGSET_DSP, >> 839 #ifdef CONFIG_MIPS_FP_SUPPORT >> 840 REGSET_FPR, >> 841 REGSET_FP_MODE, >> 842 #endif >> 843 #ifdef CONFIG_CPU_HAS_MSA >> 844 REGSET_MSA, >> 845 #endif >> 846 }; >> 847 >> 848 struct pt_regs_offset { >> 849 const char *name; >> 850 int offset; >> 851 }; >> 852 >> 853 #define REG_OFFSET_NAME(reg, r) { \ >> 854 .name = #reg, \ >> 855 .offset = offsetof(struct pt_regs, r) \ >> 856 } >> 857 >> 858 #define REG_OFFSET_END { \ >> 859 .name = NULL, \ >> 860 .offset = 0 \ >> 861 } >> 862 >> 863 static const struct pt_regs_offset regoffset_table[] = { >> 864 REG_OFFSET_NAME(r0, regs[0]), >> 865 REG_OFFSET_NAME(r1, regs[1]), >> 866 REG_OFFSET_NAME(r2, regs[2]), >> 867 REG_OFFSET_NAME(r3, regs[3]), >> 868 REG_OFFSET_NAME(r4, regs[4]), >> 869 REG_OFFSET_NAME(r5, regs[5]), >> 870 REG_OFFSET_NAME(r6, regs[6]), >> 871 REG_OFFSET_NAME(r7, regs[7]), >> 872 REG_OFFSET_NAME(r8, regs[8]), >> 873 REG_OFFSET_NAME(r9, regs[9]), >> 874 REG_OFFSET_NAME(r10, regs[10]), >> 875 REG_OFFSET_NAME(r11, regs[11]), >> 876 REG_OFFSET_NAME(r12, regs[12]), >> 877 REG_OFFSET_NAME(r13, regs[13]), >> 878 REG_OFFSET_NAME(r14, regs[14]), >> 879 REG_OFFSET_NAME(r15, regs[15]), >> 880 REG_OFFSET_NAME(r16, regs[16]), >> 881 REG_OFFSET_NAME(r17, regs[17]), >> 882 REG_OFFSET_NAME(r18, regs[18]), >> 883 REG_OFFSET_NAME(r19, regs[19]), >> 884 REG_OFFSET_NAME(r20, regs[20]), >> 885 REG_OFFSET_NAME(r21, regs[21]), >> 886 REG_OFFSET_NAME(r22, regs[22]), >> 887 REG_OFFSET_NAME(r23, regs[23]), >> 888 REG_OFFSET_NAME(r24, regs[24]), >> 889 REG_OFFSET_NAME(r25, regs[25]), >> 890 REG_OFFSET_NAME(r26, regs[26]), >> 891 REG_OFFSET_NAME(r27, regs[27]), >> 892 REG_OFFSET_NAME(r28, regs[28]), >> 893 REG_OFFSET_NAME(r29, regs[29]), >> 894 REG_OFFSET_NAME(r30, regs[30]), >> 895 REG_OFFSET_NAME(r31, regs[31]), >> 896 REG_OFFSET_NAME(c0_status, cp0_status), >> 897 REG_OFFSET_NAME(hi, hi), >> 898 REG_OFFSET_NAME(lo, lo), >> 899 #ifdef CONFIG_CPU_HAS_SMARTMIPS >> 900 REG_OFFSET_NAME(acx, acx), >> 901 #endif >> 902 REG_OFFSET_NAME(c0_badvaddr, cp0_badvaddr), >> 903 REG_OFFSET_NAME(c0_cause, cp0_cause), >> 904 REG_OFFSET_NAME(c0_epc, cp0_epc), >> 905 #ifdef CONFIG_CPU_CAVIUM_OCTEON >> 906 REG_OFFSET_NAME(mpl0, mpl[0]), >> 907 REG_OFFSET_NAME(mpl1, mpl[1]), >> 908 REG_OFFSET_NAME(mpl2, mpl[2]), >> 909 REG_OFFSET_NAME(mtp0, mtp[0]), >> 910 REG_OFFSET_NAME(mtp1, mtp[1]), >> 911 REG_OFFSET_NAME(mtp2, mtp[2]), >> 912 #endif >> 913 REG_OFFSET_END, >> 914 }; 3 915 4 /** 916 /** 5 * regs_query_register_offset() - query regist 917 * regs_query_register_offset() - query register offset from its name 6 * @name: the name of a register !! 918 * @name: the name of a register 7 * 919 * 8 * regs_query_register_offset() returns the of 920 * regs_query_register_offset() returns the offset of a register in struct 9 * pt_regs from its name. If the name is inval 921 * pt_regs from its name. If the name is invalid, this returns -EINVAL; 10 */ 922 */ 11 int regs_query_register_offset(const char *nam 923 int regs_query_register_offset(const char *name) 12 { 924 { 13 const struct pt_regs_offset *roff; !! 925 const struct pt_regs_offset *roff; 14 for (roff = regoffset_table; roff->nam !! 926 for (roff = regoffset_table; roff->name != NULL; roff++) 15 if (!strcmp(roff->name, name)) !! 927 if (!strcmp(roff->name, name)) 16 return roff->offset; !! 928 return roff->offset; 17 return -EINVAL; !! 929 return -EINVAL; 18 } 930 } 19 931 20 /** !! 932 #if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32) 21 * regs_query_register_name() - query register !! 933 22 * @offset: the offset of a register in st !! 934 static const struct user_regset mips_regsets[] = { 23 * !! 935 [REGSET_GPR] = { 24 * regs_query_register_name() returns the name !! 936 .core_note_type = NT_PRSTATUS, 25 * offset in struct pt_regs. If the @offset is !! 937 .n = ELF_NGREG, >> 938 .size = sizeof(unsigned int), >> 939 .align = sizeof(unsigned int), >> 940 .regset_get = gpr32_get, >> 941 .set = gpr32_set, >> 942 }, >> 943 [REGSET_DSP] = { >> 944 .core_note_type = NT_MIPS_DSP, >> 945 .n = NUM_DSP_REGS + 1, >> 946 .size = sizeof(u32), >> 947 .align = sizeof(u32), >> 948 .regset_get = dsp32_get, >> 949 .set = dsp32_set, >> 950 .active = dsp_active, >> 951 }, >> 952 #ifdef CONFIG_MIPS_FP_SUPPORT >> 953 [REGSET_FPR] = { >> 954 .core_note_type = NT_PRFPREG, >> 955 .n = ELF_NFPREG, >> 956 .size = sizeof(elf_fpreg_t), >> 957 .align = sizeof(elf_fpreg_t), >> 958 .regset_get = fpr_get, >> 959 .set = fpr_set, >> 960 }, >> 961 [REGSET_FP_MODE] = { >> 962 .core_note_type = NT_MIPS_FP_MODE, >> 963 .n = 1, >> 964 .size = sizeof(int), >> 965 .align = sizeof(int), >> 966 .regset_get = fp_mode_get, >> 967 .set = fp_mode_set, >> 968 }, >> 969 #endif >> 970 #ifdef CONFIG_CPU_HAS_MSA >> 971 [REGSET_MSA] = { >> 972 .core_note_type = NT_MIPS_MSA, >> 973 .n = NUM_FPU_REGS + 1, >> 974 .size = 16, >> 975 .align = 16, >> 976 .regset_get = msa_get, >> 977 .set = msa_set, >> 978 }, >> 979 #endif >> 980 }; >> 981 >> 982 static const struct user_regset_view user_mips_view = { >> 983 .name = "mips", >> 984 .e_machine = ELF_ARCH, >> 985 .ei_osabi = ELF_OSABI, >> 986 .regsets = mips_regsets, >> 987 .n = ARRAY_SIZE(mips_regsets), >> 988 }; >> 989 >> 990 #endif /* CONFIG_32BIT || CONFIG_MIPS32_O32 */ >> 991 >> 992 #ifdef CONFIG_64BIT >> 993 >> 994 static const struct user_regset mips64_regsets[] = { >> 995 [REGSET_GPR] = { >> 996 .core_note_type = NT_PRSTATUS, >> 997 .n = ELF_NGREG, >> 998 .size = sizeof(unsigned long), >> 999 .align = sizeof(unsigned long), >> 1000 .regset_get = gpr64_get, >> 1001 .set = gpr64_set, >> 1002 }, >> 1003 [REGSET_DSP] = { >> 1004 .core_note_type = NT_MIPS_DSP, >> 1005 .n = NUM_DSP_REGS + 1, >> 1006 .size = sizeof(u64), >> 1007 .align = sizeof(u64), >> 1008 .regset_get = dsp64_get, >> 1009 .set = dsp64_set, >> 1010 .active = dsp_active, >> 1011 }, >> 1012 #ifdef CONFIG_MIPS_FP_SUPPORT >> 1013 [REGSET_FP_MODE] = { >> 1014 .core_note_type = NT_MIPS_FP_MODE, >> 1015 .n = 1, >> 1016 .size = sizeof(int), >> 1017 .align = sizeof(int), >> 1018 .regset_get = fp_mode_get, >> 1019 .set = fp_mode_set, >> 1020 }, >> 1021 [REGSET_FPR] = { >> 1022 .core_note_type = NT_PRFPREG, >> 1023 .n = ELF_NFPREG, >> 1024 .size = sizeof(elf_fpreg_t), >> 1025 .align = sizeof(elf_fpreg_t), >> 1026 .regset_get = fpr_get, >> 1027 .set = fpr_set, >> 1028 }, >> 1029 #endif >> 1030 #ifdef CONFIG_CPU_HAS_MSA >> 1031 [REGSET_MSA] = { >> 1032 .core_note_type = NT_MIPS_MSA, >> 1033 .n = NUM_FPU_REGS + 1, >> 1034 .size = 16, >> 1035 .align = 16, >> 1036 .regset_get = msa_get, >> 1037 .set = msa_set, >> 1038 }, >> 1039 #endif >> 1040 }; >> 1041 >> 1042 static const struct user_regset_view user_mips64_view = { >> 1043 .name = "mips64", >> 1044 .e_machine = ELF_ARCH, >> 1045 .ei_osabi = ELF_OSABI, >> 1046 .regsets = mips64_regsets, >> 1047 .n = ARRAY_SIZE(mips64_regsets), >> 1048 }; >> 1049 >> 1050 #ifdef CONFIG_MIPS32_N32 >> 1051 >> 1052 static const struct user_regset_view user_mipsn32_view = { >> 1053 .name = "mipsn32", >> 1054 .e_flags = EF_MIPS_ABI2, >> 1055 .e_machine = ELF_ARCH, >> 1056 .ei_osabi = ELF_OSABI, >> 1057 .regsets = mips64_regsets, >> 1058 .n = ARRAY_SIZE(mips64_regsets), >> 1059 }; >> 1060 >> 1061 #endif /* CONFIG_MIPS32_N32 */ >> 1062 >> 1063 #endif /* CONFIG_64BIT */ >> 1064 >> 1065 const struct user_regset_view *task_user_regset_view(struct task_struct *task) >> 1066 { >> 1067 #ifdef CONFIG_32BIT >> 1068 return &user_mips_view; >> 1069 #else >> 1070 #ifdef CONFIG_MIPS32_O32 >> 1071 if (test_tsk_thread_flag(task, TIF_32BIT_REGS)) >> 1072 return &user_mips_view; >> 1073 #endif >> 1074 #ifdef CONFIG_MIPS32_N32 >> 1075 if (test_tsk_thread_flag(task, TIF_32BIT_ADDR)) >> 1076 return &user_mipsn32_view; >> 1077 #endif >> 1078 return &user_mips64_view; >> 1079 #endif >> 1080 } >> 1081 >> 1082 long arch_ptrace(struct task_struct *child, long request, >> 1083 unsigned long addr, unsigned long data) >> 1084 { >> 1085 int ret; >> 1086 void __user *addrp = (void __user *) addr; >> 1087 void __user *datavp = (void __user *) data; >> 1088 unsigned long __user *datalp = (void __user *) data; >> 1089 >> 1090 switch (request) { >> 1091 /* when I and D space are separate, these will need to be fixed. */ >> 1092 case PTRACE_PEEKTEXT: /* read word at location addr. */ >> 1093 case PTRACE_PEEKDATA: >> 1094 ret = generic_ptrace_peekdata(child, addr, data); >> 1095 break; >> 1096 >> 1097 /* Read the word at location addr in the USER area. */ >> 1098 case PTRACE_PEEKUSR: { >> 1099 struct pt_regs *regs; >> 1100 unsigned long tmp = 0; >> 1101 >> 1102 regs = task_pt_regs(child); >> 1103 ret = 0; /* Default return value. */ >> 1104 >> 1105 switch (addr) { >> 1106 case 0 ... 31: >> 1107 tmp = regs->regs[addr]; >> 1108 break; >> 1109 #ifdef CONFIG_MIPS_FP_SUPPORT >> 1110 case FPR_BASE ... FPR_BASE + 31: { >> 1111 union fpureg *fregs; >> 1112 >> 1113 if (!tsk_used_math(child)) { >> 1114 /* FP not yet used */ >> 1115 tmp = -1; >> 1116 break; >> 1117 } >> 1118 fregs = get_fpu_regs(child); >> 1119 >> 1120 #ifdef CONFIG_32BIT >> 1121 if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) { >> 1122 /* >> 1123 * The odd registers are actually the high >> 1124 * order bits of the values stored in the even >> 1125 * registers. >> 1126 */ >> 1127 tmp = get_fpr32(&fregs[(addr & ~1) - FPR_BASE], >> 1128 addr & 1); >> 1129 break; >> 1130 } >> 1131 #endif >> 1132 tmp = get_fpr64(&fregs[addr - FPR_BASE], 0); >> 1133 break; >> 1134 } >> 1135 case FPC_CSR: >> 1136 tmp = child->thread.fpu.fcr31; >> 1137 break; >> 1138 case FPC_EIR: >> 1139 /* implementation / version register */ >> 1140 tmp = boot_cpu_data.fpu_id; >> 1141 break; >> 1142 #endif >> 1143 case PC: >> 1144 tmp = regs->cp0_epc; >> 1145 break; >> 1146 case CAUSE: >> 1147 tmp = regs->cp0_cause; >> 1148 break; >> 1149 case BADVADDR: >> 1150 tmp = regs->cp0_badvaddr; >> 1151 break; >> 1152 case MMHI: >> 1153 tmp = regs->hi; >> 1154 break; >> 1155 case MMLO: >> 1156 tmp = regs->lo; >> 1157 break; >> 1158 #ifdef CONFIG_CPU_HAS_SMARTMIPS >> 1159 case ACX: >> 1160 tmp = regs->acx; >> 1161 break; >> 1162 #endif >> 1163 case DSP_BASE ... DSP_BASE + 5: { >> 1164 dspreg_t *dregs; >> 1165 >> 1166 if (!cpu_has_dsp) { >> 1167 tmp = 0; >> 1168 ret = -EIO; >> 1169 goto out; >> 1170 } >> 1171 dregs = __get_dsp_regs(child); >> 1172 tmp = dregs[addr - DSP_BASE]; >> 1173 break; >> 1174 } >> 1175 case DSP_CONTROL: >> 1176 if (!cpu_has_dsp) { >> 1177 tmp = 0; >> 1178 ret = -EIO; >> 1179 goto out; >> 1180 } >> 1181 tmp = child->thread.dsp.dspcontrol; >> 1182 break; >> 1183 default: >> 1184 tmp = 0; >> 1185 ret = -EIO; >> 1186 goto out; >> 1187 } >> 1188 ret = put_user(tmp, datalp); >> 1189 break; >> 1190 } >> 1191 >> 1192 /* when I and D space are separate, this will have to be fixed. */ >> 1193 case PTRACE_POKETEXT: /* write the word at location addr. */ >> 1194 case PTRACE_POKEDATA: >> 1195 ret = generic_ptrace_pokedata(child, addr, data); >> 1196 break; >> 1197 >> 1198 case PTRACE_POKEUSR: { >> 1199 struct pt_regs *regs; >> 1200 ret = 0; >> 1201 regs = task_pt_regs(child); >> 1202 >> 1203 switch (addr) { >> 1204 case 0 ... 31: >> 1205 regs->regs[addr] = data; >> 1206 /* System call number may have been changed */ >> 1207 if (addr == 2) >> 1208 mips_syscall_update_nr(child, regs); >> 1209 else if (addr == 4 && >> 1210 mips_syscall_is_indirect(child, regs)) >> 1211 mips_syscall_update_nr(child, regs); >> 1212 break; >> 1213 #ifdef CONFIG_MIPS_FP_SUPPORT >> 1214 case FPR_BASE ... FPR_BASE + 31: { >> 1215 union fpureg *fregs = get_fpu_regs(child); >> 1216 >> 1217 init_fp_ctx(child); >> 1218 #ifdef CONFIG_32BIT >> 1219 if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) { >> 1220 /* >> 1221 * The odd registers are actually the high >> 1222 * order bits of the values stored in the even >> 1223 * registers. >> 1224 */ >> 1225 set_fpr32(&fregs[(addr & ~1) - FPR_BASE], >> 1226 addr & 1, data); >> 1227 break; >> 1228 } >> 1229 #endif >> 1230 set_fpr64(&fregs[addr - FPR_BASE], 0, data); >> 1231 break; >> 1232 } >> 1233 case FPC_CSR: >> 1234 init_fp_ctx(child); >> 1235 ptrace_setfcr31(child, data); >> 1236 break; >> 1237 #endif >> 1238 case PC: >> 1239 regs->cp0_epc = data; >> 1240 break; >> 1241 case MMHI: >> 1242 regs->hi = data; >> 1243 break; >> 1244 case MMLO: >> 1245 regs->lo = data; >> 1246 break; >> 1247 #ifdef CONFIG_CPU_HAS_SMARTMIPS >> 1248 case ACX: >> 1249 regs->acx = data; >> 1250 break; >> 1251 #endif >> 1252 case DSP_BASE ... DSP_BASE + 5: { >> 1253 dspreg_t *dregs; >> 1254 >> 1255 if (!cpu_has_dsp) { >> 1256 ret = -EIO; >> 1257 break; >> 1258 } >> 1259 >> 1260 dregs = __get_dsp_regs(child); >> 1261 dregs[addr - DSP_BASE] = data; >> 1262 break; >> 1263 } >> 1264 case DSP_CONTROL: >> 1265 if (!cpu_has_dsp) { >> 1266 ret = -EIO; >> 1267 break; >> 1268 } >> 1269 child->thread.dsp.dspcontrol = data; >> 1270 break; >> 1271 default: >> 1272 /* The rest are not allowed. */ >> 1273 ret = -EIO; >> 1274 break; >> 1275 } >> 1276 break; >> 1277 } >> 1278 >> 1279 case PTRACE_GETREGS: >> 1280 ret = ptrace_getregs(child, datavp); >> 1281 break; >> 1282 >> 1283 case PTRACE_SETREGS: >> 1284 ret = ptrace_setregs(child, datavp); >> 1285 break; >> 1286 >> 1287 #ifdef CONFIG_MIPS_FP_SUPPORT >> 1288 case PTRACE_GETFPREGS: >> 1289 ret = ptrace_getfpregs(child, datavp); >> 1290 break; >> 1291 >> 1292 case PTRACE_SETFPREGS: >> 1293 ret = ptrace_setfpregs(child, datavp); >> 1294 break; >> 1295 #endif >> 1296 case PTRACE_GET_THREAD_AREA: >> 1297 ret = put_user(task_thread_info(child)->tp_value, datalp); >> 1298 break; >> 1299 >> 1300 case PTRACE_GET_WATCH_REGS: >> 1301 ret = ptrace_get_watch_regs(child, addrp); >> 1302 break; >> 1303 >> 1304 case PTRACE_SET_WATCH_REGS: >> 1305 ret = ptrace_set_watch_regs(child, addrp); >> 1306 break; >> 1307 >> 1308 default: >> 1309 ret = ptrace_request(child, request, addr, data); >> 1310 break; >> 1311 } >> 1312 out: >> 1313 return ret; >> 1314 } >> 1315 >> 1316 /* >> 1317 * Notification of system call entry/exit >> 1318 * - triggered by current->work.syscall_trace 26 */ 1319 */ 27 const char *regs_query_register_name(unsigned !! 1320 asmlinkage long syscall_trace_enter(struct pt_regs *regs) 28 { 1321 { 29 const struct pt_regs_offset *roff; !! 1322 user_exit(); 30 for (roff = regoffset_table; roff->nam !! 1323 31 if (roff->offset == offset) !! 1324 if (test_thread_flag(TIF_SYSCALL_TRACE)) { 32 return roff->name; !! 1325 if (ptrace_report_syscall_entry(regs)) 33 return NULL; !! 1326 return -1; >> 1327 } >> 1328 >> 1329 #ifdef CONFIG_SECCOMP >> 1330 if (unlikely(test_thread_flag(TIF_SECCOMP))) { >> 1331 int ret, i; >> 1332 struct seccomp_data sd; >> 1333 unsigned long args[6]; >> 1334 >> 1335 sd.nr = current_thread_info()->syscall; >> 1336 sd.arch = syscall_get_arch(current); >> 1337 syscall_get_arguments(current, regs, args); >> 1338 for (i = 0; i < 6; i++) >> 1339 sd.args[i] = args[i]; >> 1340 sd.instruction_pointer = KSTK_EIP(current); >> 1341 >> 1342 ret = __secure_computing(&sd); >> 1343 if (ret == -1) >> 1344 return ret; >> 1345 } >> 1346 #endif >> 1347 >> 1348 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) >> 1349 trace_sys_enter(regs, regs->regs[2]); >> 1350 >> 1351 audit_syscall_entry(current_thread_info()->syscall, >> 1352 regs->regs[4], regs->regs[5], >> 1353 regs->regs[6], regs->regs[7]); >> 1354 >> 1355 /* >> 1356 * Negative syscall numbers are mistaken for rejected syscalls, but >> 1357 * won't have had the return value set appropriately, so we do so now. >> 1358 */ >> 1359 if (current_thread_info()->syscall < 0) >> 1360 syscall_set_return_value(current, regs, -ENOSYS, 0); >> 1361 return current_thread_info()->syscall; >> 1362 } >> 1363 >> 1364 /* >> 1365 * Notification of system call entry/exit >> 1366 * - triggered by current->work.syscall_trace >> 1367 */ >> 1368 asmlinkage void syscall_trace_leave(struct pt_regs *regs) >> 1369 { >> 1370 /* >> 1371 * We may come here right after calling schedule_user() >> 1372 * or do_notify_resume(), in which case we can be in RCU >> 1373 * user mode. >> 1374 */ >> 1375 user_exit(); >> 1376 >> 1377 audit_syscall_exit(regs); >> 1378 >> 1379 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) >> 1380 trace_sys_exit(regs, regs_return_value(regs)); >> 1381 >> 1382 if (test_thread_flag(TIF_SYSCALL_TRACE)) >> 1383 ptrace_report_syscall_exit(regs, 0); >> 1384 >> 1385 user_enter(); 34 } 1386 } 35 1387
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.