// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2020 Arm Limited * * Based on arch/arm64/kernel/machine_kexec_file.c: * Copyright (C) 2018 Linaro Limited * * And arch/powerpc/kexec/file_load.c: * Copyright (C) 2016 IBM Corporation */ #include <linux/ima.h> #include <linux/kernel.h> #include <linux/kexec.h> #include <linux/memblock.h> #include <linux/libfdt.h> #include <linux/of.h> #include <linux/of_fdt.h> #include <linux/random.h> #include <linux/slab.h> #include <linux/types.h> #define RNG_SEED_SIZE … /* * Additional space needed for the FDT buffer so that we can add initrd, * bootargs, kaslr-seed, rng-seed, useable-memory-range and elfcorehdr. */ #define FDT_EXTRA_SPACE … /** * fdt_find_and_del_mem_rsv - delete memory reservation with given address and size * * @fdt: Flattened device tree for the current kernel. * @start: Starting address of the reserved memory. * @size: Size of the reserved memory. * * Return: 0 on success, or negative errno on error. */ static int fdt_find_and_del_mem_rsv(void *fdt, unsigned long start, unsigned long size) { … } /** * get_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. */ static int get_addr_size_cells(int *addr_cells, int *size_cells) { … } /** * do_get_kexec_buffer - Get address and size of device tree property * * @prop: Device tree property * @len: Size of @prop * @addr: Return address of the node * @size: Return size of the node * * Return: 0 on success, or negative errno on error. */ static int do_get_kexec_buffer(const void *prop, int len, unsigned long *addr, size_t *size) { … } #ifdef CONFIG_HAVE_IMA_KEXEC /** * ima_get_kexec_buffer - get IMA buffer from the previous kernel * @addr: On successful return, set to point to the buffer contents. * @size: On successful return, set to the buffer size. * * Return: 0 on success, negative errno on error. */ int __init ima_get_kexec_buffer(void **addr, size_t *size) { … } /** * ima_free_kexec_buffer - free memory used by the IMA buffer */ int __init ima_free_kexec_buffer(void) { … } #endif /** * remove_ima_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. */ static void remove_ima_buffer(void *fdt, int chosen_node) { … } #ifdef CONFIG_IMA_KEXEC /** * setup_ima_buffer - add IMA buffer information to the fdt * @image: kexec image being loaded. * @fdt: Flattened device tree for the next kernel. * @chosen_node: Offset to the chosen node. * * Return: 0 on success, or negative errno on error. */ static int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node) { … } #else /* CONFIG_IMA_KEXEC */ static inline int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node) { return 0; } #endif /* CONFIG_IMA_KEXEC */ /* * of_kexec_alloc_and_setup_fdt - Alloc and setup a new Flattened Device Tree * * @image: kexec image being loaded. * @initrd_load_addr: Address where the next initrd will be loaded. * @initrd_len: Size of the next initrd, or 0 if there will be none. * @cmdline: Command line for the next kernel, or NULL if there will * be none. * @extra_fdt_size: Additional size for the new FDT buffer. * * Return: fdt on success, or NULL errno on error. */ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image, unsigned long initrd_load_addr, unsigned long initrd_len, const char *cmdline, size_t extra_fdt_size) { … }