[patch] fix EFI memory map parsing for x86
The memory descriptors that comprise the EFI memory map are not fixed in stone such that the size could change in the future. This uses the memory descriptor size obtained from EFI to iterate over the memory map entries during boot. This enables the removal of an x86 specific pad (and ifdef) in the EFI header. I also couldn't stomach the broken up nature of the function to put EFI runtime calls into virtual mode any longer so I fixed that up a bit as well. For reference, this patch only impacts x86. arch/i386/kernel/efi.c | 101 +++ arch/i386/kernel/setup.c | 14 -- arch/i386/mm/init.c |5 +- include/asm-i386/setup.h |2 include/linux/efi.h | 14 +- 5 files changed, 67 insertions(+), 69 deletions(-) Signed-off-by: Matt Tolentino <[EMAIL PROTECTED]> --- diff -urNp linux-2.6.13-rc3/arch/i386/kernel/efi.c linux-2.6.13-rc3-efi/arch/i386/kernel/efi.c --- linux-2.6.13-rc3/arch/i386/kernel/efi.c 2005-07-15 11:30:30.0 -0400 +++ linux-2.6.13-rc3-efi/arch/i386/kernel/efi.c 2005-07-15 12:08:55.0 -0400 @@ -233,22 +233,23 @@ void __init efi_map_memmap(void) { memmap.map = NULL; - memmap.map = (efi_memory_desc_t *) - bt_ioremap((unsigned long) memmap.phys_map, - (memmap.nr_map * sizeof(efi_memory_desc_t))); - + memmap.map = bt_ioremap((unsigned long) memmap.phys_map, + (memmap.nr_map * memmap.desc_size)); if (memmap.map == NULL) printk(KERN_ERR PFX "Could not remap the EFI memmap!\n"); + + memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size); } #if EFI_DEBUG static void __init print_efi_memmap(void) { efi_memory_desc_t *md; + void *p; int i; - for (i = 0; i < memmap.nr_map; i++) { - md = &memmap.map[i]; + for (p = memmap.map, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) { + md = p; printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, " "range=[0x%016llx-0x%016llx) (%lluMB)\n", i, md->type, md->attribute, md->phys_addr, @@ -271,10 +272,10 @@ void efi_memmap_walk(efi_freemem_callbac } prev, curr; efi_memory_desc_t *md; unsigned long start, end; - int i; + void *p; - for (i = 0; i < memmap.nr_map; i++) { - md = &memmap.map[i]; + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + md = p; if ((md->num_pages == 0) || (!is_available_memory(md))) continue; @@ -325,6 +326,7 @@ void __init efi_init(void) memmap.phys_map = EFI_MEMMAP; memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE; memmap.desc_version = EFI_MEMDESC_VERSION; + memmap.desc_size = EFI_MEMDESC_SIZE; efi.systab = (efi_system_table_t *) boot_ioremap((unsigned long) efi_phys.systab, @@ -431,22 +433,30 @@ void __init efi_init(void) printk(KERN_ERR PFX "Could not map the runtime service table!\n"); /* Map the EFI memory map for use until paging_init() */ - - memmap.map = (efi_memory_desc_t *) - boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE); - + memmap.map = boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE); if (memmap.map == NULL) printk(KERN_ERR PFX "Could not map the EFI memory map!\n"); - if (EFI_MEMDESC_SIZE != sizeof(efi_memory_desc_t)) { - printk(KERN_WARNING PFX "Warning! Kernel-defined memdesc doesn't " - "match the one from EFI!\n"); - } + memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size); + #if EFI_DEBUG print_efi_memmap(); #endif } +static inline void __init check_range_for_systab(efi_memory_desc_t *md) +{ + if (((unsigned long)md->phys_addr <= (unsigned long)efi_phys.systab) && + ((unsigned long)efi_phys.systab < md->phys_addr + + ((unsigned long)md->num_pages << EFI_PAGE_SHIFT))) { + unsigned long addr; + + addr = md->virt_addr - md->phys_addr + + (unsigned long)efi_phys.systab; + efi.systab = (efi_system_table_t *)addr; + } +} + /* * This function will switch the EFI runtime services to virtual mode. * Essentially, look through the EFI memmap and map every region that @@ -460,43 +470,32 @@ void __init efi_enter_virtual_mode(void) { efi_memory_desc_t *md; efi_status_t status; - int i; + void *p; efi.systab = NULL; - for (i = 0; i < memmap.nr_map; i++) { - md = &memmap.ma
[patch] fix ACPI table discovery from EFI for x86
This patch addresses a problem on x86 EFI systems with larger memory configurations. Up until now, we've relied on the fact that the ACPI RSDT would reside somewhere in low memory that could be permanently mapped in kernel address space - so __va() has been sufficient. However, on EFI systems, the RSDT is often anywhere in the lower 4GB of physical address space. So, we may need to remap it on x86 systems. Second, this fixes some miscalculations in one of the EFI memmap callback functions. Lastly, this also removes all of the va->pa->va contortions and stores the physical location in the efi struct while preserving the validity checks. This change is the only reason this impacts ia64. Tested on x86 EFI machines and boot tested on one ia64 machine thanks to Tony. Additional testing on ia64 machines would be appreciated! Problem reported and original patch proposed by Ping Wei. Signed-off-by: Matt Tolentino <[EMAIL PROTECTED]> --- diff -urNp linux-2.6.13-rc3/arch/i386/kernel/acpi/boot.c linux-2.6.13-rc3-efi/arch/i386/kernel/acpi/boot.c --- linux-2.6.13-rc3/arch/i386/kernel/acpi/boot.c 2005-07-13 00:46:46.0 -0400 +++ linux-2.6.13-rc3-efi/arch/i386/kernel/acpi/boot.c 2005-07-13 10:32:54.073297792 -0400 @@ -682,10 +682,10 @@ acpi_find_rsdp (void) unsigned long rsdp_phys = 0; if (efi_enabled) { - if (efi.acpi20) - return __pa(efi.acpi20); - else if (efi.acpi) - return __pa(efi.acpi); + if (efi.phys_acpi20 != EFI_INVALID_ACPI_TABLE_ADDR) + return efi.phys_acpi20; + else if (efi.phys_acpi != EFI_INVALID_ACPI_TABLE_ADDR) + return efi.phys_acpi; } /* * Scan memory looking for the RSDP signature. First search EBDA (low diff -urNp linux-2.6.13-rc3/arch/i386/kernel/efi.c linux-2.6.13-rc3-efi/arch/i386/kernel/efi.c --- linux-2.6.13-rc3/arch/i386/kernel/efi.c 2005-07-13 00:46:46.0 -0400 +++ linux-2.6.13-rc3-efi/arch/i386/kernel/efi.c 2005-07-13 10:32:04.731798840 -0400 @@ -376,17 +376,20 @@ void __init efi_init(void) if (config_tables == NULL) printk(KERN_ERR PFX "Could not map EFI Configuration Table!\n"); + efi.phys_acpi20 = EFI_INVALID_ACPI_TABLE_ADDR; + efi.phys_acpi = EFI_INVALID_ACPI_TABLE_ADDR; + for (i = 0; i < num_config_tables; i++) { if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) { efi.mps = (void *)config_tables[i].table; printk(KERN_INFO " MPS=0x%lx ", config_tables[i].table); } else if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) { - efi.acpi20 = __va(config_tables[i].table); + efi.phys_acpi20 = config_tables[i].table; printk(KERN_INFO " ACPI 2.0=0x%lx ", config_tables[i].table); } else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) { - efi.acpi = __va(config_tables[i].table); + efi.phys_acpi = config_tables[i].table; printk(KERN_INFO " ACPI=0x%lx ", config_tables[i].table); } else if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) { diff -urNp linux-2.6.13-rc3/arch/i386/kernel/setup.c linux-2.6.13-rc3-efi/arch/i386/kernel/setup.c --- linux-2.6.13-rc3/arch/i386/kernel/setup.c 2005-07-13 00:46:46.0 -0400 +++ linux-2.6.13-rc3-efi/arch/i386/kernel/setup.c 2005-07-13 10:24:25.149665944 -0400 @@ -1034,10 +1034,10 @@ static int __init free_available_memory(unsigned long start, unsigned long end, void *arg) { /* check max_low_pfn */ - if (start >= ((max_low_pfn + 1) << PAGE_SHIFT)) + if (start >= (max_low_pfn << PAGE_SHIFT)) return 0; - if (end >= ((max_low_pfn + 1) << PAGE_SHIFT)) - end = (max_low_pfn + 1) << PAGE_SHIFT; + if (end >= (max_low_pfn << PAGE_SHIFT)) + end = max_low_pfn << PAGE_SHIFT; if (start < end) free_bootmem(start, end - start); diff -urNp linux-2.6.13-rc3/arch/ia64/kernel/acpi.c linux-2.6.13-rc3-efi/arch/ia64/kernel/acpi.c --- linux-2.6.13-rc3/arch/ia64/kernel/acpi.c2005-07-13 00:46:46.0 -0400 +++ linux-2.6.13-rc3-efi/arch/ia64/kernel/acpi.c2005-07-13 10:33:51.614550192 -0400 @@ -615,9 +615,9 @@ acpi_find_rsdp (void) { unsigned long rsdp_phys = 0; - if (efi.acpi20) - rsdp_phys = __pa(efi.acpi20); - else if (efi.acpi) + if (efi.phys_acpi20 != EFI_INVALID_ACPI_TABLE_ADDR) + rsdp_phys = efi.phys_acpi20; + else if (efi.ph
[patch] minor syctl fix in vsyscall_init
Andi, If CONFIG_SYCTL is not enabled then the x86-64 tree fails to build due to use of a symbol that is not compiled in. Don't bother compiling in the sysctl register call if not building with sysctl. matt Signed-off-by: Matt Tolentino <[EMAIL PROTECTED]> diff -urNp linux-2.6.12-rc2/arch/x86_64/kernel/vsyscall.c linux-2.6.12-rc2-m/arch/x86_64/kernel/vsyscall.c --- linux-2.6.12-rc2/arch/x86_64/kernel/vsyscall.c 2005-04-04 12:39:06.0 -0400 +++ linux-2.6.12-rc2-m/arch/x86_64/kernel/vsyscall.c2005-04-13 09:28:47.0 -0400 @@ -218,7 +218,9 @@ static int __init vsyscall_init(void) BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE))); map_vsyscall(); sysctl_vsyscall = 1; +#ifdef CONFIG_SYSCTL register_sysctl_table(kernel_root_table2, 0); +#endif return 0; } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/