Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109986594
D44251.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D44251.diff
View Options
diff --git a/sys/dev/xen/bus/xenpv.c b/sys/dev/xen/bus/xenpv.c
--- a/sys/dev/xen/bus/xenpv.c
+++ b/sys/dev/xen/bus/xenpv.c
@@ -65,6 +65,12 @@
#define LOW_MEM_LIMIT 0
#endif
+static struct rman unpopulated_mem = {
+ .rm_end = ~0,
+ .rm_type = RMAN_ARRAY,
+ .rm_descr = "Xen unpopulated memory",
+};
+
static void
xenpv_identify(driver_t *driver, device_t parent)
{
@@ -91,10 +97,24 @@
return (BUS_PROBE_NOWILDCARD);
}
+/* Dummy init for arches that don't have a specific implementation. */
+int __weak_symbol
+xen_arch_init_physmem(device_t dev, struct rman *mem)
+{
+ return (0);
+}
+
static int
xenpv_attach(device_t dev)
{
- int error;
+ int error = rman_init(&unpopulated_mem);
+
+ if (error != 0)
+ return (error);
+
+ error = xen_arch_init_physmem(dev, &unpopulated_mem);
+ if (error != 0)
+ return (error);
/*
* Let our child drivers identify any child devices that they
@@ -110,6 +130,14 @@
return (error);
}
+static int
+release_unpopulated_mem(device_t dev, struct resource *res)
+{
+
+ return (rman_is_region_manager(res, &unpopulated_mem) ?
+ rman_release_resource(res) : bus_release_resource(dev, res));
+}
+
static struct resource *
xenpv_alloc_physmem(device_t dev, device_t child, int *res_id, size_t size)
{
@@ -117,17 +145,48 @@
vm_paddr_t phys_addr;
void *virt_addr;
int error;
+ const unsigned int flags = RF_ACTIVE | RF_UNMAPPED |
+ RF_ALIGNMENT_LOG2(PAGE_SHIFT);
- res = bus_alloc_resource(child, SYS_RES_MEMORY, res_id, LOW_MEM_LIMIT,
- ~0, size, RF_ACTIVE | RF_UNMAPPED);
- if (res == NULL)
+ KASSERT((size & PAGE_MASK) == 0, ("unaligned size requested"));
+ size = round_page(size);
+
+ /* Attempt to allocate from arch resource manager. */
+ res = rman_reserve_resource(&unpopulated_mem, 0, ~0, size, flags,
+ child);
+ if (res != NULL) {
+ rman_set_rid(res, *res_id);
+ rman_set_type(res, SYS_RES_MEMORY);
+ } else {
+ static bool warned = false;
+
+ /* Fallback to generic MMIO allocator. */
+ if (__predict_false(!warned)) {
+ warned = true;
+ device_printf(dev,
+ "unable to allocate from arch specific routine, "
+ "fall back to unused memory areas\n");
+ }
+ res = bus_alloc_resource(child, SYS_RES_MEMORY, res_id,
+ LOW_MEM_LIMIT, ~0, size, flags);
+ }
+
+ if (res == NULL) {
+ device_printf(dev,
+ "failed to allocate Xen unpopulated memory\n");
return (NULL);
+ }
phys_addr = rman_get_start(res);
error = vm_phys_fictitious_reg_range(phys_addr, phys_addr + size,
VM_MEMATTR_XEN);
if (error) {
- bus_release_resource(child, SYS_RES_MEMORY, *res_id, res);
+ int error = release_unpopulated_mem(child, res);
+
+ if (error != 0)
+ device_printf(dev, "failed to release resource: %d\n",
+ error);
+
return (NULL);
}
virt_addr = pmap_mapdev_attr(phys_addr, size, VM_MEMATTR_XEN);
@@ -150,7 +209,8 @@
pmap_unmapdev(virt_addr, size);
vm_phys_fictitious_unreg_range(phys_addr, phys_addr + size);
- return (bus_release_resource(child, SYS_RES_MEMORY, res_id, res));
+
+ return release_unpopulated_mem(child, res);
}
static device_method_t xenpv_methods[] = {
diff --git a/sys/x86/include/xen/xen-os.h b/sys/x86/include/xen/xen-os.h
--- a/sys/x86/include/xen/xen-os.h
+++ b/sys/x86/include/xen/xen-os.h
@@ -39,6 +39,7 @@
#ifndef __ASSEMBLY__
#include <sys/pcpu.h>
+#include <sys/rman.h>
/* If non-zero, the hypervisor has been configured to use a direct vector */
extern int xen_vector_callback_enabled;
diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c
--- a/sys/x86/xen/hvm.c
+++ b/sys/x86/xen/hvm.c
@@ -47,6 +47,7 @@
#include <machine/cpu.h>
#include <machine/md_var.h>
#include <machine/metadata.h>
+#include <machine/pc/bios.h>
#include <machine/smp.h>
#include <x86/apicreg.h>
@@ -548,3 +549,52 @@
return (regs[0] & XEN_HVM_CPUID_IOMMU_MAPPINGS);
}
+
+int
+xen_arch_init_physmem(device_t dev, struct rman *mem)
+{
+ static struct bios_smap smap[128];
+ struct xen_memory_map memmap = {
+ .nr_entries = nitems(smap),
+ };
+ unsigned int i;
+ int error;
+
+ if (!xen_initial_domain())
+ return (0);
+
+ set_xen_guest_handle(memmap.buffer, smap);
+ error = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
+ if (error != 0)
+ return (error);
+
+ /*
+ * Fill with UNUSABLE regions, as it's always fine to use those for
+ * foreign mappings, they will never be populated.
+ */
+ for (i = 0; i < memmap.nr_entries; i++) {
+ vm_paddr_t start, end;
+
+ if (smap[i].type != SMAP_TYPE_ACPI_ERROR)
+ continue;
+
+ start = round_page(smap[i].base);
+ end = trunc_page(smap[i].base + smap[i].length) - 1;
+
+ if (start >= end)
+ continue;
+
+ if (bootverbose != 0)
+ device_printf(dev,
+ "scratch mapping region @ [%#lx, %#lx]\n",
+ start, end);
+
+ error = rman_manage_region(mem, start, end);
+ if (error != 0)
+ device_printf(dev,
+ "unable to add scratch region [%#lx, %#lx]: %d\n",
+ start, end, error);
+ }
+
+ return (0);
+}
diff --git a/sys/xen/xen-os.h b/sys/xen/xen-os.h
--- a/sys/xen/xen-os.h
+++ b/sys/xen/xen-os.h
@@ -158,6 +158,9 @@
*/
void xen_emergency_print(const char *str, size_t size);
+/* Arch-specific helper to init scratch mapping space. */
+int xen_arch_init_physmem(device_t dev, struct rman *mem);
+
#ifndef xen_mb
#define xen_mb() mb()
#endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Feb 13, 3:00 AM (21 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16621409
Default Alt Text
D44251.diff (5 KB)
Attached To
Mode
D44251: x86/xen: use UNUSABLE e820 regions for foreign mappings
Attached
Detach File
Event Timeline
Log In to Comment