ia64/xen-unstable

view linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h @ 9262:c445d4a0dd76

Define a new sched_op hypercall called sched_op_new, which differs from the
legacy hypercall in that it takes a pointer to a block of extra arguments
rather than an opaque unsigned long. The old hypercall still exists, for
backwards compatibility.

The new hypercall supports new sub-command SCHEDOP_poll, which can be used to
wait on a set of event-channel ports with an optional timeout. This is exported
in XenLinux as HYPERVISOR_poll, and used in the pcifront driver to wait on a
response from the pciback driver.

Can also be used for debuggers. :-)

Signed-off-by: Keir Fraser <keir@xensource.com>
Signed-off-by: John Levon <john.levon@sun.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Mar 14 19:33:45 2006 +0100 (2006-03-14)
parents 4293d6760cef
children a07e25890329
line source
1 /******************************************************************************
2 * hypercall.h
3 *
4 * Linux-specific hypervisor handling.
5 *
6 * Copyright (c) 2002-2004, K A Fraser
7 *
8 * This file may be distributed separately from the Linux kernel, or
9 * incorporated into other software packages, subject to the following license:
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this source file (the "Software"), to deal in the Software without
13 * restriction, including without limitation the rights to use, copy, modify,
14 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
15 * and to permit persons to whom the Software is furnished to do so, subject to
16 * the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27 * IN THE SOFTWARE.
28 */
30 #ifndef __HYPERCALL_H__
31 #define __HYPERCALL_H__
33 #include <xen/interface/xen.h>
34 #include <xen/interface/sched.h>
35 #include <xen/interface/nmi.h>
36 #include <linux/errno.h>
38 #define __STR(x) #x
39 #define STR(x) __STR(x)
41 #define _hypercall0(type, name) \
42 ({ \
43 long __res; \
44 asm volatile ( \
45 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
46 : "=a" (__res) \
47 : \
48 : "memory" ); \
49 (type)__res; \
50 })
52 #define _hypercall1(type, name, a1) \
53 ({ \
54 long __res, __ign1; \
55 asm volatile ( \
56 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
57 : "=a" (__res), "=b" (__ign1) \
58 : "1" ((long)(a1)) \
59 : "memory" ); \
60 (type)__res; \
61 })
63 #define _hypercall2(type, name, a1, a2) \
64 ({ \
65 long __res, __ign1, __ign2; \
66 asm volatile ( \
67 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
68 : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \
69 : "1" ((long)(a1)), "2" ((long)(a2)) \
70 : "memory" ); \
71 (type)__res; \
72 })
74 #define _hypercall3(type, name, a1, a2, a3) \
75 ({ \
76 long __res, __ign1, __ign2, __ign3; \
77 asm volatile ( \
78 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
79 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
80 "=d" (__ign3) \
81 : "1" ((long)(a1)), "2" ((long)(a2)), \
82 "3" ((long)(a3)) \
83 : "memory" ); \
84 (type)__res; \
85 })
87 #define _hypercall4(type, name, a1, a2, a3, a4) \
88 ({ \
89 long __res, __ign1, __ign2, __ign3, __ign4; \
90 asm volatile ( \
91 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
92 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
93 "=d" (__ign3), "=S" (__ign4) \
94 : "1" ((long)(a1)), "2" ((long)(a2)), \
95 "3" ((long)(a3)), "4" ((long)(a4)) \
96 : "memory" ); \
97 (type)__res; \
98 })
100 #define _hypercall5(type, name, a1, a2, a3, a4, a5) \
101 ({ \
102 long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \
103 asm volatile ( \
104 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
105 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
106 "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \
107 : "1" ((long)(a1)), "2" ((long)(a2)), \
108 "3" ((long)(a3)), "4" ((long)(a4)), \
109 "5" ((long)(a5)) \
110 : "memory" ); \
111 (type)__res; \
112 })
114 static inline int
115 HYPERVISOR_set_trap_table(
116 trap_info_t *table)
117 {
118 return _hypercall1(int, set_trap_table, table);
119 }
121 static inline int
122 HYPERVISOR_mmu_update(
123 mmu_update_t *req, int count, int *success_count, domid_t domid)
124 {
125 return _hypercall4(int, mmu_update, req, count, success_count, domid);
126 }
128 static inline int
129 HYPERVISOR_mmuext_op(
130 struct mmuext_op *op, int count, int *success_count, domid_t domid)
131 {
132 return _hypercall4(int, mmuext_op, op, count, success_count, domid);
133 }
135 static inline int
136 HYPERVISOR_set_gdt(
137 unsigned long *frame_list, int entries)
138 {
139 return _hypercall2(int, set_gdt, frame_list, entries);
140 }
142 static inline int
143 HYPERVISOR_stack_switch(
144 unsigned long ss, unsigned long esp)
145 {
146 return _hypercall2(int, stack_switch, ss, esp);
147 }
149 static inline int
150 HYPERVISOR_set_callbacks(
151 unsigned long event_selector, unsigned long event_address,
152 unsigned long failsafe_selector, unsigned long failsafe_address)
153 {
154 return _hypercall4(int, set_callbacks,
155 event_selector, event_address,
156 failsafe_selector, failsafe_address);
157 }
159 static inline int
160 HYPERVISOR_fpu_taskswitch(
161 int set)
162 {
163 return _hypercall1(int, fpu_taskswitch, set);
164 }
166 static inline int
167 HYPERVISOR_sched_op(
168 int cmd, unsigned long arg)
169 {
170 return _hypercall2(int, sched_op, cmd, arg);
171 }
173 static inline int
174 HYPERVISOR_sched_op_new(
175 int cmd, void *arg)
176 {
177 return _hypercall2(int, sched_op_new, cmd, arg);
178 }
180 static inline int
181 HYPERVISOR_poll(
182 evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
183 {
184 struct sched_poll sched_poll = {
185 .ports = ports,
186 .nr_ports = nr_ports,
187 .timeout = jiffies_to_st(timeout)
188 };
190 int rc = HYPERVISOR_sched_op_new(SCHEDOP_poll, &sched_poll);
192 if (rc == -ENOSYS)
193 rc = HYPERVISOR_sched_op(SCHEDOP_yield, 0);
195 return rc;
196 }
198 static inline long
199 HYPERVISOR_set_timer_op(
200 u64 timeout)
201 {
202 unsigned long timeout_hi = (unsigned long)(timeout>>32);
203 unsigned long timeout_lo = (unsigned long)timeout;
204 return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
205 }
207 static inline int
208 HYPERVISOR_dom0_op(
209 dom0_op_t *dom0_op)
210 {
211 dom0_op->interface_version = DOM0_INTERFACE_VERSION;
212 return _hypercall1(int, dom0_op, dom0_op);
213 }
215 static inline int
216 HYPERVISOR_set_debugreg(
217 int reg, unsigned long value)
218 {
219 return _hypercall2(int, set_debugreg, reg, value);
220 }
222 static inline unsigned long
223 HYPERVISOR_get_debugreg(
224 int reg)
225 {
226 return _hypercall1(unsigned long, get_debugreg, reg);
227 }
229 static inline int
230 HYPERVISOR_update_descriptor(
231 u64 ma, u64 desc)
232 {
233 return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32);
234 }
236 static inline int
237 HYPERVISOR_memory_op(
238 unsigned int cmd, void *arg)
239 {
240 return _hypercall2(int, memory_op, cmd, arg);
241 }
243 static inline int
244 HYPERVISOR_multicall(
245 void *call_list, int nr_calls)
246 {
247 return _hypercall2(int, multicall, call_list, nr_calls);
248 }
250 static inline int
251 HYPERVISOR_update_va_mapping(
252 unsigned long va, pte_t new_val, unsigned long flags)
253 {
254 unsigned long pte_hi = 0;
255 #ifdef CONFIG_X86_PAE
256 pte_hi = new_val.pte_high;
257 #endif
258 return _hypercall4(int, update_va_mapping, va,
259 new_val.pte_low, pte_hi, flags);
260 }
262 static inline int
263 HYPERVISOR_event_channel_op(
264 void *op)
265 {
266 return _hypercall1(int, event_channel_op, op);
267 }
269 static inline int
270 HYPERVISOR_xen_version(
271 int cmd, void *arg)
272 {
273 return _hypercall2(int, xen_version, cmd, arg);
274 }
276 static inline int
277 HYPERVISOR_console_io(
278 int cmd, int count, char *str)
279 {
280 return _hypercall3(int, console_io, cmd, count, str);
281 }
283 static inline int
284 HYPERVISOR_physdev_op(
285 void *physdev_op)
286 {
287 return _hypercall1(int, physdev_op, physdev_op);
288 }
290 static inline int
291 HYPERVISOR_grant_table_op(
292 unsigned int cmd, void *uop, unsigned int count)
293 {
294 return _hypercall3(int, grant_table_op, cmd, uop, count);
295 }
297 static inline int
298 HYPERVISOR_update_va_mapping_otherdomain(
299 unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
300 {
301 unsigned long pte_hi = 0;
302 #ifdef CONFIG_X86_PAE
303 pte_hi = new_val.pte_high;
304 #endif
305 return _hypercall5(int, update_va_mapping_otherdomain, va,
306 new_val.pte_low, pte_hi, flags, domid);
307 }
309 static inline int
310 HYPERVISOR_vm_assist(
311 unsigned int cmd, unsigned int type)
312 {
313 return _hypercall2(int, vm_assist, cmd, type);
314 }
316 static inline int
317 HYPERVISOR_vcpu_op(
318 int cmd, int vcpuid, void *extra_args)
319 {
320 return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
321 }
323 static inline int
324 HYPERVISOR_suspend(
325 unsigned long srec)
326 {
327 return _hypercall3(int, sched_op, SCHEDOP_shutdown,
328 SHUTDOWN_suspend, srec);
329 }
331 static inline int
332 HYPERVISOR_nmi_op(
333 unsigned long op, void *arg)
334 {
335 return _hypercall2(int, nmi_op, op, arg);
336 }
338 #endif /* __HYPERCALL_H__ */
340 /*
341 * Local variables:
342 * c-file-style: "linux"
343 * indent-tabs-mode: t
344 * c-indent-level: 8
345 * c-basic-offset: 8
346 * tab-width: 8
347 * End:
348 */