When a kernel is loaded for kexec the address ranges where the kexec segments will be copied to may conflict with pages already set to be preserved. Provide a way to determine if preserved pages exist in a specified range. Signed-off-by: Anthony Yznaga <anthony.yznaga@xxxxxxxxxx> --- include/linux/pkram.h | 2 ++ mm/pkram.c | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/include/linux/pkram.h b/include/linux/pkram.h index 97a7c2ac44a9..977cf45a1bcf 100644 --- a/include/linux/pkram.h +++ b/include/linux/pkram.h @@ -104,11 +104,13 @@ int pkram_prepare_save(struct pkram_stream *ps, const char *name, void pkram_reserve(void); void pkram_cleanup(void); void pkram_ban_region(unsigned long start, unsigned long end); +int pkram_has_preserved_pages(unsigned long start, unsigned long end); #else #define pkram_reserved_pages 0UL static inline void pkram_reserve(void) { } static inline void pkram_cleanup(void) { } static inline void pkram_ban_region(unsigned long start, unsigned long end) { } +static inline int pkram_has_preserved_pages(unsigned long start, unsigned long end) { return 0; } #endif #endif /* _LINUX_PKRAM_H */ diff --git a/mm/pkram.c b/mm/pkram.c index d15be75c1032..dcf84ba785a7 100644 --- a/mm/pkram.c +++ b/mm/pkram.c @@ -1668,3 +1668,23 @@ void __init pkram_cleanup(void) pkram_reserved_pages--; } } + +static int has_preserved_pages_cb(unsigned long base, unsigned long size, void *private) +{ + int *has_preserved = (int *)private; + + *has_preserved = 1; + return 1; +} + +/* + * Check whether the memory range [start, end) contains preserved pages. + */ +int pkram_has_preserved_pages(unsigned long start, unsigned long end) +{ + int has_preserved = 0; + + pkram_find_preserved(start, end, &has_preserved, has_preserved_pages_cb); + + return has_preserved; +} -- 1.8.3.1