aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorMatt Fleming <matt@codeblueprint.co.uk>2016-02-27 10:52:50 -0500
committerMatt Fleming <matt@codeblueprint.co.uk>2016-09-09 11:07:43 -0400
commitdca0f971ea6fcf2f1bb78f7995adf80da9f4767f (patch)
treecbbaa3fa266dfc30f3899cbf4d9d9aa2b266d936 /drivers/firmware
parent9479c7cebfb568f8b8b424be7f1cac120e9eea95 (diff)
efi: Add efi_memmap_init_late() for permanent EFI memmap
Drivers need a way to access the EFI memory map at runtime. ARM and arm64 currently provide this by remapping the EFI memory map into the vmalloc space before setting up the EFI virtual mappings. x86 does not provide this functionality which has resulted in the code in efi_mem_desc_lookup() where it will manually map individual EFI memmap entries if the memmap has already been torn down on x86, /* * If a driver calls this after efi_free_boot_services, * ->map will be NULL, and the target may also not be mapped. * So just always get our own virtual map on the CPU. * */ md = early_memremap(p, sizeof (*md)); There isn't a good reason for not providing a permanent EFI memory map for runtime queries, especially since the EFI regions are not mapped into the standard kernel page tables. Tested-by: Dave Young <dyoung@redhat.com> [kexec/kdump] Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> [arm] Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Leif Lindholm <leif.lindholm@linaro.org> Cc: Peter Jones <pjones@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/efi/arm-runtime.c4
-rw-r--r--drivers/firmware/efi/efi.c135
2 files changed, 96 insertions, 43 deletions
diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
index eedb30351a68..ae001450545f 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -116,12 +116,10 @@ static int __init arm_enable_runtime_services(void)
116 116
117 mapsize = efi.memmap.desc_size * efi.memmap.nr_map; 117 mapsize = efi.memmap.desc_size * efi.memmap.nr_map;
118 118
119 efi.memmap.map = memremap(efi.memmap.phys_map, mapsize, MEMREMAP_WB); 119 if (efi_memmap_init_late(efi.memmap.phys_map, mapsize)) {
120 if (!efi.memmap.map) {
121 pr_err("Failed to remap EFI memory map\n"); 120 pr_err("Failed to remap EFI memory map\n");
122 return -ENOMEM; 121 return -ENOMEM;
123 } 122 }
124 efi.memmap.map_end = efi.memmap.map + mapsize;
125 123
126 if (!efi_virtmap_init()) { 124 if (!efi_virtmap_init()) {
127 pr_err("UEFI virtual mapping missing or invalid -- runtime services will not be available\n"); 125 pr_err("UEFI virtual mapping missing or invalid -- runtime services will not be available\n");
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index c1879999abe7..8a5e0db72b8f 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -347,56 +347,31 @@ subsys_initcall(efisubsys_init);
347 347
348/* 348/*
349 * Find the efi memory descriptor for a given physical address. Given a 349 * Find the efi memory descriptor for a given physical address. Given a
350 * physicall address, determine if it exists within an EFI Memory Map entry, 350 * physical address, determine if it exists within an EFI Memory Map entry,
351 * and if so, populate the supplied memory descriptor with the appropriate 351 * and if so, populate the supplied memory descriptor with the appropriate
352 * data. 352 * data.
353 */ 353 */
354int __init efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md) 354int __init efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
355{ 355{
356 struct efi_memory_map *map = &efi.memmap; 356 efi_memory_desc_t *md;
357 phys_addr_t p, e;
358 357
359 if (!efi_enabled(EFI_MEMMAP)) { 358 if (!efi_enabled(EFI_MEMMAP)) {
360 pr_err_once("EFI_MEMMAP is not enabled.\n"); 359 pr_err_once("EFI_MEMMAP is not enabled.\n");
361 return -EINVAL; 360 return -EINVAL;
362 } 361 }
363 362
364 if (!map) {
365 pr_err_once("efi.memmap is not set.\n");
366 return -EINVAL;
367 }
368 if (!out_md) { 363 if (!out_md) {
369 pr_err_once("out_md is null.\n"); 364 pr_err_once("out_md is null.\n");
370 return -EINVAL; 365 return -EINVAL;
371 } 366 }
372 if (WARN_ON_ONCE(!map->phys_map))
373 return -EINVAL;
374 if (WARN_ON_ONCE(map->nr_map == 0) || WARN_ON_ONCE(map->desc_size == 0))
375 return -EINVAL;
376 367
377 e = map->phys_map + map->nr_map * map->desc_size; 368 for_each_efi_memory_desc(md) {
378 for (p = map->phys_map; p < e; p += map->desc_size) {
379 efi_memory_desc_t *md;
380 u64 size; 369 u64 size;
381 u64 end; 370 u64 end;
382 371
383 /*
384 * If a driver calls this after efi_free_boot_services,
385 * ->map will be NULL, and the target may also not be mapped.
386 * So just always get our own virtual map on the CPU.
387 *
388 */
389 md = early_memremap(p, sizeof (*md));
390 if (!md) {
391 pr_err_once("early_memremap(%pa, %zu) failed.\n",
392 &p, sizeof (*md));
393 return -ENOMEM;
394 }
395
396 if (!(md->attribute & EFI_MEMORY_RUNTIME) && 372 if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
397 md->type != EFI_BOOT_SERVICES_DATA && 373 md->type != EFI_BOOT_SERVICES_DATA &&
398 md->type != EFI_RUNTIME_SERVICES_DATA) { 374 md->type != EFI_RUNTIME_SERVICES_DATA) {
399 early_memunmap(md, sizeof (*md));
400 continue; 375 continue;
401 } 376 }
402 377
@@ -404,11 +379,8 @@ int __init efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
404 end = md->phys_addr + size; 379 end = md->phys_addr + size;
405 if (phys_addr >= md->phys_addr && phys_addr < end) { 380 if (phys_addr >= md->phys_addr && phys_addr < end) {
406 memcpy(out_md, md, sizeof(*out_md)); 381 memcpy(out_md, md, sizeof(*out_md));
407 early_memunmap(md, sizeof (*md));
408 return 0; 382 return 0;
409 } 383 }
410
411 early_memunmap(md, sizeof (*md));
412 } 384 }
413 pr_err_once("requested map not found.\n"); 385 pr_err_once("requested map not found.\n");
414 return -ENOENT; 386 return -ENOENT;
@@ -545,32 +517,49 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
545} 517}
546 518
547/** 519/**
548 * efi_memmap_init_early - Map the EFI memory map data structure 520 * __efi_memmap_init - Common code for mapping the EFI memory map
549 * @data: EFI memory map data 521 * @data: EFI memory map data
522 * @late: Use early or late mapping function?
550 * 523 *
551 * Use early_memremap() to map the passed in EFI memory map and assign 524 * This function takes care of figuring out which function to use to
552 * it to efi.memmap. 525 * map the EFI memory map in efi.memmap based on how far into the boot
526 * we are.
527 *
528 * During bootup @late should be %false since we only have access to
529 * the early_memremap*() functions as the vmalloc space isn't setup.
530 * Once the kernel is fully booted we can fallback to the more robust
531 * memremap*() API.
532 *
533 * Returns zero on success, a negative error code on failure.
553 */ 534 */
554int __init efi_memmap_init_early(struct efi_memory_map_data *data) 535static int __init
536__efi_memmap_init(struct efi_memory_map_data *data, bool late)
555{ 537{
556 struct efi_memory_map map; 538 struct efi_memory_map map;
539 phys_addr_t phys_map;
557 540
558 if (efi_enabled(EFI_PARAVIRT)) 541 if (efi_enabled(EFI_PARAVIRT))
559 return 0; 542 return 0;
560 543
561 map.phys_map = data->phys_map; 544 phys_map = data->phys_map;
545
546 if (late)
547 map.map = memremap(phys_map, data->size, MEMREMAP_WB);
548 else
549 map.map = early_memremap(phys_map, data->size);
562 550
563 map.map = early_memremap(data->phys_map, data->size);
564 if (!map.map) { 551 if (!map.map) {
565 pr_err("Could not map the memory map!\n"); 552 pr_err("Could not map the memory map!\n");
566 return -ENOMEM; 553 return -ENOMEM;
567 } 554 }
568 555
556 map.phys_map = data->phys_map;
569 map.nr_map = data->size / data->desc_size; 557 map.nr_map = data->size / data->desc_size;
570 map.map_end = map.map + data->size; 558 map.map_end = map.map + data->size;
571 559
572 map.desc_version = data->desc_version; 560 map.desc_version = data->desc_version;
573 map.desc_size = data->desc_size; 561 map.desc_size = data->desc_size;
562 map.late = late;
574 563
575 set_bit(EFI_MEMMAP, &efi.flags); 564 set_bit(EFI_MEMMAP, &efi.flags);
576 565
@@ -579,17 +568,83 @@ int __init efi_memmap_init_early(struct efi_memory_map_data *data)
579 return 0; 568 return 0;
580} 569}
581 570
571/**
572 * efi_memmap_init_early - Map the EFI memory map data structure
573 * @data: EFI memory map data
574 *
575 * Use early_memremap() to map the passed in EFI memory map and assign
576 * it to efi.memmap.
577 */
578int __init efi_memmap_init_early(struct efi_memory_map_data *data)
579{
580 /* Cannot go backwards */
581 WARN_ON(efi.memmap.late);
582
583 return __efi_memmap_init(data, false);
584}
585
582void __init efi_memmap_unmap(void) 586void __init efi_memmap_unmap(void)
583{ 587{
584 unsigned long size; 588 if (!efi.memmap.late) {
589 unsigned long size;
585 590
586 size = efi.memmap.desc_size * efi.memmap.nr_map; 591 size = efi.memmap.desc_size * efi.memmap.nr_map;
592 early_memunmap(efi.memmap.map, size);
593 } else {
594 memunmap(efi.memmap.map);
595 }
587 596
588 early_memunmap(efi.memmap.map, size);
589 efi.memmap.map = NULL; 597 efi.memmap.map = NULL;
590 clear_bit(EFI_MEMMAP, &efi.flags); 598 clear_bit(EFI_MEMMAP, &efi.flags);
591} 599}
592 600
601/**
602 * efi_memmap_init_late - Map efi.memmap with memremap()
603 * @phys_addr: Physical address of the new EFI memory map
604 * @size: Size in bytes of the new EFI memory map
605 *
606 * Setup a mapping of the EFI memory map using ioremap_cache(). This
607 * function should only be called once the vmalloc space has been
608 * setup and is therefore not suitable for calling during early EFI
609 * initialise, e.g. in efi_init(). Additionally, it expects
610 * efi_memmap_init_early() to have already been called.
611 *
612 * The reason there are two EFI memmap initialisation
613 * (efi_memmap_init_early() and this late version) is because the
614 * early EFI memmap should be explicitly unmapped once EFI
615 * initialisation is complete as the fixmap space used to map the EFI
616 * memmap (via early_memremap()) is a scarce resource.
617 *
618 * This late mapping is intended to persist for the duration of
619 * runtime so that things like efi_mem_desc_lookup() and
620 * efi_mem_attributes() always work.
621 *
622 * Returns zero on success, a negative error code on failure.
623 */
624int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size)
625{
626 struct efi_memory_map_data data = {
627 .phys_map = addr,
628 .size = size,
629 };
630
631 /* Did we forget to unmap the early EFI memmap? */
632 WARN_ON(efi.memmap.map);
633
634 /* Were we already called? */
635 WARN_ON(efi.memmap.late);
636
637 /*
638 * It makes no sense to allow callers to register different
639 * values for the following fields. Copy them out of the
640 * existing early EFI memmap.
641 */
642 data.desc_version = efi.memmap.desc_version;
643 data.desc_size = efi.memmap.desc_size;
644
645 return __efi_memmap_init(&data, true);
646}
647
593#ifdef CONFIG_EFI_VARS_MODULE 648#ifdef CONFIG_EFI_VARS_MODULE
594static int __init efi_load_efivars(void) 649static int __init efi_load_efivars(void)
595{ 650{