[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] Xen 3.1.2 can corrupt BIOS resevered memory between 1M and 16M.
Unfortunately, it does not appear to fix the issue. I think I found why. First I added some debug to init_boot_pages to determine when and where the caller was adding a region that stepped on reserved BIOS memory at 15M. The debug output showed this: (XEN) init_boot_pages-KAM: called from ffff828c801b7657 with (100000, 1000000) <- BAD! (XEN) init_boot_pages-KAM: called from ffff828c801b7657 with (f40000, 1000000) (XEN) init_boot_pages-KAM: called from ffff828c801b7690 with (1000000, 7e195000) (XEN) init_boot_pages-KAM: called from ffff828c801b7690 with (7fe00000, 7fef0000) (XEN) init_boot_pages-KAM: called from ffff828c801b7690 with (100000000, 180000000) It's the very first call to init_boot_pages(), in __start_xen(), that tramples the 15M BIOS hole. And I see this code in __start_xen: /* Need to create mappings above 16MB. */ map_s = max_t(uint64_t, s, 16<<20); map_e = e; #if defined(CONFIG_X86_32) /* mappings are truncated on x86_32 */ map_e = min_t(uint64_t, map_e, BOOTSTRAP_DIRECTMAP_END); #endif /* Pass mapped memory to allocator /before/ creating new mappings. */ if ( s < map_s ) init_boot_pages(s, map_s); So the first time through the loop, s == 1M and e == 15M. But map_s gets set to 16M and then we slip into the if statement and call init_boot_pages with (1M, 16M), crushing the BIOS hole. On 12/11/07, Keir Fraser <Keir.Fraser@xxxxxxxxxxxx> wrote: > Hopefully this is fixed by c/s 15546 in xen-3.1-testing.hg. It would be > great if you could confirm this fixes the issue. > > Thanks, > Keir > > > On 7/12/07 15:43, "Kimball Murray" <kimball.murray@xxxxxxxxx> wrote: > > > One of the hypervisor patches applied after the 3.1.0 build (15044.patch) > > can > > cause BIOS-reserved memory regions between 1M and 16M to be overwritten. > > > > Originally, memory in this area was added to the boot allocator only if it > > was not reserved, but the 15044 patch removed that code and added this: > > > > + init_boot_pages(1<<20, 16<<20); /* Initial seed: 15MB */ > > > > Stratus is one vendor whose BIOS e820 tables define a 256K reseverved area > > starting at 15M (0xf00000). Here are the e820 tables for that platform: > > > > (XEN) Xen-e820 RAM map: > > (XEN) 0000000000000000 - 000000000009a000 (usable) > > (XEN) 000000000009a800 - 00000000000a0000 (reserved) > > (XEN) 00000000000cc000 - 00000000000d0000 (reserved) > > (XEN) 00000000000dc000 - 0000000000100000 (reserved) > > (XEN) 0000000000100000 - 0000000000f00000 (usable) > > (XEN) 0000000000f00000 - 0000000000f40000 (reserved) > > (XEN) 0000000000f40000 - 000000007fef0000 (usable) > > (XEN) 000000007fef0000 - 000000007fefa000 (ACPI data) > > (XEN) 000000007fefa000 - 000000007ff00000 (ACPI NVS) > > (XEN) 000000007ff00000 - 0000000080000000 (reserved) > > (XEN) 00000000e0000000 - 00000000f0000000 (reserved) > > (XEN) 00000000fec80000 - 00000000fec90000 (reserved) > > (XEN) 00000000fee00000 - 00000000fee01000 (reserved) > > (XEN) 00000000ff000000 - 0000000100000000 (reserved) > > (XEN) 0000000100000000 - 0000000180000000 (usable) > > > > It turns out that the reserved area at 15M was used by the system's SMI > > handler > > as a register restore area. Because the hypervisor was stepping on this > > memory, > > the system MTRR settings would change from write-back to write-through after > > any SMI was triggered. Other, more spectacular, failures could result on > > other > > platforms. > > > > The attached patch re-adds code that pays attention to the e820 tables > > when seeding the boot allocator with low-memory pages. > > > > > > Signed-off-by: Kimball Murray (kimball.murray@xxxxxxxxx) > > > > > > ---------------------------- snip ----------------------- > > diff -Naur xen/arch/x86/setup.c ../kernel-2.6.18-55bb/xen/arch/x86/setup.c > > --- xen/arch/x86/setup.c 2007-10-23 15:23:10.000000000 -0400 > > +++ ../kernel-2.6.18-55bb/xen/arch/x86/setup.c 2007-11-30 16:04:21.000000000 > > -0500 > > @@ -441,6 +441,39 @@ > > return p; > > } > > > > +/* > > + * Add some low memory pages (from "lower" to "upper") to the boot > > + * allocator, but be careful not to add any reserved areas (pay > > + * attention to e820 map). > > + */ > > +static void seed_boot_allocator(unsigned long lower, unsigned long upper) > > +{ > > + int i; > > + > > + for ( i = 0; i < e820_raw_nr; i++ ) > > + { > > + uint64_t start, end; > > + > > + if (e820_raw[i].type != E820_RAM) > > + continue; > > + > > + start = e820_raw[i].addr; > > + if (start >= upper) > > + continue; > > + if (start < lower) > > + start = lower; > > + > > + end = e820_raw[i].addr + e820_raw[i].size; > > + if (end <= lower) > > + continue; > > + > > + if (end > upper) > > + end = upper; > > + > > + init_boot_pages(start, end); > > + } > > +} > > + > > void __init __start_xen(unsigned long mbi_p) > > { > > char *memmap_type = NULL; > > @@ -810,9 +843,10 @@ > > xenheap_phys_end += xen_phys_start; > > reserve_in_boot_e820(xen_phys_start, > > xen_phys_start + (opt_xenheap_megabytes<<20)); > > - init_boot_pages(1<<20, 16<<20); /* Initial seed: 15MB */ > > + /* Initial seed, lower 1M - 16M, but pay attention to e820 tables */ > > + seed_boot_allocator(1 << 20, 16 << 20); > > #else > > - init_boot_pages(xenheap_phys_end, 16<<20); /* Initial seed: 4MB */ > > + seed_boot_allocator(xenheap_phys_end, 16<<20); /* Initial seed: 4MB */ > > #endif > > > > if ( kexec_crash_area.size != 0 ) > > > > _______________________________________________ > > Xen-devel mailing list > > Xen-devel@xxxxxxxxxxxxxxxxxxx > > http://lists.xensource.com/xen-devel > > > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |