|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v1 5/5] hw/xen: xenpvh: Add prop to enable/disable the mapcache
From: "Edgar E. Iglesias" <edgar.iglesias@xxxxxxx>
Add a machine property to enable/disable the mapcache.
Default it to enabled for backwards compatibility.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xxxxxxx>
---
hw/xen/xen-pvh-common.c | 133 +++++++++++++++++++++++++++++---
include/hw/xen/xen-pvh-common.h | 2 +
2 files changed, 124 insertions(+), 11 deletions(-)
diff --git a/hw/xen/xen-pvh-common.c b/hw/xen/xen-pvh-common.c
index 4fade017bb..cca37202ff 100644
--- a/hw/xen/xen-pvh-common.c
+++ b/hw/xen/xen-pvh-common.c
@@ -29,6 +29,69 @@ static const MemoryListener xen_memory_listener = {
.priority = MEMORY_LISTENER_PRIORITY_ACCEL,
};
+/*
+ * Map foreign RAM in bounded chunks so we don't build a PFN array for the
+ * entire guest size (which can be huge for large guests). We reserve a VA
+ * range once and then MAP_FIXED each chunk into place.
+ */
+#define XEN_PVH_MAP_CHUNK_PAGES 65535
+
+static void *xen_map_guest_ram(XenPVHMachineState *s,
+ uint64_t addr, uint64_t size)
+{
+ size_t total_pages = size >> XC_PAGE_SHIFT;
+ size_t chunk_pages = MIN(XEN_PVH_MAP_CHUNK_PAGES, total_pages);
+ g_autofree xen_pfn_t *pfns = NULL;
+ void *base = NULL;
+ size_t offset;
+
+ if (!total_pages) {
+ goto done;
+ }
+
+ base = mmap(NULL, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (base == MAP_FAILED) {
+ base = NULL;
+ goto done;
+ }
+
+ pfns = g_new0(xen_pfn_t, chunk_pages);
+ if (!pfns) {
+ munmap(base, size);
+ base = NULL;
+ goto done;
+ }
+
+ for (offset = 0; offset < total_pages; offset += chunk_pages) {
+ size_t num_pages = MIN(chunk_pages, total_pages - offset);
+ void *mapped;
+ size_t i;
+
+ for (i = 0; i < num_pages; i++) {
+ pfns[i] = (addr >> XC_PAGE_SHIFT) + offset + i;
+ }
+
+ mapped = xenforeignmemory_map2(
+ xen_fmem, xen_domid,
+ (uint8_t *)base + (offset << XC_PAGE_SHIFT),
+ PROT_READ | PROT_WRITE, MAP_FIXED,
+ num_pages, pfns, NULL);
+ if (!mapped) {
+ munmap(base, size);
+ base = NULL;
+ goto done;
+ }
+ }
+done:
+ if (!base) {
+ /* We can't recover from this. */
+ error_report("FATAL: Failed to foreign-map %" PRIx64 " - %" PRIx64,
+ addr, addr + size);
+ exit(EXIT_FAILURE);
+ }
+ return base;
+}
+
static void xen_pvh_init_ram(XenPVHMachineState *s,
MemoryRegion *sysmem)
{
@@ -45,22 +108,42 @@ static void xen_pvh_init_ram(XenPVHMachineState *s,
block_len = s->cfg.ram_high.base + ram_size[1];
}
- memory_region_init_ram(&xen_memory, NULL, "xen.ram", block_len,
- &error_fatal);
+ if (s->cfg.mapcache) {
+ memory_region_init_ram(&xen_memory, NULL, "xen.ram",
+ block_len, &error_fatal);
+ memory_region_init_alias(&s->ram.low, NULL, "xen.ram.lo", &xen_memory,
+ s->cfg.ram_low.base, ram_size[0]);
+ if (ram_size[1] > 0) {
+ memory_region_init_alias(&s->ram.high, NULL, "xen.ram.hi",
+ &xen_memory,
+ s->cfg.ram_high.base, ram_size[1]);
+ }
+ } else {
+ void *p;
+
+ p = xen_map_guest_ram(s, s->cfg.ram_low.base, ram_size[0]);
+ memory_region_init_ram_ptr(&s->ram.low, NULL, "xen.ram.lo",
+ ram_size[0], p);
+ if (ram_size[1] > 0) {
+ p = xen_map_guest_ram(s, s->cfg.ram_high.base, ram_size[1]);
+ memory_region_init_ram_ptr(&s->ram.high, NULL, "xen.ram.hi",
+ ram_size[1], p);
+ }
+ }
- memory_region_init_alias(&s->ram.low, NULL, "xen.ram.lo", &xen_memory,
- s->cfg.ram_low.base, ram_size[0]);
+ /* Map them onto QEMU's address-space. */
memory_region_add_subregion(sysmem, s->cfg.ram_low.base, &s->ram.low);
if (ram_size[1] > 0) {
- memory_region_init_alias(&s->ram.high, NULL, "xen.ram.hi", &xen_memory,
- s->cfg.ram_high.base, ram_size[1]);
memory_region_add_subregion(sysmem, s->cfg.ram_high.base,
&s->ram.high);
}
- /* Setup support for grants. */
- memory_region_init_ram(&xen_grants, NULL, "xen.grants", block_len,
- &error_fatal);
- memory_region_add_subregion(sysmem, XEN_GRANT_ADDR_OFF, &xen_grants);
+ /* Grants are only supported when the mapcache is on. */
+ if (s->cfg.mapcache) {
+ /* Setup support for grants. */
+ memory_region_init_ram(&xen_grants, NULL, "xen.grants", block_len,
+ &error_fatal);
+ memory_region_add_subregion(sysmem, XEN_GRANT_ADDR_OFF, &xen_grants);
+ }
}
static void xen_set_irq(void *opaque, int irq, int level)
@@ -203,7 +286,7 @@ static void xen_pvh_init(MachineState *ms)
xen_register_ioreq(&s->ioreq, ms->smp.max_cpus,
xpc->handle_bufioreq,
&xen_memory_listener,
- true);
+ s->cfg.mapcache);
if (s->cfg.virtio_mmio_num) {
xen_create_virtio_mmio_devices(s);
@@ -285,6 +368,20 @@ XEN_PVH_PROP_MEMMAP(pci_ecam)
XEN_PVH_PROP_MEMMAP(pci_mmio)
XEN_PVH_PROP_MEMMAP(pci_mmio_high)
+static void xen_pvh_set_mapcache(Object *obj, bool value, Error **errp)
+{
+ XenPVHMachineState *xp = XEN_PVH_MACHINE(obj);
+
+ xp->cfg.mapcache = value;
+}
+
+static bool xen_pvh_get_mapcache(Object *obj, Error **errp)
+{
+ XenPVHMachineState *xp = XEN_PVH_MACHINE(obj);
+
+ return xp->cfg.mapcache;
+}
+
static void xen_pvh_set_pci_intx_irq_base(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
@@ -338,6 +435,12 @@ do {
\
OC_MEMMAP_PROP_SIZE(c, prop_name, name); \
} while (0)
+ object_class_property_add_bool(oc, "mapcache", xen_pvh_get_mapcache,
+ xen_pvh_set_mapcache);
+ object_class_property_set_description(oc, "mapcache",
+ "Set on/off to enable/disable the "
+ "mapcache");
+
/*
* We provide memmap properties to allow Xen to move things to other
* addresses for example when users need to accomodate the memory-map
@@ -377,6 +480,13 @@ do {
\
#endif
}
+static void xen_pvh_instance_init(Object *obj)
+{
+ XenPVHMachineState *xp = XEN_PVH_MACHINE(obj);
+
+ xp->cfg.mapcache = true;
+}
+
static void xen_pvh_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -395,6 +505,7 @@ static const TypeInfo xen_pvh_info = {
.parent = TYPE_MACHINE,
.abstract = true,
.instance_size = sizeof(XenPVHMachineState),
+ .instance_init = xen_pvh_instance_init,
.class_size = sizeof(XenPVHMachineClass),
.class_init = xen_pvh_class_init,
};
diff --git a/include/hw/xen/xen-pvh-common.h b/include/hw/xen/xen-pvh-common.h
index 0ed07c5694..0209b798f3 100644
--- a/include/hw/xen/xen-pvh-common.h
+++ b/include/hw/xen/xen-pvh-common.h
@@ -84,6 +84,8 @@ struct XenPVHMachineState {
/* PCI */
MemMapEntry pci_ecam, pci_mmio, pci_mmio_high;
uint32_t pci_intx_irq_base;
+
+ bool mapcache;
} cfg;
};
--
2.43.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |