| .. | .. |
|---|
| 24 | 24 | #include <linux/types.h> |
|---|
| 25 | 25 | #include <linux/ioport.h> |
|---|
| 26 | 26 | #include <linux/efi.h> |
|---|
| 27 | +#include <linux/pgtable.h> |
|---|
| 27 | 28 | |
|---|
| 28 | 29 | #include <asm/io.h> |
|---|
| 29 | 30 | #include <asm/desc.h> |
|---|
| 30 | 31 | #include <asm/page.h> |
|---|
| 31 | | -#include <asm/pgtable.h> |
|---|
| 32 | +#include <asm/set_memory.h> |
|---|
| 32 | 33 | #include <asm/tlbflush.h> |
|---|
| 33 | 34 | #include <asm/efi.h> |
|---|
| 35 | + |
|---|
| 36 | +void __init efi_map_region(efi_memory_desc_t *md) |
|---|
| 37 | +{ |
|---|
| 38 | + u64 start_pfn, end_pfn, end; |
|---|
| 39 | + unsigned long size; |
|---|
| 40 | + void *va; |
|---|
| 41 | + |
|---|
| 42 | + start_pfn = PFN_DOWN(md->phys_addr); |
|---|
| 43 | + size = md->num_pages << PAGE_SHIFT; |
|---|
| 44 | + end = md->phys_addr + size; |
|---|
| 45 | + end_pfn = PFN_UP(end); |
|---|
| 46 | + |
|---|
| 47 | + if (pfn_range_is_mapped(start_pfn, end_pfn)) { |
|---|
| 48 | + va = __va(md->phys_addr); |
|---|
| 49 | + |
|---|
| 50 | + if (!(md->attribute & EFI_MEMORY_WB)) |
|---|
| 51 | + set_memory_uc((unsigned long)va, md->num_pages); |
|---|
| 52 | + } else { |
|---|
| 53 | + va = ioremap_cache(md->phys_addr, size); |
|---|
| 54 | + } |
|---|
| 55 | + |
|---|
| 56 | + md->virt_addr = (unsigned long)va; |
|---|
| 57 | + if (!va) |
|---|
| 58 | + pr_err("ioremap of 0x%llX failed!\n", md->phys_addr); |
|---|
| 59 | +} |
|---|
| 34 | 60 | |
|---|
| 35 | 61 | /* |
|---|
| 36 | 62 | * To make EFI call EFI runtime service in physical addressing mode we need |
|---|
| .. | .. |
|---|
| 49 | 75 | void __init efi_dump_pagetable(void) |
|---|
| 50 | 76 | { |
|---|
| 51 | 77 | #ifdef CONFIG_EFI_PGT_DUMP |
|---|
| 52 | | - ptdump_walk_pgd_level(NULL, swapper_pg_dir); |
|---|
| 78 | + ptdump_walk_pgd_level(NULL, &init_mm); |
|---|
| 53 | 79 | #endif |
|---|
| 54 | 80 | } |
|---|
| 55 | 81 | |
|---|
| .. | .. |
|---|
| 58 | 84 | return 0; |
|---|
| 59 | 85 | } |
|---|
| 60 | 86 | |
|---|
| 61 | | -void __init efi_map_region(efi_memory_desc_t *md) |
|---|
| 62 | | -{ |
|---|
| 63 | | - old_map_region(md); |
|---|
| 64 | | -} |
|---|
| 65 | | - |
|---|
| 66 | 87 | void __init efi_map_region_fixed(efi_memory_desc_t *md) {} |
|---|
| 67 | 88 | void __init parse_efi_setup(u64 phys_addr, u32 data_len) {} |
|---|
| 68 | 89 | |
|---|
| 69 | | -pgd_t * __init efi_call_phys_prolog(void) |
|---|
| 90 | +efi_status_t efi_call_svam(efi_runtime_services_t * const *, |
|---|
| 91 | + u32, u32, u32, void *, u32); |
|---|
| 92 | + |
|---|
| 93 | +efi_status_t __init efi_set_virtual_address_map(unsigned long memory_map_size, |
|---|
| 94 | + unsigned long descriptor_size, |
|---|
| 95 | + u32 descriptor_version, |
|---|
| 96 | + efi_memory_desc_t *virtual_map, |
|---|
| 97 | + unsigned long systab_phys) |
|---|
| 70 | 98 | { |
|---|
| 99 | + const efi_system_table_t *systab = (efi_system_table_t *)systab_phys; |
|---|
| 71 | 100 | struct desc_ptr gdt_descr; |
|---|
| 101 | + efi_status_t status; |
|---|
| 102 | + unsigned long flags; |
|---|
| 72 | 103 | pgd_t *save_pgd; |
|---|
| 73 | 104 | |
|---|
| 74 | 105 | /* Current pgd is swapper_pg_dir, we'll restore it later: */ |
|---|
| .. | .. |
|---|
| 80 | 111 | gdt_descr.size = GDT_SIZE - 1; |
|---|
| 81 | 112 | load_gdt(&gdt_descr); |
|---|
| 82 | 113 | |
|---|
| 83 | | - return save_pgd; |
|---|
| 84 | | -} |
|---|
| 114 | + /* Disable interrupts around EFI calls: */ |
|---|
| 115 | + local_irq_save(flags); |
|---|
| 116 | + status = efi_call_svam(&systab->runtime, |
|---|
| 117 | + memory_map_size, descriptor_size, |
|---|
| 118 | + descriptor_version, virtual_map, |
|---|
| 119 | + __pa(&efi.runtime)); |
|---|
| 120 | + local_irq_restore(flags); |
|---|
| 85 | 121 | |
|---|
| 86 | | -void __init efi_call_phys_epilog(pgd_t *save_pgd) |
|---|
| 87 | | -{ |
|---|
| 88 | 122 | load_fixmap_gdt(0); |
|---|
| 89 | 123 | load_cr3(save_pgd); |
|---|
| 90 | 124 | __flush_tlb_all(); |
|---|
| 125 | + |
|---|
| 126 | + return status; |
|---|
| 91 | 127 | } |
|---|
| 92 | 128 | |
|---|
| 93 | 129 | void __init efi_runtime_update_mappings(void) |
|---|
| 94 | 130 | { |
|---|
| 95 | | - if (__supported_pte_mask & _PAGE_NX) |
|---|
| 96 | | - runtime_code_page_mkexec(); |
|---|
| 131 | + if (__supported_pte_mask & _PAGE_NX) { |
|---|
| 132 | + efi_memory_desc_t *md; |
|---|
| 133 | + |
|---|
| 134 | + /* Make EFI runtime service code area executable */ |
|---|
| 135 | + for_each_efi_memory_desc(md) { |
|---|
| 136 | + if (md->type != EFI_RUNTIME_SERVICES_CODE) |
|---|
| 137 | + continue; |
|---|
| 138 | + |
|---|
| 139 | + set_memory_x(md->virt_addr, md->num_pages); |
|---|
| 140 | + } |
|---|
| 141 | + } |
|---|
| 97 | 142 | } |
|---|