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.

kexec: modify the meaning of the end parameter in kimage_is_destination_range()

The end parameter received by kimage_is_destination_range() should be the
last valid byte address of the target memory segment plus 1. However, in
the locate_mem_hole_bottom_up() and locate_mem_hole_top_down() functions,
the corresponding value passed to kimage_is_destination_range() is the
last valid byte address of the target memory segment, which is 1 less.

There are two ways to fix this bug. We can either correct the logic of
the locate_mem_hole_bottom_up() and locate_mem_hole_top_down() functions,
or we can fix kimage_is_destination_range() by making the end parameter
represent the last valid byte address of the target memory segment. Here,
we choose the second approach.

Due to the modification to kimage_is_destination_range(), we also need to
adjust its callers, such as kimage_alloc_normal_control_pages() and
kimage_alloc_page().

Link: https://lkml.kernel.org/r/20231217033528.303333-2-ytcoode@gmail.com
Signed-off-by: Yuntao Wang <ytcoode@gmail.com>
Acked-by: Baoquan He <bhe@redhat.com>
Cc: Borislav Petkov (AMD) <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Yuntao Wang and committed by
Andrew Morton
816d334a 5c28913e

+4 -4
+4 -4
kernel/kexec_core.c
··· 278 278 unsigned long mstart, mend; 279 279 280 280 mstart = image->segment[i].mem; 281 - mend = mstart + image->segment[i].memsz; 282 - if ((end > mstart) && (start < mend)) 281 + mend = mstart + image->segment[i].memsz - 1; 282 + if ((end >= mstart) && (start <= mend)) 283 283 return 1; 284 284 } 285 285 ··· 372 372 pfn = page_to_boot_pfn(pages); 373 373 epfn = pfn + count; 374 374 addr = pfn << PAGE_SHIFT; 375 - eaddr = epfn << PAGE_SHIFT; 375 + eaddr = (epfn << PAGE_SHIFT) - 1; 376 376 if ((epfn >= (KEXEC_CONTROL_MEMORY_LIMIT >> PAGE_SHIFT)) || 377 377 kimage_is_destination_range(image, addr, eaddr)) { 378 378 list_add(&pages->lru, &extra_pages); ··· 718 718 719 719 /* If the page is not a destination page use it */ 720 720 if (!kimage_is_destination_range(image, addr, 721 - addr + PAGE_SIZE)) 721 + addr + PAGE_SIZE - 1)) 722 722 break; 723 723 724 724 /*