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 /* xen early printk uses console io hypercall before
53 * xencomm initialization. In that case, we just ignore it.
55 if (!xencomm_is_initialized())
58 return xencomm_arch_hypercall_console_io
59 (cmd
, count
, xencomm_map_no_alloc(str
, count
));
61 EXPORT_SYMBOL_GPL(xencomm_hypercall_console_io
);
64 xencomm_hypercall_event_channel_op(int cmd
, void *op
)
66 struct xencomm_handle
*desc
;
67 desc
= xencomm_map_no_alloc(op
, sizeof(struct evtchn_op
));
71 return xencomm_arch_hypercall_event_channel_op(cmd
, desc
);
73 EXPORT_SYMBOL_GPL(xencomm_hypercall_event_channel_op
);
76 xencomm_hypercall_xen_version(int cmd
, void *arg
)
78 struct xencomm_handle
*desc
;
83 /* do not actually pass an argument */
84 return xencomm_arch_hypercall_xen_version(cmd
, 0);
85 case XENVER_extraversion
:
86 argsize
= sizeof(struct xen_extraversion
);
88 case XENVER_compile_info
:
89 argsize
= sizeof(struct xen_compile_info
);
91 case XENVER_capabilities
:
92 argsize
= sizeof(struct xen_capabilities_info
);
94 case XENVER_changeset
:
95 argsize
= sizeof(struct xen_changeset_info
);
97 case XENVER_platform_parameters
:
98 argsize
= sizeof(struct xen_platform_parameters
);
100 case XENVER_get_features
:
101 argsize
= (arg
== NULL
) ? 0 : sizeof(struct xen_feature_info
);
106 "%s: unknown version op %d\n", __func__
, cmd
);
110 desc
= xencomm_map_no_alloc(arg
, argsize
);
114 return xencomm_arch_hypercall_xen_version(cmd
, desc
);
116 EXPORT_SYMBOL_GPL(xencomm_hypercall_xen_version
);
119 xencomm_hypercall_physdev_op(int cmd
, void *op
)
121 unsigned int argsize
;
124 case PHYSDEVOP_apic_read
:
125 case PHYSDEVOP_apic_write
:
126 argsize
= sizeof(struct physdev_apic
);
128 case PHYSDEVOP_alloc_irq_vector
:
129 case PHYSDEVOP_free_irq_vector
:
130 argsize
= sizeof(struct physdev_irq
);
132 case PHYSDEVOP_irq_status_query
:
133 argsize
= sizeof(struct physdev_irq_status_query
);
138 "%s: unknown physdev op %d\n", __func__
, cmd
);
142 return xencomm_arch_hypercall_physdev_op
143 (cmd
, xencomm_map_no_alloc(op
, argsize
));
147 xencommize_grant_table_op(struct xencomm_mini
**xc_area
,
148 unsigned int cmd
, void *op
, unsigned int count
,
149 struct xencomm_handle
**desc
)
151 struct xencomm_handle
*desc1
;
152 unsigned int argsize
;
155 case GNTTABOP_map_grant_ref
:
156 argsize
= sizeof(struct gnttab_map_grant_ref
);
158 case GNTTABOP_unmap_grant_ref
:
159 argsize
= sizeof(struct gnttab_unmap_grant_ref
);
161 case GNTTABOP_setup_table
:
163 struct gnttab_setup_table
*setup
= op
;
165 argsize
= sizeof(*setup
);
169 desc1
= __xencomm_map_no_alloc
170 (xen_guest_handle(setup
->frame_list
),
172 sizeof(*xen_guest_handle(setup
->frame_list
)),
177 set_xen_guest_handle(setup
->frame_list
, (void *)desc1
);
180 case GNTTABOP_dump_table
:
181 argsize
= sizeof(struct gnttab_dump_table
);
183 case GNTTABOP_transfer
:
184 argsize
= sizeof(struct gnttab_transfer
);
187 argsize
= sizeof(struct gnttab_copy
);
189 case GNTTABOP_query_size
:
190 argsize
= sizeof(struct gnttab_query_size
);
193 printk(KERN_DEBUG
"%s: unknown hypercall grant table op %d\n",
198 *desc
= __xencomm_map_no_alloc(op
, count
* argsize
, *xc_area
);
207 xencomm_hypercall_grant_table_op(unsigned int cmd
, void *op
,
211 struct xencomm_handle
*desc
;
212 XENCOMM_MINI_ALIGNED(xc_area
, 2);
214 rc
= xencommize_grant_table_op(&xc_area
, cmd
, op
, count
, &desc
);
218 return xencomm_arch_hypercall_grant_table_op(cmd
, desc
, count
);
220 EXPORT_SYMBOL_GPL(xencomm_hypercall_grant_table_op
);
223 xencomm_hypercall_sched_op(int cmd
, void *arg
)
225 struct xencomm_handle
*desc
;
226 unsigned int argsize
;
233 case SCHEDOP_shutdown
:
234 argsize
= sizeof(struct sched_shutdown
);
238 struct sched_poll
*poll
= arg
;
239 struct xencomm_handle
*ports
;
241 argsize
= sizeof(struct sched_poll
);
242 ports
= xencomm_map_no_alloc(xen_guest_handle(poll
->ports
),
243 sizeof(*xen_guest_handle(poll
->ports
)));
245 set_xen_guest_handle(poll
->ports
, (void *)ports
);
249 printk(KERN_DEBUG
"%s: unknown sched op %d\n", __func__
, cmd
);
253 desc
= xencomm_map_no_alloc(arg
, argsize
);
257 return xencomm_arch_hypercall_sched_op(cmd
, desc
);
259 EXPORT_SYMBOL_GPL(xencomm_hypercall_sched_op
);
262 xencomm_hypercall_multicall(void *call_list
, int nr_calls
)
266 struct multicall_entry
*mce
;
267 struct xencomm_handle
*desc
;
268 XENCOMM_MINI_ALIGNED(xc_area
, nr_calls
* 2);
270 for (i
= 0; i
< nr_calls
; i
++) {
271 mce
= (struct multicall_entry
*)call_list
+ i
;
274 case __HYPERVISOR_update_va_mapping
:
275 case __HYPERVISOR_mmu_update
:
278 case __HYPERVISOR_grant_table_op
:
279 rc
= xencommize_grant_table_op
281 mce
->args
[0], (void *)mce
->args
[1],
282 mce
->args
[2], &desc
);
285 mce
->args
[1] = (unsigned long)desc
;
287 case __HYPERVISOR_memory_op
:
290 "%s: unhandled multicall op entry op %lu\n",
296 desc
= xencomm_map_no_alloc(call_list
,
297 nr_calls
* sizeof(struct multicall_entry
));
301 return xencomm_arch_hypercall_multicall(desc
, nr_calls
);
303 EXPORT_SYMBOL_GPL(xencomm_hypercall_multicall
);
306 xencomm_hypercall_callback_op(int cmd
, void *arg
)
308 unsigned int argsize
;
310 case CALLBACKOP_register
:
311 argsize
= sizeof(struct callback_register
);
313 case CALLBACKOP_unregister
:
314 argsize
= sizeof(struct callback_unregister
);
318 "%s: unknown callback op %d\n", __func__
, cmd
);
322 return xencomm_arch_hypercall_callback_op
323 (cmd
, xencomm_map_no_alloc(arg
, argsize
));
327 xencommize_memory_reservation(struct xencomm_mini
*xc_area
,
328 struct xen_memory_reservation
*mop
)
330 struct xencomm_handle
*desc
;
332 desc
= __xencomm_map_no_alloc(xen_guest_handle(mop
->extent_start
),
334 sizeof(*xen_guest_handle(mop
->extent_start
)),
339 set_xen_guest_handle(mop
->extent_start
, (void *)desc
);
344 xencomm_hypercall_memory_op(unsigned int cmd
, void *arg
)
346 GUEST_HANDLE(xen_pfn_t
) extent_start_va
[2] = { {NULL
}, {NULL
} };
347 struct xen_memory_reservation
*xmr
= NULL
;
349 struct xencomm_handle
*desc
;
350 unsigned int argsize
;
351 XENCOMM_MINI_ALIGNED(xc_area
, 2);
354 case XENMEM_increase_reservation
:
355 case XENMEM_decrease_reservation
:
356 case XENMEM_populate_physmap
:
357 xmr
= (struct xen_memory_reservation
*)arg
;
358 set_xen_guest_handle(extent_start_va
[0],
359 xen_guest_handle(xmr
->extent_start
));
361 argsize
= sizeof(*xmr
);
362 rc
= xencommize_memory_reservation(xc_area
, xmr
);
368 case XENMEM_maximum_ram_page
:
372 case XENMEM_add_to_physmap
:
373 argsize
= sizeof(struct xen_add_to_physmap
);
377 printk(KERN_DEBUG
"%s: unknown memory op %d\n", __func__
, cmd
);
381 desc
= xencomm_map_no_alloc(arg
, argsize
);
385 rc
= xencomm_arch_hypercall_memory_op(cmd
, desc
);
388 case XENMEM_increase_reservation
:
389 case XENMEM_decrease_reservation
:
390 case XENMEM_populate_physmap
:
391 set_xen_guest_handle(xmr
->extent_start
,
392 xen_guest_handle(extent_start_va
[0]));
398 EXPORT_SYMBOL_GPL(xencomm_hypercall_memory_op
);
401 xencomm_hypercall_suspend(unsigned long srec
)
403 struct sched_shutdown arg
;
405 arg
.reason
= SHUTDOWN_suspend
;
407 return xencomm_arch_hypercall_sched_op(
408 SCHEDOP_shutdown
, xencomm_map_no_alloc(&arg
, sizeof(arg
)));
412 xencomm_hypercall_vcpu_op(int cmd
, int cpu
, void *arg
)
414 unsigned int argsize
;
416 case VCPUOP_register_runstate_memory_area
: {
417 struct vcpu_register_runstate_memory_area
*area
=
418 (struct vcpu_register_runstate_memory_area
*)arg
;
419 argsize
= sizeof(*arg
);
420 set_xen_guest_handle(area
->addr
.h
,
421 (void *)xencomm_map_no_alloc(area
->addr
.v
,
422 sizeof(area
->addr
.v
)));
427 printk(KERN_DEBUG
"%s: unknown vcpu op %d\n", __func__
, cmd
);
431 return xencomm_arch_hypercall_vcpu_op(cmd
, cpu
,
432 xencomm_map_no_alloc(arg
, argsize
));
436 xencomm_hypercall_opt_feature(void *arg
)
438 return xencomm_arch_hypercall_opt_feature(
439 xencomm_map_no_alloc(arg
,
440 sizeof(struct xen_ia64_opt_feature
)));