Message ID | 20201113192243.1993-4-nramas@linux.microsoft.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Carry forward IMA measurement log on kexec on ARM64 | expand |
On Fri, 2020-11-13 at 11:22 -0800, Lakshmi Ramasubramanian wrote: > The function do_get_kexec_buffer(), defined in arch/powerpc/kexec/ima.c, > retrieves the address and size of the given property from the device > tree blob. This function does not have architecture specific code, but is > currently limited to powerpc. This function correctly handles a device > tree property that is a child node of the root node, but not anything > other than the immediate root child nodes. > > Define an architecture independent function, namely > get_ima_kexec_buffer(), in "drivers/of/ima_kexec.c". This function > retrieves the chosen node, namely "linux,ima-kexec-buffer", from Please remove the word "namely", here, and throughout the patch sets. > the device tree, and returns the address and size of the buffer used > for carrying forward the IMA measurement log across kexec system call. get_ima_kexec_buffer() inlines the existing do_get_kexec_buffer() and get_addr_size_cells() functions, leaving a local copy of get_addr_size_cells(). Duplicating code isn't a good idea. thanks, Mimi
On 12/1/20 3:37 AM, Mimi Zohar wrote: > On Fri, 2020-11-13 at 11:22 -0800, Lakshmi Ramasubramanian wrote: >> The function do_get_kexec_buffer(), defined in arch/powerpc/kexec/ima.c, >> retrieves the address and size of the given property from the device >> tree blob. This function does not have architecture specific code, but is >> currently limited to powerpc. This function correctly handles a device >> tree property that is a child node of the root node, but not anything >> other than the immediate root child nodes. >> >> Define an architecture independent function, namely >> get_ima_kexec_buffer(), in "drivers/of/ima_kexec.c". This function >> retrieves the chosen node, namely "linux,ima-kexec-buffer", from > > Please remove the word "namely", here, and throughout the patch sets. > >> the device tree, and returns the address and size of the buffer used >> for carrying forward the IMA measurement log across kexec system call. > > get_ima_kexec_buffer() inlines the existing do_get_kexec_buffer() and > get_addr_size_cells() functions, leaving a local copy of > get_addr_size_cells(). Duplicating code isn't a good idea. > I'll move get_addr_size_cells() also to drivers/of/ima_kexec.c thanks, -lakshmi
diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 5f42aa3bbac6..5b4af994fed0 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -18,6 +18,9 @@ ifdef CONFIG_OF_FLATTREE ifdef CONFIG_KEXEC_FILE obj-y += kexec_fdt.o endif +ifdef CONFIG_HAVE_IMA_KEXEC +obj-y += ima_kexec.o +endif endif obj-$(CONFIG_OF_UNITTEST) += unittest-data/ diff --git a/drivers/of/ima_kexec.c b/drivers/of/ima_kexec.c new file mode 100644 index 000000000000..9c14777404f2 --- /dev/null +++ b/drivers/of/ima_kexec.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Microsoft Corporation + * + * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com) + * + * File: ima_kexec.c + * Defines functions to handle IMA measurement list across + * kexec system call. + */ + +#define pr_fmt(fmt) "OF: ima-kexec: " fmt + +#include <linux/kernel.h> +#include <linux/memblock.h> +#include <linux/of.h> +#include <linux/of_fdt.h> +#include <linux/sizes.h> +#include <linux/string.h> +#include <linux/errno.h> +#include <linux/libfdt.h> +#include <linux/kexec.h> + +/** + * get_ima_kexec_buffer - Get address and size of IMA kexec buffer + * + * @fdt: Flattened Device Tree + * @chosen_node: Offset of chosen node in the FDT + * @addr: Return address of the node + * @size: Return size of the node + */ +int get_ima_kexec_buffer(void *fdt, int chosen_node, + unsigned long *addr, size_t *size) +{ + const void *prop; + int addr_cells, size_cells, prop_len; + 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 (fdt) + prop = fdt_getprop(fdt, chosen_node, + "linux,ima-kexec-buffer", &prop_len); + else + prop = of_get_property(of_chosen, + "linux,ima-kexec-buffer", &prop_len); + + if (!prop) + return -ENOENT; + + if (prop_len < 4 * (addr_cells + size_cells)) + return -EINVAL; + + *addr = of_read_number(prop, addr_cells); + *size = of_read_number(prop + 4 * addr_cells, size_cells); + + return 0; +} diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 4ce09ccf2628..a4f248caa483 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -407,6 +407,17 @@ static inline int kexec_crash_loaded(void) { return 0; } #define kexec_in_progress false #endif /* CONFIG_KEXEC_CORE */ +#if defined(CONFIG_OF_FLATTREE) && defined(CONFIG_HAVE_IMA_KEXEC) +extern int get_ima_kexec_buffer(void *fdt, int chosen_node, + unsigned long *addr, size_t *size); +#else +static inline int get_ima_kexec_buffer(void *fdt, int chosen_node, + unsigned long *addr, size_t *size) +{ + return -EOPNOTSUPP; +} +#endif /* CONFIG_OF_FLATTREE && CONFIG_HAVE_IMA_KEXEC */ + #if defined(CONFIG_OF_FLATTREE) && defined(CONFIG_KEXEC_FILE) extern int delete_fdt_mem_rsv(void *fdt, unsigned long start, unsigned long size);