/* Legacy hypercall (as of 0x00030202). */
ret_t do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop)
{
+ typeof(do_physdev_op) *fn =
+ (void *)pv_hypercall_table[__HYPERVISOR_physdev_op].native;
struct physdev_op op;
if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
return -EFAULT;
- return do_physdev_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
+ return fn(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
}
#ifndef COMPAT
/* Legacy hypercall (as of 0x00030101). */
long do_sched_op_compat(int cmd, unsigned long arg)
{
+ typeof(do_sched_op) *fn =
+ (void *)pv_hypercall_table[__HYPERVISOR_sched_op].native;
+
switch ( cmd )
{
case SCHEDOP_yield:
case SCHEDOP_block:
- return do_sched_op(cmd, guest_handle_from_ptr(NULL, void));
+ return fn(cmd, guest_handle_from_ptr(NULL, void));
case SCHEDOP_shutdown:
TRACE_3D(TRC_SCHED_SHUTDOWN,
/* Legacy hypercall (as of 0x00030202). */
long do_event_channel_op_compat(XEN_GUEST_HANDLE_PARAM(evtchn_op_t) uop)
{
+ typeof(do_event_channel_op) *fn =
+ (void *)pv_hypercall_table[__HYPERVISOR_event_channel_op].native;
struct evtchn_op op;
if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
case EVTCHNOP_bind_ipi:
case EVTCHNOP_bind_vcpu:
case EVTCHNOP_unmask:
- return pv_get_hypercall_handler(__HYPERVISOR_event_channel_op, false)
- (op.cmd, (unsigned long)&uop.p->u, 0, 0, 0, 0);
+ return fn(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
default:
return -ENOSYS;
#define do_arch_1 paging_domctl_continuation
-static const hypercall_table_t pv_hypercall_table[] = {
+const hypercall_table_t pv_hypercall_table[] = {
COMPAT_CALL(set_trap_table),
HYPERCALL(mmu_update),
COMPAT_CALL(set_gdt),
*(u16 *)(p+ 6) = (HYPERCALL_VECTOR << 8) | 0xcd; /* int $xx */
}
-void __init pv_hypercall_table_replace(unsigned int hypercall,
- hypercall_fn_t * native,
- hypercall_fn_t *compat)
-{
-#define HANDLER_POINTER(f) \
- ((unsigned long *)__va(__pa(&pv_hypercall_table[hypercall].f)))
- write_atomic(HANDLER_POINTER(native), (unsigned long)native);
- write_atomic(HANDLER_POINTER(compat), (unsigned long)compat);
-#undef HANDLER_POINTER
-}
-
-hypercall_fn_t *pv_get_hypercall_handler(unsigned int hypercall, bool compat)
-{
- return compat ? pv_hypercall_table[hypercall].compat
- : pv_hypercall_table[hypercall].native;
-}
-
/*
* Local variables:
* mode: C
unsigned long console_va, unsigned long vphysmap,
start_info_t *si)
{
+ hypercall_table_t *rw_pv_hypercall_table;
uint64_t param = 0;
long rc;
mfn_x(console_mfn), vphysmap);
consoled_set_ring_addr(page);
}
- pv_hypercall_table_replace(__HYPERVISOR_event_channel_op,
- (hypercall_fn_t *)pv_shim_event_channel_op,
- (hypercall_fn_t *)pv_shim_event_channel_op);
- pv_hypercall_table_replace(__HYPERVISOR_grant_table_op,
- (hypercall_fn_t *)pv_shim_grant_table_op,
- (hypercall_fn_t *)pv_shim_grant_table_op);
+
+ /*
+ * Locate pv_hypercall_table[] (usually .rodata) in the directmap (which
+ * is writeable) and insert some shim-specific hypercall handlers.
+ */
+ rw_pv_hypercall_table = __va(__pa(pv_hypercall_table));
+ rw_pv_hypercall_table[__HYPERVISOR_event_channel_op].native =
+ rw_pv_hypercall_table[__HYPERVISOR_event_channel_op].compat =
+ (hypercall_fn_t *)pv_shim_event_channel_op;
+
+ rw_pv_hypercall_table[__HYPERVISOR_grant_table_op].native =
+ rw_pv_hypercall_table[__HYPERVISOR_grant_table_op].compat =
+ (hypercall_fn_t *)pv_shim_grant_table_op;
+
guest = d;
/*
extern const hypercall_args_t hypercall_args_table[NR_hypercalls];
+#ifdef CONFIG_PV
+extern const hypercall_table_t pv_hypercall_table[];
void pv_hypercall(struct cpu_user_regs *regs);
void hypercall_page_initialise_ring3_kernel(void *hypercall_page);
void hypercall_page_initialise_ring1_kernel(void *hypercall_page);
-void pv_hypercall_table_replace(unsigned int hypercall, hypercall_fn_t * native,
- hypercall_fn_t *compat);
-hypercall_fn_t *pv_get_hypercall_handler(unsigned int hypercall, bool compat);
+#endif
/*
* Both do_mmuext_op() and do_mmu_update():