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