~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/lib/test_emulate_step_exec_instr.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /*
  3  * Non-emulated single-stepping support (currently limited to basic integer
  4  * computations) used to validate the instruction emulation infrastructure.
  5  *
  6  * Copyright (C) 2019 IBM Corporation
  7  */
  8 
  9 #include <asm/asm-offsets.h>
 10 #include <asm/ppc_asm.h>
 11 #include <asm/code-patching-asm.h>
 12 #include <linux/errno.h>
 13 
 14 /* int exec_instr(struct pt_regs *regs) */
 15 _GLOBAL(exec_instr)
 16 
 17         /*
 18          * Stack frame layout (INT_FRAME_SIZE bytes)
 19          *   In-memory pt_regs  (SP + STACK_INT_FRAME_REGS)
 20          *   Scratch space      (SP + 8)
 21          *   Back chain         (SP + 0)
 22          */
 23 
 24         /*
 25          * Allocate a new stack frame with enough space to hold the register
 26          * states in an in-memory pt_regs and also create the back chain to
 27          * the caller's stack frame.
 28          */
 29         stdu    r1, -INT_FRAME_SIZE(r1)
 30 
 31         /*
 32          * Save non-volatile GPRs on stack. This includes TOC pointer (GPR2)
 33          * and local variables (GPR14 to GPR31). The register for the pt_regs
 34          * parameter (GPR3) is saved additionally to ensure that the resulting
 35          * register state can still be saved even if GPR3 gets overwritten
 36          * when loading the initial register state for the test instruction.
 37          * The stack pointer (GPR1) and the thread pointer (GPR13) are not
 38          * saved as these should not be modified anyway.
 39          */
 40         SAVE_GPRS(2, 3, r1)
 41         SAVE_NVGPRS(r1)
 42 
 43         /*
 44          * Save LR on stack to ensure that the return address is available
 45          * even if it gets overwritten by the test instruction.
 46          */
 47         mflr    r0
 48         std     r0, _LINK(r1)
 49 
 50         /*
 51          * Save CR on stack. For simplicity, the entire register is saved
 52          * even though only fields 2 to 4 are non-volatile.
 53          */
 54         mfcr    r0
 55         std     r0, _CCR(r1)
 56 
 57         /*
 58          * Load register state for the test instruction without touching the
 59          * critical non-volatile registers. The register state is passed as a
 60          * pointer to a pt_regs instance.
 61          */
 62         subi    r31, r3, GPR0
 63 
 64         /* Load LR from pt_regs */
 65         ld      r0, _LINK(r31)
 66         mtlr    r0
 67 
 68         /* Load CR from pt_regs */
 69         ld      r0, _CCR(r31)
 70         mtcr    r0
 71 
 72         /* Load XER from pt_regs */
 73         ld      r0, _XER(r31)
 74         mtxer   r0
 75 
 76         /* Load GPRs from pt_regs */
 77         REST_GPR(0, r31)
 78         REST_GPRS(2, 12, r31)
 79         REST_NVGPRS(r31)
 80 
 81         /* Placeholder for the test instruction */
 82         .balign 64
 83 1:      nop
 84         nop
 85         patch_site 1b patch__exec_instr
 86 
 87         /*
 88          * Since GPR3 is overwritten, temporarily restore it back to its
 89          * original state, i.e. the pointer to pt_regs, to ensure that the
 90          * resulting register state can be saved. Before doing this, a copy
 91          * of it is created in the scratch space which is used later on to
 92          * save it to pt_regs.
 93          */
 94         std     r3, 8(r1)
 95         REST_GPR(3, r1)
 96 
 97         /* Save resulting GPR state to pt_regs */
 98         subi    r3, r3, GPR0
 99         SAVE_GPR(0, r3)
100         SAVE_GPR(2, r3)
101         SAVE_GPRS(4, 12, r3)
102         SAVE_NVGPRS(r3)
103 
104         /* Save resulting LR to pt_regs */
105         mflr    r0
106         std     r0, _LINK(r3)
107 
108         /* Save resulting CR to pt_regs */
109         mfcr    r0
110         std     r0, _CCR(r3)
111 
112         /* Save resulting XER to pt_regs */
113         mfxer   r0
114         std     r0, _XER(r3)
115 
116         /* Restore resulting GPR3 from scratch space and save it to pt_regs */
117         ld      r0, 8(r1)
118         std     r0, GPR3(r3)
119 
120         /* Set return value to denote execution success */
121         li      r3, 0
122 
123         /* Continue */
124         b       3f
125 
126         /* Set return value to denote execution failure */
127 2:      li      r3, -EFAULT
128 
129         /* Restore the non-volatile GPRs from stack */
130 3:      REST_GPR(2, r1)
131         REST_NVGPRS(r1)
132 
133         /* Restore LR from stack to be able to return */
134         ld      r0, _LINK(r1)
135         mtlr    r0
136 
137         /* Restore CR from stack */
138         ld      r0, _CCR(r1)
139         mtcr    r0
140 
141         /* Tear down stack frame */
142         addi    r1, r1, INT_FRAME_SIZE
143 
144         /* Return */
145         blr
146 
147         /* Setup exception table */
148         EX_TABLE(1b, 2b)
149 
150 _ASM_NOKPROBE_SYMBOL(exec_instr)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php