[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20120517030652.GA8188@localhost>
Date: Thu, 17 May 2012 11:06:52 +0800
From: wfg@...ux.intel.com
To: Matt Fleming <matt.fleming@...el.com>
Cc: LKML <linux-kernel@...r.kernel.org>
Subject: Boot error: x86/efi/ioremap kconfig:x86_64-nfsroot commit:a790068
Hi Matt,
FYI, starting from this commit, the kernel immediately reboots in my
kvm boot tests..
Thanks,
Fengguang
commit a790068f4435a053fa16562eceed520f9b027c41
Author: Matt Fleming <matt.fleming@...el.com>
Date: Mon Mar 5 14:21:35 2012 +0000
x86, efi: Fixup efi_ioremap() breakage
Don't map holes.
* Is the e820 map the correct memory map to use?
* Is it OK to call find_early_table_space multiple times?
* Do we need add_efi_memmap anymore? Unconditionally do it?
* Should we reduce freq of printk(init_memory_mapping);?
* Are there parts of the memmap not in the e820 map?
* Do we even need to map ACPI stuff? is it ioremap'd?
* Is it save to reserve pagetables in init_memory_mapping(), are the other callers (gart_iommu) called after bootmem?
Signed-off-by: Matt Fleming <matt.fleming@...el.com>
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;
+ }
+
+ return last_pfn_mapped;
+}
/*
* devmem_is_allowed() checks to see if /dev/mem access to a certain address
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 436a030..e86e370 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -659,7 +659,7 @@ int arch_add_memory(int nid, u64 start, u64 size)
unsigned long nr_pages = size >> PAGE_SHIFT;
int ret;
- last_mapped_pfn = init_memory_mapping(start, start + size);
+ last_mapped_pfn = __init_memory_mapping(start, start + size);
if (last_mapped_pfn > max_pfn_mapped)
max_pfn_mapped = last_mapped_pfn;
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 264cc6e..ef0a725 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -573,8 +573,7 @@ void __init efi_init(void)
printk(KERN_WARNING
"Kernel-defined memdesc doesn't match the one from EFI!\n");
- if (add_efi_memmap)
- do_add_efi_memmap();
+ do_add_efi_memmap();
#ifdef CONFIG_X86_32
x86_platform.get_wallclock = efi_get_time;
View attachment "config-3.3.0-rc6+" of type "text/plain" (83385 bytes)
Powered by blists - more mailing lists