ia64/xen-unstable

view linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c @ 11721:1ec09a35d13d

[IA64] add GNTTABOP_copy to xencommize_grant_table_op

This is used w/ xennet.rx_copy

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author awilliam@xenbuild.aw
date Tue Oct 03 14:46:10 2006 -0600 (2006-10-03)
parents 5c97ef4c7147
children 9e8fdcc46fa3
line source
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * Tristan Gingold <tristan.gingold@bull.net>
17 */
18 #include <linux/types.h>
19 #include <linux/errno.h>
20 #include <linux/kernel.h>
21 #include <linux/gfp.h>
22 #include <linux/module.h>
23 #include <xen/interface/xen.h>
24 #include <xen/interface/dom0_ops.h>
25 #include <xen/interface/memory.h>
26 #include <xen/interface/xencomm.h>
27 #include <xen/interface/version.h>
28 #include <xen/interface/sched.h>
29 #include <xen/interface/event_channel.h>
30 #include <xen/interface/physdev.h>
31 #include <xen/interface/grant_table.h>
32 #include <xen/interface/callback.h>
33 #include <xen/interface/acm_ops.h>
34 #include <xen/interface/hvm/params.h>
35 #include <xen/public/privcmd.h>
36 #include <asm/hypercall.h>
37 #include <asm/page.h>
38 #include <asm/uaccess.h>
39 #include <asm/xen/xencomm.h>
41 /* Xencomm notes:
42 * This file defines hypercalls to be used by xencomm. The hypercalls simply
43 * create inlines descriptors for pointers and then call the raw arch hypercall
44 * xencomm_arch_hypercall_XXX
45 *
46 * If the arch wants to directly use these hypercalls, simply define macros
47 * in asm/hypercall.h, eg:
48 * #define HYPERVISOR_sched_op xencomm_hypercall_sched_op
49 *
50 * The arch may also define HYPERVISOR_xxx as a function and do more operations
51 * before/after doing the hypercall.
52 *
53 * Note: because only inline descriptors are created these functions must only
54 * be called with in kernel memory parameters.
55 */
57 int
58 xencomm_hypercall_console_io(int cmd, int count, char *str)
59 {
60 return xencomm_arch_hypercall_console_io
61 (cmd, count, xencomm_create_inline(str));
62 }
64 int
65 xencomm_hypercall_event_channel_op(int cmd, void *op)
66 {
67 return xencomm_arch_hypercall_event_channel_op
68 (cmd, xencomm_create_inline(op));
69 }
71 int
72 xencomm_hypercall_xen_version(int cmd, void *arg)
73 {
74 switch (cmd) {
75 case XENVER_version:
76 case XENVER_extraversion:
77 case XENVER_compile_info:
78 case XENVER_capabilities:
79 case XENVER_changeset:
80 case XENVER_platform_parameters:
81 case XENVER_pagesize:
82 case XENVER_get_features:
83 break;
84 default:
85 printk("%s: unknown version cmd %d\n", __func__, cmd);
86 return -ENOSYS;
87 }
89 return xencomm_arch_hypercall_xen_version
90 (cmd, xencomm_create_inline(arg));
91 }
93 int
94 xencomm_hypercall_physdev_op(int cmd, void *op)
95 {
96 return xencomm_arch_hypercall_physdev_op
97 (cmd, xencomm_create_inline(op));
98 }
100 static void *
101 xencommize_grant_table_op(unsigned int cmd, void *op, unsigned int count)
102 {
103 switch (cmd) {
104 case GNTTABOP_map_grant_ref:
105 case GNTTABOP_unmap_grant_ref:
106 break;
107 case GNTTABOP_setup_table:
108 {
109 struct gnttab_setup_table *setup = op;
110 struct xencomm_handle *frame_list;
112 frame_list = xencomm_create_inline
113 (xen_guest_handle(setup->frame_list));
115 set_xen_guest_handle(setup->frame_list, (void *)frame_list);
116 break;
117 }
118 case GNTTABOP_dump_table:
119 case GNTTABOP_transfer:
120 case GNTTABOP_copy:
121 break;
122 default:
123 printk("%s: unknown grant table op %d\n", __func__, cmd);
124 BUG();
125 }
127 return xencomm_create_inline(op);
128 }
130 int
131 xencomm_hypercall_grant_table_op(unsigned int cmd, void *op, unsigned int count)
132 {
133 void *desc = xencommize_grant_table_op (cmd, op, count);
135 return xencomm_arch_hypercall_grant_table_op(cmd, desc, count);
136 }
138 int
139 xencomm_hypercall_sched_op(int cmd, void *arg)
140 {
141 switch (cmd) {
142 case SCHEDOP_yield:
143 case SCHEDOP_block:
144 case SCHEDOP_shutdown:
145 case SCHEDOP_poll:
146 case SCHEDOP_remote_shutdown:
147 break;
148 default:
149 printk("%s: unknown sched op %d\n", __func__, cmd);
150 return -ENOSYS;
151 }
153 return xencomm_arch_hypercall_sched_op(cmd, xencomm_create_inline(arg));
154 }
156 int
157 xencomm_hypercall_multicall(void *call_list, int nr_calls)
158 {
159 int i;
160 multicall_entry_t *mce;
162 for (i = 0; i < nr_calls; i++) {
163 mce = (multicall_entry_t *)call_list + i;
165 switch (mce->op) {
166 case __HYPERVISOR_update_va_mapping:
167 case __HYPERVISOR_mmu_update:
168 /* No-op on ia64. */
169 break;
170 case __HYPERVISOR_grant_table_op:
171 mce->args[1] = (unsigned long)xencommize_grant_table_op
172 (mce->args[0], (void *)mce->args[1],
173 mce->args[2]);
174 break;
175 case __HYPERVISOR_memory_op:
176 default:
177 printk("%s: unhandled multicall op entry op %lu\n",
178 __func__, mce->op);
179 return -ENOSYS;
180 }
181 }
183 return xencomm_arch_hypercall_multicall
184 (xencomm_create_inline(call_list), nr_calls);
185 }
187 int
188 xencomm_hypercall_callback_op(int cmd, void *arg)
189 {
190 switch (cmd)
191 {
192 case CALLBACKOP_register:
193 case CALLBACKOP_unregister:
194 break;
195 default:
196 printk("%s: unknown callback op %d\n", __func__, cmd);
197 return -ENOSYS;
198 }
200 return xencomm_arch_hypercall_callback_op
201 (cmd, xencomm_create_inline(arg));
202 }
204 static void
205 xencommize_memory_reservation (xen_memory_reservation_t *mop)
206 {
207 struct xencomm_handle *desc;
209 desc = xencomm_create_inline(xen_guest_handle(mop->extent_start));
210 set_xen_guest_handle(mop->extent_start, (void *)desc);
211 }
213 int
214 xencomm_hypercall_memory_op(unsigned int cmd, void *arg)
215 {
216 switch (cmd) {
217 case XENMEM_increase_reservation:
218 case XENMEM_decrease_reservation:
219 case XENMEM_populate_physmap:
220 xencommize_memory_reservation((xen_memory_reservation_t *)arg);
221 break;
223 case XENMEM_maximum_ram_page:
224 break;
226 case XENMEM_exchange:
227 xencommize_memory_reservation
228 (&((xen_memory_exchange_t *)arg)->in);
229 xencommize_memory_reservation
230 (&((xen_memory_exchange_t *)arg)->out);
231 break;
233 default:
234 printk("%s: unknown memory op %d\n", __func__, cmd);
235 return -ENOSYS;
236 }
238 return xencomm_arch_hypercall_memory_op
239 (cmd, xencomm_create_inline(arg));
240 }
242 unsigned long
243 xencomm_hypercall_hvm_op(int cmd, void *arg)
244 {
245 switch (cmd) {
246 case HVMOP_set_param:
247 case HVMOP_get_param:
248 break;
249 default:
250 printk("%s: unknown hvm op %d\n", __func__, cmd);
251 return -ENOSYS;
252 }
254 return xencomm_arch_hypercall_hvm_op(cmd, xencomm_create_inline(arg));
255 }
257 int
258 xencomm_hypercall_suspend(unsigned long srec)
259 {
260 struct sched_shutdown arg;
262 arg.reason = SHUTDOWN_suspend;
264 return xencomm_arch_hypercall_suspend(xencomm_create_inline(&arg));
265 }
267 int
268 xencomm_mini_hypercall_event_channel_op(int cmd, void *op)
269 {
270 struct xencomm_mini xc_area[2];
271 int nbr_area = 2;
272 struct xencomm_handle *desc;
273 int rc;
275 rc = xencomm_create_mini(xc_area, &nbr_area,
276 op, sizeof(evtchn_op_t), &desc);
277 if (rc)
278 return rc;
280 return xencomm_arch_hypercall_event_channel_op(cmd, desc);
281 }
282 EXPORT_SYMBOL(xencomm_mini_hypercall_event_channel_op);
284 static int
285 xencommize_mini_grant_table_op(struct xencomm_mini *xc_area, int *nbr_area,
286 unsigned int cmd, void *op, unsigned int count,
287 struct xencomm_handle **desc)
288 {
289 struct xencomm_handle *desc1;
290 unsigned int argsize;
291 int rc;
293 switch (cmd) {
294 case GNTTABOP_map_grant_ref:
295 argsize = sizeof(struct gnttab_map_grant_ref);
296 break;
297 case GNTTABOP_unmap_grant_ref:
298 argsize = sizeof(struct gnttab_unmap_grant_ref);
299 break;
300 case GNTTABOP_setup_table:
301 {
302 struct gnttab_setup_table *setup = op;
304 argsize = sizeof(*setup);
306 if (count != 1)
307 return -EINVAL;
308 rc = xencomm_create_mini
309 (xc_area, nbr_area,
310 xen_guest_handle(setup->frame_list),
311 setup->nr_frames
312 * sizeof(*xen_guest_handle(setup->frame_list)),
313 &desc1);
314 if (rc)
315 return rc;
316 set_xen_guest_handle(setup->frame_list, (void *)desc1);
317 break;
318 }
319 case GNTTABOP_dump_table:
320 argsize = sizeof(struct gnttab_dump_table);
321 break;
322 case GNTTABOP_transfer:
323 argsize = sizeof(struct gnttab_transfer);
324 break;
325 default:
326 printk("%s: unknown mini grant table op %d\n", __func__, cmd);
327 BUG();
328 }
330 rc = xencomm_create_mini(xc_area, nbr_area, op, count * argsize, desc);
331 if (rc)
332 return rc;
334 return 0;
335 }
337 int
338 xencomm_mini_hypercall_grant_table_op(unsigned int cmd, void *op,
339 unsigned int count)
340 {
341 int rc;
342 struct xencomm_handle *desc;
343 int nbr_area = 2;
344 struct xencomm_mini xc_area[2];
346 rc = xencommize_mini_grant_table_op(xc_area, &nbr_area,
347 cmd, op, count, &desc);
348 if (rc)
349 return rc;
351 return xencomm_arch_hypercall_grant_table_op(cmd, desc, count);
352 }
353 EXPORT_SYMBOL(xencomm_mini_hypercall_grant_table_op);
355 int
356 xencomm_mini_hypercall_multicall(void *call_list, int nr_calls)
357 {
358 int i;
359 multicall_entry_t *mce;
360 int nbr_area = 2 + nr_calls * 3;
361 struct xencomm_mini xc_area[nbr_area];
362 struct xencomm_handle *desc;
363 int rc;
365 for (i = 0; i < nr_calls; i++) {
366 mce = (multicall_entry_t *)call_list + i;
368 switch (mce->op) {
369 case __HYPERVISOR_update_va_mapping:
370 case __HYPERVISOR_mmu_update:
371 /* No-op on ia64. */
372 break;
373 case __HYPERVISOR_grant_table_op:
374 rc = xencommize_mini_grant_table_op
375 (xc_area, &nbr_area,
376 mce->args[0], (void *)mce->args[1],
377 mce->args[2], &desc);
378 if (rc)
379 return rc;
380 mce->args[1] = (unsigned long)desc;
381 break;
382 case __HYPERVISOR_memory_op:
383 default:
384 printk("%s: unhandled multicall op entry op %lu\n",
385 __func__, mce->op);
386 return -ENOSYS;
387 }
388 }
390 rc = xencomm_create_mini(xc_area, &nbr_area, call_list,
391 nr_calls * sizeof(multicall_entry_t), &desc);
392 if (rc)
393 return rc;
395 return xencomm_arch_hypercall_multicall(desc, nr_calls);
396 }
397 EXPORT_SYMBOL(xencomm_mini_hypercall_multicall);
399 static int
400 xencommize_mini_memory_reservation(struct xencomm_mini *area, int *nbr_area,
401 xen_memory_reservation_t *mop)
402 {
403 struct xencomm_handle *desc;
404 int rc;
406 rc = xencomm_create_mini
407 (area, nbr_area,
408 xen_guest_handle(mop->extent_start),
409 mop->nr_extents
410 * sizeof(*xen_guest_handle(mop->extent_start)),
411 &desc);
412 if (rc)
413 return rc;
415 set_xen_guest_handle(mop->extent_start, (void *)desc);
417 return 0;
418 }
420 int
421 xencomm_mini_hypercall_memory_op(unsigned int cmd, void *arg)
422 {
423 int nbr_area = 4;
424 struct xencomm_mini xc_area[4];
425 struct xencomm_handle *desc;
426 int rc;
427 unsigned int argsize;
429 switch (cmd) {
430 case XENMEM_increase_reservation:
431 case XENMEM_decrease_reservation:
432 case XENMEM_populate_physmap:
433 argsize = sizeof(xen_memory_reservation_t);
434 rc = xencommize_mini_memory_reservation
435 (xc_area, &nbr_area, (xen_memory_reservation_t *)arg);
436 if (rc)
437 return rc;
438 break;
440 case XENMEM_maximum_ram_page:
441 argsize = 0;
442 break;
444 case XENMEM_exchange:
445 argsize = sizeof(xen_memory_exchange_t);
446 rc = xencommize_mini_memory_reservation
447 (xc_area, &nbr_area,
448 &((xen_memory_exchange_t *)arg)->in);
449 if (rc)
450 return rc;
451 rc = xencommize_mini_memory_reservation
452 (xc_area, &nbr_area,
453 &((xen_memory_exchange_t *)arg)->out);
454 if (rc)
455 return rc;
456 break;
458 default:
459 printk("%s: unknown mini memory op %d\n", __func__, cmd);
460 return -ENOSYS;
461 }
463 rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc);
464 if (rc)
465 return rc;
467 return xencomm_arch_hypercall_memory_op(cmd, desc);
468 }
469 EXPORT_SYMBOL(xencomm_mini_hypercall_memory_op);