Sending out this RFC in part to guage community interest. This patchset implements preserved-over-kexec memory storage or PKRAM as a method for saving memory pages of the currently executing kernel so that they may be restored after kexec into a new kernel. The patches are adapted from an RFC patchset sent out in 2013 by Vladimir Davydov [1]. They introduce the PKRAM kernel API. One use case for PKRAM is preserving guest memory and/or auxillary supporting data (e.g. iommu data) across kexec to support reboot of the host with minimal disruption to the guest. PKRAM provides a flexible way for doing this without requiring that the amount of memory used by a fixed size created a priori. Another use case is for databases to preserve their block caches in shared memory across reboot. Changes since RFC v2 - Rebased onto 6.3 - Updated API to save/load folios rather than file pages - Omitted previous patches for implementing and optimizing preservation and restoration of shmem files to reduce the number of patches and focus on core functionality. Changes since RFC v1 - Rebased onto 5.12-rc4 - Refined the API to reduce the number of calls and better support multithreading. - Allow preserving byte data of arbitrary length (was previously limited to one page). - Build a new memblock reserved list with the preserved ranges and then substitute it for the existing one. (Mike Rapoport) - Use mem_avoid_overlap() to avoid kaslr stepping on preserved ranges. (Kees Cook) -- Implementation details -- * To aid in quickly finding contiguous ranges of memory containing preserved pages a pseudo physical mapping pagetable is populated with pages as they are preserved. * If a page to be preserved is found to be in range of memory that was previously reserved during early boot or in range of memory where the kernel will be loaded to on kexec, the page will be copied to a page outside of those ranges and the new page will be preserved. A compound page will be copied to and preserved as individual base pages. Note that this means that a page that cannot be moved (e.g. pinned for DMA) currently cannot safely be preserved. This could be addressed by adding functionality to kexec to reconfigure the destination addreses for the sections of an already-loaded kexec kernel. * A single page is allocated for the PKRAM super block. For the next kernel kexec boot to find preserved memory metadata, the pfn of the PKRAM super block, which is exported via /sys/kernel/pkram, is passed in the 'pkram' boot option. * In the newly booted kernel, PKRAM adds all preserved pages to the memblock reserve list during early boot so that they will not be recycled. * Since kexec may load the new kernel code to any memory region, it could destroy preserved memory. When the kernel selects the memory region (kexec_file_load syscall), kexec will avoid preserved pages. When the user selects the kexec memory region to use (kexec_load syscall) , kexec load will fail if there is conflict with preserved pages. Pages preserved after a kexec kernel is loaded will be relocated if they conflict with the selected memory region. [1] https://lkml.org/lkml/2013/7/1/211 Anthony Yznaga (21): mm: add PKRAM API stubs and Kconfig mm: PKRAM: implement node load and save functions mm: PKRAM: implement object load and save functions mm: PKRAM: implement folio stream operations mm: PKRAM: implement byte stream operations mm: PKRAM: link nodes by pfn before reboot mm: PKRAM: introduce super block PKRAM: track preserved pages in a physical mapping pagetable PKRAM: pass a list of preserved ranges to the next kernel PKRAM: prepare for adding preserved ranges to memblock reserved mm: PKRAM: reserve preserved memory at boot PKRAM: free the preserved ranges list PKRAM: prevent inadvertent use of a stale superblock PKRAM: provide a way to ban pages from use by PKRAM kexec: PKRAM: prevent kexec clobbering preserved pages in some cases PKRAM: provide a way to check if a memory range has preserved pages kexec: PKRAM: avoid clobbering already preserved pages mm: PKRAM: allow preserved memory to be freed from userspace PKRAM: disable feature when running the kdump kernel x86/KASLR: PKRAM: support physical kaslr x86/boot/compressed/64: use 1GB pages for mappings arch/x86/boot/compressed/Makefile | 3 + arch/x86/boot/compressed/ident_map_64.c | 9 +- arch/x86/boot/compressed/kaslr.c | 10 +- arch/x86/boot/compressed/misc.h | 10 + arch/x86/boot/compressed/pkram.c | 110 ++ arch/x86/kernel/setup.c | 3 + arch/x86/mm/init_64.c | 3 + include/linux/pkram.h | 116 ++ kernel/kexec.c | 9 + kernel/kexec_core.c | 3 + kernel/kexec_file.c | 15 + mm/Kconfig | 9 + mm/Makefile | 2 + mm/pkram.c | 1753 +++++++++++++++++++++++++++++++ mm/pkram_pagetable.c | 375 +++++++ 15 files changed, 2424 insertions(+), 6 deletions(-) create mode 100644 arch/x86/boot/compressed/pkram.c create mode 100644 include/linux/pkram.h create mode 100644 mm/pkram.c create mode 100644 mm/pkram_pagetable.c -- 1.9.4