1 // SPDX-License-Identifier: GPL-2.0-or-later 2 3 #include <linux/regset.h> 4 5 #include <asm/switch_to.h> 6 #include <asm/tm.h> 7 #include <asm/asm-prototypes.h> 8 9 #include "ptrace-decl.h" 10 11 void flush_tmregs_to_thread(struct task_struct *tsk) 12 { 13 /* 14 * If task is not current, it will have been flushed already to 15 * its thread_struct during __switch_to(). 16 * 17 * A reclaim flushes ALL the state or if not in TM save TM SPRs 18 * in the appropriate thread structures from live. 19 */ 20 21 if (!cpu_has_feature(CPU_FTR_TM) || tsk != current) 22 return; 23 24 if (MSR_TM_SUSPENDED(mfmsr())) { 25 tm_reclaim_current(TM_CAUSE_SIGNAL); 26 } else { 27 tm_enable(); 28 tm_save_sprs(&tsk->thread); 29 } 30 } 31 32 static unsigned long get_user_ckpt_msr(struct task_struct *task) 33 { 34 return task->thread.ckpt_regs.msr | task->thread.fpexc_mode; 35 } 36 37 static int set_user_ckpt_msr(struct task_struct *task, unsigned long msr) 38 { 39 task->thread.ckpt_regs.msr &= ~MSR_DEBUGCHANGE; 40 task->thread.ckpt_regs.msr |= msr & MSR_DEBUGCHANGE; 41 return 0; 42 } 43 44 static int set_user_ckpt_trap(struct task_struct *task, unsigned long trap) 45 { 46 set_trap(&task->thread.ckpt_regs, trap); 47 return 0; 48 } 49 50 /** 51 * tm_cgpr_active - get active number of registers in CGPR 52 * @target: The target task. 53 * @regset: The user regset structure. 54 * 55 * This function checks for the active number of available 56 * regisers in transaction checkpointed GPR category. 57 */ 58 int tm_cgpr_active(struct task_struct *target, const struct user_regset *regset) 59 { 60 if (!cpu_has_feature(CPU_FTR_TM)) 61 return -ENODEV; 62 63 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 64 return 0; 65 66 return regset->n; 67 } 68 69 /** 70 * tm_cgpr_get - get CGPR registers 71 * @target: The target task. 72 * @regset: The user regset structure. 73 * @to: Destination of copy. 74 * 75 * This function gets transaction checkpointed GPR registers. 76 * 77 * When the transaction is active, 'ckpt_regs' holds all the checkpointed 78 * GPR register values for the current transaction to fall back on if it 79 * aborts in between. This function gets those checkpointed GPR registers. 80 * The userspace interface buffer layout is as follows. 81 * 82 * struct data { 83 * struct pt_regs ckpt_regs; 84 * }; 85 */ 86 int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset, 87 struct membuf to) 88 { 89 struct membuf to_msr = membuf_at(&to, offsetof(struct pt_regs, msr)); 90 #ifdef CONFIG_PPC64 91 struct membuf to_softe = membuf_at(&to, offsetof(struct pt_regs, softe)); 92 #endif 93 94 if (!cpu_has_feature(CPU_FTR_TM)) 95 return -ENODEV; 96 97 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 98 return -ENODATA; 99 100 flush_tmregs_to_thread(target); 101 flush_fp_to_thread(target); 102 flush_altivec_to_thread(target); 103 104 membuf_write(&to, &target->thread.ckpt_regs, sizeof(struct user_pt_regs)); 105 106 membuf_store(&to_msr, get_user_ckpt_msr(target)); 107 #ifdef CONFIG_PPC64 108 membuf_store(&to_softe, 0x1ul); 109 #endif 110 return membuf_zero(&to, ELF_NGREG * sizeof(unsigned long) - 111 sizeof(struct user_pt_regs)); 112 } 113 114 /* 115 * tm_cgpr_set - set the CGPR registers 116 * @target: The target task. 117 * @regset: The user regset structure. 118 * @pos: The buffer position. 119 * @count: Number of bytes to copy. 120 * @kbuf: Kernel buffer to copy into. 121 * @ubuf: User buffer to copy from. 122 * 123 * This function sets in transaction checkpointed GPR registers. 124 * 125 * When the transaction is active, 'ckpt_regs' holds the checkpointed 126 * GPR register values for the current transaction to fall back on if it 127 * aborts in between. This function sets those checkpointed GPR registers. 128 * The userspace interface buffer layout is as follows. 129 * 130 * struct data { 131 * struct pt_regs ckpt_regs; 132 * }; 133 */ 134 int tm_cgpr_set(struct task_struct *target, const struct user_regset *regset, 135 unsigned int pos, unsigned int count, 136 const void *kbuf, const void __user *ubuf) 137 { 138 unsigned long reg; 139 int ret; 140 141 if (!cpu_has_feature(CPU_FTR_TM)) 142 return -ENODEV; 143 144 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 145 return -ENODATA; 146 147 flush_tmregs_to_thread(target); 148 flush_fp_to_thread(target); 149 flush_altivec_to_thread(target); 150 151 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 152 &target->thread.ckpt_regs, 153 0, PT_MSR * sizeof(reg)); 154 155 if (!ret && count > 0) { 156 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®, 157 PT_MSR * sizeof(reg), 158 (PT_MSR + 1) * sizeof(reg)); 159 if (!ret) 160 ret = set_user_ckpt_msr(target, reg); 161 } 162 163 BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != 164 offsetof(struct pt_regs, msr) + sizeof(long)); 165 166 if (!ret) 167 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 168 &target->thread.ckpt_regs.orig_gpr3, 169 PT_ORIG_R3 * sizeof(reg), 170 (PT_MAX_PUT_REG + 1) * sizeof(reg)); 171 172 if (PT_MAX_PUT_REG + 1 < PT_TRAP && !ret) 173 user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 174 (PT_MAX_PUT_REG + 1) * sizeof(reg), 175 PT_TRAP * sizeof(reg)); 176 177 if (!ret && count > 0) { 178 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®, 179 PT_TRAP * sizeof(reg), 180 (PT_TRAP + 1) * sizeof(reg)); 181 if (!ret) 182 ret = set_user_ckpt_trap(target, reg); 183 } 184 185 if (!ret) 186 user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 187 (PT_TRAP + 1) * sizeof(reg), -1); 188 189 return ret; 190 } 191 192 /** 193 * tm_cfpr_active - get active number of registers in CFPR 194 * @target: The target task. 195 * @regset: The user regset structure. 196 * 197 * This function checks for the active number of available 198 * regisers in transaction checkpointed FPR category. 199 */ 200 int tm_cfpr_active(struct task_struct *target, const struct user_regset *regset) 201 { 202 if (!cpu_has_feature(CPU_FTR_TM)) 203 return -ENODEV; 204 205 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 206 return 0; 207 208 return regset->n; 209 } 210 211 /** 212 * tm_cfpr_get - get CFPR registers 213 * @target: The target task. 214 * @regset: The user regset structure. 215 * @to: Destination of copy. 216 * 217 * This function gets in transaction checkpointed FPR registers. 218 * 219 * When the transaction is active 'ckfp_state' holds the checkpointed 220 * values for the current transaction to fall back on if it aborts 221 * in between. This function gets those checkpointed FPR registers. 222 * The userspace interface buffer layout is as follows. 223 * 224 * struct data { 225 * u64 fpr[32]; 226 * u64 fpscr; 227 *}; 228 */ 229 int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset, 230 struct membuf to) 231 { 232 u64 buf[33]; 233 int i; 234 235 if (!cpu_has_feature(CPU_FTR_TM)) 236 return -ENODEV; 237 238 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 239 return -ENODATA; 240 241 flush_tmregs_to_thread(target); 242 flush_fp_to_thread(target); 243 flush_altivec_to_thread(target); 244 245 /* copy to local buffer then write that out */ 246 for (i = 0; i < 32 ; i++) 247 buf[i] = target->thread.TS_CKFPR(i); 248 buf[32] = target->thread.ckfp_state.fpscr; 249 return membuf_write(&to, buf, sizeof(buf)); 250 } 251 252 /** 253 * tm_cfpr_set - set CFPR registers 254 * @target: The target task. 255 * @regset: The user regset structure. 256 * @pos: The buffer position. 257 * @count: Number of bytes to copy. 258 * @kbuf: Kernel buffer to copy into. 259 * @ubuf: User buffer to copy from. 260 * 261 * This function sets in transaction checkpointed FPR registers. 262 * 263 * When the transaction is active 'ckfp_state' holds the checkpointed 264 * FPR register values for the current transaction to fall back on 265 * if it aborts in between. This function sets these checkpointed 266 * FPR registers. The userspace interface buffer layout is as follows. 267 * 268 * struct data { 269 * u64 fpr[32]; 270 * u64 fpscr; 271 *}; 272 */ 273 int tm_cfpr_set(struct task_struct *target, const struct user_regset *regset, 274 unsigned int pos, unsigned int count, 275 const void *kbuf, const void __user *ubuf) 276 { 277 u64 buf[33]; 278 int i; 279 280 if (!cpu_has_feature(CPU_FTR_TM)) 281 return -ENODEV; 282 283 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 284 return -ENODATA; 285 286 flush_tmregs_to_thread(target); 287 flush_fp_to_thread(target); 288 flush_altivec_to_thread(target); 289 290 for (i = 0; i < 32; i++) 291 buf[i] = target->thread.TS_CKFPR(i); 292 buf[32] = target->thread.ckfp_state.fpscr; 293 294 /* copy to local buffer then write that out */ 295 i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1); 296 if (i) 297 return i; 298 for (i = 0; i < 32 ; i++) 299 target->thread.TS_CKFPR(i) = buf[i]; 300 target->thread.ckfp_state.fpscr = buf[32]; 301 return 0; 302 } 303 304 /** 305 * tm_cvmx_active - get active number of registers in CVMX 306 * @target: The target task. 307 * @regset: The user regset structure. 308 * 309 * This function checks for the active number of available 310 * regisers in checkpointed VMX category. 311 */ 312 int tm_cvmx_active(struct task_struct *target, const struct user_regset *regset) 313 { 314 if (!cpu_has_feature(CPU_FTR_TM)) 315 return -ENODEV; 316 317 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 318 return 0; 319 320 return regset->n; 321 } 322 323 /** 324 * tm_cvmx_get - get CMVX registers 325 * @target: The target task. 326 * @regset: The user regset structure. 327 * @to: Destination of copy. 328 * 329 * This function gets in transaction checkpointed VMX registers. 330 * 331 * When the transaction is active 'ckvr_state' and 'ckvrsave' hold 332 * the checkpointed values for the current transaction to fall 333 * back on if it aborts in between. The userspace interface buffer 334 * layout is as follows. 335 * 336 * struct data { 337 * vector128 vr[32]; 338 * vector128 vscr; 339 * vector128 vrsave; 340 *}; 341 */ 342 int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset, 343 struct membuf to) 344 { 345 union { 346 elf_vrreg_t reg; 347 u32 word; 348 } vrsave; 349 BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32])); 350 351 if (!cpu_has_feature(CPU_FTR_TM)) 352 return -ENODEV; 353 354 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 355 return -ENODATA; 356 357 /* Flush the state */ 358 flush_tmregs_to_thread(target); 359 flush_fp_to_thread(target); 360 flush_altivec_to_thread(target); 361 362 membuf_write(&to, &target->thread.ckvr_state, 33 * sizeof(vector128)); 363 /* 364 * Copy out only the low-order word of vrsave. 365 */ 366 memset(&vrsave, 0, sizeof(vrsave)); 367 vrsave.word = target->thread.ckvrsave; 368 return membuf_write(&to, &vrsave, sizeof(vrsave)); 369 } 370 371 /** 372 * tm_cvmx_set - set CMVX registers 373 * @target: The target task. 374 * @regset: The user regset structure. 375 * @pos: The buffer position. 376 * @count: Number of bytes to copy. 377 * @kbuf: Kernel buffer to copy into. 378 * @ubuf: User buffer to copy from. 379 * 380 * This function sets in transaction checkpointed VMX registers. 381 * 382 * When the transaction is active 'ckvr_state' and 'ckvrsave' hold 383 * the checkpointed values for the current transaction to fall 384 * back on if it aborts in between. The userspace interface buffer 385 * layout is as follows. 386 * 387 * struct data { 388 * vector128 vr[32]; 389 * vector128 vscr; 390 * vector128 vrsave; 391 *}; 392 */ 393 int tm_cvmx_set(struct task_struct *target, const struct user_regset *regset, 394 unsigned int pos, unsigned int count, 395 const void *kbuf, const void __user *ubuf) 396 { 397 int ret; 398 399 BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32])); 400 401 if (!cpu_has_feature(CPU_FTR_TM)) 402 return -ENODEV; 403 404 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 405 return -ENODATA; 406 407 flush_tmregs_to_thread(target); 408 flush_fp_to_thread(target); 409 flush_altivec_to_thread(target); 410 411 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &target->thread.ckvr_state, 412 0, 33 * sizeof(vector128)); 413 if (!ret && count > 0) { 414 /* 415 * We use only the low-order word of vrsave. 416 */ 417 union { 418 elf_vrreg_t reg; 419 u32 word; 420 } vrsave; 421 memset(&vrsave, 0, sizeof(vrsave)); 422 vrsave.word = target->thread.ckvrsave; 423 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave, 424 33 * sizeof(vector128), -1); 425 if (!ret) 426 target->thread.ckvrsave = vrsave.word; 427 } 428 429 return ret; 430 } 431 432 /** 433 * tm_cvsx_active - get active number of registers in CVSX 434 * @target: The target task. 435 * @regset: The user regset structure. 436 * 437 * This function checks for the active number of available 438 * regisers in transaction checkpointed VSX category. 439 */ 440 int tm_cvsx_active(struct task_struct *target, const struct user_regset *regset) 441 { 442 if (!cpu_has_feature(CPU_FTR_TM)) 443 return -ENODEV; 444 445 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 446 return 0; 447 448 flush_vsx_to_thread(target); 449 return target->thread.used_vsr ? regset->n : 0; 450 } 451 452 /** 453 * tm_cvsx_get - get CVSX registers 454 * @target: The target task. 455 * @regset: The user regset structure. 456 * @to: Destination of copy. 457 * 458 * This function gets in transaction checkpointed VSX registers. 459 * 460 * When the transaction is active 'ckfp_state' holds the checkpointed 461 * values for the current transaction to fall back on if it aborts 462 * in between. This function gets those checkpointed VSX registers. 463 * The userspace interface buffer layout is as follows. 464 * 465 * struct data { 466 * u64 vsx[32]; 467 *}; 468 */ 469 int tm_cvsx_get(struct task_struct *target, const struct user_regset *regset, 470 struct membuf to) 471 { 472 u64 buf[32]; 473 int i; 474 475 if (!cpu_has_feature(CPU_FTR_TM)) 476 return -ENODEV; 477 478 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 479 return -ENODATA; 480 481 /* Flush the state */ 482 flush_tmregs_to_thread(target); 483 flush_fp_to_thread(target); 484 flush_altivec_to_thread(target); 485 flush_vsx_to_thread(target); 486 487 for (i = 0; i < 32 ; i++) 488 buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET]; 489 return membuf_write(&to, buf, 32 * sizeof(double)); 490 } 491 492 /** 493 * tm_cvsx_set - set CFPR registers 494 * @target: The target task. 495 * @regset: The user regset structure. 496 * @pos: The buffer position. 497 * @count: Number of bytes to copy. 498 * @kbuf: Kernel buffer to copy into. 499 * @ubuf: User buffer to copy from. 500 * 501 * This function sets in transaction checkpointed VSX registers. 502 * 503 * When the transaction is active 'ckfp_state' holds the checkpointed 504 * VSX register values for the current transaction to fall back on 505 * if it aborts in between. This function sets these checkpointed 506 * FPR registers. The userspace interface buffer layout is as follows. 507 * 508 * struct data { 509 * u64 vsx[32]; 510 *}; 511 */ 512 int tm_cvsx_set(struct task_struct *target, const struct user_regset *regset, 513 unsigned int pos, unsigned int count, 514 const void *kbuf, const void __user *ubuf) 515 { 516 u64 buf[32]; 517 int ret, i; 518 519 if (!cpu_has_feature(CPU_FTR_TM)) 520 return -ENODEV; 521 522 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 523 return -ENODATA; 524 525 /* Flush the state */ 526 flush_tmregs_to_thread(target); 527 flush_fp_to_thread(target); 528 flush_altivec_to_thread(target); 529 flush_vsx_to_thread(target); 530 531 for (i = 0; i < 32 ; i++) 532 buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET]; 533 534 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 535 buf, 0, 32 * sizeof(double)); 536 if (!ret) 537 for (i = 0; i < 32 ; i++) 538 target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i]; 539 540 return ret; 541 } 542 543 /** 544 * tm_spr_active - get active number of registers in TM SPR 545 * @target: The target task. 546 * @regset: The user regset structure. 547 * 548 * This function checks the active number of available 549 * regisers in the transactional memory SPR category. 550 */ 551 int tm_spr_active(struct task_struct *target, const struct user_regset *regset) 552 { 553 if (!cpu_has_feature(CPU_FTR_TM)) 554 return -ENODEV; 555 556 return regset->n; 557 } 558 559 /** 560 * tm_spr_get - get the TM related SPR registers 561 * @target: The target task. 562 * @regset: The user regset structure. 563 * @to: Destination of copy. 564 * 565 * This function gets transactional memory related SPR registers. 566 * The userspace interface buffer layout is as follows. 567 * 568 * struct { 569 * u64 tm_tfhar; 570 * u64 tm_texasr; 571 * u64 tm_tfiar; 572 * }; 573 */ 574 int tm_spr_get(struct task_struct *target, const struct user_regset *regset, 575 struct membuf to) 576 { 577 /* Build tests */ 578 BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr)); 579 BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar)); 580 BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(ckpt_regs)); 581 582 if (!cpu_has_feature(CPU_FTR_TM)) 583 return -ENODEV; 584 585 /* Flush the states */ 586 flush_tmregs_to_thread(target); 587 flush_fp_to_thread(target); 588 flush_altivec_to_thread(target); 589 590 /* TFHAR register */ 591 membuf_write(&to, &target->thread.tm_tfhar, sizeof(u64)); 592 /* TEXASR register */ 593 membuf_write(&to, &target->thread.tm_texasr, sizeof(u64)); 594 /* TFIAR register */ 595 return membuf_write(&to, &target->thread.tm_tfiar, sizeof(u64)); 596 } 597 598 /** 599 * tm_spr_set - set the TM related SPR registers 600 * @target: The target task. 601 * @regset: The user regset structure. 602 * @pos: The buffer position. 603 * @count: Number of bytes to copy. 604 * @kbuf: Kernel buffer to copy into. 605 * @ubuf: User buffer to copy from. 606 * 607 * This function sets transactional memory related SPR registers. 608 * The userspace interface buffer layout is as follows. 609 * 610 * struct { 611 * u64 tm_tfhar; 612 * u64 tm_texasr; 613 * u64 tm_tfiar; 614 * }; 615 */ 616 int tm_spr_set(struct task_struct *target, const struct user_regset *regset, 617 unsigned int pos, unsigned int count, 618 const void *kbuf, const void __user *ubuf) 619 { 620 int ret; 621 622 /* Build tests */ 623 BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr)); 624 BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar)); 625 BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(ckpt_regs)); 626 627 if (!cpu_has_feature(CPU_FTR_TM)) 628 return -ENODEV; 629 630 /* Flush the states */ 631 flush_tmregs_to_thread(target); 632 flush_fp_to_thread(target); 633 flush_altivec_to_thread(target); 634 635 /* TFHAR register */ 636 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 637 &target->thread.tm_tfhar, 0, sizeof(u64)); 638 639 /* TEXASR register */ 640 if (!ret) 641 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 642 &target->thread.tm_texasr, sizeof(u64), 643 2 * sizeof(u64)); 644 645 /* TFIAR register */ 646 if (!ret) 647 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 648 &target->thread.tm_tfiar, 649 2 * sizeof(u64), 3 * sizeof(u64)); 650 return ret; 651 } 652 653 int tm_tar_active(struct task_struct *target, const struct user_regset *regset) 654 { 655 if (!cpu_has_feature(CPU_FTR_TM)) 656 return -ENODEV; 657 658 if (MSR_TM_ACTIVE(target->thread.regs->msr)) 659 return regset->n; 660 661 return 0; 662 } 663 664 int tm_tar_get(struct task_struct *target, const struct user_regset *regset, 665 struct membuf to) 666 { 667 if (!cpu_has_feature(CPU_FTR_TM)) 668 return -ENODEV; 669 670 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 671 return -ENODATA; 672 673 return membuf_write(&to, &target->thread.tm_tar, sizeof(u64)); 674 } 675 676 int tm_tar_set(struct task_struct *target, const struct user_regset *regset, 677 unsigned int pos, unsigned int count, 678 const void *kbuf, const void __user *ubuf) 679 { 680 int ret; 681 682 if (!cpu_has_feature(CPU_FTR_TM)) 683 return -ENODEV; 684 685 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 686 return -ENODATA; 687 688 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 689 &target->thread.tm_tar, 0, sizeof(u64)); 690 return ret; 691 } 692 693 int tm_ppr_active(struct task_struct *target, const struct user_regset *regset) 694 { 695 if (!cpu_has_feature(CPU_FTR_TM)) 696 return -ENODEV; 697 698 if (MSR_TM_ACTIVE(target->thread.regs->msr)) 699 return regset->n; 700 701 return 0; 702 } 703 704 705 int tm_ppr_get(struct task_struct *target, const struct user_regset *regset, 706 struct membuf to) 707 { 708 if (!cpu_has_feature(CPU_FTR_TM)) 709 return -ENODEV; 710 711 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 712 return -ENODATA; 713 714 return membuf_write(&to, &target->thread.tm_ppr, sizeof(u64)); 715 } 716 717 int tm_ppr_set(struct task_struct *target, const struct user_regset *regset, 718 unsigned int pos, unsigned int count, 719 const void *kbuf, const void __user *ubuf) 720 { 721 int ret; 722 723 if (!cpu_has_feature(CPU_FTR_TM)) 724 return -ENODEV; 725 726 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 727 return -ENODATA; 728 729 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 730 &target->thread.tm_ppr, 0, sizeof(u64)); 731 return ret; 732 } 733 734 int tm_dscr_active(struct task_struct *target, const struct user_regset *regset) 735 { 736 if (!cpu_has_feature(CPU_FTR_TM)) 737 return -ENODEV; 738 739 if (MSR_TM_ACTIVE(target->thread.regs->msr)) 740 return regset->n; 741 742 return 0; 743 } 744 745 int tm_dscr_get(struct task_struct *target, const struct user_regset *regset, 746 struct membuf to) 747 { 748 if (!cpu_has_feature(CPU_FTR_TM)) 749 return -ENODEV; 750 751 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 752 return -ENODATA; 753 754 return membuf_write(&to, &target->thread.tm_dscr, sizeof(u64)); 755 } 756 757 int tm_dscr_set(struct task_struct *target, const struct user_regset *regset, 758 unsigned int pos, unsigned int count, 759 const void *kbuf, const void __user *ubuf) 760 { 761 int ret; 762 763 if (!cpu_has_feature(CPU_FTR_TM)) 764 return -ENODEV; 765 766 if (!MSR_TM_ACTIVE(target->thread.regs->msr)) 767 return -ENODATA; 768 769 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 770 &target->thread.tm_dscr, 0, sizeof(u64)); 771 return ret; 772 } 773 774 int tm_cgpr32_get(struct task_struct *target, const struct user_regset *regset, 775 struct membuf to) 776 { 777 gpr32_get_common(target, regset, to, 778 &target->thread.ckpt_regs.gpr[0]); 779 return membuf_zero(&to, ELF_NGREG * sizeof(u32)); 780 } 781 782 int tm_cgpr32_set(struct task_struct *target, const struct user_regset *regset, 783 unsigned int pos, unsigned int count, 784 const void *kbuf, const void __user *ubuf) 785 { 786 return gpr32_set_common(target, regset, pos, count, kbuf, ubuf, 787 &target->thread.ckpt_regs.gpr[0]); 788 } 789
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.