diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-12-14 03:02:31 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-12-14 03:02:31 +0400 |
commit | 373da0a2a33018d560afcb2c77f8842985d79594 (patch) | |
tree | 88f9ffb1357928e463514929a68781a79c1dca97 | |
parent | 653f42f6b6348652c02737924abd6a5a6426e7ee (diff) | |
parent | e1ad783b12ec8b69da83479c5d21a0d8180bc519 (diff) | |
download | linux-373da0a2a33018d560afcb2c77f8842985d79594.tar.xz |
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
Revert "x86, efi: Calling __pa() with an ioremap()ed address is invalid"
x86, efi: Make efi_call_phys_{prelog,epilog} CONFIG_RELOCATABLE-aware
-rw-r--r-- | arch/x86/include/asm/e820.h | 8 | ||||
-rw-r--r-- | arch/x86/include/asm/efi.h | 5 | ||||
-rw-r--r-- | arch/x86/kernel/e820.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 21 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi.c | 29 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi_32.c | 48 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi_64.c | 17 |
7 files changed, 37 insertions, 94 deletions
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h index c9547033e38e..908b96957d88 100644 --- a/arch/x86/include/asm/e820.h +++ b/arch/x86/include/asm/e820.h @@ -53,13 +53,6 @@ */ #define E820_RESERVED_KERN 128 -/* - * Address ranges that need to be mapped by the kernel direct - * mapping. This is used to make sure regions such as - * EFI_RUNTIME_SERVICES_DATA are directly mapped. See setup_arch(). - */ -#define E820_RESERVED_EFI 129 - #ifndef __ASSEMBLY__ #include <linux/types.h> struct e820entry { @@ -122,7 +115,6 @@ static inline void early_memtest(unsigned long start, unsigned long end) } #endif -extern unsigned long e820_end_pfn(unsigned long limit_pfn, unsigned type); extern unsigned long e820_end_of_ram_pfn(void); extern unsigned long e820_end_of_low_ram_pfn(void); extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align); diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index b8d8bfcd44a9..7093e4a6a0bc 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -33,6 +33,8 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...); #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \ efi_call_virt(f, a1, a2, a3, a4, a5, a6) +#define efi_ioremap(addr, size, type) ioremap_cache(addr, size) + #else /* !CONFIG_X86_32 */ extern u64 efi_call0(void *fp); @@ -82,6 +84,9 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3, efi_call6((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6)) +extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size, + u32 type); + #endif /* CONFIG_X86_32 */ extern int add_efi_memmap; diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 65ffd110a81b..303a0e48f076 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -135,7 +135,6 @@ static void __init e820_print_type(u32 type) printk(KERN_CONT "(usable)"); break; case E820_RESERVED: - case E820_RESERVED_EFI: printk(KERN_CONT "(reserved)"); break; case E820_ACPI: @@ -784,7 +783,7 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align) /* * Find the highest page frame number we have available */ -unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type) +static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type) { int i; unsigned long last_pfn = 0; diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 9a9e40fb091c..cf0ef986cb6d 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -691,8 +691,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(); @@ -934,24 +932,7 @@ 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, such as - * EFI_RUNTIME_SERVICES_DATA. - */ - if (efi_enabled) { - unsigned long efi_end; - - efi_end = e820_end_pfn(MAXMEM>>PAGE_SHIFT, E820_RESERVED_EFI); - if (efi_end > max_low_pfn) - end_pfn = efi_end; - } -#endif - - max_low_pfn_mapped = init_memory_mapping(0, end_pfn << PAGE_SHIFT); + max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT); max_pfn_mapped = max_low_pfn_mapped; #ifdef CONFIG_X86_64 diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index c9718a16be15..37718f0f053d 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -323,13 +323,10 @@ static void __init do_add_efi_memmap(void) case EFI_UNUSABLE_MEMORY: e820_type = E820_UNUSABLE; break; - case EFI_RUNTIME_SERVICES_DATA: - e820_type = E820_RESERVED_EFI; - break; default: /* * EFI_RESERVED_TYPE EFI_RUNTIME_SERVICES_CODE - * EFI_MEMORY_MAPPED_IO + * EFI_RUNTIME_SERVICES_DATA EFI_MEMORY_MAPPED_IO * EFI_MEMORY_MAPPED_IO_PORT_SPACE EFI_PAL_CODE */ e820_type = E820_RESERVED; @@ -674,21 +671,10 @@ void __init efi_enter_virtual_mode(void) end_pfn = PFN_UP(end); if (end_pfn <= max_low_pfn_mapped || (end_pfn > (1UL << (32 - PAGE_SHIFT)) - && end_pfn <= max_pfn_mapped)) { + && end_pfn <= max_pfn_mapped)) va = __va(md->phys_addr); - - if (!(md->attribute & EFI_MEMORY_WB)) { - addr = (u64) (unsigned long)va; - npages = md->num_pages; - memrange_efi_to_native(&addr, &npages); - set_memory_uc(addr, npages); - } - } else { - if (!(md->attribute & EFI_MEMORY_WB)) - va = ioremap_nocache(md->phys_addr, size); - else - va = ioremap_cache(md->phys_addr, size); - } + else + va = efi_ioremap(md->phys_addr, size, md->type); md->virt_addr = (u64) (unsigned long) va; @@ -698,6 +684,13 @@ void __init efi_enter_virtual_mode(void) continue; } + if (!(md->attribute & EFI_MEMORY_WB)) { + addr = md->virt_addr; + npages = md->num_pages; + memrange_efi_to_native(&addr, &npages); + set_memory_uc(addr, npages); + } + systab = (u64) (unsigned long) efi_phys.systab; if (md->phys_addr <= systab && systab < end) { systab += md->virt_addr - md->phys_addr; diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c index e36bf714cb77..40e446941dd7 100644 --- a/arch/x86/platform/efi/efi_32.c +++ b/arch/x86/platform/efi/efi_32.c @@ -39,43 +39,14 @@ */ static unsigned long efi_rt_eflags; -static pgd_t efi_bak_pg_dir_pointer[2]; void efi_call_phys_prelog(void) { - unsigned long cr4; - unsigned long temp; struct desc_ptr gdt_descr; local_irq_save(efi_rt_eflags); - /* - * If I don't have PAE, I should just duplicate two entries in page - * directory. If I have PAE, I just need to duplicate one entry in - * page directory. - */ - cr4 = read_cr4_safe(); - - if (cr4 & X86_CR4_PAE) { - efi_bak_pg_dir_pointer[0].pgd = - swapper_pg_dir[pgd_index(0)].pgd; - swapper_pg_dir[0].pgd = - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd; - } else { - efi_bak_pg_dir_pointer[0].pgd = - swapper_pg_dir[pgd_index(0)].pgd; - efi_bak_pg_dir_pointer[1].pgd = - swapper_pg_dir[pgd_index(0x400000)].pgd; - swapper_pg_dir[pgd_index(0)].pgd = - swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd; - temp = PAGE_OFFSET + 0x400000; - swapper_pg_dir[pgd_index(0x400000)].pgd = - swapper_pg_dir[pgd_index(temp)].pgd; - } - - /* - * After the lock is released, the original page table is restored. - */ + load_cr3(initial_page_table); __flush_tlb_all(); gdt_descr.address = __pa(get_cpu_gdt_table(0)); @@ -85,28 +56,13 @@ void efi_call_phys_prelog(void) void efi_call_phys_epilog(void) { - unsigned long cr4; struct desc_ptr gdt_descr; gdt_descr.address = (unsigned long)get_cpu_gdt_table(0); gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); - cr4 = read_cr4_safe(); - - if (cr4 & X86_CR4_PAE) { - swapper_pg_dir[pgd_index(0)].pgd = - efi_bak_pg_dir_pointer[0].pgd; - } else { - swapper_pg_dir[pgd_index(0)].pgd = - efi_bak_pg_dir_pointer[0].pgd; - swapper_pg_dir[pgd_index(0x400000)].pgd = - efi_bak_pg_dir_pointer[1].pgd; - } - - /* - * After the lock is released, the original page table is restored. - */ + load_cr3(swapper_pg_dir); __flush_tlb_all(); local_irq_restore(efi_rt_eflags); diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 312250c6b2de..ac3aa54e2654 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -80,3 +80,20 @@ void __init efi_call_phys_epilog(void) local_irq_restore(efi_flags); early_code_mapping_set_exec(0); } + +void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size, + u32 type) +{ + unsigned long last_map_pfn; + + if (type == EFI_MEMORY_MAPPED_IO) + return ioremap(phys_addr, size); + + last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size); + if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) { + unsigned long top = last_map_pfn << PAGE_SHIFT; + efi_ioremap(top, size - (top - phys_addr), type); + } + + return (void __iomem *)__va(phys_addr); +} |