From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.3 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A15C7C433FE for ; Sat, 12 Dec 2020 01:20:19 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3F85C23406 for ; Sat, 12 Dec 2020 01:20:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3F85C23406 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Type: Content-Transfer-Encoding:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date:Message-ID:From: References:To:Subject:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=27bESPiRZ4l4gcEuQb+z7Tw0GODpAes8YlTwhyBhB8M=; b=1sfCfpGW+zabMHQohdiqIKDIY 4UVJONgIRKqvQoUaKPSIls35YwsjVDXIWluEf0mZbYMQ38JVQojbrJ+nruG7XN0yAIGDz2CmRm25w SNqJz/pmVUBSWONcUgi0EREZBRYewYFyL4Q4A/otVbxu8gDiVwOteJ7fvVHNsLLmUNnHb6NX8VDcM o/fdKQfPGJjPDRutXSXnQFhc4UJeBbwJikYQatKBsZYqDJX3iSbh2JUHAF3NPJzpYVPZ97Zhx3N9X CgyWKkHA5tX/G8sOdpfDsPR6RJINEzYYPDcx4I6XiZxjPBdpC087UJrrnwAUvX30ODCE/2CuxagMo vdkzdtBRQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kntYY-0002oG-NI; Sat, 12 Dec 2020 01:18:42 +0000 Received: from linux.microsoft.com ([13.77.154.182]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kntYV-0002nt-Tu for linux-arm-kernel@lists.infradead.org; Sat, 12 Dec 2020 01:18:41 +0000 Received: from [192.168.0.104] (c-73-42-176-67.hsd1.wa.comcast.net [73.42.176.67]) by linux.microsoft.com (Postfix) with ESMTPSA id A65D020B717A; Fri, 11 Dec 2020 17:18:36 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com A65D020B717A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1607735917; bh=L+sSAkNyKVg99f8bs8P0XtidfzP9K6JUhgjxWMuy8zU=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=O0+EjY8JmRCvw0ikI+PgHAEt95LET9uFpYonHaDHkSrhS437xzwASjb3MY9SuuuaB eK06Z/+aI3x6vxTPaRXcqyyRUrPXz0QxSqQ4T7slQNZ94asLwC5/QL0//HwBx5B20d Z1mJPvqdQEhuOqhfLqECiw8+dv69Wl+bRQMqpxu8= Subject: Re: [RFC PATCH 2/4] of: Add a common kexec FDT setup function To: Rob Herring , takahiro.akashi@linaro.org, will@kernel.org, catalin.marinas@arm.com, mpe@ellerman.id.au References: <20201211221006.1052453-1-robh@kernel.org> <20201211221006.1052453-3-robh@kernel.org> From: Lakshmi Ramasubramanian Message-ID: <6934c005-d848-314d-cfee-23f2273c119d@linux.microsoft.com> Date: Fri, 11 Dec 2020 17:18:36 -0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: <20201211221006.1052453-3-robh@kernel.org> Content-Language: en-US X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201211_201840_382244_BEB1088A X-CRM114-Status: GOOD ( 38.99 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, benh@kernel.crashing.org, bhsharma@redhat.com, tao.li@vivo.com, zohar@linux.ibm.com, paulus@samba.org, vincenzo.frascino@arm.com, frowand.list@gmail.com, sashal@kernel.org, masahiroy@kernel.org, jmorris@namei.org, linux-arm-kernel@lists.infradead.org, serge@hallyn.com, devicetree@vger.kernel.org, pasha.tatashin@soleen.com, prsriva@linux.microsoft.com, hsinyi@chromium.org, allison@lohutok.net, christophe.leroy@c-s.fr, mbrugger@suse.com, balajib@linux.microsoft.com, dmitry.kasatkin@gmail.com, linux-kernel@vger.kernel.org, james.morse@arm.com, linux-integrity@vger.kernel.org, Thiago Jung Bauermann Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="us-ascii"; Format="flowed" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On 12/11/20 2:10 PM, Rob Herring wrote: Hi Rob, > Both arm64 and powerpc do essentially the same FDT /chosen setup for > kexec. We can simply combine everything each arch does. The differences > are either omissions that arm64 should have or additional properties > that will be ignored. > > The differences relative to the arm64 version: > - If /chosen doesn't exist, it will be created (should never happen). > - Any old dtb and initrd reserved memory will be released. > - The new initrd and elfcorehdr are marked reserved. > - "linux,booted-from-kexec" is set. > > The differences relative to the powerpc version: > - "kaslr-seed" and "rng-seed" may be set. > - "linux,elfcorehdr" is set. > - Any existing "linux,usable-memory-range" is removed. > > Signed-off-by: Rob Herring > --- > This could be taken a step further and do the allocation of the new > FDT. The difference is arm64 uses vmalloc and powerpc uses kmalloc. The > arm64 version also retries with a bigger allocation. That seems > unnecessary. > --- > drivers/of/Makefile | 1 + > drivers/of/kexec.c | 228 ++++++++++++++++++++++++++++++++++++++++++++ > include/linux/of.h | 5 + > 3 files changed, 234 insertions(+) > create mode 100644 drivers/of/kexec.c > > diff --git a/drivers/of/Makefile b/drivers/of/Makefile > index 6e1e5212f058..8ce11955afde 100644 > --- a/drivers/of/Makefile > +++ b/drivers/of/Makefile > @@ -13,5 +13,6 @@ obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o > obj-$(CONFIG_OF_RESOLVE) += resolver.o > obj-$(CONFIG_OF_OVERLAY) += overlay.o > obj-$(CONFIG_OF_NUMA) += of_numa.o > +obj-$(CONFIG_KEXEC_FILE) += kexec.o For the functions moved from powerpc & arm64 to "drivers/of/kexec.c" in this patch, compiling kexec.c when CONFIG_KEXEC_FILE is enabled is fine. But when more functions (such as remove_ima_buffer()) are moved to this file, Makefile needs to be updated for other ima kexec related CONFIGs. Why not compile kexec.c when CONFIG_OF_FLATTREE is enabled, and handle other CONFIGs using IS_ENABLED (like you'd suggested earlier)? > > obj-$(CONFIG_OF_UNITTEST) += unittest-data/ > diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c > new file mode 100644 > index 000000000000..66787be081fe > --- /dev/null > +++ b/drivers/of/kexec.c > @@ -0,0 +1,228 @@ > +// 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 > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* relevant device tree properties */ > +#define FDT_PROP_KEXEC_ELFHDR "linux,elfcorehdr" > +#define FDT_PROP_MEM_RANGE "linux,usable-memory-range" > +#define FDT_PROP_INITRD_START "linux,initrd-start" > +#define FDT_PROP_INITRD_END "linux,initrd-end" > +#define FDT_PROP_BOOTARGS "bootargs" > +#define FDT_PROP_KASLR_SEED "kaslr-seed" > +#define FDT_PROP_RNG_SEED "rng-seed" > +#define RNG_SEED_SIZE 128 > + > +/** > + * fdt_find_and_del_mem_rsv - delete memory reservation with given address and size > + * > + * 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) > +{ > + int i, ret, num_rsvs = fdt_num_mem_rsv(fdt); > + > + for (i = 0; i < num_rsvs; i++) { > + u64 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; > +} > + > +/* > + * of_kexec_setup_new_fdt - modify /chosen and memory reservation for the next kernel > + * > + * @image: kexec image being loaded. > + * @fdt: Flattened device tree for the next kernel. > + * @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. nit: alignment of the parameter description seems to be off. But it could be due to my mail client. > + * > + * Return: 0 on success, or negative errno on error. > + */ > +int of_kexec_setup_new_fdt(const struct kimage *image, void *fdt, > + unsigned long initrd_load_addr, unsigned long initrd_len, > + const char *cmdline) > +{ > + int ret, chosen_node; > + const void *prop; > + > + /* Remove memory reservation for the current device tree. */ > + ret = fdt_find_and_del_mem_rsv(fdt, __pa(initial_boot_params), > + fdt_totalsize(initial_boot_params)); > + if (ret == -EINVAL) > + return ret; > + > + chosen_node = fdt_path_offset(fdt, "/chosen"); > + if (chosen_node == -FDT_ERR_NOTFOUND) > + chosen_node = fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), > + "chosen"); > + if (chosen_node < 0) { > + ret = chosen_node; > + goto out; > + } > + > + ret = fdt_delprop(fdt, chosen_node, FDT_PROP_KEXEC_ELFHDR); > + if (ret && ret != -FDT_ERR_NOTFOUND) > + goto out; > + ret = fdt_delprop(fdt, chosen_node, FDT_PROP_MEM_RANGE); > + if (ret && ret != -FDT_ERR_NOTFOUND) > + goto out; > + > + /* Did we boot using an initrd? */ > + prop = fdt_getprop(fdt, chosen_node, "linux,initrd-start", NULL); > + if (prop) { > + u64 tmp_start, tmp_end, tmp_size; > + > + tmp_start = fdt64_to_cpu(*((const fdt64_t *) prop)); > + > + prop = fdt_getprop(fdt, chosen_node, "linux,initrd-end", NULL); > + if (!prop) > + return -EINVAL; > + > + tmp_end = fdt64_to_cpu(*((const fdt64_t *) prop)); > + > + /* > + * kexec reserves exact initrd size, while firmware may > + * reserve a multiple of PAGE_SIZE, so check for both. > + */ > + tmp_size = tmp_end - tmp_start; > + ret = fdt_find_and_del_mem_rsv(fdt, tmp_start, tmp_size); > + if (ret == -ENOENT) > + ret = fdt_find_and_del_mem_rsv(fdt, tmp_start, > + round_up(tmp_size, PAGE_SIZE)); > + if (ret == -EINVAL) > + return ret; > + } > + > + /* add initrd-* */ > + if (initrd_load_addr) { > + ret = fdt_setprop_u64(fdt, chosen_node, FDT_PROP_INITRD_START, > + initrd_load_addr); > + if (ret) > + goto out; > + > + ret = fdt_setprop_u64(fdt, chosen_node, FDT_PROP_INITRD_END, > + initrd_load_addr + initrd_len); > + if (ret) > + goto out; > + > + ret = fdt_add_mem_rsv(fdt, initrd_load_addr, initrd_len); > + if (ret) > + goto out; > + > + } else { > + ret = fdt_delprop(fdt, chosen_node, FDT_PROP_INITRD_START); > + if (ret && (ret != -FDT_ERR_NOTFOUND)) > + goto out; > + > + ret = fdt_delprop(fdt, chosen_node, FDT_PROP_INITRD_END); > + if (ret && (ret != -FDT_ERR_NOTFOUND)) > + goto out; > + } > + > + if (image->type == KEXEC_TYPE_CRASH) { > + /* add linux,elfcorehdr */ > + ret = fdt_appendprop_addrrange(fdt, 0, chosen_node, > + FDT_PROP_KEXEC_ELFHDR, > + image->arch.elf_headers_mem, > + image->arch.elf_headers_sz); > + if (ret) > + goto out; > + > + /* > + * Avoid elfcorehdr from being stomped on in kdump kernel by > + * setting up memory reserve map. > + */ > + ret = fdt_add_mem_rsv(fdt, image->arch.elf_headers_mem, > + image->arch.elf_headers_sz); Return value from fdt_add_mem_rsv() should be checked. > + > + /* add linux,usable-memory-range */ > + ret = fdt_appendprop_addrrange(fdt, 0, chosen_node, > + FDT_PROP_MEM_RANGE, > + crashk_res.start, > + crashk_res.end - crashk_res.start + 1); > + if (ret) > + goto out; > + } > + > + /* add bootargs */ > + if (cmdline) { > + ret = fdt_setprop_string(fdt, chosen_node, FDT_PROP_BOOTARGS, cmdline); > + if (ret) > + goto out; > + } else { > + ret = fdt_delprop(fdt, chosen_node, FDT_PROP_BOOTARGS); > + if (ret && (ret != -FDT_ERR_NOTFOUND)) > + goto out; > + } > + > + /* add kaslr-seed */ > + ret = fdt_delprop(fdt, chosen_node, FDT_PROP_KASLR_SEED); > + if (ret == -FDT_ERR_NOTFOUND) > + ret = 0; > + else if (ret) > + goto out; > + > + if (rng_is_initialized()) { > + u64 seed = get_random_u64(); > + ret = fdt_setprop_u64(fdt, chosen_node, FDT_PROP_KASLR_SEED, seed); > + if (ret) > + goto out; > + } else { > + pr_notice("RNG is not initialised: omitting \"%s\" property\n", > + FDT_PROP_KASLR_SEED); > + } > + > + /* add rng-seed */ > + if (rng_is_initialized()) { > + void *rng_seed; > + ret = fdt_setprop_placeholder(fdt, chosen_node, FDT_PROP_RNG_SEED, > + RNG_SEED_SIZE, &rng_seed); > + if (ret) > + goto out; > + get_random_bytes(rng_seed, RNG_SEED_SIZE); > + } else { > + pr_notice("RNG is not initialised: omitting \"%s\" property\n", > + FDT_PROP_RNG_SEED); > + } > + > + ret = fdt_setprop(fdt, chosen_node, "linux,booted-from-kexec", NULL, 0); > + > +out: > + if (ret) > + return (ret == -FDT_ERR_NOSPACE) ? -ENOMEM : -EINVAL; > + > + return 0; > +} > diff --git a/include/linux/of.h b/include/linux/of.h > index 5d51891cbf1a..3375f5295875 100644 > --- a/include/linux/of.h > +++ b/include/linux/of.h > @@ -558,6 +558,11 @@ int of_map_id(struct device_node *np, u32 id, > const char *map_name, const char *map_mask_name, > struct device_node **target, u32 *id_out); > > +struct kimage; > +int of_kexec_setup_new_fdt(const struct kimage *image, void *fdt, > + unsigned long initrd_load_addr, unsigned long initrd_len, > + const char *cmdline); of_kexec_setup_new_fdt() should only be declared if CONFIG_KEXEC_FILE is enabled. Right? -lakshmi > + > #else /* CONFIG_OF */ > > static inline void of_core_init(void) > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel