int xc_machphys_mfn_list(xc_interface *xch, unsigned long max_extents, xen_pfn_t *extent_start) { int rc; DECLARE_HYPERCALL_BOUNCE(extent_start, max_extents * sizeof(xen_pfn_t), XC_HYPERCALL_BUFFER_BOUNCE_OUT); struct xen_machphys_mfn_list xmml = { .max_extents = max_extents, }; if ( xc_hypercall_bounce_pre(xch, extent_start) ) { PERROR("Could not bounce memory for XENMEM_machphys_mfn_list hypercall"); return -1; } set_xen_guest_handle(xmml.extent_start, extent_start); rc = do_memory_op(xch, XENMEM_machphys_mfn_list, &xmml, sizeof(xmml)); if (rc || xmml.nr_extents != max_extents) rc = -1; else rc = 0; xc_hypercall_bounce_post(xch, extent_start); return rc; }
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_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; }
static int xc_memshr_memop(xc_interface *xch, domid_t domid, xen_mem_sharing_op_t *mso) { mso->domain = domid; return do_memory_op(xch, XENMEM_sharing_op, mso, sizeof(*mso)); }
int xc_memshr_audit(xc_interface *xch) { xen_mem_sharing_op_t mso; memset(&mso, 0, sizeof(mso)); mso.op = XENMEM_sharing_op_audit; return do_memory_op(xch, XENMEM_sharing_op, &mso, sizeof(mso)); }
int xc_maximum_ram_page(xc_interface *xch, unsigned long *max_mfn) { long rc = do_memory_op(xch, XENMEM_maximum_ram_page, NULL, 0); if ( rc >= 0 ) { *max_mfn = rc; rc = 0; } return rc; }
static int xc_mem_paging_memop(xc_interface *xch, domid_t domain_id, unsigned int op, uint64_t gfn, void *buffer) { xen_mem_paging_op_t mpo; memset(&mpo, 0, sizeof(mpo)); mpo.op = op; mpo.domain = domain_id; mpo.gfn = gfn; mpo.buffer = (unsigned long) buffer; return do_memory_op(xch, XENMEM_paging_op, &mpo, sizeof(mpo)); }
int xc_domain_add_to_physmap(xc_interface *xch, uint32_t domid, unsigned int space, unsigned long idx, xen_pfn_t gpfn) { struct xen_add_to_physmap xatp = { .domid = domid, .space = space, .idx = idx, .gpfn = gpfn, }; return do_memory_op(xch, XENMEM_add_to_physmap, &xatp, sizeof(xatp)); }
static int mem_write(int argc, A_CHAR *argv[]) { MEMORY_ACCESS_OPTIONS options; A_MEMZERO(&options,sizeof(options)); if (get_mem_access_options(argc,argv,&options) < 0) { return -1; } if (!(options.flags & WRITE_VALUE_OPTION)) { CONSOLE_OUTPUT("Missing Write Data\n"); return -1; } do_memory_op((void *)options.address,FALSE,options.write_val,options.width); return 0; }
static int mem_read(int argc, A_CHAR *argv[]) { MEMORY_ACCESS_OPTIONS options; int i; int incr; A_MEMZERO(&options,sizeof(options)); if (get_mem_access_options(argc,argv,&options) < 0) { return -1; } for (i = 0; i < options.count; i++) { incr = do_memory_op((void *)(options.address),TRUE,0,options.width); options.address += (A_UINT32)incr; } return 0; }
int xc_get_machine_memory_map(xc_interface *xch, struct e820entry entries[], uint32_t max_entries) { int rc; struct xen_memory_map memmap = { .nr_entries = max_entries }; DECLARE_HYPERCALL_BOUNCE(entries, sizeof(struct e820entry) * max_entries, XC_HYPERCALL_BUFFER_BOUNCE_OUT); if ( !entries || xc_hypercall_bounce_pre(xch, entries) || max_entries <= 1) return -1; set_xen_guest_handle(memmap.buffer, entries); rc = do_memory_op(xch, XENMEM_machine_memory_map, &memmap, sizeof(memmap)); xc_hypercall_bounce_post(xch, entries); return rc ? rc : memmap.nr_entries; }
int xc_domain_set_memory_map(xc_interface *xch, uint32_t domid, struct e820entry entries[], uint32_t nr_entries) { int rc; struct xen_foreign_memory_map fmap = { .domid = domid, .map = { .nr_entries = nr_entries } }; DECLARE_HYPERCALL_BOUNCE(entries, nr_entries * sizeof(struct e820entry), XC_HYPERCALL_BUFFER_BOUNCE_IN); if ( !entries || xc_hypercall_bounce_pre(xch, entries) ) return -1; set_xen_guest_handle(fmap.map.buffer, entries); rc = do_memory_op(xch, XENMEM_set_memory_map, &fmap, sizeof(fmap)); xc_hypercall_bounce_post(xch, entries); return rc; }
int xc_domain_maximum_gpfn(xc_interface *xch, domid_t domid) { return do_memory_op(xch, XENMEM_maximum_gpfn, &domid, sizeof(domid)); }
long xc_sharing_used_frames(xc_interface *xch) { return do_memory_op(xch, XENMEM_get_sharing_shared_pages, NULL, 0); }
int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid, xen_pfn_t console_gpfn, xen_pfn_t xenstore_gpfn, domid_t console_domid, domid_t xenstore_domid) { int rc; xen_pfn_t scratch_gpfn; struct xen_add_to_physmap xatp = { .domid = domid, .space = XENMAPSPACE_grant_table, .idx = 0, }; struct xen_remove_from_physmap xrfp = { .domid = domid, }; rc = xc_core_arch_get_scratch_gpfn(xch, domid, &scratch_gpfn); if ( rc < 0 ) { xc_dom_panic(xch, XC_INTERNAL_ERROR, "%s: failed to get a scratch gfn " "[errno=%d]\n", __FUNCTION__, errno); return -1; } xatp.gpfn = scratch_gpfn; xrfp.gpfn = scratch_gpfn; xc_dom_printf(xch, "%s: called, pfn=0x%"PRI_xen_pfn, __FUNCTION__, scratch_gpfn); rc = do_memory_op(xch, XENMEM_add_to_physmap, &xatp, sizeof(xatp)); if ( rc != 0 ) { xc_dom_panic(xch, XC_INTERNAL_ERROR, "%s: failed to add gnttab to physmap " "[errno=%d]\n", __FUNCTION__, errno); return -1; } rc = xc_dom_gnttab_seed(xch, domid, console_gpfn, xenstore_gpfn, console_domid, xenstore_domid); if (rc != 0) { xc_dom_panic(xch, XC_INTERNAL_ERROR, "%s: failed to seed gnttab entries\n", __FUNCTION__); (void) do_memory_op(xch, XENMEM_remove_from_physmap, &xrfp, sizeof(xrfp)); return -1; } rc = do_memory_op(xch, XENMEM_remove_from_physmap, &xrfp, sizeof(xrfp)); if (rc != 0) { xc_dom_panic(xch, XC_INTERNAL_ERROR, "%s: failed to remove gnttab from physmap " "[errno=%d]\n", __FUNCTION__, errno); return -1; } return 0; } int xc_dom_gnttab_init(struct xc_dom_image *dom) { if ( xc_dom_feature_translated(dom) ) { return xc_dom_gnttab_hvm_seed(dom->xch, dom->guest_domid, dom->console_pfn, dom->xenstore_pfn, dom->console_domid, dom->xenstore_domid); } else { return xc_dom_gnttab_seed(dom->xch, dom->guest_domid, xc_dom_p2m_host(dom, dom->console_pfn), xc_dom_p2m_host(dom, dom->xenstore_pfn), dom->console_domid, dom->xenstore_domid); } }
long xc_maximum_ram_page(xc_interface *xch) { return do_memory_op(xch, XENMEM_maximum_ram_page, NULL, 0); }