diff --git a/tools/helpers/init-dom0less.c b/tools/helpers/init-dom0less.c index fee93459c4..2b51965fa7 100644 --- a/tools/helpers/init-dom0less.c +++ b/tools/helpers/init-dom0less.c @@ -16,30 +16,18 @@ #include "init-dom-json.h" -#define XENSTORE_PFN_OFFSET 1 #define STR_MAX_LENGTH 128 -static int alloc_xs_page(struct xc_interface_core *xch, - libxl_dominfo *info, - uint64_t *xenstore_pfn) +static int get_xs_page(struct xc_interface_core *xch, libxl_dominfo *info, + uint64_t *xenstore_pfn) { int rc; - const xen_pfn_t base = GUEST_MAGIC_BASE >> XC_PAGE_SHIFT; - xen_pfn_t p2m = (GUEST_MAGIC_BASE >> XC_PAGE_SHIFT) + XENSTORE_PFN_OFFSET; - rc = xc_domain_setmaxmem(xch, info->domid, - info->max_memkb + (XC_PAGE_SIZE/1024)); - if (rc < 0) - return rc; - - rc = xc_domain_populate_physmap_exact(xch, info->domid, 1, 0, 0, &p2m); - if (rc < 0) - return rc; - - *xenstore_pfn = base + XENSTORE_PFN_OFFSET; - rc = xc_clear_domain_page(xch, info->domid, *xenstore_pfn); - if (rc < 0) - return rc; + rc = xc_hvm_param_get(xch, info->domid, HVM_PARAM_STORE_PFN, xenstore_pfn); + if (rc < 0) { + printf("Failed to get HVM_PARAM_STORE_PFN\n"); + return 1; + } return 0; } @@ -100,6 +88,7 @@ static bool do_xs_write_vm(struct xs_handle *xsh, xs_transaction_t t, */ static int create_xenstore(struct xs_handle *xsh, libxl_dominfo *info, libxl_uuid uuid, + uint64_t xenstore_pfn, evtchn_port_t xenstore_port) { domid_t domid; @@ -145,8 +134,7 @@ static int create_xenstore(struct xs_handle *xsh, rc = snprintf(target_memkb_str, STR_MAX_LENGTH, "%"PRIu64, info->current_memkb); if (rc < 0 || rc >= STR_MAX_LENGTH) return rc; - rc = snprintf(ring_ref_str, STR_MAX_LENGTH, "%lld", - (GUEST_MAGIC_BASE >> XC_PAGE_SHIFT) + XENSTORE_PFN_OFFSET); + rc = snprintf(ring_ref_str, STR_MAX_LENGTH, "%"PRIu64, xenstore_pfn); if (rc < 0 || rc >= STR_MAX_LENGTH) return rc; rc = snprintf(xenstore_port_str, STR_MAX_LENGTH, "%u", xenstore_port); @@ -230,7 +218,6 @@ static int init_domain(struct xs_handle *xsh, libxl_uuid uuid; uint64_t xenstore_evtchn, xenstore_pfn; int rc; - struct xenstore_domain_interface *intf; printf("Init dom0less domain: %u\n", info->domid); @@ -245,21 +232,12 @@ static int init_domain(struct xs_handle *xsh, if (!xenstore_evtchn) return 0; - /* Alloc xenstore page */ - if (alloc_xs_page(xch, info, &xenstore_pfn) != 0) { - printf("Error on alloc magic pages\n"); + /* Get xenstore page */ + if (get_xs_page(xch, info, &xenstore_pfn) != 0) { + printf("Error on getting xenstore page\n"); return 1; } - intf = xenforeignmemory_map(xfh, info->domid, PROT_READ | PROT_WRITE, 1, - &xenstore_pfn, NULL); - if (!intf) { - printf("Error mapping xenstore page\n"); - return 1; - } - intf->connection = XENSTORE_RECONNECT; - xenforeignmemory_unmap(xfh, intf, 1); - rc = xc_dom_gnttab_seed(xch, info->domid, true, (xen_pfn_t)-1, xenstore_pfn, 0, 0); if (rc) @@ -272,19 +250,11 @@ static int init_domain(struct xs_handle *xsh, if (rc) err(1, "gen_stub_json_config"); - /* Now everything is ready: set HVM_PARAM_STORE_PFN */ - rc = xc_hvm_param_set(xch, info->domid, HVM_PARAM_STORE_PFN, - xenstore_pfn); - if (rc < 0) - return rc; - - rc = create_xenstore(xsh, info, uuid, xenstore_evtchn); + rc = create_xenstore(xsh, info, uuid, xenstore_pfn, xenstore_evtchn); if (rc) err(1, "writing to xenstore"); - rc = xs_introduce_domain(xsh, info->domid, - (GUEST_MAGIC_BASE >> XC_PAGE_SHIFT) + XENSTORE_PFN_OFFSET, - xenstore_evtchn); + rc = xs_introduce_domain(xsh, info->domid, xenstore_pfn, xenstore_evtchn); if (!rc) err(1, "xs_introduce_domain"); return 0; diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c index 49d1f14d65..6c51f91999 100644 --- a/xen/arch/arm/dom0less-build.c +++ b/xen/arch/arm/dom0less-build.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include #include @@ -11,6 +12,8 @@ #include #include +#include + #include #include #include @@ -704,6 +707,54 @@ static int __init alloc_xenstore_evtchn(struct domain *d) return 0; } +#define XENSTORE_PFN_OFFSET 1 +static int __init alloc_xenstore_page(struct domain *d) +{ + struct page_info *xenstore_pg; + struct xenstore_domain_interface *interface; + mfn_t mfn; + gfn_t gfn; + int rc; + + if ( (UINT_MAX - d->max_pages) < 1 ) + { + printk(XENLOG_ERR "%pd: Over-allocation for d->max_pages by 1 page.\n", + d); + return -EINVAL; + } + + d->max_pages += 1; + xenstore_pg = alloc_domheap_page(d, MEMF_bits(32)); + if ( xenstore_pg == NULL && is_64bit_domain(d) ) + xenstore_pg = alloc_domheap_page(d, 0); + if ( xenstore_pg == NULL ) + return -ENOMEM; + + mfn = page_to_mfn(xenstore_pg); + if ( !mfn_x(mfn) ) + return -ENOMEM; + + if ( !is_domain_direct_mapped(d) ) + gfn = gaddr_to_gfn(GUEST_MAGIC_BASE + + (XENSTORE_PFN_OFFSET << PAGE_SHIFT)); + else + gfn = gaddr_to_gfn(mfn_to_maddr(mfn)); + + rc = guest_physmap_add_page(d, gfn, mfn, 0); + if ( rc ) + { + free_domheap_page(xenstore_pg); + return rc; + } + + d->arch.hvm.params[HVM_PARAM_STORE_PFN] = gfn_x(gfn); + interface = map_domain_page(mfn); + interface->connection = XENSTORE_RECONNECT; + unmap_domain_page(interface); + + return 0; +} + static int __init construct_domU(struct domain *d, const struct dt_device_node *node) { @@ -804,7 +855,10 @@ static int __init construct_domU(struct domain *d, rc = alloc_xenstore_evtchn(d); if ( rc < 0 ) return rc; - d->arch.hvm.params[HVM_PARAM_STORE_PFN] = ~0ULL; + + rc = alloc_xenstore_page(d); + if ( rc < 0 ) + return rc; } return rc;