int xc_domain_shutdown(xc_interface *xch, uint32_t domid, int reason) { int ret = -1; DECLARE_HYPERCALL; DECLARE_HYPERCALL_BUFFER(sched_remote_shutdown_t, arg); arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg)); if ( arg == NULL ) { PERROR("Could not allocate memory for xc_domain_shutdown hypercall"); goto out1; } hypercall.op = __HYPERVISOR_sched_op; hypercall.arg[0] = (unsigned long)SCHEDOP_remote_shutdown; hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg); arg->domain_id = domid; arg->reason = reason; ret = do_xen_hypercall(xch, &hypercall); xc_hypercall_buffer_free(xch, arg); out1: return ret; }
int xc_mmuext_op( xc_interface *xch, struct mmuext_op *op, unsigned int nr_ops, domid_t dom) { DECLARE_HYPERCALL; DECLARE_HYPERCALL_BOUNCE(op, nr_ops*sizeof(*op), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); long ret = -EINVAL; if ( xc_hypercall_bounce_pre(xch, op) ) { PERROR("Could not bounce memory for mmuext op hypercall"); goto out1; } hypercall.op = __HYPERVISOR_mmuext_op; hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(op); hypercall.arg[1] = (unsigned long)nr_ops; hypercall.arg[2] = (unsigned long)0; hypercall.arg[3] = (unsigned long)dom; ret = do_xen_hypercall(xch, &hypercall); xc_hypercall_bounce_post(xch, op); out1: return ret; }
int xc_hvm_set_isa_irq_level( xc_interface *xch, domid_t dom, uint8_t isa_irq, unsigned int level) { DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_isa_irq_level, arg); int rc; arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg)); if ( arg == NULL ) { PERROR("Could not allocate memory for xc_hvm_set_isa_irq_level hypercall"); return -1; } arg->domid = dom; arg->isa_irq = isa_irq; arg->level = level; rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op, HVMOP_set_isa_irq_level, HYPERCALL_BUFFER_AS_ARG(arg)); xc_hypercall_buffer_free(xch, arg); return rc; }
int xc_hvm_inject_msi( xc_interface *xch, domid_t dom, uint64_t addr, uint32_t data) { DECLARE_HYPERCALL_BUFFER(struct xen_hvm_inject_msi, arg); int rc; arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg)); if ( arg == NULL ) { PERROR("Could not allocate memory for xc_hvm_inject_msi hypercall"); return -1; } arg->domid = dom; arg->addr = addr; arg->data = data; rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op, HVMOP_inject_msi, HYPERCALL_BUFFER_AS_ARG(arg)); xc_hypercall_buffer_free(xch, arg); return rc; }
static int flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu) { int err = 0; DECLARE_HYPERCALL; DECLARE_NAMED_HYPERCALL_BOUNCE(updates, mmu->updates, mmu->idx*sizeof(*mmu->updates), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); if ( mmu->idx == 0 ) return 0; if ( xc_hypercall_bounce_pre(xch, updates) ) { PERROR("flush_mmu_updates: bounce buffer failed"); err = 1; goto out; } hypercall.op = __HYPERVISOR_mmu_update; hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(updates); hypercall.arg[1] = (unsigned long)mmu->idx; hypercall.arg[2] = 0; hypercall.arg[3] = mmu->subject; if ( do_xen_hypercall(xch, &hypercall) < 0 ) { ERROR("Failure when submitting mmu updates"); err = 1; } mmu->idx = 0; xc_hypercall_bounce_post(xch, updates); out: return err; }
int xc_kexec_unload(xc_interface *xch, int type) { DECLARE_HYPERCALL; DECLARE_HYPERCALL_BUFFER(xen_kexec_unload_t, unload); int ret = -1; unload = xc_hypercall_buffer_alloc(xch, unload, sizeof(*unload)); if ( unload == NULL ) { PERROR("Count not alloc buffer for kexec unload hypercall"); goto out; } unload->type = type; hypercall.op = __HYPERVISOR_kexec_op; hypercall.arg[0] = KEXEC_CMD_kexec_unload; hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(unload); ret = do_xen_hypercall(xch, &hypercall); out: xc_hypercall_buffer_free(xch, unload); return ret; }
int xc_hvm_track_dirty_vram( xc_interface *xch, domid_t dom, uint64_t first_pfn, uint64_t nr, unsigned long *dirty_bitmap) { DECLARE_HYPERCALL_BOUNCE(dirty_bitmap, (nr+7) / 8, XC_HYPERCALL_BUFFER_BOUNCE_OUT); DECLARE_HYPERCALL_BUFFER(struct xen_hvm_track_dirty_vram, arg); int rc; arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg)); if ( arg == NULL || xc_hypercall_bounce_pre(xch, dirty_bitmap) ) { PERROR("Could not bounce memory for xc_hvm_track_dirty_vram hypercall"); rc = -1; goto out; } arg->domid = dom; arg->first_pfn = first_pfn; arg->nr = nr; set_xen_guest_handle(arg->dirty_bitmap, dirty_bitmap); rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op, HVMOP_track_dirty_vram, HYPERCALL_BUFFER_AS_ARG(arg)); out: xc_hypercall_buffer_free(xch, arg); xc_hypercall_bounce_post(xch, dirty_bitmap); return rc; }
int xc_kexec_get_range(xc_interface *xch, int range, int nr, uint64_t *size, uint64_t *start) { DECLARE_HYPERCALL_BUFFER(xen_kexec_range_t, get_range); int ret = -1; get_range = xc_hypercall_buffer_alloc(xch, get_range, sizeof(*get_range)); if ( get_range == NULL ) { PERROR("Could not alloc bounce buffer for kexec_get_range hypercall"); goto out; } get_range->range = range; get_range->nr = nr; ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op, KEXEC_CMD_kexec_get_range, HYPERCALL_BUFFER_AS_ARG(get_range)); *size = get_range->size; *start = get_range->start; out: xc_hypercall_buffer_free(xch, get_range); return ret; }
int xc_hvm_inject_trap( xc_interface *xch, domid_t dom, int vcpu, uint32_t vector, uint32_t type, uint32_t error_code, uint32_t insn_len, uint64_t cr2) { DECLARE_HYPERCALL_BUFFER(struct xen_hvm_inject_trap, arg); int rc; arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg)); if ( arg == NULL ) { PERROR("Could not allocate memory for xc_hvm_inject_trap hypercall"); return -1; } arg->domid = dom; arg->vcpuid = vcpu; arg->vector = vector; arg->type = type; arg->error_code = error_code; arg->insn_len = insn_len; arg->cr2 = cr2; rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op, HVMOP_inject_trap, HYPERCALL_BUFFER_AS_ARG(arg)); xc_hypercall_buffer_free(xch, arg); return rc; }
int xc_hvm_set_mem_type( xc_interface *xch, domid_t dom, hvmmem_type_t mem_type, uint64_t first_pfn, uint64_t nr) { DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_mem_type, arg); int rc; arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg)); if ( arg == NULL ) { PERROR("Could not allocate memory for xc_hvm_set_mem_type hypercall"); return -1; } arg->domid = dom; arg->hvmmem_type = mem_type; arg->first_pfn = first_pfn; arg->nr = nr; rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op, HVMOP_set_mem_type, HYPERCALL_BUFFER_AS_ARG(arg)); xc_hypercall_buffer_free(xch, arg); return rc; }
static int flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu) { int rc, err = 0; DECLARE_NAMED_HYPERCALL_BOUNCE(updates, mmu->updates, mmu->idx*sizeof(*mmu->updates), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); if ( mmu->idx == 0 ) return 0; if ( xc_hypercall_bounce_pre(xch, updates) ) { PERROR("flush_mmu_updates: bounce buffer failed"); err = 1; goto out; } rc = xencall4(xch->xcall, __HYPERVISOR_mmu_update, HYPERCALL_BUFFER_AS_ARG(updates), mmu->idx, 0, mmu->subject); if ( rc < 0 ) { ERROR("Failure when submitting mmu updates"); err = 1; } mmu->idx = 0; xc_hypercall_bounce_post(xch, updates); out: return err; }
int xc_watchdog(xc_interface *xch, uint32_t id, uint32_t timeout) { int ret = -1; DECLARE_HYPERCALL; DECLARE_HYPERCALL_BUFFER(sched_watchdog_t, arg); arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg)); if ( arg == NULL ) { PERROR("Could not allocate memory for xc_watchdog hypercall"); goto out1; } hypercall.op = __HYPERVISOR_sched_op; hypercall.arg[0] = (unsigned long)SCHEDOP_watchdog; hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg); arg->id = id; arg->timeout = timeout; ret = do_xen_hypercall(xch, &hypercall); xc_hypercall_buffer_free(xch, arg); out1: return ret; }
int xc_kexec_exec(xc_interface *xch, int type) { DECLARE_HYPERCALL; DECLARE_HYPERCALL_BUFFER(xen_kexec_exec_t, exec); int ret = -1; exec = xc_hypercall_buffer_alloc(xch, exec, sizeof(*exec)); if ( exec == NULL ) { PERROR("Count not alloc bounce buffer for kexec_exec hypercall"); goto out; } exec->type = type; hypercall.op = __HYPERVISOR_kexec_op; hypercall.arg[0] = KEXEC_CMD_kexec; hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(exec); ret = do_xen_hypercall(xch, &hypercall); out: xc_hypercall_buffer_free(xch, exec); return ret; }
int xc_hvm_set_pci_link_route( xc_interface *xch, domid_t dom, uint8_t link, uint8_t isa_irq) { DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_pci_link_route, arg); int rc; arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg)); if ( arg == NULL ) { PERROR("Could not allocate memory for xc_hvm_set_pci_link_route hypercall"); return -1; } arg->domid = dom; arg->link = link; arg->isa_irq = isa_irq; rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op, HVMOP_set_pci_link_route, HYPERCALL_BUFFER_AS_ARG(arg)); xc_hypercall_buffer_free(xch, arg); return rc; }
int xc_flask_op(xc_interface *xch, xen_flask_op_t *op) { int ret = -1; DECLARE_HYPERCALL; DECLARE_HYPERCALL_BOUNCE(op, sizeof(*op), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); op->interface_version = XEN_FLASK_INTERFACE_VERSION; if ( xc_hypercall_bounce_pre(xch, op) ) { PERROR("Could not bounce memory for flask op hypercall"); goto out; } hypercall.op = __HYPERVISOR_xsm_op; hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(op); if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 ) { if ( errno == EACCES ) fprintf(stderr, "XSM operation failed!\n"); } xc_hypercall_bounce_post(xch, op); out: return ret; }
int xc_mca_op(xc_interface *xch, struct xen_mc *mc) { int ret = 0; DECLARE_HYPERCALL_BOUNCE(mc, sizeof(*mc), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); if ( xc_hypercall_bounce_pre(xch, mc) ) { PERROR("Could not bounce xen_mc memory buffer"); return -1; } mc->interface_version = XEN_MCA_INTERFACE_VERSION; ret = xencall1(xch->xcall, __HYPERVISOR_mca, HYPERCALL_BUFFER_AS_ARG(mc)); xc_hypercall_bounce_post(xch, mc); return ret; }
long do_memory_op(xc_interface *xch, int cmd, void *arg, size_t len) { DECLARE_HYPERCALL_BOUNCE(arg, len, XC_HYPERCALL_BUFFER_BOUNCE_BOTH); long ret = -1; if ( xc_hypercall_bounce_pre(xch, arg) ) { PERROR("Could not bounce memory for XENMEM hypercall"); goto out1; } ret = xencall2(xch->xcall, __HYPERVISOR_memory_op, cmd, HYPERCALL_BUFFER_AS_ARG(arg)); xc_hypercall_bounce_post(xch, arg); out1: return ret; }
int xc_kexec_load(xc_interface *xch, uint8_t type, uint16_t arch, uint64_t entry_maddr, uint32_t nr_segments, xen_kexec_segment_t *segments) { int ret = -1; DECLARE_HYPERCALL; DECLARE_HYPERCALL_BOUNCE(segments, sizeof(*segments) * nr_segments, XC_HYPERCALL_BUFFER_BOUNCE_IN); DECLARE_HYPERCALL_BUFFER(xen_kexec_load_t, load); if ( xc_hypercall_bounce_pre(xch, segments) ) { PERROR("Could not allocate bounce buffer for kexec load hypercall"); goto out; } load = xc_hypercall_buffer_alloc(xch, load, sizeof(*load)); if ( load == NULL ) { PERROR("Could not allocate buffer for kexec load hypercall"); goto out; } load->type = type; load->arch = arch; load->entry_maddr = entry_maddr; load->nr_segments = nr_segments; set_xen_guest_handle(load->segments.h, segments); hypercall.op = __HYPERVISOR_kexec_op; hypercall.arg[0] = KEXEC_CMD_kexec_load; hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(load); ret = do_xen_hypercall(xch, &hypercall); out: xc_hypercall_buffer_free(xch, load); xc_hypercall_bounce_post(xch, segments); return ret; }
int do_memory_op(xc_interface *xch, int cmd, void *arg, size_t len) { DECLARE_HYPERCALL; DECLARE_HYPERCALL_BOUNCE(arg, len, XC_HYPERCALL_BUFFER_BOUNCE_BOTH); long ret = -EINVAL; if ( xc_hypercall_bounce_pre(xch, arg) ) { PERROR("Could not bounce memory for XENMEM hypercall"); goto out1; } hypercall.op = __HYPERVISOR_memory_op; hypercall.arg[0] = (unsigned long) cmd; hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg); ret = do_xen_hypercall(xch, &hypercall); xc_hypercall_bounce_post(xch, arg); out1: return ret; }
static int do_tmem_op(xc_interface *xch, tmem_op_t *op) { int ret; DECLARE_HYPERCALL_BOUNCE(op, sizeof(*op), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); if ( xc_hypercall_bounce_pre(xch, op) ) { PERROR("Could not bounce buffer for tmem op hypercall"); return -EFAULT; } ret = xencall1(xch->xcall, __HYPERVISOR_tmem_op, HYPERCALL_BUFFER_AS_ARG(op)); if ( ret < 0 ) { if ( errno == EACCES ) DPRINTF("tmem operation failed -- need to" " rebuild the user-space tool set?\n"); } xc_hypercall_bounce_post(xch, op); return ret; }
int xc_kexec_unload(xc_interface *xch, int type) { DECLARE_HYPERCALL_BUFFER(xen_kexec_unload_t, unload); int ret = -1; unload = xc_hypercall_buffer_alloc(xch, unload, sizeof(*unload)); if ( unload == NULL ) { PERROR("Could not alloc buffer for kexec unload hypercall"); goto out; } unload->type = type; ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op, KEXEC_CMD_kexec_unload, HYPERCALL_BUFFER_AS_ARG(unload)); out: xc_hypercall_buffer_free(xch, unload); return ret; }
int xc_kexec_exec(xc_interface *xch, int type) { DECLARE_HYPERCALL_BUFFER(xen_kexec_exec_t, exec); int ret = -1; exec = xc_hypercall_buffer_alloc(xch, exec, sizeof(*exec)); if ( exec == NULL ) { PERROR("Could not alloc bounce buffer for kexec_exec hypercall"); goto out; } exec->type = type; ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op, KEXEC_CMD_kexec, HYPERCALL_BUFFER_AS_ARG(exec)); out: xc_hypercall_buffer_free(xch, exec); return ret; }
int xc_mmuext_op( xc_interface *xch, struct mmuext_op *op, unsigned int nr_ops, uint32_t dom) { DECLARE_HYPERCALL_BOUNCE(op, nr_ops*sizeof(*op), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); long ret = -1; if ( xc_hypercall_bounce_pre(xch, op) ) { PERROR("Could not bounce memory for mmuext op hypercall"); goto out1; } ret = xencall4(xch->xcall, __HYPERVISOR_mmuext_op, HYPERCALL_BUFFER_AS_ARG(op), nr_ops, 0, dom); xc_hypercall_bounce_post(xch, op); out1: return ret; }
int xc_gnttab_op(xc_interface *xch, int cmd, void * op, int op_size, int count) { int ret = 0; DECLARE_HYPERCALL; DECLARE_HYPERCALL_BOUNCE(op, count * op_size, XC_HYPERCALL_BUFFER_BOUNCE_BOTH); if ( xc_hypercall_bounce_pre(xch, op) ) { PERROR("Could not bounce buffer for grant table op hypercall"); goto out1; } hypercall.op = __HYPERVISOR_grant_table_op; hypercall.arg[0] = cmd; hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(op); hypercall.arg[2] = count; ret = do_xen_hypercall(xch, &hypercall); xc_hypercall_bounce_post(xch, op); out1: return ret; }
int xc_acm_op(xc_interface *xch, int cmd, void *arg, unsigned long arg_size) { int ret; DECLARE_HYPERCALL; DECLARE_HYPERCALL_BUFFER(struct xen_acmctl, acmctl); acmctl = xc_hypercall_buffer_alloc(xch, acmctl, sizeof(*acmctl)); if ( acmctl == NULL ) { PERROR("Could not allocate memory for ACM OP hypercall"); return -EFAULT; } switch (cmd) { case ACMOP_setpolicy: { struct acm_setpolicy *setpolicy = (struct acm_setpolicy *)arg; memcpy(&acmctl->u.setpolicy, setpolicy, sizeof(struct acm_setpolicy)); } break; case ACMOP_getpolicy: { struct acm_getpolicy *getpolicy = (struct acm_getpolicy *)arg; memcpy(&acmctl->u.getpolicy, getpolicy, sizeof(struct acm_getpolicy)); } break; case ACMOP_dumpstats: { struct acm_dumpstats *dumpstats = (struct acm_dumpstats *)arg; memcpy(&acmctl->u.dumpstats, dumpstats, sizeof(struct acm_dumpstats)); } break; case ACMOP_getssid: { struct acm_getssid *getssid = (struct acm_getssid *)arg; memcpy(&acmctl->u.getssid, getssid, sizeof(struct acm_getssid)); } break; case ACMOP_getdecision: { struct acm_getdecision *getdecision = (struct acm_getdecision *)arg; memcpy(&acmctl->u.getdecision, getdecision, sizeof(struct acm_getdecision)); } break; case ACMOP_chgpolicy: { struct acm_change_policy *change_policy = (struct acm_change_policy *)arg; memcpy(&acmctl->u.change_policy, change_policy, sizeof(struct acm_change_policy)); } break; case ACMOP_relabeldoms: { struct acm_relabel_doms *relabel_doms = (struct acm_relabel_doms *)arg; memcpy(&acmctl->u.relabel_doms, relabel_doms, sizeof(struct acm_relabel_doms)); } break; } acmctl->cmd = cmd; acmctl->interface_version = ACM_INTERFACE_VERSION; hypercall.op = __HYPERVISOR_xsm_op; hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(acmctl); if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0) { if ( errno == EACCES ) DPRINTF("acmctl operation failed -- need to" " rebuild the user-space tool set?\n"); } switch (cmd) { case ACMOP_getdecision: { struct acm_getdecision *getdecision = (struct acm_getdecision *)arg; memcpy(getdecision, &acmctl->u.getdecision, sizeof(struct acm_getdecision)); break; } } xc_hypercall_buffer_free(xch, acmctl); return ret; }
static int xc_resource_op_multi(xc_interface *xch, uint32_t nr_ops, xc_resource_op_t *ops) { int rc, i, entries_size; xc_resource_op_t *op; multicall_entry_t *call; DECLARE_HYPERCALL_BUFFER(multicall_entry_t, call_list); xc_hypercall_buffer_array_t *platform_ops, *entries_list = NULL; call_list = xc_hypercall_buffer_alloc(xch, call_list, sizeof(*call_list) * nr_ops); if ( !call_list ) return -1; platform_ops = xc_hypercall_buffer_array_create(xch, nr_ops); if ( !platform_ops ) { rc = -1; goto out; } entries_list = xc_hypercall_buffer_array_create(xch, nr_ops); if ( !entries_list ) { rc = -1; goto out; } for ( i = 0; i < nr_ops; i++ ) { DECLARE_HYPERCALL_BUFFER(xen_platform_op_t, platform_op); DECLARE_HYPERCALL_BUFFER(xc_resource_entry_t, entries); op = ops + i; platform_op = xc_hypercall_buffer_array_alloc(xch, platform_ops, i, platform_op, sizeof(xen_platform_op_t)); if ( !platform_op ) { rc = -1; goto out; } entries_size = sizeof(xc_resource_entry_t) * op->nr_entries; entries = xc_hypercall_buffer_array_alloc(xch, entries_list, i, entries, entries_size); if ( !entries) { rc = -1; goto out; } memcpy(entries, op->entries, entries_size); call = call_list + i; call->op = __HYPERVISOR_platform_op; call->args[0] = HYPERCALL_BUFFER_AS_ARG(platform_op); platform_op->interface_version = XENPF_INTERFACE_VERSION; platform_op->cmd = XENPF_resource_op; platform_op->u.resource_op.cpu = op->cpu; platform_op->u.resource_op.nr_entries = op->nr_entries; set_xen_guest_handle(platform_op->u.resource_op.entries, entries); } rc = do_multicall_op(xch, HYPERCALL_BUFFER(call_list), nr_ops); for ( i = 0; i < nr_ops; i++ ) { DECLARE_HYPERCALL_BUFFER(xc_resource_entry_t, entries); op = ops + i; call = call_list + i; op->result = call->result; entries_size = sizeof(xc_resource_entry_t) * op->nr_entries; entries = xc_hypercall_buffer_array_get(xch, entries_list, i, entries, entries_size); memcpy(op->entries, entries, entries_size); } out: xc_hypercall_buffer_array_destroy(xch, entries_list); xc_hypercall_buffer_array_destroy(xch, platform_ops); xc_hypercall_buffer_free(xch, call_list); return rc; }