Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

efi: Use correct type for struct efi_memory_map::phys_map

We have been getting away with using a void* for the physical
address of the UEFI memory map, since, even on 32-bit platforms
with 64-bit physical addresses, no truncation takes place if the
memory map has been allocated by the firmware (which only uses
1:1 virtually addressable memory), which is usually the case.

However, commit:

0f96a99dab36 ("efi: Add "efi_fake_mem" boot option")

adds code that clones and modifies the UEFI memory map, and the
clone may live above 4 GB on 32-bit platforms.

This means our use of void* for struct efi_memory_map::phys_map has
graduated from 'incorrect but working' to 'incorrect and
broken', and we need to fix it.

So redefine struct efi_memory_map::phys_map as phys_addr_t, and
get rid of a bunch of casts that are now unneeded.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: izumi.taku@jp.fujitsu.com
Cc: kamezawa.hiroyu@jp.fujitsu.com
Cc: linux-efi@vger.kernel.org
Cc: matt.fleming@intel.com
Link: http://lkml.kernel.org/r/1445593697-1342-1-git-send-email-ard.biesheuvel@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Ard Biesheuvel and committed by
Ingo Molnar
44511fb9 06ef431a

+9 -9
+2 -2
arch/arm64/kernel/efi.c
··· 208 208 209 209 memblock_reserve(params.mmap & PAGE_MASK, 210 210 PAGE_ALIGN(params.mmap_size + (params.mmap & ~PAGE_MASK))); 211 - memmap.phys_map = (void *)params.mmap; 211 + memmap.phys_map = params.mmap; 212 212 memmap.map = early_memremap(params.mmap, params.mmap_size); 213 213 memmap.map_end = memmap.map + params.mmap_size; 214 214 memmap.desc_size = params.desc_size; ··· 282 282 pr_info("Remapping and enabling EFI services.\n"); 283 283 284 284 mapsize = memmap.map_end - memmap.map; 285 - memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map, 285 + memmap.map = (__force void *)ioremap_cache(memmap.phys_map, 286 286 mapsize); 287 287 if (!memmap.map) { 288 288 pr_err("Failed to remap EFI memory map\n");
+2 -2
arch/x86/platform/efi/efi.c
··· 194 194 int __init efi_memblock_x86_reserve_range(void) 195 195 { 196 196 struct efi_info *e = &boot_params.efi_info; 197 - unsigned long pmap; 197 + phys_addr_t pmap; 198 198 199 199 if (efi_enabled(EFI_PARAVIRT)) 200 200 return 0; ··· 209 209 #else 210 210 pmap = (e->efi_memmap | ((__u64)e->efi_memmap_hi << 32)); 211 211 #endif 212 - memmap.phys_map = (void *)pmap; 212 + memmap.phys_map = pmap; 213 213 memmap.nr_map = e->efi_memmap_size / 214 214 e->efi_memdesc_size; 215 215 memmap.desc_size = e->efi_memdesc_size;
+4 -4
drivers/firmware/efi/efi.c
··· 254 254 int __init efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md) 255 255 { 256 256 struct efi_memory_map *map = efi.memmap; 257 - void *p, *e; 257 + phys_addr_t p, e; 258 258 259 259 if (!efi_enabled(EFI_MEMMAP)) { 260 260 pr_err_once("EFI_MEMMAP is not enabled.\n"); ··· 286 286 * So just always get our own virtual map on the CPU. 287 287 * 288 288 */ 289 - md = early_memremap((phys_addr_t)p, sizeof (*md)); 289 + md = early_memremap(p, sizeof (*md)); 290 290 if (!md) { 291 - pr_err_once("early_memremap(%p, %zu) failed.\n", 292 - p, sizeof (*md)); 291 + pr_err_once("early_memremap(%pa, %zu) failed.\n", 292 + &p, sizeof (*md)); 293 293 return -ENOMEM; 294 294 } 295 295
+1 -1
include/linux/efi.h
··· 680 680 } efi_system_table_t; 681 681 682 682 struct efi_memory_map { 683 - void *phys_map; 683 + phys_addr_t phys_map; 684 684 void *map; 685 685 void *map_end; 686 686 int nr_map;