hypervisor.h revision 1.18 1 /* $NetBSD: hypervisor.h,v 1.18 2006/01/15 22:09:51 bouyer 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 static inline int
147 HYPERVISOR_set_trap_table(trap_info_t *table)
148 {
149 int ret;
150 unsigned long ign1;
151
152 __asm volatile (
153 TRAP_INSTR
154 : "=a" (ret), "=b" (ign1)
155 : "0" (__HYPERVISOR_set_trap_table), "1" (table)
156 : "memory" );
157
158 return ret;
159 }
160
161 static inline int
162 HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
163 {
164 int ret;
165 unsigned long ign1, ign2;
166
167 __asm volatile (
168 TRAP_INSTR
169 : "=a" (ret), "=b" (ign1), "=c" (ign2)
170 : "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries)
171 : "memory" );
172
173 return ret;
174 }
175
176 static inline int
177 HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
178 {
179 int ret;
180 unsigned long ign1, ign2;
181
182 __asm volatile (
183 TRAP_INSTR
184 : "=a" (ret), "=b" (ign1), "=c" (ign2)
185 : "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp)
186 : "memory" );
187
188 return ret;
189 }
190
191 static inline int
192 HYPERVISOR_set_callbacks(
193 unsigned long event_selector, unsigned long event_address,
194 unsigned long failsafe_selector, unsigned long failsafe_address)
195 {
196 int ret;
197 unsigned long ign1, ign2, ign3, ign4;
198
199 __asm volatile (
200 TRAP_INSTR
201 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
202 : "0" (__HYPERVISOR_set_callbacks), "1" (event_selector),
203 "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address)
204 : "memory" );
205
206 return ret;
207 }
208
209 static inline int
210 HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
211 {
212 int ret;
213 unsigned long ign1;
214
215 dom0_op->interface_version = DOM0_INTERFACE_VERSION;
216 __asm volatile (
217 TRAP_INSTR
218 : "=a" (ret), "=b" (ign1)
219 : "0" (__HYPERVISOR_dom0_op), "1" (dom0_op)
220 : "memory");
221
222 return ret;
223 }
224
225 static inline int
226 HYPERVISOR_set_debugreg(int reg, unsigned long value)
227 {
228 int ret;
229 unsigned long ign1, ign2;
230
231 __asm volatile (
232 TRAP_INSTR
233 : "=a" (ret), "=b" (ign1), "=c" (ign2)
234 : "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value)
235 : "memory" );
236
237 return ret;
238 }
239
240 static inline unsigned long
241 HYPERVISOR_get_debugreg(int reg)
242 {
243 unsigned long ret;
244 unsigned long ign1;
245
246 __asm volatile (
247 TRAP_INSTR
248 : "=a" (ret), "=b" (ign1)
249 : "0" (__HYPERVISOR_get_debugreg), "1" (reg)
250 : "memory" );
251
252 return ret;
253 }
254
255 #ifdef XEN3
256 static inline int
257 HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count,
258 domid_t domid)
259 {
260 int ret;
261 unsigned long ign1, ign2, ign3, ign4;
262
263 __asm volatile (
264 TRAP_INSTR
265 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
266 : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
267 "3" (success_count), "4" (domid)
268 : "memory" );
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 __asm volatile (
281 TRAP_INSTR
282 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
283 : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count),
284 "3" (success_count), "4" (domid)
285 : "memory" );
286
287 return ret;
288 }
289
290 #if 0
291 static inline int
292 HYPERVISOR_fpu_taskswitch(int set)
293 {
294 long ret;
295 long ign1;
296 __asm volatile (
297 TRAP_INSTR
298 : "=a" (ret), "=b" (ign1)
299 : "0" (__HYPERVISOR_fpu_taskswitch), "1" (set) : "memory" );
300
301 return ret;
302 }
303 #else /* 0 */
304 /* Xen2 compat: always i38HYPERVISOR_fpu_taskswitch(1) */
305 static inline int
306 HYPERVISOR_fpu_taskswitch(void)
307 {
308 long ret;
309 long ign1;
310 __asm volatile (
311 TRAP_INSTR
312 : "=a" (ret), "=b" (ign1)
313 : "0" (__HYPERVISOR_fpu_taskswitch), "1" (1) : "memory" );
314
315 return ret;
316 }
317 #endif /* 0 */
318
319 static inline int
320 HYPERVISOR_update_descriptor(uint64_t ma, uint32_t word1, uint32_t word2)
321 {
322 int ret;
323 unsigned long ign1, ign2, ign3, ign4;
324 int ma1 = ma & 0xffffffff;
325 int ma2 = (ma >> 32) & 0xffffffff;
326
327 __asm volatile (
328 TRAP_INSTR
329 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
330 : "0" (__HYPERVISOR_update_descriptor), "1" (ma1), "2" (ma2),
331 "3" (word1), "4" (word2)
332 : "memory" );
333
334 return ret;
335 }
336
337 static inline int
338 HYPERVISOR_memory_op(unsigned int cmd, void *arg)
339 {
340 int ret;
341 unsigned long ign1, ign2;
342
343 __asm volatile (
344 TRAP_INSTR
345 : "=a" (ret), "=b" (ign1), "=c" (ign2)
346 : "0" (__HYPERVISOR_memory_op), "1" (cmd), "2" (arg)
347 : "memory" );
348
349 return ret;
350 }
351
352 static inline int
353 HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
354 unsigned long flags)
355 {
356 int ret;
357 unsigned long ign1, ign2, ign3, ign4;
358
359 __asm volatile (
360 TRAP_INSTR
361 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
362 : "0" (__HYPERVISOR_update_va_mapping),
363 "1" (page_nr), "2" (new_val), "3" (0), "4" (flags)
364 : "memory" );
365
366 #ifdef notdef
367 if (__predict_false(ret < 0))
368 panic("Failed update VA mapping: %08lx, %08lx, %08lx",
369 page_nr, new_val, flags);
370 #endif
371
372 return ret;
373 }
374
375 static inline int
376 HYPERVISOR_xen_version(int cmd, void *arg)
377 {
378 int ret;
379 unsigned long ign1, ign2;
380
381 __asm volatile (
382 TRAP_INSTR
383 : "=a" (ret), "=b" (ign1), "=c" (ign2)
384 : "0" (__HYPERVISOR_xen_version), "1" (cmd), "2" (arg)
385 : "memory" );
386
387 return ret;
388 }
389
390 static inline int
391 HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
392 {
393 int ret;
394 unsigned long ign1, ign2, ign3;
395
396 __asm volatile (
397 TRAP_INSTR
398 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
399 : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (uop), "3" (count)
400 : "memory" );
401
402 return ret;
403 }
404
405 static inline int
406 HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
407 unsigned long new_val, unsigned long flags, domid_t domid)
408 {
409 int ret;
410 unsigned long ign1, ign2, ign3, ign4, ign5;
411
412 __asm volatile (
413 TRAP_INSTR
414 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
415 "=D" (ign5)
416 : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
417 "1" (page_nr), "2" (new_val), "3" (0), "4" (flags), "5" (domid) :
418 "memory" );
419
420 return ret;
421 }
422
423 static inline int
424 HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args)
425 {
426 long ret;
427 unsigned long ign1, ign2, ign3;
428
429 __asm volatile (
430 TRAP_INSTR
431 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
432 : "0" (__HYPERVISOR_vcpu_op),
433 "1" (cmd), "2" (vcpuid), "3" (extra_args)
434 : "memory");
435
436 return ret;
437 }
438
439 static inline long
440 HYPERVISOR_yield(void)
441 {
442 long ret;
443 unsigned long ign1, ign2;
444
445 __asm volatile (
446 TRAP_INSTR
447 : "=a" (ret), "=b" (ign1), "=c" (ign2)
448 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield), "2" (0)
449 : "memory" );
450
451 return ret;
452 }
453
454 static inline long
455 HYPERVISOR_block(void)
456 {
457 long ret;
458 unsigned long ign1, ign2;
459
460 __asm volatile (
461 TRAP_INSTR
462 : "=a" (ret), "=b" (ign1), "=c" (ign2)
463 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block), "2" (0)
464 : "memory" );
465
466 return ret;
467 }
468
469 static inline long
470 HYPERVISOR_shutdown(void)
471 {
472 long ret;
473 unsigned long ign1, ign2;
474
475 __asm volatile (
476 TRAP_INSTR
477 : "=a" (ret), "=b" (ign1), "=c" (ign2)
478 : "0" (__HYPERVISOR_sched_op),
479 "1" (SCHEDOP_shutdown), "2" (SHUTDOWN_poweroff)
480 : "memory" );
481
482 return ret;
483 }
484
485 static inline long
486 HYPERVISOR_reboot(void)
487 {
488 long ret;
489 unsigned long ign1, ign2;
490
491 __asm volatile (
492 TRAP_INSTR
493 : "=a" (ret), "=b" (ign1), "=c" (ign2)
494 : "0" (__HYPERVISOR_sched_op),
495 "1" (SCHEDOP_shutdown), "2" (SHUTDOWN_reboot)
496 : "memory" );
497
498 return ret;
499 }
500
501 static inline long
502 HYPERVISOR_suspend(unsigned long srec)
503 {
504 long ret;
505 unsigned long ign1, ign2, ign3;
506
507 __asm volatile (
508 TRAP_INSTR
509 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
510 : "0" (__HYPERVISOR_sched_op),
511 "1" (SCHEDOP_shutdown), "2" (SHUTDOWN_suspend),
512 "3" (srec) : "memory");
513
514 return ret;
515 }
516
517 static inline long
518 HYPERVISOR_set_timer_op(uint64_t timeout)
519 {
520 long ret;
521 unsigned long timeout_hi = (unsigned long)(timeout>>32);
522 unsigned long timeout_lo = (unsigned long)timeout;
523 unsigned long ign1, ign2;
524
525 __asm volatile (
526 TRAP_INSTR
527 : "=a" (ret), "=b" (ign1), "=c" (ign2)
528 : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_lo), "c" (timeout_hi)
529 : "memory");
530
531 return ret;
532 }
533 #else /* XEN3 */
534 static inline int
535 HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count)
536 {
537 int ret;
538 unsigned long ign1, ign2, ign3;
539
540 __asm__ __volatile__ (
541 TRAP_INSTR
542 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
543 : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
544 "3" (success_count)
545 : "memory" );
546
547 return ret;
548 }
549
550 static inline int
551 HYPERVISOR_fpu_taskswitch(void)
552 {
553 int ret;
554 __asm volatile (
555 TRAP_INSTR
556 : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" );
557
558 return ret;
559 }
560
561 static inline int
562 HYPERVISOR_update_descriptor(unsigned long pa, unsigned long word1,
563 unsigned long word2)
564 {
565 int ret;
566 unsigned long ign1, ign2, ign3;
567
568 __asm volatile (
569 TRAP_INSTR
570 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
571 : "0" (__HYPERVISOR_update_descriptor), "1" (pa), "2" (word1),
572 "3" (word2)
573 : "memory" );
574
575 return ret;
576 }
577
578 static inline int
579 HYPERVISOR_yield(void)
580 {
581 int ret;
582 unsigned long ign1;
583
584 __asm__ __volatile__ (
585 TRAP_INSTR
586 : "=a" (ret), "=b" (ign1)
587 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
588 : "memory" );
589
590 return ret;
591 }
592
593 static inline int
594 HYPERVISOR_block(void)
595 {
596 int ret;
597 unsigned long ign1;
598
599 __asm__ __volatile__ (
600 TRAP_INSTR
601 : "=a" (ret), "=b" (ign1)
602 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
603 : "memory" );
604
605 return ret;
606 }
607
608 static inline int
609 HYPERVISOR_shutdown(void)
610 {
611 int ret;
612 unsigned long ign1;
613
614 __asm__ __volatile__ (
615 TRAP_INSTR
616 : "=a" (ret), "=b" (ign1)
617 : "0" (__HYPERVISOR_sched_op),
618 "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
619 : "memory" );
620
621 return ret;
622 }
623
624 static inline int
625 HYPERVISOR_reboot(void)
626 {
627 int ret;
628 unsigned long ign1;
629
630 __asm__ __volatile__ (
631 TRAP_INSTR
632 : "=a" (ret), "=b" (ign1)
633 : "0" (__HYPERVISOR_sched_op),
634 "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
635 : "memory" );
636
637 return ret;
638 }
639
640 static inline int
641 HYPERVISOR_suspend(unsigned long srec)
642 {
643 int ret;
644 unsigned long ign1, ign2;
645
646 /* NB. On suspend, control software expects a suspend record in %esi. */
647 __asm__ __volatile__ (
648 TRAP_INSTR
649 : "=a" (ret), "=b" (ign1), "=S" (ign2)
650 : "0" (__HYPERVISOR_sched_op),
651 "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
652 "S" (srec) : "memory");
653
654 return ret;
655 }
656
657 static inline int
658 HYPERVISOR_set_fast_trap(int idx)
659 {
660 int ret;
661 unsigned long ign1;
662
663 __asm volatile (
664 TRAP_INSTR
665 : "=a" (ret), "=b" (ign1)
666 : "0" (__HYPERVISOR_set_fast_trap), "1" (idx)
667 : "memory" );
668
669 return ret;
670 }
671
672 static inline int
673 HYPERVISOR_dom_mem_op(unsigned int op, unsigned long *extent_list,
674 unsigned long nr_extents, unsigned int extent_order)
675 {
676 int ret;
677 unsigned long ign1, ign2, ign3, ign4, ign5;
678
679 __asm volatile (
680 TRAP_INSTR
681 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
682 "=D" (ign5)
683 : "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list),
684 "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF)
685 : "memory" );
686
687 return ret;
688 }
689
690 static inline int
691 HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
692 unsigned long flags)
693 {
694 int ret;
695 unsigned long ign1, ign2, ign3;
696
697 __asm volatile (
698 TRAP_INSTR
699 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
700 : "0" (__HYPERVISOR_update_va_mapping),
701 "1" (page_nr), "2" (new_val), "3" (flags)
702 : "memory" );
703
704 #ifdef notdef
705 if (__predict_false(ret < 0))
706 panic("Failed update VA mapping: %08lx, %08lx, %08lx",
707 page_nr, new_val, flags);
708 #endif
709
710 return ret;
711 }
712
713 static inline int
714 HYPERVISOR_xen_version(int cmd)
715 {
716 int ret;
717 unsigned long ign1;
718
719 __asm volatile (
720 TRAP_INSTR
721 : "=a" (ret), "=b" (ign1)
722 : "0" (__HYPERVISOR_xen_version), "1" (cmd)
723 : "memory" );
724
725 return ret;
726 }
727
728 static inline int
729 HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
730 {
731 int ret;
732 unsigned long ign1, ign2, ign3;
733
734 __asm volatile (
735 TRAP_INSTR
736 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
737 : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (count), "3" (uop)
738 : "memory" );
739
740 return ret;
741 }
742
743 static inline int
744 HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
745 unsigned long new_val, unsigned long flags, domid_t domid)
746 {
747 int ret;
748 unsigned long ign1, ign2, ign3, ign4;
749
750 __asm volatile (
751 TRAP_INSTR
752 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
753 : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
754 "1" (page_nr), "2" (new_val), "3" (flags), "4" (domid) :
755 "memory" );
756
757 return ret;
758 }
759
760 static inline long
761 HYPERVISOR_set_timer_op(uint64_t timeout)
762 {
763 long ret;
764 unsigned long timeout_hi = (unsigned long)(timeout>>32);
765 unsigned long timeout_lo = (unsigned long)timeout;
766 unsigned long ign1, ign2;
767
768 __asm volatile (
769 TRAP_INSTR
770 : "=a" (ret), "=b" (ign1), "=c" (ign2)
771 : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_hi), "c" (timeout_lo)
772 : "memory");
773
774 return ret;
775 }
776 #endif /* XEN3 */
777
778 static inline int
779 HYPERVISOR_multicall(void *call_list, int nr_calls)
780 {
781 int ret;
782 unsigned long ign1, ign2;
783
784 __asm volatile (
785 TRAP_INSTR
786 : "=a" (ret), "=b" (ign1), "=c" (ign2)
787 : "0" (__HYPERVISOR_multicall), "1" (call_list), "2" (nr_calls)
788 : "memory" );
789
790 return ret;
791 }
792
793
794 static inline int
795 HYPERVISOR_event_channel_op(void *op)
796 {
797 int ret;
798 unsigned long ign1;
799
800 __asm volatile (
801 TRAP_INSTR
802 : "=a" (ret), "=b" (ign1)
803 : "0" (__HYPERVISOR_event_channel_op), "1" (op)
804 : "memory" );
805
806 return ret;
807 }
808
809 static inline int
810 HYPERVISOR_console_io(int cmd, int count, char *str)
811 {
812 int ret;
813 unsigned long ign1, ign2, ign3;
814
815 __asm volatile (
816 TRAP_INSTR
817 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
818 : "0" (__HYPERVISOR_console_io), "1" (cmd), "2" (count), "3" (str)
819 : "memory" );
820
821 return ret;
822 }
823
824 static inline int
825 HYPERVISOR_physdev_op(void *physdev_op)
826 {
827 int ret;
828 unsigned long ign1;
829
830 __asm volatile (
831 TRAP_INSTR
832 : "=a" (ret), "=b" (ign1)
833 : "0" (__HYPERVISOR_physdev_op), "1" (physdev_op)
834 : "memory" );
835
836 return ret;
837 }
838
839 static inline int
840 HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
841 {
842 int ret;
843 unsigned long ign1, ign2;
844
845 __asm volatile (
846 TRAP_INSTR
847 : "=a" (ret), "=b" (ign1), "=c" (ign2)
848 : "0" (__HYPERVISOR_vm_assist), "1" (cmd), "2" (type)
849 : "memory" );
850
851 return ret;
852 }
853
854 /*
855 * Force a proper event-channel callback from Xen after clearing the
856 * callback mask. We do this in a very simple manner, by making a call
857 * down into Xen. The pending flag will be checked by Xen on return.
858 */
859 static inline void hypervisor_force_callback(void)
860 {
861 #ifdef XEN3
862 (void)HYPERVISOR_xen_version(0, (void*)0);
863 #else
864 (void)HYPERVISOR_xen_version(0);
865 #endif
866 } __attribute__((no_instrument_function)) /* used by mcount */
867
868 static inline void
869 hypervisor_notify_via_evtchn(unsigned int port)
870 {
871 evtchn_op_t op;
872
873 op.cmd = EVTCHNOP_send;
874 #ifdef XEN3
875 op.u.send.port = port;
876 #else
877 op.u.send.local_port = port;
878 #endif
879 (void)HYPERVISOR_event_channel_op(&op);
880 }
881
882 #endif /* _XEN_HYPERVISOR_H_ */
883