root/arch/sparc/kernel/etrap_64.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 /*
   3  * etrap.S: Preparing for entry into the kernel on Sparc V9.
   4  *
   5  * Copyright (C) 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
   6  * Copyright (C) 1997, 1998, 1999 Jakub Jelinek (jj@ultra.linux.cz)
   7  */
   8 
   9 
  10 #include <asm/asi.h>
  11 #include <asm/pstate.h>
  12 #include <asm/ptrace.h>
  13 #include <asm/page.h>
  14 #include <asm/spitfire.h>
  15 #include <asm/head.h>
  16 #include <asm/processor.h>
  17 #include <asm/mmu.h>
  18 
  19 #define         TASK_REGOFF             (THREAD_SIZE-TRACEREG_SZ-STACKFRAME_SZ)
  20 #define         ETRAP_PSTATE1           (PSTATE_TSO | PSTATE_PRIV)
  21 #define         ETRAP_PSTATE2           \
  22                 (PSTATE_TSO | PSTATE_PEF | PSTATE_PRIV | PSTATE_IE)
  23 
  24 /*
  25  * On entry, %g7 is return address - 0x4.
  26  * %g4 and %g5 will be preserved %l4 and %l5 respectively.
  27  */
  28 
  29                 .text           
  30                 .align  64
  31                 .globl  etrap_syscall, etrap, etrap_irq, etraptl1
  32 etrap:          rdpr    %pil, %g2
  33 etrap_irq:      clr     %g3
  34 etrap_syscall:  TRAP_LOAD_THREAD_REG(%g6, %g1)
  35                 rdpr    %tstate, %g1
  36                 or      %g1, %g3, %g1
  37                 sllx    %g2, 20, %g3
  38                 andcc   %g1, TSTATE_PRIV, %g0
  39                 or      %g1, %g3, %g1
  40                 bne,pn  %xcc, 1f
  41                  sub    %sp, STACKFRAME_SZ+TRACEREG_SZ-STACK_BIAS, %g2
  42 661:            wrpr    %g0, 7, %cleanwin
  43                 .section .fast_win_ctrl_1insn_patch, "ax"
  44                 .word   661b
  45                 .word   0x85880000      ! allclean
  46                 .previous
  47 
  48                 sethi   %hi(TASK_REGOFF), %g2
  49                 sethi   %hi(TSTATE_PEF), %g3
  50                 or      %g2, %lo(TASK_REGOFF), %g2
  51                 and     %g1, %g3, %g3
  52                 brnz,pn %g3, 1f
  53                  add    %g6, %g2, %g2
  54                 wr      %g0, 0, %fprs
  55 1:              rdpr    %tpc, %g3
  56 
  57                 stx     %g1, [%g2 + STACKFRAME_SZ + PT_V9_TSTATE]
  58                 rdpr    %tnpc, %g1
  59                 stx     %g3, [%g2 + STACKFRAME_SZ + PT_V9_TPC]
  60                 rd      %y, %g3
  61                 stx     %g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC]
  62                 rdpr    %tt, %g1
  63                 st      %g3, [%g2 + STACKFRAME_SZ + PT_V9_Y]
  64                 sethi   %hi(PT_REGS_MAGIC), %g3
  65                 or      %g3, %g1, %g1
  66                 st      %g1, [%g2 + STACKFRAME_SZ + PT_V9_MAGIC]
  67 
  68                 rdpr    %cansave, %g1
  69                 brnz,pt %g1, etrap_save
  70                  nop
  71 
  72                 rdpr    %cwp, %g1
  73                 add     %g1, 2, %g1
  74                 wrpr    %g1, %cwp
  75                 be,pt   %xcc, etrap_user_spill
  76                  mov    ASI_AIUP, %g3
  77 
  78                 rdpr    %otherwin, %g3
  79                 brz     %g3, etrap_kernel_spill
  80                  mov    ASI_AIUS, %g3
  81 
  82 etrap_user_spill:
  83 
  84                 wr      %g3, 0x0, %asi
  85                 ldx     [%g6 + TI_FLAGS], %g3
  86                 and     %g3, _TIF_32BIT, %g3
  87                 brnz,pt %g3, etrap_user_spill_32bit
  88                  nop
  89                 ba,a,pt %xcc, etrap_user_spill_64bit
  90 
  91 etrap_save:     save    %g2, -STACK_BIAS, %sp
  92                 mov     %g6, %l6
  93 
  94                 bne,pn  %xcc, 3f
  95                  mov    PRIMARY_CONTEXT, %l4
  96 661:            rdpr    %canrestore, %g3
  97                 .section .fast_win_ctrl_1insn_patch, "ax"
  98                 .word   661b
  99                 nop
 100                 .previous
 101 
 102                 rdpr    %wstate, %g2
 103 661:            wrpr    %g0, 0, %canrestore
 104                 .section .fast_win_ctrl_1insn_patch, "ax"
 105                 .word   661b
 106                 nop
 107                 .previous
 108                 sll     %g2, 3, %g2
 109 
 110                 /* Set TI_SYS_FPDEPTH to 1 and clear TI_SYS_NOERROR.  */
 111                 mov     1, %l5
 112                 sth     %l5, [%l6 + TI_SYS_NOERROR]
 113 
 114 661:            wrpr    %g3, 0, %otherwin
 115                 .section .fast_win_ctrl_1insn_patch, "ax"
 116                 .word   661b
 117                 .word   0x87880000      ! otherw
 118                 .previous
 119 
 120                 wrpr    %g2, 0, %wstate
 121                 sethi   %hi(sparc64_kern_pri_context), %g2
 122                 ldx     [%g2 + %lo(sparc64_kern_pri_context)], %g3
 123 
 124 661:            stxa    %g3, [%l4] ASI_DMMU
 125                 .section .sun4v_1insn_patch, "ax"
 126                 .word   661b
 127                 stxa    %g3, [%l4] ASI_MMU
 128                 .previous
 129 
 130                 sethi   %hi(KERNBASE), %l4
 131                 flush   %l4
 132                 mov     ASI_AIUS, %l7
 133 2:              mov     %g4, %l4
 134                 mov     %g5, %l5
 135                 add     %g7, 4, %l2
 136 
 137                 /* Go to trap time globals so we can save them.  */
 138 661:            wrpr    %g0, ETRAP_PSTATE1, %pstate
 139                 .section .sun4v_1insn_patch, "ax"
 140                 .word   661b
 141                 SET_GL(0)
 142                 .previous
 143 
 144                 stx     %g1, [%sp + PTREGS_OFF + PT_V9_G1]
 145                 stx     %g2, [%sp + PTREGS_OFF + PT_V9_G2]
 146                 sllx    %l7, 24, %l7
 147                 stx     %g3, [%sp + PTREGS_OFF + PT_V9_G3]
 148                 rdpr    %cwp, %l0
 149                 stx     %g4, [%sp + PTREGS_OFF + PT_V9_G4]
 150                 stx     %g5, [%sp + PTREGS_OFF + PT_V9_G5]
 151                 stx     %g6, [%sp + PTREGS_OFF + PT_V9_G6]
 152                 stx     %g7, [%sp + PTREGS_OFF + PT_V9_G7]
 153                 or      %l7, %l0, %l7
 154 661:            sethi   %hi(TSTATE_TSO | TSTATE_PEF), %l0
 155                 /* If userspace is using ADI, it could potentially pass
 156                  * a pointer with version tag embedded in it. To maintain
 157                  * the ADI security, we must enable PSTATE.mcde. Userspace
 158                  * would have already set TTE.mcd in an earlier call to
 159                  * kernel and set the version tag for the address being
 160                  * dereferenced. Setting PSTATE.mcde would ensure any
 161                  * access to userspace data through a system call honors
 162                  * ADI and does not allow a rogue app to bypass ADI by
 163                  * using system calls. Setting PSTATE.mcde only affects
 164                  * accesses to virtual addresses that have TTE.mcd set.
 165                  * Set PMCDPER to ensure any exceptions caused by ADI
 166                  * version tag mismatch are exposed before system call
 167                  * returns to userspace. Setting PMCDPER affects only
 168                  * writes to virtual addresses that have TTE.mcd set and
 169                  * have a version tag set as well.
 170                  */
 171                 .section .sun_m7_1insn_patch, "ax"
 172                 .word   661b
 173                 sethi   %hi(TSTATE_TSO | TSTATE_PEF | TSTATE_MCDE), %l0
 174                 .previous
 175 661:            nop
 176                 .section .sun_m7_1insn_patch, "ax"
 177                 .word   661b
 178                 .word 0xaf902001        /* wrpr %g0, 1, %pmcdper */
 179                 .previous
 180                 or      %l7, %l0, %l7
 181                 wrpr    %l2, %tnpc
 182                 wrpr    %l7, (TSTATE_PRIV | TSTATE_IE), %tstate
 183                 stx     %i0, [%sp + PTREGS_OFF + PT_V9_I0]
 184                 stx     %i1, [%sp + PTREGS_OFF + PT_V9_I1]
 185                 stx     %i2, [%sp + PTREGS_OFF + PT_V9_I2]
 186                 stx     %i3, [%sp + PTREGS_OFF + PT_V9_I3]
 187                 stx     %i4, [%sp + PTREGS_OFF + PT_V9_I4]
 188                 stx     %i5, [%sp + PTREGS_OFF + PT_V9_I5]
 189                 stx     %i6, [%sp + PTREGS_OFF + PT_V9_I6]
 190                 mov     %l6, %g6
 191                 stx     %i7, [%sp + PTREGS_OFF + PT_V9_I7]
 192                 LOAD_PER_CPU_BASE(%g5, %g6, %g4, %g3, %l1)
 193                 ldx     [%g6 + TI_TASK], %g4
 194                 done
 195 
 196 3:              mov     ASI_P, %l7
 197                 ldub    [%l6 + TI_FPDEPTH], %l5
 198                 add     %l6, TI_FPSAVED + 1, %l4
 199                 srl     %l5, 1, %l3
 200                 add     %l5, 2, %l5
 201 
 202                 /* Set TI_SYS_FPDEPTH to %l5 and clear TI_SYS_NOERROR.  */
 203                 sth     %l5, [%l6 + TI_SYS_NOERROR]
 204                 ba,pt   %xcc, 2b
 205                  stb    %g0, [%l4 + %l3]
 206                 nop
 207 
 208 etraptl1:       /* Save tstate/tpc/tnpc of TL 1-->4 and the tl register itself.
 209                  * We place this right after pt_regs on the trap stack.
 210                  * The layout is:
 211                  *      0x00    TL1's TSTATE
 212                  *      0x08    TL1's TPC
 213                  *      0x10    TL1's TNPC
 214                  *      0x18    TL1's TT
 215                  *       ...
 216                  *      0x58    TL4's TT
 217                  *      0x60    TL
 218                  */
 219                 TRAP_LOAD_THREAD_REG(%g6, %g1)
 220                 sub     %sp, ((4 * 8) * 4) + 8, %g2
 221                 rdpr    %tl, %g1
 222 
 223                 wrpr    %g0, 1, %tl
 224                 rdpr    %tstate, %g3
 225                 stx     %g3, [%g2 + STACK_BIAS + 0x00]
 226                 rdpr    %tpc, %g3
 227                 stx     %g3, [%g2 + STACK_BIAS + 0x08]
 228                 rdpr    %tnpc, %g3
 229                 stx     %g3, [%g2 + STACK_BIAS + 0x10]
 230                 rdpr    %tt, %g3
 231                 stx     %g3, [%g2 + STACK_BIAS + 0x18]
 232 
 233                 wrpr    %g0, 2, %tl
 234                 rdpr    %tstate, %g3
 235                 stx     %g3, [%g2 + STACK_BIAS + 0x20]
 236                 rdpr    %tpc, %g3
 237                 stx     %g3, [%g2 + STACK_BIAS + 0x28]
 238                 rdpr    %tnpc, %g3
 239                 stx     %g3, [%g2 + STACK_BIAS + 0x30]
 240                 rdpr    %tt, %g3
 241                 stx     %g3, [%g2 + STACK_BIAS + 0x38]
 242 
 243                 sethi   %hi(is_sun4v), %g3
 244                 lduw    [%g3 + %lo(is_sun4v)], %g3
 245                 brnz,pn %g3, finish_tl1_capture
 246                  nop
 247 
 248                 wrpr    %g0, 3, %tl
 249                 rdpr    %tstate, %g3
 250                 stx     %g3, [%g2 + STACK_BIAS + 0x40]
 251                 rdpr    %tpc, %g3
 252                 stx     %g3, [%g2 + STACK_BIAS + 0x48]
 253                 rdpr    %tnpc, %g3
 254                 stx     %g3, [%g2 + STACK_BIAS + 0x50]
 255                 rdpr    %tt, %g3
 256                 stx     %g3, [%g2 + STACK_BIAS + 0x58]
 257 
 258                 wrpr    %g0, 4, %tl
 259                 rdpr    %tstate, %g3
 260                 stx     %g3, [%g2 + STACK_BIAS + 0x60]
 261                 rdpr    %tpc, %g3
 262                 stx     %g3, [%g2 + STACK_BIAS + 0x68]
 263                 rdpr    %tnpc, %g3
 264                 stx     %g3, [%g2 + STACK_BIAS + 0x70]
 265                 rdpr    %tt, %g3
 266                 stx     %g3, [%g2 + STACK_BIAS + 0x78]
 267 
 268                 stx     %g1, [%g2 + STACK_BIAS + 0x80]
 269 
 270 finish_tl1_capture:
 271                 wrpr    %g0, 1, %tl
 272 661:            nop
 273                 .section .sun4v_1insn_patch, "ax"
 274                 .word   661b
 275                 SET_GL(1)
 276                 .previous
 277 
 278                 rdpr    %tstate, %g1
 279                 sub     %g2, STACKFRAME_SZ + TRACEREG_SZ - STACK_BIAS, %g2
 280                 ba,pt   %xcc, 1b
 281                  andcc  %g1, TSTATE_PRIV, %g0
 282 
 283 #undef TASK_REGOFF
 284 #undef ETRAP_PSTATE1

/* [<][>][^][v][top][bottom][index][help] */