1/* $NetBSD: hypercalls.h,v 1.13 2011/12/07 15:47:42 cegger 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 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 */ 27 28/* 29 * 30 * Communication to/from hypervisor. 31 * 32 * Copyright (c) 2002-2004, K A Fraser 33 * 34 * Permission is hereby granted, free of charge, to any person obtaining a copy 35 * of this source file (the "Software"), to deal in the Software without 36 * restriction, including without limitation the rights to use, copy, modify, 37 * merge, publish, distribute, sublicense, and/or sell copies of the Software, 38 * and to permit persons to whom the Software is furnished to do so, subject to 39 * the following conditions: 40 * 41 * The above copyright notice and this permission notice shall be included in 42 * all copies or substantial portions of the Software. 43 * 44 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 45 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 46 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 47 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 48 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 49 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 50 * IN THE SOFTWARE. 51 */ 52 53 54#ifndef _XENI386_HYPERVISOR_H_ 55#define _XENI386_HYPERVISOR_H_ 56/* 57 * Assembler stubs for hyper-calls. 58 */ 59 60#include <machine/pte.h> /* pt_entry_t */ 61 62#if !defined(XEN_COMPAT_030001) 63/* hypercall via the hypercall call page */ 64#define __str(x) #x 65#define _str(x) __str(x) 66#define _hypercall(name, input_const, output_const) \ 67 __asm volatile ( \ 68 "call hypercall_page + ("_str(name)" * 32)" \ 69 : output_const \ 70 : input_const \ 71 : "memory" ) 72#else 73/* traditionnal hypercall via int 0x82 */ 74#define _hypercall(name, input_const, output_const) \ 75 __asm volatile ( \ 76 TRAP_INSTR \ 77 : output_const \ 78 : "0" (name), input_const \ 79 : "memory" ) 80#endif 81 82#define _harg(...) __VA_ARGS__ 83 84 85static __inline int 86HYPERVISOR_set_trap_table(trap_info_t *table) 87{ 88 int ret; 89 unsigned long ign1; 90 91 _hypercall(__HYPERVISOR_set_trap_table, _harg("1" (table)), 92 _harg("=a" (ret), "=b" (ign1))); 93 94 return ret; 95} 96 97static __inline int 98HYPERVISOR_set_gdt(unsigned long *frame_list, int entries) 99{ 100 int ret; 101 unsigned long ign1, ign2; 102 103 _hypercall(__HYPERVISOR_set_gdt, _harg("1" (frame_list), "2" (entries)), 104 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 105 106 return ret; 107} 108 109static __inline int 110HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp) 111{ 112 int ret; 113 unsigned long ign1, ign2; 114 115 _hypercall(__HYPERVISOR_stack_switch, _harg("1" (ss), "2" (esp)), 116 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 117 118 return ret; 119} 120 121static __inline int 122HYPERVISOR_set_callbacks( 123 unsigned long event_selector, unsigned long event_address, 124 unsigned long failsafe_selector, unsigned long failsafe_address) 125{ 126 int ret; 127 unsigned long ign1, ign2, ign3, ign4; 128 129 _hypercall(__HYPERVISOR_set_callbacks, 130 _harg("1" (event_selector),"2" (event_address), 131 "3" (failsafe_selector), "4" (failsafe_address)), 132 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4))); 133 134 return ret; 135} 136 137#if __XEN_INTERFACE_VERSION__ < 0x00030204 138static __inline int 139HYPERVISOR_dom0_op(dom0_op_t *dom0_op) 140{ 141 int ret; 142 unsigned long ign1; 143 144 dom0_op->interface_version = DOM0_INTERFACE_VERSION; 145 _hypercall(__HYPERVISOR_dom0_op, _harg("1" (dom0_op)), 146 _harg("=a" (ret), "=b" (ign1))); 147 148 return ret; 149} 150#endif /* __XEN_INTERFACE_VERSION__ */ 151 152static __inline int 153HYPERVISOR_set_debugreg(int reg, unsigned long value) 154{ 155 int ret; 156 unsigned long ign1, ign2; 157 158 _hypercall(__HYPERVISOR_set_debugreg, _harg("1" (reg), "2" (value)), 159 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 160 161 return ret; 162} 163 164static __inline unsigned long 165HYPERVISOR_get_debugreg(int reg) 166{ 167 unsigned long ret; 168 unsigned long ign1; 169 170 _hypercall(__HYPERVISOR_get_debugreg, _harg("1" (reg)), 171 _harg("=a" (ret), "=b" (ign1))); 172 173 return ret; 174} 175 176#include <xen/xen-public/arch-x86/xen-mca.h> 177 178static __inline int 179HYPERVISOR_machine_check(struct xen_mc *mc) 180{ 181 int ret; 182 unsigned long ign1; 183 184 mc->interface_version = XEN_MCA_INTERFACE_VERSION; 185 _hypercall(__HYPERVISOR_mca, _harg("1" (mc)), 186 _harg("=a" (ret), "=b" (ign1))); 187 188 return ret; 189} 190 191static __inline int 192HYPERVISOR_hvm_op(int cmd, void *arg) 193{ 194 int ret; 195 unsigned long ign1, ign2; 196 197 _hypercall(__HYPERVISOR_hvm_op, _harg("1" (cmd), "2" (arg)), 198 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 199 200 return ret; 201} 202 203static __inline int 204HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count, 205 domid_t domid) 206{ 207 int ret; 208 unsigned long ign1, ign2, ign3, ign4; 209 210 _hypercall(__HYPERVISOR_mmu_update, 211 _harg("1" (req), "2" (count), "3" (success_count), "4" (domid)), 212 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4))); 213 214 return ret; 215} 216 217static __inline int 218HYPERVISOR_mmuext_op(struct mmuext_op *op, int count, int *success_count, 219 domid_t domid) 220{ 221 int ret; 222 unsigned long ign1, ign2, ign3, ign4; 223 224 _hypercall(__HYPERVISOR_mmuext_op, 225 _harg("1" (op), "2" (count), "3" (success_count), "4" (domid)), 226 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4))); 227 228 return ret; 229} 230 231static __inline int 232HYPERVISOR_fpu_taskswitch(int set) 233{ 234 long ret; 235 long ign1; 236 237 _hypercall(__HYPERVISOR_fpu_taskswitch, _harg("1" (set)), 238 _harg("=a" (ret), "=b" (ign1))); 239 240 return ret; 241} 242 243static __inline int 244HYPERVISOR_update_descriptor(uint64_t ma, uint32_t word1, uint32_t word2) 245{ 246 int ret; 247 unsigned long ign1, ign2, ign3, ign4; 248 int ma1 = ma & 0xffffffff; 249 int ma2 = (ma >> 32) & 0xffffffff; 250 251 _hypercall(__HYPERVISOR_update_descriptor, 252 _harg("1" (ma1), "2" (ma2), "3" (word1), "4" (word2)), 253 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4))); 254 255 return ret; 256} 257 258static __inline int 259HYPERVISOR_memory_op(unsigned int cmd, void *arg) 260{ 261 int ret; 262 unsigned long ign1, ign2; 263 264 _hypercall(__HYPERVISOR_memory_op, _harg("1" (cmd), "2" (arg)), 265 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 266 267 return ret; 268} 269 270static __inline int 271HYPERVISOR_update_va_mapping(unsigned long page_nr, pt_entry_t new_val, 272 unsigned long flags) 273{ 274 int ret; 275 unsigned long ign1, ign2, ign3, ign4; 276 unsigned long pte_low, pte_hi; 277 278 pte_low = new_val & 0xffffffff; 279#ifdef PAE 280 pte_hi = new_val >> 32; 281#else 282 pte_hi = 0; 283#endif 284 285 _hypercall(__HYPERVISOR_update_va_mapping, 286 _harg("1" (page_nr), "2" (pte_low), "3" (pte_hi), "4" (flags)), 287 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4))); 288 289#ifdef notdef 290 if (__predict_false(ret < 0)) 291 panic("Failed update VA mapping: %08lx, %08lx, %08lx", 292 page_nr, new_val, flags); 293#endif 294 295 return ret; 296} 297 298static __inline int 299HYPERVISOR_xen_version(int cmd, void *arg) 300{ 301 int ret; 302 unsigned long ign1, ign2; 303 304 _hypercall(__HYPERVISOR_xen_version, _harg("1" (cmd), "2" (arg)), 305 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 306 307 return ret; 308} 309 310static __inline int 311HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count) 312{ 313 int ret; 314 unsigned long ign1, ign2, ign3; 315 316 _hypercall(__HYPERVISOR_grant_table_op, 317 _harg("1" (cmd), "2" (uop), "3" (count)), 318 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3))); 319 320 return ret; 321} 322 323static __inline int 324HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr, 325 pt_entry_t new_val, unsigned long flags, domid_t domid) 326{ 327 int ret; 328 unsigned long ign1, ign2, ign3, ign4, ign5; 329 unsigned long pte_low, pte_hi; 330 331 pte_low = new_val & 0xffffffff; 332#ifdef PAE 333 pte_hi = new_val >> 32; 334#else 335 pte_hi = 0; 336#endif 337 338 _hypercall(__HYPERVISOR_update_va_mapping_otherdomain, 339 _harg("1" (page_nr), "2" (pte_low), "3" (pte_hi), "4" (flags), "5" (domid)), 340 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4), 341 "=D" (ign5))); 342 343 return ret; 344} 345 346static __inline int 347HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args) 348{ 349 long ret; 350 unsigned long ign1, ign2, ign3; 351 352 _hypercall(__HYPERVISOR_vcpu_op, 353 _harg("1" (cmd), "2" (vcpuid), "3" (extra_args)), 354 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3))); 355 356 return ret; 357} 358 359static __inline long 360HYPERVISOR_yield(void) 361{ 362 long ret; 363 unsigned long ign1, ign2; 364 365 _hypercall(__HYPERVISOR_sched_op, _harg("1" (SCHEDOP_yield), "2" (0)), 366 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 367 368 return ret; 369} 370 371static __inline long 372HYPERVISOR_block(void) 373{ 374 long ret; 375 unsigned long ign1, ign2; 376 377 _hypercall(__HYPERVISOR_sched_op, _harg("1" (SCHEDOP_block), "2" (0)), 378 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 379 380 return ret; 381} 382 383static __inline long 384HYPERVISOR_shutdown(void) 385{ 386 long ret; 387 unsigned long ign1, ign2; 388 389 _hypercall(__HYPERVISOR_sched_op, 390 _harg("1" (SCHEDOP_shutdown), "2" (SHUTDOWN_poweroff)), 391 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 392 393 return ret; 394} 395 396static __inline long 397HYPERVISOR_crash(void) 398{ 399 long ret; 400 unsigned long ign1, ign2; 401 402 _hypercall(__HYPERVISOR_sched_op, 403 _harg("1" (SCHEDOP_shutdown), "2" (SHUTDOWN_crash)), 404 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 405 406 return ret; 407} 408 409static __inline long 410HYPERVISOR_reboot(void) 411{ 412 long ret; 413 unsigned long ign1, ign2; 414 415 _hypercall(__HYPERVISOR_sched_op, 416 _harg("1" (SCHEDOP_shutdown), "2" (SHUTDOWN_reboot)), 417 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 418 419 return ret; 420} 421 422static __inline long 423HYPERVISOR_suspend(unsigned long srec) 424{ 425 long ret; 426 unsigned long ign1, ign2, ign3; 427 428 _hypercall(__HYPERVISOR_sched_op, 429 _harg("1" (SCHEDOP_shutdown), "2" (SHUTDOWN_suspend), "3" (srec)), 430 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3))); 431 432 return ret; 433} 434 435static __inline long 436HYPERVISOR_set_timer_op(uint64_t timeout) 437{ 438 long ret; 439 unsigned long timeout_hi = (unsigned long)(timeout>>32); 440 unsigned long timeout_lo = (unsigned long)timeout; 441 unsigned long ign1, ign2; 442 443 _hypercall(__HYPERVISOR_set_timer_op, 444 _harg("1" (timeout_lo), "2" (timeout_hi)), 445 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 446 447 return ret; 448} 449 450static __inline int 451HYPERVISOR_platform_op(struct xen_platform_op *platform_op) 452{ 453 int ret; 454 unsigned long ign1; 455 456 platform_op->interface_version = XENPF_INTERFACE_VERSION; 457 _hypercall(__HYPERVISOR_platform_op, _harg("1" (platform_op)), 458 _harg("=a" (ret), "=b" (ign1))); 459 460 return ret; 461} 462 463static __inline int 464HYPERVISOR_multicall(void *call_list, int nr_calls) 465{ 466 int ret; 467 unsigned long ign1, ign2; 468 469 _hypercall(__HYPERVISOR_multicall, 470 _harg("1" (call_list), "2" (nr_calls)), 471 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 472 473 return ret; 474} 475 476 477static __inline int 478HYPERVISOR_event_channel_op(void *op) 479{ 480 int ret; 481 unsigned long ign1; 482 483 _hypercall(__HYPERVISOR_event_channel_op, _harg("1" (op)), 484 _harg("=a" (ret), "=b" (ign1))); 485 486 return ret; 487} 488 489static __inline int 490HYPERVISOR_console_io(int cmd, int count, char *str) 491{ 492 int ret; 493 unsigned long ign1, ign2, ign3; 494 495 _hypercall(__HYPERVISOR_console_io, 496 _harg("1" (cmd), "2" (count), "3" (str)), 497 _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3))); 498 499 return ret; 500} 501 502static __inline int 503HYPERVISOR_physdev_op(void *physdev_op) 504{ 505 int ret; 506 unsigned long ign1; 507 508 _hypercall(__HYPERVISOR_physdev_op, _harg("1" (physdev_op)), 509 _harg("=a" (ret), "=b" (ign1))); 510 511 return ret; 512} 513 514static __inline int 515HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type) 516{ 517 int ret; 518 unsigned long ign1, ign2; 519 520 _hypercall(__HYPERVISOR_vm_assist, _harg("1" (cmd), "2" (type)), 521 _harg("=a" (ret), "=b" (ign1), "=c" (ign2))); 522 523 return ret; 524} 525 526static __inline int 527HYPERVISOR_sysctl(void *sysctl) 528{ 529 int ret; 530 unsigned long ign1; 531 532 _hypercall(__HYPERVISOR_sysctl, _harg("1" (sysctl)), 533 _harg("=a" (ret), "=b" (ign1))); 534 535 return ret; 536} 537#endif /* _XENI386_HYPERVISOR_H_ */ 538