linux/arch/powerpc/kernel/ptrace/ptrace-tm.c
<<
>>
Prefs
   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
  11void flush_tmregs_to_thread(struct task_struct *tsk)
  12{
  13        /*
  14         * If task is not current, it will have been flushed already to
  15         * it's 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
  32static unsigned long get_user_ckpt_msr(struct task_struct *task)
  33{
  34        return task->thread.ckpt_regs.msr | task->thread.fpexc_mode;
  35}
  36
  37static 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
  44static 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 */
  58int 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 */
  86int 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 */
 134int 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, &reg,
 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                ret = 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, &reg,
 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                ret = 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 */
 200int 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 */
 229int 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 */
 273int 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 */
 312int 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 */
 342int 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 */
 393int 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 */
 440int 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 */
 469int 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 */
 512int 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 */
 551int 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 */
 574int 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 */
 616int 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
 653int 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
 664int 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
 676int 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
 693int 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
 705int 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
 717int 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
 734int 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
 745int 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
 757int 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
 774int 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
 782int 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