aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-i386/xen/hypercall.h
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@xensource.com>2007-07-17 21:37:04 -0400
committerJeremy Fitzhardinge <jeremy@goop.org>2007-07-18 11:47:42 -0400
commita42089dd358a7673a0a23126589a9029e57c2049 (patch)
treeaa076610832f5cdb0ee209c42ea7e40d54534ef4 /include/asm-i386/xen/hypercall.h
parent24037a8b69dbf15bfed8fd42a2a2e442d7b0395b (diff)
xen: Add Xen interface header files
Add Xen interface header files. These are taken fairly directly from the Xen tree, but somewhat rearranged to suit the kernel's conventions. Define macros and inline functions for doing hypercalls into the hypervisor. Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Signed-off-by: Ian Pratt <ian.pratt@xensource.com> Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk> Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Diffstat (limited to 'include/asm-i386/xen/hypercall.h')
-rw-r--r--include/asm-i386/xen/hypercall.h395
1 files changed, 395 insertions, 0 deletions
diff --git a/include/asm-i386/xen/hypercall.h b/include/asm-i386/xen/hypercall.h
new file mode 100644
index 000000000000..53912859708b
--- /dev/null
+++ b/include/asm-i386/xen/hypercall.h
@@ -0,0 +1,395 @@
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 __HYPERCALL_H__
34#define __HYPERCALL_H__
35
36#include <linux/errno.h>
37#include <linux/string.h>
38
39#include <xen/interface/xen.h>
40#include <xen/interface/sched.h>
41#include <xen/interface/physdev.h>
42
43extern struct { char _entry[32]; } hypercall_page[];
44
45#define _hypercall0(type, name) \
46({ \
47 long __res; \
48 asm volatile ( \
49 "call %[call]" \
50 : "=a" (__res) \
51 : [call] "m" (hypercall_page[__HYPERVISOR_##name]) \
52 : "memory" ); \
53 (type)__res; \
54})
55
56#define _hypercall1(type, name, a1) \
57({ \
58 long __res, __ign1; \
59 asm volatile ( \
60 "call %[call]" \
61 : "=a" (__res), "=b" (__ign1) \
62 : "1" ((long)(a1)), \
63 [call] "m" (hypercall_page[__HYPERVISOR_##name]) \
64 : "memory" ); \
65 (type)__res; \
66})
67
68#define _hypercall2(type, name, a1, a2) \
69({ \
70 long __res, __ign1, __ign2; \
71 asm volatile ( \
72 "call %[call]" \
73 : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \
74 : "1" ((long)(a1)), "2" ((long)(a2)), \
75 [call] "m" (hypercall_page[__HYPERVISOR_##name]) \
76 : "memory" ); \
77 (type)__res; \
78})
79
80#define _hypercall3(type, name, a1, a2, a3) \
81({ \
82 long __res, __ign1, __ign2, __ign3; \
83 asm volatile ( \
84 "call %[call]" \
85 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
86 "=d" (__ign3) \
87 : "1" ((long)(a1)), "2" ((long)(a2)), \
88 "3" ((long)(a3)), \
89 [call] "m" (hypercall_page[__HYPERVISOR_##name]) \
90 : "memory" ); \
91 (type)__res; \
92})
93
94#define _hypercall4(type, name, a1, a2, a3, a4) \
95({ \
96 long __res, __ign1, __ign2, __ign3, __ign4; \
97 asm volatile ( \
98 "call %[call]" \
99 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
100 "=d" (__ign3), "=S" (__ign4) \
101 : "1" ((long)(a1)), "2" ((long)(a2)), \
102 "3" ((long)(a3)), "4" ((long)(a4)), \
103 [call] "m" (hypercall_page[__HYPERVISOR_##name]) \
104 : "memory" ); \
105 (type)__res; \
106})
107
108#define _hypercall5(type, name, a1, a2, a3, a4, a5) \
109({ \
110 long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \
111 asm volatile ( \
112 "call %[call]" \
113 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
114 "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \
115 : "1" ((long)(a1)), "2" ((long)(a2)), \
116 "3" ((long)(a3)), "4" ((long)(a4)), \
117 "5" ((long)(a5)), \
118 [call] "m" (hypercall_page[__HYPERVISOR_##name]) \
119 : "memory" ); \
120 (type)__res; \
121})
122
123static inline int
124HYPERVISOR_set_trap_table(struct trap_info *table)
125{
126 return _hypercall1(int, set_trap_table, table);
127}
128
129static inline int
130HYPERVISOR_mmu_update(struct mmu_update *req, int count,
131 int *success_count, domid_t domid)
132{
133 return _hypercall4(int, mmu_update, req, count, success_count, domid);
134}
135
136static inline int
137HYPERVISOR_mmuext_op(struct mmuext_op *op, int count,
138 int *success_count, domid_t domid)
139{
140 return _hypercall4(int, mmuext_op, op, count, success_count, domid);
141}
142
143static inline int
144HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
145{
146 return _hypercall2(int, set_gdt, frame_list, entries);
147}
148
149static inline int
150HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
151{
152 return _hypercall2(int, stack_switch, ss, esp);
153}
154
155static inline int
156HYPERVISOR_set_callbacks(unsigned long event_selector,
157 unsigned long event_address,
158 unsigned long failsafe_selector,
159 unsigned long failsafe_address)
160{
161 return _hypercall4(int, set_callbacks,
162 event_selector, event_address,
163 failsafe_selector, failsafe_address);
164}
165
166static inline int
167HYPERVISOR_fpu_taskswitch(int set)
168{
169 return _hypercall1(int, fpu_taskswitch, set);
170}
171
172static inline int
173HYPERVISOR_sched_op(int cmd, unsigned long arg)
174{
175 return _hypercall2(int, sched_op, cmd, arg);
176}
177
178static inline long
179HYPERVISOR_set_timer_op(u64 timeout)
180{
181 unsigned long timeout_hi = (unsigned long)(timeout>>32);
182 unsigned long timeout_lo = (unsigned long)timeout;
183 return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
184}
185
186static inline int
187HYPERVISOR_set_debugreg(int reg, unsigned long value)
188{
189 return _hypercall2(int, set_debugreg, reg, value);
190}
191
192static inline unsigned long
193HYPERVISOR_get_debugreg(int reg)
194{
195 return _hypercall1(unsigned long, get_debugreg, reg);
196}
197
198static inline int
199HYPERVISOR_update_descriptor(u64 ma, u64 desc)
200{
201 return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32);
202}
203
204static inline int
205HYPERVISOR_memory_op(unsigned int cmd, void *arg)
206{
207 return _hypercall2(int, memory_op, cmd, arg);
208}
209
210static inline int
211HYPERVISOR_multicall(void *call_list, int nr_calls)
212{
213 return _hypercall2(int, multicall, call_list, nr_calls);
214}
215
216static inline int
217HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val,
218 unsigned long flags)
219{
220 unsigned long pte_hi = 0;
221#ifdef CONFIG_X86_PAE
222 pte_hi = new_val.pte_high;
223#endif
224 return _hypercall4(int, update_va_mapping, va,
225 new_val.pte_low, pte_hi, flags);
226}
227
228static inline int
229HYPERVISOR_event_channel_op(int cmd, void *arg)
230{
231 int rc = _hypercall2(int, event_channel_op, cmd, arg);
232 if (unlikely(rc == -ENOSYS)) {
233 struct evtchn_op op;
234 op.cmd = cmd;
235 memcpy(&op.u, arg, sizeof(op.u));
236 rc = _hypercall1(int, event_channel_op_compat, &op);
237 memcpy(arg, &op.u, sizeof(op.u));
238 }
239 return rc;
240}
241
242static inline int
243HYPERVISOR_xen_version(int cmd, void *arg)
244{
245 return _hypercall2(int, xen_version, cmd, arg);
246}
247
248static inline int
249HYPERVISOR_console_io(int cmd, int count, char *str)
250{
251 return _hypercall3(int, console_io, cmd, count, str);
252}
253
254static inline int
255HYPERVISOR_physdev_op(int cmd, void *arg)
256{
257 int rc = _hypercall2(int, physdev_op, cmd, arg);
258 if (unlikely(rc == -ENOSYS)) {
259 struct physdev_op op;
260 op.cmd = cmd;
261 memcpy(&op.u, arg, sizeof(op.u));
262 rc = _hypercall1(int, physdev_op_compat, &op);
263 memcpy(arg, &op.u, sizeof(op.u));
264 }
265 return rc;
266}
267
268static inline int
269HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
270{
271 return _hypercall3(int, grant_table_op, cmd, uop, count);
272}
273
274static inline int
275HYPERVISOR_update_va_mapping_otherdomain(unsigned long va, pte_t new_val,
276 unsigned long flags, domid_t domid)
277{
278 unsigned long pte_hi = 0;
279#ifdef CONFIG_X86_PAE
280 pte_hi = new_val.pte_high;
281#endif
282 return _hypercall5(int, update_va_mapping_otherdomain, va,
283 new_val.pte_low, pte_hi, flags, domid);
284}
285
286static inline int
287HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
288{
289 return _hypercall2(int, vm_assist, cmd, type);
290}
291
292static inline int
293HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args)
294{
295 return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
296}
297
298static inline int
299HYPERVISOR_suspend(unsigned long srec)
300{
301 return _hypercall3(int, sched_op, SCHEDOP_shutdown,
302 SHUTDOWN_suspend, srec);
303}
304
305static inline int
306HYPERVISOR_nmi_op(unsigned long op, unsigned long arg)
307{
308 return _hypercall2(int, nmi_op, op, arg);
309}
310
311static inline void
312MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
313 pte_t new_val, unsigned long flags)
314{
315 mcl->op = __HYPERVISOR_update_va_mapping;
316 mcl->args[0] = va;
317#ifdef CONFIG_X86_PAE
318 mcl->args[1] = new_val.pte_low;
319 mcl->args[2] = new_val.pte_high;
320#else
321 mcl->args[1] = new_val.pte_low;
322 mcl->args[2] = 0;
323#endif
324 mcl->args[3] = flags;
325}
326
327static inline void
328MULTI_grant_table_op(struct multicall_entry *mcl, unsigned int cmd,
329 void *uop, unsigned int count)
330{
331 mcl->op = __HYPERVISOR_grant_table_op;
332 mcl->args[0] = cmd;
333 mcl->args[1] = (unsigned long)uop;
334 mcl->args[2] = count;
335}
336
337static inline void
338MULTI_update_va_mapping_otherdomain(struct multicall_entry *mcl, unsigned long va,
339 pte_t new_val, unsigned long flags,
340 domid_t domid)
341{
342 mcl->op = __HYPERVISOR_update_va_mapping_otherdomain;
343 mcl->args[0] = va;
344#ifdef CONFIG_X86_PAE
345 mcl->args[1] = new_val.pte_low;
346 mcl->args[2] = new_val.pte_high;
347#else
348 mcl->args[1] = new_val.pte_low;
349 mcl->args[2] = 0;
350#endif
351 mcl->args[3] = flags;
352 mcl->args[4] = domid;
353}
354
355static inline void
356MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr,
357 struct desc_struct desc)
358{
359 mcl->op = __HYPERVISOR_update_descriptor;
360 mcl->args[0] = maddr;
361 mcl->args[1] = maddr >> 32;
362 mcl->args[2] = desc.a;
363 mcl->args[3] = desc.b;
364}
365
366static inline void
367MULTI_memory_op(struct multicall_entry *mcl, unsigned int cmd, void *arg)
368{
369 mcl->op = __HYPERVISOR_memory_op;
370 mcl->args[0] = cmd;
371 mcl->args[1] = (unsigned long)arg;
372}
373
374static inline void
375MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req,
376 int count, int *success_count, domid_t domid)
377{
378 mcl->op = __HYPERVISOR_mmu_update;
379 mcl->args[0] = (unsigned long)req;
380 mcl->args[1] = count;
381 mcl->args[2] = (unsigned long)success_count;
382 mcl->args[3] = domid;
383}
384
385static inline void
386MULTI_mmuext_op(struct multicall_entry *mcl, struct mmuext_op *op, int count,
387 int *success_count, domid_t domid)
388{
389 mcl->op = __HYPERVISOR_mmuext_op;
390 mcl->args[0] = (unsigned long)op;
391 mcl->args[1] = count;
392 mcl->args[2] = (unsigned long)success_count;
393 mcl->args[3] = domid;
394}
395#endif /* __HYPERCALL_H__ */