root/arch/powerpc/lib/test_emulate_step_exec_instr.S

/* [<][>][^][v][top][bottom][index][help] */
   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_FRAME_OVERHEAD)
  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_2GPRS(2, 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_10GPRS(2, r31)
  79         REST_GPR(12, r31)
  80         REST_NVGPRS(r31)
  81 
  82         /* Placeholder for the test instruction */
  83 1:      nop
  84         patch_site 1b patch__exec_instr
  85 
  86         /*
  87          * Since GPR3 is overwritten, temporarily restore it back to its
  88          * original state, i.e. the pointer to pt_regs, to ensure that the
  89          * resulting register state can be saved. Before doing this, a copy
  90          * of it is created in the scratch space which is used later on to
  91          * save it to pt_regs.
  92          */
  93         std     r3, 8(r1)
  94         REST_GPR(3, r1)
  95 
  96         /* Save resulting GPR state to pt_regs */
  97         subi    r3, r3, GPR0
  98         SAVE_GPR(0, r3)
  99         SAVE_GPR(2, r3)
 100         SAVE_8GPRS(4, r3)
 101         SAVE_GPR(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)

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