hypercall.h revision 185181
1240116Smarcel/****************************************************************************** 2240116Smarcel * hypercall.h 3240116Smarcel * 4240116Smarcel * Linux-specific hypervisor handling. 5240116Smarcel * 6240116Smarcel * Copyright (c) 2002-2004, K A Fraser 7240116Smarcel * 8240116Smarcel * This file may be distributed separately from the Linux kernel, or 9240116Smarcel * incorporated into other software packages, subject to the following license: 10240116Smarcel * 11240116Smarcel * Permission is hereby granted, free of charge, to any person obtaining a copy 12240116Smarcel * of this source file (the "Software"), to deal in the Software without 13240116Smarcel * restriction, including without limitation the rights to use, copy, modify, 14240116Smarcel * merge, publish, distribute, sublicense, and/or sell copies of the Software, 15240116Smarcel * and to permit persons to whom the Software is furnished to do so, subject to 16240116Smarcel * the following conditions: 17240116Smarcel * 18240116Smarcel * The above copyright notice and this permission notice shall be included in 19240116Smarcel * all copies or substantial portions of the Software. 20240116Smarcel * 21240116Smarcel * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22240116Smarcel * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23240116Smarcel * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24240116Smarcel * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25240116Smarcel * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26240116Smarcel * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 27240116Smarcel * IN THE SOFTWARE. 28240116Smarcel */ 29240116Smarcel 30240116Smarcel#ifndef __HYPERCALL_H__ 31240116Smarcel#define __HYPERCALL_H__ 32240116Smarcel 33240116Smarcel#include <sys/systm.h> 34240116Smarcel#include <xen/interface/xen.h> 35240116Smarcel#include <xen/interface/sched.h> 36240116Smarcel 37240116Smarcel#define __STR(x) #x 38240116Smarcel#define STR(x) __STR(x) 39240116Smarcel#define ENOXENSYS 38 40240116Smarcel#define CONFIG_XEN_COMPAT 0x030002 41240116Smarcel 42240116Smarcel 43240116Smarcel#if defined(XEN) 44240116Smarcel#define HYPERCALL_STR(name) \ 45240116Smarcel "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)" 46240116Smarcel#else 47240116Smarcel#define HYPERCALL_STR(name) \ 48240116Smarcel "mov hypercall_stubs,%%eax; " \ 49240116Smarcel "add $("STR(__HYPERVISOR_##name)" * 32),%%eax; " \ 50240116Smarcel "call *%%eax" 51240116Smarcel#endif 52240116Smarcel 53240116Smarcel#define _hypercall0(type, name) \ 54240116Smarcel({ \ 55240116Smarcel long __res; \ 56240116Smarcel __asm__ volatile ( \ 57240116Smarcel HYPERCALL_STR(name) \ 58240116Smarcel : "=a" (__res) \ 59240116Smarcel : \ 60240116Smarcel : "memory" ); \ 61240116Smarcel (type)__res; \ 62240116Smarcel}) 63240116Smarcel 64240116Smarcel#define _hypercall1(type, name, a1) \ 65240116Smarcel({ \ 66240116Smarcel long __res, __ign1; \ 67240116Smarcel __asm__ volatile ( \ 68240116Smarcel HYPERCALL_STR(name) \ 69240116Smarcel : "=a" (__res), "=b" (__ign1) \ 70240116Smarcel : "1" ((long)(a1)) \ 71240116Smarcel : "memory" ); \ 72240116Smarcel (type)__res; \ 73240116Smarcel}) 74240116Smarcel 75240116Smarcel#define _hypercall2(type, name, a1, a2) \ 76240116Smarcel({ \ 77240116Smarcel long __res, __ign1, __ign2; \ 78240116Smarcel __asm__ volatile ( \ 79240116Smarcel HYPERCALL_STR(name) \ 80240116Smarcel : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \ 81240116Smarcel : "1" ((long)(a1)), "2" ((long)(a2)) \ 82240116Smarcel : "memory" ); \ 83240116Smarcel (type)__res; \ 84240116Smarcel}) 85240116Smarcel 86240116Smarcel#define _hypercall3(type, name, a1, a2, a3) \ 87240116Smarcel({ \ 88240116Smarcel long __res, __ign1, __ign2, __ign3; \ 89240116Smarcel __asm__ volatile ( \ 90240116Smarcel HYPERCALL_STR(name) \ 91240116Smarcel : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ 92240116Smarcel "=d" (__ign3) \ 93240116Smarcel : "1" ((long)(a1)), "2" ((long)(a2)), \ 94240116Smarcel "3" ((long)(a3)) \ 95240116Smarcel : "memory" ); \ 96240116Smarcel (type)__res; \ 97240116Smarcel}) 98240116Smarcel 99240116Smarcel#define _hypercall4(type, name, a1, a2, a3, a4) \ 100240116Smarcel({ \ 101240116Smarcel long __res, __ign1, __ign2, __ign3, __ign4; \ 102240116Smarcel __asm__ volatile ( \ 103240116Smarcel HYPERCALL_STR(name) \ 104240116Smarcel : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ 105240116Smarcel "=d" (__ign3), "=S" (__ign4) \ 106240116Smarcel : "1" ((long)(a1)), "2" ((long)(a2)), \ 107240116Smarcel "3" ((long)(a3)), "4" ((long)(a4)) \ 108240116Smarcel : "memory" ); \ 109240116Smarcel (type)__res; \ 110240116Smarcel}) 111240116Smarcel 112240116Smarcel#define _hypercall5(type, name, a1, a2, a3, a4, a5) \ 113240116Smarcel({ \ 114240116Smarcel long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \ 115240116Smarcel __asm__ volatile ( \ 116240116Smarcel HYPERCALL_STR(name) \ 117240116Smarcel : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ 118240116Smarcel "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \ 119240116Smarcel : "1" ((long)(a1)), "2" ((long)(a2)), \ 120240116Smarcel "3" ((long)(a3)), "4" ((long)(a4)), \ 121240116Smarcel "5" ((long)(a5)) \ 122240116Smarcel : "memory" ); \ 123240116Smarcel (type)__res; \ 124240116Smarcel}) 125240116Smarcel 126240116Smarcelstatic inline int 127240116SmarcelHYPERVISOR_set_trap_table( 128240116Smarcel trap_info_t *table) 129240116Smarcel{ 130240116Smarcel return _hypercall1(int, set_trap_table, table); 131240116Smarcel} 132240116Smarcel 133240116Smarcelstatic inline int 134240116SmarcelHYPERVISOR_mmu_update( 135240116Smarcel mmu_update_t *req, int count, int *success_count, domid_t domid) 136240116Smarcel{ 137240116Smarcel return _hypercall4(int, mmu_update, req, count, success_count, domid); 138240116Smarcel} 139240116Smarcel 140240116Smarcelstatic inline int 141240116SmarcelHYPERVISOR_mmuext_op( 142240116Smarcel mmuext_op_t *op, int count, int *success_count, domid_t domid) 143240116Smarcel{ 144240116Smarcel return _hypercall4(int, mmuext_op, op, count, success_count, domid); 145240116Smarcel} 146240116Smarcel 147240116Smarcelstatic inline int 148240116SmarcelHYPERVISOR_set_gdt( 149240116Smarcel unsigned long *frame_list, int entries) 150240116Smarcel{ 151240116Smarcel return _hypercall2(int, set_gdt, frame_list, entries); 152240116Smarcel} 153240116Smarcel 154240116Smarcelstatic inline int 155240116SmarcelHYPERVISOR_stack_switch( 156240116Smarcel unsigned long ss, unsigned long esp) 157240116Smarcel{ 158240116Smarcel return _hypercall2(int, stack_switch, ss, esp); 159240116Smarcel} 160240116Smarcel 161240116Smarcelstatic inline int 162240116SmarcelHYPERVISOR_set_callbacks( 163240116Smarcel unsigned long event_selector, unsigned long event_address, 164240116Smarcel unsigned long failsafe_selector, unsigned long failsafe_address) 165240116Smarcel{ 166240116Smarcel return _hypercall4(int, set_callbacks, 167240116Smarcel event_selector, event_address, 168240116Smarcel failsafe_selector, failsafe_address); 169240116Smarcel} 170240116Smarcel 171240116Smarcelstatic inline int 172240116SmarcelHYPERVISOR_fpu_taskswitch( 173240116Smarcel int set) 174240116Smarcel{ 175240116Smarcel return _hypercall1(int, fpu_taskswitch, set); 176240116Smarcel} 177240116Smarcel 178240116Smarcelstatic inline int 179240116SmarcelHYPERVISOR_sched_op_compat( 180240116Smarcel int cmd, unsigned long arg) 181240116Smarcel{ 182240116Smarcel return _hypercall2(int, sched_op_compat, cmd, arg); 183240116Smarcel} 184240116Smarcel 185240116Smarcelstatic inline int 186240116SmarcelHYPERVISOR_sched_op( 187240116Smarcel int cmd, void *arg) 188240116Smarcel{ 189240116Smarcel return _hypercall2(int, sched_op, cmd, arg); 190240116Smarcel} 191240116Smarcel 192240116Smarcelstatic inline long 193240116SmarcelHYPERVISOR_set_timer_op( 194240116Smarcel uint64_t timeout) 195240116Smarcel{ 196240116Smarcel unsigned long timeout_hi = (unsigned long)(timeout>>32); 197240116Smarcel unsigned long timeout_lo = (unsigned long)timeout; 198240116Smarcel return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi); 199240116Smarcel} 200240116Smarcel#if 0 201240116Smarcelstatic inline int 202240116SmarcelHYPERVISOR_platform_op( 203240116Smarcel struct xen_platform_op *platform_op) 204240116Smarcel{ 205240116Smarcel platform_op->interface_version = XENPF_INTERFACE_VERSION; 206240116Smarcel return _hypercall1(int, platform_op, platform_op); 207240116Smarcel} 208240116Smarcel#endif 209240116Smarcelstatic inline int 210240116SmarcelHYPERVISOR_set_debugreg( 211240116Smarcel int reg, unsigned long value) 212240116Smarcel{ 213240116Smarcel return _hypercall2(int, set_debugreg, reg, value); 214240116Smarcel} 215240116Smarcel 216240116Smarcelstatic inline unsigned long 217240116SmarcelHYPERVISOR_get_debugreg( 218240116Smarcel int reg) 219240116Smarcel{ 220240116Smarcel return _hypercall1(unsigned long, get_debugreg, reg); 221240116Smarcel} 222240116Smarcel 223240116Smarcelstatic inline int 224240116SmarcelHYPERVISOR_update_descriptor( 225240116Smarcel uint64_t ma, uint64_t desc) 226240116Smarcel{ 227240116Smarcel return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32); 228240116Smarcel} 229240116Smarcel 230240116Smarcelstatic inline int 231240116SmarcelHYPERVISOR_memory_op( 232240116Smarcel unsigned int cmd, void *arg) 233240116Smarcel{ 234240116Smarcel return _hypercall2(int, memory_op, cmd, arg); 235240116Smarcel} 236240116Smarcel 237240116Smarcelstatic inline int 238240116SmarcelHYPERVISOR_multicall( 239240116Smarcel void *call_list, int nr_calls) 240240116Smarcel{ 241240116Smarcel return _hypercall2(int, multicall, call_list, nr_calls); 242240116Smarcel} 243240116Smarcel 244240116Smarcelstatic inline int 245240116SmarcelHYPERVISOR_update_va_mapping( 246240116Smarcel unsigned long va, uint64_t new_val, unsigned long flags) 247240116Smarcel{ 248240116Smarcel uint32_t hi, lo; 249240116Smarcel 250240116Smarcel lo = (uint32_t)(new_val & 0xffffffff); 251240116Smarcel hi = (uint32_t)(new_val >> 32); 252240116Smarcel 253240116Smarcel return _hypercall4(int, update_va_mapping, va, 254240116Smarcel lo, hi, flags); 255240116Smarcel} 256240116Smarcel 257240116Smarcelstatic inline int 258240116SmarcelHYPERVISOR_event_channel_op( 259240116Smarcel int cmd, void *arg) 260240116Smarcel{ 261240116Smarcel int rc = _hypercall2(int, event_channel_op, cmd, arg); 262240116Smarcel 263240116Smarcel#if CONFIG_XEN_COMPAT <= 0x030002 264240116Smarcel if (__predict_false(rc == -ENOXENSYS)) { 265240116Smarcel struct evtchn_op op; 266240116Smarcel op.cmd = cmd; 267240116Smarcel memcpy(&op.u, arg, sizeof(op.u)); 268240116Smarcel rc = _hypercall1(int, event_channel_op_compat, &op); 269240116Smarcel memcpy(arg, &op.u, sizeof(op.u)); 270240116Smarcel } 271240116Smarcel#endif 272240116Smarcel return (rc); 273240116Smarcel} 274240116Smarcel 275240116Smarcelstatic inline int 276240116SmarcelHYPERVISOR_xen_version( 277240116Smarcel int cmd, void *arg) 278240116Smarcel{ 279240116Smarcel return _hypercall2(int, xen_version, cmd, arg); 280240116Smarcel} 281240116Smarcel 282240116Smarcelstatic inline int 283240116SmarcelHYPERVISOR_console_io( 284240116Smarcel int cmd, int count, char *str) 285240116Smarcel{ 286240116Smarcel return _hypercall3(int, console_io, cmd, count, str); 287240116Smarcel} 288240116Smarcel 289240116Smarcelstatic inline int 290240116SmarcelHYPERVISOR_physdev_op( 291240116Smarcel int cmd, void *arg) 292240116Smarcel{ 293240116Smarcel int rc = _hypercall2(int, physdev_op, cmd, arg); 294240116Smarcel#if CONFIG_XEN_COMPAT <= 0x030002 295240116Smarcel if (__predict_false(rc == -ENOXENSYS)) { 296240116Smarcel struct physdev_op op; 297240116Smarcel op.cmd = cmd; 298240116Smarcel memcpy(&op.u, arg, sizeof(op.u)); 299240116Smarcel rc = _hypercall1(int, physdev_op_compat, &op); 300240116Smarcel memcpy(arg, &op.u, sizeof(op.u)); 301240116Smarcel } 302240116Smarcel#endif 303240116Smarcel return (rc); 304240116Smarcel} 305240116Smarcel 306240116Smarcelstatic inline int 307240116SmarcelHYPERVISOR_grant_table_op( 308240116Smarcel unsigned int cmd, void *uop, unsigned int count) 309240116Smarcel{ 310240116Smarcel return _hypercall3(int, grant_table_op, cmd, uop, count); 311240116Smarcel} 312240116Smarcel 313240116Smarcelstatic inline int 314240116SmarcelHYPERVISOR_update_va_mapping_otherdomain( 315240116Smarcel unsigned long va, uint64_t new_val, unsigned long flags, domid_t domid) 316240116Smarcel{ 317240116Smarcel uint32_t hi, lo; 318240116Smarcel 319240116Smarcel lo = (uint32_t)(new_val & 0xffffffff); 320240116Smarcel hi = (uint32_t)(new_val >> 32); 321240116Smarcel 322240116Smarcel return _hypercall5(int, update_va_mapping_otherdomain, va, 323240116Smarcel lo, hi, flags, domid); 324240116Smarcel} 325240116Smarcel 326240116Smarcelstatic inline int 327240116SmarcelHYPERVISOR_vm_assist( 328240116Smarcel unsigned int cmd, unsigned int type) 329240116Smarcel{ 330240116Smarcel return _hypercall2(int, vm_assist, cmd, type); 331240116Smarcel} 332240116Smarcel 333240116Smarcelstatic inline int 334240116SmarcelHYPERVISOR_vcpu_op( 335240116Smarcel int cmd, int vcpuid, void *extra_args) 336240116Smarcel{ 337240116Smarcel return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args); 338240116Smarcel} 339240116Smarcel 340240116Smarcelstatic inline int 341240116SmarcelHYPERVISOR_suspend( 342240116Smarcel unsigned long srec) 343240116Smarcel{ 344240116Smarcel struct sched_shutdown sched_shutdown = { 345240116Smarcel .reason = SHUTDOWN_suspend 346240116Smarcel }; 347240116Smarcel int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown, 348240116Smarcel &sched_shutdown, srec); 349240116Smarcel#if CONFIG_XEN_COMPAT <= 0x030002 350240116Smarcel if (rc == -ENOXENSYS) 351240116Smarcel rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown, 352240116Smarcel SHUTDOWN_suspend, srec); 353240116Smarcel#endif 354240116Smarcel return (rc); 355240116Smarcel} 356240116Smarcel 357240116Smarcel#if CONFIG_XEN_COMPAT <= 0x030002 358240116Smarcelstatic inline int 359240116SmarcelHYPERVISOR_nmi_op( 360240116Smarcel unsigned long op, void *arg) 361240116Smarcel{ 362240116Smarcel return _hypercall2(int, nmi_op, op, arg); 363240116Smarcel} 364240116Smarcel#endif 365240116Smarcel 366240116Smarcelstatic inline int 367240116SmarcelHYPERVISOR_callback_op( 368240116Smarcel int cmd, void *arg) 369240116Smarcel{ 370240116Smarcel return _hypercall2(int, callback_op, cmd, arg); 371240116Smarcel} 372240116Smarcel 373240116Smarcel#ifndef CONFIG_XEN 374240116Smarcelstatic inline unsigned long 375240116SmarcelHYPERVISOR_hvm_op( 376240116Smarcel int op, void *arg) 377240116Smarcel{ 378240116Smarcel return _hypercall2(unsigned long, hvm_op, op, arg); 379240116Smarcel} 380240116Smarcel#endif 381240116Smarcel 382240116Smarcelstatic inline int 383240116SmarcelHYPERVISOR_xenoprof_op( 384240116Smarcel int op, void *arg) 385240116Smarcel{ 386240116Smarcel return _hypercall2(int, xenoprof_op, op, arg); 387240116Smarcel} 388240116Smarcel 389240116Smarcelstatic inline int 390240116SmarcelHYPERVISOR_kexec_op( 391240116Smarcel unsigned long op, void *args) 392{ 393 return _hypercall2(int, kexec_op, op, args); 394} 395#endif /* __HYPERCALL_H__ */ 396 397/* 398 * Local variables: 399 * c-file-style: "linux" 400 * indent-tabs-mode: t 401 * c-indent-level: 8 402 * c-basic-offset: 8 403 * tab-width: 8 404 * End: 405 */ 406