diff mbox series

[v10,3/8] powerpc: Move ima buffer functions to drivers/of/kexec.c

Message ID 20201204195149.611-4-nramas@linux.microsoft.com (mailing list archive)
State New, archived
Headers show
Series Carry forward IMA measurement log on kexec on ARM64 | expand

Commit Message

Lakshmi Ramasubramanian Dec. 4, 2020, 7:51 p.m. UTC
The functions do_get_kexec_buffer() and get_addr_size_cells(),
defined in arch/powerpc/kexec/ima.c, retrieve the address and size
of the given property from the device tree blob. These functions do
not have architecture specific code, but are currently limited to
powerpc. do_get_kexec_buffer() 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.

Move architecture independent functions get_ima_kexec_buffer() and
get_root_addr_size_cells() to "drivers/of/kexec.c". These functions
retrieve the chosen node "linux,ima-kexec-buffer" from the device tree,
and return the address and size of the buffer used for carrying forward
the IMA measurement log across kexec system call.

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>
---
 drivers/of/kexec.c    | 70 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/kexec.h |  3 ++
 2 files changed, 73 insertions(+)

Comments

Thiago Jung Bauermann Dec. 5, 2020, 7:48 p.m. UTC | #1
Lakshmi Ramasubramanian <nramas@linux.microsoft.com> writes:

> The functions do_get_kexec_buffer() and get_addr_size_cells(),
> defined in arch/powerpc/kexec/ima.c, retrieve the address and size
> of the given property from the device tree blob. These functions do
> not have architecture specific code, but are currently limited to
> powerpc. do_get_kexec_buffer() 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.
>
> Move architecture independent functions get_ima_kexec_buffer() and
> get_root_addr_size_cells() to "drivers/of/kexec.c". These functions
> retrieve the chosen node "linux,ima-kexec-buffer" from the device tree,
> and return the address and size of the buffer used for carrying forward
> the IMA measurement log across kexec system call.
>
> 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>

I'd personally squash this patch with the next one, but I'll leave it
just as a suggestion since maintainers are the ones who know best what
works well in this regard.

The code is good, except for a nit below:

Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>

> ---
>  drivers/of/kexec.c    | 70 +++++++++++++++++++++++++++++++++++++++++++
>  include/linux/kexec.h |  3 ++
>  2 files changed, 73 insertions(+)
>
> diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c
> index b7d59105fcb8..516b86f7113a 100644
> --- a/drivers/of/kexec.c
> +++ b/drivers/of/kexec.c
> @@ -59,3 +59,73 @@ int delete_fdt_mem_rsv(void *fdt, unsigned long start, unsigned long size)
>  
>  	return -ENOENT;
>  }
> +
> +/**
> + * get_root_addr_size_cells - Get address and size of root node
> + *
> + * @addr_cells: Return address of the root node
> + * @size_cells: Return size of the root node
> + *
> + * Return: 0 on success, or negative errno on error.
> + */
> +int get_root_addr_size_cells(int *addr_cells, int *size_cells)
> +{
> +	struct device_node *root;
> +
> +	if (!IS_ENABLED(CONFIG_HAVE_IMA_KEXEC))
> +		return -EOPNOTSUPP;
> +
> +	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);
> +
> +	return 0;
> +}
> +
> +/**
> + * 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
> + *
> + * Return: 0 on success, or negative errno on error.
> + */
> +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;
> +	int rc;
> +
> +	if (!IS_ENABLED(CONFIG_HAVE_IMA_KEXEC))
> +		return -EOPNOTSUPP;
> +
> +	rc = get_root_addr_size_cells(&addr_cells, &size_cells);
> +	if (rc)
> +		return rc;
> +
> +	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 d0234c4815da..10ff704ab670 100644
> --- a/include/linux/kexec.h
> +++ b/include/linux/kexec.h
> @@ -408,6 +408,9 @@ static inline int kexec_crash_loaded(void) { return 0; }
>  #endif /* CONFIG_KEXEC_CORE */
>  
>  #if defined(CONFIG_OF_FLATTREE)
> +extern int get_root_addr_size_cells(int *addr_cells, int *size_cells);
> +extern int get_ima_kexec_buffer(void *fdt, int chosen_node,
> +				unsigned long *addr, size_t *size);
>  extern int delete_fdt_mem_rsv(void *fdt, unsigned long start,
>  			      unsigned long size);
>  #endif /* CONFIG_OF_FLATTREE */

The extern keyword on function prototypes doesn't have any meaning.
It's better to drop them (I should have mentioned this on the previous
patch as well).
Lakshmi Ramasubramanian Dec. 7, 2020, 1:53 a.m. UTC | #2
On 12/5/20 11:48 AM, Thiago Jung Bauermann wrote:
> 
> Lakshmi Ramasubramanian <nramas@linux.microsoft.com> writes:
> 
>> The functions do_get_kexec_buffer() and get_addr_size_cells(),
>> defined in arch/powerpc/kexec/ima.c, retrieve the address and size
>> of the given property from the device tree blob. These functions do
>> not have architecture specific code, but are currently limited to
>> powerpc. do_get_kexec_buffer() 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.
>>
>> Move architecture independent functions get_ima_kexec_buffer() and
>> get_root_addr_size_cells() to "drivers/of/kexec.c". These functions
>> retrieve the chosen node "linux,ima-kexec-buffer" from the device tree,
>> and return the address and size of the buffer used for carrying forward
>> the IMA measurement log across kexec system call.
>>
>> 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>
> 
> I'd personally squash this patch with the next one, but I'll leave it
> just as a suggestion since maintainers are the ones who know best what
> works well in this regard.
> 
> The code is good, except for a nit below:
> 
> Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>

Thanks Thiago.

I'll remove "extern" key word in function declarations when I update the 
patch.

  -lakshmi

> 
>> ---
>>   drivers/of/kexec.c    | 70 +++++++++++++++++++++++++++++++++++++++++++
>>   include/linux/kexec.h |  3 ++
>>   2 files changed, 73 insertions(+)
>>
>> diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c
>> index b7d59105fcb8..516b86f7113a 100644
>> --- a/drivers/of/kexec.c
>> +++ b/drivers/of/kexec.c
>> @@ -59,3 +59,73 @@ int delete_fdt_mem_rsv(void *fdt, unsigned long start, unsigned long size)
>>   
>>   	return -ENOENT;
>>   }
>> +
>> +/**
>> + * get_root_addr_size_cells - Get address and size of root node
>> + *
>> + * @addr_cells: Return address of the root node
>> + * @size_cells: Return size of the root node
>> + *
>> + * Return: 0 on success, or negative errno on error.
>> + */
>> +int get_root_addr_size_cells(int *addr_cells, int *size_cells)
>> +{
>> +	struct device_node *root;
>> +
>> +	if (!IS_ENABLED(CONFIG_HAVE_IMA_KEXEC))
>> +		return -EOPNOTSUPP;
>> +
>> +	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);
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>> + * 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
>> + *
>> + * Return: 0 on success, or negative errno on error.
>> + */
>> +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;
>> +	int rc;
>> +
>> +	if (!IS_ENABLED(CONFIG_HAVE_IMA_KEXEC))
>> +		return -EOPNOTSUPP;
>> +
>> +	rc = get_root_addr_size_cells(&addr_cells, &size_cells);
>> +	if (rc)
>> +		return rc;
>> +
>> +	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 d0234c4815da..10ff704ab670 100644
>> --- a/include/linux/kexec.h
>> +++ b/include/linux/kexec.h
>> @@ -408,6 +408,9 @@ static inline int kexec_crash_loaded(void) { return 0; }
>>   #endif /* CONFIG_KEXEC_CORE */
>>   
>>   #if defined(CONFIG_OF_FLATTREE)
>> +extern int get_root_addr_size_cells(int *addr_cells, int *size_cells);
>> +extern int get_ima_kexec_buffer(void *fdt, int chosen_node,
>> +				unsigned long *addr, size_t *size);
>>   extern int delete_fdt_mem_rsv(void *fdt, unsigned long start,
>>   			      unsigned long size);
>>   #endif /* CONFIG_OF_FLATTREE */
> 
> The extern keyword on function prototypes doesn't have any meaning.
> It's better to drop them (I should have mentioned this on the previous
> patch as well).
>
diff mbox series

Patch

diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c
index b7d59105fcb8..516b86f7113a 100644
--- a/drivers/of/kexec.c
+++ b/drivers/of/kexec.c
@@ -59,3 +59,73 @@  int delete_fdt_mem_rsv(void *fdt, unsigned long start, unsigned long size)
 
 	return -ENOENT;
 }
+
+/**
+ * get_root_addr_size_cells - Get address and size of root node
+ *
+ * @addr_cells: Return address of the root node
+ * @size_cells: Return size of the root node
+ *
+ * Return: 0 on success, or negative errno on error.
+ */
+int get_root_addr_size_cells(int *addr_cells, int *size_cells)
+{
+	struct device_node *root;
+
+	if (!IS_ENABLED(CONFIG_HAVE_IMA_KEXEC))
+		return -EOPNOTSUPP;
+
+	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);
+
+	return 0;
+}
+
+/**
+ * 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
+ *
+ * Return: 0 on success, or negative errno on error.
+ */
+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;
+	int rc;
+
+	if (!IS_ENABLED(CONFIG_HAVE_IMA_KEXEC))
+		return -EOPNOTSUPP;
+
+	rc = get_root_addr_size_cells(&addr_cells, &size_cells);
+	if (rc)
+		return rc;
+
+	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 d0234c4815da..10ff704ab670 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -408,6 +408,9 @@  static inline int kexec_crash_loaded(void) { return 0; }
 #endif /* CONFIG_KEXEC_CORE */
 
 #if defined(CONFIG_OF_FLATTREE)
+extern int get_root_addr_size_cells(int *addr_cells, int *size_cells);
+extern int get_ima_kexec_buffer(void *fdt, int chosen_node,
+				unsigned long *addr, size_t *size);
 extern int delete_fdt_mem_rsv(void *fdt, unsigned long start,
 			      unsigned long size);
 #endif /* CONFIG_OF_FLATTREE */