blob: 74b5b8e239c8235ac61b529b8085cc3ceff096ed [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * This file contains the generic code to perform a call to the
3 * pSeries LPAR hypervisor.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 */
Anton Blanchard58995a92015-04-09 13:51:32 +100010#include <linux/jump_label.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011#include <asm/hvcall.h>
12#include <asm/processor.h>
13#include <asm/ppc_asm.h>
Mike Kravetz57852a82006-09-06 16:23:12 -070014#include <asm/asm-offsets.h>
Stephen Rothwell46f52212010-11-18 15:06:17 +000015#include <asm/ptrace.h>
Anton Blanchardcc1adb52014-07-03 15:52:03 +100016
17 .section ".text"
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
Anton Blanchardc8cd0932009-10-26 18:50:29 +000019#ifdef CONFIG_TRACEPOINTS
20
Anton Blanchard1bc9e472014-10-30 15:43:43 +110021#ifndef HAVE_JUMP_LABEL
Anton Blanchardc8cd0932009-10-26 18:50:29 +000022 .section ".toc","aw"
23
24 .globl hcall_tracepoint_refcount
25hcall_tracepoint_refcount:
26 .llong 0
27
28 .section ".text"
Anton Blanchardcc1adb52014-07-03 15:52:03 +100029#endif
Anton Blanchardc8cd0932009-10-26 18:50:29 +000030
Mike Kravetz57852a82006-09-06 16:23:12 -070031/*
Michael Neuling44ce6a52012-06-25 13:33:14 +000032 * precall must preserve all registers. use unused STK_PARAM()
Anton Blanchardcc1adb52014-07-03 15:52:03 +100033 * areas to save snapshots and opcode.
Mike Kravetz57852a82006-09-06 16:23:12 -070034 */
Anton Blanchard6f263532009-10-26 18:51:09 +000035#define HCALL_INST_PRECALL(FIRST_REG) \
Anton Blanchardc8cd0932009-10-26 18:50:29 +000036 mflr r0; \
Michael Neuling44ce6a52012-06-25 13:33:14 +000037 std r3,STK_PARAM(R3)(r1); \
38 std r4,STK_PARAM(R4)(r1); \
39 std r5,STK_PARAM(R5)(r1); \
40 std r6,STK_PARAM(R6)(r1); \
41 std r7,STK_PARAM(R7)(r1); \
42 std r8,STK_PARAM(R8)(r1); \
43 std r9,STK_PARAM(R9)(r1); \
44 std r10,STK_PARAM(R10)(r1); \
Anton Blanchardc8cd0932009-10-26 18:50:29 +000045 std r0,16(r1); \
Michael Neuling44ce6a52012-06-25 13:33:14 +000046 addi r4,r1,STK_PARAM(FIRST_REG); \
Anton Blanchardc8cd0932009-10-26 18:50:29 +000047 stdu r1,-STACK_FRAME_OVERHEAD(r1); \
Anton Blanchardb1576fe2014-02-04 16:04:35 +110048 bl __trace_hcall_entry; \
Anton Blanchardaaad4222014-07-03 15:52:56 +100049 ld r3,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1); \
50 ld r4,STACK_FRAME_OVERHEAD+STK_PARAM(R4)(r1); \
51 ld r5,STACK_FRAME_OVERHEAD+STK_PARAM(R5)(r1); \
52 ld r6,STACK_FRAME_OVERHEAD+STK_PARAM(R6)(r1); \
53 ld r7,STACK_FRAME_OVERHEAD+STK_PARAM(R7)(r1); \
54 ld r8,STACK_FRAME_OVERHEAD+STK_PARAM(R8)(r1); \
55 ld r9,STACK_FRAME_OVERHEAD+STK_PARAM(R9)(r1); \
56 ld r10,STACK_FRAME_OVERHEAD+STK_PARAM(R10)(r1)
Anton Blanchardc8cd0932009-10-26 18:50:29 +000057
Mike Kravetz57852a82006-09-06 16:23:12 -070058/*
59 * postcall is performed immediately before function return which
Anton Blanchardcc1adb52014-07-03 15:52:03 +100060 * allows liberal use of volatile registers.
Mike Kravetz57852a82006-09-06 16:23:12 -070061 */
Anton Blanchard6f263532009-10-26 18:51:09 +000062#define __HCALL_INST_POSTCALL \
Anton Blanchardaaad4222014-07-03 15:52:56 +100063 ld r0,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1); \
64 std r3,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1); \
Anton Blanchardc8cd0932009-10-26 18:50:29 +000065 mr r4,r3; \
Anton Blanchardaaad4222014-07-03 15:52:56 +100066 mr r3,r0; \
Anton Blanchardb1576fe2014-02-04 16:04:35 +110067 bl __trace_hcall_exit; \
Anton Blanchardaaad4222014-07-03 15:52:56 +100068 ld r0,STACK_FRAME_OVERHEAD+16(r1); \
Anton Blanchardc8cd0932009-10-26 18:50:29 +000069 addi r1,r1,STACK_FRAME_OVERHEAD; \
Michael Neuling44ce6a52012-06-25 13:33:14 +000070 ld r3,STK_PARAM(R3)(r1); \
Anton Blanchardcc1adb52014-07-03 15:52:03 +100071 mtlr r0
Anton Blanchard6f263532009-10-26 18:51:09 +000072
73#define HCALL_INST_POSTCALL_NORETS \
74 li r5,0; \
75 __HCALL_INST_POSTCALL
76
77#define HCALL_INST_POSTCALL(BUFREG) \
78 mr r5,BUFREG; \
79 __HCALL_INST_POSTCALL
80
Anton Blanchard1bc9e472014-10-30 15:43:43 +110081#ifdef HAVE_JUMP_LABEL
Anton Blanchardcc1adb52014-07-03 15:52:03 +100082#define HCALL_BRANCH(LABEL) \
83 ARCH_STATIC_BRANCH(LABEL, hcall_tracepoint_key)
84#else
85
86/*
87 * We branch around this in early init (eg when populating the MMU
88 * hashtable) by using an unconditional cpu feature.
89 */
90#define HCALL_BRANCH(LABEL) \
91BEGIN_FTR_SECTION; \
92 b 1f; \
93END_FTR_SECTION(0, 1); \
94 ld r12,hcall_tracepoint_refcount@toc(r2); \
95 std r12,32(r1); \
96 cmpdi r12,0; \
97 bne- LABEL; \
981:
99#endif
100
Mike Kravetz57852a82006-09-06 16:23:12 -0700101#else
Anton Blanchard6f263532009-10-26 18:51:09 +0000102#define HCALL_INST_PRECALL(FIRST_ARG)
103#define HCALL_INST_POSTCALL_NORETS
104#define HCALL_INST_POSTCALL(BUFREG)
Anton Blanchardcc1adb52014-07-03 15:52:03 +1000105#define HCALL_BRANCH(LABEL)
Mike Kravetz57852a82006-09-06 16:23:12 -0700106#endif
107
Anton Blanchardc1931e22014-05-13 20:48:57 +1000108_GLOBAL_TOC(plpar_hcall_norets)
Anton Blanchardeeb24de2005-05-01 08:58:46 -0700109 HMT_MEDIUM
110
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 mfcr r0
112 stw r0,8(r1)
Anton Blanchardcc1adb52014-07-03 15:52:03 +1000113 HCALL_BRANCH(plpar_hcall_norets_trace)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114 HVSC /* invoke the hypervisor */
115
116 lwz r0,8(r1)
117 mtcrf 0xff,r0
118 blr /* return r3 = status */
119
Anton Blanchardcc1adb52014-07-03 15:52:03 +1000120#ifdef CONFIG_TRACEPOINTS
121plpar_hcall_norets_trace:
122 HCALL_INST_PRECALL(R4)
123 HVSC
124 HCALL_INST_POSTCALL_NORETS
125 lwz r0,8(r1)
126 mtcrf 0xff,r0
127 blr
128#endif
129
Anton Blanchardc1931e22014-05-13 20:48:57 +1000130_GLOBAL_TOC(plpar_hcall)
Anton Blanchardeeb24de2005-05-01 08:58:46 -0700131 HMT_MEDIUM
132
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133 mfcr r0
134 stw r0,8(r1)
135
Anton Blanchardcc1adb52014-07-03 15:52:03 +1000136 HCALL_BRANCH(plpar_hcall_trace)
Mike Kravetz57852a82006-09-06 16:23:12 -0700137
Michael Neuling44ce6a52012-06-25 13:33:14 +0000138 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
Anton Blanchardb9377ff2006-07-19 08:01:28 +1000139
140 mr r4,r5
141 mr r5,r6
142 mr r6,r7
143 mr r7,r8
144 mr r8,r9
145 mr r9,r10
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146
147 HVSC /* invoke the hypervisor */
148
Michael Neuling44ce6a52012-06-25 13:33:14 +0000149 ld r12,STK_PARAM(R4)(r1)
Anton Blanchardb9377ff2006-07-19 08:01:28 +1000150 std r4, 0(r12)
151 std r5, 8(r12)
152 std r6, 16(r12)
153 std r7, 24(r12)
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200154
Anton Blanchardcc1adb52014-07-03 15:52:03 +1000155 lwz r0,8(r1)
156 mtcrf 0xff,r0
157
158 blr /* return r3 = status */
159
160#ifdef CONFIG_TRACEPOINTS
161plpar_hcall_trace:
162 HCALL_INST_PRECALL(R5)
163
164 std r4,STK_PARAM(R4)(r1)
165 mr r0,r4
166
167 mr r4,r5
168 mr r5,r6
169 mr r6,r7
170 mr r7,r8
171 mr r8,r9
172 mr r9,r10
173
174 HVSC
175
176 ld r12,STK_PARAM(R4)(r1)
177 std r4,0(r12)
178 std r5,8(r12)
179 std r6,16(r12)
180 std r7,24(r12)
181
Anton Blanchard6f263532009-10-26 18:51:09 +0000182 HCALL_INST_POSTCALL(r12)
Mike Kravetz57852a82006-09-06 16:23:12 -0700183
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200184 lwz r0,8(r1)
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200185 mtcrf 0xff,r0
186
Anton Blanchardcc1adb52014-07-03 15:52:03 +1000187 blr
188#endif
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200189
Mohan Kumar Mb4aea362007-03-21 11:21:32 +0530190/*
191 * plpar_hcall_raw can be called in real mode. kexec/kdump need some
192 * hypervisor calls to be executed in real mode. So plpar_hcall_raw
193 * does not access the per cpu hypervisor call statistics variables,
194 * since these variables may not be present in the RMO region.
195 */
196_GLOBAL(plpar_hcall_raw)
197 HMT_MEDIUM
198
199 mfcr r0
200 stw r0,8(r1)
201
Michael Neuling44ce6a52012-06-25 13:33:14 +0000202 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
Mohan Kumar Mb4aea362007-03-21 11:21:32 +0530203
204 mr r4,r5
205 mr r5,r6
206 mr r6,r7
207 mr r7,r8
208 mr r8,r9
209 mr r9,r10
210
211 HVSC /* invoke the hypervisor */
212
Michael Neuling44ce6a52012-06-25 13:33:14 +0000213 ld r12,STK_PARAM(R4)(r1)
Mohan Kumar Mb4aea362007-03-21 11:21:32 +0530214 std r4, 0(r12)
215 std r5, 8(r12)
216 std r6, 16(r12)
217 std r7, 24(r12)
218
219 lwz r0,8(r1)
220 mtcrf 0xff,r0
221
222 blr /* return r3 = status */
223
Anton Blanchardc1931e22014-05-13 20:48:57 +1000224_GLOBAL_TOC(plpar_hcall9)
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200225 HMT_MEDIUM
226
227 mfcr r0
228 stw r0,8(r1)
229
Anton Blanchardcc1adb52014-07-03 15:52:03 +1000230 HCALL_BRANCH(plpar_hcall9_trace)
Mike Kravetz57852a82006-09-06 16:23:12 -0700231
Michael Neuling44ce6a52012-06-25 13:33:14 +0000232 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
Anton Blanchardb9377ff2006-07-19 08:01:28 +1000233
234 mr r4,r5
235 mr r5,r6
236 mr r6,r7
237 mr r7,r8
238 mr r8,r9
239 mr r9,r10
Michael Neuling44ce6a52012-06-25 13:33:14 +0000240 ld r10,STK_PARAM(R11)(r1) /* put arg7 in R10 */
241 ld r11,STK_PARAM(R12)(r1) /* put arg8 in R11 */
242 ld r12,STK_PARAM(R13)(r1) /* put arg9 in R12 */
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200243
244 HVSC /* invoke the hypervisor */
245
Anton Blanchardab87e8d2007-01-09 02:37:16 +1100246 mr r0,r12
Michael Neuling44ce6a52012-06-25 13:33:14 +0000247 ld r12,STK_PARAM(R4)(r1)
Anton Blanchardb9377ff2006-07-19 08:01:28 +1000248 std r4, 0(r12)
249 std r5, 8(r12)
250 std r6, 16(r12)
251 std r7, 24(r12)
252 std r8, 32(r12)
253 std r9, 40(r12)
254 std r10,48(r12)
255 std r11,56(r12)
Anton Blanchardab87e8d2007-01-09 02:37:16 +1100256 std r0, 64(r12)
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200257
Anton Blanchardcc1adb52014-07-03 15:52:03 +1000258 lwz r0,8(r1)
259 mtcrf 0xff,r0
260
261 blr /* return r3 = status */
262
263#ifdef CONFIG_TRACEPOINTS
264plpar_hcall9_trace:
265 HCALL_INST_PRECALL(R5)
266
267 std r4,STK_PARAM(R4)(r1)
268 mr r0,r4
269
270 mr r4,r5
271 mr r5,r6
272 mr r6,r7
273 mr r7,r8
274 mr r8,r9
275 mr r9,r10
Anton Blanchardaaad4222014-07-03 15:52:56 +1000276 ld r10,STACK_FRAME_OVERHEAD+STK_PARAM(R11)(r1)
277 ld r11,STACK_FRAME_OVERHEAD+STK_PARAM(R12)(r1)
278 ld r12,STACK_FRAME_OVERHEAD+STK_PARAM(R13)(r1)
Anton Blanchardcc1adb52014-07-03 15:52:03 +1000279
280 HVSC
281
282 mr r0,r12
Anton Blanchardaaad4222014-07-03 15:52:56 +1000283 ld r12,STACK_FRAME_OVERHEAD+STK_PARAM(R4)(r1)
Anton Blanchardcc1adb52014-07-03 15:52:03 +1000284 std r4,0(r12)
285 std r5,8(r12)
286 std r6,16(r12)
287 std r7,24(r12)
288 std r8,32(r12)
289 std r9,40(r12)
290 std r10,48(r12)
291 std r11,56(r12)
292 std r0,64(r12)
293
Anton Blanchard6f263532009-10-26 18:51:09 +0000294 HCALL_INST_POSTCALL(r12)
Mike Kravetz57852a82006-09-06 16:23:12 -0700295
Heiko J Schickb13a96c2006-03-30 22:47:14 +0200296 lwz r0,8(r1)
297 mtcrf 0xff,r0
298
Anton Blanchardcc1adb52014-07-03 15:52:03 +1000299 blr
300#endif
Michael Neulingf90ece22010-05-10 20:28:26 +0000301
302/* See plpar_hcall_raw to see why this is needed */
303_GLOBAL(plpar_hcall9_raw)
304 HMT_MEDIUM
305
306 mfcr r0
307 stw r0,8(r1)
308
Michael Neuling44ce6a52012-06-25 13:33:14 +0000309 std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
Michael Neulingf90ece22010-05-10 20:28:26 +0000310
311 mr r4,r5
312 mr r5,r6
313 mr r6,r7
314 mr r7,r8
315 mr r8,r9
316 mr r9,r10
Michael Neuling44ce6a52012-06-25 13:33:14 +0000317 ld r10,STK_PARAM(R11)(r1) /* put arg7 in R10 */
318 ld r11,STK_PARAM(R12)(r1) /* put arg8 in R11 */
319 ld r12,STK_PARAM(R13)(r1) /* put arg9 in R12 */
Michael Neulingf90ece22010-05-10 20:28:26 +0000320
321 HVSC /* invoke the hypervisor */
322
323 mr r0,r12
Michael Neuling44ce6a52012-06-25 13:33:14 +0000324 ld r12,STK_PARAM(R4)(r1)
Michael Neulingf90ece22010-05-10 20:28:26 +0000325 std r4, 0(r12)
326 std r5, 8(r12)
327 std r6, 16(r12)
328 std r7, 24(r12)
329 std r8, 32(r12)
330 std r9, 40(r12)
331 std r10,48(r12)
332 std r11,56(r12)
333 std r0, 64(r12)
334
335 lwz r0,8(r1)
336 mtcrf 0xff,r0
337
338 blr /* return r3 = status */