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

TOMOYO Linux Cross Reference
Linux/arch/powerpc/platforms/pseries/hvCall.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-or-later */
  2 /*
  3  * This file contains the generic code to perform a call to the
  4  * pSeries LPAR hypervisor.
  5  */
  6 #include <linux/jump_label.h>
  7 #include <asm/hvcall.h>
  8 #include <asm/processor.h>
  9 #include <asm/ppc_asm.h>
 10 #include <asm/asm-offsets.h>
 11 #include <asm/ptrace.h>
 12 #include <asm/feature-fixups.h>
 13 
 14         .section        ".text"
 15         
 16 #ifdef CONFIG_TRACEPOINTS
 17 
 18 #ifndef CONFIG_JUMP_LABEL
 19         .data
 20 
 21         .globl hcall_tracepoint_refcount
 22 hcall_tracepoint_refcount:
 23         .8byte  0
 24 
 25         .section        ".text"
 26 #endif
 27 
 28 /*
 29  * precall must preserve all registers.  use unused STK_PARAM()
 30  * areas to save snapshots and opcode. STK_PARAM() in the caller's
 31  * frame will be available even on ELFv2 because these are all
 32  * variadic functions.
 33  */
 34 #define HCALL_INST_PRECALL(FIRST_REG)                           \
 35         mflr    r0;                                             \
 36         std     r3,STK_PARAM(R3)(r1);                           \
 37         std     r4,STK_PARAM(R4)(r1);                           \
 38         std     r5,STK_PARAM(R5)(r1);                           \
 39         std     r6,STK_PARAM(R6)(r1);                           \
 40         std     r7,STK_PARAM(R7)(r1);                           \
 41         std     r8,STK_PARAM(R8)(r1);                           \
 42         std     r9,STK_PARAM(R9)(r1);                           \
 43         std     r10,STK_PARAM(R10)(r1);                         \
 44         std     r0,16(r1);                                      \
 45         addi    r4,r1,STK_PARAM(FIRST_REG);                     \
 46         stdu    r1,-STACK_FRAME_MIN_SIZE(r1);                   \
 47         bl      CFUNC(__trace_hcall_entry);                     \
 48         ld      r3,STACK_FRAME_MIN_SIZE+STK_PARAM(R3)(r1);      \
 49         ld      r4,STACK_FRAME_MIN_SIZE+STK_PARAM(R4)(r1);      \
 50         ld      r5,STACK_FRAME_MIN_SIZE+STK_PARAM(R5)(r1);      \
 51         ld      r6,STACK_FRAME_MIN_SIZE+STK_PARAM(R6)(r1);      \
 52         ld      r7,STACK_FRAME_MIN_SIZE+STK_PARAM(R7)(r1);      \
 53         ld      r8,STACK_FRAME_MIN_SIZE+STK_PARAM(R8)(r1);      \
 54         ld      r9,STACK_FRAME_MIN_SIZE+STK_PARAM(R9)(r1);      \
 55         ld      r10,STACK_FRAME_MIN_SIZE+STK_PARAM(R10)(r1)
 56 
 57 /*
 58  * postcall is performed immediately before function return which
 59  * allows liberal use of volatile registers.
 60  */
 61 #define __HCALL_INST_POSTCALL                                   \
 62         ld      r0,STACK_FRAME_MIN_SIZE+STK_PARAM(R3)(r1);      \
 63         std     r3,STACK_FRAME_MIN_SIZE+STK_PARAM(R3)(r1);      \
 64         mr      r4,r3;                                          \
 65         mr      r3,r0;                                          \
 66         bl      CFUNC(__trace_hcall_exit);                      \
 67         ld      r0,STACK_FRAME_MIN_SIZE+16(r1);                 \
 68         addi    r1,r1,STACK_FRAME_MIN_SIZE;                     \
 69         ld      r3,STK_PARAM(R3)(r1);                           \
 70         mtlr    r0
 71 
 72 #define HCALL_INST_POSTCALL_NORETS                              \
 73         li      r5,0;                                           \
 74         __HCALL_INST_POSTCALL
 75 
 76 #define HCALL_INST_POSTCALL(BUFREG)                             \
 77         mr      r5,BUFREG;                                      \
 78         __HCALL_INST_POSTCALL
 79 
 80 #ifdef CONFIG_JUMP_LABEL
 81 #define HCALL_BRANCH(LABEL)                                     \
 82         ARCH_STATIC_BRANCH(LABEL, hcall_tracepoint_key)
 83 #else
 84 
 85 /*
 86  * We branch around this in early init (eg when populating the MMU
 87  * hashtable) by using an unconditional cpu feature.
 88  */
 89 #define HCALL_BRANCH(LABEL)                                     \
 90 BEGIN_FTR_SECTION;                                              \
 91         b       1f;                                             \
 92 END_FTR_SECTION(0, 1);                                          \
 93         LOAD_REG_ADDR(r12, hcall_tracepoint_refcount) ;         \
 94         ld      r12,0(r12);                                     \
 95         cmpdi   r12,0;                                          \
 96         bne-    LABEL;                                          \
 97 1:
 98 #endif
 99 
100 #else
101 #define HCALL_INST_PRECALL(FIRST_ARG)
102 #define HCALL_INST_POSTCALL_NORETS
103 #define HCALL_INST_POSTCALL(BUFREG)
104 #define HCALL_BRANCH(LABEL)
105 #endif
106 
107 _GLOBAL_TOC(plpar_hcall_norets_notrace)
108         HMT_MEDIUM
109 
110         mfcr    r0
111         stw     r0,8(r1)
112         HVSC                            /* invoke the hypervisor */
113 
114         li      r4,0
115         stb     r4,PACASRR_VALID(r13)
116 
117         lwz     r0,8(r1)
118         mtcrf   0xff,r0
119         blr                             /* return r3 = status */
120 
121 _GLOBAL_TOC(plpar_hcall_norets)
122         HMT_MEDIUM
123 
124         mfcr    r0
125         stw     r0,8(r1)
126         HCALL_BRANCH(plpar_hcall_norets_trace)
127         HVSC                            /* invoke the hypervisor */
128 
129         li      r4,0
130         stb     r4,PACASRR_VALID(r13)
131 
132         lwz     r0,8(r1)
133         mtcrf   0xff,r0
134         blr                             /* return r3 = status */
135 
136 #ifdef CONFIG_TRACEPOINTS
137 plpar_hcall_norets_trace:
138         HCALL_INST_PRECALL(R4)
139         HVSC
140         HCALL_INST_POSTCALL_NORETS
141 
142         li      r4,0
143         stb     r4,PACASRR_VALID(r13)
144 
145         lwz     r0,8(r1)
146         mtcrf   0xff,r0
147         blr
148 #endif
149 
150 _GLOBAL_TOC(plpar_hcall)
151         HMT_MEDIUM
152 
153         mfcr    r0
154         stw     r0,8(r1)
155 
156         HCALL_BRANCH(plpar_hcall_trace)
157 
158         std     r4,STK_PARAM(R4)(r1)     /* Save ret buffer */
159 
160         mr      r4,r5
161         mr      r5,r6
162         mr      r6,r7
163         mr      r7,r8
164         mr      r8,r9
165         mr      r9,r10
166 
167         HVSC                            /* invoke the hypervisor */
168 
169         ld      r12,STK_PARAM(R4)(r1)
170         std     r4,  0(r12)
171         std     r5,  8(r12)
172         std     r6, 16(r12)
173         std     r7, 24(r12)
174 
175         li      r4,0
176         stb     r4,PACASRR_VALID(r13)
177 
178         lwz     r0,8(r1)
179         mtcrf   0xff,r0
180 
181         blr                             /* return r3 = status */
182 
183 #ifdef CONFIG_TRACEPOINTS
184 plpar_hcall_trace:
185         HCALL_INST_PRECALL(R5)
186 
187         mr      r4,r5
188         mr      r5,r6
189         mr      r6,r7
190         mr      r7,r8
191         mr      r8,r9
192         mr      r9,r10
193 
194         HVSC
195 
196         ld      r12,STACK_FRAME_MIN_SIZE+STK_PARAM(R4)(r1)
197         std     r4,0(r12)
198         std     r5,8(r12)
199         std     r6,16(r12)
200         std     r7,24(r12)
201 
202         HCALL_INST_POSTCALL(r12)
203 
204         li      r4,0
205         stb     r4,PACASRR_VALID(r13)
206 
207         lwz     r0,8(r1)
208         mtcrf   0xff,r0
209 
210         blr
211 #endif
212 
213 /*
214  * plpar_hcall_raw can be called in real mode. kexec/kdump need some
215  * hypervisor calls to be executed in real mode. So plpar_hcall_raw
216  * does not access the per cpu hypervisor call statistics variables,
217  * since these variables may not be present in the RMO region.
218  */
219 _GLOBAL(plpar_hcall_raw)
220         HMT_MEDIUM
221 
222         mfcr    r0
223         stw     r0,8(r1)
224 
225         std     r4,STK_PARAM(R4)(r1)     /* Save ret buffer */
226 
227         mr      r4,r5
228         mr      r5,r6
229         mr      r6,r7
230         mr      r7,r8
231         mr      r8,r9
232         mr      r9,r10
233 
234         HVSC                            /* invoke the hypervisor */
235 
236         ld      r12,STK_PARAM(R4)(r1)
237         std     r4,  0(r12)
238         std     r5,  8(r12)
239         std     r6, 16(r12)
240         std     r7, 24(r12)
241 
242         li      r4,0
243         stb     r4,PACASRR_VALID(r13)
244 
245         lwz     r0,8(r1)
246         mtcrf   0xff,r0
247 
248         blr                             /* return r3 = status */
249 
250 _GLOBAL_TOC(plpar_hcall9)
251         HMT_MEDIUM
252 
253         mfcr    r0
254         stw     r0,8(r1)
255 
256         HCALL_BRANCH(plpar_hcall9_trace)
257 
258         std     r4,STK_PARAM(R4)(r1)     /* Save ret buffer */
259 
260         mr      r4,r5
261         mr      r5,r6
262         mr      r6,r7
263         mr      r7,r8
264         mr      r8,r9
265         mr      r9,r10
266         ld      r10,STK_PARAM(R11)(r1)   /* put arg7 in R10 */
267         ld      r11,STK_PARAM(R12)(r1)   /* put arg8 in R11 */
268         ld      r12,STK_PARAM(R13)(r1)    /* put arg9 in R12 */
269 
270         HVSC                            /* invoke the hypervisor */
271 
272         mr      r0,r12
273         ld      r12,STK_PARAM(R4)(r1)
274         std     r4,  0(r12)
275         std     r5,  8(r12)
276         std     r6, 16(r12)
277         std     r7, 24(r12)
278         std     r8, 32(r12)
279         std     r9, 40(r12)
280         std     r10,48(r12)
281         std     r11,56(r12)
282         std     r0, 64(r12)
283 
284         li      r4,0
285         stb     r4,PACASRR_VALID(r13)
286 
287         lwz     r0,8(r1)
288         mtcrf   0xff,r0
289 
290         blr                             /* return r3 = status */
291 
292 #ifdef CONFIG_TRACEPOINTS
293 plpar_hcall9_trace:
294         HCALL_INST_PRECALL(R5)
295 
296         mr      r4,r5
297         mr      r5,r6
298         mr      r6,r7
299         mr      r7,r8
300         mr      r8,r9
301         mr      r9,r10
302         ld      r10,STACK_FRAME_MIN_SIZE+STK_PARAM(R11)(r1)
303         ld      r11,STACK_FRAME_MIN_SIZE+STK_PARAM(R12)(r1)
304         ld      r12,STACK_FRAME_MIN_SIZE+STK_PARAM(R13)(r1)
305 
306         HVSC
307 
308         mr      r0,r12
309         ld      r12,STACK_FRAME_MIN_SIZE+STK_PARAM(R4)(r1)
310         std     r4,0(r12)
311         std     r5,8(r12)
312         std     r6,16(r12)
313         std     r7,24(r12)
314         std     r8,32(r12)
315         std     r9,40(r12)
316         std     r10,48(r12)
317         std     r11,56(r12)
318         std     r0,64(r12)
319 
320         HCALL_INST_POSTCALL(r12)
321 
322         li      r4,0
323         stb     r4,PACASRR_VALID(r13)
324 
325         lwz     r0,8(r1)
326         mtcrf   0xff,r0
327 
328         blr
329 #endif
330 
331 /* See plpar_hcall_raw to see why this is needed */
332 _GLOBAL(plpar_hcall9_raw)
333         HMT_MEDIUM
334 
335         mfcr    r0
336         stw     r0,8(r1)
337 
338         std     r4,STK_PARAM(R4)(r1)     /* Save ret buffer */
339 
340         mr      r4,r5
341         mr      r5,r6
342         mr      r6,r7
343         mr      r7,r8
344         mr      r8,r9
345         mr      r9,r10
346         ld      r10,STK_PARAM(R11)(r1)   /* put arg7 in R10 */
347         ld      r11,STK_PARAM(R12)(r1)   /* put arg8 in R11 */
348         ld      r12,STK_PARAM(R13)(r1)    /* put arg9 in R12 */
349 
350         HVSC                            /* invoke the hypervisor */
351 
352         mr      r0,r12
353         ld      r12,STK_PARAM(R4)(r1)
354         std     r4,  0(r12)
355         std     r5,  8(r12)
356         std     r6, 16(r12)
357         std     r7, 24(r12)
358         std     r8, 32(r12)
359         std     r9, 40(r12)
360         std     r10,48(r12)
361         std     r11,56(r12)
362         std     r0, 64(r12)
363 
364         li      r4,0
365         stb     r4,PACASRR_VALID(r13)
366 
367         lwz     r0,8(r1)
368         mtcrf   0xff,r0
369 
370         blr                             /* return r3 = status */

~ [ 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