@@ -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,20 +232,11 @@ 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");
- return 1;
- }
-
- intf = xenforeignmemory_map(xfh, info->domid, PROT_READ | PROT_WRITE, 1,
- &xenstore_pfn, NULL);
- if (!intf) {
- printf("Error mapping xenstore page\n");
+ /* Get xenstore page */
+ if (get_xs_page(xch, info, &xenstore_pfn) != 0) {
+ printf("Error on getting 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);
@@ -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;
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <xen/device_tree.h>
+#include <xen/domain_page.h>
#include <xen/err.h>
#include <xen/event.h>
#include <xen/grant_table.h>
@@ -11,6 +12,8 @@
#include <xen/sizes.h>
#include <xen/vmap.h>
+#include <public/io/xs_wire.h>
+
#include <asm/arm64/sve.h>
#include <asm/dom0less-build.h>
#include <asm/domain_build.h>
@@ -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;