linux/arch/powerpc/kernel/tm.S
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * Transactional memory support routines to reclaim and recheckpoint
   4 * transactional process state.
   5 *
   6 * Copyright 2012 Matt Evans & Michael Neuling, IBM Corporation.
   7 */
   8
   9#include <asm/asm-offsets.h>
  10#include <asm/ppc_asm.h>
  11#include <asm/ppc-opcode.h>
  12#include <asm/ptrace.h>
  13#include <asm/reg.h>
  14#include <asm/bug.h>
  15#include <asm/export.h>
  16#include <asm/feature-fixups.h>
  17
  18#ifdef CONFIG_VSX
  19/* See fpu.S, this is borrowed from there */
  20#define __SAVE_32FPRS_VSRS(n,c,base)            \
  21BEGIN_FTR_SECTION                               \
  22        b       2f;                             \
  23END_FTR_SECTION_IFSET(CPU_FTR_VSX);             \
  24        SAVE_32FPRS(n,base);                    \
  25        b       3f;                             \
  262:      SAVE_32VSRS(n,c,base);                  \
  273:
  28#define __REST_32FPRS_VSRS(n,c,base)            \
  29BEGIN_FTR_SECTION                               \
  30        b       2f;                             \
  31END_FTR_SECTION_IFSET(CPU_FTR_VSX);             \
  32        REST_32FPRS(n,base);                    \
  33        b       3f;                             \
  342:      REST_32VSRS(n,c,base);                  \
  353:
  36#else
  37#define __SAVE_32FPRS_VSRS(n,c,base)    SAVE_32FPRS(n, base)
  38#define __REST_32FPRS_VSRS(n,c,base)    REST_32FPRS(n, base)
  39#endif
  40#define SAVE_32FPRS_VSRS(n,c,base) \
  41        __SAVE_32FPRS_VSRS(n,__REG_##c,__REG_##base)
  42#define REST_32FPRS_VSRS(n,c,base) \
  43        __REST_32FPRS_VSRS(n,__REG_##c,__REG_##base)
  44
  45/* Stack frame offsets for local variables. */
  46#define TM_FRAME_L0     TM_FRAME_SIZE-16
  47#define TM_FRAME_L1     TM_FRAME_SIZE-8
  48
  49
  50/* In order to access the TM SPRs, TM must be enabled.  So, do so: */
  51_GLOBAL(tm_enable)
  52        mfmsr   r4
  53        li      r3, MSR_TM >> 32
  54        sldi    r3, r3, 32
  55        and.    r0, r4, r3
  56        bne     1f
  57        or      r4, r4, r3
  58        mtmsrd  r4
  591:      blr
  60EXPORT_SYMBOL_GPL(tm_enable);
  61
  62_GLOBAL(tm_disable)
  63        mfmsr   r4
  64        li      r3, MSR_TM >> 32
  65        sldi    r3, r3, 32
  66        andc    r4, r4, r3
  67        mtmsrd  r4
  68        blr
  69EXPORT_SYMBOL_GPL(tm_disable);
  70
  71_GLOBAL(tm_save_sprs)
  72        mfspr   r0, SPRN_TFHAR
  73        std     r0, THREAD_TM_TFHAR(r3)
  74        mfspr   r0, SPRN_TEXASR
  75        std     r0, THREAD_TM_TEXASR(r3)
  76        mfspr   r0, SPRN_TFIAR
  77        std     r0, THREAD_TM_TFIAR(r3)
  78        blr
  79
  80_GLOBAL(tm_restore_sprs)
  81        ld      r0, THREAD_TM_TFHAR(r3)
  82        mtspr   SPRN_TFHAR, r0
  83        ld      r0, THREAD_TM_TEXASR(r3)
  84        mtspr   SPRN_TEXASR, r0
  85        ld      r0, THREAD_TM_TFIAR(r3)
  86        mtspr   SPRN_TFIAR, r0
  87        blr
  88
  89        /* Passed an 8-bit failure cause as first argument. */
  90_GLOBAL(tm_abort)
  91        TABORT(R3)
  92        blr
  93EXPORT_SYMBOL_GPL(tm_abort);
  94
  95/*
  96 * void tm_reclaim(struct thread_struct *thread,
  97 *                 uint8_t cause)
  98 *
  99 *      - Performs a full reclaim.  This destroys outstanding
 100 *        transactions and updates thread.ckpt_regs, thread.ckfp_state and
 101 *        thread.ckvr_state with the original checkpointed state.  Note that
 102 *        thread->regs is unchanged.
 103 *
 104 * Purpose is to both abort transactions of, and preserve the state of,
 105 * a transactions at a context switch. We preserve/restore both sets of process
 106 * state to restore them when the thread's scheduled again.  We continue in
 107 * userland as though nothing happened, but when the transaction is resumed
 108 * they will abort back to the checkpointed state we save out here.
 109 *
 110 * Call with IRQs off, stacks get all out of sync for some periods in here!
 111 */
 112_GLOBAL(tm_reclaim)
 113        mfcr    r5
 114        mflr    r0
 115        stw     r5, 8(r1)
 116        std     r0, 16(r1)
 117        std     r2, STK_GOT(r1)
 118        stdu    r1, -TM_FRAME_SIZE(r1)
 119
 120        /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD]. */
 121
 122        std     r3, STK_PARAM(R3)(r1)
 123        SAVE_NVGPRS(r1)
 124
 125        /* We need to setup MSR for VSX register save instructions. */
 126        mfmsr   r14
 127        mr      r15, r14
 128        ori     r15, r15, MSR_FP
 129        li      r16, 0
 130        ori     r16, r16, MSR_EE /* IRQs hard off */
 131        andc    r15, r15, r16
 132        oris    r15, r15, MSR_VEC@h
 133#ifdef CONFIG_VSX
 134        BEGIN_FTR_SECTION
 135        oris    r15,r15, MSR_VSX@h
 136        END_FTR_SECTION_IFSET(CPU_FTR_VSX)
 137#endif
 138        mtmsrd  r15
 139        std     r14, TM_FRAME_L0(r1)
 140
 141        /* Do sanity check on MSR to make sure we are suspended */
 142        li      r7, (MSR_TS_S)@higher
 143        srdi    r6, r14, 32
 144        and     r6, r6, r7
 1451:      tdeqi   r6, 0
 146        EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0
 147
 148        /* Stash the stack pointer away for use after reclaim */
 149        std     r1, PACAR1(r13)
 150
 151        /* Clear MSR RI since we are about to use SCRATCH0, EE is already off */
 152        li      r5, 0
 153        mtmsrd  r5, 1
 154
 155        /*
 156         * BE CAREFUL HERE:
 157         * At this point we can't take an SLB miss since we have MSR_RI
 158         * off. Load only to/from the stack/paca which are in SLB bolted regions
 159         * until we turn MSR RI back on.
 160         *
 161         * The moment we treclaim, ALL of our GPRs will switch
 162         * to user register state.  (FPRs, CCR etc. also!)
 163         * Use an sprg and a tm_scratch in the PACA to shuffle.
 164         */
 165        TRECLAIM(R4)                            /* Cause in r4 */
 166
 167        /*
 168         * ******************** GPRs ********************
 169         * Stash the checkpointed r13 in the scratch SPR and get the real paca.
 170         */
 171        SET_SCRATCH0(r13)
 172        GET_PACA(r13)
 173
 174        /*
 175         * Stash the checkpointed r1 away in paca->tm_scratch and get the real
 176         * stack pointer back into r1.
 177         */
 178        std     r1, PACATMSCRATCH(r13)
 179        ld      r1, PACAR1(r13)
 180
 181        std     r11, GPR11(r1)                  /* Temporary stash */
 182
 183        /*
 184         * Move the saved user r1 to the kernel stack in case PACATMSCRATCH is
 185         * clobbered by an exception once we turn on MSR_RI below.
 186         */
 187        ld      r11, PACATMSCRATCH(r13)
 188        std     r11, GPR1(r1)
 189
 190        /*
 191         * Store r13 away so we can free up the scratch SPR for the SLB fault
 192         * handler (needed once we start accessing the thread_struct).
 193         */
 194        GET_SCRATCH0(r11)
 195        std     r11, GPR13(r1)
 196
 197        /* Reset MSR RI so we can take SLB faults again */
 198        li      r11, MSR_RI
 199        mtmsrd  r11, 1
 200
 201        /* Store the PPR in r11 and reset to decent value */
 202        mfspr   r11, SPRN_PPR
 203        HMT_MEDIUM
 204
 205        /* Now get some more GPRS free */
 206        std     r7, GPR7(r1)                    /* Temporary stash */
 207        std     r12, GPR12(r1)                  /* ''   ''    ''   */
 208        ld      r12, STK_PARAM(R3)(r1)          /* Param 0, thread_struct * */
 209
 210        std     r11, THREAD_TM_PPR(r12)         /* Store PPR and free r11 */
 211
 212        addi    r7, r12, PT_CKPT_REGS           /* Thread's ckpt_regs */
 213
 214        /*
 215         * Make r7 look like an exception frame so that we can use the neat
 216         * GPRx(n) macros. r7 is NOT a pt_regs ptr!
 217         */
 218        subi    r7, r7, STACK_FRAME_OVERHEAD
 219
 220        /* Sync the userland GPRs 2-12, 14-31 to thread->regs: */
 221        SAVE_GPR(0, r7)                         /* user r0 */
 222        SAVE_GPR(2, r7)                         /* user r2 */
 223        SAVE_4GPRS(3, r7)                       /* user r3-r6 */
 224        SAVE_GPR(8, r7)                         /* user r8 */
 225        SAVE_GPR(9, r7)                         /* user r9 */
 226        SAVE_GPR(10, r7)                        /* user r10 */
 227        ld      r3, GPR1(r1)                    /* user r1 */
 228        ld      r4, GPR7(r1)                    /* user r7 */
 229        ld      r5, GPR11(r1)                   /* user r11 */
 230        ld      r6, GPR12(r1)                   /* user r12 */
 231        ld      r8, GPR13(r1)                   /* user r13 */
 232        std     r3, GPR1(r7)
 233        std     r4, GPR7(r7)
 234        std     r5, GPR11(r7)
 235        std     r6, GPR12(r7)
 236        std     r8, GPR13(r7)
 237
 238        SAVE_NVGPRS(r7)                         /* user r14-r31 */
 239
 240        /* ******************** NIP ******************** */
 241        mfspr   r3, SPRN_TFHAR
 242        std     r3, _NIP(r7)                    /* Returns to failhandler */
 243        /*
 244         * The checkpointed NIP is ignored when rescheduling/rechkpting,
 245         * but is used in signal return to 'wind back' to the abort handler.
 246         */
 247
 248        /* ******************** CR,LR,CCR,MSR ********** */
 249        mfctr   r3
 250        mflr    r4
 251        mfcr    r5
 252        mfxer   r6
 253
 254        std     r3, _CTR(r7)
 255        std     r4, _LINK(r7)
 256        std     r5, _CCR(r7)
 257        std     r6, _XER(r7)
 258
 259
 260        /* ******************** TAR, DSCR ********** */
 261        mfspr   r3, SPRN_TAR
 262        mfspr   r4, SPRN_DSCR
 263
 264        std     r3, THREAD_TM_TAR(r12)
 265        std     r4, THREAD_TM_DSCR(r12)
 266
 267        /*
 268         * MSR and flags: We don't change CRs, and we don't need to alter MSR.
 269         */
 270
 271
 272        /*
 273         * ******************** FPR/VR/VSRs ************
 274         * After reclaiming, capture the checkpointed FPRs/VRs.
 275         *
 276         * We enabled VEC/FP/VSX in the msr above, so we can execute these
 277         * instructions!
 278         */
 279        mr      r3, r12
 280
 281        /* Altivec (VEC/VMX/VR)*/
 282        addi    r7, r3, THREAD_CKVRSTATE
 283        SAVE_32VRS(0, r6, r7)   /* r6 scratch, r7 ckvr_state */
 284        mfvscr  v0
 285        li      r6, VRSTATE_VSCR
 286        stvx    v0, r7, r6
 287
 288        /* VRSAVE */
 289        mfspr   r0, SPRN_VRSAVE
 290        std     r0, THREAD_CKVRSAVE(r3)
 291
 292        /* Floating Point (FP) */
 293        addi    r7, r3, THREAD_CKFPSTATE
 294        SAVE_32FPRS_VSRS(0, R6, R7)     /* r6 scratch, r7 ckfp_state */
 295        mffs    fr0
 296        stfd    fr0,FPSTATE_FPSCR(r7)
 297
 298
 299        /*
 300         * TM regs, incl TEXASR -- these live in thread_struct.  Note they've
 301         * been updated by the treclaim, to explain to userland the failure
 302         * cause (aborted).
 303         */
 304        mfspr   r0, SPRN_TEXASR
 305        mfspr   r3, SPRN_TFHAR
 306        mfspr   r4, SPRN_TFIAR
 307        std     r0, THREAD_TM_TEXASR(r12)
 308        std     r3, THREAD_TM_TFHAR(r12)
 309        std     r4, THREAD_TM_TFIAR(r12)
 310
 311        /* AMR is checkpointed too, but is unsupported by Linux. */
 312
 313        /* Restore original MSR/IRQ state & clear TM mode */
 314        ld      r14, TM_FRAME_L0(r1)            /* Orig MSR */
 315
 316        li      r15, 0
 317        rldimi  r14, r15, MSR_TS_LG, (63-MSR_TS_LG)-1
 318        mtmsrd  r14
 319
 320        REST_NVGPRS(r1)
 321
 322        addi    r1, r1, TM_FRAME_SIZE
 323        lwz     r4, 8(r1)
 324        ld      r0, 16(r1)
 325        mtcr    r4
 326        mtlr    r0
 327        ld      r2, STK_GOT(r1)
 328
 329        /* Load CPU's default DSCR */
 330        ld      r0, PACA_DSCR_DEFAULT(r13)
 331        mtspr   SPRN_DSCR, r0
 332
 333        blr
 334
 335
 336        /*
 337         * void __tm_recheckpoint(struct thread_struct *thread)
 338         *      - Restore the checkpointed register state saved by tm_reclaim
 339         *        when we switch_to a process.
 340         *
 341         *      Call with IRQs off, stacks get all out of sync for
 342         *      some periods in here!
 343         */
 344_GLOBAL(__tm_recheckpoint)
 345        mfcr    r5
 346        mflr    r0
 347        stw     r5, 8(r1)
 348        std     r0, 16(r1)
 349        std     r2, STK_GOT(r1)
 350        stdu    r1, -TM_FRAME_SIZE(r1)
 351
 352        /*
 353         * We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD].
 354         * This is used for backing up the NVGPRs:
 355         */
 356        SAVE_NVGPRS(r1)
 357
 358        /* Load complete register state from ts_ckpt* registers */
 359
 360        addi    r7, r3, PT_CKPT_REGS            /* Thread's ckpt_regs */
 361
 362        /*
 363         * Make r7 look like an exception frame so that we can use the neat
 364         * GPRx(n) macros. r7 is now NOT a pt_regs ptr!
 365         */
 366        subi    r7, r7, STACK_FRAME_OVERHEAD
 367
 368        /* We need to setup MSR for FP/VMX/VSX register save instructions. */
 369        mfmsr   r6
 370        mr      r5, r6
 371        ori     r5, r5, MSR_FP
 372#ifdef CONFIG_ALTIVEC
 373        oris    r5, r5, MSR_VEC@h
 374#endif
 375#ifdef CONFIG_VSX
 376        BEGIN_FTR_SECTION
 377        oris    r5,r5, MSR_VSX@h
 378        END_FTR_SECTION_IFSET(CPU_FTR_VSX)
 379#endif
 380        mtmsrd  r5
 381
 382#ifdef CONFIG_ALTIVEC
 383        /*
 384         * FP and VEC registers: These are recheckpointed from
 385         * thread.ckfp_state and thread.ckvr_state respectively. The
 386         * thread.fp_state[] version holds the 'live' (transactional)
 387         * and will be loaded subsequently by any FPUnavailable trap.
 388         */
 389        addi    r8, r3, THREAD_CKVRSTATE
 390        li      r5, VRSTATE_VSCR
 391        lvx     v0, r8, r5
 392        mtvscr  v0
 393        REST_32VRS(0, r5, r8)                   /* r5 scratch, r8 ptr */
 394        ld      r5, THREAD_CKVRSAVE(r3)
 395        mtspr   SPRN_VRSAVE, r5
 396#endif
 397
 398        addi    r8, r3, THREAD_CKFPSTATE
 399        lfd     fr0, FPSTATE_FPSCR(r8)
 400        MTFSF_L(fr0)
 401        REST_32FPRS_VSRS(0, R4, R8)
 402
 403        mtmsr   r6                              /* FP/Vec off again! */
 404
 405restore_gprs:
 406
 407        /* ******************** CR,LR,CCR,MSR ********** */
 408        ld      r4, _CTR(r7)
 409        ld      r5, _LINK(r7)
 410        ld      r8, _XER(r7)
 411
 412        mtctr   r4
 413        mtlr    r5
 414        mtxer   r8
 415
 416        /* ******************** TAR ******************** */
 417        ld      r4, THREAD_TM_TAR(r3)
 418        mtspr   SPRN_TAR,       r4
 419
 420        /* Load up the PPR and DSCR in GPRs only at this stage */
 421        ld      r5, THREAD_TM_DSCR(r3)
 422        ld      r6, THREAD_TM_PPR(r3)
 423
 424        REST_GPR(0, r7)                         /* GPR0 */
 425        REST_2GPRS(2, r7)                       /* GPR2-3 */
 426        REST_GPR(4, r7)                         /* GPR4 */
 427        REST_4GPRS(8, r7)                       /* GPR8-11 */
 428        REST_2GPRS(12, r7)                      /* GPR12-13 */
 429
 430        REST_NVGPRS(r7)                         /* GPR14-31 */
 431
 432        /* Load up PPR and DSCR here so we don't run with user values for long */
 433        mtspr   SPRN_DSCR, r5
 434        mtspr   SPRN_PPR, r6
 435
 436        /*
 437         * Do final sanity check on TEXASR to make sure FS is set. Do this
 438         * here before we load up the userspace r1 so any bugs we hit will get
 439         * a call chain.
 440         */
 441        mfspr   r5, SPRN_TEXASR
 442        srdi    r5, r5, 16
 443        li      r6, (TEXASR_FS)@h
 444        and     r6, r6, r5
 4451:      tdeqi   r6, 0
 446        EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0
 447
 448        /*
 449         * Do final sanity check on MSR to make sure we are not transactional
 450         * or suspended.
 451         */
 452        mfmsr   r6
 453        li      r5, (MSR_TS_MASK)@higher
 454        srdi    r6, r6, 32
 455        and     r6, r6, r5
 4561:      tdnei   r6, 0
 457        EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0
 458
 459        /* Restore CR */
 460        ld      r6, _CCR(r7)
 461        mtcr    r6
 462
 463        REST_GPR(6, r7)
 464
 465        /*
 466         * Store r1 and r5 on the stack so that we can access them after we
 467         * clear MSR RI.
 468         */
 469
 470        REST_GPR(5, r7)
 471        std     r5, -8(r1)
 472        ld      r5, GPR1(r7)
 473        std     r5, -16(r1)
 474
 475        REST_GPR(7, r7)
 476
 477        /* Clear MSR RI since we are about to use SCRATCH0. EE is already off */
 478        li      r5, 0
 479        mtmsrd  r5, 1
 480
 481        /*
 482         * BE CAREFUL HERE:
 483         * At this point we can't take an SLB miss since we have MSR_RI
 484         * off. Load only to/from the stack/paca which are in SLB bolted regions
 485         * until we turn MSR RI back on.
 486         */
 487
 488        SET_SCRATCH0(r1)
 489        ld      r5, -8(r1)
 490        ld      r1, -16(r1)
 491
 492        /* Commit register state as checkpointed state: */
 493        TRECHKPT
 494
 495        HMT_MEDIUM
 496
 497        /*
 498         * Our transactional state has now changed.
 499         *
 500         * Now just get out of here.  Transactional (current) state will be
 501         * updated once restore is called on the return path in the _switch-ed
 502         * -to process.
 503         */
 504
 505        GET_PACA(r13)
 506        GET_SCRATCH0(r1)
 507
 508        /* R1 is restored, so we are recoverable again.  EE is still off */
 509        li      r4, MSR_RI
 510        mtmsrd  r4, 1
 511
 512        REST_NVGPRS(r1)
 513
 514        addi    r1, r1, TM_FRAME_SIZE
 515        lwz     r4, 8(r1)
 516        ld      r0, 16(r1)
 517        mtcr    r4
 518        mtlr    r0
 519        ld      r2, STK_GOT(r1)
 520
 521        /* Load CPU's default DSCR */
 522        ld      r0, PACA_DSCR_DEFAULT(r13)
 523        mtspr   SPRN_DSCR, r0
 524
 525        blr
 526
 527        /* ****************************************************************** */
 528