On Wed, Mar 7, 2012 at 2:30 AM, Matt Fleming <matt.fleming@xxxxxxxxx> wrote: > On Mon, 2012-02-27 at 18:27 -0800, H. Peter Anvin wrote: >> On 02/23/2012 08:47 PM, H. Peter Anvin wrote: >> >> >> >> please check attach patch for tip/efi branch. >> > >> > That doesn't do anything like what I noted above. >> > >> > We should get rid of dependencies on legacy PC memory layouts, not add >> > more hacks. What is so hard about "when we create the initial mappings, >> > only create for RAM/ACPI/EFI regions" (if we even need to do so for >> > ACPI, I think ACPI might use ioremap() already)? >> > >> >> Hi Yinghai, >> >> Can you please answer my question? > > Did you have something like this in mind? Note that it doesn't go all > the way to removing the add_do_memmap boot parameter because I'm not > sure how to do that for GPL exported symbols. > > The only testing I've done with this is to ensure that it boots under > qemu (both for EFI and BIOS) on 32/64-bit. > > This is on top of tip/x86/efi. > > diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h > index bce688d..4f95f23 100644 > --- a/arch/x86/include/asm/page_types.h > +++ b/arch/x86/include/asm/page_types.h > @@ -51,8 +51,9 @@ static inline phys_addr_t get_max_mapped(void) > return (phys_addr_t)max_pfn_mapped << PAGE_SHIFT; > } > > -extern unsigned long init_memory_mapping(unsigned long start, > - unsigned long end); > +extern unsigned long init_memory_mapping(void); > +extern unsigned long __init_memory_mapping(unsigned long start, > + unsigned long end); > > extern void initmem_init(void); > extern void free_initmem(void); > diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c > index b1e7c7f..f52ced2 100644 > --- a/arch/x86/kernel/amd_gart_64.c > +++ b/arch/x86/kernel/amd_gart_64.c > @@ -769,7 +769,7 @@ int __init gart_iommu_init(void) > > if (end_pfn > max_low_pfn_mapped) { > start_pfn = (aper_base>>PAGE_SHIFT); > - init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT); > + __init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT); > } > > pr_info("PCI-DMA: using GART IOMMU.\n"); > diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c > index e22bb08..b65d287 100644 > --- a/arch/x86/kernel/setup.c > +++ b/arch/x86/kernel/setup.c > @@ -690,8 +690,6 @@ early_param("reservelow", parse_reservelow); > > void __init setup_arch(char **cmdline_p) > { > - unsigned long end_pfn; > - > #ifdef CONFIG_X86_32 > memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); > visws_early_detect(); > @@ -927,31 +925,11 @@ void __init setup_arch(char **cmdline_p) > > init_gbpages(); > > - /* max_pfn_mapped is updated here */ > - end_pfn = max_low_pfn; > - > -#ifdef CONFIG_X86_64 > - /* > - * There may be regions after the last E820_RAM region that we > - * want to include in the kernel direct mapping because their > - * contents are needed at runtime. > - */ > - if (efi_enabled) { > - unsigned long efi_end; > - > - efi_end = e820_end_pfn(MAXMEM>>PAGE_SHIFT, E820_RESERVED_EFI); > - if (efi_end > end_pfn) > - end_pfn = efi_end; > - } > -#endif > - > - max_low_pfn_mapped = init_memory_mapping(0, end_pfn << PAGE_SHIFT); > - max_pfn_mapped = max_low_pfn_mapped; > + /* max_low_pfn_mapped is updated here */ > + max_pfn_mapped = init_memory_mapping(); > > #ifdef CONFIG_X86_64 > if (max_pfn > max_low_pfn) { > - max_pfn_mapped = init_memory_mapping(1UL<<32, > - max_pfn<<PAGE_SHIFT); > /* can we preseve max_low_pfn ?*/ > max_low_pfn = max_pfn; > } > diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c > index 6cabf65..f1835e9 100644 > --- a/arch/x86/mm/init.c > +++ b/arch/x86/mm/init.c > @@ -118,8 +118,8 @@ static int __meminit save_mr(struct map_range *mr, int nr_range, > * This runs before bootmem is initialized and gets pages directly from > * the physical memory. To access them they are temporarily mapped. > */ > -unsigned long __init_refok init_memory_mapping(unsigned long start, > - unsigned long end) > +unsigned long __init_refok __init_memory_mapping(unsigned long start, > + unsigned long end) > { > unsigned long page_size_mask = 0; > unsigned long start_pfn, end_pfn; > @@ -301,6 +301,59 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, > return ret >> PAGE_SHIFT; > } > > +/* > + * Traverse the E820 memory map and add RAM/ACPI/EFI regions to the > + * initial memory mapping. > + */ > +unsigned long __init_refok init_memory_mapping(void) > +{ > + struct e820entry *entry; > + unsigned long last_pfn_mapped = 0; > + unsigned long start, end; > + int i; > + > + /* Map the legacy region until we fix all drivers */ > + __init_memory_mapping(0, 1 << 20); > + > + for (i = 0; i < e820.nr_map; i++) { > + entry = &e820.map[i]; > + start = entry->addr; > + end = start + entry->size; > + > + /* We've already mapped below 1MB */ > + if (end < (1 << 20)) > + continue; > + > + if (start < (1 << 20)) > + start = 1 << 20; > +#ifdef CONFIG_X86_32 > + /* > + * The map is sorted, so bail once we hit a region > + * that's above max_low_pfn. > + */ > + if (start >= max_low_pfn << PAGE_SHIFT) > + break; > + > + if (end > max_low_pfn << PAGE_SHIFT) > + end = max_low_pfn << PAGE_SHIFT; > +#endif > + switch (entry->type) { > + case E820_RAM: > + case E820_RESERVED_EFI: > + case E820_ACPI: > + case E820_NVS: > + last_pfn_mapped = __init_memory_mapping(start, end); > + break; > + default: > + continue; > + } > + > + if (end <= max_low_pfn << PAGE_SHIFT) > + max_low_pfn_mapped = last_pfn_mapped; those two line could be dropped if you have last_pfn_mapped = 1<<(20 - 12); before the loop Also you can not use max_low_pfn here... you need to update e820_end_pfn to search max pfn for several types like > + case E820_RAM: > + case E820_RESERVED_EFI: > + case E820_ACPI: > + case E820_NVS: but my question is: is there any system that will put EFI runtime, or ACPI or NVS above 4G? is that legal? Yinghai -- To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html