static int xencomm_privcmd_sched_op(privcmd_hypercall_t *hypercall) { int cmd = hypercall->arg[0]; struct xencomm_handle *desc; unsigned int argsize; int ret; switch (cmd) { case SCHEDOP_remote_shutdown: argsize = sizeof(sched_remote_shutdown_t); break; default: printk("%s: unknown SCHEDOP %d\n", __func__, cmd); return -EINVAL; } ret = xencomm_create((void *)hypercall->arg[1], argsize, &desc, GFP_KERNEL); if (ret) return ret; ret = xencomm_arch_hypercall_sched_op(cmd, desc); xencomm_free(desc); return ret; }
int xencomm_hypercall_suspend(unsigned long srec) { struct sched_shutdown arg; arg.reason = SHUTDOWN_suspend; return xencomm_arch_hypercall_sched_op( SCHEDOP_shutdown, xencomm_map_no_alloc(&arg, sizeof(arg))); }
int xencomm_hypercall_sched_op(int cmd, void *arg) { struct xencomm_handle *desc; unsigned int argsize; switch (cmd) { case SCHEDOP_yield: case SCHEDOP_block: argsize = 0; break; case SCHEDOP_shutdown: argsize = sizeof(struct sched_shutdown); break; case SCHEDOP_poll: { struct sched_poll *poll = arg; struct xencomm_handle *ports; argsize = sizeof(struct sched_poll); ports = xencomm_map_no_alloc(xen_guest_handle(poll->ports), sizeof(*xen_guest_handle(poll->ports))); set_xen_guest_handle(poll->ports, (void *)ports); break; } default: printk(KERN_DEBUG "%s: unknown sched op %d\n", __func__, cmd); return -ENOSYS; } desc = xencomm_map_no_alloc(arg, argsize); if (desc == NULL) return -EINVAL; return xencomm_arch_hypercall_sched_op(cmd, desc); }