[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH RFC] x86/mm: split unmapping and marking-as-I/O in arch_init_memory()
On 07.08.2025 11:37, Jan Beulich wrote: > The unmapping part also wants to cover UNUSABLE regions, and it will now > be necessary for space outside the low 16Mb (wherever Xen is placed). > > While there, limit the scopes of involved variables. > > Fixes: e4dd91ea85a3 ("x86: Ensure RAM holes really are not mapped in Xen's > ongoing 1:1 physmap") > Fixes: 7cd7f2f5e116 ("x86/boot: Remove the preconstructed low 16M superpage > mappings") > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > --- > Originally I had the unmap cover the entire range up to 4Gb, which made > this ACPI mapping issue more pronounced: Mappings done by > acpi_dmar_init(), erst_init(), and acpi_hest_init() may wrongly be > undone this way. Having limited things to the initial mapping range, the > risk of an overlap with some area which needs to remain mapped is lower, > but it's not gone. > > As the excess mappings could, at least in principle, also cause other > issues (like mapping a range WB which must strictly be non-cachable), I > wonder whether we can actually get away with those excess mappings, > despite properly tearing them down in arch_init_memory() (directmap) and > __start_xen() (Xen image space). Options would appear to be to move > _end[] to a 2Mb aligned boundary (or at least extend the PT_LOAD segment > to end at the next 2Mb boundary), or to use 4k mappings for the tail > part of .bss. That would then also eliminate the remaining concern here. > > Extending the PT_LOAD segment (in mkelf32) would apparently allow to do > away with the hackery introduced by 773ded42218d ("Move cpu0_stack out > of Xen text section and into BSS"), to "work around" a supposed linker > bug (which really was a bug in the linker script imo). The extra command > line argument then wouldn't be needed anymore. Thinking about it, this would then also simplify ... > --- a/xen/arch/x86/mm.c > +++ b/xen/arch/x86/mm.c > @@ -275,8 +275,6 @@ static void __init assign_io_page(struct > > void __init arch_init_memory(void) > { > - unsigned long i, pfn, rstart_pfn, rend_pfn, iostart_pfn, ioend_pfn; > - > /* > * Basic guest-accessible flags: > * PRESENT, R/W, USER, A/D, AVAIL[0,1,2], AVAIL_HIGH, NX (if > available). > @@ -292,12 +290,55 @@ void __init arch_init_memory(void) > * case the low 1MB. > */ > BUG_ON(pvh_boot && trampoline_phys != 0x1000); > - for ( i = 0; i < 0x100; i++ ) > + for ( unsigned int i = 0; i < MB(1) >> PAGE_SHIFT; i++ ) > assign_io_page(mfn_to_page(_mfn(i))); > > - /* Any areas not specified as RAM by the e820 map are considered I/O. */ > - for ( i = 0, pfn = 0; pfn < max_page; i++ ) > + /* > + * Any areas not specified as RAM by the e820 map want to have no > mappings. > + * We may have established some by mapping more than necessary in head.S, > + * due to the use of super-pages there. > + */ > + for ( unsigned long i = 0, pfn = 0, > + rlimit_pfn = PFN_DOWN(PAGE_ALIGN_2M(__pa(_end))); > + pfn < rlimit_pfn; i++ ) > { > + unsigned long rstart_pfn, rend_pfn, start_pfn; > + > + while ( i < e820.nr_map && > + e820.map[i].type != E820_RAM ) > + i++; > + > + if ( i >= e820.nr_map ) > + { > + /* No more RAM regions: Unmap right to upper boundary. */ > + rstart_pfn = rend_pfn = rlimit_pfn; > + } > + else > + { > + /* Unmap just up as far as next RAM region. */ > + rstart_pfn = min(rlimit_pfn, PFN_UP(e820.map[i].addr)); > + rend_pfn = max(rstart_pfn, > + PFN_DOWN(e820.map[i].addr + e820.map[i].size)); > + } > + > + /* NB: _start is already 2Mb-aligned. */ > + start_pfn = max(pfn, PFN_DOWN(__pa(_start))); > + if ( start_pfn < rstart_pfn ) > + destroy_xen_mappings((unsigned long)mfn_to_virt(start_pfn), > + (unsigned long)mfn_to_virt(rstart_pfn)); > + > + /* Skip the RAM region. */ > + pfn = rend_pfn; > + } ... this: If we're loaded in an area that's a multiple of 2Mb in size (and 2Mb aligned), we wouldn't need to walk the E820 map anymore. The boot loader (or whatever else) must have placed the entire image inside a RAM region. Hence we could simply unmap [PAGE_ALIGN_4K(_end), PAGE_ALIGN_2M(_end)), outside of any loop. Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |