int xc_numainfo(xc_interface *xch, unsigned *max_nodes, xc_meminfo_t *meminfo, uint32_t *distance) { int ret; DECLARE_SYSCTL; DECLARE_HYPERCALL_BOUNCE(meminfo, *max_nodes * sizeof(*meminfo), XC_HYPERCALL_BUFFER_BOUNCE_OUT); DECLARE_HYPERCALL_BOUNCE(distance, *max_nodes * *max_nodes * sizeof(*distance), XC_HYPERCALL_BUFFER_BOUNCE_OUT); if ( (ret = xc_hypercall_bounce_pre(xch, meminfo)) ) goto out; if ((ret = xc_hypercall_bounce_pre(xch, distance)) ) goto out; sysctl.u.numainfo.num_nodes = *max_nodes; set_xen_guest_handle(sysctl.u.numainfo.meminfo, meminfo); set_xen_guest_handle(sysctl.u.numainfo.distance, distance); sysctl.cmd = XEN_SYSCTL_numainfo; if ( (ret = do_sysctl(xch, &sysctl)) != 0 ) goto out; *max_nodes = sysctl.u.numainfo.num_nodes; out: xc_hypercall_bounce_post(xch, meminfo); xc_hypercall_bounce_post(xch, distance); return ret; }
int xc_pm_get_cxstat(xc_interface *xch, int cpuid, struct xc_cx_stat *cxpt) { DECLARE_SYSCTL; DECLARE_NAMED_HYPERCALL_BOUNCE(triggers, cxpt->triggers, cxpt->nr * sizeof(*cxpt->triggers), XC_HYPERCALL_BUFFER_BOUNCE_OUT); DECLARE_NAMED_HYPERCALL_BOUNCE(residencies, cxpt->residencies, cxpt->nr * sizeof(*cxpt->residencies), XC_HYPERCALL_BUFFER_BOUNCE_OUT); DECLARE_NAMED_HYPERCALL_BOUNCE(pc, cxpt->pc, cxpt->nr_pc * sizeof(*cxpt->pc), XC_HYPERCALL_BUFFER_BOUNCE_OUT); DECLARE_NAMED_HYPERCALL_BOUNCE(cc, cxpt->cc, cxpt->nr_cc * sizeof(*cxpt->cc), XC_HYPERCALL_BUFFER_BOUNCE_OUT); int ret = -1; if ( xc_hypercall_bounce_pre(xch, triggers) ) goto unlock_0; if ( xc_hypercall_bounce_pre(xch, residencies) ) goto unlock_1; if ( xc_hypercall_bounce_pre(xch, pc) ) goto unlock_2; if ( xc_hypercall_bounce_pre(xch, cc) ) goto unlock_3; sysctl.cmd = XEN_SYSCTL_get_pmstat; sysctl.u.get_pmstat.type = PMSTAT_get_cxstat; sysctl.u.get_pmstat.cpuid = cpuid; sysctl.u.get_pmstat.u.getcx.nr = cxpt->nr; sysctl.u.get_pmstat.u.getcx.nr_pc = cxpt->nr_pc; sysctl.u.get_pmstat.u.getcx.nr_cc = cxpt->nr_cc; set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.triggers, triggers); set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.residencies, residencies); set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.pc, pc); set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.cc, cc); if ( (ret = xc_sysctl(xch, &sysctl)) ) goto unlock_4; cxpt->nr = sysctl.u.get_pmstat.u.getcx.nr; cxpt->last = sysctl.u.get_pmstat.u.getcx.last; cxpt->idle_time = sysctl.u.get_pmstat.u.getcx.idle_time; cxpt->nr_pc = sysctl.u.get_pmstat.u.getcx.nr_pc; cxpt->nr_cc = sysctl.u.get_pmstat.u.getcx.nr_cc; unlock_4: xc_hypercall_bounce_post(xch, cc); unlock_3: xc_hypercall_bounce_post(xch, pc); unlock_2: xc_hypercall_bounce_post(xch, residencies); unlock_1: xc_hypercall_bounce_post(xch, triggers); unlock_0: return ret; }
int xencomm_hypercall_memory_op(unsigned int cmd, void *arg) { GUEST_HANDLE(xen_pfn_t) extent_start_va[2] = { {NULL}, {NULL} }; struct xen_memory_reservation *xmr = NULL; int rc; struct xencomm_handle *desc; unsigned int argsize; XENCOMM_MINI_ALIGNED(xc_area, 2); switch (cmd) { case XENMEM_increase_reservation: case XENMEM_decrease_reservation: case XENMEM_populate_physmap: xmr = (struct xen_memory_reservation *)arg; set_xen_guest_handle(extent_start_va[0], xen_guest_handle(xmr->extent_start)); argsize = sizeof(*xmr); rc = xencommize_memory_reservation(xc_area, xmr); if (rc) return rc; xc_area++; break; case XENMEM_maximum_ram_page: argsize = 0; break; case XENMEM_add_to_physmap: argsize = sizeof(struct xen_add_to_physmap); break; default: printk(KERN_DEBUG "%s: unknown memory op %d\n", __func__, cmd); return -ENOSYS; } desc = xencomm_map_no_alloc(arg, argsize); if (desc == NULL) return -EINVAL; rc = xencomm_arch_hypercall_memory_op(cmd, desc); switch (cmd) { case XENMEM_increase_reservation: case XENMEM_decrease_reservation: case XENMEM_populate_physmap: set_xen_guest_handle(xmr->extent_start, xen_guest_handle(extent_start_va[0])); break; } return rc; }
int xc_perfc_reset(xc_interface *xch) { DECLARE_SYSCTL; sysctl.cmd = XEN_SYSCTL_perfc_op; sysctl.u.perfc_op.cmd = XEN_SYSCTL_PERFCOP_reset; set_xen_guest_handle(sysctl.u.perfc_op.desc, HYPERCALL_BUFFER_NULL); set_xen_guest_handle(sysctl.u.perfc_op.val, HYPERCALL_BUFFER_NULL); return do_sysctl(xch, &sysctl); }
int xc_pm_get_pxstat(xc_interface *xch, int cpuid, struct xc_px_stat *pxpt) { DECLARE_SYSCTL; /* Sizes unknown until xc_pm_get_max_px */ DECLARE_NAMED_HYPERCALL_BOUNCE(trans, pxpt->trans_pt, 0, XC_HYPERCALL_BUFFER_BOUNCE_BOTH); DECLARE_NAMED_HYPERCALL_BOUNCE(pt, pxpt->pt, 0, XC_HYPERCALL_BUFFER_BOUNCE_BOTH); int max_px, ret; if ( !pxpt->trans_pt || !pxpt->pt ) { errno = EINVAL; return -1; } if ( (ret = xc_pm_get_max_px(xch, cpuid, &max_px)) != 0) return ret; HYPERCALL_BOUNCE_SET_SIZE(trans, max_px * max_px * sizeof(uint64_t)); HYPERCALL_BOUNCE_SET_SIZE(pt, max_px * sizeof(struct xc_px_val)); if ( xc_hypercall_bounce_pre(xch, trans) ) return ret; if ( xc_hypercall_bounce_pre(xch, pt) ) { xc_hypercall_bounce_post(xch, trans); return ret; } sysctl.cmd = XEN_SYSCTL_get_pmstat; sysctl.u.get_pmstat.type = PMSTAT_get_pxstat; sysctl.u.get_pmstat.cpuid = cpuid; sysctl.u.get_pmstat.u.getpx.total = max_px; set_xen_guest_handle(sysctl.u.get_pmstat.u.getpx.trans_pt, trans); set_xen_guest_handle(sysctl.u.get_pmstat.u.getpx.pt, pt); ret = xc_sysctl(xch, &sysctl); if ( ret ) { xc_hypercall_bounce_post(xch, trans); xc_hypercall_bounce_post(xch, pt); return ret; } pxpt->total = sysctl.u.get_pmstat.u.getpx.total; pxpt->usable = sysctl.u.get_pmstat.u.getpx.usable; pxpt->last = sysctl.u.get_pmstat.u.getpx.last; pxpt->cur = sysctl.u.get_pmstat.u.getpx.cur; xc_hypercall_bounce_post(xch, trans); xc_hypercall_bounce_post(xch, pt); return ret; }
int xc_livepatch_upload(xc_interface *xch, char *name, unsigned char *payload, uint32_t size) { int rc; DECLARE_SYSCTL; DECLARE_HYPERCALL_BUFFER(char, local); DECLARE_HYPERCALL_BOUNCE(name, 0 /* later */, XC_HYPERCALL_BUFFER_BOUNCE_IN); xen_livepatch_name_t def_name = { .pad = { 0, 0, 0 } }; if ( !name || !payload ) { errno = EINVAL; return -1; } def_name.size = strlen(name) + 1; if ( def_name.size > XEN_LIVEPATCH_NAME_SIZE ) { errno = EINVAL; return -1; } HYPERCALL_BOUNCE_SET_SIZE(name, def_name.size); if ( xc_hypercall_bounce_pre(xch, name) ) return -1; local = xc_hypercall_buffer_alloc(xch, local, size); if ( !local ) { xc_hypercall_bounce_post(xch, name); return -1; } memcpy(local, payload, size); sysctl.cmd = XEN_SYSCTL_livepatch_op; sysctl.u.livepatch.cmd = XEN_SYSCTL_LIVEPATCH_UPLOAD; sysctl.u.livepatch.pad = 0; sysctl.u.livepatch.u.upload.size = size; set_xen_guest_handle(sysctl.u.livepatch.u.upload.payload, local); sysctl.u.livepatch.u.upload.name = def_name; set_xen_guest_handle(sysctl.u.livepatch.u.upload.name.name, name); rc = do_sysctl(xch, &sysctl); xc_hypercall_buffer_free(xch, local); xc_hypercall_bounce_post(xch, name); return rc; }
int __init bind_virq_for_mce(void) { int ret; xen_mc_t mc_op; g_mi = kmalloc(sizeof(*g_mi), GFP_KERNEL); if (!g_mi) return -ENOMEM; /* fetch physical CPU count */ mc_op.cmd = XEN_MC_physcpuinfo; mc_op.interface_version = XEN_MCA_INTERFACE_VERSION; set_xen_guest_handle(mc_op.u.mc_physcpuinfo.info, NULL); ret = HYPERVISOR_mca(&mc_op); if (ret) { printk(KERN_ERR "MCE: Failed to get physical CPU count\n"); kfree(g_mi); return ret; } /* fetch CPU physical info for later reference */ ncpus = mc_op.u.mc_physcpuinfo.ncpus; g_physinfo = kmalloc(sizeof(*g_physinfo) * ncpus, GFP_KERNEL); if (!g_physinfo) { kfree(g_mi); return -ENOMEM; } set_xen_guest_handle(mc_op.u.mc_physcpuinfo.info, g_physinfo); ret = HYPERVISOR_mca(&mc_op); if (ret) { printk(KERN_ERR "MCE: Failed to get physical CPUs' info\n"); kfree(g_mi); kfree(g_physinfo); return ret; } ret = bind_virq_to_irqhandler(VIRQ_MCA, 0, mce_dom0_interrupt, 0, "mce", NULL); if (ret < 0) { printk(KERN_ERR "MCE: Failed to bind vIRQ for Dom0\n"); kfree(g_mi); kfree(g_physinfo); return ret; } /* Log the machine checks left over from the previous reset. */ mce_dom0_interrupt(VIRQ_MCA, NULL); return 0; }
static PyObject *chgpolicy(PyObject *self, PyObject *args) { struct acm_change_policy chgpolicy; int xc_handle, rc; char *bin_pol = NULL, *del_arr = NULL, *chg_arr = NULL; int bin_pol_len = 0, del_arr_len = 0, chg_arr_len = 0; uint errarray_mbrs = 20 * 2; uint32_t error_array[errarray_mbrs]; PyObject *result; uint len; memset(&chgpolicy, 0x0, sizeof(chgpolicy)); if (!PyArg_ParseTuple(args, "s#s#s#" ,&bin_pol, &bin_pol_len, &del_arr, &del_arr_len, &chg_arr, &chg_arr_len)) { PyErr_SetString(PyExc_TypeError, bad_arg); return NULL; } chgpolicy.policy_pushcache_size = bin_pol_len; chgpolicy.delarray_size = del_arr_len; chgpolicy.chgarray_size = chg_arr_len; chgpolicy.errarray_size = sizeof(error_array); set_xen_guest_handle(chgpolicy.policy_pushcache, bin_pol); set_xen_guest_handle(chgpolicy.del_array, del_arr); set_xen_guest_handle(chgpolicy.chg_array, chg_arr); set_xen_guest_handle(chgpolicy.err_array, error_array); if ((xc_handle = xc_interface_open()) <= 0) { PyErr_SetString(PyExc_IOError, ctrlif_op); return NULL; } rc = xc_acm_op(xc_handle, ACMOP_chgpolicy, &chgpolicy, sizeof(chgpolicy)); xc_interface_close(xc_handle); /* only pass the filled error codes */ for (len = 0; (len + 1) < errarray_mbrs; len += 2) { if (error_array[len] == 0) { len *= sizeof(error_array[0]); break; } } result = Py_BuildValue("is#", rc, error_array, len); return result; }
int xc_perfc_query(xc_interface *xch, struct xc_hypercall_buffer *desc, struct xc_hypercall_buffer *val) { DECLARE_SYSCTL; DECLARE_HYPERCALL_BUFFER_ARGUMENT(desc); DECLARE_HYPERCALL_BUFFER_ARGUMENT(val); sysctl.cmd = XEN_SYSCTL_perfc_op; sysctl.u.perfc_op.cmd = XEN_SYSCTL_PERFCOP_query; set_xen_guest_handle(sysctl.u.perfc_op.desc, desc); set_xen_guest_handle(sysctl.u.perfc_op.val, val); return do_sysctl(xch, &sysctl); }
static int gnttab_map(unsigned int start_idx, unsigned int end_idx) { struct gnttab_setup_table setup; unsigned long *frames; unsigned int nr_gframes = end_idx + 1; int rc; frames = kmalloc(nr_gframes * sizeof(unsigned long), GFP_ATOMIC); if (!frames) return -ENOMEM; setup.dom = DOMID_SELF; setup.nr_frames = nr_gframes; set_xen_guest_handle(setup.frame_list, frames); rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1); if (rc == -ENOSYS) { kfree(frames); return -ENOSYS; } BUG_ON(rc || setup.status); rc = arch_gnttab_map_shared(frames, nr_gframes, max_nr_grant_frames(), &shared); BUG_ON(rc); kfree(frames); return 0; }
int xc_flask_context_to_sid(xc_interface *xch, char *buf, uint32_t size, uint32_t *sid) { int err; DECLARE_FLASK_OP; DECLARE_HYPERCALL_BOUNCE(buf, size, XC_HYPERCALL_BUFFER_BOUNCE_IN); if ( xc_hypercall_bounce_pre(xch, buf) ) { PERROR("Could not bounce memory for flask op hypercall"); return -1; } op.cmd = FLASK_CONTEXT_TO_SID; op.u.sid_context.size = size; set_xen_guest_handle(op.u.sid_context.context, buf); err = xc_flask_op(xch, &op); if ( !err ) *sid = op.u.sid_context.sid; xc_hypercall_bounce_post(xch, buf); return err; }
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_domain_getinfolist(int xc_handle, uint32_t first_domain, unsigned int max_domains, xc_domaininfo_t *info) { int ret = 0; DECLARE_SYSCTL; if ( lock_pages(info, max_domains*sizeof(xc_domaininfo_t)) != 0 ) return -1; sysctl.cmd = XEN_SYSCTL_getdomaininfolist; sysctl.u.getdomaininfolist.first_domain = first_domain; sysctl.u.getdomaininfolist.max_domains = max_domains; set_xen_guest_handle(sysctl.u.getdomaininfolist.buffer, info); if ( xc_sysctl(xc_handle, &sysctl) < 0 ) ret = -1; else ret = sysctl.u.getdomaininfolist.num_domains; unlock_pages(info, max_domains*sizeof(xc_domaininfo_t)); return ret; }
int xc_domain_memory_increase_reservation(int xc_handle, uint32_t domid, unsigned long nr_extents, unsigned int extent_order, unsigned int mem_flags, xen_pfn_t *extent_start) { int err; struct xen_memory_reservation reservation = { .nr_extents = nr_extents, .extent_order = extent_order, .mem_flags = mem_flags, .domid = domid }; /* may be NULL */ set_xen_guest_handle(reservation.extent_start, extent_start); err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation); if ( err == nr_extents ) return 0; if ( err >= 0 ) { DPRINTF("Failed allocation for dom %d: " "%ld extents of order %d, mem_flags %x\n", domid, nr_extents, extent_order, mem_flags); errno = ENOMEM; err = -1; } return err; }
int xc_readconsolering(int xc_handle, char **pbuffer, unsigned int *pnr_chars, int clear, int incremental, uint32_t *pindex) { int ret; DECLARE_SYSCTL; char *buffer = *pbuffer; unsigned int nr_chars = *pnr_chars; sysctl.cmd = XEN_SYSCTL_readconsole; set_xen_guest_handle(sysctl.u.readconsole.buffer, buffer); sysctl.u.readconsole.count = nr_chars; sysctl.u.readconsole.clear = clear; sysctl.u.readconsole.incremental = 0; if ( pindex ) { sysctl.u.readconsole.index = *pindex; sysctl.u.readconsole.incremental = incremental; } if ( (ret = lock_pages(buffer, nr_chars)) != 0 ) return ret; if ( (ret = do_sysctl(xc_handle, &sysctl)) == 0 ) { *pnr_chars = sysctl.u.readconsole.count; if ( pindex ) *pindex = sysctl.u.readconsole.index; } unlock_pages(buffer, nr_chars); return ret; }
int xc_domain_decrease_reservation(xc_interface *xch, uint32_t domid, unsigned long nr_extents, unsigned int extent_order, xen_pfn_t *extent_start) { int err; DECLARE_HYPERCALL_BOUNCE(extent_start, nr_extents * sizeof(*extent_start), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); struct xen_memory_reservation reservation = { .nr_extents = nr_extents, .extent_order = extent_order, .mem_flags = 0, .domid = domid }; if ( extent_start == NULL ) { DPRINTF("decrease_reservation extent_start is NULL!\n"); errno = EINVAL; return -1; } if ( xc_hypercall_bounce_pre(xch, extent_start) ) { PERROR("Could not bounce memory for XENMEM_decrease_reservation hypercall"); return -1; } set_xen_guest_handle(reservation.extent_start, extent_start); err = do_memory_op(xch, XENMEM_decrease_reservation, &reservation, sizeof(reservation)); xc_hypercall_bounce_post(xch, extent_start); return err; } int xc_domain_decrease_reservation_exact(xc_interface *xch, uint32_t domid, unsigned long nr_extents, unsigned int extent_order, xen_pfn_t *extent_start) { int err; err = xc_domain_decrease_reservation(xch, domid, nr_extents, extent_order, extent_start); if ( err == nr_extents ) return 0; if ( err >= 0 ) { DPRINTF("Failed deallocation for dom %d: %ld extents of order %d\n", domid, nr_extents, extent_order); errno = EINVAL; err = -1; } return err; }
/* Get just one element of the HVM guest context. * size must be >= HVM_SAVE_LENGTH(type) */ int xc_domain_hvm_getcontext_partial(xc_interface *xch, uint32_t domid, uint16_t typecode, uint16_t instance, void *ctxt_buf, uint32_t size) { int ret; DECLARE_DOMCTL; DECLARE_HYPERCALL_BOUNCE(ctxt_buf, size, XC_HYPERCALL_BUFFER_BOUNCE_OUT); if ( !ctxt_buf || xc_hypercall_bounce_pre(xch, ctxt_buf) ) return -1; domctl.cmd = XEN_DOMCTL_gethvmcontext_partial; domctl.domain = (domid_t) domid; domctl.u.hvmcontext_partial.type = typecode; domctl.u.hvmcontext_partial.instance = instance; set_xen_guest_handle(domctl.u.hvmcontext_partial.buffer, ctxt_buf); ret = do_domctl(xch, &domctl); if ( ctxt_buf ) xc_hypercall_bounce_post(xch, ctxt_buf); return ret ? -1 : 0; }
static int check_mfn(int nr) { struct xen_memory_reservation reservation = { .extent_order = 0, .domid = DOMID_SELF }; if (likely(alloc_index >= nr)) return 0; set_xen_guest_handle(reservation.extent_start, mfn_list + alloc_index); reservation.nr_extents = MAX_MFN_ALLOC - alloc_index; alloc_index += HYPERVISOR_memory_op(XENMEM_increase_reservation, &reservation); return alloc_index >= nr ? 0 : -ENOMEM; } static inline void maybe_schedule_tx_action(void) { smp_mb(); if ((NR_PENDING_REQS < (MAX_PENDING_REQS/2)) && !list_empty(&net_schedule_list)) tasklet_schedule(&net_tx_tasklet); }
int xc_vcpu_setaffinity(int xc_handle, uint32_t domid, int vcpu, uint64_t cpumap) { DECLARE_DOMCTL; int ret = -1; uint8_t local[sizeof (cpumap)]; domctl.cmd = XEN_DOMCTL_setvcpuaffinity; domctl.domain = (domid_t)domid; domctl.u.vcpuaffinity.vcpu = vcpu; bitmap_64_to_byte(local, &cpumap, sizeof(cpumap) * 8); set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local); domctl.u.vcpuaffinity.cpumap.nr_cpus = sizeof(cpumap) * 8; if ( lock_pages(local, sizeof(local)) != 0 ) { PERROR("Could not lock memory for Xen hypercall"); goto out; } ret = do_domctl(xc_handle, &domctl); unlock_pages(local, sizeof(local)); out: return ret; }
int xc_get_device_group( int xc_handle, uint32_t domid, uint32_t machine_bdf, uint32_t max_sdevs, uint32_t *num_sdevs, uint32_t *sdev_array) { int rc; DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_get_device_group; domctl.domain = (domid_t)domid; domctl.u.get_device_group.machine_bdf = machine_bdf; domctl.u.get_device_group.max_sdevs = max_sdevs; set_xen_guest_handle(domctl.u.get_device_group.sdev_array, sdev_array); if ( lock_pages(sdev_array, max_sdevs * sizeof(*sdev_array)) != 0 ) { PERROR("Could not lock memory for xc_get_device_group\n"); return -ENOMEM; } rc = do_domctl(xc_handle, &domctl); unlock_pages(sdev_array, max_sdevs * sizeof(*sdev_array)); *num_sdevs = domctl.u.get_device_group.num_sdevs; return rc; }
int xc_vcpu_setcontext(int xc_handle, uint32_t domid, uint32_t vcpu, vcpu_guest_context_any_t *ctxt) { DECLARE_DOMCTL; int rc; size_t sz = sizeof(vcpu_guest_context_any_t); if (ctxt == NULL) { errno = EINVAL; return -1; } domctl.cmd = XEN_DOMCTL_setvcpucontext; domctl.domain = domid; domctl.u.vcpucontext.vcpu = vcpu; set_xen_guest_handle(domctl.u.vcpucontext.ctxt, &ctxt->c); if ( (rc = lock_pages(ctxt, sz)) != 0 ) return rc; rc = do_domctl(xc_handle, &domctl); unlock_pages(ctxt, sz); return rc; }
int xc_get_cpu_featureset(xc_interface *xch, uint32_t index, uint32_t *nr_features, uint32_t *featureset) { DECLARE_SYSCTL; DECLARE_HYPERCALL_BOUNCE(featureset, *nr_features * sizeof(*featureset), XC_HYPERCALL_BUFFER_BOUNCE_OUT); int ret; if ( xc_hypercall_bounce_pre(xch, featureset) ) return -1; sysctl.cmd = XEN_SYSCTL_get_cpu_featureset; sysctl.u.cpu_featureset.index = index; sysctl.u.cpu_featureset.nr_features = *nr_features; set_xen_guest_handle(sysctl.u.cpu_featureset.features, featureset); ret = do_sysctl(xch, &sysctl); xc_hypercall_bounce_post(xch, featureset); if ( !ret ) *nr_features = sysctl.u.cpu_featureset.nr_features; return ret; }
int xc_hvm_track_dirty_vram( int xc_handle, domid_t dom, uint64_t first_pfn, uint64_t nr, unsigned long *dirty_bitmap) { DECLARE_HYPERCALL; struct xen_hvm_track_dirty_vram arg; int rc; hypercall.op = __HYPERVISOR_hvm_op; hypercall.arg[0] = HVMOP_track_dirty_vram; hypercall.arg[1] = (unsigned long)&arg; arg.domid = dom; arg.first_pfn = first_pfn; arg.nr = nr; set_xen_guest_handle(arg.dirty_bitmap, (uint8_t *)dirty_bitmap); if ( (rc = lock_pages(&arg, sizeof(arg))) != 0 ) { PERROR("Could not lock memory"); return rc; } rc = do_xen_hypercall(xc_handle, &hypercall); unlock_pages(&arg, sizeof(arg)); return rc; }
/* Get just one element of the HVM guest context. * size must be >= HVM_SAVE_LENGTH(type) */ int xc_domain_hvm_getcontext_partial(int xc_handle, uint32_t domid, uint16_t typecode, uint16_t instance, void *ctxt_buf, uint32_t size) { int ret; DECLARE_DOMCTL; if ( !ctxt_buf ) return -EINVAL; domctl.cmd = XEN_DOMCTL_gethvmcontext_partial; domctl.domain = (domid_t) domid; domctl.u.hvmcontext_partial.type = typecode; domctl.u.hvmcontext_partial.instance = instance; set_xen_guest_handle(domctl.u.hvmcontext_partial.buffer, ctxt_buf); if ( (ret = lock_pages(ctxt_buf, size)) != 0 ) return ret; ret = do_domctl(xc_handle, &domctl); if ( ctxt_buf ) unlock_pages(ctxt_buf, size); return ret ? -1 : 0; }
int xc_domain_getinfolist(xc_interface *xch, uint32_t first_domain, unsigned int max_domains, xc_domaininfo_t *info) { int ret = 0; DECLARE_SYSCTL; DECLARE_HYPERCALL_BOUNCE(info, max_domains*sizeof(*info), XC_HYPERCALL_BUFFER_BOUNCE_OUT); if ( xc_hypercall_bounce_pre(xch, info) ) return -1; sysctl.cmd = XEN_SYSCTL_getdomaininfolist; sysctl.u.getdomaininfolist.first_domain = first_domain; sysctl.u.getdomaininfolist.max_domains = max_domains; set_xen_guest_handle(sysctl.u.getdomaininfolist.buffer, info); if ( xc_sysctl(xch, &sysctl) < 0 ) ret = -1; else ret = sysctl.u.getdomaininfolist.num_domains; xc_hypercall_bounce_post(xch, info); return ret; }
int xc_shadow_control(int xc_handle, uint32_t domid, unsigned int sop, unsigned long *dirty_bitmap, unsigned long pages, unsigned long *mb, uint32_t mode, xc_shadow_op_stats_t *stats) { int rc; DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_shadow_op; domctl.domain = (domid_t)domid; domctl.u.shadow_op.op = sop; domctl.u.shadow_op.pages = pages; domctl.u.shadow_op.mb = mb ? *mb : 0; domctl.u.shadow_op.mode = mode; set_xen_guest_handle(domctl.u.shadow_op.dirty_bitmap, (uint8_t *)dirty_bitmap); rc = do_domctl(xc_handle, &domctl); if ( stats ) memcpy(stats, &domctl.u.shadow_op.stats, sizeof(xc_shadow_op_stats_t)); if ( mb ) *mb = domctl.u.shadow_op.mb; return (rc == 0) ? domctl.u.shadow_op.pages : rc; }
int xc_domain_get_tsc_info(xc_interface *xch, uint32_t domid, uint32_t *tsc_mode, uint64_t *elapsed_nsec, uint32_t *gtsc_khz, uint32_t *incarnation) { int rc; DECLARE_DOMCTL; DECLARE_HYPERCALL_BUFFER(xen_guest_tsc_info_t, info); info = xc_hypercall_buffer_alloc(xch, info, sizeof(*info)); if ( info == NULL ) return -ENOMEM; domctl.cmd = XEN_DOMCTL_gettscinfo; domctl.domain = (domid_t)domid; set_xen_guest_handle(domctl.u.tsc_info.out_info, info); rc = do_domctl(xch, &domctl); if ( rc == 0 ) { *tsc_mode = info->tsc_mode; *elapsed_nsec = info->elapsed_nsec; *gtsc_khz = info->gtsc_khz; *incarnation = info->incarnation; } xc_hypercall_buffer_free(xch, info); return rc; }
int xc_readconsolering(xc_interface *xch, char *buffer, unsigned int *pnr_chars, int clear, int incremental, uint32_t *pindex) { int ret; unsigned int nr_chars = *pnr_chars; DECLARE_SYSCTL; DECLARE_HYPERCALL_BOUNCE(buffer, nr_chars, XC_HYPERCALL_BUFFER_BOUNCE_OUT); if ( xc_hypercall_bounce_pre(xch, buffer) ) return -1; sysctl.cmd = XEN_SYSCTL_readconsole; set_xen_guest_handle(sysctl.u.readconsole.buffer, buffer); sysctl.u.readconsole.count = nr_chars; sysctl.u.readconsole.clear = clear; sysctl.u.readconsole.incremental = 0; if ( pindex ) { sysctl.u.readconsole.index = *pindex; sysctl.u.readconsole.incremental = incremental; } if ( (ret = do_sysctl(xch, &sysctl)) == 0 ) { *pnr_chars = sysctl.u.readconsole.count; if ( pindex ) *pindex = sysctl.u.readconsole.index; } xc_hypercall_bounce_post(xch, buffer); return ret; }
int xc_domain_populate_physmap(xc_interface *xch, uint32_t domid, unsigned long nr_extents, unsigned int extent_order, unsigned int mem_flags, xen_pfn_t *extent_start) { int err; DECLARE_HYPERCALL_BOUNCE(extent_start, nr_extents * sizeof(*extent_start), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); struct xen_memory_reservation reservation = { .nr_extents = nr_extents, .extent_order = extent_order, .mem_flags = mem_flags, .domid = domid }; if ( xc_hypercall_bounce_pre(xch, extent_start) ) { PERROR("Could not bounce memory for XENMEM_populate_physmap hypercall"); return -1; } set_xen_guest_handle(reservation.extent_start, extent_start); err = do_memory_op(xch, XENMEM_populate_physmap, &reservation, sizeof(reservation)); xc_hypercall_bounce_post(xch, extent_start); return err; }
int xc_cputopoinfo(xc_interface *xch, unsigned *max_cpus, xc_cputopo_t *cputopo) { int ret; DECLARE_SYSCTL; DECLARE_HYPERCALL_BOUNCE(cputopo, *max_cpus * sizeof(*cputopo), XC_HYPERCALL_BUFFER_BOUNCE_OUT); if ( (ret = xc_hypercall_bounce_pre(xch, cputopo)) ) goto out; sysctl.u.cputopoinfo.num_cpus = *max_cpus; set_xen_guest_handle(sysctl.u.cputopoinfo.cputopo, cputopo); sysctl.cmd = XEN_SYSCTL_cputopoinfo; if ( (ret = do_sysctl(xch, &sysctl)) != 0 ) goto out; *max_cpus = sysctl.u.cputopoinfo.num_cpus; out: xc_hypercall_bounce_post(xch, cputopo); return ret; }