1/* $NetBSD: hypercalls.h,v 1.7 2011/12/07 15:47:42 cegger Exp $ */ 2/****************************************************************************** 3 * hypercall.h 4 * 5 * Linux-specific hypervisor handling. 6 * 7 * Copyright (c) 2002-2004, K A Fraser 8 * 9 * 64-bit updates: 10 * Benjamin Liu <benjamin.liu@intel.com> 11 * Jun Nakajima <jun.nakajima@intel.com> 12 * 13 * This program is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU General Public License version 2 15 * as published by the Free Software Foundation; or, when distributed 16 * separately from the Linux kernel or incorporated into other 17 * software packages, subject to the following license: 18 * 19 * Permission is hereby granted, free of charge, to any person obtaining a copy 20 * of this source file (the "Software"), to deal in the Software without 21 * restriction, including without limitation the rights to use, copy, modify, 22 * merge, publish, distribute, sublicense, and/or sell copies of the Software, 23 * and to permit persons to whom the Software is furnished to do so, subject to 24 * the following conditions: 25 * 26 * The above copyright notice and this permission notice shall be included in 27 * all copies or substantial portions of the Software. 28 * 29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 34 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 35 * IN THE SOFTWARE. 36 */ 37 38#ifndef __HYPERCALL_H__ 39#define __HYPERCALL_H__ 40 41#define __STR(x) #x 42#define STR(x) __STR(x) 43 44#define HYPERCALL_STR(name) \ 45 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)" 46 47#define _hypercall0(type, name) \ 48({ \ 49 long __res; \ 50 asm volatile ( \ 51 HYPERCALL_STR(name) \ 52 : "=a" (__res) \ 53 : \ 54 : "memory" ); \ 55 (type)__res; \ 56}) 57 58#define _hypercall1(type, name, a1) \ 59({ \ 60 long __res, __ign1; \ 61 asm volatile ( \ 62 HYPERCALL_STR(name) \ 63 : "=a" (__res), "=D" (__ign1) \ 64 : "1" ((long)(a1)) \ 65 : "memory" ); \ 66 (type)__res; \ 67}) 68 69#define _hypercall2(type, name, a1, a2) \ 70({ \ 71 long __res, __ign1, __ign2; \ 72 asm volatile ( \ 73 HYPERCALL_STR(name) \ 74 : "=a" (__res), "=D" (__ign1), "=S" (__ign2) \ 75 : "1" ((long)(a1)), "2" ((long)(a2)) \ 76 : "memory" ); \ 77 (type)__res; \ 78}) 79 80#define _hypercall3(type, name, a1, a2, a3) \ 81({ \ 82 long __res, __ign1, __ign2, __ign3; \ 83 asm volatile ( \ 84 HYPERCALL_STR(name) \ 85 : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ 86 "=d" (__ign3) \ 87 : "1" ((long)(a1)), "2" ((long)(a2)), \ 88 "3" ((long)(a3)) \ 89 : "memory" ); \ 90 (type)__res; \ 91}) 92 93#define _hypercall4(type, name, a1, a2, a3, a4) \ 94({ \ 95 long __res, __ign1, __ign2, __ign3; \ 96 asm volatile ( \ 97 "movq %7,%%r10; " \ 98 HYPERCALL_STR(name) \ 99 : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ 100 "=d" (__ign3) \ 101 : "1" ((long)(a1)), "2" ((long)(a2)), \ 102 "3" ((long)(a3)), "g" ((long)(a4)) \ 103 : "memory", "r10" ); \ 104 (type)__res; \ 105}) 106 107#define _hypercall5(type, name, a1, a2, a3, a4, a5) \ 108({ \ 109 long __res, __ign1, __ign2, __ign3; \ 110 asm volatile ( \ 111 "movq %7,%%r10; movq %8,%%r8; " \ 112 HYPERCALL_STR(name) \ 113 : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ 114 "=d" (__ign3) \ 115 : "1" ((long)(a1)), "2" ((long)(a2)), \ 116 "3" ((long)(a3)), "g" ((long)(a4)), \ 117 "g" ((long)(a5)) \ 118 : "memory", "r10", "r8" ); \ 119 (type)__res; \ 120}) 121 122static inline int 123HYPERVISOR_set_trap_table( 124 trap_info_t *table) 125{ 126 return _hypercall1(int, set_trap_table, table); 127} 128 129static inline int 130HYPERVISOR_mmu_update( 131 mmu_update_t *req, int count, int *success_count, domid_t domid) 132{ 133 return _hypercall4(int, mmu_update, req, count, success_count, domid); 134} 135 136static inline int 137HYPERVISOR_mmuext_op( 138 struct mmuext_op *op, int count, int *success_count, domid_t domid) 139{ 140 return _hypercall4(int, mmuext_op, op, count, success_count, domid); 141} 142 143static inline int 144HYPERVISOR_set_gdt( 145 unsigned long *frame_list, int entries) 146{ 147 return _hypercall2(int, set_gdt, frame_list, entries); 148} 149 150static inline int 151HYPERVISOR_stack_switch( 152 unsigned long ss, unsigned long esp) 153{ 154 return _hypercall2(int, stack_switch, ss, esp); 155} 156 157static inline int 158HYPERVISOR_set_callbacks( 159 unsigned long event_address, unsigned long failsafe_address, 160 unsigned long syscall_address) 161{ 162 return _hypercall3(int, set_callbacks, 163 event_address, failsafe_address, syscall_address); 164} 165 166static inline int 167HYPERVISOR_fpu_taskswitch( 168 int set) 169{ 170 return _hypercall1(int, fpu_taskswitch, set); 171} 172 173static inline int 174HYPERVISOR_sched_op_compat( 175 int cmd, unsigned long arg) 176{ 177 return _hypercall2(int, sched_op_compat, cmd, arg); 178} 179 180static inline int 181HYPERVISOR_sched_op( 182 int cmd, void *arg) 183{ 184 return _hypercall2(int, sched_op, cmd, arg); 185} 186 187static inline long 188HYPERVISOR_set_timer_op( 189 u64 timeout) 190{ 191 return _hypercall1(long, set_timer_op, timeout); 192} 193 194static inline int 195HYPERVISOR_platform_op( 196 struct xen_platform_op *platform_op) 197{ 198 platform_op->interface_version = XENPF_INTERFACE_VERSION; 199 return _hypercall1(int, platform_op, platform_op); 200} 201 202static inline int 203HYPERVISOR_set_debugreg( 204 int reg, unsigned long value) 205{ 206 return _hypercall2(int, set_debugreg, reg, value); 207} 208 209static inline unsigned long 210HYPERVISOR_get_debugreg( 211 int reg) 212{ 213 return _hypercall1(unsigned long, get_debugreg, reg); 214} 215 216static inline int 217HYPERVISOR_update_descriptor( 218 unsigned long ma, unsigned long word) 219{ 220 return _hypercall2(int, update_descriptor, ma, word); 221} 222 223static inline int 224HYPERVISOR_memory_op( 225 unsigned int cmd, void *arg) 226{ 227 return _hypercall2(int, memory_op, cmd, arg); 228} 229 230static inline int 231HYPERVISOR_multicall( 232 multicall_entry_t *call_list, int nr_calls) 233{ 234 return _hypercall2(int, multicall, call_list, nr_calls); 235} 236 237static inline int 238HYPERVISOR_update_va_mapping( 239 unsigned long va, unsigned long new_val, unsigned long flags) 240{ 241 return _hypercall3(int, update_va_mapping, va, new_val, flags); 242} 243 244static inline int 245HYPERVISOR_event_channel_op(void *op) 246{ 247 return _hypercall1(int, event_channel_op, op); 248} 249 250static inline int 251HYPERVISOR_acm_op( 252 int cmd, void *arg) 253{ 254 return _hypercall2(int, acm_op, cmd, arg); 255} 256 257static inline int 258HYPERVISOR_xen_version( 259 int cmd, void *arg) 260{ 261 return _hypercall2(int, xen_version, cmd, arg); 262} 263 264static inline int 265HYPERVISOR_console_io( 266 int cmd, int count, char *str) 267{ 268 return _hypercall3(int, console_io, cmd, count, str); 269} 270 271static inline int 272HYPERVISOR_physdev_op(void *op) 273{ 274 return _hypercall1(int, physdev_op_compat, op); 275} 276 277static inline int 278HYPERVISOR_grant_table_op( 279 unsigned int cmd, void *uop, unsigned int count) 280{ 281 return _hypercall3(int, grant_table_op, cmd, uop, count); 282} 283 284static inline int 285HYPERVISOR_update_va_mapping_otherdomain( 286 unsigned long va, unsigned long new_val, unsigned long flags, 287 domid_t domid) 288{ 289 return _hypercall4(int, update_va_mapping_otherdomain, va, 290 new_val, flags, domid); 291} 292 293static inline int 294HYPERVISOR_vm_assist( 295 unsigned int cmd, unsigned int type) 296{ 297 return _hypercall2(int, vm_assist, cmd, type); 298} 299 300static inline int 301HYPERVISOR_vcpu_op( 302 int cmd, int vcpuid, void *extra_args) 303{ 304 return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args); 305} 306 307static inline int 308HYPERVISOR_set_segment_base( 309 int reg, unsigned long value) 310{ 311 return _hypercall2(int, set_segment_base, reg, value); 312} 313 314static inline int 315HYPERVISOR_suspend( 316 unsigned long srec) 317{ 318 return _hypercall3(int, sched_op, SCHEDOP_shutdown, 319 SHUTDOWN_suspend, srec); 320} 321 322static inline long 323HYPERVISOR_yield( 324 void) 325{ 326 return _hypercall2(int, sched_op, SCHEDOP_yield, 0); 327} 328 329static inline long 330HYPERVISOR_block( 331 void) 332{ 333 return _hypercall2(int, sched_op, SCHEDOP_block, 0); 334} 335 336static inline long 337HYPERVISOR_shutdown( 338 void) 339{ 340 return _hypercall2(int, sched_op, SCHEDOP_shutdown, SHUTDOWN_poweroff); 341} 342 343static inline long 344HYPERVISOR_crash( 345 void) 346{ 347 return _hypercall2(int, sched_op, SCHEDOP_shutdown, SHUTDOWN_crash); 348} 349 350static inline long 351HYPERVISOR_reboot( 352 void) 353{ 354 return _hypercall2(int, sched_op, SCHEDOP_shutdown, SHUTDOWN_reboot); 355} 356 357static inline int 358HYPERVISOR_nmi_op( 359 unsigned long op, void *arg) 360{ 361 return _hypercall2(int, nmi_op, op, arg); 362} 363 364static inline unsigned long 365HYPERVISOR_hvm_op( 366 int op, void *arg) 367{ 368 return _hypercall2(unsigned long, hvm_op, op, arg); 369} 370 371static inline int 372HYPERVISOR_callback_op( 373 int cmd, void *arg) 374{ 375 return _hypercall2(int, callback_op, cmd, arg); 376} 377 378static inline int 379HYPERVISOR_xenoprof_op( 380 int op, void *arg) 381{ 382 return _hypercall2(int, xenoprof_op, op, arg); 383} 384 385static inline int 386HYPERVISOR_kexec_op( 387 unsigned long op, void *args) 388{ 389 return _hypercall2(int, kexec_op, op, args); 390} 391 392#if __XEN_INTERFACE_VERSION__ < 0x00030204 393static inline int 394HYPERVISOR_dom0_op( 395 dom0_op_t *dom0_op) 396{ 397 dom0_op->interface_version = DOM0_INTERFACE_VERSION; 398 return _hypercall1(int, dom0_op, dom0_op); 399} 400#endif /* __XEN_INTERFACE_VERSION__ */ 401 402#include <xen/xen-public/arch-x86/xen-mca.h> 403 404static inline int 405HYPERVISOR_machine_check(struct xen_mc *mc) 406{ 407 mc->interface_version = XEN_MCA_INTERFACE_VERSION; 408 return _hypercall1(int, mca, mc); 409} 410 411static inline int 412HYPERVISOR_sysctl(void *sysctl) 413{ 414 return _hypercall1(int, sysctl, sysctl); 415} 416 417#endif /* __HYPERCALL_H__ */ 418