![]() |
|
|||
0001 /* SPDX-License-Identifier: GPL-2.0 */ 0002 /* 0003 * Non-emulated single-stepping support (currently limited to basic integer 0004 * computations) used to validate the instruction emulation infrastructure. 0005 * 0006 * Copyright (C) 2019 IBM Corporation 0007 */ 0008 0009 #include <asm/asm-offsets.h> 0010 #include <asm/ppc_asm.h> 0011 #include <asm/code-patching-asm.h> 0012 #include <linux/errno.h> 0013 0014 /* int exec_instr(struct pt_regs *regs) */ 0015 _GLOBAL(exec_instr) 0016 0017 /* 0018 * Stack frame layout (INT_FRAME_SIZE bytes) 0019 * In-memory pt_regs (SP + STACK_FRAME_OVERHEAD) 0020 * Scratch space (SP + 8) 0021 * Back chain (SP + 0) 0022 */ 0023 0024 /* 0025 * Allocate a new stack frame with enough space to hold the register 0026 * states in an in-memory pt_regs and also create the back chain to 0027 * the caller's stack frame. 0028 */ 0029 stdu r1, -INT_FRAME_SIZE(r1) 0030 0031 /* 0032 * Save non-volatile GPRs on stack. This includes TOC pointer (GPR2) 0033 * and local variables (GPR14 to GPR31). The register for the pt_regs 0034 * parameter (GPR3) is saved additionally to ensure that the resulting 0035 * register state can still be saved even if GPR3 gets overwritten 0036 * when loading the initial register state for the test instruction. 0037 * The stack pointer (GPR1) and the thread pointer (GPR13) are not 0038 * saved as these should not be modified anyway. 0039 */ 0040 SAVE_GPRS(2, 3, r1) 0041 SAVE_NVGPRS(r1) 0042 0043 /* 0044 * Save LR on stack to ensure that the return address is available 0045 * even if it gets overwritten by the test instruction. 0046 */ 0047 mflr r0 0048 std r0, _LINK(r1) 0049 0050 /* 0051 * Save CR on stack. For simplicity, the entire register is saved 0052 * even though only fields 2 to 4 are non-volatile. 0053 */ 0054 mfcr r0 0055 std r0, _CCR(r1) 0056 0057 /* 0058 * Load register state for the test instruction without touching the 0059 * critical non-volatile registers. The register state is passed as a 0060 * pointer to a pt_regs instance. 0061 */ 0062 subi r31, r3, GPR0 0063 0064 /* Load LR from pt_regs */ 0065 ld r0, _LINK(r31) 0066 mtlr r0 0067 0068 /* Load CR from pt_regs */ 0069 ld r0, _CCR(r31) 0070 mtcr r0 0071 0072 /* Load XER from pt_regs */ 0073 ld r0, _XER(r31) 0074 mtxer r0 0075 0076 /* Load GPRs from pt_regs */ 0077 REST_GPR(0, r31) 0078 REST_GPRS(2, 12, r31) 0079 REST_NVGPRS(r31) 0080 0081 /* Placeholder for the test instruction */ 0082 .balign 64 0083 1: nop 0084 nop 0085 patch_site 1b patch__exec_instr 0086 0087 /* 0088 * Since GPR3 is overwritten, temporarily restore it back to its 0089 * original state, i.e. the pointer to pt_regs, to ensure that the 0090 * resulting register state can be saved. Before doing this, a copy 0091 * of it is created in the scratch space which is used later on to 0092 * save it to pt_regs. 0093 */ 0094 std r3, 8(r1) 0095 REST_GPR(3, r1) 0096 0097 /* Save resulting GPR state to pt_regs */ 0098 subi r3, r3, GPR0 0099 SAVE_GPR(0, r3) 0100 SAVE_GPR(2, r3) 0101 SAVE_GPRS(4, 12, r3) 0102 SAVE_NVGPRS(r3) 0103 0104 /* Save resulting LR to pt_regs */ 0105 mflr r0 0106 std r0, _LINK(r3) 0107 0108 /* Save resulting CR to pt_regs */ 0109 mfcr r0 0110 std r0, _CCR(r3) 0111 0112 /* Save resulting XER to pt_regs */ 0113 mfxer r0 0114 std r0, _XER(r3) 0115 0116 /* Restore resulting GPR3 from scratch space and save it to pt_regs */ 0117 ld r0, 8(r1) 0118 std r0, GPR3(r3) 0119 0120 /* Set return value to denote execution success */ 0121 li r3, 0 0122 0123 /* Continue */ 0124 b 3f 0125 0126 /* Set return value to denote execution failure */ 0127 2: li r3, -EFAULT 0128 0129 /* Restore the non-volatile GPRs from stack */ 0130 3: REST_GPR(2, r1) 0131 REST_NVGPRS(r1) 0132 0133 /* Restore LR from stack to be able to return */ 0134 ld r0, _LINK(r1) 0135 mtlr r0 0136 0137 /* Restore CR from stack */ 0138 ld r0, _CCR(r1) 0139 mtcr r0 0140 0141 /* Tear down stack frame */ 0142 addi r1, r1, INT_FRAME_SIZE 0143 0144 /* Return */ 0145 blr 0146 0147 /* Setup exception table */ 0148 EX_TABLE(1b, 2b) 0149 0150 _ASM_NOKPROBE_SYMBOL(exec_instr)
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |