1 /* $NetBSD: hypervisor.h,v 1.23 2006/10/17 19:57:24 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 #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