diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-12-17 10:39:55 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-12-17 10:39:55 -0800 |
commit | a114a18c7dbc2b7ac5a1379a8dcced6095c52ead (patch) | |
tree | f7cbac989f21d8e06e6cecbc5533c73feccc1350 /drivers/firmware/efi/efi.c | |
parent | ea200dec51285c82655e50ddb774fdb6b97e784d (diff) | |
parent | a470552ee8965da0fe6fd4df0aa39c4cda652c7c (diff) | |
download | linux-a114a18c7dbc2b7ac5a1379a8dcced6095c52ead.tar.bz2 |
Merge branch 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull EFI fixes from Ingo Molnar:
"Protect presistent EFI memory reservations from kexec, fix EFIFB early
console, EFI stub graphics output fixes and other misc fixes."
* 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
efi: Don't attempt to map RCI2 config table if it doesn't exist
efi/earlycon: Remap entire framebuffer after page initialization
efi: Fix efi_loaded_image_t::unload type
efi/gop: Fix memory leak in __gop_query32/64()
efi/gop: Return EFI_SUCCESS if a usable GOP was found
efi/gop: Return EFI_NOT_FOUND if there are no usable GOPs
efi/memreserve: Register reservations as 'reserved' in /proc/iomem
Diffstat (limited to 'drivers/firmware/efi/efi.c')
-rw-r--r-- | drivers/firmware/efi/efi.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 407816da9fcb..2b02cb165f16 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -979,6 +979,24 @@ static int __init efi_memreserve_map_root(void) return 0; } +static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size) +{ + struct resource *res, *parent; + + res = kzalloc(sizeof(struct resource), GFP_ATOMIC); + if (!res) + return -ENOMEM; + + res->name = "reserved"; + res->flags = IORESOURCE_MEM; + res->start = addr; + res->end = addr + size - 1; + + /* we expect a conflict with a 'System RAM' region */ + parent = request_resource_conflict(&iomem_resource, res); + return parent ? request_resource(parent, res) : 0; +} + int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) { struct linux_efi_memreserve *rsv; @@ -1003,7 +1021,7 @@ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) rsv->entry[index].size = size; memunmap(rsv); - return 0; + return efi_mem_reserve_iomem(addr, size); } memunmap(rsv); } @@ -1013,6 +1031,12 @@ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) if (!rsv) return -ENOMEM; + rc = efi_mem_reserve_iomem(__pa(rsv), SZ_4K); + if (rc) { + free_page((unsigned long)rsv); + return rc; + } + /* * The memremap() call above assumes that a linux_efi_memreserve entry * never crosses a page boundary, so let's ensure that this remains true @@ -1029,7 +1053,7 @@ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) efi_memreserve_root->next = __pa(rsv); spin_unlock(&efi_mem_reserve_persistent_lock); - return 0; + return efi_mem_reserve_iomem(addr, size); } static int __init efi_memreserve_root_init(void) |