1 /******************************************************************************
4 * Linux-specific hypervisor handling.
6 * Copyright (c) 2002-2004, K A Fraser
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:
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:
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
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
33 #ifndef __HYPERCALL_H__
34 #define __HYPERCALL_H__
36 #include <linux/string.h> /* memcpy() */
38 #ifndef __HYPERVISOR_H__
39 # error "please don't include this file directly"
43 * Assembler stubs for hyper-calls.
46 #define _hypercall0(type, name) \
49 __asm__ __volatile__ (";;\n" \
54 : "J" (__HYPERVISOR_##name) \
60 #define _hypercall1(type, name, a1) \
63 __asm__ __volatile__ (";;\n" \
69 : "J" (__HYPERVISOR_##name), \
70 "rI" ((unsigned long)(a1)) \
76 #define _hypercall2(type, name, a1, a2) \
79 __asm__ __volatile__ (";;\n" \
86 : "J" (__HYPERVISOR_##name), \
87 "rI" ((unsigned long)(a1)), \
88 "rI" ((unsigned long)(a2)) \
89 : "r14","r15","r2","r8", \
94 #define _hypercall3(type, name, a1, a2, a3) \
97 __asm__ __volatile__ (";;\n" \
102 "break 0x1000 ;;\n" \
105 : "J" (__HYPERVISOR_##name), \
106 "rI" ((unsigned long)(a1)), \
107 "rI" ((unsigned long)(a2)), \
108 "rI" ((unsigned long)(a3)) \
109 : "r14","r15","r16","r2","r8", \
114 #define _hypercall4(type, name, a1, a2, a3, a4) \
117 __asm__ __volatile__ (";;\n" \
123 "break 0x1000 ;;\n" \
126 : "J" (__HYPERVISOR_##name), \
127 "rI" ((unsigned long)(a1)), \
128 "rI" ((unsigned long)(a2)), \
129 "rI" ((unsigned long)(a3)), \
130 "rI" ((unsigned long)(a4)) \
131 : "r14","r15","r16","r2","r8", \
136 #define _hypercall5(type, name, a1, a2, a3, a4, a5) \
139 __asm__ __volatile__ (";;\n" \
146 "break 0x1000 ;;\n" \
149 : "J" (__HYPERVISOR_##name), \
150 "rI" ((unsigned long)(a1)), \
151 "rI" ((unsigned long)(a2)), \
152 "rI" ((unsigned long)(a3)), \
153 "rI" ((unsigned long)(a4)), \
154 "rI" ((unsigned long)(a5)) \
155 : "r14","r15","r16","r2","r8", \
156 "r17","r18","memory" ); \
161 HYPERVISOR_sched_op_compat(
162 int cmd, unsigned long arg)
164 return _hypercall2(int, sched_op_compat, cmd, arg);
171 return _hypercall2(int, sched_op, cmd, arg);
175 HYPERVISOR_set_timer_op(
178 unsigned long timeout_hi = (unsigned long)(timeout>>32);
179 unsigned long timeout_lo = (unsigned long)timeout;
180 return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
187 dom0_op->interface_version = DOM0_INTERFACE_VERSION;
188 return _hypercall1(int, dom0_op, dom0_op);
192 HYPERVISOR_multicall(
193 void *call_list, int nr_calls)
195 return _hypercall2(int, multicall, call_list, nr_calls);
198 //XXX xen/ia64 copy_from_guest() is broken.
199 // This is a temporal work around until it is fixed.
201 ____HYPERVISOR_memory_op(
202 unsigned int cmd, void *arg)
204 return _hypercall2(int, memory_op, cmd, arg);
207 #include <xen/interface/memory.h>
208 #ifdef CONFIG_VMX_GUEST
209 # define ia64_xenmem_reservation_op(op, xmr) (0)
211 int ia64_xenmem_reservation_op(unsigned long op,
212 struct xen_memory_reservation* reservation__);
215 HYPERVISOR_memory_op(
216 unsigned int cmd, void *arg)
219 case XENMEM_increase_reservation:
220 case XENMEM_decrease_reservation:
221 case XENMEM_populate_physmap:
222 return ia64_xenmem_reservation_op(cmd,
223 (struct xen_memory_reservation*)arg);
225 return ____HYPERVISOR_memory_op(cmd, arg);
231 HYPERVISOR_event_channel_op(
234 int rc = _hypercall2(int, event_channel_op, cmd, arg);
235 if (unlikely(rc == -ENOSYS)) {
238 memcpy(&op.u, arg, sizeof(op.u));
239 rc = _hypercall1(int, event_channel_op_compat, &op);
246 unsigned int cmd, void *arg)
248 return _hypercall2(int, acm_op, cmd, arg);
252 HYPERVISOR_xen_version(
255 return _hypercall2(int, xen_version, cmd, arg);
259 HYPERVISOR_console_io(
260 int cmd, int count, char *str)
262 return _hypercall3(int, console_io, cmd, count, str);
266 HYPERVISOR_physdev_op(
269 int rc = _hypercall2(int, physdev_op, cmd, arg);
270 if (unlikely(rc == -ENOSYS)) {
271 struct physdev_op op;
273 memcpy(&op.u, arg, sizeof(op.u));
274 rc = _hypercall1(int, physdev_op_compat, &op);
279 //XXX __HYPERVISOR_grant_table_op is used for this hypercall constant.
281 ____HYPERVISOR_grant_table_op(
282 unsigned int cmd, void *uop, unsigned int count,
283 unsigned long pa1, unsigned long pa2)
285 return _hypercall5(int, grant_table_op, cmd, uop, count, pa1, pa2);
288 int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
292 int cmd, int vcpuid, void *extra_args)
294 return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
297 extern int HYPERVISOR_suspend(unsigned long srec);
299 static inline unsigned long
303 return _hypercall2(unsigned long, hvm_op, cmd, arg);
307 HYPERVISOR_callback_op(
310 return _hypercall2(int, callback_op, cmd, arg);
313 extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
314 static inline void exit_idle(void) {}
315 #define do_IRQ(irq, regs) ({ \
317 __do_IRQ((irq), (regs)); \
321 #include <linux/err.h>
323 #include <asm/xen/privop.h>
324 #endif /* CONFIG_XEN */
326 static inline unsigned long
327 __HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
329 return _hypercall3(unsigned long, ia64_dom0vp_op,
330 IA64_DOM0VP_ioremap, ioaddr, size);
333 static inline unsigned long
334 HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
336 unsigned long ret = ioaddr;
337 if (is_running_on_xen()) {
338 ret = __HYPERVISOR_ioremap(ioaddr, size);
339 if (unlikely(ret == -ENOSYS))
340 panic("hypercall %s failed with %ld. "
341 "Please check Xen and Linux config mismatch\n",
343 else if (unlikely(IS_ERR_VALUE(ret)))
349 static inline unsigned long
350 __HYPERVISOR_phystomach(unsigned long gpfn)
352 return _hypercall2(unsigned long, ia64_dom0vp_op,
353 IA64_DOM0VP_phystomach, gpfn);
356 static inline unsigned long
357 HYPERVISOR_phystomach(unsigned long gpfn)
359 unsigned long ret = gpfn;
360 if (is_running_on_xen()) {
361 ret = __HYPERVISOR_phystomach(gpfn);
366 static inline unsigned long
367 __HYPERVISOR_machtophys(unsigned long mfn)
369 return _hypercall2(unsigned long, ia64_dom0vp_op,
370 IA64_DOM0VP_machtophys, mfn);
373 static inline unsigned long
374 HYPERVISOR_machtophys(unsigned long mfn)
376 unsigned long ret = mfn;
377 if (is_running_on_xen()) {
378 ret = __HYPERVISOR_machtophys(mfn);
383 static inline unsigned long
384 __HYPERVISOR_zap_physmap(unsigned long gpfn, unsigned int extent_order)
386 return _hypercall3(unsigned long, ia64_dom0vp_op,
387 IA64_DOM0VP_zap_physmap, gpfn, extent_order);
390 static inline unsigned long
391 HYPERVISOR_zap_physmap(unsigned long gpfn, unsigned int extent_order)
393 unsigned long ret = 0;
394 if (is_running_on_xen()) {
395 ret = __HYPERVISOR_zap_physmap(gpfn, extent_order);
400 static inline unsigned long
401 __HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
402 unsigned long flags, domid_t domid)
404 return _hypercall5(unsigned long, ia64_dom0vp_op,
405 IA64_DOM0VP_add_physmap, gpfn, mfn, flags, domid);
408 static inline unsigned long
409 HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
410 unsigned long flags, domid_t domid)
412 unsigned long ret = 0;
413 BUG_ON(!is_running_on_xen());//XXX
414 if (is_running_on_xen()) {
415 ret = __HYPERVISOR_add_physmap(gpfn, mfn, flags, domid);
420 // for balloon driver
421 #define HYPERVISOR_update_va_mapping(va, new_val, flags) (0)
423 #endif /* __HYPERCALL_H__ */