@@ -52,6 +52,12 @@
/* KHO passes an array of kho_mem as "mem cache" to the new kernel */
struct kho_mem {
+ /*
+ * Use the last bits for flags; addrs should be at least word
+ * aligned.
+ */
+#define KHO_MEM_ADDR_FLAG_NOINIT BIT(0)
+#define KHO_MEM_ADDR_FLAG_MASK (BIT(1) - 1)
__u64 addr;
__u64 len;
};
@@ -75,6 +75,11 @@ __init void kho_populate_refcount(void)
*/
for (offset = 0; offset < mem_len; offset += sizeof(struct kho_mem)) {
struct kho_mem *mem = mem_virt + offset;
+
+ /* No struct pages for this region; nothing to claim. */
+ if (mem->addr & KHO_MEM_ADDR_FLAG_NOINIT)
+ continue;
+
u64 start_pfn = PFN_DOWN(mem->addr);
u64 end_pfn = PFN_UP(mem->addr + mem->len);
u64 pfn;
@@ -183,8 +188,13 @@ void __init kho_reserve_previous_mem(void)
/* Then populate all preserved memory areas as reserved */
for (off = 0; off < mem_len; off += sizeof(struct kho_mem)) {
struct kho_mem *mem = mem_virt + off;
+ __u64 addr = mem->addr & ~KHO_MEM_ADDR_FLAG_MASK;
- memblock_reserve(mem->addr, mem->len);
+ memblock_reserve(addr, mem->len);
+ if (mem->addr & KHO_MEM_ADDR_FLAG_NOINIT) {
+ memblock_reserved_mark_noinit(addr, mem->len);
+ memblock_mark_nomap(addr, mem->len);
+ }
}
/* Unreserve the mem cache - we don't need it from here on */
@@ -175,6 +175,10 @@ static int kho_alloc_mem_cache(struct kimage *image, void *fdt)
const struct kho_mem *mem = &mems[i];
ulong mstart = PAGE_ALIGN_DOWN(mem->addr);
ulong mend = PAGE_ALIGN(mem->addr + mem->len);
+
+ /* Re-apply flags lost during round down. */
+ mstart |= mem->addr & KHO_MEM_ADDR_FLAG_MASK;
+
struct kho_mem cmem = {
.addr = mstart,
.len = (mend - mstart),
Smuggle a flag on the address field. If set the memory region being reserved via KHO will be marked as no init in memblocks so it will not get struct pages, will not get given to the buddy allocator and will not be part of the direct map. This allows drivers to pass memory ranges which the driver has allocated itself from memblocks, independent of the kernel's mm and struct page based memory management. Signed-off-by: James Gowans <jgowans@amazon.com> --- include/uapi/linux/kexec.h | 6 ++++++ kernel/kexec_kho_in.c | 12 +++++++++++- kernel/kexec_kho_out.c | 4 ++++ 3 files changed, 21 insertions(+), 1 deletion(-)