rev |
line source |
cl349@4492
|
1 /******************************************************************************
|
cl349@4492
|
2 * hypercall.h
|
cl349@4492
|
3 *
|
cl349@4492
|
4 * Linux-specific hypervisor handling.
|
cl349@4492
|
5 *
|
cl349@4492
|
6 * Copyright (c) 2002-2004, K A Fraser
|
cl349@4492
|
7 *
|
cl349@4492
|
8 * This file may be distributed separately from the Linux kernel, or
|
cl349@4492
|
9 * incorporated into other software packages, subject to the following license:
|
cl349@4492
|
10 *
|
cl349@4492
|
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
|
cl349@4492
|
12 * of this source file (the "Software"), to deal in the Software without
|
cl349@4492
|
13 * restriction, including without limitation the rights to use, copy, modify,
|
cl349@4492
|
14 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
cl349@4492
|
15 * and to permit persons to whom the Software is furnished to do so, subject to
|
cl349@4492
|
16 * the following conditions:
|
cl349@4492
|
17 *
|
cl349@4492
|
18 * The above copyright notice and this permission notice shall be included in
|
cl349@4492
|
19 * all copies or substantial portions of the Software.
|
cl349@4492
|
20 *
|
cl349@4492
|
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
cl349@4492
|
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
cl349@4492
|
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
cl349@4492
|
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
cl349@4492
|
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
cl349@4492
|
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
cl349@4492
|
27 * IN THE SOFTWARE.
|
cl349@4492
|
28 */
|
cl349@4492
|
29
|
cl349@4492
|
30 #ifndef __HYPERCALL_H__
|
cl349@4492
|
31 #define __HYPERCALL_H__
|
kaf24@6452
|
32
|
cl349@4492
|
33 #include <asm-xen/xen-public/xen.h>
|
cl349@4492
|
34
|
kaf24@6452
|
35 #define _hypercall0(type, name) \
|
kaf24@6452
|
36 ({ \
|
kaf24@6452
|
37 long __res; \
|
kaf24@6452
|
38 asm volatile ( \
|
kaf24@6452
|
39 TRAP_INSTR \
|
kaf24@6452
|
40 : "=a" (__res) \
|
kaf24@6452
|
41 : "0" (__HYPERVISOR_##name) \
|
kaf24@6452
|
42 : "memory" ); \
|
kaf24@6452
|
43 (type)__res; \
|
kaf24@6452
|
44 })
|
kaf24@6452
|
45
|
kaf24@6452
|
46 #define _hypercall1(type, name, a1) \
|
kaf24@6452
|
47 ({ \
|
kaf24@6452
|
48 long __res, __ign1; \
|
kaf24@6452
|
49 asm volatile ( \
|
kaf24@6452
|
50 TRAP_INSTR \
|
kaf24@6452
|
51 : "=a" (__res), "=b" (__ign1) \
|
kaf24@6452
|
52 : "0" (__HYPERVISOR_##name), "1" ((long)(a1)) \
|
kaf24@6452
|
53 : "memory" ); \
|
kaf24@6452
|
54 (type)__res; \
|
kaf24@6452
|
55 })
|
kaf24@6452
|
56
|
kaf24@6452
|
57 #define _hypercall2(type, name, a1, a2) \
|
kaf24@6452
|
58 ({ \
|
kaf24@6452
|
59 long __res, __ign1, __ign2; \
|
kaf24@6452
|
60 asm volatile ( \
|
kaf24@6452
|
61 TRAP_INSTR \
|
kaf24@6452
|
62 : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \
|
kaf24@6452
|
63 : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \
|
kaf24@6452
|
64 "2" ((long)(a2)) \
|
kaf24@6452
|
65 : "memory" ); \
|
kaf24@6452
|
66 (type)__res; \
|
kaf24@6452
|
67 })
|
kaf24@6452
|
68
|
kaf24@6452
|
69 #define _hypercall3(type, name, a1, a2, a3) \
|
kaf24@6452
|
70 ({ \
|
kaf24@6452
|
71 long __res, __ign1, __ign2, __ign3; \
|
kaf24@6452
|
72 asm volatile ( \
|
kaf24@6452
|
73 TRAP_INSTR \
|
kaf24@6452
|
74 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
|
kaf24@6452
|
75 "=d" (__ign3) \
|
kaf24@6452
|
76 : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \
|
kaf24@6452
|
77 "2" ((long)(a2)), "3" ((long)(a3)) \
|
kaf24@6452
|
78 : "memory" ); \
|
kaf24@6452
|
79 (type)__res; \
|
kaf24@6452
|
80 })
|
kaf24@6452
|
81
|
kaf24@6452
|
82 #define _hypercall4(type, name, a1, a2, a3, a4) \
|
kaf24@6452
|
83 ({ \
|
kaf24@6452
|
84 long __res, __ign1, __ign2, __ign3, __ign4; \
|
kaf24@6452
|
85 asm volatile ( \
|
kaf24@6452
|
86 TRAP_INSTR \
|
kaf24@6452
|
87 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
|
kaf24@6452
|
88 "=d" (__ign3), "=S" (__ign4) \
|
kaf24@6452
|
89 : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \
|
kaf24@6452
|
90 "2" ((long)(a2)), "3" ((long)(a3)), \
|
kaf24@6452
|
91 "4" ((long)(a4)) \
|
kaf24@6452
|
92 : "memory" ); \
|
kaf24@6452
|
93 (type)__res; \
|
kaf24@6452
|
94 })
|
kaf24@6452
|
95
|
kaf24@6452
|
96 #define _hypercall5(type, name, a1, a2, a3, a4, a5) \
|
kaf24@6452
|
97 ({ \
|
kaf24@6452
|
98 long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \
|
kaf24@6452
|
99 asm volatile ( \
|
kaf24@6452
|
100 TRAP_INSTR \
|
kaf24@6452
|
101 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
|
kaf24@6452
|
102 "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \
|
kaf24@6452
|
103 : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \
|
kaf24@6452
|
104 "2" ((long)(a2)), "3" ((long)(a3)), \
|
kaf24@6452
|
105 "4" ((long)(a4)), "5" ((long)(a5)) \
|
kaf24@6452
|
106 : "memory" ); \
|
kaf24@6452
|
107 (type)__res; \
|
kaf24@6452
|
108 })
|
cl349@4492
|
109
|
cl349@4492
|
110 static inline int
|
cl349@4492
|
111 HYPERVISOR_set_trap_table(
|
kaf24@6452
|
112 trap_info_t *table)
|
cl349@4492
|
113 {
|
kaf24@6452
|
114 return _hypercall1(int, set_trap_table, table);
|
cl349@4492
|
115 }
|
cl349@4492
|
116
|
cl349@4492
|
117 static inline int
|
cl349@4492
|
118 HYPERVISOR_mmu_update(
|
kaf24@6452
|
119 mmu_update_t *req, int count, int *success_count, domid_t domid)
|
cl349@4492
|
120 {
|
kaf24@6452
|
121 return _hypercall4(int, mmu_update, req, count, success_count, domid);
|
cl349@4492
|
122 }
|
cl349@4492
|
123
|
cl349@4492
|
124 static inline int
|
cl349@4492
|
125 HYPERVISOR_mmuext_op(
|
kaf24@6452
|
126 struct mmuext_op *op, int count, int *success_count, domid_t domid)
|
cl349@4492
|
127 {
|
kaf24@6452
|
128 return _hypercall4(int, mmuext_op, op, count, success_count, domid);
|
cl349@4492
|
129 }
|
cl349@4492
|
130
|
cl349@4492
|
131 static inline int
|
cl349@4492
|
132 HYPERVISOR_set_gdt(
|
kaf24@6452
|
133 unsigned long *frame_list, int entries)
|
cl349@4492
|
134 {
|
kaf24@6452
|
135 return _hypercall2(int, set_gdt, frame_list, entries);
|
cl349@4492
|
136 }
|
cl349@4492
|
137
|
cl349@4492
|
138 static inline int
|
cl349@4492
|
139 HYPERVISOR_stack_switch(
|
kaf24@6452
|
140 unsigned long ss, unsigned long esp)
|
cl349@4492
|
141 {
|
kaf24@6452
|
142 return _hypercall2(int, stack_switch, ss, esp);
|
cl349@4492
|
143 }
|
cl349@4492
|
144
|
cl349@4492
|
145 static inline int
|
cl349@4492
|
146 HYPERVISOR_set_callbacks(
|
kaf24@6452
|
147 unsigned long event_selector, unsigned long event_address,
|
kaf24@6452
|
148 unsigned long failsafe_selector, unsigned long failsafe_address)
|
cl349@4492
|
149 {
|
kaf24@6452
|
150 return _hypercall4(int, set_callbacks,
|
kaf24@6452
|
151 event_selector, event_address,
|
kaf24@6452
|
152 failsafe_selector, failsafe_address);
|
cl349@4492
|
153 }
|
cl349@4492
|
154
|
cl349@4492
|
155 static inline int
|
cl349@4492
|
156 HYPERVISOR_fpu_taskswitch(
|
kaf24@6452
|
157 int set)
|
cl349@4492
|
158 {
|
kaf24@6452
|
159 return _hypercall1(int, fpu_taskswitch, set);
|
cl349@4492
|
160 }
|
cl349@4492
|
161
|
cl349@4492
|
162 static inline int
|
cl349@4492
|
163 HYPERVISOR_yield(
|
kaf24@6452
|
164 void)
|
cl349@4492
|
165 {
|
kaf24@6452
|
166 return _hypercall2(int, sched_op, SCHEDOP_yield, 0);
|
cl349@4492
|
167 }
|
cl349@4492
|
168
|
cl349@4492
|
169 static inline int
|
cl349@4492
|
170 HYPERVISOR_block(
|
kaf24@6452
|
171 void)
|
cl349@4492
|
172 {
|
kaf24@6452
|
173 return _hypercall2(int, sched_op, SCHEDOP_block, 0);
|
cl349@4492
|
174 }
|
cl349@4492
|
175
|
cl349@4492
|
176 static inline int
|
cl349@4492
|
177 HYPERVISOR_shutdown(
|
kaf24@6452
|
178 void)
|
cl349@4492
|
179 {
|
kaf24@6452
|
180 return _hypercall2(int, sched_op, SCHEDOP_shutdown |
|
kaf24@6452
|
181 (SHUTDOWN_poweroff << SCHEDOP_reasonshift), 0);
|
cl349@4492
|
182 }
|
cl349@4492
|
183
|
cl349@4492
|
184 static inline int
|
cl349@4492
|
185 HYPERVISOR_reboot(
|
kaf24@6452
|
186 void)
|
cl349@4492
|
187 {
|
kaf24@6452
|
188 return _hypercall2(int, sched_op, SCHEDOP_shutdown |
|
kaf24@6452
|
189 (SHUTDOWN_reboot << SCHEDOP_reasonshift), 0);
|
cl349@4492
|
190 }
|
cl349@4492
|
191
|
cl349@4492
|
192 static inline int
|
cl349@4492
|
193 HYPERVISOR_crash(
|
kaf24@6452
|
194 void)
|
cl349@4492
|
195 {
|
kaf24@6452
|
196 return _hypercall2(int, sched_op, SCHEDOP_shutdown |
|
kaf24@6452
|
197 (SHUTDOWN_crash << SCHEDOP_reasonshift), 0);
|
cl349@4492
|
198 }
|
cl349@4492
|
199
|
cl349@4492
|
200 static inline long
|
cl349@4492
|
201 HYPERVISOR_set_timer_op(
|
kaf24@6452
|
202 u64 timeout)
|
cl349@4492
|
203 {
|
kaf24@6452
|
204 unsigned long timeout_hi = (unsigned long)(timeout>>32);
|
kaf24@6452
|
205 unsigned long timeout_lo = (unsigned long)timeout;
|
kaf24@6452
|
206 return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
|
cl349@4492
|
207 }
|
cl349@4492
|
208
|
cl349@4492
|
209 static inline int
|
cl349@4492
|
210 HYPERVISOR_dom0_op(
|
kaf24@6452
|
211 dom0_op_t *dom0_op)
|
cl349@4492
|
212 {
|
kaf24@6452
|
213 dom0_op->interface_version = DOM0_INTERFACE_VERSION;
|
kaf24@6452
|
214 return _hypercall1(int, dom0_op, dom0_op);
|
cl349@4492
|
215 }
|
cl349@4492
|
216
|
cl349@4492
|
217 static inline int
|
cl349@4492
|
218 HYPERVISOR_set_debugreg(
|
kaf24@6452
|
219 int reg, unsigned long value)
|
cl349@4492
|
220 {
|
kaf24@6452
|
221 return _hypercall2(int, set_debugreg, reg, value);
|
cl349@4492
|
222 }
|
cl349@4492
|
223
|
cl349@4492
|
224 static inline unsigned long
|
cl349@4492
|
225 HYPERVISOR_get_debugreg(
|
kaf24@6452
|
226 int reg)
|
cl349@4492
|
227 {
|
kaf24@6452
|
228 return _hypercall1(unsigned long, get_debugreg, reg);
|
cl349@4492
|
229 }
|
cl349@4492
|
230
|
cl349@4492
|
231 static inline int
|
cl349@4492
|
232 HYPERVISOR_update_descriptor(
|
kaf24@6452
|
233 u64 ma, u64 desc)
|
cl349@4492
|
234 {
|
kaf24@6452
|
235 return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32);
|
cl349@4492
|
236 }
|
cl349@4492
|
237
|
cl349@4492
|
238 static inline int
|
kaf24@6468
|
239 HYPERVISOR_memory_op(
|
kaf24@6468
|
240 unsigned int cmd, void *arg)
|
cl349@4492
|
241 {
|
kaf24@6468
|
242 return _hypercall2(int, memory_op, cmd, arg);
|
cl349@4492
|
243 }
|
cl349@4492
|
244
|
cl349@4492
|
245 static inline int
|
cl349@4492
|
246 HYPERVISOR_multicall(
|
kaf24@6452
|
247 void *call_list, int nr_calls)
|
cl349@4492
|
248 {
|
kaf24@6452
|
249 return _hypercall2(int, multicall, call_list, nr_calls);
|
cl349@4492
|
250 }
|
cl349@4492
|
251
|
cl349@4492
|
252 static inline int
|
cl349@4492
|
253 HYPERVISOR_update_va_mapping(
|
kaf24@6452
|
254 unsigned long va, pte_t new_val, unsigned long flags)
|
cl349@4492
|
255 {
|
kaf24@6452
|
256 unsigned long pte_hi = 0;
|
kaf24@5671
|
257 #ifdef CONFIG_X86_PAE
|
kaf24@6452
|
258 pte_hi = new_val.pte_high;
|
kaf24@5671
|
259 #endif
|
kaf24@6452
|
260 return _hypercall4(int, update_va_mapping, va,
|
kaf24@6452
|
261 new_val.pte_low, pte_hi, flags);
|
cl349@4492
|
262 }
|
cl349@4492
|
263
|
cl349@4492
|
264 static inline int
|
cl349@4492
|
265 HYPERVISOR_event_channel_op(
|
kaf24@6452
|
266 void *op)
|
cl349@4492
|
267 {
|
kaf24@6452
|
268 return _hypercall1(int, event_channel_op, op);
|
cl349@4492
|
269 }
|
cl349@4492
|
270
|
cl349@4492
|
271 static inline int
|
cl349@4492
|
272 HYPERVISOR_xen_version(
|
kaf24@6452
|
273 int cmd)
|
cl349@4492
|
274 {
|
kaf24@6452
|
275 return _hypercall1(int, xen_version, cmd);
|
cl349@4492
|
276 }
|
cl349@4492
|
277
|
cl349@4492
|
278 static inline int
|
cl349@4492
|
279 HYPERVISOR_console_io(
|
kaf24@6452
|
280 int cmd, int count, char *str)
|
cl349@4492
|
281 {
|
kaf24@6452
|
282 return _hypercall3(int, console_io, cmd, count, str);
|
cl349@4492
|
283 }
|
cl349@4492
|
284
|
cl349@4492
|
285 static inline int
|
cl349@4492
|
286 HYPERVISOR_physdev_op(
|
kaf24@6452
|
287 void *physdev_op)
|
cl349@4492
|
288 {
|
kaf24@6452
|
289 return _hypercall1(int, physdev_op, physdev_op);
|
cl349@4492
|
290 }
|
cl349@4492
|
291
|
cl349@4492
|
292 static inline int
|
cl349@4492
|
293 HYPERVISOR_grant_table_op(
|
kaf24@6452
|
294 unsigned int cmd, void *uop, unsigned int count)
|
cl349@4492
|
295 {
|
kaf24@6452
|
296 return _hypercall3(int, grant_table_op, cmd, uop, count);
|
cl349@4492
|
297 }
|
cl349@4492
|
298
|
cl349@4492
|
299 static inline int
|
cl349@4492
|
300 HYPERVISOR_update_va_mapping_otherdomain(
|
kaf24@6452
|
301 unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
|
cl349@4492
|
302 {
|
kaf24@6452
|
303 unsigned long pte_hi = 0;
|
kaf24@5671
|
304 #ifdef CONFIG_X86_PAE
|
kaf24@6452
|
305 pte_hi = new_val.pte_high;
|
kaf24@5671
|
306 #endif
|
kaf24@6452
|
307 return _hypercall5(int, update_va_mapping_otherdomain, va,
|
kaf24@6452
|
308 new_val.pte_low, pte_hi, flags, domid);
|
cl349@4492
|
309 }
|
cl349@4492
|
310
|
cl349@4492
|
311 static inline int
|
cl349@4492
|
312 HYPERVISOR_vm_assist(
|
kaf24@6452
|
313 unsigned int cmd, unsigned int type)
|
cl349@4492
|
314 {
|
kaf24@6452
|
315 return _hypercall2(int, vm_assist, cmd, type);
|
cl349@4492
|
316 }
|
cl349@4492
|
317
|
cl349@4492
|
318 static inline int
|
cl349@4492
|
319 HYPERVISOR_boot_vcpu(
|
kaf24@6452
|
320 unsigned long vcpu, vcpu_guest_context_t *ctxt)
|
cl349@4492
|
321 {
|
kaf24@6452
|
322 return _hypercall2(int, boot_vcpu, vcpu, ctxt);
|
kaf24@6452
|
323 }
|
kaf24@6452
|
324
|
kaf24@6452
|
325 static inline int
|
kaf24@6452
|
326 HYPERVISOR_vcpu_up(
|
kaf24@6452
|
327 int vcpu)
|
kaf24@6452
|
328 {
|
kaf24@6452
|
329 return _hypercall2(int, sched_op, SCHEDOP_vcpu_up |
|
kaf24@6452
|
330 (vcpu << SCHEDOP_vcpushift), 0);
|
kaf24@6452
|
331 }
|
cl349@4492
|
332
|
kaf24@6452
|
333 static inline int
|
kaf24@6452
|
334 HYPERVISOR_vcpu_pickle(
|
kaf24@6452
|
335 int vcpu, vcpu_guest_context_t *ctxt)
|
kaf24@6452
|
336 {
|
kaf24@6452
|
337 return _hypercall2(int, sched_op, SCHEDOP_vcpu_pickle |
|
kaf24@6452
|
338 (vcpu << SCHEDOP_vcpushift), ctxt);
|
kaf24@6452
|
339 }
|
cl349@4492
|
340
|
kaf24@6452
|
341 static inline int
|
kaf24@6452
|
342 HYPERVISOR_suspend(
|
kaf24@6452
|
343 unsigned long srec)
|
kaf24@6452
|
344 {
|
kaf24@6452
|
345 int ret;
|
kaf24@6452
|
346 unsigned long ign1, ign2;
|
kaf24@6452
|
347
|
kaf24@6452
|
348 /* On suspend, control software expects a suspend record in %esi. */
|
kaf24@6452
|
349 __asm__ __volatile__ (
|
kaf24@6452
|
350 TRAP_INSTR
|
kaf24@6452
|
351 : "=a" (ret), "=b" (ign1), "=S" (ign2)
|
kaf24@6452
|
352 : "0" (__HYPERVISOR_sched_op),
|
kaf24@6452
|
353 "1" (SCHEDOP_shutdown | (SHUTDOWN_suspend <<
|
kaf24@6452
|
354 SCHEDOP_reasonshift)),
|
kaf24@6452
|
355 "2" (srec) : "memory", "ecx");
|
kaf24@6452
|
356
|
kaf24@6452
|
357 return ret;
|
cl349@4492
|
358 }
|
cl349@4492
|
359
|
cl349@5523
|
360 static inline int
|
cl349@5523
|
361 HYPERVISOR_vcpu_down(
|
kaf24@6452
|
362 int vcpu)
|
cl349@5523
|
363 {
|
kaf24@6452
|
364 int ret;
|
kaf24@6452
|
365 unsigned long ign1;
|
kaf24@6452
|
366 /* Yes, I really do want to clobber edx here: when we resume a
|
kaf24@6452
|
367 vcpu after unpickling a multi-processor domain, it returns
|
kaf24@6452
|
368 here, but clobbers all of the call clobbered registers. */
|
kaf24@6452
|
369 __asm__ __volatile__ (
|
kaf24@6452
|
370 TRAP_INSTR
|
kaf24@6452
|
371 : "=a" (ret), "=b" (ign1)
|
kaf24@6452
|
372 : "0" (__HYPERVISOR_sched_op),
|
kaf24@6452
|
373 "1" (SCHEDOP_vcpu_down | (vcpu << SCHEDOP_vcpushift))
|
kaf24@6452
|
374 : "memory", "ecx", "edx" );
|
kaf24@6452
|
375 return ret;
|
cl349@5523
|
376 }
|
sos22@6268
|
377
|
cl349@4492
|
378 #endif /* __HYPERCALL_H__ */
|
kaf24@6452
|
379
|
kaf24@6452
|
380 /*
|
kaf24@6452
|
381 * Local variables:
|
kaf24@6452
|
382 * c-file-style: "linux"
|
kaf24@6452
|
383 * indent-tabs-mode: t
|
kaf24@6452
|
384 * c-indent-level: 8
|
kaf24@6452
|
385 * c-basic-offset: 8
|
kaf24@6452
|
386 * tab-width: 8
|
kaf24@6452
|
387 * End:
|
kaf24@6452
|
388 */
|