From patchwork Tue Mar 6 10:22:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 130758 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp3761940lja; Tue, 6 Mar 2018 02:23:23 -0800 (PST) X-Google-Smtp-Source: AG47ELu5wBQm1jx1I2d6gJy94GVDknvxStftCFfFhv5Y7YY3smeMX5iPIofCa1u+XdsnR+ovzqig X-Received: by 2002:a17:902:d891:: with SMTP id b17-v6mr15904253plz.241.1520331803698; Tue, 06 Mar 2018 02:23:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520331803; cv=none; d=google.com; s=arc-20160816; b=MGTV+b4fbkj+OgoQqEeJfUxW2svRtz6nmTDfpAIQ1It6nPVt1pzTVQBGjdecW9OhS1 3ZeB9xYonuiTCWraEGqp+7HlX1rk1AlvZrtTbNQ7zQY1UidDTSkidHKUbC2n7yvmRTC9 XvTbIppSZKzYafZt1KeIE6KYY3n4vkH/i1awBCnsQbb0OAAe+Rc82IBcOa9P837zQxw3 9gy0P0Abx+bpGb7Ncb/S4HrFtFQsaQSmsgI0PYRfLHSLiB3Z19r5qOWP+3I9HkZkghWj Wpd3xsazs4cCMm5M0JM0STqLlhOzDP8kzIEu+30OuUgxCWCK5TcjtglS+RYpUczneYLs hPzQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=TLkC14gfKn6Fp3BIip6KOc5tun8h4G9Y1pI52+NjIwI=; b=EaMKnA7pgTrZAqAgN3yy2dZifK1xY8rbJobeJAef+KfIFGH/gr5mgOMfK8M5D+3SpW 4F0B7CLHwq+7lLiIrIsqd6XWY2LtE/EFeLM6fVTh+mL/CMYU8fSWpWnBBamFqruEO4Em El3wAlDFyvX8I458Bue19quPbI6d+sOfMbLN2m8UqPpDeDF6DdF+Y9jZyr+FsiAhJvaW hp4SeOSlVRl7EfQl7aDLN2FjOl7Oa6t6hsUC0+TfXZEnFKoHmPYgfQ5eBxdvXAtkZojL lAZYvtctL/uJjnewt0jltn6Ck9TweMdP49F2ZdBBRF+7vlBWRfJeqFIZYRzhCJqJ6318 g+4w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=QvB1eUfD; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a2si9647023pgd.452.2018.03.06.02.23.23; Tue, 06 Mar 2018 02:23:23 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=QvB1eUfD; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753386AbeCFKXT (ORCPT + 28 others); Tue, 6 Mar 2018 05:23:19 -0500 Received: from mail-it0-f68.google.com ([209.85.214.68]:53401 "EHLO mail-it0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753155AbeCFKXR (ORCPT ); Tue, 6 Mar 2018 05:23:17 -0500 Received: by mail-it0-f68.google.com with SMTP id w63so13141369ita.3 for ; Tue, 06 Mar 2018 02:23:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TLkC14gfKn6Fp3BIip6KOc5tun8h4G9Y1pI52+NjIwI=; b=QvB1eUfDM8b/oiIvTAUrgqcuY1qVdvoM8OOI2kGAi5zsI8EYpZgBhdzj8SEt9NhewI Hcf5j2TasQ/x6LlNSbCZNVOIPr1dGJTMQGgFFlWCUu5i8zi+Lj0x0GKkYa11uF4Opynt 9O5yrqQphSpV3gEPJ8aOmbljp4BRsW0CcXG/w= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TLkC14gfKn6Fp3BIip6KOc5tun8h4G9Y1pI52+NjIwI=; b=QaoO1zu85GNfnDTPZFw1lYQS6IbzfwgHNb009FM8WIifmLJQERD1oHicCcJI3rKW0Y nWgIBgkblR50gu+XT3iMFfj8Q0Qc6SXjGm3Xe1Hi6QQ3yr38K6DNYIPN5dCwWf4wSPeE AZzWIDMDrHPo+9ey8Ua/h0kSQPo/haG6Sth0Ihx4KxTvkYPMI+R9hLwOJ3NKg+jm0bIS wyFGkDHJSHGYfZiqEQJUKIqtHQBWfUUU+c0tL9/LEJbQfwSKEzpWY66B4xUe2s061jBg btzCk+aJ0YtIWhxCbIH4CDlZhlAgPghPa8ntiB09tC86A/5/n+LdDejl/LuwKJD7ErWI Jrrg== X-Gm-Message-State: AElRT7FJ37ndJmpKPXT7n1YZqpgCyjcsf4Sr9HO8clfgSNbxhOl9p/DL ZemAoF7TBVjlIcy+9iDUZcersQ== X-Received: by 10.36.111.4 with SMTP id x4mr18162462itb.51.1520331796476; Tue, 06 Mar 2018 02:23:16 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id 30sm9963125iop.73.2018.03.06.02.23.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Mar 2018 02:23:15 -0800 (PST) From: AKASHI Takahiro To: dyoung@redhat.com, vgoyal@redhat.com, bhe@redhat.com, mpe@ellerman.id.au, bauerman@linux.vnet.ibm.com, prudo@linux.vnet.ibm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v2 1/7] kexec_file: make an use of purgatory optional Date: Tue, 6 Mar 2018 19:22:57 +0900 Message-Id: <20180306102303.9063-2-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180306102303.9063-1-takahiro.akashi@linaro.org> References: <20180306102303.9063-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On arm64, crash dump kernel's usable memory is protected by *unmapping* it from kernel virtual space unlike other architectures where the region is just made read-only. It is highly unlikely that the region is accidentally corrupted and this observation rationalizes that digest check code can also be dropped from purgatory. The resulting code is so simple as it doesn't require a bit ugly re-linking/relocation stuff, i.e. arch_kexec_apply_relocations_add(). Please see: http://lists.infradead.org/pipermail/linux-arm-kernel/2017-December/545428.html All that the purgatory does is to shuffle arguments and jump into a new kernel, while we still need to have some space for a hash value (purgatory_sha256_digest) which is never checked against. As such, it doesn't make sense to have trampline code between old kernel and new kernel on arm64. This patch introduces a new configuration, ARCH_HAS_KEXEC_PURGATORY, and allows related code to be compiled in only if necessary. Signed-off-by: AKASHI Takahiro Cc: Dave Young Cc: Vivek Goyal Cc: Baoquan He --- arch/powerpc/Kconfig | 3 +++ arch/x86/Kconfig | 3 +++ kernel/kexec_file.c | 5 +++++ 3 files changed, 11 insertions(+) -- 2.16.2 diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 73ce5dd07642..c32a181a7cbb 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -552,6 +552,9 @@ config KEXEC_FILE for kernel and initramfs as opposed to a list of segments as is the case for the older kexec call. +config ARCH_HAS_KEXEC_PURGATORY + def_bool KEXEC_FILE + config RELOCATABLE bool "Build a relocatable kernel" depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE)) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c1236b187824..f031c3efe47e 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2019,6 +2019,9 @@ config KEXEC_FILE for kernel and initramfs as opposed to list of segments as accepted by previous system call. +config ARCH_HAS_KEXEC_PURGATORY + def_bool KEXEC_FILE + config KEXEC_VERIFY_SIG bool "Verify kernel signature during kexec_file_load() syscall" depends on KEXEC_FILE diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index e5bcd94c1efb..6dbbb89cbbac 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -532,6 +532,9 @@ static int kexec_calculate_store_digests(struct kimage *image) struct kexec_sha_region *sha_regions; struct purgatory_info *pi = &image->purgatory_info; + if (!IS_ENABLED(ARCH_HAS_KEXEC_PURGATORY)) + return 0; + zero_buf = __va(page_to_pfn(ZERO_PAGE(0)) << PAGE_SHIFT); zero_buf_sz = PAGE_SIZE; @@ -633,6 +636,7 @@ static int kexec_calculate_store_digests(struct kimage *image) return ret; } +#ifdef CONFIG_ARCH_HAS_KEXEC_PURGATORY /* Actually load purgatory. Lot of code taken from kexec-tools */ static int __kexec_load_purgatory(struct kimage *image, unsigned long min, unsigned long max, int top_down) @@ -1022,3 +1026,4 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name, return 0; } +#endif /* CONFIG_ARCH_HAS_KEXEC_PURGATORY */ From patchwork Tue Mar 6 10:22:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 130759 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp3762024lja; Tue, 6 Mar 2018 02:23:28 -0800 (PST) X-Google-Smtp-Source: AG47ELu6NOhvSzMCT5g7AilS/XrvFMVYAtsPGaeZGOgtey9FUi4ZyUEOx+pnalPRV57caSf4Gz7c X-Received: by 2002:a17:902:50ec:: with SMTP id c41-v6mr16387399plj.208.1520331808641; Tue, 06 Mar 2018 02:23:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520331808; cv=none; d=google.com; s=arc-20160816; b=Nk03qR1qs98ivT702DnQ2/apavb62HGEvmBgZ9NnYc7e5IINNfxOIkt3IZ9VU04N9g p6akNpe7YaLwtH5Xevz0c96TwwTVDZy8KlaMn1/tgli8226/k9ER0RMEnPTCbfbWt5Ln ujqi82pDVxhClat4H0z2bhszBrlHu6a0Sao0s0kbj1TlbIAr6BOue+dpMIDbkYyR7Dcs LzR6LwDIYdbq/Nq+pyFFa+ROWXwsqGellYbpRbtQki4K/9rtO4Gu176fHwXc5+vFLQ1Q 09BVKuIq2M50MKE2gy6NSdQ/XWECQqwQNfQoM//SyHLO8dJ7MS60h+lGIVjDmg+e2Y8b nU3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=2Pajw5krnDVg94y/bOMsvxtioZ8KNf1j7bpHrYQbD3M=; b=oOds/oz92UPzQ3TgV8/XXLj1q26MNKXQYuNQOZR64NmVF8VINTK8vHvCkgHZTzOzyL VHAd5vQtaPsPc9VmM7PjXwGU7c75dQdpLcyo/DrdvJyzK6hiMNDF4x2RNYY+NW4mn0vN 8zM1lw4Z3FUtjjDBy4ldy68CD/JwO/wckNopL99smHTOZvsrZtkfwj4O2KxdorCBaGNI ONN2txbLb1l5+1JuwQ4IRCB7VUEv5m7Q0FF4ngYKzZsIS/FtBkpQMDBQpy0rKJbWrW0c dUf7bBFhvE6PC4lkoKdFnNUrvWPUcZ837CrKm90ZXMMkiwCTY/Fctr+6PkG7+aPjYofE Hh0g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AfchWtu8; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a2si9647023pgd.452.2018.03.06.02.23.28; Tue, 06 Mar 2018 02:23:28 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AfchWtu8; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753436AbeCFKXZ (ORCPT + 28 others); Tue, 6 Mar 2018 05:23:25 -0500 Received: from mail-it0-f65.google.com ([209.85.214.65]:39703 "EHLO mail-it0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753392AbeCFKXV (ORCPT ); Tue, 6 Mar 2018 05:23:21 -0500 Received: by mail-it0-f65.google.com with SMTP id l187so14114628ith.4 for ; Tue, 06 Mar 2018 02:23:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=2Pajw5krnDVg94y/bOMsvxtioZ8KNf1j7bpHrYQbD3M=; b=AfchWtu891u+pd9diEDASGbkLv2UK9X5HIY0zkE8mySmN9Q7mpQcVhZACT8REza2Bs dtFUdE8xcfVEsazQqXZZQHUwFvL2Z/0CbbREZenush4Qz0bi2r0sM0L5bKrvkAV4Fage 9wPqH6KnhMmUkR/puODW4+dvxkupyhI11dKWI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=2Pajw5krnDVg94y/bOMsvxtioZ8KNf1j7bpHrYQbD3M=; b=PfSfVun2vm/QvLQ3Iat3fc2wae3dySjzzF8Pnw9Ghvi91T5mPmC8bbs6En+2hm2iHr tTc0K4/aBUwxzTnA7zkaAatv8yI0OnZtcE+bX0bHegwaff6In4HPIDi0628YUt21hqAW uxQWhP6CNzz0KWSSUvUmivMpx5Hezg4R3UKjCrvSmrzMsvU+hNSujz3oEehWwOcG9VVq 5/trOUDYpfR/5eNQEmLsFpizmUqGqXwdC3eeTskEPZc9vt0jqmMy1Wno6sT403zpAFD9 FybzUeDTsJNA82MTkcW2faWAI1jwlXyQCqCRQNR5sTFqLpH9c6bn6ASW9Ba41d5t8u/5 DyOA== X-Gm-Message-State: AElRT7EQgeHwPIQL4CPWRmr26qCvZW9X72ZamGTm407vnA9xdGAvAeDc E6b6uWGs0yAMWvZc10opgRnQeQ== X-Received: by 10.36.118.81 with SMTP id z78mr474329itb.104.1520331800992; Tue, 06 Mar 2018 02:23:20 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id w37sm10010387ioi.1.2018.03.06.02.23.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Mar 2018 02:23:20 -0800 (PST) From: AKASHI Takahiro To: dyoung@redhat.com, vgoyal@redhat.com, bhe@redhat.com, mpe@ellerman.id.au, bauerman@linux.vnet.ibm.com, prudo@linux.vnet.ibm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v2 2/7] kexec_file, x86, powerpc: factor out kexec_file_ops functions Date: Tue, 6 Mar 2018 19:22:58 +0900 Message-Id: <20180306102303.9063-3-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180306102303.9063-1-takahiro.akashi@linaro.org> References: <20180306102303.9063-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org As arch_kexec_kernel_image_{probe,load}(), arch_kimage_file_post_load_cleanup() and arch_kexec_kernel_verify_sig() are almost duplicated among architectures, they can be commonalized with an architecture-defined kexec_file_ops array. So let's factor them out. Signed-off-by: AKASHI Takahiro Cc: Dave Young Cc: Vivek Goyal Cc: Baoquan He Cc: Michael Ellerman Cc: Thiago Jung Bauermann --- arch/powerpc/include/asm/kexec.h | 2 +- arch/powerpc/kernel/kexec_elf_64.c | 2 +- arch/powerpc/kernel/machine_kexec_file_64.c | 39 ++----------------- arch/x86/include/asm/kexec-bzimage64.h | 2 +- arch/x86/kernel/kexec-bzimage64.c | 2 +- arch/x86/kernel/machine_kexec_64.c | 45 +--------------------- include/linux/kexec.h | 13 +++---- kernel/kexec_file.c | 60 +++++++++++++++++++++++++++-- 8 files changed, 71 insertions(+), 94 deletions(-) -- 2.16.2 Reviewed-by: Thiago Jung Bauermann Tested-by: Thiago Jung Bauermann Acked-by: Michael Ellerman (powerpc) diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h index d8b1e8e7e035..4a585cba1787 100644 --- a/arch/powerpc/include/asm/kexec.h +++ b/arch/powerpc/include/asm/kexec.h @@ -95,7 +95,7 @@ static inline bool kdump_in_progress(void) } #ifdef CONFIG_KEXEC_FILE -extern struct kexec_file_ops kexec_elf64_ops; +extern const struct kexec_file_ops kexec_elf64_ops; #ifdef CONFIG_IMA_KEXEC #define ARCH_HAS_KIMAGE_ARCH diff --git a/arch/powerpc/kernel/kexec_elf_64.c b/arch/powerpc/kernel/kexec_elf_64.c index 9a42309b091a..6c78c11c7faf 100644 --- a/arch/powerpc/kernel/kexec_elf_64.c +++ b/arch/powerpc/kernel/kexec_elf_64.c @@ -657,7 +657,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, return ret ? ERR_PTR(ret) : fdt; } -struct kexec_file_ops kexec_elf64_ops = { +const struct kexec_file_ops kexec_elf64_ops = { .probe = elf64_probe, .load = elf64_load, }; diff --git a/arch/powerpc/kernel/machine_kexec_file_64.c b/arch/powerpc/kernel/machine_kexec_file_64.c index e4395f937d63..3a962c87149a 100644 --- a/arch/powerpc/kernel/machine_kexec_file_64.c +++ b/arch/powerpc/kernel/machine_kexec_file_64.c @@ -31,52 +31,19 @@ #define SLAVE_CODE_SIZE 256 -static struct kexec_file_ops *kexec_file_loaders[] = { +const struct kexec_file_ops * const kexec_file_loaders[] = { &kexec_elf64_ops, + NULL }; int arch_kexec_kernel_image_probe(struct kimage *image, void *buf, unsigned long buf_len) { - int i, ret = -ENOEXEC; - struct kexec_file_ops *fops; - /* We don't support crash kernels yet. */ if (image->type == KEXEC_TYPE_CRASH) return -ENOTSUPP; - for (i = 0; i < ARRAY_SIZE(kexec_file_loaders); i++) { - fops = kexec_file_loaders[i]; - if (!fops || !fops->probe) - continue; - - ret = fops->probe(buf, buf_len); - if (!ret) { - image->fops = fops; - return ret; - } - } - - return ret; -} - -void *arch_kexec_kernel_image_load(struct kimage *image) -{ - if (!image->fops || !image->fops->load) - return ERR_PTR(-ENOEXEC); - - return image->fops->load(image, image->kernel_buf, - image->kernel_buf_len, image->initrd_buf, - image->initrd_buf_len, image->cmdline_buf, - image->cmdline_buf_len); -} - -int arch_kimage_file_post_load_cleanup(struct kimage *image) -{ - if (!image->fops || !image->fops->cleanup) - return 0; - - return image->fops->cleanup(image->image_loader_data); + return kexec_image_probe_default(image, buf, buf_len); } /** diff --git a/arch/x86/include/asm/kexec-bzimage64.h b/arch/x86/include/asm/kexec-bzimage64.h index 9f07cff43705..df89ee7d3e9e 100644 --- a/arch/x86/include/asm/kexec-bzimage64.h +++ b/arch/x86/include/asm/kexec-bzimage64.h @@ -2,6 +2,6 @@ #ifndef _ASM_KEXEC_BZIMAGE64_H #define _ASM_KEXEC_BZIMAGE64_H -extern struct kexec_file_ops kexec_bzImage64_ops; +extern const struct kexec_file_ops kexec_bzImage64_ops; #endif /* _ASM_KEXE_BZIMAGE64_H */ diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c index fb095ba0c02f..705654776c0c 100644 --- a/arch/x86/kernel/kexec-bzimage64.c +++ b/arch/x86/kernel/kexec-bzimage64.c @@ -538,7 +538,7 @@ static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len) } #endif -struct kexec_file_ops kexec_bzImage64_ops = { +const struct kexec_file_ops kexec_bzImage64_ops = { .probe = bzImage64_probe, .load = bzImage64_load, .cleanup = bzImage64_cleanup, diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 1f790cf9d38f..2cdd29d64181 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -30,8 +30,9 @@ #include #ifdef CONFIG_KEXEC_FILE -static struct kexec_file_ops *kexec_file_loaders[] = { +const struct kexec_file_ops * const kexec_file_loaders[] = { &kexec_bzImage64_ops, + NULL }; #endif @@ -363,27 +364,6 @@ void arch_crash_save_vmcoreinfo(void) /* arch-dependent functionality related to kexec file-based syscall */ #ifdef CONFIG_KEXEC_FILE -int arch_kexec_kernel_image_probe(struct kimage *image, void *buf, - unsigned long buf_len) -{ - int i, ret = -ENOEXEC; - struct kexec_file_ops *fops; - - for (i = 0; i < ARRAY_SIZE(kexec_file_loaders); i++) { - fops = kexec_file_loaders[i]; - if (!fops || !fops->probe) - continue; - - ret = fops->probe(buf, buf_len); - if (!ret) { - image->fops = fops; - return ret; - } - } - - return ret; -} - void *arch_kexec_kernel_image_load(struct kimage *image) { vfree(image->arch.elf_headers); @@ -398,27 +378,6 @@ void *arch_kexec_kernel_image_load(struct kimage *image) image->cmdline_buf_len); } -int arch_kimage_file_post_load_cleanup(struct kimage *image) -{ - if (!image->fops || !image->fops->cleanup) - return 0; - - return image->fops->cleanup(image->image_loader_data); -} - -#ifdef CONFIG_KEXEC_VERIFY_SIG -int arch_kexec_kernel_verify_sig(struct kimage *image, void *kernel, - unsigned long kernel_len) -{ - if (!image->fops || !image->fops->verify_sig) { - pr_debug("kernel loader does not support signature verification."); - return -EKEYREJECTED; - } - - return image->fops->verify_sig(kernel, kernel_len); -} -#endif - /* * Apply purgatory relocations. * diff --git a/include/linux/kexec.h b/include/linux/kexec.h index f16f6ceb3875..4ed18cc718fc 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -135,6 +135,11 @@ struct kexec_file_ops { #endif }; +extern const struct kexec_file_ops * const kexec_file_loaders[]; + +int kexec_image_probe_default(struct kimage *image, void *buf, + unsigned long buf_len); + /** * struct kexec_buf - parameters for finding a place for a buffer in memory * @image: kexec image in which memory to search. @@ -209,7 +214,7 @@ struct kimage { unsigned long cmdline_buf_len; /* File operations provided by image loader */ - struct kexec_file_ops *fops; + const struct kexec_file_ops *fops; /* Image loader handling the kernel can store a pointer here */ void *image_loader_data; @@ -277,12 +282,6 @@ int crash_shrink_memory(unsigned long new_size); size_t crash_get_memory_size(void); void crash_free_reserved_phys_range(unsigned long begin, unsigned long end); -int __weak arch_kexec_kernel_image_probe(struct kimage *image, void *buf, - unsigned long buf_len); -void * __weak arch_kexec_kernel_image_load(struct kimage *image); -int __weak arch_kimage_file_post_load_cleanup(struct kimage *image); -int __weak arch_kexec_kernel_verify_sig(struct kimage *image, void *buf, - unsigned long buf_len); int __weak arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, unsigned int relsec); int __weak arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 6dbbb89cbbac..6a62c5ef8a07 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -28,28 +28,80 @@ static int kexec_calculate_store_digests(struct kimage *image); +/* + * Currently this is the only default function that is exported as some + * architectures need it to do additional handlings. + * In the future, other default functions may be exported too if required. + */ +int kexec_image_probe_default(struct kimage *image, void *buf, + unsigned long buf_len) +{ + const struct kexec_file_ops * const *fops; + int ret = -ENOEXEC; + + for (fops = &kexec_file_loaders[0]; *fops && (*fops)->probe; ++fops) { + ret = (*fops)->probe(buf, buf_len); + if (!ret) { + image->fops = *fops; + return ret; + } + } + + return ret; +} + /* Architectures can provide this probe function */ int __weak arch_kexec_kernel_image_probe(struct kimage *image, void *buf, unsigned long buf_len) { - return -ENOEXEC; + return kexec_image_probe_default(image, buf, buf_len); +} + +static void *kexec_image_load_default(struct kimage *image) +{ + if (!image->fops || !image->fops->load) + return ERR_PTR(-ENOEXEC); + + return image->fops->load(image, image->kernel_buf, + image->kernel_buf_len, image->initrd_buf, + image->initrd_buf_len, image->cmdline_buf, + image->cmdline_buf_len); } void * __weak arch_kexec_kernel_image_load(struct kimage *image) { - return ERR_PTR(-ENOEXEC); + return kexec_image_load_default(image); +} + +static int kexec_image_post_load_cleanup_default(struct kimage *image) +{ + if (!image->fops || !image->fops->cleanup) + return 0; + + return image->fops->cleanup(image->image_loader_data); } int __weak arch_kimage_file_post_load_cleanup(struct kimage *image) { - return -EINVAL; + return kexec_image_post_load_cleanup_default(image); } #ifdef CONFIG_KEXEC_VERIFY_SIG +static int kexec_image_verify_sig_default(struct kimage *image, void *buf, + unsigned long buf_len) +{ + if (!image->fops || !image->fops->verify_sig) { + pr_debug("kernel loader does not support signature verification.\n"); + return -EKEYREJECTED; + } + + return image->fops->verify_sig(buf, buf_len); +} + int __weak arch_kexec_kernel_verify_sig(struct kimage *image, void *buf, unsigned long buf_len) { - return -EKEYREJECTED; + return kexec_image_verify_sig_default(image, buf, buf_len); } #endif From patchwork Tue Mar 6 10:22:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 130764 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp3762857lja; Tue, 6 Mar 2018 02:24:27 -0800 (PST) X-Google-Smtp-Source: AG47ELsVGBM6MUv2eci9cghbuyNvqouZQVrSYnXks+Erqq+hyox3bY4TmQcpsZ0Mtkh2zVjQaeh+ X-Received: by 10.101.81.132 with SMTP id h4mr14895018pgq.332.1520331867617; Tue, 06 Mar 2018 02:24:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520331867; cv=none; d=google.com; s=arc-20160816; b=GIuhsSvktNxUHP6bq33Lk22DENiYW4gVCGqPHJkej0r1URhaOlfOtrJmxE6vTwKkbx ruZk5pMps7MKTMRzWiopDJq6qBk4gI28OQeNkShMlM3DpBLzZNBtYrlgVbwDzG4NPz+i zfsaP0eh6Bb3NzRjlsjuQ9nRZbB5UoipuMPoZvDbWMrqTHrOwSSDJBhyx/VnJwb1JGry k1/tXFEuOjnPT6xP7uMz4UiUHivklMywqv/htCyjX+d+1FD5f+6vk4gi6l1ynrytV23e vx3eG8Rmf9qDSJb0xwnnHrjc5Pi5ubf2vLQn0iN5im/cAmmMEgxvqgPraGEA+PgEQ4zB oTAw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=+vdHx8igNuwtKYBwEka16s0oES3aT+sWWLO70kkZrSg=; b=egBdCJ+mjj8WMDq25mIUcacJHhw0iJp8kIJKBnEW+tZw+13OuGDmqdRSIUZmk618hC VdYm1BBgBgfF1L/Ej4gmLuTabA10MISAC0RdCy8sQTjPe2oj0LmbzT3+4JhYPMHOnRus os/KtOqMvwAERWDDyb+gtbjBSNc+oCHMWPhCOr18cbFl2IZd9GLIaOtP08fEe5cDS2ov 6iO+LiELg/N6Q7Wk6liNzt+YfT3RYrlEefi+6IV2XkabiCcRaELBGuH+a3FPi+LmnXY+ Hw0Lzivmb7Ry88i8axWQAvXzvGiaxaYqqL85LaRQWG2GP1sS5ADre7EHPBhJI7RV7/mc TdPQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=gaUn6etB; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w5-v6si10684393plz.551.2018.03.06.02.24.27; Tue, 06 Mar 2018 02:24:27 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=gaUn6etB; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753475AbeCFKXa (ORCPT + 28 others); Tue, 6 Mar 2018 05:23:30 -0500 Received: from mail-io0-f194.google.com ([209.85.223.194]:41864 "EHLO mail-io0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753442AbeCFKX0 (ORCPT ); Tue, 6 Mar 2018 05:23:26 -0500 Received: by mail-io0-f194.google.com with SMTP id q24so21464343ioh.8 for ; Tue, 06 Mar 2018 02:23:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+vdHx8igNuwtKYBwEka16s0oES3aT+sWWLO70kkZrSg=; b=gaUn6etBk+tP09kV0mX+o/d6dwlbT18KJBg3aRajKzQriZ38t10S2XcqSJcuDcDj/i mHp2dOuOCIPwltDWJ0lQ/DyeUvFClKQcFltQ1L5pSJi29SoNVSZ8bYC+ZjoeoFTeuY95 iY6KkXb8YaprU0KWVxX9sk6kF4npOa967ycvY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+vdHx8igNuwtKYBwEka16s0oES3aT+sWWLO70kkZrSg=; b=WxjZdEnYRBzjH4fy+4lq1vUevhZ4im/tsMl1k3TbQfUKsLKjQjgCUCIYIML7CjXCJH KoO36e8C2WvSB3nGwwbu0b1FS4TSPag5kbm2p7srkQmnuXfHm8NmmXwxWx7ldgpZCnR1 N450rGwGDrHX9scYH5Gl9PzII41LMBqN1LrETOVXrgg0ibtvgUPR3yGwwq02GaW2fwSP 8Vw7AYRGX0rh6l0oCmygSJoEX+U00gLrSvh+Kn1BfRvb99QuoG4+eiY8MhLjtq1wl2go Z7tiaIG1ZxYgpYbfwRVM4af9qXvt+Z3GkSjXazJGpCQpTuw71pPh7Mqmyxc/UIfS6/V5 ecNg== X-Gm-Message-State: APf1xPBDPasH8xzef86EyLpcmuaotsxG8320uiRW0/1OytY0wzSSQFyB 52BjgpdbhxP5kHzJBl9DYztQwQ== X-Received: by 10.107.143.23 with SMTP id r23mr20762572iod.191.1520331805415; Tue, 06 Mar 2018 02:23:25 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id n22sm9691145iob.62.2018.03.06.02.23.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Mar 2018 02:23:24 -0800 (PST) From: AKASHI Takahiro To: dyoung@redhat.com, vgoyal@redhat.com, bhe@redhat.com, mpe@ellerman.id.au, bauerman@linux.vnet.ibm.com, prudo@linux.vnet.ibm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v2 3/7] x86: kexec_file: purge system-ram walking from prepare_elf64_headers() Date: Tue, 6 Mar 2018 19:22:59 +0900 Message-Id: <20180306102303.9063-4-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180306102303.9063-1-takahiro.akashi@linaro.org> References: <20180306102303.9063-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org While prepare_elf64_headers() in x86 looks pretty generic for other architectures' use, it contains some code which tries to list crash memory regions by walking through system resources, which is not always architecture agnostic. To make this function more generic, the related code should be purged. In this patch, prepare_elf64_headers() simply scans crash_mem buffer passed and add all the listed regions to elf header as a PT_LOAD segment. So walk_system_ram_res(prepare_elf64_headers_callback) have been moved forward before prepare_elf64_headers() where the callback, prepare_elf64_headers_callback(), is now responsible for filling up crash_mem buffer. Meanwhile exclude_elf_header_ranges() used to be called every time in this callback it is rather redundant and now called only once in prepare_elf_headers() as well. Signed-off-by: AKASHI Takahiro Cc: Dave Young Cc: Vivek Goyal Cc: Baoquan He --- arch/x86/kernel/crash.c | 121 +++++++++++++++++++++++------------------------- 1 file changed, 58 insertions(+), 63 deletions(-) -- 2.16.2 diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 10e74d4778a1..2123fa0efc17 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -316,18 +316,11 @@ static int exclude_mem_range(struct crash_mem *mem, * Look for any unwanted ranges between mstart, mend and remove them. This * might lead to split and split ranges are put in ced->mem.ranges[] array */ -static int elf_header_exclude_ranges(struct crash_elf_data *ced, - unsigned long long mstart, unsigned long long mend) +static int elf_header_exclude_ranges(struct crash_elf_data *ced) { struct crash_mem *cmem = &ced->mem; int ret = 0; - memset(cmem->ranges, 0, sizeof(cmem->ranges)); - - cmem->ranges[0].start = mstart; - cmem->ranges[0].end = mend; - cmem->nr_ranges = 1; - /* Exclude crashkernel region */ ret = exclude_mem_range(cmem, crashk_res.start, crashk_res.end); if (ret) @@ -345,53 +338,13 @@ static int elf_header_exclude_ranges(struct crash_elf_data *ced, static int prepare_elf64_ram_headers_callback(struct resource *res, void *arg) { struct crash_elf_data *ced = arg; - Elf64_Ehdr *ehdr; - Elf64_Phdr *phdr; - unsigned long mstart, mend; - struct kimage *image = ced->image; - struct crash_mem *cmem; - int ret, i; - - ehdr = ced->ehdr; - - /* Exclude unwanted mem ranges */ - ret = elf_header_exclude_ranges(ced, res->start, res->end); - if (ret) - return ret; - - /* Go through all the ranges in ced->mem.ranges[] and prepare phdr */ - cmem = &ced->mem; - - for (i = 0; i < cmem->nr_ranges; i++) { - mstart = cmem->ranges[i].start; - mend = cmem->ranges[i].end; - - phdr = ced->bufp; - ced->bufp += sizeof(Elf64_Phdr); + struct crash_mem *cmem = &ced->mem; - phdr->p_type = PT_LOAD; - phdr->p_flags = PF_R|PF_W|PF_X; - phdr->p_offset = mstart; + cmem->ranges[cmem->nr_ranges].start = res->start; + cmem->ranges[cmem->nr_ranges].end = res->end; + cmem->nr_ranges++; - /* - * If a range matches backup region, adjust offset to backup - * segment. - */ - if (mstart == image->arch.backup_src_start && - (mend - mstart + 1) == image->arch.backup_src_sz) - phdr->p_offset = image->arch.backup_load_addr; - - phdr->p_paddr = mstart; - phdr->p_vaddr = (unsigned long long) __va(mstart); - phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; - phdr->p_align = 0; - ehdr->e_phnum++; - pr_debug("Crash PT_LOAD elf header. phdr=%p vaddr=0x%llx, paddr=0x%llx, sz=0x%llx e_phnum=%d p_offset=0x%llx\n", - phdr, phdr->p_vaddr, phdr->p_paddr, phdr->p_filesz, - ehdr->e_phnum, phdr->p_offset); - } - - return ret; + return 0; } static int prepare_elf64_headers(struct crash_elf_data *ced, @@ -401,9 +354,10 @@ static int prepare_elf64_headers(struct crash_elf_data *ced, Elf64_Phdr *phdr; unsigned long nr_cpus = num_possible_cpus(), nr_phdr, elf_sz; unsigned char *buf, *bufp; - unsigned int cpu; + unsigned int cpu, i; unsigned long long notes_addr; - int ret; + struct crash_mem *cmem = &ced->mem; + unsigned long mstart, mend; /* extra phdr for vmcoreinfo elf note */ nr_phdr = nr_cpus + 1; @@ -472,13 +426,25 @@ static int prepare_elf64_headers(struct crash_elf_data *ced, (ehdr->e_phnum)++; #endif - /* Prepare PT_LOAD headers for system ram chunks. */ - ced->ehdr = ehdr; - ced->bufp = bufp; - ret = walk_system_ram_res(0, -1, ced, - prepare_elf64_ram_headers_callback); - if (ret < 0) - return ret; + /* Go through all the ranges in cmem->ranges[] and prepare phdr */ + for (i = 0; i < cmem->nr_ranges; i++) { + mstart = cmem->ranges[i].start; + mend = cmem->ranges[i].end; + + phdr->p_type = PT_LOAD; + phdr->p_flags = PF_R|PF_W|PF_X; + phdr->p_offset = mstart; + + phdr->p_paddr = mstart; + phdr->p_vaddr = (unsigned long long) __va(mstart); + phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; + phdr->p_align = 0; + ehdr->e_phnum++; + phdr++; + pr_debug("Crash PT_LOAD elf header. phdr=%p vaddr=0x%llx, paddr=0x%llx, sz=0x%llx e_phnum=%d p_offset=0x%llx\n", + phdr, phdr->p_vaddr, phdr->p_paddr, phdr->p_filesz, + ehdr->e_phnum, phdr->p_offset); + } *addr = buf; *sz = elf_sz; @@ -490,7 +456,9 @@ static int prepare_elf_headers(struct kimage *image, void **addr, unsigned long *sz) { struct crash_elf_data *ced; - int ret; + Elf64_Ehdr *ehdr; + Elf64_Phdr *phdr; + int ret, i; ced = kzalloc(sizeof(*ced), GFP_KERNEL); if (!ced) @@ -498,8 +466,35 @@ static int prepare_elf_headers(struct kimage *image, void **addr, fill_up_crash_elf_data(ced, image); + ret = walk_system_ram_res(0, -1, ced, + prepare_elf64_ram_headers_callback); + if (ret) + goto out; + + /* Exclude unwanted mem ranges */ + ret = elf_header_exclude_ranges(ced); + if (ret) + goto out; + /* By default prepare 64bit headers */ ret = prepare_elf64_headers(ced, addr, sz); + if (ret) + goto out; + + /* + * If a range matches backup region, adjust offset to backup + * segment. + */ + ehdr = (Elf64_Ehdr *)*addr; + phdr = (Elf64_Phdr *)(ehdr + 1); + for (i = 0; i < ehdr->e_phnum; phdr++, i++) + if (phdr->p_type == PT_LOAD && + phdr->p_paddr == image->arch.backup_src_start && + phdr->p_memsz == image->arch.backup_src_sz) { + phdr->p_offset = image->arch.backup_load_addr; + break; + } +out: kfree(ced); return ret; } From patchwork Tue Mar 6 10:23:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 130760 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp3762149lja; Tue, 6 Mar 2018 02:23:37 -0800 (PST) X-Google-Smtp-Source: AG47ELvagU1PYHQjQQa1c2YdpEbyruWSIAwegCYy743hIjGozjxmdJGEhtgS1GgivUvD7uYzqFdV X-Received: by 10.99.185.7 with SMTP id z7mr15141708pge.123.1520331817421; Tue, 06 Mar 2018 02:23:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520331817; cv=none; d=google.com; s=arc-20160816; b=esBKmMwCp4W8hWC22K8OxJtDlSe1BKLzQ3X17rpnTyRD1wajaDHYaxMMJ2dMhHJC7a O8PJ7CXgjUK3Sc8bzzVLcCE5nfsydmgXce69HxGCJTEPfyigMfL07MaaJERoCG6H30Ed PgbRCqvlMPKPk6kt3cHluXwrdhGsLgzNdQbduGHtvhKMVqD4oYNzuFY1m1BKOUbU94KH L5D46BY9FmMv/IN8d4vLEYMxiHIHpIMV32Oi/gxmhlHTltkr8tLxXxC1yMG4LMI6OJh8 r7bHDPTA19SYdbFGYiLCxdvFiyM/e4poYOBep4ltOt5cCBVRHlFuuswHo23DWeSrfHDs Udzw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=d6Ypw70si/N5yDuCn8ahcqNjgVw4ZqeO0m057ExWqoA=; b=YvCQyJuy7d1K69bJgb3AUpP36/U34OrJ8hPEBQ02C0Pyjwjcz4rSk09R1fBNLeALRw Nna9lKVOLwCGBATvFU/v7CvpduY3B2hDPfCSng17AiHwyG6MCXEYouvUwCqhz5K1xNgi v9JaY4phloha8m1pylU5Aie22gcEKqjm1She9UidYMfrN3MancydxB1WOBjT4vqpBp6h rE4KFVI1KjLVAOUuVkxbdp50Y1vqeaERexd5nYDQSc6AmN4Rt1Gj0F3q/1WfOFEDfHz8 MpKmJ+zsKszDE6easT03nxJGED6Q4hCN7ELGmXxDuMmQfHX6nCt8yEszHSrwh5TlGbMk ZPuA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=LQfesa+C; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x4-v6si10789697plw.297.2018.03.06.02.23.37; Tue, 06 Mar 2018 02:23:37 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=LQfesa+C; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753496AbeCFKXd (ORCPT + 28 others); Tue, 6 Mar 2018 05:23:33 -0500 Received: from mail-it0-f65.google.com ([209.85.214.65]:53418 "EHLO mail-it0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753453AbeCFKXa (ORCPT ); Tue, 6 Mar 2018 05:23:30 -0500 Received: by mail-it0-f65.google.com with SMTP id w63so13141955ita.3 for ; Tue, 06 Mar 2018 02:23:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=d6Ypw70si/N5yDuCn8ahcqNjgVw4ZqeO0m057ExWqoA=; b=LQfesa+Cd9vDV3kRQy2p39RZL2z//JnhmcrN+dVIRRFvElmvR3sWq7bgUcAY/4CPmx TGDUTJ8WbWa0yJlO71ZXiaXECfwsdf6+uX8fe5g4kupHrXYdKQblqj0a3yzWYB03Zra/ iiE6NlaZV895Or03bg/95gGOlKxQBpbPDEiRo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=d6Ypw70si/N5yDuCn8ahcqNjgVw4ZqeO0m057ExWqoA=; b=e92mIaXRcv0f1ql18venhj122k8JzkmMmfgA90uOgI7AyHx3L8NLCTXNXg6P4hTnE4 EKEncg5TB0Y2wST2AsjJfRXVOsX+h3G+l2yGrHEIRm+EA4vbnQ0Eu+LzS4g5x/nz3Of8 3lAa04vlMWw7vDZwP4x5cOCJRAkV8D4k7H9+/IuEF14Aeku5PB/pEc9x6+m+0ojt8L58 DFhe2Dzi9gpcVrOBpU9CNJZgO+iFEedT3FAczGEqIEumrrC5JUB5UKEt3RQOvLRUAXr4 4Ildk83pjSTPTpwNABaqg5zmaZ/iaVy5pUVzr5nXK4CQCAZZn+gQ3BsBUKClFdHdbjkr 9bNw== X-Gm-Message-State: AElRT7H4JIr9zDoUN/WYIgft68u2/gvVnHqRIIA7ryatpuA+8VWyDCP4 KTUaXCYiwkE0GUnnwII+wReGCw== X-Received: by 10.36.175.66 with SMTP id l2mr17564596iti.43.1520331809633; Tue, 06 Mar 2018 02:23:29 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id v2sm9672414iob.21.2018.03.06.02.23.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Mar 2018 02:23:29 -0800 (PST) From: AKASHI Takahiro To: dyoung@redhat.com, vgoyal@redhat.com, bhe@redhat.com, mpe@ellerman.id.au, bauerman@linux.vnet.ibm.com, prudo@linux.vnet.ibm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v2 4/7] x86: kexec_file: remove X86_64 dependency from prepare_elf64_headers() Date: Tue, 6 Mar 2018 19:23:00 +0900 Message-Id: <20180306102303.9063-5-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180306102303.9063-1-takahiro.akashi@linaro.org> References: <20180306102303.9063-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The code guarded by CONFIG_X86_64 is necessary on some architectures which have a dedicated kernel mapping outside of linear memory mapping. (arm64 is among those.) In this patch, an additional argument, kernel_map, is added to enable/ disable the code removing #ifdef. Signed-off-by: AKASHI Takahiro Cc: Dave Young Cc: Vivek Goyal Cc: Baoquan He --- arch/x86/kernel/crash.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) -- 2.16.2 diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 2123fa0efc17..b328153cee65 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -347,7 +347,7 @@ static int prepare_elf64_ram_headers_callback(struct resource *res, void *arg) return 0; } -static int prepare_elf64_headers(struct crash_elf_data *ced, +static int prepare_elf64_headers(struct crash_elf_data *ced, bool kernel_map, void **addr, unsigned long *sz) { Elf64_Ehdr *ehdr; @@ -414,17 +414,17 @@ static int prepare_elf64_headers(struct crash_elf_data *ced, phdr->p_filesz = phdr->p_memsz = VMCOREINFO_NOTE_SIZE; (ehdr->e_phnum)++; -#ifdef CONFIG_X86_64 /* Prepare PT_LOAD type program header for kernel text region */ - phdr = (Elf64_Phdr *)bufp; - bufp += sizeof(Elf64_Phdr); - phdr->p_type = PT_LOAD; - phdr->p_flags = PF_R|PF_W|PF_X; - phdr->p_vaddr = (Elf64_Addr)_text; - phdr->p_filesz = phdr->p_memsz = _end - _text; - phdr->p_offset = phdr->p_paddr = __pa_symbol(_text); - (ehdr->e_phnum)++; -#endif + if (kernel_map) { + phdr = (Elf64_Phdr *)bufp; + bufp += sizeof(Elf64_Phdr); + phdr->p_type = PT_LOAD; + phdr->p_flags = PF_R|PF_W|PF_X; + phdr->p_vaddr = (Elf64_Addr)_text; + phdr->p_filesz = phdr->p_memsz = _end - _text; + phdr->p_offset = phdr->p_paddr = __pa_symbol(_text); + (ehdr->e_phnum)++; + } /* Go through all the ranges in cmem->ranges[] and prepare phdr */ for (i = 0; i < cmem->nr_ranges; i++) { @@ -477,7 +477,7 @@ static int prepare_elf_headers(struct kimage *image, void **addr, goto out; /* By default prepare 64bit headers */ - ret = prepare_elf64_headers(ced, addr, sz); + ret = prepare_elf64_headers(ced, IS_ENABLED(CONFIG_X86_64), addr, sz); if (ret) goto out; From patchwork Tue Mar 6 10:23:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 130761 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp3762211lja; Tue, 6 Mar 2018 02:23:42 -0800 (PST) X-Google-Smtp-Source: AG47ELvuolabMYAOVqRYOIJfFNhtPaz7jRnMo6PAS7Bqkf/KUsvuP+Ga2OxG6P6yFFbl+H8OsNtj X-Received: by 10.99.143.3 with SMTP id n3mr14711598pgd.159.1520331821902; Tue, 06 Mar 2018 02:23:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520331821; cv=none; d=google.com; s=arc-20160816; b=XJvBz5q4o407n3iR5yfY7h+OS2l6rjdeo30Pmt55MOTG46F+qVFb8zmS35JI5yVIIg X1Al5twEMD9UinKZ/BzxoeVUix8I62XIix5RZFF7vsNxJn54nRlPV2oAGSfXGg9rhin9 exTIfbihX4zTPfE7Xgjp4MTQ2nWZL4hCK9Qt4eB0BxxXYfuRctJvckw4CEhSkYA5WRXr OmhZCqckrPtBprnbrBN0lCll7l1NUSdHOyJLUk1AhLc280GAjzAu3rAB9Fu0TQj9i9Nc O5crkR2tQcOOOMxt4AECjHjHyxttK4HiUUJFZ+Wu1V28NkPFKScy/vZJPMpKiJTUqcoo bBag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=/VY+FFJrNPaxjaCzFTNjK1ZYe2uky/NRRaXjMwBDnfI=; b=Tp4EHtZYtF3HdRgbYe3M2qqdnEApSaR4FhijDGVmnTlXGrfPpl0wxqC+aLHTtSxPnG kt27apRTo28rYUhsoGqcogz0KDUnJv5vZ1oR5NXhemE+KG3UXoG7nzTexEimEQlGZzwx o9oM6mSmGtoDfzGIdsSgeVIw7SYFWc6MaAl7gAHc8dBrA/snnLgfRxY2y08YoVcTWrnm W0JvMrtN6xJYu1yG5Cvs+LeQarcrAkfRe1P97nl/5yzn2bnIyOPEF6s3alSrrvp7I8QV 3BVRAhdgolI7mHo5XyB3zacuvG29Y/F4ul+eGO3xRYU+8cd18l98tG2HqJP9MpjqPTKC Fa6w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Kjyelv8v; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x4-v6si10789697plw.297.2018.03.06.02.23.41; Tue, 06 Mar 2018 02:23:41 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Kjyelv8v; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753516AbeCFKXi (ORCPT + 28 others); Tue, 6 Mar 2018 05:23:38 -0500 Received: from mail-io0-f194.google.com ([209.85.223.194]:35338 "EHLO mail-io0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753305AbeCFKXe (ORCPT ); Tue, 6 Mar 2018 05:23:34 -0500 Received: by mail-io0-f194.google.com with SMTP id 30so21493665iog.2 for ; Tue, 06 Mar 2018 02:23:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/VY+FFJrNPaxjaCzFTNjK1ZYe2uky/NRRaXjMwBDnfI=; b=Kjyelv8v2b0h2S8Kw5mmmH3wOPXAwdE4Zm6txuifKbeXMwxpmvKcTdFaS2F5CgIFhs vqSoxRTFhr9xjC6MBb0XH/gceGyvHJ8xRNY+eqy7LUyWiIWdwNVeKuzx/akVMWskZweY 4EdvX1T0owU+FNMBHsOxhD4cYT8LCqQFyYpBE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/VY+FFJrNPaxjaCzFTNjK1ZYe2uky/NRRaXjMwBDnfI=; b=HGwgXTmrzVNem4jneFtanSZg5/VGRjj3uR8oh2Pk93Ld+KTiYgSzukQlB23sH7YXg9 A1M1/KaHZGFE6hFvTgYkNtND0T4mgNsk12dcv4QfF8X5HFkk6K5QdwDGSlKs0rUu29fp WURJ3K/Lc40yeBU+BKwo5uJGMIiTkf1d5LZy3JHIHNj/WLLNLkv3A7Z4k0kVU8o6XmYi 44SpDpg46qTAVs6qFnL7d/O5NXI43v03bsmUR4yemQqohalzbBoXbtNvLpdF/jS7Eg45 +J427y2DZkmcauWmj2mqcJxcZ5N0mNp/T254fT66JBXbnkhLmN7Dhxlt6yVDVeexxwkh VfDg== X-Gm-Message-State: APf1xPBjQnhBW4tJ5XNdF4wgU4s2cc6NHT0evM60tZux4G9Uhnq/Euvy 7JHxsrer0+mobE2ySzxYzz4ZNA== X-Received: by 10.107.59.130 with SMTP id i124mr20744173ioa.129.1520331814189; Tue, 06 Mar 2018 02:23:34 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id k198sm6494478itk.5.2018.03.06.02.23.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Mar 2018 02:23:33 -0800 (PST) From: AKASHI Takahiro To: dyoung@redhat.com, vgoyal@redhat.com, bhe@redhat.com, mpe@ellerman.id.au, bauerman@linux.vnet.ibm.com, prudo@linux.vnet.ibm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v2 5/7] x86: kexec_file: lift CRASH_MAX_RANGES limit on crash_mem buffer Date: Tue, 6 Mar 2018 19:23:01 +0900 Message-Id: <20180306102303.9063-6-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180306102303.9063-1-takahiro.akashi@linaro.org> References: <20180306102303.9063-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org While CRASH_MAX_RANGES (== 16) seems to be good enough, fixed-number array is not a good idea in general. In this patch, size of crash_mem buffer is calculated as before and the buffer is now dynamically allocated. This change also allows removing crash_elf_data structure. Signed-off-by: AKASHI Takahiro Cc: Dave Young Cc: Vivek Goyal Cc: Baoquan He --- arch/x86/kernel/crash.c | 82 +++++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 51 deletions(-) -- 2.16.2 diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index b328153cee65..0f20a6330bd6 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -41,32 +41,14 @@ /* Alignment required for elf header segment */ #define ELF_CORE_HEADER_ALIGN 4096 -/* This primarily represents number of split ranges due to exclusion */ -#define CRASH_MAX_RANGES 16 - struct crash_mem_range { u64 start, end; }; struct crash_mem { - unsigned int nr_ranges; - struct crash_mem_range ranges[CRASH_MAX_RANGES]; -}; - -/* Misc data about ram ranges needed to prepare elf headers */ -struct crash_elf_data { - struct kimage *image; - /* - * Total number of ram ranges we have after various adjustments for - * crash reserved region, etc. - */ unsigned int max_nr_ranges; - - /* Pointer to elf header */ - void *ehdr; - /* Pointer to next phdr */ - void *bufp; - struct crash_mem mem; + unsigned int nr_ranges; + struct crash_mem_range ranges[0]; }; /* Used while preparing memory map entries for second kernel */ @@ -217,26 +199,31 @@ static int get_nr_ram_ranges_callback(struct resource *res, void *arg) return 0; } - /* Gather all the required information to prepare elf headers for ram regions */ -static void fill_up_crash_elf_data(struct crash_elf_data *ced, - struct kimage *image) +static struct crash_mem *fill_up_crash_elf_data(void) { unsigned int nr_ranges = 0; - - ced->image = image; + struct crash_mem *cmem; walk_system_ram_res(0, -1, &nr_ranges, get_nr_ram_ranges_callback); + if (!nr_ranges) + return NULL; - ced->max_nr_ranges = nr_ranges; + /* + * Exclusion of crash region and/or crashk_low_res may cause + * another range split. So add extra two slots here. + */ + nr_ranges += 2; + cmem = vzalloc(sizeof(struct crash_mem) + + sizeof(struct crash_mem_range) * nr_ranges); + if (!cmem) + return NULL; - /* Exclusion of crash region could split memory ranges */ - ced->max_nr_ranges++; + cmem->max_nr_ranges = nr_ranges; + cmem->nr_ranges = 0; - /* If crashk_low_res is not 0, another range split possible */ - if (crashk_low_res.end) - ced->max_nr_ranges++; + return cmem; } static int exclude_mem_range(struct crash_mem *mem, @@ -293,10 +280,8 @@ static int exclude_mem_range(struct crash_mem *mem, return 0; /* Split happened */ - if (i == CRASH_MAX_RANGES - 1) { - pr_err("Too many crash ranges after split\n"); + if (i == mem->max_nr_ranges - 1) return -ENOMEM; - } /* Location where new range should go */ j = i + 1; @@ -314,11 +299,10 @@ static int exclude_mem_range(struct crash_mem *mem, /* * Look for any unwanted ranges between mstart, mend and remove them. This - * might lead to split and split ranges are put in ced->mem.ranges[] array + * might lead to split and split ranges are put in cmem->ranges[] array */ -static int elf_header_exclude_ranges(struct crash_elf_data *ced) +static int elf_header_exclude_ranges(struct crash_mem *cmem) { - struct crash_mem *cmem = &ced->mem; int ret = 0; /* Exclude crashkernel region */ @@ -337,8 +321,7 @@ static int elf_header_exclude_ranges(struct crash_elf_data *ced) static int prepare_elf64_ram_headers_callback(struct resource *res, void *arg) { - struct crash_elf_data *ced = arg; - struct crash_mem *cmem = &ced->mem; + struct crash_mem *cmem = arg; cmem->ranges[cmem->nr_ranges].start = res->start; cmem->ranges[cmem->nr_ranges].end = res->end; @@ -347,7 +330,7 @@ static int prepare_elf64_ram_headers_callback(struct resource *res, void *arg) return 0; } -static int prepare_elf64_headers(struct crash_elf_data *ced, bool kernel_map, +static int prepare_elf64_headers(struct crash_mem *cmem, bool kernel_map, void **addr, unsigned long *sz) { Elf64_Ehdr *ehdr; @@ -356,12 +339,11 @@ static int prepare_elf64_headers(struct crash_elf_data *ced, bool kernel_map, unsigned char *buf, *bufp; unsigned int cpu, i; unsigned long long notes_addr; - struct crash_mem *cmem = &ced->mem; unsigned long mstart, mend; /* extra phdr for vmcoreinfo elf note */ nr_phdr = nr_cpus + 1; - nr_phdr += ced->max_nr_ranges; + nr_phdr += cmem->nr_ranges; /* * kexec-tools creates an extra PT_LOAD phdr for kernel text mapping @@ -455,29 +437,27 @@ static int prepare_elf64_headers(struct crash_elf_data *ced, bool kernel_map, static int prepare_elf_headers(struct kimage *image, void **addr, unsigned long *sz) { - struct crash_elf_data *ced; + struct crash_mem *cmem; Elf64_Ehdr *ehdr; Elf64_Phdr *phdr; int ret, i; - ced = kzalloc(sizeof(*ced), GFP_KERNEL); - if (!ced) + cmem = fill_up_crash_elf_data(); + if (!cmem) return -ENOMEM; - fill_up_crash_elf_data(ced, image); - - ret = walk_system_ram_res(0, -1, ced, + ret = walk_system_ram_res(0, -1, cmem, prepare_elf64_ram_headers_callback); if (ret) goto out; /* Exclude unwanted mem ranges */ - ret = elf_header_exclude_ranges(ced); + ret = elf_header_exclude_ranges(cmem); if (ret) goto out; /* By default prepare 64bit headers */ - ret = prepare_elf64_headers(ced, IS_ENABLED(CONFIG_X86_64), addr, sz); + ret = prepare_elf64_headers(cmem, IS_ENABLED(CONFIG_X86_64), addr, sz); if (ret) goto out; @@ -495,7 +475,7 @@ static int prepare_elf_headers(struct kimage *image, void **addr, break; } out: - kfree(ced); + vfree(cmem); return ret; } From patchwork Tue Mar 6 10:23:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 130762 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp3762342lja; Tue, 6 Mar 2018 02:23:49 -0800 (PST) X-Google-Smtp-Source: AG47ELsG0bvMdfpQz7SFVlT/qgao5eH8QhlZZzN31urbo2L2OHchUeqaofOlrvoD65NEIEO6r/6b X-Received: by 2002:a17:902:5303:: with SMTP id b3-v6mr16549533pli.19.1520331829616; Tue, 06 Mar 2018 02:23:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520331829; cv=none; d=google.com; s=arc-20160816; b=qlKwkX7iRNRHWD9SQO6oriBBHdchioBQd/xb4yKjmFxb9Uve/k0mYb3YLgj9A041mx NDf/4MUSJPg1NIokAthFf+al7TyW/OEATb88aCqqD9XH7GjolzvWFHOL/E/PeaZFmLdg oadAhnULRGWbO5bbNj+Fzti7bIYUf4tJwxWayisdReKjvJ06DHYrQoplZSieN1JJH8s+ i/TpYn3bSUocyk0bIxMpSz6CbSvY6wE9fWL2Z1Yy4StmSSNu+pl8akqfcpzTVzj8l9ir gK4m2UcG2mv/PPhyhAGiDb+2dfQak975bmadxVk6RiHvnB15A+Xyf5CMIy8ig2nYkHGa yDGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=cvruR1fK+YTngn6oDfuQqc3wPWykq+0V2AulaM5gBOY=; b=avhMwji5MKYCPLqhsgXIIsqFkD0X9LEmF8iR2Rq2PF+sEN2mMfxhxakHosniTWU9Vp tdPnBDKjKr2cP7H12sg2XTrxwSDAQzL5USai6FZeQ/yq8OJ8EPemALufy4xDdp2kOWMp q75rNone/T6VEDXYQmoaH15tdxzsxC+0h5qTodYOahchpzJo3F2QUwnNSgzyPNCNvE67 +ocp4CYo5bW1mwjxBgChrNCTC59M44H43J726FJG/+CgGrFUw9WQqLM5ITBhgQL6tpax s1eOJXVJUYI+S0YylABko1A+dw0hJoTynWEAvUhLY+UQ5HS0jJLpjWzbLAgZZLZT/Jjs MzHg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=E83ezOS7; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s190si9656611pgc.510.2018.03.06.02.23.49; Tue, 06 Mar 2018 02:23:49 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=E83ezOS7; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753534AbeCFKXo (ORCPT + 28 others); Tue, 6 Mar 2018 05:23:44 -0500 Received: from mail-io0-f193.google.com ([209.85.223.193]:46671 "EHLO mail-io0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753305AbeCFKXj (ORCPT ); Tue, 6 Mar 2018 05:23:39 -0500 Received: by mail-io0-f193.google.com with SMTP id p78so21481568iod.13 for ; Tue, 06 Mar 2018 02:23:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cvruR1fK+YTngn6oDfuQqc3wPWykq+0V2AulaM5gBOY=; b=E83ezOS7joLwYiR1oFoCW9mbVBxVMzbx8Th2Qkzg6g4NOhrAs4MTwj9e+zBnI3HUV3 lrNH6SL1PzC6JemSGWg5ugv9fao45TQxWyyW9nl5mLoztkF0Cqx85/2upNW2M3UobIO4 dYKIjPKjsMKM0xFaEGu28uGpyTSfiJm2N+w/E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=cvruR1fK+YTngn6oDfuQqc3wPWykq+0V2AulaM5gBOY=; b=q+/zS3290oHg2tsAvJnKasKRAWhM8JJMss+6pZav/9yn+nRGC/9SxONUWkGOlrQsSn O3NuHPIZ+zXHvhNcaCwPpAk19sLkkFMaFSdLDe/F5XH81jZzm3NQjJqgVD9DYrl9nMxs vrufYY0nwVwyhekm63RECDPy/EYQBAdUXLteMXra91HwdXub54rlBsy/kwGihGKzLpwj lCzA/B7+F1Al6d+GdGdHi2INQRmOTXprTQ8t9XJogM9Tbw8sMsDV+YWmfuqgEI95ou1o Ci7NQMo+GFRLQneBe81BVZIVZOy4SC8xi4pfTDkAzG0D6yI4Q1dtC8Xt8ps5wcSvv5tu naxA== X-Gm-Message-State: APf1xPBafVN3FzeehfAfZpZHmMhBDmmg/CVWwWIqrNuolVqcBNyNM7kn VXPCXGc1xdB2ZkpzHaKObQmKhw== X-Received: by 10.107.175.151 with SMTP id p23mr20299484ioo.215.1520331818831; Tue, 06 Mar 2018 02:23:38 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id i197sm9909999ioe.54.2018.03.06.02.23.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Mar 2018 02:23:38 -0800 (PST) From: AKASHI Takahiro To: dyoung@redhat.com, vgoyal@redhat.com, bhe@redhat.com, mpe@ellerman.id.au, bauerman@linux.vnet.ibm.com, prudo@linux.vnet.ibm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v2 6/7] x86: kexec_file: clean up prepare_elf64_headers() Date: Tue, 6 Mar 2018 19:23:02 +0900 Message-Id: <20180306102303.9063-7-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180306102303.9063-1-takahiro.akashi@linaro.org> References: <20180306102303.9063-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org removing bufp variable in prepare_elf64_headers() makes the code simpler and more understandable. Signed-off-by: AKASHI Takahiro Cc: Dave Young Cc: Vivek Goyal Cc: Baoquan He --- arch/x86/kernel/crash.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) -- 2.16.2 diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 0f20a6330bd6..24de3f13f40c 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -336,7 +336,7 @@ static int prepare_elf64_headers(struct crash_mem *cmem, bool kernel_map, Elf64_Ehdr *ehdr; Elf64_Phdr *phdr; unsigned long nr_cpus = num_possible_cpus(), nr_phdr, elf_sz; - unsigned char *buf, *bufp; + unsigned char *buf; unsigned int cpu, i; unsigned long long notes_addr; unsigned long mstart, mend; @@ -361,9 +361,8 @@ static int prepare_elf64_headers(struct crash_mem *cmem, bool kernel_map, if (!buf) return -ENOMEM; - bufp = buf; - ehdr = (Elf64_Ehdr *)bufp; - bufp += sizeof(Elf64_Ehdr); + ehdr = (Elf64_Ehdr *)buf; + phdr = (Elf64_Phdr *)(ehdr + 1); memcpy(ehdr->e_ident, ELFMAG, SELFMAG); ehdr->e_ident[EI_CLASS] = ELFCLASS64; ehdr->e_ident[EI_DATA] = ELFDATA2LSB; @@ -379,33 +378,30 @@ static int prepare_elf64_headers(struct crash_mem *cmem, bool kernel_map, /* Prepare one phdr of type PT_NOTE for each present cpu */ for_each_present_cpu(cpu) { - phdr = (Elf64_Phdr *)bufp; - bufp += sizeof(Elf64_Phdr); phdr->p_type = PT_NOTE; notes_addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpu)); phdr->p_offset = phdr->p_paddr = notes_addr; phdr->p_filesz = phdr->p_memsz = sizeof(note_buf_t); (ehdr->e_phnum)++; + phdr++; } /* Prepare one PT_NOTE header for vmcoreinfo */ - phdr = (Elf64_Phdr *)bufp; - bufp += sizeof(Elf64_Phdr); phdr->p_type = PT_NOTE; phdr->p_offset = phdr->p_paddr = paddr_vmcoreinfo_note(); phdr->p_filesz = phdr->p_memsz = VMCOREINFO_NOTE_SIZE; (ehdr->e_phnum)++; + phdr++; /* Prepare PT_LOAD type program header for kernel text region */ if (kernel_map) { - phdr = (Elf64_Phdr *)bufp; - bufp += sizeof(Elf64_Phdr); phdr->p_type = PT_LOAD; phdr->p_flags = PF_R|PF_W|PF_X; phdr->p_vaddr = (Elf64_Addr)_text; phdr->p_filesz = phdr->p_memsz = _end - _text; phdr->p_offset = phdr->p_paddr = __pa_symbol(_text); - (ehdr->e_phnum)++; + ehdr->e_phnum++; + phdr++; } /* Go through all the ranges in cmem->ranges[] and prepare phdr */ From patchwork Tue Mar 6 10:23:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 130763 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp3762388lja; Tue, 6 Mar 2018 02:23:53 -0800 (PST) X-Google-Smtp-Source: AG47ELuaS2hiC001SmleHPbxXPhhuU9Ia15o1cscg75+o8PZStP/1s9Fg76Hb2L7zNdlou7uh2Ne X-Received: by 2002:a17:902:76c4:: with SMTP id j4-v6mr16764251plt.410.1520331833335; Tue, 06 Mar 2018 02:23:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520331833; cv=none; d=google.com; s=arc-20160816; b=doUmWkl3R36SEb63fKCHGg0/FZ9uFR6qfM92JzIg/jYVi3557pDmjHPQiC4zuOcXWd MzsifZyW/MvJcAAKZ1uXnGep6ossGV76QjkGLbRrZaNt7Zj/loHuuwrtFvqV+iUJghsn rBxcFYWgnodrXi3R7IFddFkYLCbQvwfzLzulq/wKHWZtSiK7D/XjTxmxhV9SDR2Ry/IN k4KLatO2VY8Ecjw2Tj886HO1gWHap7mL+Oy5562ZnZTU2pHfUfr9VnDJMbQEG21XkH2u 5wdl8ijCjk0qoLrd0bKH5qnSvyP7yhN+bAhgcXKRN9oC4l00R+R47xAL3LYsJz+il9uU 8mkA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=i5UJ4ulVH6tjQa8IviOO8w+SjdcTE6o9qLnrRU5tZt4=; b=UGrQQ0BpTwfMov+wiRoEHVWZ9zV62LAtz4/IPtXEeXBmTGjD5SqX4m3NxS9+XJM+Zd Ra39499eMC6ug82BBg6qrz1dOseFdFj3AKu0OBfvORnYOGuEIMZ1tDyZ9jKdVtgFa/lt 44tQ1b9OAeVTWNKngxG1LxoMgZMYztWxRthDKfxoHheF0cculzeOVNPlMWYWo1ebPGVZ JlO1iqw8FkEoVA/lNUOk+UjA0umrmyZo59wDW6y5Pju8uOFMf0wjumqdoNHFicntFkYO 2WCDkG0NbXUgBv1SFo095PrFkrxsu8HXzragrUYu4/ON4l1JQzcbSSrKkxNQkHhlCLVT XUdA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=kCB8Rmh/; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s190si9656611pgc.510.2018.03.06.02.23.53; Tue, 06 Mar 2018 02:23:53 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=kCB8Rmh/; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753551AbeCFKXt (ORCPT + 28 others); Tue, 6 Mar 2018 05:23:49 -0500 Received: from mail-it0-f65.google.com ([209.85.214.65]:39764 "EHLO mail-it0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753535AbeCFKXo (ORCPT ); Tue, 6 Mar 2018 05:23:44 -0500 Received: by mail-it0-f65.google.com with SMTP id l187so14116078ith.4 for ; Tue, 06 Mar 2018 02:23:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=i5UJ4ulVH6tjQa8IviOO8w+SjdcTE6o9qLnrRU5tZt4=; b=kCB8Rmh/0eJG6pDHlWLNrMtLfZxF6RUQWMUSdvC/osNO5j6JtIaOS7BAD25zx1sdfT GWuMdKwsDfJHv51d4VZk524YLFTwpWNTcCr6lZpcWl4Xe0oE5v0kf7A+56Uu3ANnsV6s 1N2JBZRC95PntR67YN6Go018+8rUe9Tsp/xJM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=i5UJ4ulVH6tjQa8IviOO8w+SjdcTE6o9qLnrRU5tZt4=; b=cWHl24/jAS6TsrICdanmarmv3zV47x8n+Q6+Y4BjHzb6YvjetjSAn5jQB2mEAB5A/N NokI1kO/pN8kAWiaKwpUzF4My249n+PeCfS1/CCCMx32+yckjJi8qdr7xoaEfxYmSH7D PEVkJ+/D/Nnq+Hua5gkZEIBQHXO3qqimir1VrHaRGOv1bvlzFdwOjPaUkifAmmCETQXc h4GCAW+x64w21fsevVA1pDYGYORew8sclncZMt4khgd1yBxrVMeANSSnrZpcBqay7oIB a3XUw9TSv8DdMXYSxjFY88WbODmyewRbp6HofigiY89oQhB2pcIt1vDX+usPWUi6cDfn mCxg== X-Gm-Message-State: AElRT7HRuUBO5hf09HlfZfCdXY4H3HN5W+5LVWsLe1O5hcXzoyxhs8sq Q19dimIik27g3s5SXK8lUBF5PA== X-Received: by 10.36.212.3 with SMTP id x3mr14910509itg.22.1520331824193; Tue, 06 Mar 2018 02:23:44 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id c8sm6584326ita.18.2018.03.06.02.23.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Mar 2018 02:23:43 -0800 (PST) From: AKASHI Takahiro To: dyoung@redhat.com, vgoyal@redhat.com, bhe@redhat.com, mpe@ellerman.id.au, bauerman@linux.vnet.ibm.com, prudo@linux.vnet.ibm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v2 7/7] kexec_file, x86: move re-factored code to generic side Date: Tue, 6 Mar 2018 19:23:03 +0900 Message-Id: <20180306102303.9063-8-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180306102303.9063-1-takahiro.akashi@linaro.org> References: <20180306102303.9063-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In the previous patches, commonly-used routines, exclude_mem_range() and prepare_elf64_headers(), were carved out. Now place them in kexec common code. A prefix "crash_" is given to each of their names to avoid possible name collisions. Signed-off-by: AKASHI Takahiro Cc: Dave Young Cc: Vivek Goyal Cc: Baoquan He --- arch/x86/kernel/crash.c | 195 ++---------------------------------------------- include/linux/kexec.h | 19 +++++ kernel/kexec_file.c | 175 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 201 insertions(+), 188 deletions(-) -- 2.16.2 diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 24de3f13f40c..a52671487ff2 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -38,19 +38,6 @@ #include #include -/* Alignment required for elf header segment */ -#define ELF_CORE_HEADER_ALIGN 4096 - -struct crash_mem_range { - u64 start, end; -}; - -struct crash_mem { - unsigned int max_nr_ranges; - unsigned int nr_ranges; - struct crash_mem_range ranges[0]; -}; - /* Used while preparing memory map entries for second kernel */ struct crash_memmap_data { struct boot_params *params; @@ -226,77 +213,6 @@ static struct crash_mem *fill_up_crash_elf_data(void) return cmem; } -static int exclude_mem_range(struct crash_mem *mem, - unsigned long long mstart, unsigned long long mend) -{ - int i, j; - unsigned long long start, end; - struct crash_mem_range temp_range = {0, 0}; - - for (i = 0; i < mem->nr_ranges; i++) { - start = mem->ranges[i].start; - end = mem->ranges[i].end; - - if (mstart > end || mend < start) - continue; - - /* Truncate any area outside of range */ - if (mstart < start) - mstart = start; - if (mend > end) - mend = end; - - /* Found completely overlapping range */ - if (mstart == start && mend == end) { - mem->ranges[i].start = 0; - mem->ranges[i].end = 0; - if (i < mem->nr_ranges - 1) { - /* Shift rest of the ranges to left */ - for (j = i; j < mem->nr_ranges - 1; j++) { - mem->ranges[j].start = - mem->ranges[j+1].start; - mem->ranges[j].end = - mem->ranges[j+1].end; - } - } - mem->nr_ranges--; - return 0; - } - - if (mstart > start && mend < end) { - /* Split original range */ - mem->ranges[i].end = mstart - 1; - temp_range.start = mend + 1; - temp_range.end = end; - } else if (mstart != start) - mem->ranges[i].end = mstart - 1; - else - mem->ranges[i].start = mend + 1; - break; - } - - /* If a split happend, add the split to array */ - if (!temp_range.end) - return 0; - - /* Split happened */ - if (i == mem->max_nr_ranges - 1) - return -ENOMEM; - - /* Location where new range should go */ - j = i + 1; - if (j < mem->nr_ranges) { - /* Move over all ranges one slot towards the end */ - for (i = mem->nr_ranges - 1; i >= j; i--) - mem->ranges[i + 1] = mem->ranges[i]; - } - - mem->ranges[j].start = temp_range.start; - mem->ranges[j].end = temp_range.end; - mem->nr_ranges++; - return 0; -} - /* * Look for any unwanted ranges between mstart, mend and remove them. This * might lead to split and split ranges are put in cmem->ranges[] array @@ -306,12 +222,13 @@ static int elf_header_exclude_ranges(struct crash_mem *cmem) int ret = 0; /* Exclude crashkernel region */ - ret = exclude_mem_range(cmem, crashk_res.start, crashk_res.end); + ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end); if (ret) return ret; if (crashk_low_res.end) { - ret = exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end); + ret = crash_exclude_mem_range(cmem, crashk_low_res.start, + crashk_low_res.end); if (ret) return ret; } @@ -330,105 +247,6 @@ static int prepare_elf64_ram_headers_callback(struct resource *res, void *arg) return 0; } -static int prepare_elf64_headers(struct crash_mem *cmem, bool kernel_map, - void **addr, unsigned long *sz) -{ - Elf64_Ehdr *ehdr; - Elf64_Phdr *phdr; - unsigned long nr_cpus = num_possible_cpus(), nr_phdr, elf_sz; - unsigned char *buf; - unsigned int cpu, i; - unsigned long long notes_addr; - unsigned long mstart, mend; - - /* extra phdr for vmcoreinfo elf note */ - nr_phdr = nr_cpus + 1; - nr_phdr += cmem->nr_ranges; - - /* - * kexec-tools creates an extra PT_LOAD phdr for kernel text mapping - * area on x86_64 (ffffffff80000000 - ffffffffa0000000). - * I think this is required by tools like gdb. So same physical - * memory will be mapped in two elf headers. One will contain kernel - * text virtual addresses and other will have __va(physical) addresses. - */ - - nr_phdr++; - elf_sz = sizeof(Elf64_Ehdr) + nr_phdr * sizeof(Elf64_Phdr); - elf_sz = ALIGN(elf_sz, ELF_CORE_HEADER_ALIGN); - - buf = vzalloc(elf_sz); - if (!buf) - return -ENOMEM; - - ehdr = (Elf64_Ehdr *)buf; - phdr = (Elf64_Phdr *)(ehdr + 1); - memcpy(ehdr->e_ident, ELFMAG, SELFMAG); - ehdr->e_ident[EI_CLASS] = ELFCLASS64; - ehdr->e_ident[EI_DATA] = ELFDATA2LSB; - ehdr->e_ident[EI_VERSION] = EV_CURRENT; - ehdr->e_ident[EI_OSABI] = ELF_OSABI; - memset(ehdr->e_ident + EI_PAD, 0, EI_NIDENT - EI_PAD); - ehdr->e_type = ET_CORE; - ehdr->e_machine = ELF_ARCH; - ehdr->e_version = EV_CURRENT; - ehdr->e_phoff = sizeof(Elf64_Ehdr); - ehdr->e_ehsize = sizeof(Elf64_Ehdr); - ehdr->e_phentsize = sizeof(Elf64_Phdr); - - /* Prepare one phdr of type PT_NOTE for each present cpu */ - for_each_present_cpu(cpu) { - phdr->p_type = PT_NOTE; - notes_addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpu)); - phdr->p_offset = phdr->p_paddr = notes_addr; - phdr->p_filesz = phdr->p_memsz = sizeof(note_buf_t); - (ehdr->e_phnum)++; - phdr++; - } - - /* Prepare one PT_NOTE header for vmcoreinfo */ - phdr->p_type = PT_NOTE; - phdr->p_offset = phdr->p_paddr = paddr_vmcoreinfo_note(); - phdr->p_filesz = phdr->p_memsz = VMCOREINFO_NOTE_SIZE; - (ehdr->e_phnum)++; - phdr++; - - /* Prepare PT_LOAD type program header for kernel text region */ - if (kernel_map) { - phdr->p_type = PT_LOAD; - phdr->p_flags = PF_R|PF_W|PF_X; - phdr->p_vaddr = (Elf64_Addr)_text; - phdr->p_filesz = phdr->p_memsz = _end - _text; - phdr->p_offset = phdr->p_paddr = __pa_symbol(_text); - ehdr->e_phnum++; - phdr++; - } - - /* Go through all the ranges in cmem->ranges[] and prepare phdr */ - for (i = 0; i < cmem->nr_ranges; i++) { - mstart = cmem->ranges[i].start; - mend = cmem->ranges[i].end; - - phdr->p_type = PT_LOAD; - phdr->p_flags = PF_R|PF_W|PF_X; - phdr->p_offset = mstart; - - phdr->p_paddr = mstart; - phdr->p_vaddr = (unsigned long long) __va(mstart); - phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; - phdr->p_align = 0; - ehdr->e_phnum++; - phdr++; - pr_debug("Crash PT_LOAD elf header. phdr=%p vaddr=0x%llx, paddr=0x%llx, sz=0x%llx e_phnum=%d p_offset=0x%llx\n", - phdr, phdr->p_vaddr, phdr->p_paddr, phdr->p_filesz, - ehdr->e_phnum, phdr->p_offset); - } - - *addr = buf; - *sz = elf_sz; - return 0; -} - /* Prepare elf headers. Return addr and size */ static int prepare_elf_headers(struct kimage *image, void **addr, unsigned long *sz) @@ -453,7 +271,8 @@ static int prepare_elf_headers(struct kimage *image, void **addr, goto out; /* By default prepare 64bit headers */ - ret = prepare_elf64_headers(cmem, IS_ENABLED(CONFIG_X86_64), addr, sz); + ret = crash_prepare_elf64_headers(cmem, + IS_ENABLED(CONFIG_X86_64), addr, sz); if (ret) goto out; @@ -517,14 +336,14 @@ static int memmap_exclude_ranges(struct kimage *image, struct crash_mem *cmem, /* Exclude Backup region */ start = image->arch.backup_load_addr; end = start + image->arch.backup_src_sz - 1; - ret = exclude_mem_range(cmem, start, end); + ret = crash_exclude_mem_range(cmem, start, end); if (ret) return ret; /* Exclude elf header region */ start = image->arch.elf_load_addr; end = start + image->arch.elf_headers_sz - 1; - return exclude_mem_range(cmem, start, end); + return crash_exclude_mem_range(cmem, start, end); } /* Prepare memory map for crash dump kernel */ diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 4ed18cc718fc..85609221cd80 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -168,6 +168,25 @@ int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf, int (*func)(struct resource *, void *)); extern int kexec_add_buffer(struct kexec_buf *kbuf); int kexec_locate_mem_hole(struct kexec_buf *kbuf); + +/* Alignment required for elf header segment */ +#define ELF_CORE_HEADER_ALIGN 4096 + +struct crash_mem_range { + u64 start, end; +}; + +struct crash_mem { + unsigned int max_nr_ranges; + unsigned int nr_ranges; + struct crash_mem_range ranges[0]; +}; + +extern int crash_exclude_mem_range(struct crash_mem *mem, + unsigned long long mstart, + unsigned long long mend); +extern int crash_prepare_elf64_headers(struct crash_mem *mem, int kernel_map, + void **addr, unsigned long *sz); #endif /* CONFIG_KEXEC_FILE */ struct kimage { diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 6a62c5ef8a07..7d38eb578116 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -22,6 +22,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include "kexec_internal.h" @@ -1079,3 +1084,173 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name, return 0; } #endif /* CONFIG_ARCH_HAS_KEXEC_PURGATORY */ + +int crash_exclude_mem_range(struct crash_mem *mem, + unsigned long long mstart, unsigned long long mend) +{ + int i, j; + unsigned long long start, end; + struct crash_mem_range temp_range = {0, 0}; + + for (i = 0; i < mem->nr_ranges; i++) { + start = mem->ranges[i].start; + end = mem->ranges[i].end; + + if (mstart > end || mend < start) + continue; + + /* Truncate any area outside of range */ + if (mstart < start) + mstart = start; + if (mend > end) + mend = end; + + /* Found completely overlapping range */ + if (mstart == start && mend == end) { + mem->ranges[i].start = 0; + mem->ranges[i].end = 0; + if (i < mem->nr_ranges - 1) { + /* Shift rest of the ranges to left */ + for (j = i; j < mem->nr_ranges - 1; j++) { + mem->ranges[j].start = + mem->ranges[j+1].start; + mem->ranges[j].end = + mem->ranges[j+1].end; + } + } + mem->nr_ranges--; + return 0; + } + + if (mstart > start && mend < end) { + /* Split original range */ + mem->ranges[i].end = mstart - 1; + temp_range.start = mend + 1; + temp_range.end = end; + } else if (mstart != start) + mem->ranges[i].end = mstart - 1; + else + mem->ranges[i].start = mend + 1; + break; + } + + /* If a split happened, add the split to array */ + if (!temp_range.end) + return 0; + + /* Split happened */ + if (i == mem->max_nr_ranges - 1) + return -ENOMEM; + + /* Location where new range should go */ + j = i + 1; + if (j < mem->nr_ranges) { + /* Move over all ranges one slot towards the end */ + for (i = mem->nr_ranges - 1; i >= j; i--) + mem->ranges[i + 1] = mem->ranges[i]; + } + + mem->ranges[j].start = temp_range.start; + mem->ranges[j].end = temp_range.end; + mem->nr_ranges++; + return 0; +} + +int crash_prepare_elf64_headers(struct crash_mem *mem, int kernel_map, + void **addr, unsigned long *sz) +{ + Elf64_Ehdr *ehdr; + Elf64_Phdr *phdr; + unsigned long nr_cpus = num_possible_cpus(), nr_phdr, elf_sz; + unsigned char *buf; + unsigned int cpu, i; + unsigned long long notes_addr; + unsigned long mstart, mend; + + /* extra phdr for vmcoreinfo elf note */ + nr_phdr = nr_cpus + 1; + nr_phdr += mem->nr_ranges; + + /* + * kexec-tools creates an extra PT_LOAD phdr for kernel text mapping + * area (for example, ffffffff80000000 - ffffffffa0000000 on x86_64). + * I think this is required by tools like gdb. So same physical + * memory will be mapped in two elf headers. One will contain kernel + * text virtual addresses and other will have __va(physical) addresses. + */ + + nr_phdr++; + elf_sz = sizeof(Elf64_Ehdr) + nr_phdr * sizeof(Elf64_Phdr); + elf_sz = ALIGN(elf_sz, ELF_CORE_HEADER_ALIGN); + + buf = vzalloc(elf_sz); + if (!buf) + return -ENOMEM; + + ehdr = (Elf64_Ehdr *)buf; + phdr = (Elf64_Phdr *)(ehdr + 1); + memcpy(ehdr->e_ident, ELFMAG, SELFMAG); + ehdr->e_ident[EI_CLASS] = ELFCLASS64; + ehdr->e_ident[EI_DATA] = ELFDATA2LSB; + ehdr->e_ident[EI_VERSION] = EV_CURRENT; + ehdr->e_ident[EI_OSABI] = ELF_OSABI; + memset(ehdr->e_ident + EI_PAD, 0, EI_NIDENT - EI_PAD); + ehdr->e_type = ET_CORE; + ehdr->e_machine = ELF_ARCH; + ehdr->e_version = EV_CURRENT; + ehdr->e_phoff = sizeof(Elf64_Ehdr); + ehdr->e_ehsize = sizeof(Elf64_Ehdr); + ehdr->e_phentsize = sizeof(Elf64_Phdr); + + /* Prepare one phdr of type PT_NOTE for each present cpu */ + for_each_present_cpu(cpu) { + phdr->p_type = PT_NOTE; + notes_addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpu)); + phdr->p_offset = phdr->p_paddr = notes_addr; + phdr->p_filesz = phdr->p_memsz = sizeof(note_buf_t); + (ehdr->e_phnum)++; + phdr++; + } + + /* Prepare one PT_NOTE header for vmcoreinfo */ + phdr->p_type = PT_NOTE; + phdr->p_offset = phdr->p_paddr = paddr_vmcoreinfo_note(); + phdr->p_filesz = phdr->p_memsz = VMCOREINFO_NOTE_SIZE; + (ehdr->e_phnum)++; + phdr++; + + /* Prepare PT_LOAD type program header for kernel text region */ + if (kernel_map) { + phdr->p_type = PT_LOAD; + phdr->p_flags = PF_R|PF_W|PF_X; + phdr->p_vaddr = (Elf64_Addr)_text; + phdr->p_filesz = phdr->p_memsz = _end - _text; + phdr->p_offset = phdr->p_paddr = __pa_symbol(_text); + ehdr->e_phnum++; + phdr++; + } + + /* Go through all the ranges in mem->ranges[] and prepare phdr */ + for (i = 0; i < mem->nr_ranges; i++) { + mstart = mem->ranges[i].start; + mend = mem->ranges[i].end; + + phdr->p_type = PT_LOAD; + phdr->p_flags = PF_R|PF_W|PF_X; + phdr->p_offset = mstart; + + phdr->p_paddr = mstart; + phdr->p_vaddr = (unsigned long long) __va(mstart); + phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; + phdr->p_align = 0; + ehdr->e_phnum++; + phdr++; + pr_debug("Crash PT_LOAD elf header. phdr=%p vaddr=0x%llx, paddr=0x%llx, sz=0x%llx e_phnum=%d p_offset=0x%llx\n", + phdr, phdr->p_vaddr, phdr->p_paddr, phdr->p_filesz, + ehdr->e_phnum, phdr->p_offset); + } + + *addr = buf; + *sz = elf_sz; + return 0; +}