On Tue, Jul 09, 2013 at 06:00:17PM +0100, Aurelien Chartier wrote: > On 09/07/13 14:38, David Vrabel wrote: > > From: David Vrabel <david.vrabel@xxxxxxxxxx> > > > > If there are UNUSABLE regions in the machine memory map, dom0 will > > attempt to map them 1:1 which is not permitted by Xen and the kernel > > will crash. > > > > There isn't anything interesting in the UNUSABLE region that the dom0 > > kernel needs access to so we can avoid making the 1:1 mapping and > > leave the region as RAM. > > > > Since the obtaining the memory map for dom0 and domU are now more > > different, refactor each into separate functions. > > > > This fixes a dom0 boot failure if tboot is used (because tboot was > > marking a memory region as UNUSABLE). > > > > Signed-off-by: David Vrabel <david.vrabel@xxxxxxxxxx> > > Cc: stable@xxxxxxxxxxxxxxx > > I tested it with Xen 4.1.3-rc and Linux 3.8.13.4 and it is fixing the > early boot crash I reported. How did you test it? How can one reproduce this crash? Do you see this failure with v3.10 or just with v3.8 (and earlier)? > > Tested-by: Aurelien Chartier <aurelien.chartier@xxxxxxxxxx> > > > --- > > arch/x86/xen/setup.c | 114 ++++++++++++++++++++++++++++++++++++++++---------- > > 1 files changed, 91 insertions(+), 23 deletions(-) > > > > diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c > > index 94eac5c..3fdb6bd 100644 > > --- a/arch/x86/xen/setup.c > > +++ b/arch/x86/xen/setup.c > > @@ -55,6 +55,91 @@ unsigned long xen_released_pages; > > */ > > #define EXTRA_MEM_RATIO (10) > > > > +static int __init xen_get_memory_map_dom0(struct e820entry *map, > > + unsigned *nr_entries) > > +{ > > + struct xen_memory_map memmap; > > + unsigned i; > > + int ret; > > + > > + /* > > + * Dom0 requires access to machine addresses for BIOS data and > > + * MMIO (e.g. PCI) devices. The reset of the kernel expects > > + * to be able to access these through a 1:1 p2m mapping. > > + * > > + * We need to take the pseudo physical memory map and set up > > + * 1:1 mappings corresponding to the RESERVED regions and > > + * holes in the /machine/ memory map, adding/expanding the RAM > > + * region at the end of the map for the relocated RAM. > > + * > > + * This is more easily done if we just start with the machine > > + * memory map. > > + * > > + * UNUSABLE regions are awkward, they are not interesting to > > + * dom0 and Xen won't allow them to be mapped so we want to > > + * leave these as RAM in the pseudo physical map. > > + * > > + * Again, this is easiest if we take the machine memory map > > + * and change the UNUSABLE regions to RAM. > > + */ > > + > > + memmap.nr_entries = *nr_entries; > > + set_xen_guest_handle(memmap.buffer, map); > > + > > + ret = HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap); > > + if (ret < 0) > > + return ret; > > + > > + for (i = 0; i < memmap.nr_entries; i++) { > > + if (map[i].type == E820_UNUSABLE) > > + map[i].type = E820_RAM; > > + } > > + > > + *nr_entries = memmap.nr_entries; > > + return 0; > > +} > > + > > +static int __init xen_get_memory_map_domu(struct e820entry *map, > > + unsigned *nr_entries) > > +{ > > + struct xen_memory_map memmap; > > + int ret; > > + > > + /* > > + * For domUs, use the psuedo-physical memory map. > > Small typo here. > > > + * > > + * If this is not available, fake up a memory map with a > > + * single region containing the initial number of pages. > > + */ > > + > > + memmap.nr_entries = *nr_entries; > > + set_xen_guest_handle(memmap.buffer, map); > > + > > + ret = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap); > > + if (ret == -ENOSYS) { > > + unsigned long max_pfn = min(MAX_DOMAIN_PAGES, > > + xen_start_info->nr_pages); > > + memmap.nr_entries = 1; > > + map[0].addr = 0ULL; > > + map[0].size = PFN_PHYS(max_pfn); > > + /* 8MB slack (to balance backend allocations). */ > > + map[0].size += 8ULL << 20; > > + map[0].type = E820_RAM; > > + } else if (ret < 0) > > + return ret; > > + > > + *nr_entries = memmap.nr_entries; > > + return 0; > > +} > > + > > +static int __init xen_get_memory_map(struct e820entry *map, unsigned *nr_entries) > > +{ > > + if (xen_initial_domain()) > > + return xen_get_memory_map_dom0(map, nr_entries); > > + else > > + return xen_get_memory_map_domu(map, nr_entries); > > +} > > + > > static void __init xen_add_extra_mem(u64 start, u64 size) > > { > > unsigned long pfn; > > @@ -319,42 +404,25 @@ static void xen_align_and_add_e820_region(u64 start, u64 size, int type) > > char * __init xen_memory_setup(void) > > { > > static struct e820entry map[E820MAX] __initdata; > > + unsigned map_nr_entries = E820MAX; > > > > unsigned long max_pfn = xen_start_info->nr_pages; > > unsigned long long mem_end; > > int rc; > > - struct xen_memory_map memmap; > > unsigned long max_pages; > > unsigned long last_pfn = 0; > > unsigned long extra_pages = 0; > > unsigned long populated; > > int i; > > - int op; > > > > max_pfn = min(MAX_DOMAIN_PAGES, max_pfn); > > mem_end = PFN_PHYS(max_pfn); > > > > - memmap.nr_entries = E820MAX; > > - set_xen_guest_handle(memmap.buffer, map); > > - > > - op = xen_initial_domain() ? > > - XENMEM_machine_memory_map : > > - XENMEM_memory_map; > > - rc = HYPERVISOR_memory_op(op, &memmap); > > - if (rc == -ENOSYS) { > > - BUG_ON(xen_initial_domain()); > > - memmap.nr_entries = 1; > > - map[0].addr = 0ULL; > > - map[0].size = mem_end; > > - /* 8MB slack (to balance backend allocations). */ > > - map[0].size += 8ULL << 20; > > - map[0].type = E820_RAM; > > - rc = 0; > > - } > > + rc = xen_get_memory_map(map, &map_nr_entries); > > BUG_ON(rc); > > > > /* Make sure the Xen-supplied memory map is well-ordered. */ > > - sanitize_e820_map(map, memmap.nr_entries, &memmap.nr_entries); > > + sanitize_e820_map(map, map_nr_entries, &map_nr_entries); > > > > max_pages = xen_get_max_pages(); > > if (max_pages > max_pfn) > > @@ -366,12 +434,12 @@ char * __init xen_memory_setup(void) > > * this are first released. > > */ > > xen_released_pages = xen_set_identity_and_release( > > - map, memmap.nr_entries, max_pfn); > > + map, map_nr_entries, max_pfn); > > > > /* > > * Populate back the non-RAM pages and E820 gaps that had been > > * released. */ > > - populated = xen_populate_chunk(map, memmap.nr_entries, > > + populated = xen_populate_chunk(map, map_nr_entries, > > max_pfn, &last_pfn, xen_released_pages); > > > > xen_released_pages -= populated; > > @@ -395,7 +463,7 @@ char * __init xen_memory_setup(void) > > extra_pages = min(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)), > > extra_pages); > > i = 0; > > - while (i < memmap.nr_entries) { > > + while (i < map_nr_entries) { > > u64 addr = map[i].addr; > > u64 size = map[i].size; > > u32 type = map[i].type; > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxx > http://lists.xen.org/xen-devel -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html