1 /* $NetBSD: hypervisor.h,v 1.20 2006/03/06 19:54:50 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), "1" (timeout_lo), "2" (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