lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240805093245.889357-7-jgowans@amazon.com>
Date: Mon, 5 Aug 2024 11:32:41 +0200
From: James Gowans <jgowans@...zon.com>
To: <linux-kernel@...r.kernel.org>
CC: James Gowans <jgowans@...zon.com>, Sean Christopherson
	<seanjc@...gle.com>, Paolo Bonzini <pbonzini@...hat.com>, Alexander Viro
	<viro@...iv.linux.org.uk>, Steve Sistare <steven.sistare@...cle.com>,
	Christian Brauner <brauner@...nel.org>, Jan Kara <jack@...e.cz>, "Anthony
 Yznaga" <anthony.yznaga@...cle.com>, Mike Rapoport <rppt@...nel.org>, "Andrew
 Morton" <akpm@...ux-foundation.org>, <linux-mm@...ck.org>, Jason Gunthorpe
	<jgg@...pe.ca>, <linux-fsdevel@...r.kernel.org>, Usama Arif
	<usama.arif@...edance.com>, <kvm@...r.kernel.org>, Alexander Graf
	<graf@...zon.com>, David Woodhouse <dwmw@...zon.co.uk>, Paul Durrant
	<pdurrant@...zon.co.uk>, Nicolas Saenz Julienne <nsaenz@...zon.es>
Subject: [PATCH 06/10] kexec/kho: Add addr flag to not initialise memory

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@...zon.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(-)

diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
index ad9e95b88b34..1c031a261c2c 100644
--- a/include/uapi/linux/kexec.h
+++ b/include/uapi/linux/kexec.h
@@ -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;
 };
diff --git a/kernel/kexec_kho_in.c b/kernel/kexec_kho_in.c
index 5f8e0d9f9e12..943d9483b009 100644
--- a/kernel/kexec_kho_in.c
+++ b/kernel/kexec_kho_in.c
@@ -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 */
diff --git a/kernel/kexec_kho_out.c b/kernel/kexec_kho_out.c
index 2cf5755f5e4a..4d9da501c5dc 100644
--- a/kernel/kexec_kho_out.c
+++ b/kernel/kexec_kho_out.c
@@ -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),
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ