|
@@ -143,12 +143,55 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn,
|
|
|
return released;
|
|
|
}
|
|
|
|
|
|
+static unsigned long __init xen_set_identity(const struct e820entry *list,
|
|
|
+ ssize_t map_size)
|
|
|
+{
|
|
|
+ phys_addr_t last = xen_initial_domain() ? 0 : ISA_END_ADDRESS;
|
|
|
+ phys_addr_t start_pci = last;
|
|
|
+ const struct e820entry *entry;
|
|
|
+ unsigned long identity = 0;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0, entry = list; i < map_size; i++, entry++) {
|
|
|
+ phys_addr_t start = entry->addr;
|
|
|
+ phys_addr_t end = start + entry->size;
|
|
|
+
|
|
|
+ if (start < last)
|
|
|
+ start = last;
|
|
|
+
|
|
|
+ if (end <= start)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ /* Skip over the 1MB region. */
|
|
|
+ if (last > end)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (entry->type == E820_RAM) {
|
|
|
+ if (start > start_pci)
|
|
|
+ identity += set_phys_range_identity(
|
|
|
+ PFN_UP(start_pci), PFN_DOWN(start));
|
|
|
+
|
|
|
+ /* Without saving 'last' we would gooble RAM too
|
|
|
+ * at the end of the loop. */
|
|
|
+ last = end;
|
|
|
+ start_pci = end;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ start_pci = min(start, start_pci);
|
|
|
+ last = end;
|
|
|
+ }
|
|
|
+ if (last > start_pci)
|
|
|
+ identity += set_phys_range_identity(
|
|
|
+ PFN_UP(start_pci), PFN_DOWN(last));
|
|
|
+ return identity;
|
|
|
+}
|
|
|
/**
|
|
|
* machine_specific_memory_setup - Hook for machine specific memory setup.
|
|
|
**/
|
|
|
char * __init xen_memory_setup(void)
|
|
|
{
|
|
|
static struct e820entry map[E820MAX] __initdata;
|
|
|
+ static struct e820entry map_raw[E820MAX] __initdata;
|
|
|
|
|
|
unsigned long max_pfn = xen_start_info->nr_pages;
|
|
|
unsigned long long mem_end;
|
|
@@ -156,6 +199,7 @@ char * __init xen_memory_setup(void)
|
|
|
struct xen_memory_map memmap;
|
|
|
unsigned long extra_pages = 0;
|
|
|
unsigned long extra_limit;
|
|
|
+ unsigned long identity_pages = 0;
|
|
|
int i;
|
|
|
int op;
|
|
|
|
|
@@ -181,6 +225,7 @@ char * __init xen_memory_setup(void)
|
|
|
}
|
|
|
BUG_ON(rc);
|
|
|
|
|
|
+ memcpy(map_raw, map, sizeof(map));
|
|
|
e820.nr_map = 0;
|
|
|
xen_extra_mem_start = mem_end;
|
|
|
for (i = 0; i < memmap.nr_entries; i++) {
|
|
@@ -251,6 +296,13 @@ char * __init xen_memory_setup(void)
|
|
|
|
|
|
xen_add_extra_mem(extra_pages);
|
|
|
|
|
|
+ /*
|
|
|
+ * Set P2M for all non-RAM pages and E820 gaps to be identity
|
|
|
+ * type PFNs. We supply it with the non-sanitized version
|
|
|
+ * of the E820.
|
|
|
+ */
|
|
|
+ identity_pages = xen_set_identity(map_raw, memmap.nr_entries);
|
|
|
+ printk(KERN_INFO "Set %ld page(s) to 1-1 mapping.\n", identity_pages);
|
|
|
return "Xen";
|
|
|
}
|
|
|
|