This commit was generated by cvs2svn to compensate for changes in r925,
[linux-2.6.git] / include / asm-xen / asm-x86_64 / hypercall.h
1 /******************************************************************************
2  * hypercall.h
3  * 
4  * Linux-specific hypervisor handling.
5  * 
6  * Copyright (c) 2002-2004, K A Fraser
7  * 
8  * This file may be distributed separately from the Linux kernel, or
9  * incorporated into other software packages, subject to the following license:
10  * 
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this source file (the "Software"), to deal in the Software without
13  * restriction, including without limitation the rights to use, copy, modify,
14  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
15  * and to permit persons to whom the Software is furnished to do so, subject to
16  * the following conditions:
17  * 
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20  * 
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27  * IN THE SOFTWARE.
28  */
29 /*
30  * Benjamin Liu <benjamin.liu@intel.com>
31  * Jun Nakajima <jun.nakajima@intel.com>
32  *   Ported to x86-64.
33  * 
34  */
35
36 #ifndef __HYPERCALL_H__
37 #define __HYPERCALL_H__
38 #include <asm-xen/xen-public/xen.h>
39
40 #define __syscall_clobber "r11","rcx","memory"
41
42 /*
43  * Assembler stubs for hyper-calls.
44  */
45 static inline int
46 HYPERVISOR_set_trap_table(
47     trap_info_t *table)
48 {
49     int ret;
50
51     __asm__ __volatile__ (
52         TRAP_INSTR
53         : "=a" (ret)
54         : "0" ((unsigned long)__HYPERVISOR_set_trap_table), "D" (table)
55         : __syscall_clobber );
56
57     return ret;
58 }
59
60 static inline int
61 HYPERVISOR_mmu_update(
62     mmu_update_t *req, int count, int *success_count, domid_t domid)
63 {
64     int ret;
65
66     __asm__ __volatile__ (
67         "movq %5, %%r10;" TRAP_INSTR
68         : "=a" (ret)
69         : "0" ((unsigned long)__HYPERVISOR_mmu_update), "D" (req), "S" ((long)count),
70           "d" (success_count), "g" ((unsigned long)domid)
71         : __syscall_clobber, "r10" );
72
73     return ret;
74 }
75
76 static inline int
77 HYPERVISOR_mmuext_op(
78     struct mmuext_op *op, int count, int *success_count, domid_t domid)
79 {
80     int ret;
81
82     __asm__ __volatile__ (
83         "movq %5, %%r10;" TRAP_INSTR
84         : "=a" (ret)
85         : "0" (__HYPERVISOR_mmuext_op), "D" (op), "S" ((long)count), 
86           "d" (success_count), "g" ((unsigned long)domid)
87         : __syscall_clobber, "r10" );
88
89     return ret;
90 }
91
92 static inline int
93 HYPERVISOR_set_gdt(
94     unsigned long *frame_list, int entries)
95 {
96     int ret;
97
98     __asm__ __volatile__ (
99         TRAP_INSTR
100         : "=a" (ret)
101         : "0" ((unsigned long)__HYPERVISOR_set_gdt), "D" (frame_list), "S" ((long)entries)
102         : __syscall_clobber );
103
104
105     return ret;
106 }
107 static inline int
108 HYPERVISOR_stack_switch(
109     unsigned long ss, unsigned long esp)
110 {
111     int ret;
112
113     __asm__ __volatile__ (
114         TRAP_INSTR
115         : "=a" (ret)
116         : "0" ((unsigned long)__HYPERVISOR_stack_switch), "D" (ss), "S" (esp)
117         : __syscall_clobber );
118
119     return ret;
120 }
121
122 static inline int
123 HYPERVISOR_set_callbacks(
124     unsigned long event_address, unsigned long failsafe_address, 
125     unsigned long syscall_address)
126 {
127     int ret;
128
129     __asm__ __volatile__ (
130         TRAP_INSTR
131         : "=a" (ret)
132         : "0" ((unsigned long)__HYPERVISOR_set_callbacks), "D" (event_address),
133           "S" (failsafe_address), "d" (syscall_address)
134         : __syscall_clobber );
135
136     return ret;
137 }
138
139 static inline int
140 HYPERVISOR_fpu_taskswitch(
141     int set)
142 {
143     int ret;
144     __asm__ __volatile__ (
145         TRAP_INSTR
146         : "=a" (ret) : "0" ((unsigned long)__HYPERVISOR_fpu_taskswitch),
147           "D" ((unsigned long) set) : __syscall_clobber );
148
149     return ret;
150 }
151
152 static inline int
153 HYPERVISOR_yield(
154     void)
155 {
156     int ret;
157
158     __asm__ __volatile__ (
159         TRAP_INSTR
160         : "=a" (ret)
161         : "0" ((unsigned long)__HYPERVISOR_sched_op), "D" ((unsigned long)SCHEDOP_yield)
162         : __syscall_clobber );
163
164     return ret;
165 }
166
167 static inline int
168 HYPERVISOR_block(
169     void)
170 {
171     int ret;
172     __asm__ __volatile__ (
173         TRAP_INSTR
174         : "=a" (ret)
175         : "0" ((unsigned long)__HYPERVISOR_sched_op), "D" ((unsigned long)SCHEDOP_block)
176         : __syscall_clobber );
177
178     return ret;
179 }
180
181 static inline int
182 HYPERVISOR_shutdown(
183     void)
184 {
185     int ret;
186     __asm__ __volatile__ (
187         TRAP_INSTR
188         : "=a" (ret)
189         : "0" ((unsigned long)__HYPERVISOR_sched_op),
190           "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)))
191         : __syscall_clobber );
192
193     return ret;
194 }
195
196 static inline int
197 HYPERVISOR_reboot(
198     void)
199 {
200     int ret;
201
202     __asm__ __volatile__ (
203         TRAP_INSTR
204         : "=a" (ret)
205         : "0" ((unsigned long)__HYPERVISOR_sched_op),
206           "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)))
207         : __syscall_clobber );
208
209     return ret;
210 }
211
212 static inline int
213 HYPERVISOR_suspend(
214     unsigned long srec)
215 {
216     int ret;
217
218     /* NB. On suspend, control software expects a suspend record in %esi. */
219     __asm__ __volatile__ (
220         TRAP_INSTR
221         : "=a" (ret)
222         : "0" ((unsigned long)__HYPERVISOR_sched_op),
223         "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift))), 
224         "S" (srec)
225         : __syscall_clobber );
226
227     return ret;
228 }
229
230 /*
231  * We can have the timeout value in a single argument for the hypercall, but
232  * that will break the common code. 
233  */
234 static inline long
235 HYPERVISOR_set_timer_op(
236     u64 timeout)
237 {
238     int ret;
239
240     __asm__ __volatile__ (
241         TRAP_INSTR
242         : "=a" (ret)
243         : "0" ((unsigned long)__HYPERVISOR_set_timer_op),
244           "D" (timeout)
245         : __syscall_clobber );
246
247     return ret;
248 }
249
250 static inline int
251 HYPERVISOR_dom0_op(
252     dom0_op_t *dom0_op)
253 {
254     int ret;
255
256     dom0_op->interface_version = DOM0_INTERFACE_VERSION;
257     __asm__ __volatile__ (
258         TRAP_INSTR
259         : "=a" (ret)
260         : "0" ((unsigned long)__HYPERVISOR_dom0_op), "D" (dom0_op)
261         : __syscall_clobber );
262
263     return ret;
264 }
265
266 static inline int
267 HYPERVISOR_set_debugreg(
268     int reg, unsigned long value)
269 {
270     int ret;
271
272     __asm__ __volatile__ (
273         TRAP_INSTR
274         : "=a" (ret)
275         : "0" ((unsigned long)__HYPERVISOR_set_debugreg), "D" ((unsigned long)reg), "S" (value)
276         : __syscall_clobber );
277
278     return ret;
279 }
280
281 static inline unsigned long
282 HYPERVISOR_get_debugreg(
283     int reg)
284 {
285     unsigned long ret;
286
287     __asm__ __volatile__ (
288         TRAP_INSTR
289         : "=a" (ret)
290         : "0" ((unsigned long)__HYPERVISOR_get_debugreg), "D" ((unsigned long)reg)
291         : __syscall_clobber );
292
293     return ret;
294 }
295
296 static inline int
297 HYPERVISOR_update_descriptor(
298     unsigned long ma, unsigned long word)
299 {
300     int ret;
301
302     __asm__ __volatile__ (
303         TRAP_INSTR
304         : "=a" (ret)
305         : "0" ((unsigned long)__HYPERVISOR_update_descriptor), "D" (ma),
306           "S" (word)
307         : __syscall_clobber );
308
309     return ret;
310 }
311
312 static inline int
313 HYPERVISOR_set_fast_trap(
314     int idx)
315 {
316     int ret;
317
318     __asm__ __volatile__ (
319         TRAP_INSTR
320         : "=a" (ret)
321         : "0" ((unsigned long)__HYPERVISOR_set_fast_trap), "D" ((unsigned long)idx)
322         : __syscall_clobber );
323
324     return ret;
325 }
326
327 static inline int
328 HYPERVISOR_dom_mem_op(
329     unsigned int op, unsigned long *extent_list,
330     unsigned long nr_extents, unsigned int extent_order)
331 {
332     int ret;
333
334     __asm__ __volatile__ (
335         "movq %5,%%r10; movq %6,%%r8;" TRAP_INSTR
336         : "=a" (ret)
337         : "0" ((unsigned long)__HYPERVISOR_dom_mem_op), "D" ((unsigned long)op), "S" (extent_list),
338           "d" (nr_extents), "g" ((unsigned long) extent_order), "g" ((unsigned long) DOMID_SELF)
339         : __syscall_clobber,"r8","r10");
340
341     return ret;
342 }
343
344 static inline int
345 HYPERVISOR_multicall(
346     void *call_list, int nr_calls)
347 {
348     int ret;
349
350     __asm__ __volatile__ (
351         TRAP_INSTR
352         : "=a" (ret)
353         : "0" ((unsigned long)__HYPERVISOR_multicall), "D" (call_list), "S" ((unsigned long)nr_calls)
354         : __syscall_clobber);
355
356     return ret;
357 }
358
359 static inline int
360 HYPERVISOR_update_va_mapping(
361     unsigned long page_nr, pte_t new_val, unsigned long flags)
362 {
363     int ret;
364
365     __asm__ __volatile__ (
366         TRAP_INSTR
367         : "=a" (ret)
368         : "0" ((unsigned long)__HYPERVISOR_update_va_mapping), 
369           "D" (page_nr), "S" (new_val.pte), "d" (flags)
370         : __syscall_clobber);
371
372     return ret;
373 }
374
375 static inline int
376 HYPERVISOR_event_channel_op(
377     void *op)
378 {
379     int ret;
380     __asm__ __volatile__ (
381         TRAP_INSTR
382         : "=a" (ret)
383         : "0" ((unsigned long)__HYPERVISOR_event_channel_op), "D" (op)
384         : __syscall_clobber);
385
386     return ret;
387 }
388
389 static inline int
390 HYPERVISOR_xen_version(
391     int cmd)
392 {
393     int ret;
394
395     __asm__ __volatile__ (
396         TRAP_INSTR
397         : "=a" (ret)
398         : "0" ((unsigned long)__HYPERVISOR_xen_version), "D" ((unsigned long)cmd)
399         : __syscall_clobber);
400
401     return ret;
402 }
403
404 static inline int
405 HYPERVISOR_console_io(
406     int cmd, int count, char *str)
407 {
408     int ret;
409     __asm__ __volatile__ (
410         TRAP_INSTR
411         : "=a" (ret)
412         : "0" ((unsigned long)__HYPERVISOR_console_io), "D" ((unsigned long)cmd), "S" ((unsigned long)count), "d" (str)
413         : __syscall_clobber);
414
415     return ret;
416 }
417
418 static inline int
419 HYPERVISOR_physdev_op(
420     void *physdev_op)
421 {
422     int ret;
423
424     __asm__ __volatile__ (
425         TRAP_INSTR
426         : "=a" (ret)
427         : "0" ((unsigned long)__HYPERVISOR_physdev_op), "D" (physdev_op)
428         : __syscall_clobber);
429
430     return ret;
431 }
432
433 static inline int
434 HYPERVISOR_grant_table_op(
435     unsigned int cmd, void *uop, unsigned int count)
436 {
437     int ret;
438
439     __asm__ __volatile__ (
440         TRAP_INSTR
441         : "=a" (ret)
442         : "0" ((unsigned long)__HYPERVISOR_grant_table_op), "D" ((unsigned long)cmd), "S" ((unsigned long)uop), "d" (count)
443         : __syscall_clobber);
444
445     return ret;
446 }
447
448 static inline int
449 HYPERVISOR_update_va_mapping_otherdomain(
450     unsigned long page_nr, pte_t new_val, unsigned long flags, domid_t domid)
451 {
452     int ret;
453
454     __asm__ __volatile__ (
455         "movq %5, %%r10;" TRAP_INSTR
456         : "=a" (ret)
457         : "0" ((unsigned long)__HYPERVISOR_update_va_mapping_otherdomain),
458           "D" (page_nr), "S" (new_val.pte), "d" (flags), "g" ((unsigned long)domid)
459         : __syscall_clobber,"r10");
460     
461     return ret;
462 }
463
464 static inline int
465 HYPERVISOR_vm_assist(
466     unsigned int cmd, unsigned int type)
467 {
468     int ret;
469
470     __asm__ __volatile__ (
471         TRAP_INSTR
472         : "=a" (ret)
473         : "0" ((unsigned long)__HYPERVISOR_vm_assist), "D" ((unsigned long)cmd), "S" ((unsigned long)type)
474         : __syscall_clobber);
475
476     return ret;
477 }
478
479 static inline int
480 HYPERVISOR_switch_to_user(void)
481 {
482     int ret;
483     __asm__ __volatile__ (
484         TRAP_INSTR
485         : "=a" (ret) : "0" ((unsigned long)__HYPERVISOR_switch_to_user) : __syscall_clobber );
486
487     return ret;
488 }
489
490 static inline int
491 HYPERVISOR_boot_vcpu(
492     unsigned long vcpu, full_execution_context_t *ctxt)
493 {
494     int ret;
495
496     __asm__ __volatile__ (
497         TRAP_INSTR
498         : "=a" (ret)
499         : "0" (__HYPERVISOR_boot_vcpu), "D" (vcpu), "S" (ctxt)
500         : __syscall_clobber);
501
502     return ret;
503 }
504
505 static inline int
506 HYPERVISOR_set_segment_base(
507     int reg, unsigned long value)
508 {
509     int ret;
510
511     __asm__ __volatile__ (
512         TRAP_INSTR
513         : "=a" (ret)
514         : "0" ((unsigned long)__HYPERVISOR_set_segment_base), "D" ((unsigned long)reg), "S" (value)
515         : __syscall_clobber );
516
517     return ret;
518 }
519
520 #endif /* __HYPERCALL_H__ */