hypercall.h revision 185181
1240116Smarcel/******************************************************************************
2240116Smarcel * hypercall.h
3240116Smarcel *
4240116Smarcel * Linux-specific hypervisor handling.
5240116Smarcel *
6240116Smarcel * Copyright (c) 2002-2004, K A Fraser
7240116Smarcel *
8240116Smarcel * This file may be distributed separately from the Linux kernel, or
9240116Smarcel * incorporated into other software packages, subject to the following license:
10240116Smarcel *
11240116Smarcel * Permission is hereby granted, free of charge, to any person obtaining a copy
12240116Smarcel * of this source file (the "Software"), to deal in the Software without
13240116Smarcel * restriction, including without limitation the rights to use, copy, modify,
14240116Smarcel * merge, publish, distribute, sublicense, and/or sell copies of the Software,
15240116Smarcel * and to permit persons to whom the Software is furnished to do so, subject to
16240116Smarcel * the following conditions:
17240116Smarcel *
18240116Smarcel * The above copyright notice and this permission notice shall be included in
19240116Smarcel * all copies or substantial portions of the Software.
20240116Smarcel *
21240116Smarcel * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22240116Smarcel * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23240116Smarcel * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24240116Smarcel * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25240116Smarcel * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26240116Smarcel * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27240116Smarcel * IN THE SOFTWARE.
28240116Smarcel */
29240116Smarcel
30240116Smarcel#ifndef __HYPERCALL_H__
31240116Smarcel#define __HYPERCALL_H__
32240116Smarcel
33240116Smarcel#include <sys/systm.h>
34240116Smarcel#include <xen/interface/xen.h>
35240116Smarcel#include <xen/interface/sched.h>
36240116Smarcel
37240116Smarcel#define __STR(x) #x
38240116Smarcel#define STR(x) __STR(x)
39240116Smarcel#define	ENOXENSYS	38
40240116Smarcel#define CONFIG_XEN_COMPAT	0x030002
41240116Smarcel
42240116Smarcel
43240116Smarcel#if defined(XEN)
44240116Smarcel#define HYPERCALL_STR(name)                                     \
45240116Smarcel        "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"
46240116Smarcel#else
47240116Smarcel#define HYPERCALL_STR(name)                                     \
48240116Smarcel        "mov hypercall_stubs,%%eax; "                           \
49240116Smarcel        "add $("STR(__HYPERVISOR_##name)" * 32),%%eax; "        \
50240116Smarcel        "call *%%eax"
51240116Smarcel#endif
52240116Smarcel
53240116Smarcel#define _hypercall0(type, name)                 \
54240116Smarcel({                                              \
55240116Smarcel        long __res;                             \
56240116Smarcel        __asm__ volatile (                          \
57240116Smarcel                HYPERCALL_STR(name)             \
58240116Smarcel                : "=a" (__res)                  \
59240116Smarcel                :                               \
60240116Smarcel                : "memory" );                   \
61240116Smarcel        (type)__res;                            \
62240116Smarcel})
63240116Smarcel
64240116Smarcel#define _hypercall1(type, name, a1)                             \
65240116Smarcel({                                                              \
66240116Smarcel        long __res, __ign1;                                     \
67240116Smarcel        __asm__ volatile (                                          \
68240116Smarcel                HYPERCALL_STR(name)                             \
69240116Smarcel                : "=a" (__res), "=b" (__ign1)                   \
70240116Smarcel                : "1" ((long)(a1))                              \
71240116Smarcel                : "memory" );                                   \
72240116Smarcel        (type)__res;                                            \
73240116Smarcel})
74240116Smarcel
75240116Smarcel#define _hypercall2(type, name, a1, a2)                         \
76240116Smarcel({                                                              \
77240116Smarcel        long __res, __ign1, __ign2;                             \
78240116Smarcel        __asm__ volatile (                                          \
79240116Smarcel                HYPERCALL_STR(name)                             \
80240116Smarcel                : "=a" (__res), "=b" (__ign1), "=c" (__ign2)    \
81240116Smarcel                : "1" ((long)(a1)), "2" ((long)(a2))            \
82240116Smarcel                : "memory" );                                   \
83240116Smarcel        (type)__res;                                            \
84240116Smarcel})
85240116Smarcel
86240116Smarcel#define _hypercall3(type, name, a1, a2, a3)                     \
87240116Smarcel({                                                              \
88240116Smarcel        long __res, __ign1, __ign2, __ign3;                     \
89240116Smarcel        __asm__ volatile (                                          \
90240116Smarcel                HYPERCALL_STR(name)                             \
91240116Smarcel                : "=a" (__res), "=b" (__ign1), "=c" (__ign2),   \
92240116Smarcel                "=d" (__ign3)                                   \
93240116Smarcel                : "1" ((long)(a1)), "2" ((long)(a2)),           \
94240116Smarcel                "3" ((long)(a3))                                \
95240116Smarcel                : "memory" );                                   \
96240116Smarcel        (type)__res;                                            \
97240116Smarcel})
98240116Smarcel
99240116Smarcel#define _hypercall4(type, name, a1, a2, a3, a4)                 \
100240116Smarcel({                                                              \
101240116Smarcel        long __res, __ign1, __ign2, __ign3, __ign4;             \
102240116Smarcel        __asm__ volatile (                                          \
103240116Smarcel                HYPERCALL_STR(name)                             \
104240116Smarcel                : "=a" (__res), "=b" (__ign1), "=c" (__ign2),   \
105240116Smarcel                "=d" (__ign3), "=S" (__ign4)                    \
106240116Smarcel                : "1" ((long)(a1)), "2" ((long)(a2)),           \
107240116Smarcel                "3" ((long)(a3)), "4" ((long)(a4))              \
108240116Smarcel                : "memory" );                                   \
109240116Smarcel        (type)__res;                                            \
110240116Smarcel})
111240116Smarcel
112240116Smarcel#define _hypercall5(type, name, a1, a2, a3, a4, a5)             \
113240116Smarcel({                                                              \
114240116Smarcel        long __res, __ign1, __ign2, __ign3, __ign4, __ign5;     \
115240116Smarcel        __asm__ volatile (                                          \
116240116Smarcel                HYPERCALL_STR(name)                             \
117240116Smarcel                : "=a" (__res), "=b" (__ign1), "=c" (__ign2),   \
118240116Smarcel                "=d" (__ign3), "=S" (__ign4), "=D" (__ign5)     \
119240116Smarcel                : "1" ((long)(a1)), "2" ((long)(a2)),           \
120240116Smarcel                "3" ((long)(a3)), "4" ((long)(a4)),             \
121240116Smarcel                "5" ((long)(a5))                                \
122240116Smarcel                : "memory" );                                   \
123240116Smarcel        (type)__res;                                            \
124240116Smarcel})
125240116Smarcel
126240116Smarcelstatic inline int
127240116SmarcelHYPERVISOR_set_trap_table(
128240116Smarcel	trap_info_t *table)
129240116Smarcel{
130240116Smarcel	return _hypercall1(int, set_trap_table, table);
131240116Smarcel}
132240116Smarcel
133240116Smarcelstatic inline int
134240116SmarcelHYPERVISOR_mmu_update(
135240116Smarcel	mmu_update_t *req, int count, int *success_count, domid_t domid)
136240116Smarcel{
137240116Smarcel	return _hypercall4(int, mmu_update, req, count, success_count, domid);
138240116Smarcel}
139240116Smarcel
140240116Smarcelstatic inline int
141240116SmarcelHYPERVISOR_mmuext_op(
142240116Smarcel	mmuext_op_t *op, int count, int *success_count, domid_t domid)
143240116Smarcel{
144240116Smarcel	return _hypercall4(int, mmuext_op, op, count, success_count, domid);
145240116Smarcel}
146240116Smarcel
147240116Smarcelstatic inline int
148240116SmarcelHYPERVISOR_set_gdt(
149240116Smarcel	unsigned long *frame_list, int entries)
150240116Smarcel{
151240116Smarcel	return _hypercall2(int, set_gdt, frame_list, entries);
152240116Smarcel}
153240116Smarcel
154240116Smarcelstatic inline int
155240116SmarcelHYPERVISOR_stack_switch(
156240116Smarcel	unsigned long ss, unsigned long esp)
157240116Smarcel{
158240116Smarcel	return _hypercall2(int, stack_switch, ss, esp);
159240116Smarcel}
160240116Smarcel
161240116Smarcelstatic inline int
162240116SmarcelHYPERVISOR_set_callbacks(
163240116Smarcel	unsigned long event_selector, unsigned long event_address,
164240116Smarcel	unsigned long failsafe_selector, unsigned long failsafe_address)
165240116Smarcel{
166240116Smarcel	return _hypercall4(int, set_callbacks,
167240116Smarcel			   event_selector, event_address,
168240116Smarcel			   failsafe_selector, failsafe_address);
169240116Smarcel}
170240116Smarcel
171240116Smarcelstatic inline int
172240116SmarcelHYPERVISOR_fpu_taskswitch(
173240116Smarcel	int set)
174240116Smarcel{
175240116Smarcel	return _hypercall1(int, fpu_taskswitch, set);
176240116Smarcel}
177240116Smarcel
178240116Smarcelstatic inline int
179240116SmarcelHYPERVISOR_sched_op_compat(
180240116Smarcel	int cmd, unsigned long arg)
181240116Smarcel{
182240116Smarcel	return _hypercall2(int, sched_op_compat, cmd, arg);
183240116Smarcel}
184240116Smarcel
185240116Smarcelstatic inline int
186240116SmarcelHYPERVISOR_sched_op(
187240116Smarcel	int cmd, void *arg)
188240116Smarcel{
189240116Smarcel	return _hypercall2(int, sched_op, cmd, arg);
190240116Smarcel}
191240116Smarcel
192240116Smarcelstatic inline long
193240116SmarcelHYPERVISOR_set_timer_op(
194240116Smarcel	uint64_t timeout)
195240116Smarcel{
196240116Smarcel	unsigned long timeout_hi = (unsigned long)(timeout>>32);
197240116Smarcel	unsigned long timeout_lo = (unsigned long)timeout;
198240116Smarcel	return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
199240116Smarcel}
200240116Smarcel#if 0
201240116Smarcelstatic inline int
202240116SmarcelHYPERVISOR_platform_op(
203240116Smarcel        struct xen_platform_op *platform_op)
204240116Smarcel{
205240116Smarcel        platform_op->interface_version = XENPF_INTERFACE_VERSION;
206240116Smarcel        return _hypercall1(int, platform_op, platform_op);
207240116Smarcel}
208240116Smarcel#endif
209240116Smarcelstatic inline int
210240116SmarcelHYPERVISOR_set_debugreg(
211240116Smarcel	int reg, unsigned long value)
212240116Smarcel{
213240116Smarcel	return _hypercall2(int, set_debugreg, reg, value);
214240116Smarcel}
215240116Smarcel
216240116Smarcelstatic inline unsigned long
217240116SmarcelHYPERVISOR_get_debugreg(
218240116Smarcel	int reg)
219240116Smarcel{
220240116Smarcel	return _hypercall1(unsigned long, get_debugreg, reg);
221240116Smarcel}
222240116Smarcel
223240116Smarcelstatic inline int
224240116SmarcelHYPERVISOR_update_descriptor(
225240116Smarcel	uint64_t ma, uint64_t desc)
226240116Smarcel{
227240116Smarcel	return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32);
228240116Smarcel}
229240116Smarcel
230240116Smarcelstatic inline int
231240116SmarcelHYPERVISOR_memory_op(
232240116Smarcel	unsigned int cmd, void *arg)
233240116Smarcel{
234240116Smarcel	return _hypercall2(int, memory_op, cmd, arg);
235240116Smarcel}
236240116Smarcel
237240116Smarcelstatic inline int
238240116SmarcelHYPERVISOR_multicall(
239240116Smarcel	void *call_list, int nr_calls)
240240116Smarcel{
241240116Smarcel	return _hypercall2(int, multicall, call_list, nr_calls);
242240116Smarcel}
243240116Smarcel
244240116Smarcelstatic inline int
245240116SmarcelHYPERVISOR_update_va_mapping(
246240116Smarcel	unsigned long va, uint64_t new_val, unsigned long flags)
247240116Smarcel{
248240116Smarcel	uint32_t hi, lo;
249240116Smarcel
250240116Smarcel	lo = (uint32_t)(new_val & 0xffffffff);
251240116Smarcel	hi = (uint32_t)(new_val >> 32);
252240116Smarcel
253240116Smarcel	return _hypercall4(int, update_va_mapping, va,
254240116Smarcel			   lo, hi, flags);
255240116Smarcel}
256240116Smarcel
257240116Smarcelstatic inline int
258240116SmarcelHYPERVISOR_event_channel_op(
259240116Smarcel	int cmd, void *arg)
260240116Smarcel{
261240116Smarcel	int rc = _hypercall2(int, event_channel_op, cmd, arg);
262240116Smarcel
263240116Smarcel#if CONFIG_XEN_COMPAT <= 0x030002
264240116Smarcel	if (__predict_false(rc == -ENOXENSYS)) {
265240116Smarcel		struct evtchn_op op;
266240116Smarcel		op.cmd = cmd;
267240116Smarcel		memcpy(&op.u, arg, sizeof(op.u));
268240116Smarcel		rc = _hypercall1(int, event_channel_op_compat, &op);
269240116Smarcel		memcpy(arg, &op.u, sizeof(op.u));
270240116Smarcel	}
271240116Smarcel#endif
272240116Smarcel	return (rc);
273240116Smarcel}
274240116Smarcel
275240116Smarcelstatic inline int
276240116SmarcelHYPERVISOR_xen_version(
277240116Smarcel	int cmd, void *arg)
278240116Smarcel{
279240116Smarcel	return _hypercall2(int, xen_version, cmd, arg);
280240116Smarcel}
281240116Smarcel
282240116Smarcelstatic inline int
283240116SmarcelHYPERVISOR_console_io(
284240116Smarcel	int cmd, int count, char *str)
285240116Smarcel{
286240116Smarcel	return _hypercall3(int, console_io, cmd, count, str);
287240116Smarcel}
288240116Smarcel
289240116Smarcelstatic inline int
290240116SmarcelHYPERVISOR_physdev_op(
291240116Smarcel	int cmd, void *arg)
292240116Smarcel{
293240116Smarcel	int rc = _hypercall2(int, physdev_op, cmd, arg);
294240116Smarcel#if CONFIG_XEN_COMPAT <= 0x030002
295240116Smarcel	if (__predict_false(rc == -ENOXENSYS)) {
296240116Smarcel		struct physdev_op op;
297240116Smarcel		op.cmd = cmd;
298240116Smarcel		memcpy(&op.u, arg, sizeof(op.u));
299240116Smarcel		rc = _hypercall1(int, physdev_op_compat, &op);
300240116Smarcel		memcpy(arg, &op.u, sizeof(op.u));
301240116Smarcel	}
302240116Smarcel#endif
303240116Smarcel	return (rc);
304240116Smarcel}
305240116Smarcel
306240116Smarcelstatic inline int
307240116SmarcelHYPERVISOR_grant_table_op(
308240116Smarcel	unsigned int cmd, void *uop, unsigned int count)
309240116Smarcel{
310240116Smarcel	return _hypercall3(int, grant_table_op, cmd, uop, count);
311240116Smarcel}
312240116Smarcel
313240116Smarcelstatic inline int
314240116SmarcelHYPERVISOR_update_va_mapping_otherdomain(
315240116Smarcel	unsigned long va, uint64_t new_val, unsigned long flags, domid_t domid)
316240116Smarcel{
317240116Smarcel	uint32_t hi, lo;
318240116Smarcel
319240116Smarcel	lo = (uint32_t)(new_val & 0xffffffff);
320240116Smarcel	hi = (uint32_t)(new_val >> 32);
321240116Smarcel
322240116Smarcel	return _hypercall5(int, update_va_mapping_otherdomain, va,
323240116Smarcel			   lo, hi, flags, domid);
324240116Smarcel}
325240116Smarcel
326240116Smarcelstatic inline int
327240116SmarcelHYPERVISOR_vm_assist(
328240116Smarcel	unsigned int cmd, unsigned int type)
329240116Smarcel{
330240116Smarcel	return _hypercall2(int, vm_assist, cmd, type);
331240116Smarcel}
332240116Smarcel
333240116Smarcelstatic inline int
334240116SmarcelHYPERVISOR_vcpu_op(
335240116Smarcel	int cmd, int vcpuid, void *extra_args)
336240116Smarcel{
337240116Smarcel	return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
338240116Smarcel}
339240116Smarcel
340240116Smarcelstatic inline int
341240116SmarcelHYPERVISOR_suspend(
342240116Smarcel	unsigned long srec)
343240116Smarcel{
344240116Smarcel	struct sched_shutdown sched_shutdown = {
345240116Smarcel		.reason = SHUTDOWN_suspend
346240116Smarcel	};
347240116Smarcel	int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown,
348240116Smarcel			   &sched_shutdown, srec);
349240116Smarcel#if CONFIG_XEN_COMPAT <= 0x030002
350240116Smarcel	if (rc == -ENOXENSYS)
351240116Smarcel		rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown,
352240116Smarcel				 SHUTDOWN_suspend, srec);
353240116Smarcel#endif
354240116Smarcel	return (rc);
355240116Smarcel}
356240116Smarcel
357240116Smarcel#if CONFIG_XEN_COMPAT <= 0x030002
358240116Smarcelstatic inline int
359240116SmarcelHYPERVISOR_nmi_op(
360240116Smarcel        unsigned long op, void *arg)
361240116Smarcel{
362240116Smarcel        return _hypercall2(int, nmi_op, op, arg);
363240116Smarcel}
364240116Smarcel#endif
365240116Smarcel
366240116Smarcelstatic inline int
367240116SmarcelHYPERVISOR_callback_op(
368240116Smarcel        int cmd, void *arg)
369240116Smarcel{
370240116Smarcel        return _hypercall2(int, callback_op, cmd, arg);
371240116Smarcel}
372240116Smarcel
373240116Smarcel#ifndef CONFIG_XEN
374240116Smarcelstatic inline unsigned long
375240116SmarcelHYPERVISOR_hvm_op(
376240116Smarcel    int op, void *arg)
377240116Smarcel{
378240116Smarcel    return _hypercall2(unsigned long, hvm_op, op, arg);
379240116Smarcel}
380240116Smarcel#endif
381240116Smarcel
382240116Smarcelstatic inline int
383240116SmarcelHYPERVISOR_xenoprof_op(
384240116Smarcel        int op, void *arg)
385240116Smarcel{
386240116Smarcel        return _hypercall2(int, xenoprof_op, op, arg);
387240116Smarcel}
388240116Smarcel
389240116Smarcelstatic inline int
390240116SmarcelHYPERVISOR_kexec_op(
391240116Smarcel        unsigned long op, void *args)
392{
393        return _hypercall2(int, kexec_op, op, args);
394}
395#endif /* __HYPERCALL_H__ */
396
397/*
398 * Local variables:
399 *  c-file-style: "linux"
400 *  indent-tabs-mode: t
401 *  c-indent-level: 8
402 *  c-basic-offset: 8
403 *  tab-width: 8
404 * End:
405 */
406