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) |
151 | |