1/****************************************************************************** 2 * hypercall.h 3 * 4 * Linux-specific hypervisor handling. 5 * 6 * Copyright (c) 2002-2004, K A Fraser 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License version 2 10 * as published by the Free Software Foundation; or, when distributed 11 * separately from the Linux kernel or incorporated into other 12 * software packages, subject to the following license: 13 * 14 * Permission is hereby granted, free of charge, to any person obtaining a copy 15 * of this source file (the "Software"), to deal in the Software without 16 * restriction, including without limitation the rights to use, copy, modify, 17 * merge, publish, distribute, sublicense, and/or sell copies of the Software, 18 * and to permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be included in 22 * all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 30 * IN THE SOFTWARE. 31 */ 32 33#ifndef _ASM_IA64_XEN_HYPERCALL_H 34#define _ASM_IA64_XEN_HYPERCALL_H 35 36#include <xen/interface/xen.h> 37#include <xen/interface/physdev.h> 38#include <xen/interface/sched.h> 39#include <asm/xen/xcom_hcall.h> 40struct xencomm_handle; 41extern unsigned long __hypercall(unsigned long a1, unsigned long a2, 42 unsigned long a3, unsigned long a4, 43 unsigned long a5, unsigned long cmd); 44 45/* 46 * Assembler stubs for hyper-calls. 47 */ 48 49#define _hypercall0(type, name) \ 50({ \ 51 long __res; \ 52 __res = __hypercall(0, 0, 0, 0, 0, __HYPERVISOR_##name);\ 53 (type)__res; \ 54}) 55 56#define _hypercall1(type, name, a1) \ 57({ \ 58 long __res; \ 59 __res = __hypercall((unsigned long)a1, \ 60 0, 0, 0, 0, __HYPERVISOR_##name); \ 61 (type)__res; \ 62}) 63 64#define _hypercall2(type, name, a1, a2) \ 65({ \ 66 long __res; \ 67 __res = __hypercall((unsigned long)a1, \ 68 (unsigned long)a2, \ 69 0, 0, 0, __HYPERVISOR_##name); \ 70 (type)__res; \ 71}) 72 73#define _hypercall3(type, name, a1, a2, a3) \ 74({ \ 75 long __res; \ 76 __res = __hypercall((unsigned long)a1, \ 77 (unsigned long)a2, \ 78 (unsigned long)a3, \ 79 0, 0, __HYPERVISOR_##name); \ 80 (type)__res; \ 81}) 82 83#define _hypercall4(type, name, a1, a2, a3, a4) \ 84({ \ 85 long __res; \ 86 __res = __hypercall((unsigned long)a1, \ 87 (unsigned long)a2, \ 88 (unsigned long)a3, \ 89 (unsigned long)a4, \ 90 0, __HYPERVISOR_##name); \ 91 (type)__res; \ 92}) 93 94#define _hypercall5(type, name, a1, a2, a3, a4, a5) \ 95({ \ 96 long __res; \ 97 __res = __hypercall((unsigned long)a1, \ 98 (unsigned long)a2, \ 99 (unsigned long)a3, \ 100 (unsigned long)a4, \ 101 (unsigned long)a5, \ 102 __HYPERVISOR_##name); \ 103 (type)__res; \ 104}) 105 106 107static inline int 108xencomm_arch_hypercall_sched_op(int cmd, struct xencomm_handle *arg) 109{ 110 return _hypercall2(int, sched_op_new, cmd, arg); 111} 112 113static inline long 114HYPERVISOR_set_timer_op(u64 timeout) 115{ 116 unsigned long timeout_hi = (unsigned long)(timeout >> 32); 117 unsigned long timeout_lo = (unsigned long)timeout; 118 return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi); 119} 120 121static inline int 122xencomm_arch_hypercall_multicall(struct xencomm_handle *call_list, 123 int nr_calls) 124{ 125 return _hypercall2(int, multicall, call_list, nr_calls); 126} 127 128static inline int 129xencomm_arch_hypercall_memory_op(unsigned int cmd, struct xencomm_handle *arg) 130{ 131 return _hypercall2(int, memory_op, cmd, arg); 132} 133 134static inline int 135xencomm_arch_hypercall_event_channel_op(int cmd, struct xencomm_handle *arg) 136{ 137 return _hypercall2(int, event_channel_op, cmd, arg); 138} 139 140static inline int 141xencomm_arch_hypercall_xen_version(int cmd, struct xencomm_handle *arg) 142{ 143 return _hypercall2(int, xen_version, cmd, arg); 144} 145 146static inline int 147xencomm_arch_hypercall_console_io(int cmd, int count, 148 struct xencomm_handle *str) 149{ 150 return _hypercall3(int, console_io, cmd, count, str); 151} 152 153static inline int 154xencomm_arch_hypercall_physdev_op(int cmd, struct xencomm_handle *arg) 155{ 156 return _hypercall2(int, physdev_op, cmd, arg); 157} 158 159static inline int 160xencomm_arch_hypercall_grant_table_op(unsigned int cmd, 161 struct xencomm_handle *uop, 162 unsigned int count) 163{ 164 return _hypercall3(int, grant_table_op, cmd, uop, count); 165} 166 167int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count); 168 169extern int xencomm_arch_hypercall_suspend(struct xencomm_handle *arg); 170 171static inline int 172xencomm_arch_hypercall_callback_op(int cmd, struct xencomm_handle *arg) 173{ 174 return _hypercall2(int, callback_op, cmd, arg); 175} 176 177static inline long 178xencomm_arch_hypercall_vcpu_op(int cmd, int cpu, void *arg) 179{ 180 return _hypercall3(long, vcpu_op, cmd, cpu, arg); 181} 182 183static inline int 184HYPERVISOR_physdev_op(int cmd, void *arg) 185{ 186 switch (cmd) { 187 case PHYSDEVOP_eoi: 188 return _hypercall1(int, ia64_fast_eoi, 189 ((struct physdev_eoi *)arg)->irq); 190 default: 191 return xencomm_hypercall_physdev_op(cmd, arg); 192 } 193} 194 195static inline long 196xencomm_arch_hypercall_opt_feature(struct xencomm_handle *arg) 197{ 198 return _hypercall1(long, opt_feature, arg); 199} 200 201/* for balloon driver */ 202#define HYPERVISOR_update_va_mapping(va, new_val, flags) (0) 203 204/* Use xencomm to do hypercalls. */ 205#define HYPERVISOR_sched_op xencomm_hypercall_sched_op 206#define HYPERVISOR_event_channel_op xencomm_hypercall_event_channel_op 207#define HYPERVISOR_callback_op xencomm_hypercall_callback_op 208#define HYPERVISOR_multicall xencomm_hypercall_multicall 209#define HYPERVISOR_xen_version xencomm_hypercall_xen_version 210#define HYPERVISOR_console_io xencomm_hypercall_console_io 211#define HYPERVISOR_memory_op xencomm_hypercall_memory_op 212#define HYPERVISOR_suspend xencomm_hypercall_suspend 213#define HYPERVISOR_vcpu_op xencomm_hypercall_vcpu_op 214#define HYPERVISOR_opt_feature xencomm_hypercall_opt_feature 215 216/* to compile gnttab_copy_grant_page() in drivers/xen/core/gnttab.c */ 217#define HYPERVISOR_mmu_update(req, count, success_count, domid) ({ BUG(); 0; }) 218 219static inline int 220HYPERVISOR_shutdown( 221 unsigned int reason) 222{ 223 struct sched_shutdown sched_shutdown = { 224 .reason = reason 225 }; 226 227 int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown); 228 229 return rc; 230} 231 232/* for netfront.c, netback.c */ 233#define MULTI_UVMFLAGS_INDEX 0 234 235static inline void 236MULTI_update_va_mapping( 237 struct multicall_entry *mcl, unsigned long va, 238 pte_t new_val, unsigned long flags) 239{ 240 mcl->op = __HYPERVISOR_update_va_mapping; 241 mcl->result = 0; 242} 243 244static inline void 245MULTI_grant_table_op(struct multicall_entry *mcl, unsigned int cmd, 246 void *uop, unsigned int count) 247{ 248 mcl->op = __HYPERVISOR_grant_table_op; 249 mcl->args[0] = cmd; 250 mcl->args[1] = (unsigned long)uop; 251 mcl->args[2] = count; 252} 253 254static inline void 255MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req, 256 int count, int *success_count, domid_t domid) 257{ 258 mcl->op = __HYPERVISOR_mmu_update; 259 mcl->args[0] = (unsigned long)req; 260 mcl->args[1] = count; 261 mcl->args[2] = (unsigned long)success_count; 262 mcl->args[3] = domid; 263} 264 265#endif /* _ASM_IA64_XEN_HYPERCALL_H */ 266