From: steven chen <chenste@linux.microsoft.com>
To: zohar@linux.ibm.com, stefanb@linux.ibm.com,
roberto.sassu@huaweicloud.com, petr@tesarici.cz,
eric.snowberg@oracle.com, paul@paul-moore.com, code@tyhicks.com,
nramas@linux.microsoft.com,
James.Bottomley@HansenPartnership.com,
madvenka@linux.microsoft.com
Cc: linux-integrity@vger.kernel.org,
linux-security-module@vger.kernel.org,
linux-kernel@vger.kernel.org, chenste@linux.microsoft.com
Subject: [PATCH v6 2/7] kexec: define functions to map and unmap segments
Date: Fri, 24 Jan 2025 14:55:42 -0800 [thread overview]
Message-ID: <20250124225547.22684-3-chenste@linux.microsoft.com> (raw)
In-Reply-To: <20250124225547.22684-1-chenste@linux.microsoft.com>
Currently, the mechanism to map and unmap segments to the kimage
structure is not available to the subsystems outside of kexec. This
functionality is needed when IMA is allocating the memory segments
during kexec 'load' operation. Implement functions to map and unmap
segments to kimage.
Implement kimage_map_segment() to enable mapping of IMA buffer source
pages to the kimage structure post kexec 'load'. This function,
accepting a kimage pointer, an address, and a size, will gather the
source pages within the specified address range, create an array of page
pointers, and map these to a contiguous virtual address range. The
function returns the start of this range if successful, or NULL if
unsuccessful.
Implement kimage_unmap_segment() for unmapping segments
using vunmap().
From: Tushar Sugandhi <tusharsu@linux.microsoft.com>
Author: Tushar Sugandhi <tusharsu@linux.microsoft.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com>
Signed-off-by: steven chen <chenste@linux.microsoft.com>
---
include/linux/kexec.h | 7 ++++++
kernel/kexec_core.c | 54 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index f0e9f8eda7a3..f8413ea5c8c8 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -467,6 +467,9 @@ extern bool kexec_file_dbg_print;
#define kexec_dprintk(fmt, arg...) \
do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0)
+extern void *kimage_map_segment(struct kimage *image,
+ unsigned long addr, unsigned long size);
+extern void kimage_unmap_segment(void *buffer);
#else /* !CONFIG_KEXEC_CORE */
struct pt_regs;
struct task_struct;
@@ -474,6 +477,10 @@ static inline void __crash_kexec(struct pt_regs *regs) { }
static inline void crash_kexec(struct pt_regs *regs) { }
static inline int kexec_should_crash(struct task_struct *p) { return 0; }
static inline int kexec_crash_loaded(void) { return 0; }
+static inline void *kimage_map_segment(struct kimage *image,
+ unsigned long addr, unsigned long size)
+{ return NULL; }
+static inline void kimage_unmap_segment(void *buffer) { }
#define kexec_in_progress false
#endif /* CONFIG_KEXEC_CORE */
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index c0caa14880c3..4029df8f6860 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -867,6 +867,60 @@ int kimage_load_segment(struct kimage *image,
return result;
}
+void *kimage_map_segment(struct kimage *image,
+ unsigned long addr, unsigned long size)
+{
+ unsigned long eaddr = addr + size;
+ unsigned long src_page_addr, dest_page_addr;
+ unsigned int npages;
+ struct page **src_pages;
+ int i;
+ kimage_entry_t *ptr, entry;
+ void *vaddr = NULL;
+
+ /*
+ * Collect the source pages and map them in a contiguous VA range.
+ */
+ npages = PFN_UP(eaddr) - PFN_DOWN(addr);
+ src_pages = kmalloc_array(npages, sizeof(*src_pages), GFP_KERNEL);
+ if (!src_pages) {
+ pr_err("Could not allocate ima pages array.\n");
+ return NULL;
+ }
+
+ i = 0;
+ for_each_kimage_entry(image, ptr, entry) {
+ if (entry & IND_DESTINATION)
+ dest_page_addr = entry & PAGE_MASK;
+ else if (entry & IND_SOURCE) {
+ if (dest_page_addr >= addr && dest_page_addr < eaddr) {
+ src_page_addr = entry & PAGE_MASK;
+ src_pages[i++] =
+ virt_to_page(__va(src_page_addr));
+ if (i == npages)
+ break;
+ dest_page_addr += PAGE_SIZE;
+ }
+ }
+ }
+
+ /* Sanity check. */
+ WARN_ON(i < npages);
+
+ vaddr = vmap(src_pages, npages, VM_MAP, PAGE_KERNEL);
+ kfree(src_pages);
+
+ if (!vaddr)
+ pr_err("Could not map ima buffer.\n");
+
+ return vaddr;
+}
+
+void kimage_unmap_segment(void *segment_buffer)
+{
+ vunmap(segment_buffer);
+}
+
struct kexec_load_limit {
/* Mutex protects the limit count. */
struct mutex mutex;
--
2.25.1
next prev parent reply other threads:[~2025-01-24 22:55 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-24 22:55 [PATCH v6 0/7] ima: kexec: measure events between kexec load and excute steven chen
2025-01-24 22:55 ` [PATCH v6 1/7] ima: define and call ima_alloc_kexec_file_buf steven chen
2025-01-24 22:55 ` steven chen [this message]
2025-01-24 22:55 ` [PATCH v6 3/7] ima: kexec: skip IMA segment validation after kexec soft reboot steven chen
2025-01-28 15:23 ` Stefan Berger
2025-01-29 17:58 ` steven chen
2025-01-24 22:55 ` [PATCH v6 4/7] ima: kexec: define functions to copy IMA log at soft boot steven chen
2025-01-24 22:55 ` [PATCH v6 5/7] ima: kexec: move IMA log copy from kexec load to execute steven chen
2025-01-24 22:55 ` [PATCH v6 6/7] ima: make the kexec extra memory configurable steven chen
2025-01-28 15:18 ` Stefan Berger
2025-01-28 18:34 ` steven chen
2025-01-24 22:55 ` [PATCH 7/7] ima: measure kexec load and exec events as critical data steven chen
2025-01-28 15:28 ` Stefan Berger
2025-01-28 17:29 ` Stefan Berger
2025-01-28 18:35 ` steven chen
-- strict thread matches above, loose matches on Subject: below --
2025-01-24 22:42 [PATCH v6 0/7] *** SUBJECT HERE *** steven chen
2025-01-24 22:42 ` [PATCH v6 2/7] kexec: define functions to map and unmap segments steven chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250124225547.22684-3-chenste@linux.microsoft.com \
--to=chenste@linux.microsoft.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=code@tyhicks.com \
--cc=eric.snowberg@oracle.com \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=madvenka@linux.microsoft.com \
--cc=nramas@linux.microsoft.com \
--cc=paul@paul-moore.com \
--cc=petr@tesarici.cz \
--cc=roberto.sassu@huaweicloud.com \
--cc=stefanb@linux.ibm.com \
--cc=zohar@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).