Inter-revision diff: patch 1

Comparing v8 (message) to v18 (message)

--- v8
+++ v18
@@ -1,406 +1,79 @@
-The functions remove_ima_buffer() and delete_fdt_mem_rsv() that handle
-carrying forward the IMA measurement logs on kexec for powerpc do not
-have architecture specific code, but they are currently defined for
-powerpc only.
+From: Rob Herring <robh@kernel.org>
 
-remove_ima_buffer() and delete_fdt_mem_rsv() are used to remove
-the IMA log entry from the device tree and free the memory reserved
-for the log. These functions need to be defined even if the current
-kernel does not support carrying forward IMA log across kexec since
-the previous kernel could have supported that and therefore the current
-kernel needs to free the allocation.
+The architecture specific field, elfcorehdr_addr in struct kimage_arch,
+that holds the address of the buffer in memory for ELF core header for
+powerpc has a different name than the one used for x86_64.  This makes
+it hard to have a common code for setting up the device tree for
+kexec system call.
 
-Rename remove_ima_buffer() to remove_ima_kexec_buffer().
-Define remove_ima_kexec_buffer() and delete_fdt_mem_rsv() in
-drivers/of/fdt.c. A later patch in this series will use these functions
-to free the allocation, if any, made by the previous kernel for ARM64.
+Rename elfcorehdr_addr to elf_load_addr to align with x86_64 name so
+common code can use it.
 
-Define FDT_PROP_IMA_KEXEC_BUFFER for the chosen node, namely
-"linux,ima-kexec-buffer", that is added to the DTB to hold
-the address and the size of the memory reserved to carry
-the IMA measurement log.
+Signed-off-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
+---
+ arch/powerpc/include/asm/kexec.h  | 2 +-
+ arch/powerpc/kexec/file_load.c    | 4 ++--
+ arch/powerpc/kexec/file_load_64.c | 4 ++--
+ 3 files changed, 5 insertions(+), 5 deletions(-)
 
-Co-developed-by: Prakhar Srivastava <prsriva@linux.microsoft.com>
-Signed-off-by: Prakhar Srivastava <prsriva@linux.microsoft.com>
-Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
-Reported-by: kernel test robot <lkp@intel.com> error: kernel/kexec_file_fdt.c:30: undefined reference to `fdt_num_mem_rsv'
----
- arch/powerpc/include/asm/ima.h   |  10 +--
- arch/powerpc/include/asm/kexec.h |   1 -
- arch/powerpc/kexec/file_load.c   |  33 +---------
- arch/powerpc/kexec/ima.c         |  55 +++-------------
- drivers/of/fdt.c                 | 110 +++++++++++++++++++++++++++++++
- include/linux/kexec.h            |  24 +++++++
- include/linux/libfdt.h           |   3 +
- 7 files changed, 149 insertions(+), 87 deletions(-)
-
-diff --git a/arch/powerpc/include/asm/ima.h b/arch/powerpc/include/asm/ima.h
-index ead488cf3981..6355a85a3289 100644
---- a/arch/powerpc/include/asm/ima.h
-+++ b/arch/powerpc/include/asm/ima.h
-@@ -2,17 +2,13 @@
- #ifndef _ASM_POWERPC_IMA_H
- #define _ASM_POWERPC_IMA_H
+diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
+index 55d6ede30c19..4d9b250cf1e6 100644
+--- a/arch/powerpc/include/asm/kexec.h
++++ b/arch/powerpc/include/asm/kexec.h
+@@ -108,7 +108,7 @@ struct kimage_arch {
+ 	unsigned long backup_start;
+ 	void *backup_buf;
  
-+#include <linux/kexec.h>
-+
- struct kimage;
+-	unsigned long elfcorehdr_addr;
++	unsigned long elf_load_addr;
+ 	unsigned long elf_headers_sz;
+ 	void *elf_headers;
  
- int ima_get_kexec_buffer(void **addr, size_t *size);
- int ima_free_kexec_buffer(void);
+diff --git a/arch/powerpc/kexec/file_load.c b/arch/powerpc/kexec/file_load.c
+index 9a232bc36c8f..f7c31daf8a2e 100644
+--- a/arch/powerpc/kexec/file_load.c
++++ b/arch/powerpc/kexec/file_load.c
+@@ -45,7 +45,7 @@ char *setup_kdump_cmdline(struct kimage *image, char *cmdline,
+ 		return NULL;
  
--#ifdef CONFIG_IMA
--void remove_ima_buffer(void *fdt, int chosen_node);
--#else
--static inline void remove_ima_buffer(void *fdt, int chosen_node) {}
--#endif
--
- #ifdef CONFIG_IMA_KEXEC
- int arch_ima_add_kexec_buffer(struct kimage *image, unsigned long load_addr,
- 			      size_t size);
-@@ -22,7 +18,7 @@ int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node);
- static inline int setup_ima_buffer(const struct kimage *image, void *fdt,
- 				   int chosen_node)
- {
--	remove_ima_buffer(fdt, chosen_node);
-+	remove_ima_kexec_buffer(fdt, chosen_node);
+ 	elfcorehdr_strlen = sprintf(cmdline_ptr, "elfcorehdr=0x%lx ",
+-				    image->arch.elfcorehdr_addr);
++				    image->arch.elf_load_addr);
+ 
+ 	if (elfcorehdr_strlen + cmdline_len > COMMAND_LINE_SIZE) {
+ 		pr_err("Appending elfcorehdr=<addr> exceeds cmdline size\n");
+@@ -263,7 +263,7 @@ int setup_new_fdt(const struct kimage *image, void *fdt,
+ 		 * Avoid elfcorehdr from being stomped on in kdump kernel by
+ 		 * setting up memory reserve map.
+ 		 */
+-		ret = fdt_add_mem_rsv(fdt, image->arch.elfcorehdr_addr,
++		ret = fdt_add_mem_rsv(fdt, image->arch.elf_load_addr,
+ 				      image->arch.elf_headers_sz);
+ 		if (ret) {
+ 			pr_err("Error reserving elfcorehdr memory: %s\n",
+diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
+index c69bcf9b547a..e539b7d401a2 100644
+--- a/arch/powerpc/kexec/file_load_64.c
++++ b/arch/powerpc/kexec/file_load_64.c
+@@ -815,7 +815,7 @@ static int load_elfcorehdr_segment(struct kimage *image, struct kexec_buf *kbuf)
+ 		goto out;
+ 	}
+ 
+-	image->arch.elfcorehdr_addr = kbuf->mem;
++	image->arch.elf_load_addr = kbuf->mem;
+ 	image->arch.elf_headers_sz = headers_sz;
+ 	image->arch.elf_headers = headers;
+ out:
+@@ -851,7 +851,7 @@ int load_crashdump_segments_ppc64(struct kimage *image,
+ 		return ret;
+ 	}
+ 	pr_debug("Loaded elf core header at 0x%lx, bufsz=0x%lx memsz=0x%lx\n",
+-		 image->arch.elfcorehdr_addr, kbuf->bufsz, kbuf->memsz);
++		 image->arch.elf_load_addr, kbuf->bufsz, kbuf->memsz);
+ 
  	return 0;
  }
- #endif /* CONFIG_IMA_KEXEC */
-diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
-index 55d6ede30c19..7c223031ecdd 100644
---- a/arch/powerpc/include/asm/kexec.h
-+++ b/arch/powerpc/include/asm/kexec.h
-@@ -126,7 +126,6 @@ int setup_purgatory(struct kimage *image, const void *slave_code,
- int setup_new_fdt(const struct kimage *image, void *fdt,
- 		  unsigned long initrd_load_addr, unsigned long initrd_len,
- 		  const char *cmdline);
--int delete_fdt_mem_rsv(void *fdt, unsigned long start, unsigned long size);
- 
- #ifdef CONFIG_PPC64
- struct kexec_buf;
-diff --git a/arch/powerpc/kexec/file_load.c b/arch/powerpc/kexec/file_load.c
-index 9a232bc36c8f..7a17655c530e 100644
---- a/arch/powerpc/kexec/file_load.c
-+++ b/arch/powerpc/kexec/file_load.c
-@@ -18,6 +18,7 @@
- #include <linux/kexec.h>
- #include <linux/of_fdt.h>
- #include <linux/libfdt.h>
-+#include <linux/kexec.h>
- #include <asm/setup.h>
- #include <asm/ima.h>
- 
-@@ -109,38 +110,6 @@ int setup_purgatory(struct kimage *image, const void *slave_code,
- 	return 0;
- }
- 
--/**
-- * delete_fdt_mem_rsv - delete memory reservation with given address and size
-- *
-- * Return: 0 on success, or negative errno on error.
-- */
--int delete_fdt_mem_rsv(void *fdt, unsigned long start, unsigned long size)
--{
--	int i, ret, num_rsvs = fdt_num_mem_rsv(fdt);
--
--	for (i = 0; i < num_rsvs; i++) {
--		uint64_t rsv_start, rsv_size;
--
--		ret = fdt_get_mem_rsv(fdt, i, &rsv_start, &rsv_size);
--		if (ret) {
--			pr_err("Malformed device tree.\n");
--			return -EINVAL;
--		}
--
--		if (rsv_start == start && rsv_size == size) {
--			ret = fdt_del_mem_rsv(fdt, i);
--			if (ret) {
--				pr_err("Error deleting device tree reservation.\n");
--				return -EINVAL;
--			}
--
--			return 0;
--		}
--	}
--
--	return -ENOENT;
--}
--
- /*
-  * setup_new_fdt - modify /chosen and memory reservation for the next kernel
-  * @image:		kexec image being loaded.
-diff --git a/arch/powerpc/kexec/ima.c b/arch/powerpc/kexec/ima.c
-index 720e50e490b6..2b790230ea15 100644
---- a/arch/powerpc/kexec/ima.c
-+++ b/arch/powerpc/kexec/ima.c
-@@ -11,6 +11,8 @@
- #include <linux/of.h>
- #include <linux/memblock.h>
- #include <linux/libfdt.h>
-+#include <linux/ima.h>
-+#include <asm/ima.h>
- 
- static int get_addr_size_cells(int *addr_cells, int *size_cells)
- {
-@@ -28,24 +30,6 @@ static int get_addr_size_cells(int *addr_cells, int *size_cells)
- 	return 0;
- }
- 
--static int do_get_kexec_buffer(const void *prop, int len, unsigned long *addr,
--			       size_t *size)
--{
--	int ret, addr_cells, size_cells;
--
--	ret = get_addr_size_cells(&addr_cells, &size_cells);
--	if (ret)
--		return ret;
--
--	if (len < 4 * (addr_cells + size_cells))
--		return -ENOENT;
--
--	*addr = of_read_number(prop, addr_cells);
--	*size = of_read_number(prop + 4 * addr_cells, size_cells);
--
--	return 0;
--}
--
- /**
-  * ima_get_kexec_buffer - get IMA buffer from the previous kernel
-  * @addr:	On successful return, set to point to the buffer contents.
-@@ -100,37 +84,14 @@ int ima_free_kexec_buffer(void)
- 
- }
- 
--/**
-- * remove_ima_buffer - remove the IMA buffer property and reservation from @fdt
-- *
-- * The IMA measurement buffer is of no use to a subsequent kernel, so we always
-- * remove it from the device tree.
-- */
--void remove_ima_buffer(void *fdt, int chosen_node)
--{
--	int ret, len;
--	unsigned long addr;
--	size_t size;
--	const void *prop;
--
--	prop = fdt_getprop(fdt, chosen_node, "linux,ima-kexec-buffer", &len);
--	if (!prop)
--		return;
--
--	ret = do_get_kexec_buffer(prop, len, &addr, &size);
--	fdt_delprop(fdt, chosen_node, "linux,ima-kexec-buffer");
--	if (ret)
--		return;
--
--	ret = delete_fdt_mem_rsv(fdt, addr, size);
--	if (!ret)
--		pr_debug("Removed old IMA buffer reservation.\n");
--}
--
- #ifdef CONFIG_IMA_KEXEC
- /**
-  * arch_ima_add_kexec_buffer - do arch-specific steps to add the IMA buffer
-  *
-+ * @image: kimage struct to set IMA buffer data
-+ * @load_addr: Starting address where IMA buffer is loaded at
-+ * @size: Number of bytes in the IMA buffer
-+ *
-  * Architectures should use this function to pass on the IMA buffer
-  * information to the next kernel.
-  *
-@@ -179,7 +140,7 @@ int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node)
- 	int ret, addr_cells, size_cells, entry_size;
- 	u8 value[16];
- 
--	remove_ima_buffer(fdt, chosen_node);
-+	remove_ima_kexec_buffer(fdt, chosen_node);
- 	if (!image->arch.ima_buffer_size)
- 		return 0;
- 
-@@ -201,7 +162,7 @@ int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node)
- 	if (ret)
- 		return ret;
- 
--	ret = fdt_setprop(fdt, chosen_node, "linux,ima-kexec-buffer", value,
-+	ret = fdt_setprop(fdt, chosen_node, FDT_PROP_IMA_KEXEC_BUFFER, value,
- 			  entry_size);
- 	if (ret < 0)
- 		return -EINVAL;
-diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
-index 4602e467ca8b..d2e6f8ce0e42 100644
---- a/drivers/of/fdt.c
-+++ b/drivers/of/fdt.c
-@@ -25,6 +25,7 @@
- #include <linux/serial_core.h>
- #include <linux/sysfs.h>
- #include <linux/random.h>
-+#include <linux/kexec.h>
- 
- #include <asm/setup.h>  /* for COMMAND_LINE_SIZE */
- #include <asm/page.h>
-@@ -1289,4 +1290,113 @@ static int __init of_fdt_raw_init(void)
- late_initcall(of_fdt_raw_init);
- #endif
- 
-+#ifdef CONFIG_HAVE_IMA_KEXEC
-+/**
-+ * do_get_kexec_buffer - Get address and size of IMA kexec buffer
-+ *
-+ * @prop: IMA kexec buffer node in the device tree
-+ * @len: Size of the given device tree node property
-+ * @addr: Return address of the node
-+ * @size: Return size of the node
-+ */
-+int do_get_kexec_buffer(const void *prop, int len, unsigned long *addr,
-+			size_t *size)
-+{
-+	int addr_cells, size_cells;
-+	struct device_node *root;
-+
-+	root = of_find_node_by_path("/");
-+	if (!root)
-+		return -EINVAL;
-+
-+	addr_cells = of_n_addr_cells(root);
-+	size_cells = of_n_size_cells(root);
-+
-+	of_node_put(root);
-+
-+	if (len < 4 * (addr_cells + size_cells))
-+		return -ENOENT;
-+
-+	*addr = of_read_number(prop, addr_cells);
-+	*size = of_read_number(prop + 4 * addr_cells, size_cells);
-+
-+	return 0;
-+}
-+
-+/**
-+ * remove_ima_kexec_buffer - remove the IMA buffer property and
-+ *			     reservation from @fdt
-+ *
-+ * @fdt: Flattened Device Tree to update
-+ * @chosen_node: Offset to the chosen node in the device tree
-+ *
-+ * The IMA measurement buffer is of no use to a subsequent kernel,
-+ * so we always remove it from the device tree.
-+ */
-+void remove_ima_kexec_buffer(void *fdt, int chosen_node)
-+{
-+	int ret, len;
-+	unsigned long addr;
-+	size_t size;
-+	const void *prop;
-+
-+	prop = fdt_getprop(fdt, chosen_node, FDT_PROP_IMA_KEXEC_BUFFER, &len);
-+	if (!prop) {
-+		pr_debug("Unable to find the ima kexec buffer node\n");
-+		return;
-+	}
-+
-+	ret = do_get_kexec_buffer(prop, len, &addr, &size);
-+	fdt_delprop(fdt, chosen_node, FDT_PROP_IMA_KEXEC_BUFFER);
-+	if (ret) {
-+		pr_err("Unable to delete the ima kexec buffer node\n");
-+		return;
-+	}
-+
-+	ret = delete_fdt_mem_rsv(fdt, addr, size);
-+	if (!ret)
-+		pr_debug("Removed old IMA buffer reservation.\n");
-+}
-+#endif /* CONFIG_HAVE_IMA_KEXEC */
-+
-+#ifdef CONFIG_KEXEC_FILE
-+/**
-+ * delete_fdt_mem_rsv - delete memory reservation with given address and size
-+ *
-+ * @fdt: Flattened Device Tree to update
-+ * @start: Starting address of the reservation to delete
-+ * @size: Size of the reservation to delete
-+ *
-+ * Return: 0 on success, or negative errno on error.
-+ */
-+int delete_fdt_mem_rsv(void *fdt, unsigned long start, unsigned long size)
-+{
-+	int i, ret, num_rsvs = fdt_num_mem_rsv(fdt);
-+
-+	for (i = 0; i < num_rsvs; i++) {
-+		uint64_t rsv_start, rsv_size;
-+
-+		ret = fdt_get_mem_rsv(fdt, i, &rsv_start, &rsv_size);
-+		if (ret) {
-+			pr_err("Malformed device tree.\n");
-+			return -EINVAL;
-+		}
-+
-+		if (rsv_start == start && rsv_size == size) {
-+			ret = fdt_del_mem_rsv(fdt, i);
-+			if (ret) {
-+				pr_err("Error deleting device tree reservation.\n");
-+				return -EINVAL;
-+			}
-+
-+			pr_debug("Freed reserved memory at %lu of size %lu\n",
-+				 start, size);
-+			return 0;
-+		}
-+	}
-+
-+	return -ENOENT;
-+}
-+#endif /* CONFIG_KEXEC_FILE */
-+
- #endif /* CONFIG_OF_EARLY_FLATTREE */
-diff --git a/include/linux/kexec.h b/include/linux/kexec.h
-index 9e93bef52968..6c6c6791a7ba 100644
---- a/include/linux/kexec.h
-+++ b/include/linux/kexec.h
-@@ -407,6 +407,30 @@ static inline int kexec_crash_loaded(void) { return 0; }
- #define kexec_in_progress false
- #endif /* CONFIG_KEXEC_CORE */
- 
-+#if defined(CONFIG_OF_EARLY_FLATTREE) && defined(CONFIG_HAVE_IMA_KEXEC)
-+extern void remove_ima_kexec_buffer(void *fdt, int chosen_node);
-+extern int do_get_kexec_buffer(const void *prop, int len, unsigned long *addr,
-+			       size_t *size);
-+#else
-+static inline void remove_ima_kexec_buffer(void *fdt, int chosen_node) {}
-+static inline int do_get_kexec_buffer(const void *prop, int len,
-+				      unsigned long *addr, size_t *size)
-+{
-+	return -EOPNOTSUPP;
-+}
-+#endif /* CONFIG_OF_EARLY_FLATTREE && CONFIG_HAVE_IMA_KEXEC */
-+
-+#if defined(CONFIG_OF_EARLY_FLATTREE) && defined(CONFIG_KEXEC_FILE)
-+extern int delete_fdt_mem_rsv(void *fdt, unsigned long start,
-+			      unsigned long size);
-+#else
-+static inline int delete_fdt_mem_rsv(void *fdt, unsigned long start,
-+				     unsigned long size)
-+{
-+	return 0;
-+}
-+#endif /* CONFIG_OF_EARLY_FLATTREE && CONFIG_KEXEC_FILE */
-+
- #endif /* !defined(__ASSEBMLY__) */
- 
- #endif /* LINUX_KEXEC_H */
-diff --git a/include/linux/libfdt.h b/include/linux/libfdt.h
-index 90ed4ebfa692..75fb40aa013b 100644
---- a/include/linux/libfdt.h
-+++ b/include/linux/libfdt.h
-@@ -5,4 +5,7 @@
- #include <linux/libfdt_env.h>
- #include "../../scripts/dtc/libfdt/libfdt.h"
- 
-+/* Common device tree properties */
-+#define FDT_PROP_IMA_KEXEC_BUFFER	"linux,ima-kexec-buffer"
-+
- #endif /* _INCLUDE_LIBFDT_H_ */
 -- 
-2.29.0
+2.30.0
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help