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 _ASM_IA64_XEN_HYPERCALL_H
34 #define _ASM_IA64_XEN_HYPERCALL_H
35 
36 #include <xen/interface/xen.h>
37 #include <xen/interface/physdev.h>
38 #include <xen/interface/sched.h>
39 #include <asm/xen/xcom_hcall.h>
40 struct xencomm_handle;
41 extern unsigned long __hypercall(unsigned long a1, unsigned long a2,
42 				 unsigned long a3, unsigned long a4,
43 				 unsigned long a5, unsigned long cmd);
44 
45 /*
46  * Assembler stubs for hyper-calls.
47  */
48 
49 #define _hypercall0(type, name)					\
50 ({								\
51 	long __res;						\
52 	__res = __hypercall(0, 0, 0, 0, 0, __HYPERVISOR_##name);\
53 	(type)__res;						\
54 })
55 
56 #define _hypercall1(type, name, a1)				\
57 ({								\
58 	long __res;						\
59 	__res = __hypercall((unsigned long)a1,			\
60 			     0, 0, 0, 0, __HYPERVISOR_##name);	\
61 	(type)__res;						\
62 })
63 
64 #define _hypercall2(type, name, a1, a2)				\
65 ({								\
66 	long __res;						\
67 	__res = __hypercall((unsigned long)a1,			\
68 			    (unsigned long)a2,			\
69 			    0, 0, 0, __HYPERVISOR_##name);	\
70 	(type)__res;						\
71 })
72 
73 #define _hypercall3(type, name, a1, a2, a3)			\
74 ({								\
75 	long __res;						\
76 	__res = __hypercall((unsigned long)a1,			\
77 			    (unsigned long)a2,			\
78 			    (unsigned long)a3,			\
79 			    0, 0, __HYPERVISOR_##name);		\
80 	(type)__res;						\
81 })
82 
83 #define _hypercall4(type, name, a1, a2, a3, a4)			\
84 ({								\
85 	long __res;						\
86 	__res = __hypercall((unsigned long)a1,			\
87 			    (unsigned long)a2,			\
88 			    (unsigned long)a3,			\
89 			    (unsigned long)a4,			\
90 			    0, __HYPERVISOR_##name);		\
91 	(type)__res;						\
92 })
93 
94 #define _hypercall5(type, name, a1, a2, a3, a4, a5)		\
95 ({								\
96 	long __res;						\
97 	__res = __hypercall((unsigned long)a1,			\
98 			    (unsigned long)a2,			\
99 			    (unsigned long)a3,			\
100 			    (unsigned long)a4,			\
101 			    (unsigned long)a5,			\
102 			    __HYPERVISOR_##name);		\
103 	(type)__res;						\
104 })
105 
106 
107 static inline int
xencomm_arch_hypercall_sched_op(int cmd,struct xencomm_handle * arg)108 xencomm_arch_hypercall_sched_op(int cmd, struct xencomm_handle *arg)
109 {
110 	return _hypercall2(int, sched_op, cmd, arg);
111 }
112 
113 static inline long
HYPERVISOR_set_timer_op(u64 timeout)114 HYPERVISOR_set_timer_op(u64 timeout)
115 {
116 	unsigned long timeout_hi = (unsigned long)(timeout >> 32);
117 	unsigned long timeout_lo = (unsigned long)timeout;
118 	return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
119 }
120 
121 static inline int
xencomm_arch_hypercall_multicall(struct xencomm_handle * call_list,int nr_calls)122 xencomm_arch_hypercall_multicall(struct xencomm_handle *call_list,
123 				 int nr_calls)
124 {
125 	return _hypercall2(int, multicall, call_list, nr_calls);
126 }
127 
128 static inline int
xencomm_arch_hypercall_memory_op(unsigned int cmd,struct xencomm_handle * arg)129 xencomm_arch_hypercall_memory_op(unsigned int cmd, struct xencomm_handle *arg)
130 {
131 	return _hypercall2(int, memory_op, cmd, arg);
132 }
133 
134 static inline int
xencomm_arch_hypercall_event_channel_op(int cmd,struct xencomm_handle * arg)135 xencomm_arch_hypercall_event_channel_op(int cmd, struct xencomm_handle *arg)
136 {
137 	return _hypercall2(int, event_channel_op, cmd, arg);
138 }
139 
140 static inline int
xencomm_arch_hypercall_xen_version(int cmd,struct xencomm_handle * arg)141 xencomm_arch_hypercall_xen_version(int cmd, struct xencomm_handle *arg)
142 {
143 	return _hypercall2(int, xen_version, cmd, arg);
144 }
145 
146 static inline int
xencomm_arch_hypercall_console_io(int cmd,int count,struct xencomm_handle * str)147 xencomm_arch_hypercall_console_io(int cmd, int count,
148 				  struct xencomm_handle *str)
149 {
150 	return _hypercall3(int, console_io, cmd, count, str);
151 }
152 
153 static inline int
xencomm_arch_hypercall_physdev_op(int cmd,struct xencomm_handle * arg)154 xencomm_arch_hypercall_physdev_op(int cmd, struct xencomm_handle *arg)
155 {
156 	return _hypercall2(int, physdev_op, cmd, arg);
157 }
158 
159 static inline int
xencomm_arch_hypercall_grant_table_op(unsigned int cmd,struct xencomm_handle * uop,unsigned int count)160 xencomm_arch_hypercall_grant_table_op(unsigned int cmd,
161 				      struct xencomm_handle *uop,
162 				      unsigned int count)
163 {
164 	return _hypercall3(int, grant_table_op, cmd, uop, count);
165 }
166 
167 int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
168 
169 extern int xencomm_arch_hypercall_suspend(struct xencomm_handle *arg);
170 
171 static inline int
xencomm_arch_hypercall_callback_op(int cmd,struct xencomm_handle * arg)172 xencomm_arch_hypercall_callback_op(int cmd, struct xencomm_handle *arg)
173 {
174 	return _hypercall2(int, callback_op, cmd, arg);
175 }
176 
177 static inline long
xencomm_arch_hypercall_vcpu_op(int cmd,int cpu,void * arg)178 xencomm_arch_hypercall_vcpu_op(int cmd, int cpu, void *arg)
179 {
180 	return _hypercall3(long, vcpu_op, cmd, cpu, arg);
181 }
182 
183 static inline int
HYPERVISOR_physdev_op(int cmd,void * arg)184 HYPERVISOR_physdev_op(int cmd, void *arg)
185 {
186 	switch (cmd) {
187 	case PHYSDEVOP_eoi:
188 		return _hypercall1(int, ia64_fast_eoi,
189 				   ((struct physdev_eoi *)arg)->irq);
190 	default:
191 		return xencomm_hypercall_physdev_op(cmd, arg);
192 	}
193 }
194 
195 static inline long
xencomm_arch_hypercall_opt_feature(struct xencomm_handle * arg)196 xencomm_arch_hypercall_opt_feature(struct xencomm_handle *arg)
197 {
198 	return _hypercall1(long, opt_feature, arg);
199 }
200 
201 /* for balloon driver */
202 #define HYPERVISOR_update_va_mapping(va, new_val, flags) (0)
203 
204 /* Use xencomm to do hypercalls.  */
205 #define HYPERVISOR_sched_op xencomm_hypercall_sched_op
206 #define HYPERVISOR_event_channel_op xencomm_hypercall_event_channel_op
207 #define HYPERVISOR_callback_op xencomm_hypercall_callback_op
208 #define HYPERVISOR_multicall xencomm_hypercall_multicall
209 #define HYPERVISOR_xen_version xencomm_hypercall_xen_version
210 #define HYPERVISOR_console_io xencomm_hypercall_console_io
211 #define HYPERVISOR_memory_op xencomm_hypercall_memory_op
212 #define HYPERVISOR_suspend xencomm_hypercall_suspend
213 #define HYPERVISOR_vcpu_op xencomm_hypercall_vcpu_op
214 #define HYPERVISOR_opt_feature xencomm_hypercall_opt_feature
215 
216 /* to compile gnttab_copy_grant_page() in drivers/xen/core/gnttab.c */
217 #define HYPERVISOR_mmu_update(req, count, success_count, domid) ({ BUG(); 0; })
218 
219 static inline int
HYPERVISOR_shutdown(unsigned int reason)220 HYPERVISOR_shutdown(
221 	unsigned int reason)
222 {
223 	struct sched_shutdown sched_shutdown = {
224 		.reason = reason
225 	};
226 
227 	int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
228 
229 	return rc;
230 }
231 
232 /* for netfront.c, netback.c */
233 #define MULTI_UVMFLAGS_INDEX 0 /* XXX any value */
234 
235 static inline void
MULTI_update_va_mapping(struct multicall_entry * mcl,unsigned long va,pte_t new_val,unsigned long flags)236 MULTI_update_va_mapping(
237 	struct multicall_entry *mcl, unsigned long va,
238 	pte_t new_val, unsigned long flags)
239 {
240 	mcl->op = __HYPERVISOR_update_va_mapping;
241 	mcl->result = 0;
242 }
243 
244 static inline void
MULTI_grant_table_op(struct multicall_entry * mcl,unsigned int cmd,void * uop,unsigned int count)245 MULTI_grant_table_op(struct multicall_entry *mcl, unsigned int cmd,
246 	void *uop, unsigned int count)
247 {
248 	mcl->op = __HYPERVISOR_grant_table_op;
249 	mcl->args[0] = cmd;
250 	mcl->args[1] = (unsigned long)uop;
251 	mcl->args[2] = count;
252 }
253 
254 static inline void
MULTI_mmu_update(struct multicall_entry * mcl,struct mmu_update * req,int count,int * success_count,domid_t domid)255 MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req,
256 		 int count, int *success_count, domid_t domid)
257 {
258 	mcl->op = __HYPERVISOR_mmu_update;
259 	mcl->args[0] = (unsigned long)req;
260 	mcl->args[1] = count;
261 	mcl->args[2] = (unsigned long)success_count;
262 	mcl->args[3] = domid;
263 }
264 
265 #endif /* _ASM_IA64_XEN_HYPERCALL_H */
266