diff options
Diffstat (limited to 'arch/arm64/kernel/efi.c')
-rw-r--r-- | arch/arm64/kernel/efi.c | 369 |
1 files changed, 121 insertions, 248 deletions
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index 2bb4347d0edf..a98415b5979c 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c | |||
@@ -11,25 +11,31 @@ | |||
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/atomic.h> | ||
14 | #include <linux/dmi.h> | 15 | #include <linux/dmi.h> |
15 | #include <linux/efi.h> | 16 | #include <linux/efi.h> |
16 | #include <linux/export.h> | 17 | #include <linux/export.h> |
17 | #include <linux/memblock.h> | 18 | #include <linux/memblock.h> |
19 | #include <linux/mm_types.h> | ||
18 | #include <linux/bootmem.h> | 20 | #include <linux/bootmem.h> |
19 | #include <linux/of.h> | 21 | #include <linux/of.h> |
20 | #include <linux/of_fdt.h> | 22 | #include <linux/of_fdt.h> |
23 | #include <linux/preempt.h> | ||
24 | #include <linux/rbtree.h> | ||
25 | #include <linux/rwsem.h> | ||
21 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
22 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/spinlock.h> | ||
23 | 29 | ||
24 | #include <asm/cacheflush.h> | 30 | #include <asm/cacheflush.h> |
25 | #include <asm/efi.h> | 31 | #include <asm/efi.h> |
26 | #include <asm/tlbflush.h> | 32 | #include <asm/tlbflush.h> |
27 | #include <asm/mmu_context.h> | 33 | #include <asm/mmu_context.h> |
34 | #include <asm/mmu.h> | ||
35 | #include <asm/pgtable.h> | ||
28 | 36 | ||
29 | struct efi_memory_map memmap; | 37 | struct efi_memory_map memmap; |
30 | 38 | ||
31 | static efi_runtime_services_t *runtime; | ||
32 | |||
33 | static u64 efi_system_table; | 39 | static u64 efi_system_table; |
34 | 40 | ||
35 | static int uefi_debug __initdata; | 41 | static int uefi_debug __initdata; |
@@ -48,30 +54,33 @@ static int __init is_normal_ram(efi_memory_desc_t *md) | |||
48 | return 0; | 54 | return 0; |
49 | } | 55 | } |
50 | 56 | ||
51 | static void __init efi_setup_idmap(void) | 57 | /* |
58 | * Translate a EFI virtual address into a physical address: this is necessary, | ||
59 | * as some data members of the EFI system table are virtually remapped after | ||
60 | * SetVirtualAddressMap() has been called. | ||
61 | */ | ||
62 | static phys_addr_t efi_to_phys(unsigned long addr) | ||
52 | { | 63 | { |
53 | struct memblock_region *r; | ||
54 | efi_memory_desc_t *md; | 64 | efi_memory_desc_t *md; |
55 | u64 paddr, npages, size; | ||
56 | |||
57 | for_each_memblock(memory, r) | ||
58 | create_id_mapping(r->base, r->size, 0); | ||
59 | 65 | ||
60 | /* map runtime io spaces */ | ||
61 | for_each_efi_memory_desc(&memmap, md) { | 66 | for_each_efi_memory_desc(&memmap, md) { |
62 | if (!(md->attribute & EFI_MEMORY_RUNTIME) || is_normal_ram(md)) | 67 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) |
63 | continue; | 68 | continue; |
64 | paddr = md->phys_addr; | 69 | if (md->virt_addr == 0) |
65 | npages = md->num_pages; | 70 | /* no virtual mapping has been installed by the stub */ |
66 | memrange_efi_to_native(&paddr, &npages); | 71 | break; |
67 | size = npages << PAGE_SHIFT; | 72 | if (md->virt_addr <= addr && |
68 | create_id_mapping(paddr, size, 1); | 73 | (addr - md->virt_addr) < (md->num_pages << EFI_PAGE_SHIFT)) |
74 | return md->phys_addr + addr - md->virt_addr; | ||
69 | } | 75 | } |
76 | return addr; | ||
70 | } | 77 | } |
71 | 78 | ||
72 | static int __init uefi_init(void) | 79 | static int __init uefi_init(void) |
73 | { | 80 | { |
74 | efi_char16_t *c16; | 81 | efi_char16_t *c16; |
82 | void *config_tables; | ||
83 | u64 table_size; | ||
75 | char vendor[100] = "unknown"; | 84 | char vendor[100] = "unknown"; |
76 | int i, retval; | 85 | int i, retval; |
77 | 86 | ||
@@ -99,7 +108,7 @@ static int __init uefi_init(void) | |||
99 | efi.systab->hdr.revision & 0xffff); | 108 | efi.systab->hdr.revision & 0xffff); |
100 | 109 | ||
101 | /* Show what we know for posterity */ | 110 | /* Show what we know for posterity */ |
102 | c16 = early_memremap(efi.systab->fw_vendor, | 111 | c16 = early_memremap(efi_to_phys(efi.systab->fw_vendor), |
103 | sizeof(vendor)); | 112 | sizeof(vendor)); |
104 | if (c16) { | 113 | if (c16) { |
105 | for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i) | 114 | for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i) |
@@ -112,8 +121,14 @@ static int __init uefi_init(void) | |||
112 | efi.systab->hdr.revision >> 16, | 121 | efi.systab->hdr.revision >> 16, |
113 | efi.systab->hdr.revision & 0xffff, vendor); | 122 | efi.systab->hdr.revision & 0xffff, vendor); |
114 | 123 | ||
115 | retval = efi_config_init(NULL); | 124 | table_size = sizeof(efi_config_table_64_t) * efi.systab->nr_tables; |
125 | config_tables = early_memremap(efi_to_phys(efi.systab->tables), | ||
126 | table_size); | ||
127 | |||
128 | retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables, | ||
129 | sizeof(efi_config_table_64_t), NULL); | ||
116 | 130 | ||
131 | early_memunmap(config_tables, table_size); | ||
117 | out: | 132 | out: |
118 | early_memunmap(efi.systab, sizeof(efi_system_table_t)); | 133 | early_memunmap(efi.systab, sizeof(efi_system_table_t)); |
119 | return retval; | 134 | return retval; |
@@ -163,9 +178,7 @@ static __init void reserve_regions(void) | |||
163 | if (is_normal_ram(md)) | 178 | if (is_normal_ram(md)) |
164 | early_init_dt_add_memory_arch(paddr, size); | 179 | early_init_dt_add_memory_arch(paddr, size); |
165 | 180 | ||
166 | if (is_reserve_region(md) || | 181 | if (is_reserve_region(md)) { |
167 | md->type == EFI_BOOT_SERVICES_CODE || | ||
168 | md->type == EFI_BOOT_SERVICES_DATA) { | ||
169 | memblock_reserve(paddr, size); | 182 | memblock_reserve(paddr, size); |
170 | if (uefi_debug) | 183 | if (uefi_debug) |
171 | pr_cont("*"); | 184 | pr_cont("*"); |
@@ -178,123 +191,6 @@ static __init void reserve_regions(void) | |||
178 | set_bit(EFI_MEMMAP, &efi.flags); | 191 | set_bit(EFI_MEMMAP, &efi.flags); |
179 | } | 192 | } |
180 | 193 | ||
181 | |||
182 | static u64 __init free_one_region(u64 start, u64 end) | ||
183 | { | ||
184 | u64 size = end - start; | ||
185 | |||
186 | if (uefi_debug) | ||
187 | pr_info(" EFI freeing: 0x%012llx-0x%012llx\n", start, end - 1); | ||
188 | |||
189 | free_bootmem_late(start, size); | ||
190 | return size; | ||
191 | } | ||
192 | |||
193 | static u64 __init free_region(u64 start, u64 end) | ||
194 | { | ||
195 | u64 map_start, map_end, total = 0; | ||
196 | |||
197 | if (end <= start) | ||
198 | return total; | ||
199 | |||
200 | map_start = (u64)memmap.phys_map; | ||
201 | map_end = PAGE_ALIGN(map_start + (memmap.map_end - memmap.map)); | ||
202 | map_start &= PAGE_MASK; | ||
203 | |||
204 | if (start < map_end && end > map_start) { | ||
205 | /* region overlaps UEFI memmap */ | ||
206 | if (start < map_start) | ||
207 | total += free_one_region(start, map_start); | ||
208 | |||
209 | if (map_end < end) | ||
210 | total += free_one_region(map_end, end); | ||
211 | } else | ||
212 | total += free_one_region(start, end); | ||
213 | |||
214 | return total; | ||
215 | } | ||
216 | |||
217 | static void __init free_boot_services(void) | ||
218 | { | ||
219 | u64 total_freed = 0; | ||
220 | u64 keep_end, free_start, free_end; | ||
221 | efi_memory_desc_t *md; | ||
222 | |||
223 | /* | ||
224 | * If kernel uses larger pages than UEFI, we have to be careful | ||
225 | * not to inadvertantly free memory we want to keep if there is | ||
226 | * overlap at the kernel page size alignment. We do not want to | ||
227 | * free is_reserve_region() memory nor the UEFI memmap itself. | ||
228 | * | ||
229 | * The memory map is sorted, so we keep track of the end of | ||
230 | * any previous region we want to keep, remember any region | ||
231 | * we want to free and defer freeing it until we encounter | ||
232 | * the next region we want to keep. This way, before freeing | ||
233 | * it, we can clip it as needed to avoid freeing memory we | ||
234 | * want to keep for UEFI. | ||
235 | */ | ||
236 | |||
237 | keep_end = 0; | ||
238 | free_start = 0; | ||
239 | |||
240 | for_each_efi_memory_desc(&memmap, md) { | ||
241 | u64 paddr, npages, size; | ||
242 | |||
243 | if (is_reserve_region(md)) { | ||
244 | /* | ||
245 | * We don't want to free any memory from this region. | ||
246 | */ | ||
247 | if (free_start) { | ||
248 | /* adjust free_end then free region */ | ||
249 | if (free_end > md->phys_addr) | ||
250 | free_end -= PAGE_SIZE; | ||
251 | total_freed += free_region(free_start, free_end); | ||
252 | free_start = 0; | ||
253 | } | ||
254 | keep_end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT); | ||
255 | continue; | ||
256 | } | ||
257 | |||
258 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
259 | md->type != EFI_BOOT_SERVICES_DATA) { | ||
260 | /* no need to free this region */ | ||
261 | continue; | ||
262 | } | ||
263 | |||
264 | /* | ||
265 | * We want to free memory from this region. | ||
266 | */ | ||
267 | paddr = md->phys_addr; | ||
268 | npages = md->num_pages; | ||
269 | memrange_efi_to_native(&paddr, &npages); | ||
270 | size = npages << PAGE_SHIFT; | ||
271 | |||
272 | if (free_start) { | ||
273 | if (paddr <= free_end) | ||
274 | free_end = paddr + size; | ||
275 | else { | ||
276 | total_freed += free_region(free_start, free_end); | ||
277 | free_start = paddr; | ||
278 | free_end = paddr + size; | ||
279 | } | ||
280 | } else { | ||
281 | free_start = paddr; | ||
282 | free_end = paddr + size; | ||
283 | } | ||
284 | if (free_start < keep_end) { | ||
285 | free_start += PAGE_SIZE; | ||
286 | if (free_start >= free_end) | ||
287 | free_start = 0; | ||
288 | } | ||
289 | } | ||
290 | if (free_start) | ||
291 | total_freed += free_region(free_start, free_end); | ||
292 | |||
293 | if (total_freed) | ||
294 | pr_info("Freed 0x%llx bytes of EFI boot services memory", | ||
295 | total_freed); | ||
296 | } | ||
297 | |||
298 | void __init efi_init(void) | 194 | void __init efi_init(void) |
299 | { | 195 | { |
300 | struct efi_fdt_params params; | 196 | struct efi_fdt_params params; |
@@ -319,61 +215,14 @@ void __init efi_init(void) | |||
319 | reserve_regions(); | 215 | reserve_regions(); |
320 | } | 216 | } |
321 | 217 | ||
322 | void __init efi_idmap_init(void) | ||
323 | { | ||
324 | if (!efi_enabled(EFI_BOOT)) | ||
325 | return; | ||
326 | |||
327 | /* boot time idmap_pg_dir is incomplete, so fill in missing parts */ | ||
328 | efi_setup_idmap(); | ||
329 | early_memunmap(memmap.map, memmap.map_end - memmap.map); | ||
330 | } | ||
331 | |||
332 | static int __init remap_region(efi_memory_desc_t *md, void **new) | ||
333 | { | ||
334 | u64 paddr, vaddr, npages, size; | ||
335 | |||
336 | paddr = md->phys_addr; | ||
337 | npages = md->num_pages; | ||
338 | memrange_efi_to_native(&paddr, &npages); | ||
339 | size = npages << PAGE_SHIFT; | ||
340 | |||
341 | if (is_normal_ram(md)) | ||
342 | vaddr = (__force u64)ioremap_cache(paddr, size); | ||
343 | else | ||
344 | vaddr = (__force u64)ioremap(paddr, size); | ||
345 | |||
346 | if (!vaddr) { | ||
347 | pr_err("Unable to remap 0x%llx pages @ %p\n", | ||
348 | npages, (void *)paddr); | ||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | /* adjust for any rounding when EFI and system pagesize differs */ | ||
353 | md->virt_addr = vaddr + (md->phys_addr - paddr); | ||
354 | |||
355 | if (uefi_debug) | ||
356 | pr_info(" EFI remap 0x%012llx => %p\n", | ||
357 | md->phys_addr, (void *)md->virt_addr); | ||
358 | |||
359 | memcpy(*new, md, memmap.desc_size); | ||
360 | *new += memmap.desc_size; | ||
361 | |||
362 | return 1; | ||
363 | } | ||
364 | |||
365 | /* | 218 | /* |
366 | * Switch UEFI from an identity map to a kernel virtual map | 219 | * Enable the UEFI Runtime Services if all prerequisites are in place, i.e., |
220 | * non-early mapping of the UEFI system table and virtual mappings for all | ||
221 | * EFI_MEMORY_RUNTIME regions. | ||
367 | */ | 222 | */ |
368 | static int __init arm64_enter_virtual_mode(void) | 223 | static int __init arm64_enable_runtime_services(void) |
369 | { | 224 | { |
370 | efi_memory_desc_t *md; | ||
371 | phys_addr_t virtmap_phys; | ||
372 | void *virtmap, *virt_md; | ||
373 | efi_status_t status; | ||
374 | u64 mapsize; | 225 | u64 mapsize; |
375 | int count = 0; | ||
376 | unsigned long flags; | ||
377 | 226 | ||
378 | if (!efi_enabled(EFI_BOOT)) { | 227 | if (!efi_enabled(EFI_BOOT)) { |
379 | pr_info("EFI services will not be available.\n"); | 228 | pr_info("EFI services will not be available.\n"); |
@@ -395,81 +244,28 @@ static int __init arm64_enter_virtual_mode(void) | |||
395 | 244 | ||
396 | efi.memmap = &memmap; | 245 | efi.memmap = &memmap; |
397 | 246 | ||
398 | /* Map the runtime regions */ | 247 | efi.systab = (__force void *)ioremap_cache(efi_system_table, |
399 | virtmap = kmalloc(mapsize, GFP_KERNEL); | 248 | sizeof(efi_system_table_t)); |
400 | if (!virtmap) { | ||
401 | pr_err("Failed to allocate EFI virtual memmap\n"); | ||
402 | return -1; | ||
403 | } | ||
404 | virtmap_phys = virt_to_phys(virtmap); | ||
405 | virt_md = virtmap; | ||
406 | |||
407 | for_each_efi_memory_desc(&memmap, md) { | ||
408 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) | ||
409 | continue; | ||
410 | if (!remap_region(md, &virt_md)) | ||
411 | goto err_unmap; | ||
412 | ++count; | ||
413 | } | ||
414 | |||
415 | efi.systab = (__force void *)efi_lookup_mapped_addr(efi_system_table); | ||
416 | if (!efi.systab) { | 249 | if (!efi.systab) { |
417 | /* | 250 | pr_err("Failed to remap EFI System Table\n"); |
418 | * If we have no virtual mapping for the System Table at this | 251 | return -1; |
419 | * point, the memory map doesn't cover the physical offset where | ||
420 | * it resides. This means the System Table will be inaccessible | ||
421 | * to Runtime Services themselves once the virtual mapping is | ||
422 | * installed. | ||
423 | */ | ||
424 | pr_err("Failed to remap EFI System Table -- buggy firmware?\n"); | ||
425 | goto err_unmap; | ||
426 | } | 252 | } |
427 | set_bit(EFI_SYSTEM_TABLES, &efi.flags); | 253 | set_bit(EFI_SYSTEM_TABLES, &efi.flags); |
428 | 254 | ||
429 | local_irq_save(flags); | 255 | if (!efi_enabled(EFI_VIRTMAP)) { |
430 | cpu_switch_mm(idmap_pg_dir, &init_mm); | 256 | pr_err("No UEFI virtual mapping was installed -- runtime services will not be available\n"); |
431 | |||
432 | /* Call SetVirtualAddressMap with the physical address of the map */ | ||
433 | runtime = efi.systab->runtime; | ||
434 | efi.set_virtual_address_map = runtime->set_virtual_address_map; | ||
435 | |||
436 | status = efi.set_virtual_address_map(count * memmap.desc_size, | ||
437 | memmap.desc_size, | ||
438 | memmap.desc_version, | ||
439 | (efi_memory_desc_t *)virtmap_phys); | ||
440 | cpu_set_reserved_ttbr0(); | ||
441 | flush_tlb_all(); | ||
442 | local_irq_restore(flags); | ||
443 | |||
444 | kfree(virtmap); | ||
445 | |||
446 | free_boot_services(); | ||
447 | |||
448 | if (status != EFI_SUCCESS) { | ||
449 | pr_err("Failed to set EFI virtual address map! [%lx]\n", | ||
450 | status); | ||
451 | return -1; | 257 | return -1; |
452 | } | 258 | } |
453 | 259 | ||
454 | /* Set up runtime services function pointers */ | 260 | /* Set up runtime services function pointers */ |
455 | runtime = efi.systab->runtime; | ||
456 | efi_native_runtime_setup(); | 261 | efi_native_runtime_setup(); |
457 | set_bit(EFI_RUNTIME_SERVICES, &efi.flags); | 262 | set_bit(EFI_RUNTIME_SERVICES, &efi.flags); |
458 | 263 | ||
459 | efi.runtime_version = efi.systab->hdr.revision; | 264 | efi.runtime_version = efi.systab->hdr.revision; |
460 | 265 | ||
461 | return 0; | 266 | return 0; |
462 | |||
463 | err_unmap: | ||
464 | /* unmap all mappings that succeeded: there are 'count' of those */ | ||
465 | for (virt_md = virtmap; count--; virt_md += memmap.desc_size) { | ||
466 | md = virt_md; | ||
467 | iounmap((__force void __iomem *)md->virt_addr); | ||
468 | } | ||
469 | kfree(virtmap); | ||
470 | return -1; | ||
471 | } | 267 | } |
472 | early_initcall(arm64_enter_virtual_mode); | 268 | early_initcall(arm64_enable_runtime_services); |
473 | 269 | ||
474 | static int __init arm64_dmi_init(void) | 270 | static int __init arm64_dmi_init(void) |
475 | { | 271 | { |
@@ -484,3 +280,80 @@ static int __init arm64_dmi_init(void) | |||
484 | return 0; | 280 | return 0; |
485 | } | 281 | } |
486 | core_initcall(arm64_dmi_init); | 282 | core_initcall(arm64_dmi_init); |
283 | |||
284 | static pgd_t efi_pgd[PTRS_PER_PGD] __page_aligned_bss; | ||
285 | |||
286 | static struct mm_struct efi_mm = { | ||
287 | .mm_rb = RB_ROOT, | ||
288 | .pgd = efi_pgd, | ||
289 | .mm_users = ATOMIC_INIT(2), | ||
290 | .mm_count = ATOMIC_INIT(1), | ||
291 | .mmap_sem = __RWSEM_INITIALIZER(efi_mm.mmap_sem), | ||
292 | .page_table_lock = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock), | ||
293 | .mmlist = LIST_HEAD_INIT(efi_mm.mmlist), | ||
294 | INIT_MM_CONTEXT(efi_mm) | ||
295 | }; | ||
296 | |||
297 | static void efi_set_pgd(struct mm_struct *mm) | ||
298 | { | ||
299 | cpu_switch_mm(mm->pgd, mm); | ||
300 | flush_tlb_all(); | ||
301 | if (icache_is_aivivt()) | ||
302 | __flush_icache_all(); | ||
303 | } | ||
304 | |||
305 | void efi_virtmap_load(void) | ||
306 | { | ||
307 | preempt_disable(); | ||
308 | efi_set_pgd(&efi_mm); | ||
309 | } | ||
310 | |||
311 | void efi_virtmap_unload(void) | ||
312 | { | ||
313 | efi_set_pgd(current->active_mm); | ||
314 | preempt_enable(); | ||
315 | } | ||
316 | |||
317 | void __init efi_virtmap_init(void) | ||
318 | { | ||
319 | efi_memory_desc_t *md; | ||
320 | |||
321 | if (!efi_enabled(EFI_BOOT)) | ||
322 | return; | ||
323 | |||
324 | for_each_efi_memory_desc(&memmap, md) { | ||
325 | u64 paddr, npages, size; | ||
326 | pgprot_t prot; | ||
327 | |||
328 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) | ||
329 | continue; | ||
330 | if (WARN(md->virt_addr == 0, | ||
331 | "UEFI virtual mapping incomplete or missing -- no entry found for 0x%llx\n", | ||
332 | md->phys_addr)) | ||
333 | return; | ||
334 | |||
335 | paddr = md->phys_addr; | ||
336 | npages = md->num_pages; | ||
337 | memrange_efi_to_native(&paddr, &npages); | ||
338 | size = npages << PAGE_SHIFT; | ||
339 | |||
340 | pr_info(" EFI remap 0x%016llx => %p\n", | ||
341 | md->phys_addr, (void *)md->virt_addr); | ||
342 | |||
343 | /* | ||
344 | * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be | ||
345 | * executable, everything else can be mapped with the XN bits | ||
346 | * set. | ||
347 | */ | ||
348 | if (!is_normal_ram(md)) | ||
349 | prot = __pgprot(PROT_DEVICE_nGnRE); | ||
350 | else if (md->type == EFI_RUNTIME_SERVICES_CODE) | ||
351 | prot = PAGE_KERNEL_EXEC; | ||
352 | else | ||
353 | prot = PAGE_KERNEL; | ||
354 | |||
355 | create_pgd_mapping(&efi_mm, paddr, md->virt_addr, size, prot); | ||
356 | } | ||
357 | set_bit(EFI_VIRTMAP, &efi.flags); | ||
358 | early_memunmap(memmap.map, memmap.map_end - memmap.map); | ||
359 | } | ||