Ensure destination ranges of the kexec segments do not overlap with any kernel pages marked to be preserved across kexec. For kexec_load, return EADDRNOTAVAIL if overlap is detected. For kexec_file_load, skip ranges containing preserved pages when seaching for available ranges to use. Signed-off-by: Anthony Yznaga <anthony.yznaga@xxxxxxxxxx> --- kernel/kexec_core.c | 3 +++ kernel/kexec_file.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index c19c0dad1ebe..8c24b546352e 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -37,6 +37,7 @@ #include <linux/compiler.h> #include <linux/hugetlb.h> #include <linux/frame.h> +#include <linux/pkram.h> #include <asm/page.h> #include <asm/sections.h> @@ -176,6 +177,8 @@ int sanity_check_segment_list(struct kimage *image) return -EADDRNOTAVAIL; if (mend >= KEXEC_DESTINATION_MEMORY_LIMIT) return -EADDRNOTAVAIL; + if (pkram_has_preserved_pages(mstart, mend)) + return -EADDRNOTAVAIL; } /* Verify our destination addresses do not overlap. diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index f57f72237859..7b14e1b1a178 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -498,6 +498,11 @@ static int locate_mem_hole_top_down(unsigned long start, unsigned long end, continue; } + if (pkram_has_preserved_pages(temp_start, temp_end + 1)) { + temp_start = temp_start - PAGE_SIZE; + continue; + } + /* We found a suitable memory range */ break; } while (1); -- 2.13.3