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.
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.
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.
16 * Tristan Gingold <tristan.gingold@bull.net>
19 * Isaku Yamahata <yamahata at valinux co jp>
20 * VA Linux Systems Japan K.K.
21 * consolidate mini and inline version.
24 #include <linux/module.h>
25 #include <xen/interface/xen.h>
26 #include <xen/interface/memory.h>
27 #include <xen/interface/grant_table.h>
28 #include <xen/interface/callback.h>
29 #include <xen/interface/vcpu.h>
30 #include <asm/xen/hypervisor.h>
31 #include <asm/xen/xencomm.h>
34 * This file defines hypercalls to be used by xencomm. The hypercalls simply
35 * create inlines or mini descriptors for pointers and then call the raw arch
36 * hypercall xencomm_arch_hypercall_XXX
38 * If the arch wants to directly use these hypercalls, simply define macros
39 * in asm/xen/hypercall.h, eg:
40 * #define HYPERVISOR_sched_op xencomm_hypercall_sched_op
42 * The arch may also define HYPERVISOR_xxx as a function and do more operations
43 * before/after doing the hypercall.
45 * Note: because only inline or mini descriptors are created these functions
46 * must only be called with in kernel memory parameters.
50 xencomm_hypercall_console_io(int cmd
, int count
, char *str
)
52 return xencomm_arch_hypercall_console_io
53 (cmd
, count
, xencomm_map_no_alloc(str
, count
));
55 EXPORT_SYMBOL_GPL(xencomm_hypercall_console_io
);
58 xencomm_hypercall_event_channel_op(int cmd
, void *op
)
60 struct xencomm_handle
*desc
;
61 desc
= xencomm_map_no_alloc(op
, sizeof(struct evtchn_op
));
65 return xencomm_arch_hypercall_event_channel_op(cmd
, desc
);
67 EXPORT_SYMBOL_GPL(xencomm_hypercall_event_channel_op
);
70 xencomm_hypercall_xen_version(int cmd
, void *arg
)
72 struct xencomm_handle
*desc
;
77 /* do not actually pass an argument */
78 return xencomm_arch_hypercall_xen_version(cmd
, 0);
79 case XENVER_extraversion
:
80 argsize
= sizeof(struct xen_extraversion
);
82 case XENVER_compile_info
:
83 argsize
= sizeof(struct xen_compile_info
);
85 case XENVER_capabilities
:
86 argsize
= sizeof(struct xen_capabilities_info
);
88 case XENVER_changeset
:
89 argsize
= sizeof(struct xen_changeset_info
);
91 case XENVER_platform_parameters
:
92 argsize
= sizeof(struct xen_platform_parameters
);
94 case XENVER_get_features
:
95 argsize
= (arg
== NULL
) ? 0 : sizeof(struct xen_feature_info
);
100 "%s: unknown version op %d\n", __func__
, cmd
);
104 desc
= xencomm_map_no_alloc(arg
, argsize
);
108 return xencomm_arch_hypercall_xen_version(cmd
, desc
);
110 EXPORT_SYMBOL_GPL(xencomm_hypercall_xen_version
);
113 xencomm_hypercall_physdev_op(int cmd
, void *op
)
115 unsigned int argsize
;
118 case PHYSDEVOP_apic_read
:
119 case PHYSDEVOP_apic_write
:
120 argsize
= sizeof(struct physdev_apic
);
122 case PHYSDEVOP_alloc_irq_vector
:
123 case PHYSDEVOP_free_irq_vector
:
124 argsize
= sizeof(struct physdev_irq
);
126 case PHYSDEVOP_irq_status_query
:
127 argsize
= sizeof(struct physdev_irq_status_query
);
132 "%s: unknown physdev op %d\n", __func__
, cmd
);
136 return xencomm_arch_hypercall_physdev_op
137 (cmd
, xencomm_map_no_alloc(op
, argsize
));
141 xencommize_grant_table_op(struct xencomm_mini
**xc_area
,
142 unsigned int cmd
, void *op
, unsigned int count
,
143 struct xencomm_handle
**desc
)
145 struct xencomm_handle
*desc1
;
146 unsigned int argsize
;
149 case GNTTABOP_map_grant_ref
:
150 argsize
= sizeof(struct gnttab_map_grant_ref
);
152 case GNTTABOP_unmap_grant_ref
:
153 argsize
= sizeof(struct gnttab_unmap_grant_ref
);
155 case GNTTABOP_setup_table
:
157 struct gnttab_setup_table
*setup
= op
;
159 argsize
= sizeof(*setup
);
163 desc1
= __xencomm_map_no_alloc
164 (xen_guest_handle(setup
->frame_list
),
166 sizeof(*xen_guest_handle(setup
->frame_list
)),
171 set_xen_guest_handle(setup
->frame_list
, (void *)desc1
);
174 case GNTTABOP_dump_table
:
175 argsize
= sizeof(struct gnttab_dump_table
);
177 case GNTTABOP_transfer
:
178 argsize
= sizeof(struct gnttab_transfer
);
181 argsize
= sizeof(struct gnttab_copy
);
183 case GNTTABOP_query_size
:
184 argsize
= sizeof(struct gnttab_query_size
);
187 printk(KERN_DEBUG
"%s: unknown hypercall grant table op %d\n",
192 *desc
= __xencomm_map_no_alloc(op
, count
* argsize
, *xc_area
);
201 xencomm_hypercall_grant_table_op(unsigned int cmd
, void *op
,
205 struct xencomm_handle
*desc
;
206 XENCOMM_MINI_ALIGNED(xc_area
, 2);
208 rc
= xencommize_grant_table_op(&xc_area
, cmd
, op
, count
, &desc
);
212 return xencomm_arch_hypercall_grant_table_op(cmd
, desc
, count
);
214 EXPORT_SYMBOL_GPL(xencomm_hypercall_grant_table_op
);
217 xencomm_hypercall_sched_op(int cmd
, void *arg
)
219 struct xencomm_handle
*desc
;
220 unsigned int argsize
;
227 case SCHEDOP_shutdown
:
228 argsize
= sizeof(struct sched_shutdown
);
232 struct sched_poll
*poll
= arg
;
233 struct xencomm_handle
*ports
;
235 argsize
= sizeof(struct sched_poll
);
236 ports
= xencomm_map_no_alloc(xen_guest_handle(poll
->ports
),
237 sizeof(*xen_guest_handle(poll
->ports
)));
239 set_xen_guest_handle(poll
->ports
, (void *)ports
);
243 printk(KERN_DEBUG
"%s: unknown sched op %d\n", __func__
, cmd
);
247 desc
= xencomm_map_no_alloc(arg
, argsize
);
251 return xencomm_arch_hypercall_sched_op(cmd
, desc
);
253 EXPORT_SYMBOL_GPL(xencomm_hypercall_sched_op
);
256 xencomm_hypercall_multicall(void *call_list
, int nr_calls
)
260 struct multicall_entry
*mce
;
261 struct xencomm_handle
*desc
;
262 XENCOMM_MINI_ALIGNED(xc_area
, nr_calls
* 2);
264 for (i
= 0; i
< nr_calls
; i
++) {
265 mce
= (struct multicall_entry
*)call_list
+ i
;
268 case __HYPERVISOR_update_va_mapping
:
269 case __HYPERVISOR_mmu_update
:
272 case __HYPERVISOR_grant_table_op
:
273 rc
= xencommize_grant_table_op
275 mce
->args
[0], (void *)mce
->args
[1],
276 mce
->args
[2], &desc
);
279 mce
->args
[1] = (unsigned long)desc
;
281 case __HYPERVISOR_memory_op
:
284 "%s: unhandled multicall op entry op %lu\n",
290 desc
= xencomm_map_no_alloc(call_list
,
291 nr_calls
* sizeof(struct multicall_entry
));
295 return xencomm_arch_hypercall_multicall(desc
, nr_calls
);
297 EXPORT_SYMBOL_GPL(xencomm_hypercall_multicall
);
300 xencomm_hypercall_callback_op(int cmd
, void *arg
)
302 unsigned int argsize
;
304 case CALLBACKOP_register
:
305 argsize
= sizeof(struct callback_register
);
307 case CALLBACKOP_unregister
:
308 argsize
= sizeof(struct callback_unregister
);
312 "%s: unknown callback op %d\n", __func__
, cmd
);
316 return xencomm_arch_hypercall_callback_op
317 (cmd
, xencomm_map_no_alloc(arg
, argsize
));
321 xencommize_memory_reservation(struct xencomm_mini
*xc_area
,
322 struct xen_memory_reservation
*mop
)
324 struct xencomm_handle
*desc
;
326 desc
= __xencomm_map_no_alloc(xen_guest_handle(mop
->extent_start
),
328 sizeof(*xen_guest_handle(mop
->extent_start
)),
333 set_xen_guest_handle(mop
->extent_start
, (void *)desc
);
338 xencomm_hypercall_memory_op(unsigned int cmd
, void *arg
)
340 GUEST_HANDLE(xen_pfn_t
) extent_start_va
[2] = { {NULL
}, {NULL
} };
341 struct xen_memory_reservation
*xmr
= NULL
;
343 struct xencomm_handle
*desc
;
344 unsigned int argsize
;
345 XENCOMM_MINI_ALIGNED(xc_area
, 2);
348 case XENMEM_increase_reservation
:
349 case XENMEM_decrease_reservation
:
350 case XENMEM_populate_physmap
:
351 xmr
= (struct xen_memory_reservation
*)arg
;
352 set_xen_guest_handle(extent_start_va
[0],
353 xen_guest_handle(xmr
->extent_start
));
355 argsize
= sizeof(*xmr
);
356 rc
= xencommize_memory_reservation(xc_area
, xmr
);
362 case XENMEM_maximum_ram_page
:
366 case XENMEM_add_to_physmap
:
367 argsize
= sizeof(struct xen_add_to_physmap
);
371 printk(KERN_DEBUG
"%s: unknown memory op %d\n", __func__
, cmd
);
375 desc
= xencomm_map_no_alloc(arg
, argsize
);
379 rc
= xencomm_arch_hypercall_memory_op(cmd
, desc
);
382 case XENMEM_increase_reservation
:
383 case XENMEM_decrease_reservation
:
384 case XENMEM_populate_physmap
:
385 set_xen_guest_handle(xmr
->extent_start
,
386 xen_guest_handle(extent_start_va
[0]));
392 EXPORT_SYMBOL_GPL(xencomm_hypercall_memory_op
);
395 xencomm_hypercall_vcpu_op(int cmd
, int cpu
, void *arg
)
397 unsigned int argsize
;
399 case VCPUOP_register_runstate_memory_area
: {
400 struct vcpu_register_runstate_memory_area
*area
=
401 (struct vcpu_register_runstate_memory_area
*)arg
;
402 argsize
= sizeof(*arg
);
403 set_xen_guest_handle(area
->addr
.h
,
404 (void *)xencomm_map_no_alloc(area
->addr
.v
,
405 sizeof(area
->addr
.v
)));
410 printk(KERN_DEBUG
"%s: unknown vcpu op %d\n", __func__
, cmd
);
414 return xencomm_arch_hypercall_vcpu_op(cmd
, cpu
,
415 xencomm_map_no_alloc(arg
, argsize
));
419 xencomm_hypercall_opt_feature(void *arg
)
421 return xencomm_arch_hypercall_opt_feature(
422 xencomm_map_no_alloc(arg
,
423 sizeof(struct xen_ia64_opt_feature
)));