kexec_file: skip checksum verification when safe Checksum verification is needed 1. for crash kernels. In a crash, we can't be sure the kernel is intact. 2. if we're worried about relocating the kernel into a region used by some DMA that wasn't properly cancelled. If KHO is enabled then relocations will happen to KHO scratch, which is free from DMA regions. If we used CMA to allocate segments then relocations are not going to happen at all. Therefore, we can safely disable checksum verification in both of those cases. Instead of adding a new variable to purgatory, just skip adding regions and save the default value of SHA256 hash. Saves ~250ms on my 4.0 GHz CPU. This is an important saving for the live-update project. Signed-off-by: Michal Clapinski <mclapinski@google.com> Reviewed-by: Pratyush Yadav (Google) <pratyush@kernel.org> Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com> Acked-by: Baoquan He <baoquan.he@linux.dev> Link: https://patch.msgid.link/20260602123311.1841746-1-mclapinski@google.com Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 2bfbb2d..59fb9d7 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c
@@ -27,6 +27,7 @@ #include <linux/syscalls.h> #include <linux/vmalloc.h> #include <linux/dma-map-ops.h> +#include <linux/kexec_handover.h> #include "kexec_internal.h" #ifdef CONFIG_KEXEC_SIG @@ -798,6 +799,16 @@ int kexec_add_buffer(struct kexec_buf *kbuf) return 0; } +static bool kexec_only_cma_segments(struct kimage *image) +{ + for (int i = 0; i < image->nr_segments; i++) { + if (!image->segment_cma[i]) + return false; + } + + return true; +} + /* Calculate and store the digest of segments */ static int kexec_calculate_store_digests(struct kimage *image) { @@ -822,6 +833,21 @@ static int kexec_calculate_store_digests(struct kimage *image) sha256_init(&sctx); + /* + * If KHO is enabled, the destinations are located in KHO scratch. + * KHO scratch can only contain early boot allocations and movable + * allocations. That means there is no risk of memory corruption by + * uncancelled DMA. + * + * If all segments were loaded into contiguous memory, there will be no + * relocations at all, so also no risk of corruption. + */ + if (image->type != KEXEC_TYPE_CRASH && + (kho_is_enabled() || kexec_only_cma_segments(image))) { + pr_debug("disabling checksum verification in purgatory\n"); + goto skip_checksum; + } + for (j = i = 0; i < image->nr_segments; i++) { struct kexec_segment *ksegment; @@ -867,6 +893,7 @@ static int kexec_calculate_store_digests(struct kimage *image) j++; } +skip_checksum: sha256_final(&sctx, digest); ret = kexec_purgatory_get_set_symbol(image, "purgatory_sha_regions",