1 /******************************************************************************
4 * Linux-specific hypervisor handling.
6 * Copyright (c) 2002-2004, K A Fraser
9 * Benjamin Liu <benjamin.liu@intel.com>
10 * Jun Nakajima <jun.nakajima@intel.com>
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:
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:
25 * The above copyright notice and this permission notice shall be included in
26 * all copies or substantial portions of the Software.
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
37 #ifndef __MACHINE_XEN_HYPERCALL_H__
38 #define __MACHINE_XEN_HYPERCALL_H__
40 #include <sys/systm.h>
42 #ifndef __XEN_HYPERVISOR_H__
43 # error "please don't include this file directly"
47 #define STR(x) __STR(x)
49 #define CONFIG_XEN_COMPAT 0x030002
53 #define HYPERCALL_STR(name) \
54 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"
56 #define HYPERCALL_STR(name) \
57 "mov $("STR(__HYPERVISOR_##name)" * 32),%%eax; "\
58 "add hypercall_stubs(%%rip),%%rax; " \
62 #define _hypercall0(type, name) \
73 #define _hypercall1(type, name, a1) \
79 : "=a" (__res), "=D" (__ign1) \
85 #define _hypercall2(type, name, a1, a2) \
88 long __ign1, __ign2; \
91 : "=a" (__res), "=D" (__ign1), "=S" (__ign2) \
92 : "1" ((long)(a1)), "2" ((long)(a2)) \
97 #define _hypercall3(type, name, a1, a2, a3) \
100 long __ign1, __ign2, __ign3; \
102 HYPERCALL_STR(name) \
103 : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \
105 : "1" ((long)(a1)), "2" ((long)(a2)), \
111 #define _hypercall4(type, name, a1, a2, a3, a4) \
114 long __ign1, __ign2, __ign3; \
115 register long __arg4 __asm__("r10") = (long)(a4); \
117 HYPERCALL_STR(name) \
118 : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \
119 "=d" (__ign3), "+r" (__arg4) \
120 : "1" ((long)(a1)), "2" ((long)(a2)), \
126 #define _hypercall5(type, name, a1, a2, a3, a4, a5) \
129 long __ign1, __ign2, __ign3; \
130 register long __arg4 __asm__("r10") = (long)(a4); \
131 register long __arg5 __asm__("r8") = (long)(a5); \
133 HYPERCALL_STR(name) \
134 : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \
135 "=d" (__ign3), "+r" (__arg4), "+r" (__arg5) \
136 : "1" ((long)(a1)), "2" ((long)(a2)), \
142 static inline int __must_check
143 HYPERVISOR_set_trap_table(
144 const trap_info_t *table)
146 return _hypercall1(int, set_trap_table, table);
149 static inline int __must_check
150 HYPERVISOR_mmu_update(
151 mmu_update_t *req, unsigned int count, unsigned int *success_count,
154 return _hypercall4(int, mmu_update, req, count, success_count, domid);
157 static inline int __must_check
158 HYPERVISOR_mmuext_op(
159 struct mmuext_op *op, unsigned int count, unsigned int *success_count,
162 return _hypercall4(int, mmuext_op, op, count, success_count, domid);
165 static inline int __must_check
167 unsigned long *frame_list, unsigned int entries)
169 return _hypercall2(int, set_gdt, frame_list, entries);
172 static inline int __must_check
173 HYPERVISOR_stack_switch(
174 unsigned long ss, unsigned long esp)
176 return _hypercall2(int, stack_switch, ss, esp);
179 static inline int __must_check
180 HYPERVISOR_set_callbacks(
181 unsigned long event_address, unsigned long failsafe_address,
182 unsigned long syscall_address)
184 return _hypercall3(int, set_callbacks,
185 event_address, failsafe_address, syscall_address);
189 HYPERVISOR_fpu_taskswitch(
192 return _hypercall1(int, fpu_taskswitch, set);
195 static inline int __must_check
196 HYPERVISOR_sched_op_compat(
197 int cmd, unsigned long arg)
199 return _hypercall2(int, sched_op_compat, cmd, arg);
202 static inline int __must_check
206 return _hypercall2(int, sched_op, cmd, arg);
209 static inline long __must_check
210 HYPERVISOR_set_timer_op(
213 return _hypercall1(long, set_timer_op, timeout);
216 static inline int __must_check
217 HYPERVISOR_platform_op(
218 struct xen_platform_op *platform_op)
220 platform_op->interface_version = XENPF_INTERFACE_VERSION;
221 return _hypercall1(int, platform_op, platform_op);
224 static inline int __must_check
225 HYPERVISOR_set_debugreg(
226 unsigned int reg, unsigned long value)
228 return _hypercall2(int, set_debugreg, reg, value);
231 static inline unsigned long __must_check
232 HYPERVISOR_get_debugreg(
235 return _hypercall1(unsigned long, get_debugreg, reg);
238 static inline int __must_check
239 HYPERVISOR_update_descriptor(
240 unsigned long ma, unsigned long word)
242 return _hypercall2(int, update_descriptor, ma, word);
245 static inline int __must_check
246 HYPERVISOR_memory_op(
247 unsigned int cmd, void *arg)
249 return _hypercall2(int, memory_op, cmd, arg);
252 static inline int __must_check
253 HYPERVISOR_multicall(
254 multicall_entry_t *call_list, unsigned int nr_calls)
256 return _hypercall2(int, multicall, call_list, nr_calls);
259 static inline int __must_check
260 HYPERVISOR_update_va_mapping(
261 unsigned long va, uint64_t new_val, unsigned long flags)
263 return _hypercall3(int, update_va_mapping, va, new_val, flags);
266 static inline int __must_check
267 HYPERVISOR_event_channel_op(
270 int rc = _hypercall2(int, event_channel_op, cmd, arg);
272 #if CONFIG_XEN_COMPAT <= 0x030002
273 if (unlikely(rc == -ENOXENSYS)) {
276 memcpy(&op.u, arg, sizeof(op.u));
277 rc = _hypercall1(int, event_channel_op_compat, &op);
278 memcpy(arg, &op.u, sizeof(op.u));
285 static inline int __must_check
286 HYPERVISOR_xen_version(
289 return _hypercall2(int, xen_version, cmd, arg);
292 static inline int __must_check
293 HYPERVISOR_console_io(
294 int cmd, unsigned int count, char *str)
296 return _hypercall3(int, console_io, cmd, count, str);
299 static inline int __must_check
300 HYPERVISOR_physdev_op(
303 int rc = _hypercall2(int, physdev_op, cmd, arg);
305 #if CONFIG_XEN_COMPAT <= 0x030002
306 if (unlikely(rc == -ENOXENSYS)) {
307 struct physdev_op op;
309 memcpy(&op.u, arg, sizeof(op.u));
310 rc = _hypercall1(int, physdev_op_compat, &op);
311 memcpy(arg, &op.u, sizeof(op.u));
318 static inline int __must_check
319 HYPERVISOR_grant_table_op(
320 unsigned int cmd, void *uop, unsigned int count)
322 return _hypercall3(int, grant_table_op, cmd, uop, count);
325 static inline int __must_check
326 HYPERVISOR_update_va_mapping_otherdomain(
327 unsigned long va, uint64_t new_val, unsigned long flags, domid_t domid)
329 return _hypercall4(int, update_va_mapping_otherdomain, va,
330 new_val, flags, domid);
333 static inline int __must_check
334 HYPERVISOR_vm_assist(
335 unsigned int cmd, unsigned int type)
337 return _hypercall2(int, vm_assist, cmd, type);
340 static inline int __must_check
342 int cmd, unsigned int vcpuid, void *extra_args)
344 return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
347 static inline int __must_check
348 HYPERVISOR_set_segment_base(
349 int reg, unsigned long value)
351 return _hypercall2(int, set_segment_base, reg, value);
354 static inline int __must_check
358 struct sched_shutdown sched_shutdown = {
359 .reason = SHUTDOWN_suspend
362 int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown,
363 &sched_shutdown, srec);
365 #if CONFIG_XEN_COMPAT <= 0x030002
366 if (rc == -ENOXENSYS)
367 rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown,
368 SHUTDOWN_suspend, srec);
374 #if CONFIG_XEN_COMPAT <= 0x030002
377 unsigned long op, void *arg)
379 return _hypercall2(int, nmi_op, op, arg);
384 static inline unsigned long __must_check
388 return _hypercall2(unsigned long, hvm_op, op, arg);
392 static inline int __must_check
393 HYPERVISOR_callback_op(
394 int cmd, const void *arg)
396 return _hypercall2(int, callback_op, cmd, arg);
399 static inline int __must_check
400 HYPERVISOR_xenoprof_op(
403 return _hypercall2(int, xenoprof_op, op, arg);
406 static inline int __must_check
408 unsigned long op, void *args)
410 return _hypercall2(int, kexec_op, op, args);
415 #endif /* __MACHINE_XEN_HYPERCALL_H__ */