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