hypervisor.h revision 1.14.2.2 1 /* $NetBSD: hypervisor.h,v 1.14.2.2 2006/12/30 20:47:25 yamt Exp $ */
2
3 /*
4 * Copyright (c) 2006 Manuel Bouyer.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Manuel Bouyer.
17 * 4. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33 /*
34 *
35 * Communication to/from hypervisor.
36 *
37 * Copyright (c) 2002-2004, K A Fraser
38 *
39 * Permission is hereby granted, free of charge, to any person obtaining a copy
40 * of this source file (the "Software"), to deal in the Software without
41 * restriction, including without limitation the rights to use, copy, modify,
42 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
43 * and to permit persons to whom the Software is furnished to do so, subject to
44 * the following conditions:
45 *
46 * The above copyright notice and this permission notice shall be included in
47 * all copies or substantial portions of the Software.
48 *
49 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
54 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
55 * IN THE SOFTWARE.
56 */
57
58
59 #ifndef _XEN_HYPERVISOR_H_
60 #define _XEN_HYPERVISOR_H_
61
62 #include "opt_xen.h"
63
64
65 struct hypervisor_attach_args {
66 const char *haa_busname;
67 };
68
69 struct xencons_attach_args {
70 const char *xa_device;
71 };
72
73 struct xen_npx_attach_args {
74 const char *xa_device;
75 };
76
77
78 #define u8 uint8_t
79 #define u16 uint16_t
80 #define u32 uint32_t
81 #define u64 uint64_t
82 #define s8 int8_t
83 #define s16 int16_t
84 #define s32 int32_t
85 #define s64 int64_t
86
87 #ifdef XEN3
88 #include <machine/xen3-public/xen.h>
89 #include <machine/xen3-public/sched.h>
90 #include <machine/xen3-public/dom0_ops.h>
91 #include <machine/xen3-public/event_channel.h>
92 #include <machine/xen3-public/physdev.h>
93 #include <machine/xen3-public/memory.h>
94 #include <machine/xen3-public/io/netif.h>
95 #include <machine/xen3-public/io/blkif.h>
96 #else
97 #include <machine/xen-public/xen.h>
98 #include <machine/xen-public/dom0_ops.h>
99 #include <machine/xen-public/event_channel.h>
100 #include <machine/xen-public/physdev.h>
101 #include <machine/xen-public/io/domain_controller.h>
102 #include <machine/xen-public/io/netif.h>
103 #include <machine/xen-public/io/blkif.h>
104 #endif
105
106 #undef u8
107 #undef u16
108 #undef u32
109 #undef u64
110 #undef s8
111 #undef s16
112 #undef s32
113 #undef s64
114
115
116 /*
117 * a placeholder for the start of day information passed up from the hypervisor
118 */
119 union start_info_union
120 {
121 start_info_t start_info;
122 char padding[512];
123 };
124 extern union start_info_union start_info_union;
125 #define xen_start_info (start_info_union.start_info)
126
127 /* For use in guest OSes. */
128 volatile extern shared_info_t *HYPERVISOR_shared_info;
129
130 /* hypervisor.c */
131 struct intrframe;
132 void do_hypervisor_callback(struct intrframe *regs);
133 void hypervisor_enable_event(unsigned int);
134
135 /* hypervisor_machdep.c */
136 void hypervisor_unmask_event(unsigned int);
137 void hypervisor_mask_event(unsigned int);
138 void hypervisor_clear_event(unsigned int);
139 void hypervisor_enable_ipl(unsigned int);
140 void hypervisor_set_ipending(u_int32_t, int, int);
141
142 /*
143 * Assembler stubs for hyper-calls.
144 */
145
146 #if defined(XEN3) && !defined(XEN_COMPAT_030001)
147 /* hypercall via the hypercall call page */
148 #define __str(x) #x
149 #define _str(x) __str(x)
150 #define _hypercall(name, input_const, output_const) \
151 __asm volatile ( \
152 "call hypercall_page + ("_str(name)" * 32)" \
153 : output_const \
154 : input_const \
155 : "memory" )
156 #else
157 /* traditionnal hypercall via int 0x82 */
158 #define _hypercall(name, input_const, output_const) \
159 __asm volatile ( \
160 TRAP_INSTR \
161 : output_const \
162 : "0" (name), input_const \
163 : "memory" )
164 #endif
165
166 #define _harg(...) __VA_ARGS__
167
168
169 static __inline int
170 HYPERVISOR_set_trap_table(trap_info_t *table)
171 {
172 int ret;
173 unsigned long ign1;
174
175 _hypercall(__HYPERVISOR_set_trap_table, _harg("1" (table)),
176 _harg("=a" (ret), "=b" (ign1)));
177
178 return ret;
179 }
180
181 static __inline int
182 HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
183 {
184 int ret;
185 unsigned long ign1, ign2;
186
187 _hypercall(__HYPERVISOR_set_gdt, _harg("1" (frame_list), "2" (entries)),
188 _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
189
190 return ret;
191 }
192
193 static __inline int
194 HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
195 {
196 int ret;
197 unsigned long ign1, ign2;
198
199 _hypercall(__HYPERVISOR_stack_switch, _harg("1" (ss), "2" (esp)),
200 _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
201
202 return ret;
203 }
204
205 static __inline int
206 HYPERVISOR_set_callbacks(
207 unsigned long event_selector, unsigned long event_address,
208 unsigned long failsafe_selector, unsigned long failsafe_address)
209 {
210 int ret;
211 unsigned long ign1, ign2, ign3, ign4;
212
213 _hypercall(__HYPERVISOR_set_callbacks,
214 _harg("1" (event_selector),"2" (event_address),
215 "3" (failsafe_selector), "4" (failsafe_address)),
216 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)));
217
218 return ret;
219 }
220
221 static __inline int
222 HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
223 {
224 int ret;
225 unsigned long ign1;
226
227 dom0_op->interface_version = DOM0_INTERFACE_VERSION;
228 _hypercall(__HYPERVISOR_dom0_op, _harg("1" (dom0_op)),
229 _harg("=a" (ret), "=b" (ign1)));
230
231 return ret;
232 }
233
234 static __inline int
235 HYPERVISOR_set_debugreg(int reg, unsigned long value)
236 {
237 int ret;
238 unsigned long ign1, ign2;
239
240 _hypercall(__HYPERVISOR_set_debugreg, _harg("1" (reg), "2" (value)),
241 _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
242
243 return ret;
244 }
245
246 static __inline unsigned long
247 HYPERVISOR_get_debugreg(int reg)
248 {
249 unsigned long ret;
250 unsigned long ign1;
251
252 _hypercall(__HYPERVISOR_get_debugreg, _harg("1" (reg)),
253 _harg("=a" (ret), "=b" (ign1)));
254
255 return ret;
256 }
257
258 #ifdef XEN3
259 static __inline int
260 HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count,
261 domid_t domid)
262 {
263 int ret;
264 unsigned long ign1, ign2, ign3, ign4;
265
266 _hypercall(__HYPERVISOR_mmu_update,
267 _harg("1" (req), "2" (count), "3" (success_count), "4" (domid)),
268 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)));
269
270 return ret;
271 }
272
273 static __inline int
274 HYPERVISOR_mmuext_op(struct mmuext_op *op, int count, int *success_count,
275 domid_t domid)
276 {
277 int ret;
278 unsigned long ign1, ign2, ign3, ign4;
279
280 _hypercall(__HYPERVISOR_mmuext_op,
281 _harg("1" (op), "2" (count), "3" (success_count), "4" (domid)),
282 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)));
283
284 return ret;
285 }
286
287 #if 0
288 static __inline int
289 HYPERVISOR_fpu_taskswitch(int set)
290 {
291 long ret;
292 long ign1;
293
294 _hypercall(__HYPERVISOR_fpu_taskswitch, _harg("1" (set)),
295 _harg("=a" (ret), "=b" (ign1)));
296
297 return ret;
298 }
299 #else /* 0 */
300 /* Xen2 compat: always i38HYPERVISOR_fpu_taskswitch(1) */
301 static __inline int
302 HYPERVISOR_fpu_taskswitch(void)
303 {
304 long ret;
305 long ign1;
306 _hypercall(__HYPERVISOR_fpu_taskswitch, _harg("1" (1)),
307 _harg("=a" (ret), "=b" (ign1)));
308
309 return ret;
310 }
311 #endif /* 0 */
312
313 static __inline int
314 HYPERVISOR_update_descriptor(uint64_t ma, uint32_t word1, uint32_t word2)
315 {
316 int ret;
317 unsigned long ign1, ign2, ign3, ign4;
318 int ma1 = ma & 0xffffffff;
319 int ma2 = (ma >> 32) & 0xffffffff;
320
321 _hypercall(__HYPERVISOR_update_descriptor,
322 _harg("1" (ma1), "2" (ma2), "3" (word1), "4" (word2)),
323 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)));
324
325 return ret;
326 }
327
328 static __inline int
329 HYPERVISOR_memory_op(unsigned int cmd, void *arg)
330 {
331 int ret;
332 unsigned long ign1, ign2;
333
334 _hypercall(__HYPERVISOR_memory_op, _harg("1" (cmd), "2" (arg)),
335 _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
336
337 return ret;
338 }
339
340 static __inline int
341 HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
342 unsigned long flags)
343 {
344 int ret;
345 unsigned long ign1, ign2, ign3, ign4;
346
347 _hypercall(__HYPERVISOR_update_va_mapping,
348 _harg("1" (page_nr), "2" (new_val), "3" (0), "4" (flags)),
349 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)));
350
351 #ifdef notdef
352 if (__predict_false(ret < 0))
353 panic("Failed update VA mapping: %08lx, %08lx, %08lx",
354 page_nr, new_val, flags);
355 #endif
356
357 return ret;
358 }
359
360 static __inline int
361 HYPERVISOR_xen_version(int cmd, void *arg)
362 {
363 int ret;
364 unsigned long ign1, ign2;
365
366 _hypercall(__HYPERVISOR_xen_version, _harg("1" (cmd), "2" (arg)),
367 _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
368
369 return ret;
370 }
371
372 static __inline int
373 HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
374 {
375 int ret;
376 unsigned long ign1, ign2, ign3;
377
378 _hypercall(__HYPERVISOR_grant_table_op,
379 _harg("1" (cmd), "2" (uop), "3" (count)),
380 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)));
381
382 return ret;
383 }
384
385 static __inline int
386 HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
387 unsigned long new_val, unsigned long flags, domid_t domid)
388 {
389 int ret;
390 unsigned long ign1, ign2, ign3, ign4, ign5;
391
392 _hypercall(__HYPERVISOR_update_va_mapping_otherdomain,
393 _harg("1" (page_nr), "2" (new_val), "3" (0), "4" (flags), "5" (domid)),
394 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
395 "=D" (ign5)));
396
397 return ret;
398 }
399
400 static __inline int
401 HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args)
402 {
403 long ret;
404 unsigned long ign1, ign2, ign3;
405
406 _hypercall(__HYPERVISOR_vcpu_op,
407 _harg("1" (cmd), "2" (vcpuid), "3" (extra_args)),
408 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)));
409
410 return ret;
411 }
412
413 static __inline long
414 HYPERVISOR_yield(void)
415 {
416 long ret;
417 unsigned long ign1, ign2;
418
419 _hypercall(__HYPERVISOR_sched_op, _harg("1" (SCHEDOP_yield), "2" (0)),
420 _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
421
422 return ret;
423 }
424
425 static __inline long
426 HYPERVISOR_block(void)
427 {
428 long ret;
429 unsigned long ign1, ign2;
430
431 _hypercall(__HYPERVISOR_sched_op, _harg("1" (SCHEDOP_block), "2" (0)),
432 _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
433
434 return ret;
435 }
436
437 static __inline long
438 HYPERVISOR_shutdown(void)
439 {
440 long ret;
441 unsigned long ign1, ign2;
442
443 _hypercall(__HYPERVISOR_sched_op,
444 _harg("1" (SCHEDOP_shutdown), "2" (SHUTDOWN_poweroff)),
445 _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
446
447 return ret;
448 }
449
450 static __inline long
451 HYPERVISOR_reboot(void)
452 {
453 long ret;
454 unsigned long ign1, ign2;
455
456 _hypercall(__HYPERVISOR_sched_op,
457 _harg("1" (SCHEDOP_shutdown), "2" (SHUTDOWN_reboot)),
458 _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
459
460 return ret;
461 }
462
463 static __inline long
464 HYPERVISOR_suspend(unsigned long srec)
465 {
466 long ret;
467 unsigned long ign1, ign2, ign3;
468
469 _hypercall(__HYPERVISOR_sched_op,
470 _harg("1" (SCHEDOP_shutdown), "2" (SHUTDOWN_suspend), "3" (srec)),
471 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)));
472
473 return ret;
474 }
475
476 static __inline long
477 HYPERVISOR_set_timer_op(uint64_t timeout)
478 {
479 long ret;
480 unsigned long timeout_hi = (unsigned long)(timeout>>32);
481 unsigned long timeout_lo = (unsigned long)timeout;
482 unsigned long ign1, ign2;
483
484 _hypercall(__HYPERVISOR_set_timer_op,
485 _harg("1" (timeout_lo), "2" (timeout_hi)),
486 _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
487
488 return ret;
489 }
490 #else /* !XEN3 */
491 static __inline int
492 HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count)
493 {
494 int ret;
495 unsigned long ign1, ign2, ign3;
496
497 __asm__ __volatile__ (
498 TRAP_INSTR
499 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
500 : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
501 "3" (success_count)
502 : "memory" );
503
504 return ret;
505 }
506
507 static __inline int
508 HYPERVISOR_fpu_taskswitch(void)
509 {
510 int ret;
511 __asm volatile (
512 TRAP_INSTR
513 : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" );
514
515 return ret;
516 }
517
518 static __inline int
519 HYPERVISOR_update_descriptor(unsigned long pa, unsigned long word1,
520 unsigned long word2)
521 {
522 int ret;
523 unsigned long ign1, ign2, ign3;
524
525 __asm volatile (
526 TRAP_INSTR
527 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
528 : "0" (__HYPERVISOR_update_descriptor), "1" (pa), "2" (word1),
529 "3" (word2)
530 : "memory" );
531
532 return ret;
533 }
534
535 static __inline int
536 HYPERVISOR_yield(void)
537 {
538 int ret;
539 unsigned long ign1;
540
541 __asm__ __volatile__ (
542 TRAP_INSTR
543 : "=a" (ret), "=b" (ign1)
544 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
545 : "memory" );
546
547 return ret;
548 }
549
550 static __inline int
551 HYPERVISOR_block(void)
552 {
553 int ret;
554 unsigned long ign1;
555
556 __asm__ __volatile__ (
557 TRAP_INSTR
558 : "=a" (ret), "=b" (ign1)
559 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
560 : "memory" );
561
562 return ret;
563 }
564
565 static __inline int
566 HYPERVISOR_shutdown(void)
567 {
568 int ret;
569 unsigned long ign1;
570
571 __asm__ __volatile__ (
572 TRAP_INSTR
573 : "=a" (ret), "=b" (ign1)
574 : "0" (__HYPERVISOR_sched_op),
575 "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
576 : "memory" );
577
578 return ret;
579 }
580
581 static __inline int
582 HYPERVISOR_reboot(void)
583 {
584 int ret;
585 unsigned long ign1;
586
587 __asm__ __volatile__ (
588 TRAP_INSTR
589 : "=a" (ret), "=b" (ign1)
590 : "0" (__HYPERVISOR_sched_op),
591 "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
592 : "memory" );
593
594 return ret;
595 }
596
597 static __inline int
598 HYPERVISOR_suspend(unsigned long srec)
599 {
600 int ret;
601 unsigned long ign1, ign2;
602
603 /* NB. On suspend, control software expects a suspend record in %esi. */
604 __asm__ __volatile__ (
605 TRAP_INSTR
606 : "=a" (ret), "=b" (ign1), "=S" (ign2)
607 : "0" (__HYPERVISOR_sched_op),
608 "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
609 "S" (srec) : "memory");
610
611 return ret;
612 }
613
614 static __inline int
615 HYPERVISOR_set_fast_trap(int idx)
616 {
617 int ret;
618 unsigned long ign1;
619
620 __asm volatile (
621 TRAP_INSTR
622 : "=a" (ret), "=b" (ign1)
623 : "0" (__HYPERVISOR_set_fast_trap), "1" (idx)
624 : "memory" );
625
626 return ret;
627 }
628
629 static __inline int
630 HYPERVISOR_dom_mem_op(unsigned int op, unsigned long *extent_list,
631 unsigned long nr_extents, unsigned int extent_order)
632 {
633 int ret;
634 unsigned long ign1, ign2, ign3, ign4, ign5;
635
636 __asm volatile (
637 TRAP_INSTR
638 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
639 "=D" (ign5)
640 : "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list),
641 "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF)
642 : "memory" );
643
644 return ret;
645 }
646
647 static __inline int
648 HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
649 unsigned long flags)
650 {
651 int ret;
652 unsigned long ign1, ign2, ign3;
653
654 __asm volatile (
655 TRAP_INSTR
656 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
657 : "0" (__HYPERVISOR_update_va_mapping),
658 "1" (page_nr), "2" (new_val), "3" (flags)
659 : "memory" );
660
661 #ifdef notdef
662 if (__predict_false(ret < 0))
663 panic("Failed update VA mapping: %08lx, %08lx, %08lx",
664 page_nr, new_val, flags);
665 #endif
666
667 return ret;
668 }
669
670 static __inline int
671 HYPERVISOR_xen_version(int cmd)
672 {
673 int ret;
674 unsigned long ign1;
675
676 __asm volatile (
677 TRAP_INSTR
678 : "=a" (ret), "=b" (ign1)
679 : "0" (__HYPERVISOR_xen_version), "1" (cmd)
680 : "memory" );
681
682 return ret;
683 }
684
685 static __inline int
686 HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
687 {
688 int ret;
689 unsigned long ign1, ign2, ign3;
690
691 __asm volatile (
692 TRAP_INSTR
693 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
694 : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (count), "3" (uop)
695 : "memory" );
696
697 return ret;
698 }
699
700 static __inline int
701 HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
702 unsigned long new_val, unsigned long flags, domid_t domid)
703 {
704 int ret;
705 unsigned long ign1, ign2, ign3, ign4;
706
707 __asm volatile (
708 TRAP_INSTR
709 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
710 : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
711 "1" (page_nr), "2" (new_val), "3" (flags), "4" (domid) :
712 "memory" );
713
714 return ret;
715 }
716
717 static __inline long
718 HYPERVISOR_set_timer_op(uint64_t timeout)
719 {
720 long ret;
721 unsigned long timeout_hi = (unsigned long)(timeout>>32);
722 unsigned long timeout_lo = (unsigned long)timeout;
723 unsigned long ign1, ign2;
724
725 __asm volatile (
726 TRAP_INSTR
727 : "=a" (ret), "=b" (ign1), "=c" (ign2)
728 : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_hi), "c" (timeout_lo)
729 : "memory");
730
731 return ret;
732 }
733 #endif /* XEN3 */
734
735 static __inline int
736 HYPERVISOR_multicall(void *call_list, int nr_calls)
737 {
738 int ret;
739 unsigned long ign1, ign2;
740
741 _hypercall(__HYPERVISOR_multicall,
742 _harg("1" (call_list), "2" (nr_calls)),
743 _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
744
745 return ret;
746 }
747
748
749 static __inline int
750 HYPERVISOR_event_channel_op(void *op)
751 {
752 int ret;
753 unsigned long ign1;
754
755 _hypercall(__HYPERVISOR_event_channel_op, _harg("1" (op)),
756 _harg("=a" (ret), "=b" (ign1)));
757
758 return ret;
759 }
760
761 static __inline int
762 HYPERVISOR_console_io(int cmd, int count, char *str)
763 {
764 int ret;
765 unsigned long ign1, ign2, ign3;
766
767 _hypercall(__HYPERVISOR_console_io,
768 _harg("1" (cmd), "2" (count), "3" (str)),
769 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)));
770
771 return ret;
772 }
773
774 static __inline int
775 HYPERVISOR_physdev_op(void *physdev_op)
776 {
777 int ret;
778 unsigned long ign1;
779
780 _hypercall(__HYPERVISOR_physdev_op, _harg("1" (physdev_op)),
781 _harg("=a" (ret), "=b" (ign1)));
782
783 return ret;
784 }
785
786 static __inline int
787 HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
788 {
789 int ret;
790 unsigned long ign1, ign2;
791
792 _hypercall(__HYPERVISOR_vm_assist, _harg("1" (cmd), "2" (type)),
793 _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
794
795 return ret;
796 }
797
798 /*
799 * Force a proper event-channel callback from Xen after clearing the
800 * callback mask. We do this in a very simple manner, by making a call
801 * down into Xen. The pending flag will be checked by Xen on return.
802 */
803 static __inline void hypervisor_force_callback(void)
804 {
805 #ifdef XEN3
806 (void)HYPERVISOR_xen_version(0, (void*)0);
807 #else
808 (void)HYPERVISOR_xen_version(0);
809 #endif
810 } __attribute__((no_instrument_function)) /* used by mcount */
811
812 static __inline void
813 hypervisor_notify_via_evtchn(unsigned int port)
814 {
815 evtchn_op_t op;
816
817 op.cmd = EVTCHNOP_send;
818 #ifdef XEN3
819 op.u.send.port = port;
820 #else
821 op.u.send.local_port = port;
822 #endif
823 (void)HYPERVISOR_event_channel_op(&op);
824 }
825
826 #endif /* _XEN_HYPERVISOR_H_ */
827