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

Configure Feed

Select the types of activity you want to include in your feed.

kho: verify deserialization status and fix FDT alignment access

During boot, kho_restore_folio() relies on the memory map having been
successfully deserialized. If deserialization fails or no map is present,
attempting to restore the FDT folio is unsafe.

Update kho_mem_deserialize() to return a boolean indicating success. Use
this return value in kho_memory_init() to disable KHO if deserialization
fails. Also, the incoming FDT folio is never used, there is no reason to
restore it.

Additionally, use get_unaligned() to retrieve the memory map pointer from
the FDT. FDT properties are not guaranteed to be naturally aligned, and
accessing a 64-bit value via a pointer that is only 32-bit aligned can
cause faults.

Link: https://lkml.kernel.org/r/20251114190002.3311679-6-pasha.tatashin@soleen.com
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Reviewed-by: Pratyush Yadav <pratyush@kernel.org>
Cc: Alexander Graf <graf@amazon.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Baoquan He <bhe@redhat.com>
Cc: Coiby Xu <coxu@redhat.com>
Cc: Dave Vasilevsky <dave@vasilevsky.ca>
Cc: Eric Biggers <ebiggers@google.com>
Cc: Kees Cook <kees@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Pasha Tatashin and committed by
Andrew Morton
53f8f064 85de0090

+19 -13
+19 -13
kernel/liveupdate/kexec_handover.c
··· 18 18 #include <linux/list.h> 19 19 #include <linux/memblock.h> 20 20 #include <linux/page-isolation.h> 21 + #include <linux/unaligned.h> 21 22 #include <linux/vmalloc.h> 22 23 23 24 #include <asm/early_ioremap.h> ··· 452 451 } 453 452 } 454 453 455 - static void __init kho_mem_deserialize(const void *fdt) 454 + /* Return true if memory was deserizlied */ 455 + static bool __init kho_mem_deserialize(const void *fdt) 456 456 { 457 457 struct khoser_mem_chunk *chunk; 458 - const phys_addr_t *mem; 458 + const void *mem_ptr; 459 + u64 mem; 459 460 int len; 460 461 461 - mem = fdt_getprop(fdt, 0, PROP_PRESERVED_MEMORY_MAP, &len); 462 - 463 - if (!mem || len != sizeof(*mem)) { 462 + mem_ptr = fdt_getprop(fdt, 0, PROP_PRESERVED_MEMORY_MAP, &len); 463 + if (!mem_ptr || len != sizeof(u64)) { 464 464 pr_err("failed to get preserved memory bitmaps\n"); 465 - return; 465 + return false; 466 466 } 467 467 468 - chunk = *mem ? phys_to_virt(*mem) : NULL; 468 + mem = get_unaligned((const u64 *)mem_ptr); 469 + chunk = mem ? phys_to_virt(mem) : NULL; 470 + 471 + /* No preserved physical pages were passed, no deserialization */ 472 + if (!chunk) 473 + return false; 474 + 469 475 while (chunk) { 470 476 unsigned int i; 471 477 ··· 481 473 &chunk->bitmaps[i]); 482 474 chunk = KHOSER_LOAD_PTR(chunk->hdr.next); 483 475 } 476 + 477 + return true; 484 478 } 485 479 486 480 /* ··· 1468 1458 1469 1459 void __init kho_memory_init(void) 1470 1460 { 1471 - struct folio *folio; 1472 - 1473 1461 if (kho_in.scratch_phys) { 1474 1462 kho_scratch = phys_to_virt(kho_in.scratch_phys); 1475 1463 kho_release_scratch(); 1476 1464 1477 - kho_mem_deserialize(kho_get_fdt()); 1478 - folio = kho_restore_folio(kho_in.fdt_phys); 1479 - if (!folio) 1480 - pr_warn("failed to restore folio for KHO fdt\n"); 1465 + if (!kho_mem_deserialize(kho_get_fdt())) 1466 + kho_in.fdt_phys = 0; 1481 1467 } else { 1482 1468 kho_reserve_scratch(); 1483 1469 }