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