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.yzn...@oracle.com>
---
 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

Reply via email to