From patchwork Tue Feb 27 04:48:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 129733 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp972617lja; Mon, 26 Feb 2018 20:48:52 -0800 (PST) X-Google-Smtp-Source: AH8x224M1ePY+cCIVIYY1DwCwqG3HqqHo75GQEQLkRI5zKwcdm38a4+Aw3hUrgi31SfS3ZK7CSz9 X-Received: by 10.98.212.80 with SMTP id u16mr12936477pfl.58.1519706932000; Mon, 26 Feb 2018 20:48:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519706931; cv=none; d=google.com; s=arc-20160816; b=pnv4QLE4N9/bD7PwEb5tcYRFK8nk4D8a/6COcthk6W/Zy7GK20IbkkS0fcygmCs/Ug fxJnbytiip/5uq51q0ZZv7Rh0QsAO52i7UrdDN3QMC7kD7umyGU8i/vFsNdXCf8dadVy 4mBDXoX7ge8a6z5gHtahatnNC3RTj3JBAvYNZKnMrdvcy2g/FFRhGRm+LS6zA4TAWJvN dfq1nOa/fReFkNEjXyIemXGBQPvV6cOxn8uyw3q4j28UKFZrNImve/RmCC2mLwKL8aki lG9RriV9xMRdBEerLMrMD6hFJfEcQ/9TOPe41ryFEdzkbRYpKsrZshlis4bCPwBC5gXh 5Piw== 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=8KQUdI4Z9ingM2mimjl+JsuTI/1wm7KWpRgsWzyKrbg=; b=Y1C54BbXk7WwQQXLDThD8/Eya8MK55te9qDekcWAgq3YihL3idWwxDTtB/Wji9kmrV SOJkPOSAIGoelC0mVW3FSnVG6phRe70isDsqIQq0MTTd59Fz3bOj8GgYpQmUayoiGFsC xAnTOVajWL9Q1Dp4Yf3X9Z9IjFAsR/trS0MPnNG+N+kGK7CFygpE41szhcPQ+UETOw+X S/m85/MPef8aF+KQqXCyfK0OuP5Z/7CloyrkfRZALUX16oS+IrcUE5CvaW6R0hlhkhHW ETB6d1LLr9FsuBRWYoKIwXAo5KHDu60YK9AhbLqYl6SNElZwGw+V/xC9CjIH6gkeVYI0 ZwJg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jgBwCJeY; 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 t15si2069346pgu.62.2018.02.26.20.48.51; Mon, 26 Feb 2018 20:48:51 -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=jgBwCJeY; 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 S1752015AbeB0Ess (ORCPT + 28 others); Mon, 26 Feb 2018 23:48:48 -0500 Received: from mail-pf0-f196.google.com ([209.85.192.196]:43798 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751819AbeB0Esq (ORCPT ); Mon, 26 Feb 2018 23:48:46 -0500 Received: by mail-pf0-f196.google.com with SMTP id z14so7506145pfe.10 for ; Mon, 26 Feb 2018 20:48:46 -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=8KQUdI4Z9ingM2mimjl+JsuTI/1wm7KWpRgsWzyKrbg=; b=jgBwCJeY2mSzDywcuaMPQprXVub/cu0YURgSK6wiHbu8qF2GmTmYb8TlOYqJ+nGSxO impWhW483jKjQEhF0HifkTRq3LQo5dvJ/fO+7ZtuQ/gzf68bk7W/K3p1Oha5P+2W3xuw H69+3hTIKrKL/RjS2QZlSLIRn8crNUkPU4CTQ= 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=8KQUdI4Z9ingM2mimjl+JsuTI/1wm7KWpRgsWzyKrbg=; b=Dpcej8sSOh24prtL+6L2YJPzPXnfskZylOubkDuo2gh2dbfo/hC7LqdP0jCwcfzw3c mk9j5TwfHylPgqVY70Jc4GhA1Q5Zt8T+odQBlf985oJebLlJim6Abn34ycISMObG0GGd tyiVDTOxHs1JGlC1Zc65vkHk4ug4IUuMDEYR9PJxRaZvT082/2MqjhuqAH+Gft160RkJ juceJlfn2UMhYgX1Vq6B0C+Hv9RApVOYdj0PPVd3j+YYOVxYlczIF+tk6BJLTNS2kjSD y9Xp9FT8ndRyYCOsp6AGrqbYqaO25f2BcwLYghLAM2taeINNRWmMJd3NBmkc4cn8PI59 Ah5Q== X-Gm-Message-State: APf1xPChcT0xsw49rsIfA/HnMyqnYBQ0b4i4hJ2Vzh35zXAb0PkbW3gy Kj5048a4Tb4g6fwGm5Yfu01LlA== X-Received: by 10.99.183.68 with SMTP id w4mr7299704pgt.113.1519706926274; Mon, 26 Feb 2018 20:48:46 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id i11sm15983332pgq.34.2018.02.26.20.48.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Feb 2018 20:48:45 -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 1/7] kexec_file: make an use of purgatory optional Date: Tue, 27 Feb 2018 13:48:08 +0900 Message-Id: <20180227044814.24808-2-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180227044814.24808-1-takahiro.akashi@linaro.org> References: <20180227044814.24808-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 | 6 ++++++ 3 files changed, 12 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..990adae52151 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -26,7 +26,11 @@ #include #include "kexec_internal.h" +#ifdef CONFIG_ARCH_HAS_KEXEC_PURGATORY static int kexec_calculate_store_digests(struct kimage *image); +#else +static int kexec_calculate_store_digests(struct kimage *image) { return 0; }; +#endif /* Architectures can provide this probe function */ int __weak arch_kexec_kernel_image_probe(struct kimage *image, void *buf, @@ -520,6 +524,7 @@ int kexec_add_buffer(struct kexec_buf *kbuf) return 0; } +#ifdef CONFIG_ARCH_HAS_KEXEC_PURGATORY /* Calculate and store the digest of segments */ static int kexec_calculate_store_digests(struct kimage *image) { @@ -1022,3 +1027,4 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name, return 0; } +#endif /* CONFIG_ARCH_HAS_KEXEC_PURGATORY */ From patchwork Tue Feb 27 04:48:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 129734 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp972703lja; Mon, 26 Feb 2018 20:49:02 -0800 (PST) X-Google-Smtp-Source: AH8x225gx8xtJU/jpgvzqDtp/9NjaCXC58/E5MOlOsGPHzGECJErMFcK+OsHbQ9Omjo4k0uXSCje X-Received: by 2002:a17:902:3a1:: with SMTP id d30-v6mr12762635pld.409.1519706941858; Mon, 26 Feb 2018 20:49:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519706941; cv=none; d=google.com; s=arc-20160816; b=s6yXGMvwqN3YmlUuvqn80RVh3R4jKIFUvNX5aZvssvWq7OaVgepLC5c2DZ/SNQA6WH sHWJ/4Vge8csm9tXZRHfbvXmHZ5eh+l8Wj6dfBXENRGzAdiPlvGHKD2QwDX9HXGF+FIO RSkbZDi/TqzEchxBtdAJQmbDy4+BWxHQtgrNsokBpR2n52q8niryaNFPuuJfep7bolmk /d3Eb3sCBBOAXgRm4jZHj4/Dn6IFzjQu7K7e5YLAjI5Gjo4pjsshMn9aCyZJvcc8mh5s krddzlxSeIXA0Hm8pOTeIF3WKHP6LKOvEj0hbUCDwvcJrxstZWxaVU95/3JtuD2YlteC Y6Fw== 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=E4nxmy+CqVKFxED5M5q4vZosQj4XwDfOnMA0P/+5qaw=; b=TRzwrvB5JWlFYYzF3YzcerNPmUwEkJHXLMI1NmDqF2v0fLnb6nHYJOT7idUhc+zft2 3r+A5ksDEQP3ab6UwiJI3B25v2XvZpJumqzCaWASzKrfR0Xp4z39uG5+KLql+TCfkCyC EiTIdkHgHc8SsW+3ylkc7eZWTcKOKBiPMlL0xKs12LUpOaaMibzluSzYZ7PJGPGRD9nj EBrs3blgEAg1tpMN9lZjEMl9JfWH0RcgmpyEAlWnfm9VqC//g3v09fSqOV8LMPKGCA5F tT9L9xxGGJ795CnRQF+EB+/1qaGU9kvU+Di1lqB3CuXgtTQBLuahQ0vbxTyehjjszZfj xD6w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZyJR4BUx; 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 t15si2069346pgu.62.2018.02.26.20.49.01; Mon, 26 Feb 2018 20:49:01 -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=ZyJR4BUx; 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 S1752064AbeB0Es5 (ORCPT + 28 others); Mon, 26 Feb 2018 23:48:57 -0500 Received: from mail-pl0-f65.google.com ([209.85.160.65]:46280 "EHLO mail-pl0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751930AbeB0Esx (ORCPT ); Mon, 26 Feb 2018 23:48:53 -0500 Received: by mail-pl0-f65.google.com with SMTP id y8-v6so255376pll.13 for ; Mon, 26 Feb 2018 20:48:52 -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=E4nxmy+CqVKFxED5M5q4vZosQj4XwDfOnMA0P/+5qaw=; b=ZyJR4BUxypWFkZ1cJVXxccbKerpQdpMrdhPsoQqAQM0pZLPM8Dtwoeu3dh6DDvjbYB nlbtrqEeTVhdDxrCRk5dozBEW9KSBMSXx0D5rVNLdj7N7jLjLWxgd2x8FrpvCUdjVYdJ Icml+f56KVuKtjNXp4dQ9LdQ1NY2euusSczk4= 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=E4nxmy+CqVKFxED5M5q4vZosQj4XwDfOnMA0P/+5qaw=; b=C2DAzzLQ70tHJyb5QC/yWT9sGKex2SL0iKayYBjMAlpRPqC57FwC03K2Lo/zQcRxKs J3YvtnAfNfBDadpP1gtCxpjS6h5f0E13uff1yQ13x13A95+5vsv3lPwTaRoQnj0dHMmS uEMGDGbuEQ8sF5WwApSil2GeFuZqaK5TMUxEA6wXknlFMN8tzfG+OwYyB9k1b9P2A66m QDdIB3M6TMOdTWdq7KyiQBOYXBNzd2Hl6SPId+LR04eTIiJ5LqudKgjepE25vy5cR+iE 0NjC4KW/HL7Z3TT4Lln8ciiS2rK7mLYj01jajZVlg83ENMScotVtjHx3qYP70lIHVERx cIkQ== X-Gm-Message-State: APf1xPBKuFh0hWrBfZtgW5/OlyGyzBygNr9Oo4iRKDvgiDbS6x9ZWR7G x0keirlmlbyQi5EK+fcWCjpWhH6/R9w= X-Received: by 2002:a17:902:43e4:: with SMTP id j91-v6mr12749297pld.153.1519706932529; Mon, 26 Feb 2018 20:48:52 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id 5sm7059367pfh.133.2018.02.26.20.48.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Feb 2018 20:48:51 -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 2/7] kexec_file, x86, powerpc: factor out kexec_file_ops functions Date: Tue, 27 Feb 2018 13:48:09 +0900 Message-Id: <20180227044814.24808-3-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180227044814.24808-1-takahiro.akashi@linaro.org> References: <20180227044814.24808-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 | 17 +++++---- kernel/kexec_file.c | 55 ++++++++++++++++++++++++++--- 8 files changed, 70 insertions(+), 94 deletions(-) -- 2.16.2 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..a27ec647350c 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_kernel_image_probe(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..2e095c3b4537 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -159,6 +159,15 @@ struct kexec_buf { bool top_down; }; +extern const struct kexec_file_ops * const kexec_file_loaders[]; + +int _kexec_kernel_image_probe(struct kimage *image, void *buf, + unsigned long buf_len); +void *_kexec_kernel_image_load(struct kimage *image); +int _kimage_file_post_load_cleanup(struct kimage *image); +int _kexec_kernel_verify_sig(struct kimage *image, void *buf, + unsigned long buf_len); + int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf, int (*func)(struct resource *, void *)); extern int kexec_add_buffer(struct kexec_buf *kbuf); @@ -209,7 +218,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 +286,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 990adae52151..60bdfc1104ff 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -32,28 +32,75 @@ static int kexec_calculate_store_digests(struct kimage *image); static int kexec_calculate_store_digests(struct kimage *image) { return 0; }; #endif +int _kexec_kernel_image_probe(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_kernel_image_probe(image, buf, buf_len); +} + +void *_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); } void * __weak arch_kexec_kernel_image_load(struct kimage *image) { - return ERR_PTR(-ENOEXEC); + return _kexec_kernel_image_load(image); +} + +int _kimage_file_post_load_cleanup(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 _kimage_file_post_load_cleanup(image); } #ifdef CONFIG_KEXEC_VERIFY_SIG +int _kexec_kernel_verify_sig(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_kernel_verify_sig(image, buf, buf_len); } #endif From patchwork Tue Feb 27 04:48:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 129735 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp972779lja; Mon, 26 Feb 2018 20:49:10 -0800 (PST) X-Google-Smtp-Source: AH8x226FxTzDH0FadIBQEng/LxNMY9KFaHzCDlaO5yPsJTj2XpIwRQlp1a1WVGthL6ISME/1AKAc X-Received: by 10.99.140.85 with SMTP id q21mr10087268pgn.51.1519706949873; Mon, 26 Feb 2018 20:49:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519706949; cv=none; d=google.com; s=arc-20160816; b=CPyyNQ6uhWF6YT8XBmh4d1wWINwjVpHQ+Xfl4VQIDV4+X/CbJRVfEvhbfI92cof2TH sAZFIJK+MSXj7ErXJLpW7ICBDjBWzV9EWxDk0qpK82DzdTfVJuo4s/53iHb/zh651ZLP 7+fASLRuIid2XpW+73Xt/RcJOr/khxWKGrd0axNohRlDNs8KfO2hSSlCfBfOw1cHAawf cwDvdP1X8vxYiFwKe0+mM/jp7Alqa+9b17II84dgCkcnb6RS+wWyEkFq7iCHuwI9l5/U wmHOiPAWDdIFgSNw9Tdl1dRmnJA0dsJ8lMlKd3m5OBy90ZDJoA65HVD4kOUXog5YbWia ryyA== 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=c1K0dIcZ0fwOuhAjy77oGzeKlVWJDPCo1SKgcII7qh+t5h9DkmjYFX+Tj8va3pvvm3 LIA+g+YR3+1H5TZdGmjcWFD8873wAl6gfB4MqwhFhBF0PM49YQjlJWBvmkbcGvwre+NV RC+HPlFBobW07hVsMgJ1HGK//HVmkULqrlv78/PRd9h4gXKIRWuUgvL8HjwR9zTfzXvL oR0Em6cVCIrm+88qUqM+P9OoYFMagdJSicYtcXIZht0V8eJ0SzJiwN6bNVjRu9ciydXg 21w7eHw0vKRWhnJbhxzZH0NQ9ztWkiK8gSmGZmFbi8dP257L7IQ7lfRSzkSPvUDYQCMi +B/w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FoISrgfb; 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 t15si2069346pgu.62.2018.02.26.20.49.09; Mon, 26 Feb 2018 20:49:09 -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=FoISrgfb; 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 S1752093AbeB0EtD (ORCPT + 28 others); Mon, 26 Feb 2018 23:49:03 -0500 Received: from mail-pf0-f193.google.com ([209.85.192.193]:35774 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752030AbeB0Es4 (ORCPT ); Mon, 26 Feb 2018 23:48:56 -0500 Received: by mail-pf0-f193.google.com with SMTP id y186so6824872pfb.2 for ; Mon, 26 Feb 2018 20:48:56 -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=FoISrgfb5W1fxFzdgdME7XeS+Y52e+qOFlx918CRCeM6aKxHEXxq/YQwH6TMj/2e6S ZC9otZaQtAP7/KdZ/ftYfhO/u4UOury1JJJF63E6XNU+rycmgbfTnRM4wXO5av3LRmqG Jz+um81QWPqw5sZLiLVtGrjsGz/5GDCTPP+Tk= 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=Wop7kVDAyBi+oI911R4gmefZiw2RO1ia57b8/v2pMhJEXTA6EzTrcUUJxHEEfEqPdt 15VtfEXe5zd2gcCA4WKaka5IIUErnyfX9MeKWfgzI/l5lNLnAUpm1ccK3TZukxjMQsZD knwG874CRMxkptJDdWeTTYt1XSGZv2Cd9+NWm3+PEQVFo4i22X4BCFdMTjGPSQ6NzQ0c n32tj/A+UXRUqbpUsDGYa1pyzkVMoPG9w1jxepHF2yWb00JogDl/36vb4tOCLvnPhy6q ne5kXYXQlnbfbStO4DG4dOVLc59ZJmWYnUHUXJwG8nu5yn+T/Q0wzg7L9MwHGloYEdSj nxqg== X-Gm-Message-State: APf1xPBCgVqs+qETSpEt74zwVQeu9nQ+UbuRa9ib4sjT6h30T96ryPhy HV4YXPXLVlnQkRa+AaRg/Tn5Aw== X-Received: by 10.99.120.193 with SMTP id t184mr10547429pgc.348.1519706936039; Mon, 26 Feb 2018 20:48:56 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id u27sm16178570pfk.172.2018.02.26.20.48.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Feb 2018 20:48:55 -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 3/7] x86: kexec_file: purge system-ram walking from prepare_elf64_headers() Date: Tue, 27 Feb 2018 13:48:10 +0900 Message-Id: <20180227044814.24808-4-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180227044814.24808-1-takahiro.akashi@linaro.org> References: <20180227044814.24808-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 Feb 27 04:48:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 129739 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp973332lja; Mon, 26 Feb 2018 20:49:58 -0800 (PST) X-Google-Smtp-Source: AH8x225stVRhOlPeTlPbuus2MpbxsXDYVDYQANDL2AYEZWkozYMuuOMfeFNWEZHTEWRpOpvsirfX X-Received: by 2002:a17:902:5a88:: with SMTP id r8-v6mr13443076pli.426.1519706998301; Mon, 26 Feb 2018 20:49:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519706998; cv=none; d=google.com; s=arc-20160816; b=I1sElfHuO9jhiFr7M1CrcROFo6onGgF79ULVv1rPzRami0C7wnpWdmMQaD5XltvXmk VQ8zOEvqzJsziR+RiIHr7LZzoE7LSE0QOCz6+z8MzDkn/NsvvP6BN9IAtZt8H1h70XS2 s6jFVJCa5yQp+wg+6+KVnf2s6hRfYoMdUw7IqOApWYf7wttSM1USnNcDPaoLTtmCI3l3 zAC9ExzIAaN4iwAxqEgRnBH8GlQNpaTRaQ/Sb4+i2zre/MXqB/W8/DnB3S0FpZp78z2Z Q/QPrTGKxCOsXMiKkzMxIjrqHx7U/DvyuxarmuJzmhq38EquYJITz/weidRKDsqVeYJg IwYg== 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=QvzF2gs9p77aZLCB3cMbh1eerON3Jw+ujHfeF/3NmMU=; b=dmx+Zaiy4S0OKJbU1U5YXWD9W21xpPaXPOUAX3BSw6uhq7pRj+pGQ9Nv/Df5qQdvOK lPxBBI+hN+IpvGHB0sWnIspq3SZOOpPFKhvtfOwYQ+sKJ/UWUXtP7C7TxixlpwZSJJYG jCW9zTGmeWfZm6BuIkB3rOBZjd8SDnW0dpzPKyJGZynqGU6UVRh5Gs40f85zmNn/v6Y4 PhjOaKAibefenH7iBCbt240pFix7fjOcObDU989WhP2NRIGCGw0iKcs/5o/tVfAJlz8l VOLXPMyh0kcxz9PnmN+vkrXrEBpWZGVeNuCJrsgFR7tZMPRhRT5Sj/YM3gHHu9Bu7wPk RxiQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FrhZKf7N; 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 1-v6si6192007plk.52.2018.02.26.20.49.58; Mon, 26 Feb 2018 20:49:58 -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=FrhZKf7N; 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 S1752164AbeB0Etz (ORCPT + 28 others); Mon, 26 Feb 2018 23:49:55 -0500 Received: from mail-pl0-f65.google.com ([209.85.160.65]:35910 "EHLO mail-pl0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752066AbeB0EtA (ORCPT ); Mon, 26 Feb 2018 23:49:00 -0500 Received: by mail-pl0-f65.google.com with SMTP id v3so10726204plg.3 for ; Mon, 26 Feb 2018 20:49:00 -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=QvzF2gs9p77aZLCB3cMbh1eerON3Jw+ujHfeF/3NmMU=; b=FrhZKf7NOeSkcgT6GEM1x3Pi3MPt5QgstPi3YppXnG2mA4B1JU9t9XWbs3f/L6KCqG 8M6tktyB0O02RvzsWSVw1Ku07ZPh5OTTBxs11CSdDHcm9G1aNKQaUlaUe52G2vVyqaii UejRjV0QnwtcKgAAGhi2e+o1BASILTrJz0QiY= 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=QvzF2gs9p77aZLCB3cMbh1eerON3Jw+ujHfeF/3NmMU=; b=b6mq5bF2KxzPhBMkVnO0Ed/JJbwuYw3LLHAxv59Le3+tx70LoAdsb31NMiN3z+3wBg 08Er95tWVZhYjDxo1RpIp7mJvSwO3UEUvbOWUj888tAouHH4eh6jami8by05x8a1/kvH JBwrnT4WS1I+0cH3BHVH5Y+j7smBvWPgFiIqQ5MfkMakunHR13rhrfvEuGo45zSs4c4y vQHkZF5JteOCxFp+CT9PwjLaYMpui7cX4N6l/V/wh66MiQ95Ir6wbSyPHZvU5QOuXkxt pdTSQVwmgZXgWqYVRfLEruQlAAtMoSPKMPWQLwTA5jjONVmOww+FAGKQTELFJgrmxQXE V8MA== X-Gm-Message-State: APf1xPC5BIjGU8zi4S5do78OgSuO0ihkl2l0+GDvuFkSdBAde7YETUIA pLTArwyHlPkIwvBOIA8nMKad3A== X-Received: by 2002:a17:902:9881:: with SMTP id s1-v6mr12791067plp.286.1519706939942; Mon, 26 Feb 2018 20:48:59 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id o184sm16563895pga.16.2018.02.26.20.48.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Feb 2018 20:48:59 -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 4/7] x86: kexec_file: remove X86_64 dependency from prepare_elf64_headers() Date: Tue, 27 Feb 2018 13:48:11 +0900 Message-Id: <20180227044814.24808-5-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180227044814.24808-1-takahiro.akashi@linaro.org> References: <20180227044814.24808-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 | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) -- 2.16.2 diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 2123fa0efc17..913fd8021f8a 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, int 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,8 @@ 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, + (int)IS_ENABLED(CONFIG_X86_64), addr, sz); if (ret) goto out; From patchwork Tue Feb 27 04:48:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 129736 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp972801lja; Mon, 26 Feb 2018 20:49:11 -0800 (PST) X-Google-Smtp-Source: AH8x2261o+gKkh8NB7lXMF+QHGSbde7qwNA6nHenBjJB4ANi8PYi/d6RDK++eyQCSdswJ7KsIyeO X-Received: by 10.99.96.199 with SMTP id u190mr10305351pgb.231.1519706950984; Mon, 26 Feb 2018 20:49:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519706950; cv=none; d=google.com; s=arc-20160816; b=jmT/sL9hJTehGGb3QiiKkZouYNqbv7xOYhMQvnF4D01M3T6iQVhmNlmmPS5tiV5yIN GFWvm4zRjS9rv7xAYySfKH2DvzmT/9xjUIuHuXIAaQyjrLjJxlIfZntG3xRc2NdCkHIs slWDmbq/O613x/QomihB00RaphQ7PEaXj7oo0uehkRSi2ycoBQrykxAgHNjBLk5poaCr WjwmD513zPsh0hAsRl+t6p+QOaK5JPjmSN2ZVxeqpt4ZdsSVa107TyBVGpO6NN1K6JUi N8X6VnepMrmE20Z0TikjrQIV6uLWn1s7v4Hngc/SgI/tndjKh2zXIAIGO2r74ajPO5ap +hjQ== 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=6J4PL6OwT926Kxkehg8cPsNnwK0orobwxAOR83ZTd0o=; b=Cyvm/1xz16DZoH52mLHYcuDJ02/tN7+1wRSZn/GDhc8/HTPue6Kf+IPy4GTSVqZ9fO XffkJ301vXU/1WgGfPpyMnJchdpAagkLAMnT5u3M5SDP6N02YTiu5BSXuB6zgR5MIaAI pHFy7boTOScclQTcogOqKElwniJCmRAwzl+w3lEhmQWbf0o/Ho7E53P5OOgRm/wqvOKH RZJZjdb50eEctlp9jzBDIB0Rzn3Ymt93mx516xHRyuY6e8WrsBFFmJRHU3CMvp4iyCWP 5Sk3LGW9f7zrlQWNIvvh7VTD0WFV9sQzyaXvnpVxO02RGIvrIEHpkWeg+DD6qrgbViE3 N7qQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=eeA3mZOR; 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 t4si2734104pfh.290.2018.02.26.20.49.10; Mon, 26 Feb 2018 20:49:10 -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=eeA3mZOR; 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 S1752116AbeB0EtH (ORCPT + 28 others); Mon, 26 Feb 2018 23:49:07 -0500 Received: from mail-pf0-f195.google.com ([209.85.192.195]:46455 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752097AbeB0EtE (ORCPT ); Mon, 26 Feb 2018 23:49:04 -0500 Received: by mail-pf0-f195.google.com with SMTP id z10so3170742pfh.13 for ; Mon, 26 Feb 2018 20:49:04 -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=6J4PL6OwT926Kxkehg8cPsNnwK0orobwxAOR83ZTd0o=; b=eeA3mZORYL1kdcznaSkxNsl8SLcBTItGoeSmiPoPqxno6roaKv9f7uMg9NSmqSa13S 6ekRc+JC9sYzCKcVpW6T/e0NcMrULxR+1i7CqYUBF84xOkPP8nw1QdENjnNtKo/Z0fn0 LW9iBt8aF1C+s84yFMBez3MmaA2xhpeyx8qeM= 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=6J4PL6OwT926Kxkehg8cPsNnwK0orobwxAOR83ZTd0o=; b=Mu1i7CjQnuHx3Ab4O8ZD7HqpwdNifD7ReTOGKlGkhKBXrqhiOjtWzgY+WtLzskEAHL 6IZ/w1Eqt52vazKsZWvf+GHgIvrEJml+px0DnPvj26/onBrMKF2rPjNkNFPSi6rjQ5XZ wVf5IthIE+lYfHWnPo5DWShwVOpOkIV9MEE3qNxUqZ5LeNCSHv8/q/nBWZPg8F5yYors NAPQc4sdOJNFJuEU5z8dEKvJgkpYihI7SUH872tpkI6tSYNiEIpljRSGxSVASFvPkRmy VnXEN2pG+3ESAVB+FGSs5VKVuc2GHm/ABb+LTPB5L7YLEcFu3tIDMszKL06GF1wKqyqR 3TyA== X-Gm-Message-State: APf1xPB3KVrJYzbpZJoKs7CytMirqTg1f7frQhcg1Pdz6ujJqpCtoI24 xyHZsTEcO9WYxjr8pBjO/gtCWw== X-Received: by 10.99.96.137 with SMTP id u131mr10523483pgb.103.1519706944103; Mon, 26 Feb 2018 20:49:04 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id g80sm20981660pfj.101.2018.02.26.20.49.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Feb 2018 20:49:03 -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 5/7] x86: kexec_file: lift CRASH_MAX_RANGES limit on crash_mem buffer Date: Tue, 27 Feb 2018 13:48:12 +0900 Message-Id: <20180227044814.24808-6-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180227044814.24808-1-takahiro.akashi@linaro.org> References: <20180227044814.24808-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 | 80 ++++++++++++++++++------------------------------- 1 file changed, 29 insertions(+), 51 deletions(-) -- 2.16.2 diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 913fd8021f8a..bfc37ad20d4a 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,29 @@ 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); - 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 = vmalloc(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 +278,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 +297,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 +319,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 +328,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, int kernel_map, +static int prepare_elf64_headers(struct crash_mem *cmem, int kernel_map, void **addr, unsigned long *sz) { Elf64_Ehdr *ehdr; @@ -356,12 +337,11 @@ static int prepare_elf64_headers(struct crash_elf_data *ced, int 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 +435,27 @@ static int prepare_elf64_headers(struct crash_elf_data *ced, int 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, + ret = prepare_elf64_headers(cmem, (int)IS_ENABLED(CONFIG_X86_64), addr, sz); if (ret) goto out; @@ -496,7 +474,7 @@ static int prepare_elf_headers(struct kimage *image, void **addr, break; } out: - kfree(ced); + vfree(cmem); return ret; } From patchwork Tue Feb 27 04:48:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 129737 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp972860lja; Mon, 26 Feb 2018 20:49:18 -0800 (PST) X-Google-Smtp-Source: AH8x226b0yoYAJCknCFcGFk2qAsaIs225RIG7mEJG2H40Mh1E1PsOw4CkWjgkE6pWW89QfG6kSKn X-Received: by 10.99.4.131 with SMTP id 125mr10098898pge.375.1519706957886; Mon, 26 Feb 2018 20:49:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519706957; cv=none; d=google.com; s=arc-20160816; b=nCMXXvrzNAlaq5uVxWJZ+o/E5pAmQwheh4RDcLCYspuz82iLWSTyfgufTAneFCm5sC +8onikw1R0ZEfsjAhJAt3KeK9GKDQPKmdu3DgOo+VwZdFEk5iNKqrIKgvr3IoT+N8K5j 7UKchCKYKhMojMg+KTp4+Eq9sZYsxi5oEs1UVWf8PL5sZvgjgcj5V6bEvvqgvNKWJ/dz dmpUDwI0nckiaiAiTTpNNk2iviftKNVTw8ju3YViXVtrAl7lpItDdcYNgMozpNtFersL haDXfBN7Hng57qKfMkdN510LaYoDysQj2m8nAXLs5gvmfk3vCaOuxqStBZ6m5rzrFvU2 nvFw== 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=xn902+Uwdq4r1q+SLbai3XhIDKcpWgF42j/eR9GRetQ=; b=RGMESTE0BDhdwnVHszzLeOJ5h302Y6T6LONQ8ZtYGMFXYxou5BBPIBC2cOebcecosv QEaWk/xMUojQBSB8QZgOcldgPDRTU38cc7jsLvtlAkB+PFU5Y7tyzOx3DQpNWzj9i/hJ DiRiV57hw7LCUoLFIpGqiNChRG248D/bHoLHlyrVL8OP/DLFGxqQyRJfhOex+oUXgsoX WrcWyro8ctkq5+liQztpyUjd7K7hPuYQY9hMaU8D+D/B7/PbA2vEXbnB0mqOQiIVYcmO jnTiSyZaRQTH+okrRGcI5fulMFlemkZ/wTNxk6dZ1P8SplomPKGA+eUCK92YcKqhKI1d vU4Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Th7R5DWF; 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 h1-v6si8075959plt.728.2018.02.26.20.49.17; Mon, 26 Feb 2018 20:49:17 -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=Th7R5DWF; 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 S1752141AbeB0EtO (ORCPT + 28 others); Mon, 26 Feb 2018 23:49:14 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:42799 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751961AbeB0EtK (ORCPT ); Mon, 26 Feb 2018 23:49:10 -0500 Received: by mail-pg0-f67.google.com with SMTP id y8so7097468pgr.9 for ; Mon, 26 Feb 2018 20:49:10 -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=xn902+Uwdq4r1q+SLbai3XhIDKcpWgF42j/eR9GRetQ=; b=Th7R5DWFFSc0Sz9ylMr0i8bbc6QkY8N1lfR+Tp7WKugaQM+TsqzInTNv6drRlATY9E ANMmFOGlyUPSibGXOYbtfpvIuP66KXj+1zSiAPJ+pO6ChG+62Zm/Izpq+hZktwLwIU2x dBUj1KwwibsChmfnYlon8nHPtRUDPLYaSjGrE= 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=xn902+Uwdq4r1q+SLbai3XhIDKcpWgF42j/eR9GRetQ=; b=MCa0rovdDTCuu+0o6cuEY9nb587D/PaOwlF/V2uFWnhCr2yhE7WlVmm2Ddl0yEcf3t Kl5ThWF4Eu1/8W9sg7YqYd2aZDRYvnQyctB6x4taUHdTtNvLEkAbW+adizPBOmf2OUzC tXrqfOtBgYfWchvtFEqBoTd4Znc7FzegiFQ0/leiEprVqN2PnFYkIqKXWAu4RWt4sRCN rChwZy9KB1RqiTkNBM1Z7kljI/JesCllyIMjv0bsVLK3EiNYBU3y2nfN92UDewXGw5+W kgrLTWWwVczjtjAj1kMtJbzizYzU1qoqIp5FkAovzu+bfFIc9CueEmuqZhYs8GOvOUWD 0zHg== X-Gm-Message-State: APf1xPDpJ+3stlM5VwYyk250RmWRUfxesExCbfJ1WdnLmBFFMDL0zhqI olKMuUIL5KZViJ7+rZkUVrplIA== X-Received: by 10.98.137.90 with SMTP id v87mr12879685pfd.80.1519706949883; Mon, 26 Feb 2018 20:49:09 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id h75sm21246815pfh.28.2018.02.26.20.49.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Feb 2018 20:49:09 -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 6/7] x86: kexec_file: clean up prepare_elf64_headers() Date: Tue, 27 Feb 2018 13:48:13 +0900 Message-Id: <20180227044814.24808-7-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180227044814.24808-1-takahiro.akashi@linaro.org> References: <20180227044814.24808-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 bfc37ad20d4a..a842fd847684 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -334,7 +334,7 @@ static int prepare_elf64_headers(struct crash_mem *cmem, int 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; @@ -359,9 +359,8 @@ static int prepare_elf64_headers(struct crash_mem *cmem, int 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; @@ -377,33 +376,30 @@ static int prepare_elf64_headers(struct crash_mem *cmem, int 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 Feb 27 04:48:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 129738 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp972914lja; Mon, 26 Feb 2018 20:49:24 -0800 (PST) X-Google-Smtp-Source: AH8x225B2UdyzEZ+FtSKirTefJ4KXRv4nPSBV0pomrfyhA51nWTyeJR2Gm213QBa/AlCHMuHpK+6 X-Received: by 2002:a17:902:3303:: with SMTP id a3-v6mr12877777plc.399.1519706964220; Mon, 26 Feb 2018 20:49:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519706964; cv=none; d=google.com; s=arc-20160816; b=wvkx1r9PQfpuS3oNZhijbyknhNPm7fMf5C2SAg/Pewe5E+JHwTRKrYkntBTuQ4yX+3 6KSMjDyz0TlAV9jFFbI66Irg+UaSTm4v8PFJ6M1Iu68mLwIj3mL08ZsL2RGAVO3zhocg SODURY57VhD0tgG14AMfM7Ts3Izx39hpb9ulEi9TPphuawfJZNHnuY9lJafYLOh9dMxQ rMakOXQYsKsOIxNfFPu8zdq52mC2JOwpQFoHqMN2zG/Fr639LhdeydmHCB1UzYzdGn7L Izsagzl4fvaRS10pvQE2dm1JHRBuw9ne3xIbixIFqjhE6B0C+LxiQ1wxzfFAQA9w7i3l xEPw== 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=pEs2QfBkTwjTtrr20xQ3R2mvQVkY9yUrchay0fZIuNY=; b=rPHlzpvjLAUeaXl/GAd03iKn0rUEGWdhNvpyx28es5oRw30Z8xPwHAQ36sy77hDq1T 7TWzajdeE72CNpO6psB6vCpDgibj3Sk/u8RgrOi31ZlAl/YDkcwU3zlODEn/6P3IiHS/ kPO/oqzk7TVnT0fXdWN7cxlI/J+mnNPWEqMTT1ZaWQWyWT+I/5/HGIB4rbnxhva28fMx GOGPi9rmdGobDc09HVybK7uLYDiD7fDbgRsPB+V5P4x8XvbAZ90wiMopcenDSm5cfhoC YUM7Wzaeo4LwDL71aap2EWCft0JSy8pN6bXY7iquUNNw2PbFPH3BT5bJgaHmvcO/xYlL ggoQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=SlN0SkjU; 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 m6si3091876pgu.633.2018.02.26.20.49.23; Mon, 26 Feb 2018 20:49:24 -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=SlN0SkjU; 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 S1752161AbeB0EtT (ORCPT + 28 others); Mon, 26 Feb 2018 23:49:19 -0500 Received: from mail-pl0-f68.google.com ([209.85.160.68]:40762 "EHLO mail-pl0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752138AbeB0EtO (ORCPT ); Mon, 26 Feb 2018 23:49:14 -0500 Received: by mail-pl0-f68.google.com with SMTP id i6so10725326plt.7 for ; Mon, 26 Feb 2018 20:49:14 -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=pEs2QfBkTwjTtrr20xQ3R2mvQVkY9yUrchay0fZIuNY=; b=SlN0SkjUvdKVm52M/rWo+aPrmoIqPgbZTJpyT+3Tnbpol/nqaksi/fFzhrzi2zGMdr pWDPP82xYL4MkR2I+q7OdmK/D4crohnx7MwG7cWR4Z8X4rnD+xyjKGDoy6ATGn7vCTLC KqGw6GRxhrgjNpY7noo2KUaEKrgXV16iZTBXw= 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=pEs2QfBkTwjTtrr20xQ3R2mvQVkY9yUrchay0fZIuNY=; b=qwiP427yz+Oqfv4ihR/M814g/7OD/OUBMVF2NOtC3+pX4mUcaNYBdlWS5jtyGxingK BvbBttP9d36OyXGFrr3hh+sPNXoKSiwLx/HXxwIJXWhH6SggRsVDxv5M/erXQgFUlFoN w3gXvX+DGuelYRYwN9Zfw8GHKeZ+B2RlyYEmOwEc5dh+/Os65x9fw2GczIu/TzlbTKfD N5ZISuMGpYs4rQaeszj+bj1nngzkGEaFbyzUXTq2Yra4daq/LcWJo0nPl+NoAwfHLzTY jlPYIjaQAGwdo3u43pLGEF89C84QyMX/laXuukJC9YUS6AkCUH5jBJdB3KkyhcD6DoUl AE3w== X-Gm-Message-State: APf1xPDY37iGs1kEdSlfgJes/gxlPCcExcPRzHlelH5ZBA9Dgd3uzhxB 4/Y845Cc2uDHLRWDiNH40ff90g== X-Received: by 2002:a17:902:6589:: with SMTP id c9-v6mr12823859plk.51.1519706953971; Mon, 26 Feb 2018 20:49:13 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id o184sm16565063pga.16.2018.02.26.20.49.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Feb 2018 20:49:13 -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 7/7] kexec_file, x86: move re-factored code to generic side Date: Tue, 27 Feb 2018 13:48:14 +0900 Message-Id: <20180227044814.24808-8-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180227044814.24808-1-takahiro.akashi@linaro.org> References: <20180227044814.24808-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 | 194 ++---------------------------------------------- include/linux/kexec.h | 19 +++++ kernel/kexec_file.c | 175 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+), 188 deletions(-) -- 2.16.2 diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index a842fd847684..3e4f3980688d 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; @@ -224,77 +211,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 @@ -304,12 +220,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; } @@ -328,105 +245,6 @@ static int prepare_elf64_ram_headers_callback(struct resource *res, void *arg) return 0; } -static int prepare_elf64_headers(struct crash_mem *cmem, 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 += 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) @@ -451,7 +269,7 @@ static int prepare_elf_headers(struct kimage *image, void **addr, goto out; /* By default prepare 64bit headers */ - ret = prepare_elf64_headers(cmem, + ret = crash_prepare_elf64_headers(cmem, (int)IS_ENABLED(CONFIG_X86_64), addr, sz); if (ret) goto out; @@ -516,14 +334,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 2e095c3b4537..9aecf5472596 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -172,6 +172,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 60bdfc1104ff..04bbfd2209d0 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" @@ -1075,3 +1080,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; +}