ia64/xen-unstable

view linux-2.6-xen-sparse/include/asm-x86_64/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 * 64-bit updates:
9 * Benjamin Liu <benjamin.liu@intel.com>
10 * Jun Nakajima <jun.nakajima@intel.com>
11 *
12 * This file may be distributed separately from the Linux kernel, or
13 * incorporated into other software packages, subject to the following license:
14 *
15 * Permission is hereby granted, free of charge, to any person obtaining a copy
16 * of this source file (the "Software"), to deal in the Software without
17 * restriction, including without limitation the rights to use, copy, modify,
18 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
19 * and to permit persons to whom the Software is furnished to do so, subject to
20 * the following conditions:
21 *
22 * The above copyright notice and this permission notice shall be included in
23 * all copies or substantial portions of the Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
31 * IN THE SOFTWARE.
32 */
34 #ifndef __HYPERCALL_H__
35 #define __HYPERCALL_H__
37 #include <xen/interface/xen.h>
38 #include <xen/interface/sched.h>
39 #include <xen/interface/nmi.h>
40 #include <linux/errno.h>
42 #define __STR(x) #x
43 #define STR(x) __STR(x)
45 #define _hypercall0(type, name) \
46 ({ \
47 long __res; \
48 asm volatile ( \
49 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
50 : "=a" (__res) \
51 : \
52 : "memory" ); \
53 (type)__res; \
54 })
56 #define _hypercall1(type, name, a1) \
57 ({ \
58 long __res, __ign1; \
59 asm volatile ( \
60 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
61 : "=a" (__res), "=D" (__ign1) \
62 : "1" ((long)(a1)) \
63 : "memory" ); \
64 (type)__res; \
65 })
67 #define _hypercall2(type, name, a1, a2) \
68 ({ \
69 long __res, __ign1, __ign2; \
70 asm volatile ( \
71 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
72 : "=a" (__res), "=D" (__ign1), "=S" (__ign2) \
73 : "1" ((long)(a1)), "2" ((long)(a2)) \
74 : "memory" ); \
75 (type)__res; \
76 })
78 #define _hypercall3(type, name, a1, a2, a3) \
79 ({ \
80 long __res, __ign1, __ign2, __ign3; \
81 asm volatile ( \
82 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
83 : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \
84 "=d" (__ign3) \
85 : "1" ((long)(a1)), "2" ((long)(a2)), \
86 "3" ((long)(a3)) \
87 : "memory" ); \
88 (type)__res; \
89 })
91 #define _hypercall4(type, name, a1, a2, a3, a4) \
92 ({ \
93 long __res, __ign1, __ign2, __ign3; \
94 asm volatile ( \
95 "movq %7,%%r10; " \
96 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
97 : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \
98 "=d" (__ign3) \
99 : "1" ((long)(a1)), "2" ((long)(a2)), \
100 "3" ((long)(a3)), "g" ((long)(a4)) \
101 : "memory", "r10" ); \
102 (type)__res; \
103 })
105 #define _hypercall5(type, name, a1, a2, a3, a4, a5) \
106 ({ \
107 long __res, __ign1, __ign2, __ign3; \
108 asm volatile ( \
109 "movq %7,%%r10; movq %8,%%r8; " \
110 "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
111 : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \
112 "=d" (__ign3) \
113 : "1" ((long)(a1)), "2" ((long)(a2)), \
114 "3" ((long)(a3)), "g" ((long)(a4)), \
115 "g" ((long)(a5)) \
116 : "memory", "r10", "r8" ); \
117 (type)__res; \
118 })
120 static inline int
121 HYPERVISOR_set_trap_table(
122 trap_info_t *table)
123 {
124 return _hypercall1(int, set_trap_table, table);
125 }
127 static inline int
128 HYPERVISOR_mmu_update(
129 mmu_update_t *req, int count, int *success_count, domid_t domid)
130 {
131 return _hypercall4(int, mmu_update, req, count, success_count, domid);
132 }
134 static inline int
135 HYPERVISOR_mmuext_op(
136 struct mmuext_op *op, int count, int *success_count, domid_t domid)
137 {
138 return _hypercall4(int, mmuext_op, op, count, success_count, domid);
139 }
141 static inline int
142 HYPERVISOR_set_gdt(
143 unsigned long *frame_list, int entries)
144 {
145 return _hypercall2(int, set_gdt, frame_list, entries);
146 }
148 static inline int
149 HYPERVISOR_stack_switch(
150 unsigned long ss, unsigned long esp)
151 {
152 return _hypercall2(int, stack_switch, ss, esp);
153 }
155 static inline int
156 HYPERVISOR_set_callbacks(
157 unsigned long event_address, unsigned long failsafe_address,
158 unsigned long syscall_address)
159 {
160 return _hypercall3(int, set_callbacks,
161 event_address, failsafe_address, syscall_address);
162 }
164 static inline int
165 HYPERVISOR_fpu_taskswitch(
166 int set)
167 {
168 return _hypercall1(int, fpu_taskswitch, set);
169 }
171 static inline int
172 HYPERVISOR_sched_op(
173 int cmd, unsigned long arg)
174 {
175 return _hypercall2(int, sched_op, cmd, arg);
176 }
178 static inline int
179 HYPERVISOR_sched_op_new(
180 int cmd, void *arg)
181 {
182 return _hypercall2(int, sched_op_new, cmd, arg);
183 }
185 static inline int
186 HYPERVISOR_poll(
187 evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
188 {
189 struct sched_poll sched_poll = {
190 .ports = ports,
191 .nr_ports = nr_ports,
192 .timeout = jiffies_to_st(timeout)
193 };
195 int rc = HYPERVISOR_sched_op_new(SCHEDOP_poll, &sched_poll);
197 if (rc == -ENOSYS)
198 rc = HYPERVISOR_sched_op(SCHEDOP_yield, 0);
200 return rc;
201 }
203 static inline long
204 HYPERVISOR_set_timer_op(
205 u64 timeout)
206 {
207 return _hypercall1(long, set_timer_op, timeout);
208 }
210 static inline int
211 HYPERVISOR_dom0_op(
212 dom0_op_t *dom0_op)
213 {
214 dom0_op->interface_version = DOM0_INTERFACE_VERSION;
215 return _hypercall1(int, dom0_op, dom0_op);
216 }
218 static inline int
219 HYPERVISOR_set_debugreg(
220 int reg, unsigned long value)
221 {
222 return _hypercall2(int, set_debugreg, reg, value);
223 }
225 static inline unsigned long
226 HYPERVISOR_get_debugreg(
227 int reg)
228 {
229 return _hypercall1(unsigned long, get_debugreg, reg);
230 }
232 static inline int
233 HYPERVISOR_update_descriptor(
234 unsigned long ma, unsigned long word)
235 {
236 return _hypercall2(int, update_descriptor, ma, word);
237 }
239 static inline int
240 HYPERVISOR_memory_op(
241 unsigned int cmd, void *arg)
242 {
243 return _hypercall2(int, memory_op, cmd, arg);
244 }
246 static inline int
247 HYPERVISOR_multicall(
248 void *call_list, int nr_calls)
249 {
250 return _hypercall2(int, multicall, call_list, nr_calls);
251 }
253 static inline int
254 HYPERVISOR_update_va_mapping(
255 unsigned long va, pte_t new_val, unsigned long flags)
256 {
257 return _hypercall3(int, update_va_mapping, va, new_val.pte, flags);
258 }
260 static inline int
261 HYPERVISOR_event_channel_op(
262 void *op)
263 {
264 return _hypercall1(int, event_channel_op, op);
265 }
267 static inline int
268 HYPERVISOR_xen_version(
269 int cmd, void *arg)
270 {
271 return _hypercall2(int, xen_version, cmd, arg);
272 }
274 static inline int
275 HYPERVISOR_console_io(
276 int cmd, int count, char *str)
277 {
278 return _hypercall3(int, console_io, cmd, count, str);
279 }
281 static inline int
282 HYPERVISOR_physdev_op(
283 void *physdev_op)
284 {
285 return _hypercall1(int, physdev_op, physdev_op);
286 }
288 static inline int
289 HYPERVISOR_grant_table_op(
290 unsigned int cmd, void *uop, unsigned int count)
291 {
292 return _hypercall3(int, grant_table_op, cmd, uop, count);
293 }
295 static inline int
296 HYPERVISOR_update_va_mapping_otherdomain(
297 unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
298 {
299 return _hypercall4(int, update_va_mapping_otherdomain, va,
300 new_val.pte, flags, domid);
301 }
303 static inline int
304 HYPERVISOR_vm_assist(
305 unsigned int cmd, unsigned int type)
306 {
307 return _hypercall2(int, vm_assist, cmd, type);
308 }
310 static inline int
311 HYPERVISOR_vcpu_op(
312 int cmd, int vcpuid, void *extra_args)
313 {
314 return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
315 }
317 static inline int
318 HYPERVISOR_set_segment_base(
319 int reg, unsigned long value)
320 {
321 return _hypercall2(int, set_segment_base, reg, value);
322 }
324 static inline int
325 HYPERVISOR_suspend(
326 unsigned long srec)
327 {
328 return _hypercall3(int, sched_op, SCHEDOP_shutdown,
329 SHUTDOWN_suspend, srec);
330 }
332 static inline int
333 HYPERVISOR_nmi_op(
334 unsigned long op, void *arg)
335 {
336 return _hypercall2(int, nmi_op, op, arg);
337 }
339 #endif /* __HYPERCALL_H__ */
341 /*
342 * Local variables:
343 * c-file-style: "linux"
344 * indent-tabs-mode: t
345 * c-indent-level: 8
346 * c-basic-offset: 8
347 * tab-width: 8
348 * End:
349 */