From patchwork Mon Dec 4 02:57:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 120475 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3919646qgn; Sun, 3 Dec 2017 18:55:02 -0800 (PST) X-Google-Smtp-Source: AGs4zMYSJkGreLuKjrY5f4IvQNOA+pyEPL4p0mHyLPY89hAvKu+9nWh8ERdAY1JvilS8IQjUcJTC X-Received: by 10.84.179.193 with SMTP id b59mr13293165plc.12.1512356102235; Sun, 03 Dec 2017 18:55:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512356102; cv=none; d=google.com; s=arc-20160816; b=TZyWBSUB1u2CX3fxOR+m/0eFBppj2Mf41NNrs2UTE+SA089/LSSsYsQrwNz2jjo5VE gOlcqry2IgvSYXl9Rz992xZtmxq40wsc0DLTgyEmJUTtzr8823orvd39R9Rbzu25B+A/ FHA6XJJHodLztVDnNEnRLe6yXG2pyU2h+VNRwJDX7AT94DFegEh/jHyTw/5F0whJviC3 GZjIKOFypPSelmpJu120PxTxHZfC6lxN4smqNX3rTJpY9J5fK8jcf89XWcSJr+yncdfl T+nnEIY6NvIaoRfW3kCTPCYplMe3I0Wf/zDwDv7kZcewYOkrDVg0e1iC7oncDSQW3YJZ 7TrA== 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=44Ew9lzPcyWpGu+HB4lFG4+Mr/vH9nKg0bdPyWw8+h0=; b=0j6KVjKxRmxlJXmY9Nuw43dXX6uKvEXdzdr8rC6P9ko+VdrPplsp56+N7FDlE7CFTu rqoO8zFX9PMfxPxAqNexsm+CEjwlDnY1JJslI9PeIshn1Ufri+gkBs03o7f/13Ob5hNq 37bsNp8voUQhfngTDbnQbXVkLM1okhKVw0fCDYo2whRlg7IFa3RuxKs5Z24xqadMNvT8 GiZ5whHPOqw67rq2AFhyLkRlxoMoXUNS302UrnuXMlFMl4LXrAZC4n9JsncBuuJiMLjF 3Ez5duS2FltSJAjddDXa7/1au7Hyci4+zrhgW1ib8Jcz3o5Y72aJo+QauSO5A80k8U/S 0K+g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=iyzh/6Qh; 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 w15si8712279pgv.219.2017.12.03.18.55.01; Sun, 03 Dec 2017 18:55:02 -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=iyzh/6Qh; 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 S1753153AbdLDCyu (ORCPT + 28 others); Sun, 3 Dec 2017 21:54:50 -0500 Received: from mail-pg0-f66.google.com ([74.125.83.66]:35629 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753060AbdLDCyq (ORCPT ); Sun, 3 Dec 2017 21:54:46 -0500 Received: by mail-pg0-f66.google.com with SMTP id q20so7213906pgv.2 for ; Sun, 03 Dec 2017 18:54: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=44Ew9lzPcyWpGu+HB4lFG4+Mr/vH9nKg0bdPyWw8+h0=; b=iyzh/6Qh7qzoOQzh5wlf7USyH6my2Jf2FC44F0oaK4rAtzC3Y4dVSxTojRRy+baZCR 5J5SLrFYoldA8VI3s2g0MqIVVKFIjN3DNT+T2i/X6AwAPE3qlWL55xGdo77FZdXRsIVP P3jfrdLoUu2SAq9ixsKiiO7leZSj3XMq99auE= 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=44Ew9lzPcyWpGu+HB4lFG4+Mr/vH9nKg0bdPyWw8+h0=; b=g/1MsLZ3eHdCoziAt/URfiMWg16cQTJ7frMun30Styt/mtF54YitiMsc7ggBWZvy6+ Lp3kXUd/h8BU62V5vPZ5ADADLNB3bq+m3o89fsYrfSNOOzN5TZqh1Hp4FiVL532D6iwT n2jtbQ4lZclHoUcqKWXKZvzElWCUtHfjY5+FXcCZSBmf0tStr+VleFuOdAYZQrrB/m83 EjmM6GTL4rNsFJUczpu8Yy/xwlgKShDewi8xXdtANxv1A0zTz1Q8G+u8jKjz7VVgKYtA f9VFKqrQc7paBPR4oaR9cGMUUaD19yWCuMbDInYN/VAOZ4c3u2gsVaSXBKeGJnlI0NKJ 2Ouw== X-Gm-Message-State: AJaThX6cZ5na9W1RcJMnNY1sA5rsx/0Z4ogpuT3uq2ecB6gI1IcsXzQw T/A/ktw1Ni0C2LgEbUEVSWEBMQ== X-Received: by 10.84.246.194 with SMTP id j2mr12993602plt.7.1512356085935; Sun, 03 Dec 2017 18:54:45 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id n6sm21855672pfg.188.2017.12.03.18.54.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Dec 2017 18:54:45 -0800 (PST) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, bauerman@linux.vnet.ibm.com, dhowells@redhat.com, vgoyal@redhat.com, herbert@gondor.apana.org.au, davem@davemloft.net, akpm@linux-foundation.org, mpe@ellerman.id.au, dyoung@redhat.com, bhe@redhat.com, arnd@arndb.de, ard.biesheuvel@linaro.org, julien.thierry@arm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro , Linus Torvalds Subject: [PATCH v7 01/11] resource: add walk_system_ram_res_rev() Date: Mon, 4 Dec 2017 11:57:51 +0900 Message-Id: <20171204025801.12161-2-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171204025801.12161-1-takahiro.akashi@linaro.org> References: <20171204025801.12161-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This function, being a variant of walk_system_ram_res() introduced in commit 8c86e70acead ("resource: provide new functions to walk through resources"), walks through a list of all the resources of System RAM in reversed order, i.e., from higher to lower. It will be used in kexec_file implementation on arm64. Signed-off-by: AKASHI Takahiro Cc: Vivek Goyal Cc: Andrew Morton Cc: Linus Torvalds --- include/linux/ioport.h | 3 +++ kernel/resource.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) -- 2.14.1 diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 93b4183cf53d..322ac1f58b36 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -277,6 +277,9 @@ extern int walk_system_ram_res(u64 start, u64 end, void *arg, int (*func)(struct resource *, void *)); extern int +walk_system_ram_res_rev(u64 start, u64 end, void *arg, + int (*func)(struct resource *, void *)); +extern int walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end, void *arg, int (*func)(struct resource *, void *)); diff --git a/kernel/resource.c b/kernel/resource.c index 54ba6de3757c..aefc1d5d6b75 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include @@ -486,6 +488,61 @@ int walk_mem_res(u64 start, u64 end, void *arg, arg, func); } +int walk_system_ram_res_rev(u64 start, u64 end, void *arg, + int (*func)(struct resource *, void *)) +{ + struct resource res, *rams; + int rams_size = 16, i; + int ret = -1; + + /* create a list */ + rams = vmalloc(sizeof(struct resource) * rams_size); + if (!rams) + return ret; + + res.start = start; + res.end = end; + res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; + i = 0; + while ((res.start < res.end) && + (!find_next_iomem_res(&res, IORES_DESC_NONE, true))) { + if (i >= rams_size) { + /* re-alloc */ + struct resource *rams_new; + int rams_new_size; + + rams_new_size = rams_size + 16; + rams_new = vmalloc(sizeof(struct resource) + * rams_new_size); + if (!rams_new) + goto out; + + memcpy(rams_new, rams, + sizeof(struct resource) * rams_size); + vfree(rams); + rams = rams_new; + rams_size = rams_new_size; + } + + rams[i].start = res.start; + rams[i++].end = res.end; + + res.start = res.end + 1; + res.end = end; + } + + /* go reverse */ + for (i--; i >= 0; i--) { + ret = (*func)(&rams[i], arg); + if (ret) + break; + } + +out: + vfree(rams); + return ret; +} + #if !defined(CONFIG_ARCH_HAS_WALK_MEMORY) /* From patchwork Mon Dec 4 02:57:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 120476 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3919653qgn; Sun, 3 Dec 2017 18:55:03 -0800 (PST) X-Google-Smtp-Source: AGs4zMZ7WvoCrEUYNMoZqyZ8gP9ZbRWOftEGqmNNobQDzdcnSewhYT+HtjgljeowvTGaeNC5iHU+ X-Received: by 10.99.170.1 with SMTP id e1mr13179802pgf.120.1512356103002; Sun, 03 Dec 2017 18:55:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512356102; cv=none; d=google.com; s=arc-20160816; b=eZjQAPT1qf+tzq+khfZFsTwJuHu8EnbFFA6r+WMhhWKs0INao+AvcYSeca0Vp4tnH9 NlkfgTUTqIXz2M5+kUA8tgy1BLSneRfYgPzVOpjb0v8a8q3BPdHOZC9ChCbYjpbmMiOm MjAH7xhcWua4ZmRkWHLxiGvV6jAhIeHgbtOoOkvdPEDidjMrkm+9yv3Oq4NVyNHNyUtJ cDLkGMebuR9p1TjhtWbyppyw7Ht+E3JDAmHbrDQJ2iiPEgEefEVavqoyPG/S/ysPp30T sj4ln+TzeBAZEOtJS4X+yTJxjzdDHVEWjAVr1jJr61AukEG2f5bDhm4/vgzb8FXRKTAx wn8A== 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=BltUP2QS1e/91tmxRlX0/ydxTbKBlM2GXxKgSu+6Urc=; b=xgMB0Hhgv78s9cupv3Ralk6JpyN/SayXI4KxpbH6OmG+W7iINr5xcldPcVYpvuujrx vvo4EkqlKcHWNL3+nxjEIbUCbjKgAYd0H9yAsJqPym/lSpH3BBMQxB905ttcNxOqOCFI K2WlgiN72hk33N2Qx8x0F24EPxmYPa754kDVh43FWJKa6sgScOb4nMEuK0F/Aaw5o45y 83MGOHzmssshH3v0g5jt/fWy7GzZlf2zwkAsqxq7Plop49bMUFqGxVQSSpJ5c3vQeeVv xE24QQB0+UzdYJCXCDvrb3oNDf5DwT4oS5Q6HXAminrWhqjQH0HH1YZRNDaRx/Azpi/P jZog== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WEgWUHXM; 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 w15si8712279pgv.219.2017.12.03.18.55.02; Sun, 03 Dec 2017 18:55:02 -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=WEgWUHXM; 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 S1753169AbdLDCyy (ORCPT + 28 others); Sun, 3 Dec 2017 21:54:54 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:36979 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753129AbdLDCyv (ORCPT ); Sun, 3 Dec 2017 21:54:51 -0500 Received: by mail-pg0-f67.google.com with SMTP id y6so7212805pgp.4 for ; Sun, 03 Dec 2017 18:54:51 -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=BltUP2QS1e/91tmxRlX0/ydxTbKBlM2GXxKgSu+6Urc=; b=WEgWUHXMOKXw9lB3jKTUaUMTs9jD301VLltyvmO9LM4pTFbzdOL/RugBI/7s72mIcy sDMJB020fNatSBKNSA+veZ9j71OItrrSu5ScLrOtgWynjiQyRuKuVSDLsxz0qAK6z4MY vJlNKLCZoYMbw8XB3KZIJxt0N9iJgttyJjLeg= 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=BltUP2QS1e/91tmxRlX0/ydxTbKBlM2GXxKgSu+6Urc=; b=aEIJnlQXg4kx5T/joy9ceCz3xYHnaIqFjuellWE2I+zwX2moFZcg1iCBP77Q/1mVyu SKYZYNDta8QvnxSTielbl6pFREGZNCXQUbdrBrvVPY4yjwJBgLWvS6Z9mx8U6B9GNTUW f9/9kf3TKNysmtZPdDC3ac23myXEKzLTd6AvTVB+oZ9HEiYD9tir1vE/dn7tRNlknlCu BLlUdd3gp8iNOaaQGd2yTntDit4Coq8WBUgXkkvLS3FPsPzQgzbAo727zh4346iunX7G 3GC+WEn/Ksu9GotbN9ZbvmzbTK7uWLUB5GjCARnyGTaAdD1LxvkfFP5jVpL0obJQlJHy +kWg== X-Gm-Message-State: AJaThX4KZfdnYO32otzYYNwfPsN6iOou2Oexmb2EQEpWuLhvkUhu7k6p 7Np9k2qlQDzj15u/un/cIztRaw== X-Received: by 10.84.240.1 with SMTP id y1mr13401776plk.391.1512356091237; Sun, 03 Dec 2017 18:54:51 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id p126sm18814517pga.58.2017.12.03.18.54.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Dec 2017 18:54:50 -0800 (PST) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, bauerman@linux.vnet.ibm.com, dhowells@redhat.com, vgoyal@redhat.com, herbert@gondor.apana.org.au, davem@davemloft.net, akpm@linux-foundation.org, mpe@ellerman.id.au, dyoung@redhat.com, bhe@redhat.com, arnd@arndb.de, ard.biesheuvel@linaro.org, julien.thierry@arm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v7 02/11] kexec_file: factor out arch_kexec_kernel_*() from x86, powerpc Date: Mon, 4 Dec 2017 11:57:52 +0900 Message-Id: <20171204025801.12161-3-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171204025801.12161-1-takahiro.akashi@linaro.org> References: <20171204025801.12161-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org arch_kexec_kernel_*() and arch_kimage_file_post_load_cleanup can now be duplicated among some architectures, 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 | 15 ++++---- kernel/kexec_file.c | 57 +++++++++++++++++++++++++++-- 8 files changed, 70 insertions(+), 94 deletions(-) -- 2.14.1 diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h index 4419d435639a..3fc293b090ee 100644 --- a/arch/powerpc/include/asm/kexec.h +++ b/arch/powerpc/include/asm/kexec.h @@ -93,7 +93,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..325980537125 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -209,7 +209,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 +277,13 @@ 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 _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_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 e5bcd94c1efb..c95e3ffd4be8 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -26,30 +26,79 @@ #include #include "kexec_internal.h" +const __weak struct kexec_file_ops * const kexec_file_loaders[] = {NULL}; + static int kexec_calculate_store_digests(struct kimage *image); +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 Mon Dec 4 02:57:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 120477 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3919686qgn; Sun, 3 Dec 2017 18:55:07 -0800 (PST) X-Google-Smtp-Source: AGs4zMYg7hKG6c2E2u9IVRYU8DrMGjDWsBLMCHVT7JMpwkbj9YWmFTTjQvqPDJgt3xg4elnNCwob X-Received: by 10.98.11.71 with SMTP id t68mr17594290pfi.79.1512356107329; Sun, 03 Dec 2017 18:55:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512356107; cv=none; d=google.com; s=arc-20160816; b=uEWVE6NArdV5r+bbzfSyQDr9bJcMYwUcu118JiAwoqMBUelFqtTDTSiTEiTIbSVpEI ihjfow4ys7shMCPdL9ZE1tLoVzTQ6JA6ctE2xWeXbIsM5XZJ2l5ZSOXTHd+WrL+fWta0 KL2gO8uo9kHVOhj1Rj/YPxkXHC78Ki2WU/mQx0dAQQONXuXqgWHiwC5ecH1FlTTmpwC0 6ellxQazP+cVNtf6Im3BGdU3Q9pVm+2/Lg3b7qC1W0oAm4zBzpTgeGTM0MZ5kiGeQv/s 5f5wZ1ylF0KE9np8m/cKTQ5K/GLS3iJcsEkNh0YqrvaGcuGnRBf0I9b9lrRT5ZrqKeq0 M/Qg== 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=KEvkskwtJzCqjIoTPRy8lp88u5+MP6G29bpcPn7T5dM=; b=nPFqnKjQ4RjoFW6hGjCbYn5LNymzdNwPCWbIIkmpUYhOm9BYSgoKEATo/zzCwALYKL jO8pSa4J8oTi+yZ+3vdyDfNcVgOchtjgZ/Pm10qs26sRTM29BhxDE7M+bCkLn19JZ5nF VSKUz82fVwnRgDSq4zNWvA3S/fv+7T++rFw+DSt4nVNIOoTvFoDAbvqZk6UgjNxWSrRq WSZzHFa4io+jtCNQU9jwbUHyRWAyrknt0vQRMbi+oi+cS9/kPG1pPVCw8m+5KfQUcTXL VU7SQBTLaFfWgoGxqL9/8HWW9ylq70rCgGkAsX2BSMvvn7mNWuKLxrg7YsMSoyYER4rb W0SQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KrzJzVpQ; 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 f9si8822884plo.553.2017.12.03.18.55.07; Sun, 03 Dec 2017 18:55:07 -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=KrzJzVpQ; 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 S1753188AbdLDCzE (ORCPT + 28 others); Sun, 3 Dec 2017 21:55:04 -0500 Received: from mail-pf0-f194.google.com ([209.85.192.194]:43623 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753129AbdLDCy5 (ORCPT ); Sun, 3 Dec 2017 21:54:57 -0500 Received: by mail-pf0-f194.google.com with SMTP id e3so7466919pfi.10 for ; Sun, 03 Dec 2017 18:54:57 -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=KEvkskwtJzCqjIoTPRy8lp88u5+MP6G29bpcPn7T5dM=; b=KrzJzVpQiuasdZZyJooFpM9dC3Jm2/8jbBCvkR9Bue7hW3c6a9VrOWfOc2811sFAjy powFsygN1v6LEZF6F+QUwbqMuje3rQkHspNO/06NmO8osA/u7ltnmAIjie+02GBUCr50 qIt5MLtfPj+PCHVIcOywNN3hnRcbmw7VCUwmo= 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=KEvkskwtJzCqjIoTPRy8lp88u5+MP6G29bpcPn7T5dM=; b=C3Qw/Nzd55pcVuaSMuq4/5/pF87+9Kev65oY9E5jqWUIgkdaAMx1nQDWM6i/kzF8h9 r7w+Kt1xLTFa7nuXyj8DXFzfGrABbnBGAeReqASdDB7HyhY6vntMHLyMJNZYiXBxFlkg kZkTHOsDJ+Ujjaumfh0bwBrr1kpwrO1WoLAsMpikTBWhvTNGmdVvwGTLCQKtbxObJkDV dcKKPONbfR0Wa4cTKqU3HoDnjuxeE1XYej7nu6J6mZ+NgJguzruZS7xSJh+nQaYaBqkp V1QkCouC1+lNll+B5QIrUo8RsC+LtFWRYlRZrwCKWuc9r66c/P2G+r+6gBA75Ovs17cD 1VuQ== X-Gm-Message-State: AJaThX4jTZPzmon20GhbZrWQkLUbjTPWZZePJh69hfbycfDFb3QUi9iw QTO7oMl1YWDqb7eCMsj+j2DbuA== X-Received: by 10.98.141.26 with SMTP id z26mr17512557pfd.85.1512356096595; Sun, 03 Dec 2017 18:54:56 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id w1sm18293854pgq.34.2017.12.03.18.54.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Dec 2017 18:54:55 -0800 (PST) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, bauerman@linux.vnet.ibm.com, dhowells@redhat.com, vgoyal@redhat.com, herbert@gondor.apana.org.au, davem@davemloft.net, akpm@linux-foundation.org, mpe@ellerman.id.au, dyoung@redhat.com, bhe@redhat.com, arnd@arndb.de, ard.biesheuvel@linaro.org, julien.thierry@arm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v7 03/11] kexec_file: factor out crashdump elf header function from x86 Date: Mon, 4 Dec 2017 11:57:53 +0900 Message-Id: <20171204025801.12161-4-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171204025801.12161-1-takahiro.akashi@linaro.org> References: <20171204025801.12161-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org prepare_elf_headers() can also be useful for other architectures, including arm64. So let it factored out. Signed-off-by: AKASHI Takahiro Cc: Dave Young Cc: Vivek Goyal Cc: Baoquan He --- arch/x86/kernel/crash.c | 324 ------------------------------------------------ include/linux/kexec.h | 17 +++ kernel/kexec_file.c | 308 +++++++++++++++++++++++++++++++++++++++++++++ kernel/kexec_internal.h | 20 +++ 4 files changed, 345 insertions(+), 324 deletions(-) -- 2.14.1 diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 10e74d4778a1..bb8f3dcddaaa 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -41,34 +40,6 @@ /* 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; -}; - /* Used while preparing memory map entries for second kernel */ struct crash_memmap_data { struct boot_params *params; @@ -209,301 +180,6 @@ void native_machine_crash_shutdown(struct pt_regs *regs) } #ifdef CONFIG_KEXEC_FILE -static int get_nr_ram_ranges_callback(struct resource *res, void *arg) -{ - unsigned int *nr_ranges = arg; - - (*nr_ranges)++; - 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) -{ - unsigned int nr_ranges = 0; - - ced->image = image; - - walk_system_ram_res(0, -1, &nr_ranges, - get_nr_ram_ranges_callback); - - ced->max_nr_ranges = nr_ranges; - - /* Exclusion of crash region could split memory ranges */ - ced->max_nr_ranges++; - - /* If crashk_low_res is not 0, another range split possible */ - if (crashk_low_res.end) - ced->max_nr_ranges++; -} - -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 == CRASH_MAX_RANGES - 1) { - pr_err("Too many crash ranges after split\n"); - 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 ced->mem.ranges[] array - */ -static int elf_header_exclude_ranges(struct crash_elf_data *ced, - unsigned long long mstart, unsigned long long mend) -{ - 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) - return ret; - - if (crashk_low_res.end) { - ret = exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end); - if (ret) - return ret; - } - - return ret; -} - -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); - - phdr->p_type = PT_LOAD; - phdr->p_flags = PF_R|PF_W|PF_X; - phdr->p_offset = mstart; - - /* - * 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; -} - -static int prepare_elf64_headers(struct crash_elf_data *ced, - 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, *bufp; - unsigned int cpu; - unsigned long long notes_addr; - int ret; - - /* extra phdr for vmcoreinfo elf note */ - nr_phdr = nr_cpus + 1; - nr_phdr += ced->max_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; - - bufp = buf; - ehdr = (Elf64_Ehdr *)bufp; - bufp += sizeof(Elf64_Ehdr); - 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 = (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)++; - } - - /* 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)++; - -#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 - - /* 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; - - *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) -{ - struct crash_elf_data *ced; - int ret; - - ced = kzalloc(sizeof(*ced), GFP_KERNEL); - if (!ced) - return -ENOMEM; - - fill_up_crash_elf_data(ced, image); - - /* By default prepare 64bit headers */ - ret = prepare_elf64_headers(ced, addr, sz); - kfree(ced); - return ret; -} - static int add_e820_entry(struct boot_params *params, struct e820_entry *entry) { unsigned int nr_e820_entries; diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 325980537125..a8ac11633969 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -163,6 +163,23 @@ 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); +extern int prepare_elf_headers(struct kimage *image, void **addr, + unsigned long *sz); + +/* 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]; +}; + +extern int exclude_mem_range(struct crash_mem *mem, + unsigned long long mstart, unsigned long long mend); #endif /* CONFIG_KEXEC_FILE */ struct kimage { diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index c95e3ffd4be8..b2c425e6afc6 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" @@ -1071,3 +1076,306 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name, return 0; } + +static int get_nr_ram_ranges_callback(struct resource *res, void *arg) +{ + unsigned int *nr_ranges = arg; + + (*nr_ranges)++; + 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) +{ + unsigned int nr_ranges = 0; + + ced->image = image; + + walk_system_ram_res(0, -1, &nr_ranges, + get_nr_ram_ranges_callback); + + ced->max_nr_ranges = nr_ranges; + + /* Exclusion of crash region could split memory ranges */ + ced->max_nr_ranges++; + +#ifdef CONFIG_X86_64 + /* If crashk_low_res is not 0, another range split possible */ + if (crashk_low_res.end) + ced->max_nr_ranges++; +#endif +} + +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 happened, add the split to array */ + if (!temp_range.end) + return 0; + + /* Split happened */ + if (i == CRASH_MAX_RANGES - 1) { + pr_err("Too many crash ranges after split\n"); + 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 ced->mem.ranges[] array + */ +static int elf_header_exclude_ranges(struct crash_elf_data *ced, + unsigned long long mstart, unsigned long long mend) +{ + 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) + return ret; + +#ifdef CONFIG_X86_64 + if (crashk_low_res.end) { + ret = exclude_mem_range(cmem, crashk_low_res.start, + crashk_low_res.end); + if (ret) + return ret; + } +#endif + + return ret; +} + +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; +#ifdef CONFIG_X86_64 + struct kimage *image = ced->image; +#endif + 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); + + phdr->p_type = PT_LOAD; + phdr->p_flags = PF_R|PF_W|PF_X; + phdr->p_offset = mstart; + +#ifdef CONFIG_X86_64 + /* + * 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; +#endif + + 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; +} + +static int prepare_elf64_headers(struct crash_elf_data *ced, + 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, *bufp; + unsigned int cpu; + unsigned long long notes_addr; + int ret; + + /* extra phdr for vmcoreinfo elf note */ + nr_phdr = nr_cpus + 1; + nr_phdr += ced->max_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; + + bufp = buf; + ehdr = (Elf64_Ehdr *)bufp; + bufp += sizeof(Elf64_Ehdr); + 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 = (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)++; + } + + /* 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)++; + +#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 + + /* 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; + + *addr = buf; + *sz = elf_sz; + return 0; +} + +/* Prepare elf headers. Return addr and size */ +int prepare_elf_headers(struct kimage *image, void **addr, unsigned long *sz) +{ + struct crash_elf_data *ced; + int ret; + + ced = kzalloc(sizeof(*ced), GFP_KERNEL); + if (!ced) + return -ENOMEM; + + fill_up_crash_elf_data(ced, image); + + /* By default prepare 64bit headers */ + ret = prepare_elf64_headers(ced, addr, sz); + kfree(ced); + return ret; +} diff --git a/kernel/kexec_internal.h b/kernel/kexec_internal.h index 48aaf2ac0d0d..2415e1f5e558 100644 --- a/kernel/kexec_internal.h +++ b/kernel/kexec_internal.h @@ -17,6 +17,26 @@ extern struct mutex kexec_mutex; #ifdef CONFIG_KEXEC_FILE #include + +/* Alignment required for elf header segment */ +#define ELF_CORE_HEADER_ALIGN 4096 + +/* 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; +}; + void kimage_file_post_load_cleanup(struct kimage *image); extern char kexec_purgatory[]; extern size_t kexec_purgatory_size; From patchwork Mon Dec 4 02:57:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 120485 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3920873qgn; Sun, 3 Dec 2017 18:57:09 -0800 (PST) X-Google-Smtp-Source: AGs4zMb5+A2PfiOSLGALJCE+PXjOF6oC54oj53WBXcmKmdmF6wQOd2W26k+UKLZ8n6nsiHFAIEla X-Received: by 10.99.134.73 with SMTP id x70mr12860052pgd.130.1512356229787; Sun, 03 Dec 2017 18:57:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512356229; cv=none; d=google.com; s=arc-20160816; b=hEHLR3HevL4nzc1s7I67H39y5wXZrJQNbtHaH7rXsJs7aqY1yCKlAPMkGP4s3zaaHN 4CzTSpq62vgElAXWTUMVtSDTEJvjS+tip8By+QKMhZTbOZ6bQh06ucNx20hi4aFml3zv FBIzGtDkqITs0V9YryZHQ5Jkhbi6btckCzcH5YE3jAbZp5Bk859YC61ByzrMIgz9D0v7 UWDX+F0pvgmQnPrYR3jL1keT8/rtX4+3qh9L2Dat6oEBoxKWM8gXtDTUFUre+0hKqEMz OrZwFpW3ReffRauJRPYqmFrpVbQEPGpFSqsh/w9GB3ZXLhTVLv5h/De+bYKHhZUdJqsg OV+A== 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=0ksGx4L+xN6AyzfgPucu9sDki/2xdJxO1EeZcxrOad4=; b=fdNsqgTJSaL5zKjv8GhIAemxAc3fvGhATGeFWdI+LeYc6aMonoJ0rqbfItWdKVMTbI A0OD7tfWYL8Je84skUJyog7jy44CUGsK5lZ3CXNaer2Wsdi1vJNjGsTOltV2xjl6H2Wi xVL2/hEebqhuGu5PUZi+m3OoFsE+O2x7fpsFO24jLOzn4T1+OkpX26ICCfMv/d8byf34 j/cXQNAQN9CeqITWpzp7iq8eiifQs+haowkXap4FgIM0FPDPDctVJIsg3+RNHUCwZhh/ o+RYrrn+dXoBZLl1RzqRtUHXR6wafygI/URSo9ZI3NfUW/NOBon56PWUtHOr1Kt5eS7F QVZg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=dR9nqaw0; 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 v18si8513804pgb.63.2017.12.03.18.57.09; Sun, 03 Dec 2017 18:57: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=dR9nqaw0; 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 S1753330AbdLDC5H (ORCPT + 28 others); Sun, 3 Dec 2017 21:57:07 -0500 Received: from mail-pg0-f68.google.com ([74.125.83.68]:36991 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753173AbdLDCzC (ORCPT ); Sun, 3 Dec 2017 21:55:02 -0500 Received: by mail-pg0-f68.google.com with SMTP id y6so7213069pgp.4 for ; Sun, 03 Dec 2017 18:55:02 -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=0ksGx4L+xN6AyzfgPucu9sDki/2xdJxO1EeZcxrOad4=; b=dR9nqaw0qAy768XKa8hzF/CvXhQgCA9/ssqmJ8BGI4YpiEwlJvVW6IS+jNCfRzascK TI4K6Ej344+JplQEjV4K1FJKM31isojTX/cKd/E8YePf5nVwUzadN/Ayzp086HPm18J5 UESr7O7GbjTVdhZ9Ph9S/iaKpXyYGN065k4ko= 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=0ksGx4L+xN6AyzfgPucu9sDki/2xdJxO1EeZcxrOad4=; b=n9+sUUrddXfx7QofzAV/4xObMKJ2QuAIKjdA+B57s/+5lf4WFJJ6n66D42WKCnPo32 uJM8fu5uzsLdWrjNM5tw57Li8qYKwR14+M5cD/mZgnmA0jU+FVZWE6cB1JnB7zu/3HWJ 9NLylBqJxNN7trTaT6NQ+WSVjFmop2BZrKKyT8ueQ8YeXKv+tetlOh4xariEaBaFmk0K Swf0vdS1vdPSEH+6cRz8FLCXyc55l90uO47FPN9KET6IaGJ4QZQf3G/Ec/BerLFJhtzf 5NKYBbFWJM4oKv4jHA7Rh6KvzkeKNXKLRDtrjYLskNZ+qdO1GbOKqTqavv2ysUA3aqbq kYHw== X-Gm-Message-State: AJaThX4IZrhSccQ6Fmj/wQJNXGgE4ki+Ap2JWhcV4i06TPSuIA3G3tvD ffE25CvENh47M33TrYlc5RiSnw== X-Received: by 10.99.3.146 with SMTP id 140mr12672027pgd.275.1512356101714; Sun, 03 Dec 2017 18:55:01 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id 67sm19399296pfz.171.2017.12.03.18.55.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Dec 2017 18:55:01 -0800 (PST) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, bauerman@linux.vnet.ibm.com, dhowells@redhat.com, vgoyal@redhat.com, herbert@gondor.apana.org.au, davem@davemloft.net, akpm@linux-foundation.org, mpe@ellerman.id.au, dyoung@redhat.com, bhe@redhat.com, arnd@arndb.de, ard.biesheuvel@linaro.org, julien.thierry@arm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v7 04/11] asm-generic: add kexec_file_load system call to unistd.h Date: Mon, 4 Dec 2017 11:57:54 +0900 Message-Id: <20171204025801.12161-5-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171204025801.12161-1-takahiro.akashi@linaro.org> References: <20171204025801.12161-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 initial user of this system call number is arm64. Signed-off-by: AKASHI Takahiro Acked-by: Arnd Bergmann --- include/uapi/asm-generic/unistd.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) -- 2.14.1 diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index 8b87de067bc7..33761525ed2f 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -732,9 +732,11 @@ __SYSCALL(__NR_pkey_alloc, sys_pkey_alloc) __SYSCALL(__NR_pkey_free, sys_pkey_free) #define __NR_statx 291 __SYSCALL(__NR_statx, sys_statx) +#define __NR_kexec_file_load 292 +__SYSCALL(__NR_kexec_file_load, sys_kexec_file_load) #undef __NR_syscalls -#define __NR_syscalls 292 +#define __NR_syscalls 293 /* * All syscalls below here should go away really, From patchwork Mon Dec 4 02:57:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 120478 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3919808qgn; Sun, 3 Dec 2017 18:55:18 -0800 (PST) X-Google-Smtp-Source: AGs4zMZYZ4wm4nWJUO2+ZDj5VhHhFl4HlpgBbfU9VW37YeRrx5+mwM+m4vrcs5G+VyppfVADUvtE X-Received: by 10.99.114.30 with SMTP id n30mr12957036pgc.271.1512356117958; Sun, 03 Dec 2017 18:55:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512356117; cv=none; d=google.com; s=arc-20160816; b=NxQj58r1he9lbA9FfwsCXobV2tHUxUOIYBmyZH5fqVH3EOHQ3k2kgqydgAkh/We1eB O00xeS8R3O3pduiJS3a1c9OUehQz/yeiWT6FgVsrAvZ5ogALRtIdeZ8X3G6hmcBdA56u bzgQIdzntrF5ktV8OOiBi6lRhBFLrxrYZn4fayGdvNZPpGBR/i3kYJKASN+n+aAjtSjM g4zPZs11uotaqCogrPRb2rAF47GKx8pUW2ZuVhUmpluZU0aBxb0QMz3sUB9l0j8R7U3P Aj791ii7bcCKDRiIGBPPDa3IJKcfXE0u9pxrTZ9QPkLqcgrBUYkajEuvZhmXtL+gUWUO ZhxQ== 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=eaqM2YFE4pLElTWxPIy6UQX/U/pjnZQFhFnPPPh5vXc=; b=oMSkI/AYQ9Gt86sPaWuQBYgrve/yoqdcNsagC9T5tn5TkYplSEcaW4RYYCvuzZ4+au opprPX3Ugf1qFAQqDsYecYU1Wxg7vdu/TogI8OgbNQmaka+qQkyt2iJWDv91tWa4s3I6 IUon8Pk7ESpkIOXQYRtWBw+zAuzr1Ba7oZYYPb/zwOFfGL2cPk6/TQdLO478AJR83NRQ ib1FIdyb6RtN+slMSKdlc2jxoGhRXMS7uWAOE1kWAlkVdjwkgm+rntjJBGL9MexoiKNA xqYtBBl8/zxHXmZcDllEMRTGI7UZdvBwdPp2sjF7WLhp+PYO7nRaQ84lcTR8ajzeQfFp /S2A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AbTTBDfv; 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 f9si8822884plo.553.2017.12.03.18.55.17; Sun, 03 Dec 2017 18:55: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=AbTTBDfv; 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 S1753209AbdLDCzO (ORCPT + 28 others); Sun, 3 Dec 2017 21:55:14 -0500 Received: from mail-pf0-f193.google.com ([209.85.192.193]:42704 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753129AbdLDCzG (ORCPT ); Sun, 3 Dec 2017 21:55:06 -0500 Received: by mail-pf0-f193.google.com with SMTP id d23so7463027pfe.9 for ; Sun, 03 Dec 2017 18:55:06 -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=eaqM2YFE4pLElTWxPIy6UQX/U/pjnZQFhFnPPPh5vXc=; b=AbTTBDfvbtgluZgPbed2pReVmnrfwwvj/Lm68Q1TXy01G+JXWAtPzF5e5OfUtFG0cH lz2bQ/7jcOmBanQNPez7qVoBUlIFWW885j/DyJQV+RGKmYMdL2CjJe3RLeImkLEsWpZt MOsnFqwsp4OYM7PM564wiiBl7tEJvh+FLp284= 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=eaqM2YFE4pLElTWxPIy6UQX/U/pjnZQFhFnPPPh5vXc=; b=hxtPiwMdhoWXJC37RqK/4hvHB59YXbjgJMAOLnjZbzkhMD5X5XJR1bSmYmlD7cx3g1 MM7mVEZEuQRSCxq/DrhJ7wxn6Lx2VGHpNtmnMbQpl3XBS7SEmFqE2qKQNXzxid+Wh3Mp 49xnqO78OwVfHuvs0A4GVBxCa+cWRLz3WFexMalBrt2GcCn7XOr0+7BPRFNRXkSGUXLL dcDg5RyNjQVNQZC2x4nBRTlg2fPt5Gf0Br2PT4B7JNgbT8PfBM2WC2obfW8eVhX5u1nJ nPpLIn2cD3zeOle5xvyAkuQsPk08j0MPGTZCeizf5JlXszRnNZrOAss+svDgJTPmOzzP vZpg== X-Gm-Message-State: AJaThX4zX8j9GY7eNwVfxN0exQP6kSKwbWwo0ioPEcAx2uulLIQcoTD9 /oAA0EwJ7VfT75l2YUPDLyGlFw== X-Received: by 10.84.202.194 with SMTP id q2mr9599585plh.220.1512356105385; Sun, 03 Dec 2017 18:55:05 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id v43sm3124735pgn.65.2017.12.03.18.55.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Dec 2017 18:55:04 -0800 (PST) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, bauerman@linux.vnet.ibm.com, dhowells@redhat.com, vgoyal@redhat.com, herbert@gondor.apana.org.au, davem@davemloft.net, akpm@linux-foundation.org, mpe@ellerman.id.au, dyoung@redhat.com, bhe@redhat.com, arnd@arndb.de, ard.biesheuvel@linaro.org, julien.thierry@arm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v7 05/11] arm64: kexec_file: create purgatory Date: Mon, 4 Dec 2017 11:57:55 +0900 Message-Id: <20171204025801.12161-6-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171204025801.12161-1-takahiro.akashi@linaro.org> References: <20171204025801.12161-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This is a basic purgatory, or a kind of glue code between the two kernels, for arm64. Since purgatory is assumed to be relocatable (not executable) object by kexec generic code, arch_kexec_apply_relocations_add() is required in general. Arm64's purgatory, however, is a simple asm and all the references can be resolved as local, no re-linking is needed here. Please note that even if we don't support digest check at purgatory we need purgatory_sha_regions and purgatory_sha256_digest as they are referenced by generic kexec code. Signed-off-by: AKASHI Takahiro Cc: Catalin Marinas Cc: Will Deacon --- arch/arm64/Makefile | 1 + arch/arm64/purgatory/Makefile | 24 +++++++++++++++++++ arch/arm64/purgatory/entry.S | 55 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 arch/arm64/purgatory/Makefile create mode 100644 arch/arm64/purgatory/entry.S -- 2.14.1 diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index b481b4a7c011..0f0742e98c08 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -113,6 +113,7 @@ core-$(CONFIG_XEN) += arch/arm64/xen/ core-$(CONFIG_CRYPTO) += arch/arm64/crypto/ libs-y := arch/arm64/lib/ $(libs-y) core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a +core-$(CONFIG_KEXEC_FILE) += arch/arm64/purgatory/ # Default target when executing plain make boot := arch/arm64/boot diff --git a/arch/arm64/purgatory/Makefile b/arch/arm64/purgatory/Makefile new file mode 100644 index 000000000000..c2127a2cbd51 --- /dev/null +++ b/arch/arm64/purgatory/Makefile @@ -0,0 +1,24 @@ +OBJECT_FILES_NON_STANDARD := y + +purgatory-y := entry.o + +targets += $(purgatory-y) +PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y)) + +LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined \ + -nostdlib -z nodefaultlib +targets += purgatory.ro + +$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE + $(call if_changed,ld) + +targets += kexec_purgatory.c + +CMD_BIN2C = $(objtree)/scripts/basic/bin2c +quiet_cmd_bin2c = BIN2C $@ + cmd_bin2c = $(CMD_BIN2C) kexec_purgatory < $< > $@ + +$(obj)/kexec_purgatory.c: $(obj)/purgatory.ro FORCE + $(call if_changed,bin2c) + +obj-${CONFIG_KEXEC_FILE} += kexec_purgatory.o diff --git a/arch/arm64/purgatory/entry.S b/arch/arm64/purgatory/entry.S new file mode 100644 index 000000000000..fe6e968076db --- /dev/null +++ b/arch/arm64/purgatory/entry.S @@ -0,0 +1,55 @@ +/* + * kexec core purgatory + */ +#include +#include + +#define SHA256_DIGEST_SIZE 32 /* defined in crypto/sha.h */ + +.text + +ENTRY(purgatory_start) + /* Start new image. */ + ldr x17, __kernel_entry + ldr x0, __dtb_addr + mov x1, xzr + mov x2, xzr + mov x3, xzr + br x17 +END(purgatory_start) + +/* + * data section: + * kernel_entry and dtb_addr are global but also labelled as local, + * "__xxx:", to avoid unwanted re-linking. + * + * purgatory_sha_regions and purgatory_sha256_digest are referenced + * by kexec generic code and so must exist, but not actually used + * here because hash check is not that useful in purgatory. + */ +.align 3 + +.globl kernel_entry +kernel_entry: +__kernel_entry: + .quad 0 +END(kernel_entry) + +.globl dtb_addr +dtb_addr: +__dtb_addr: + .quad 0 +END(dtb_addr) + +.globl purgatory_sha_regions +purgatory_sha_regions: + .rept KEXEC_SEGMENT_MAX + .quad 0 + .quad 0 + .endr +END(purgatory_sha_regions) + +.globl purgatory_sha256_digest +purgatory_sha256_digest: + .skip SHA256_DIGEST_SIZE +END(purgatory_sha256_digest) From patchwork Mon Dec 4 02:57:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 120479 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3919841qgn; Sun, 3 Dec 2017 18:55:21 -0800 (PST) X-Google-Smtp-Source: AGs4zMbTWlKOUzJ/6hZHuaOhHK+8TrmaPMAExvZdNWsFBex2Pmv0cbs8C9kESaPOJyCZN2ov80lW X-Received: by 10.99.124.89 with SMTP id l25mr12277900pgn.86.1512356121838; Sun, 03 Dec 2017 18:55:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512356121; cv=none; d=google.com; s=arc-20160816; b=J/KIrA3u0H1pbmnDKPmfPt00lNRXDjI0cHSGTdjTlfPCtDSN2DwGR/oR3kKM75t/9j breL+N+Pb4b8utsEr5MuFVpWlofBu93Int8b534l2vCxbH+9AgYl6K5iOaZus/25y3eH 0puR1WKv5m+HYLgFIKL0QvmkOvviTkaydMFBXRhRn6MYvncPO1Q8BUGqmzhH3eZl9HPk /bhGXcaiz+/mUxjwSriErMa25T1otSaomPiLT/Xg2dZiYKxhmDrohg9AbBV3JgHJQyMU uwGqUtYqDEXMtz+cury7fTbSmvqTRMdf6ZArdJs/UBtWfnlxbYhfw47O+KTUSrS5CTeC U19w== 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=1VtlP1RPtQsx4jY6leAj9Aoyz4+vfh+gkEYKtf4tdtU=; b=EuAsymZefJWgrFFR2RApazHA8nmjxDUz/NFmXwRviyrlFd47lsgHZvEI1thegH3vEY 9bD1nWwFGEH7ZJF64PUQmvI9w25/ay4CqjSTKv/OeeN8NTmyOFO6J3lLsf0WD1UxkZlC I8NfYWANUkjMCh9biD455kCMl29z9CNHTyzuYQM3WTaz1O49+Kcekn5giHf3HEuvE7jC uMS0pOYX+mF0zV7NfzfnZD/Ityw6/xfUJRB11i6hbzMQtrn7yPrZHhIh6xNq56/oeofF 7UANIHz8cz+eaIryxII0DE2VyMvV/kifrkksW2Y7jTWYAActUH7QLxIssqA+du5stG4U R3qQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=TrLF6gd0; 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 f9si8822884plo.553.2017.12.03.18.55.21; Sun, 03 Dec 2017 18:55:21 -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=TrLF6gd0; 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 S1753223AbdLDCzT (ORCPT + 28 others); Sun, 3 Dec 2017 21:55:19 -0500 Received: from mail-pf0-f196.google.com ([209.85.192.196]:41879 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753189AbdLDCzJ (ORCPT ); Sun, 3 Dec 2017 21:55:09 -0500 Received: by mail-pf0-f196.google.com with SMTP id j28so7467613pfk.8 for ; Sun, 03 Dec 2017 18:55:09 -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=1VtlP1RPtQsx4jY6leAj9Aoyz4+vfh+gkEYKtf4tdtU=; b=TrLF6gd0RKz9yjtge1OfhiQSejIn1LIoeQBkhvW/ePN4vvONk90pxp2whmeqsepZOm H3cQ6zUKb1e5wD7LO/w+qERMn9SAzwai4q/SnAV13toKqS4OjwR6TMfvEaB8yJ74cvdk /VO//V5cIIrzt0hu40bP9K44Exy/5aph0t+Ow= 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=1VtlP1RPtQsx4jY6leAj9Aoyz4+vfh+gkEYKtf4tdtU=; b=jQavmpecCHxZFFqZhfXsA8DTOXXWFxW4B5/r7H2mI4eGgiBMDb1j2uWJSfJct3Du29 +XzMwyfXDjUx/WiklyyHMX3Xoxxz6pYnULjAc3eGKFmj+T+7DE4i5fZiLUKMIJ0B0aYv A/ozS+J9KAyUhGjBrECcxUzILdCLT/2i18f58LgR6WMF8zfLDgnddcuP/efalBr29tvJ jhO1lS0Z423CoFutpLbZ23S1rpkI9gHMBQGGZUH5kttIT3+7QP21dN5+meVqm7qjW74w YVuiMMH11SExSWFYBLcKdvb26OE8SdUh8jfN8rH6I4MH/yEOOUl4Q+HSYGtv75rvPPxP 9qkw== X-Gm-Message-State: AJaThX4i/6Bx4zyHamHM70FyDOlp6m4M+vdxtESRNXSQI0pLzffYnaAn tyVMXeH9NmDhocwuHTmRQQUPOg== X-Received: by 10.98.104.194 with SMTP id d185mr17751711pfc.155.1512356109219; Sun, 03 Dec 2017 18:55:09 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id p72sm21084096pfa.84.2017.12.03.18.55.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Dec 2017 18:55:08 -0800 (PST) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, bauerman@linux.vnet.ibm.com, dhowells@redhat.com, vgoyal@redhat.com, herbert@gondor.apana.org.au, davem@davemloft.net, akpm@linux-foundation.org, mpe@ellerman.id.au, dyoung@redhat.com, bhe@redhat.com, arnd@arndb.de, ard.biesheuvel@linaro.org, julien.thierry@arm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v7 06/11] arm64: kexec_file: load initrd, device-tree and purgatory segments Date: Mon, 4 Dec 2017 11:57:56 +0900 Message-Id: <20171204025801.12161-7-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171204025801.12161-1-takahiro.akashi@linaro.org> References: <20171204025801.12161-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org load_other_segments() sets up and adds all the memory segments necessary other than kernel, including initrd, device-tree blob and purgatory. Most of the code was borrowed from kexec-tools' counterpart. arch_kimage_kernel_post_load_cleanup() is meant to free arm64-specific data allocated for loading kernel. Signed-off-by: AKASHI Takahiro Cc: Catalin Marinas Cc: Will Deacon --- arch/arm64/include/asm/kexec.h | 22 ++++ arch/arm64/kernel/Makefile | 3 +- arch/arm64/kernel/machine_kexec_file.c | 214 +++++++++++++++++++++++++++++++++ 3 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/kernel/machine_kexec_file.c -- 2.14.1 diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h index e17f0529a882..2fadd3cbf3af 100644 --- a/arch/arm64/include/asm/kexec.h +++ b/arch/arm64/include/asm/kexec.h @@ -93,6 +93,28 @@ static inline void crash_prepare_suspend(void) {} static inline void crash_post_resume(void) {} #endif +#ifdef CONFIG_KEXEC_FILE +#define ARCH_HAS_KIMAGE_ARCH + +struct kimage_arch { + void *dtb_buf; +}; + +struct kimage; + +#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup +extern int arch_kimage_file_post_load_cleanup(struct kimage *image); + +extern int setup_dtb(struct kimage *image, + unsigned long initrd_load_addr, unsigned long initrd_len, + char *cmdline, unsigned long cmdline_len, + char **dtb_buf, size_t *dtb_buf_len); +extern int load_other_segments(struct kimage *image, + unsigned long kernel_load_addr, + char *initrd, unsigned long initrd_len, + char *cmdline, unsigned long cmdline_len); +#endif + #endif /* __ASSEMBLY__ */ #endif diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 067baace74a0..2cd982b779b9 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -47,8 +47,9 @@ arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o arm64-obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o -arm64-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o \ +arm64-obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o \ cpu-reset.o +arm64-obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o arm64-obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c new file mode 100644 index 000000000000..8300d68087d2 --- /dev/null +++ b/arch/arm64/kernel/machine_kexec_file.c @@ -0,0 +1,214 @@ +/* + * kexec_file for arm64 + * + * Copyright (C) 2017 Linaro Limited + * Author: AKASHI Takahiro + * + * Most code is derived from arm64 port of kexec-tools + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#define pr_fmt(fmt) "kexec_file: " fmt + +#include +#include +#include +#include +#include +#include + +static int __dt_root_addr_cells; +static int __dt_root_size_cells; + +const struct kexec_file_ops * const kexec_file_loaders[] = { + NULL +}; + +int arch_kimage_file_post_load_cleanup(struct kimage *image) +{ + vfree(image->arch.dtb_buf); + image->arch.dtb_buf = NULL; + + return _kimage_file_post_load_cleanup(image); +} + +int arch_kexec_walk_mem(struct kexec_buf *kbuf, + int (*func)(struct resource *, void *)) +{ + if (kbuf->image->type == KEXEC_TYPE_CRASH) + return walk_iomem_res_desc(crashk_res.desc, + IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY, + crashk_res.start, crashk_res.end, + kbuf, func); + else if (kbuf->top_down) + return walk_system_ram_res_rev(0, ULONG_MAX, kbuf, func); + else + return walk_system_ram_res(0, ULONG_MAX, kbuf, func); +} + +int setup_dtb(struct kimage *image, + unsigned long initrd_load_addr, unsigned long initrd_len, + char *cmdline, unsigned long cmdline_len, + char **dtb_buf, size_t *dtb_buf_len) +{ + char *buf = NULL; + size_t buf_size; + int nodeoffset; + u64 value; + int range_len; + int ret; + + /* duplicate dt blob */ + buf_size = fdt_totalsize(initial_boot_params); + range_len = (__dt_root_addr_cells + __dt_root_size_cells) * sizeof(u32); + + if (initrd_load_addr) + buf_size += fdt_prop_len("initrd-start", sizeof(u64)) + + fdt_prop_len("initrd-end", sizeof(u64)); + + if (cmdline) + buf_size += fdt_prop_len("bootargs", cmdline_len + 1); + + buf = vmalloc(buf_size); + if (!buf) { + ret = -ENOMEM; + goto out_err; + } + + ret = fdt_open_into(initial_boot_params, buf, buf_size); + if (ret) + goto out_err; + + nodeoffset = fdt_path_offset(buf, "/chosen"); + if (nodeoffset < 0) + goto out_err; + + /* add bootargs */ + if (cmdline) { + ret = fdt_setprop(buf, nodeoffset, "bootargs", + cmdline, cmdline_len + 1); + if (ret) + goto out_err; + } + + /* add initrd-* */ + if (initrd_load_addr) { + value = cpu_to_fdt64(initrd_load_addr); + ret = fdt_setprop(buf, nodeoffset, "initrd-start", + &value, sizeof(value)); + if (ret) + goto out_err; + + value = cpu_to_fdt64(initrd_load_addr + initrd_len); + ret = fdt_setprop(buf, nodeoffset, "initrd-end", + &value, sizeof(value)); + if (ret) + goto out_err; + } + + /* trim a buffer */ + fdt_pack(buf); + *dtb_buf = buf; + *dtb_buf_len = fdt_totalsize(buf); + + return 0; + +out_err: + vfree(buf); + return ret; +} + +int load_other_segments(struct kimage *image, unsigned long kernel_load_addr, + char *initrd, unsigned long initrd_len, + char *cmdline, unsigned long cmdline_len) +{ + struct kexec_buf kbuf; + unsigned long initrd_load_addr = 0; + unsigned long purgatory_load_addr, dtb_load_addr; + char *dtb = NULL; + unsigned long dtb_len; + int ret = 0; + + kbuf.image = image; + /* not allocate anything below the kernel */ + kbuf.buf_min = kernel_load_addr; + + /* Load initrd */ + if (initrd) { + kbuf.buffer = initrd; + kbuf.bufsz = initrd_len; + kbuf.memsz = initrd_len; + kbuf.buf_align = PAGE_SIZE; + /* within 1GB-aligned window of up to 32GB in size */ + kbuf.buf_max = round_down(kernel_load_addr, SZ_1G) + + (unsigned long)SZ_1G * 31; + kbuf.top_down = 0; + + ret = kexec_add_buffer(&kbuf); + if (ret) + goto out_err; + initrd_load_addr = kbuf.mem; + + pr_debug("Loaded initrd at 0x%lx bufsz=0x%lx memsz=0x%lx\n", + initrd_load_addr, initrd_len, initrd_len); + } + + /* Load dtb blob */ + ret = setup_dtb(image, initrd_load_addr, initrd_len, + cmdline, cmdline_len, &dtb, &dtb_len); + if (ret) { + pr_err("Preparing for new dtb failed\n"); + goto out_err; + } + + kbuf.buffer = dtb; + kbuf.bufsz = dtb_len; + kbuf.memsz = dtb_len; + /* not across 2MB boundary */ + kbuf.buf_align = SZ_2M; + kbuf.buf_max = ULONG_MAX; + kbuf.top_down = 1; + + ret = kexec_add_buffer(&kbuf); + if (ret) + goto out_err; + dtb_load_addr = kbuf.mem; + image->arch.dtb_buf = dtb; + + pr_debug("Loaded dtb at 0x%lx bufsz=0x%lx memsz=0x%lx\n", + dtb_load_addr, dtb_len, dtb_len); + + /* Load purgatory */ + ret = kexec_load_purgatory(image, kernel_load_addr, ULONG_MAX, 1, + &purgatory_load_addr); + if (ret) { + pr_err("Loading purgatory failed\n"); + goto out_err; + } + + ret = kexec_purgatory_get_set_symbol(image, "kernel_entry", + &kernel_load_addr, sizeof(kernel_load_addr), 0); + if (ret) { + pr_err("Setting symbol (kernel_entry) failed.\n"); + goto out_err; + } + + ret = kexec_purgatory_get_set_symbol(image, "dtb_addr", + &dtb_load_addr, sizeof(dtb_load_addr), 0); + if (ret) { + pr_err("Setting symbol (dtb_addr) failed.\n"); + goto out_err; + } + + pr_debug("Loaded purgatory at 0x%lx\n", purgatory_load_addr); + + return 0; + +out_err: + vfree(dtb); + image->arch.dtb_buf = NULL; + return ret; +} From patchwork Mon Dec 4 02:57:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 120480 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3919882qgn; Sun, 3 Dec 2017 18:55:25 -0800 (PST) X-Google-Smtp-Source: AGs4zMawmP+9iES2eHGGe3u9XGMd4OZa24fTvnYcqIs91zwXypeOijrB08qBno+DGaQUjt6ALvIl X-Received: by 10.99.108.66 with SMTP id h63mr12721348pgc.362.1512356125731; Sun, 03 Dec 2017 18:55:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512356125; cv=none; d=google.com; s=arc-20160816; b=XiZ1lvrKBzedjKMNpf9besL6ReEHtol0PJ5zNYRRvqTnoDYUVmB03NsnsgcOs/j+Sw SrkxatSPNIDIYSQGqpon+ac8OcZrFBfH32AdpebKapxxHsHroYdpisAXYxKXfZRb1R6L MUO3xalArYsVwWnhFlmCVLiVcuB3IdvfD+JdyGXktM4Ex4ypf6DOreoCB0mhFaAiTJBu w7o9Nkho4QWQVn/LeDFauQjl9PWcasPIbzLscBtq1WUbx+zhtXVKKTR/lZn+/Iy90IgA cBtO4TpHKIPA7/CUTdRT1HEqy04Se/BqHuydgAWLV+M0UH5muKblcgUEztdnH3Os6KDr KSpQ== 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=g1J9jn+csKdwa6G08JYz4Rh9aPgn/FhO8dy+q/XUSrE=; b=gUfbetTbP4z2YGo+Jygnvkt+rhj5Uymzky/19PnCISgNBKQlfQNNnL884vV8jvarLc Nk7OZ/Cxd1zNoVLjM66Xt95HCRCmUNbPB8qSXCYSL97a0qmH+1vj+qWG/Vyt9/UvuNDJ F9td0POk85ybZxR6Ib9Ydlv8GGHoBnBAN2Y8hX0VYsm9XZknHRFJwtr1O2BIoIt76WvF U/0xpfKlgyXlg9Veu7XcTUCCk7TqCMDrgOrEma+QRkgkgcWvh2WvtSIWjIDRq+AMNU/c 4pI3GRmpV5nTMIa/FTGMQlMSfLnY3I1pHNm9wG7DvS/1kiQzU79Y5Zo1Yc5JrFtxEeTS Dqwg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Y4xF4NZz; 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 q7si8629770pgn.232.2017.12.03.18.55.25; Sun, 03 Dec 2017 18:55:25 -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=Y4xF4NZz; 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 S1753243AbdLDCzY (ORCPT + 28 others); Sun, 3 Dec 2017 21:55:24 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:46212 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753194AbdLDCzO (ORCPT ); Sun, 3 Dec 2017 21:55:14 -0500 Received: by mail-pg0-f67.google.com with SMTP id b11so7202601pgu.13 for ; Sun, 03 Dec 2017 18:55:13 -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=g1J9jn+csKdwa6G08JYz4Rh9aPgn/FhO8dy+q/XUSrE=; b=Y4xF4NZzWfiCNCGXens5EJCq1aCGbqCNgJGjYCnH4SthVP0QHCwt1ryZKTsjInLfYf U87wfa/poG9nH1HaVRcevRY+GHFvfZhmn9+uRbV0y0eSmDPv215CqUXcJOPm9wW9Fhd3 /js6RhCdQtvZDGZqr4+TnSy0/IXrSeWokBR5c= 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=g1J9jn+csKdwa6G08JYz4Rh9aPgn/FhO8dy+q/XUSrE=; b=CdnDselUkzEDULCD8wFNKXhHI0ag922Zm/C/nXC0OugCbFz3GENkQQa3pGjloQhSEs /jjWJBVwtY/lUtmvXhyYCzxC4+wEBveR1XbBRnUMH+zPRq/a/uIykTzxj+JcIHDUsh3r 6KDKvUY9RZhoz5ksrBW/T2icLdjvWqtOusrTso2Ezt3oRSmsvdXW6U1Tcl36/DV4E9sn 9BwBx5bkazflDt/KxmCgLoOoKx8fuNXfjunFBclZQwTVD4AKxdiaQ7s7kv5RtLg3FKza RH1BhIeukszIfUDLzNhRrwCMQMawoRLvqqmmZJ7ZrcIibpWf3N7GQYPhlttXps6RL53y 2E7w== X-Gm-Message-State: AJaThX6aC4KDG8o/ftCNxOtKzjMYnAiVIGHJZAcbZFleSHW+ZZ+JuEcQ SQ4/K3d88YrgCXRK9lxzNa2mfA== X-Received: by 10.98.156.81 with SMTP id f78mr17727530pfe.211.1512356113415; Sun, 03 Dec 2017 18:55:13 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id o10sm18092534pgq.89.2017.12.03.18.55.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Dec 2017 18:55:12 -0800 (PST) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, bauerman@linux.vnet.ibm.com, dhowells@redhat.com, vgoyal@redhat.com, herbert@gondor.apana.org.au, davem@davemloft.net, akpm@linux-foundation.org, mpe@ellerman.id.au, dyoung@redhat.com, bhe@redhat.com, arnd@arndb.de, ard.biesheuvel@linaro.org, julien.thierry@arm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v7 07/11] arm64: kexec_file: set up for crash dump adding elf core header Date: Mon, 4 Dec 2017 11:57:57 +0900 Message-Id: <20171204025801.12161-8-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171204025801.12161-1-takahiro.akashi@linaro.org> References: <20171204025801.12161-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org load_crashdump_segments() creates and loads a memory segment of elf core header for crash dump. "linux,usable-memory-range" and "linux,elfcorehdr" will add to the 2nd kernel's device-tree blob. The logic of this cod is also from kexec-tools. Signed-off-by: AKASHI Takahiro Cc: Catalin Marinas Cc: Will Deacon --- arch/arm64/include/asm/kexec.h | 5 ++ arch/arm64/kernel/machine_kexec_file.c | 151 +++++++++++++++++++++++++++++++++ kernel/kexec_file.c | 2 +- 3 files changed, 157 insertions(+), 1 deletion(-) -- 2.14.1 diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h index 2fadd3cbf3af..edb702e64a8a 100644 --- a/arch/arm64/include/asm/kexec.h +++ b/arch/arm64/include/asm/kexec.h @@ -98,6 +98,10 @@ static inline void crash_post_resume(void) {} struct kimage_arch { void *dtb_buf; + /* Core ELF header buffer */ + void *elf_headers; + unsigned long elf_headers_sz; + unsigned long elf_load_addr; }; struct kimage; @@ -113,6 +117,7 @@ extern int load_other_segments(struct kimage *image, unsigned long kernel_load_addr, char *initrd, unsigned long initrd_len, char *cmdline, unsigned long cmdline_len); +extern int load_crashdump_segments(struct kimage *image); #endif #endif /* __ASSEMBLY__ */ diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c index 8300d68087d2..012b2af4e27b 100644 --- a/arch/arm64/kernel/machine_kexec_file.c +++ b/arch/arm64/kernel/machine_kexec_file.c @@ -19,6 +19,7 @@ #include #include #include +#include static int __dt_root_addr_cells; static int __dt_root_size_cells; @@ -32,6 +33,10 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image) vfree(image->arch.dtb_buf); image->arch.dtb_buf = NULL; + vfree(image->arch.elf_headers); + image->arch.elf_headers = NULL; + image->arch.elf_headers_sz = 0; + return _kimage_file_post_load_cleanup(image); } @@ -49,6 +54,78 @@ int arch_kexec_walk_mem(struct kexec_buf *kbuf, return walk_system_ram_res(0, ULONG_MAX, kbuf, func); } +static int __init arch_kexec_file_init(void) +{ + /* Those values are used later on loading the kernel */ + __dt_root_addr_cells = dt_root_addr_cells; + __dt_root_size_cells = dt_root_size_cells; + + return 0; +} +late_initcall(arch_kexec_file_init); + +#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) +#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) + +static int fdt_prop_len(const char *prop_name, int len) +{ + return (strlen(prop_name) + 1) + + sizeof(struct fdt_property) + + FDT_TAGALIGN(len); +} + +static bool cells_size_fitted(unsigned long base, unsigned long size) +{ + /* if *_cells >= 2, cells can hold 64-bit values anyway */ + if ((__dt_root_addr_cells == 1) && (base >= (1ULL << 32))) + return false; + + if ((__dt_root_size_cells == 1) && (size >= (1ULL << 32))) + return false; + + return true; +} + +static void fill_property(void *buf, u64 val64, int cells) +{ + u32 val32; + + if (cells == 1) { + val32 = cpu_to_fdt32((u32)val64); + memcpy(buf, &val32, sizeof(val32)); + } else { + memset(buf, 0, cells * sizeof(u32) - sizeof(u64)); + buf += cells * sizeof(u32) - sizeof(u64); + + val64 = cpu_to_fdt64(val64); + memcpy(buf, &val64, sizeof(val64)); + } +} + +static int fdt_setprop_range(void *fdt, int nodeoffset, const char *name, + unsigned long addr, unsigned long size) +{ + void *buf, *prop; + size_t buf_size; + int result; + + buf_size = (__dt_root_addr_cells + __dt_root_size_cells) * sizeof(u32); + prop = buf = vmalloc(buf_size); + if (!buf) + return -ENOMEM; + + fill_property(prop, addr, __dt_root_addr_cells); + prop += __dt_root_addr_cells * sizeof(u32); + + fill_property(prop, size, __dt_root_size_cells); + + result = fdt_setprop(fdt, nodeoffset, name, buf, buf_size); + + vfree(buf); + + return result; +} + int setup_dtb(struct kimage *image, unsigned long initrd_load_addr, unsigned long initrd_len, char *cmdline, unsigned long cmdline_len, @@ -61,10 +138,26 @@ int setup_dtb(struct kimage *image, int range_len; int ret; + /* check ranges against root's #address-cells and #size-cells */ + if (image->type == KEXEC_TYPE_CRASH && + (!cells_size_fitted(image->arch.elf_load_addr, + image->arch.elf_headers_sz) || + !cells_size_fitted(crashk_res.start, + crashk_res.end - crashk_res.start + 1))) { + pr_err("Crash memory region doesn't fit into DT's root cell sizes.\n"); + ret = -EINVAL; + goto out_err; + } + /* duplicate dt blob */ buf_size = fdt_totalsize(initial_boot_params); range_len = (__dt_root_addr_cells + __dt_root_size_cells) * sizeof(u32); + if (image->type == KEXEC_TYPE_CRASH) + buf_size += fdt_prop_len("linux,elfcorehdr", range_len) + + fdt_prop_len("linux,usable-memory-range", + range_len); + if (initrd_load_addr) buf_size += fdt_prop_len("initrd-start", sizeof(u64)) + fdt_prop_len("initrd-end", sizeof(u64)); @@ -86,6 +179,23 @@ int setup_dtb(struct kimage *image, if (nodeoffset < 0) goto out_err; + if (image->type == KEXEC_TYPE_CRASH) { + /* add linux,elfcorehdr */ + ret = fdt_setprop_range(buf, nodeoffset, "linux,elfcorehdr", + image->arch.elf_load_addr, + image->arch.elf_headers_sz); + if (ret) + goto out_err; + + /* add linux,usable-memory-range */ + ret = fdt_setprop_range(buf, nodeoffset, + "linux,usable-memory-range", + crashk_res.start, + crashk_res.end - crashk_res.start + 1); + if (ret) + goto out_err; + } + /* add bootargs */ if (cmdline) { ret = fdt_setprop(buf, nodeoffset, "bootargs", @@ -212,3 +322,44 @@ int load_other_segments(struct kimage *image, unsigned long kernel_load_addr, image->arch.dtb_buf = NULL; return ret; } + +int load_crashdump_segments(struct kimage *image) +{ + void *elf_addr; + unsigned long elf_sz; + struct kexec_buf kbuf; + int ret; + + if (image->type != KEXEC_TYPE_CRASH) + return 0; + + /* Prepare elf headers and add a segment */ + ret = prepare_elf_headers(image, &elf_addr, &elf_sz); + if (ret) { + pr_err("Preparing elf core header failed\n"); + return ret; + } + + kbuf.image = image; + kbuf.buffer = elf_addr; + kbuf.bufsz = elf_sz; + kbuf.memsz = elf_sz; + kbuf.buf_align = PAGE_SIZE; + kbuf.buf_min = crashk_res.start; + kbuf.buf_max = crashk_res.end + 1; + kbuf.top_down = 1; + + ret = kexec_add_buffer(&kbuf); + if (ret) { + vfree(elf_addr); + return ret; + } + image->arch.elf_headers = elf_addr; + image->arch.elf_headers_sz = elf_sz; + image->arch.elf_load_addr = kbuf.mem; + + pr_debug("Loaded elf core header at 0x%lx bufsz=0x%lx memsz=0x%lx\n", + image->arch.elf_load_addr, elf_sz, elf_sz); + + return ret; +} diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index b2c425e6afc6..0ec7181d16d9 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -1337,7 +1337,7 @@ 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 +#if defined(CONFIG_X86_64) || defined(CONFIG_ARM64) /* Prepare PT_LOAD type program header for kernel text region */ phdr = (Elf64_Phdr *)bufp; bufp += sizeof(Elf64_Phdr); From patchwork Mon Dec 4 02:57:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 120484 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3920613qgn; Sun, 3 Dec 2017 18:56:43 -0800 (PST) X-Google-Smtp-Source: AGs4zMYMbb4x+5IAF+L1h06Asqwq9WUIYn81mApncMYabuAO1i/QyrxKiwZyQsu4wIsX3wF7RdCQ X-Received: by 10.99.56.26 with SMTP id f26mr12616942pga.328.1512356203405; Sun, 03 Dec 2017 18:56:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512356203; cv=none; d=google.com; s=arc-20160816; b=CMHGX5uCPotT7pY/ySATi8+rnhzWFIgahdUxWGjdT+Jo0ZUAGNKtnkZ80c0pBpVlPd WsgFv/M4udpeBPeXc0BkWarO4gbpkN84SDGAfRMq28smrxlMYj3rxP6ruGr6xotWm3l/ likCoz/Jnq9+yR3VaekPFsOptuNwFkcCwEd4FQ5kPO7W7Fyfgu3YfpY0gIjwIRIPc5cI JC3LFeJhrYfbD5QHRofR3dDM/QUp4EjnW4J8gNZOru8G+fAd6vIOpiAWtsoursOCaQq2 DPe5Jew3DYKSz6WghZ6DbmENs3iePwXXcCyH0b2bw6Ul3JojPRaj5rxQcMKQMGuymNic jonA== 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=gIes1NT4TbQ+5KEpJOppBlHvlF5rX1DfbzTxeM6IGYw=; b=x4z1QgsOtu0Hn0QaW4FSRxVvBrC2imTWPHdUfwRZURbjQSQJiBC83qP7LKDoTu/oUp gaDkQz+t0f0MmsMdbOl+EltxYnAhr9Oi2h0olr9ZT3f8kEpzy/AtrAKqpHqpUR9/CcCM 5Vo2fwRf21uARFc4PE+Q/6i+8tdOIlmA8XP4WUbTZDT5OKboDNM35CnZgilXzWxUZ2k0 uyTw9WrsHHFM+Tbw/Dv/UhxWa+i74nCQ3I4MnUfE8w1TlgklXroFLbLZ0SjZGzMfZ6fe fFDl7WRxG/4W3d0/YOS1Jn7YO+hQHlc9acMej5IC8bi1t8fBHrTTiCc7tOszFZWjqbNZ GDeA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AOWV/v/A; 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 y22si1141222pll.476.2017.12.03.18.56.42; Sun, 03 Dec 2017 18:56:43 -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=AOWV/v/A; 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 S1753324AbdLDC4l (ORCPT + 28 others); Sun, 3 Dec 2017 21:56:41 -0500 Received: from mail-pf0-f193.google.com ([209.85.192.193]:42721 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753210AbdLDCzS (ORCPT ); Sun, 3 Dec 2017 21:55:18 -0500 Received: by mail-pf0-f193.google.com with SMTP id d23so7463383pfe.9 for ; Sun, 03 Dec 2017 18:55:18 -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=gIes1NT4TbQ+5KEpJOppBlHvlF5rX1DfbzTxeM6IGYw=; b=AOWV/v/AQkaAGlJRLqOSD9v+95xayE3c2Pej59FJ0KanR0bQJN2VU8ycZDE/o8dhJH 9GKwSmC6zFu8g2EOkyLfq+3WQpyZ6Xss0GPdvaMuzT5eYQPbm6cGuxZLYeGsYwxrlNrJ uQgGU5kF5tU0aHsPJoKP7MMW9ABmC1W6R8vzE= 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=gIes1NT4TbQ+5KEpJOppBlHvlF5rX1DfbzTxeM6IGYw=; b=nzVhMh1ro4pZ8QBTEqDLDyKcoy/tp2d+UmYYXMIZvhCxbeMIgWiv4JxBZotWp5nvkC VuETd65zdqfCjScBwtffC81ZWZttnU/SAugTwIKMzSPOl6P+SeL0j6FzFOzGc+M77tyB dSem2qiq3x9agmJhrJH4JBBHVUaL1pBpNs1rb3Ppx2AaxI3KgrMd9WdgQpcf2r69JzYN 4RkbeKBC/VaUiKnTGt0fk6XX37ytkLuDAPuNjVtnHQgB0RNPm945NRiA46PhO6DbS+RW dQlpnZVqCqmwSVZyAKB+Vcc/fTdRkNRBVT/xJNCftgmn6/Ox4EMF7yYXp0FCqTCHYU3/ Kb4A== X-Gm-Message-State: AJaThX5p3YXz3oafDFFVgFajr7WSnaTJWmsbKOlwDMAD/zMppV7C06hS 7VfrlANFoJqRRrTT2cGuRFFrcg== X-Received: by 10.159.231.22 with SMTP id w22mr12933077plq.125.1512356117972; Sun, 03 Dec 2017 18:55:17 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id s14sm23382113pfe.36.2017.12.03.18.55.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Dec 2017 18:55:17 -0800 (PST) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, bauerman@linux.vnet.ibm.com, dhowells@redhat.com, vgoyal@redhat.com, herbert@gondor.apana.org.au, davem@davemloft.net, akpm@linux-foundation.org, mpe@ellerman.id.au, dyoung@redhat.com, bhe@redhat.com, arnd@arndb.de, ard.biesheuvel@linaro.org, julien.thierry@arm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v7 08/11] arm64: kexec_file: enable KEXEC_FILE config Date: Mon, 4 Dec 2017 11:57:58 +0900 Message-Id: <20171204025801.12161-9-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171204025801.12161-1-takahiro.akashi@linaro.org> References: <20171204025801.12161-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Modify arm64/Kconfig and Makefile to enable kexec_file_load support. File-format specific hook functions to load a kernel image will follow this patch. Signed-off-by: AKASHI Takahiro Cc: Catalin Marinas Cc: Will Deacon --- arch/arm64/Kconfig | 13 +++++++++++++ 1 file changed, 13 insertions(+) -- 2.14.1 diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index a93339f5178f..865d110809f9 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -794,6 +794,19 @@ config KEXEC but it is independent of the system firmware. And like a reboot you can start any kernel with it, not just Linux. +config KEXEC_FILE + bool "kexec file based system call" + select KEXEC_CORE + select BUILD_BIN2C + ---help--- + This is new version of kexec system call. This system call is + file based and takes file descriptors as system call argument + for kernel and initramfs as opposed to list of segments as + accepted by previous system call. + + In addition to this option, you need to enable a specific type + of image support. + config CRASH_DUMP bool "Build kdump crash kernel" help From patchwork Mon Dec 4 02:57:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 120483 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3920380qgn; Sun, 3 Dec 2017 18:56:18 -0800 (PST) X-Google-Smtp-Source: AGs4zMZk4TSQQUf8pcp8rxXk/A/LOCuR2Avc717O1b3vCAz9iQ3BfvlCAFjvfqTgHzHxagaFlVUR X-Received: by 10.84.136.131 with SMTP id 3mr13195235pll.430.1512356178458; Sun, 03 Dec 2017 18:56:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512356178; cv=none; d=google.com; s=arc-20160816; b=RCwDk6QZfsELcGcpWI4SCVT8LR+2vNLt+1Lod5F2w+JLXQcTigtxuVmPHv3endP9gd +0jmG1OgQI2WfWOkG1aYkfhO3y4psE8QWRmvlSn3H17QJrEpCBD62pZ+iAKOhkvjXQNA GvV90LGEe9lRqYhvfY+hMMITelcQT3afthoYZ8LpafesK1/Be3UAAiywX7Sh7fc5BhoV 37EL+SXpIrVeclZFrRfnfYnmSLg+qSxIRj/bdYLo1/0pnQY2e6mIUc0G2Xnfyseu66oT +xMMs+G34R7boD+BEsIvL52UVe3LjA4FRESRyKCdNJET/1r+76ce55aS70a+/F+4wO26 dr6A== 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=kgH8eyD3B1m7GIDQxEIGt4HtbnePSwan1FG7QEAsfeM=; b=IKYu1HYuJvltLvxFDihHhx8PQSwmd3zZSuLrwVhZu7hRL12K1Ep1GRyze15DYemWGy kbbxllJmL6jPk78YcUykpo2GwA7liAiu4hBcy9gKWMZwZG0qXoDHVS3dFb7EFuSIXbjc BhHuy5ySCsj8k/hwoVVVxBpf88bzqLZJiMr1HUkIkTkJXaYBCkDCMctHTpJDIrgStc6u FsXU8z9C9p/ODZSQxpIjOYDSNp6O3bVM1PVZvlt7uX91QMLDJtVvWMs+STMDUye6f5wr 7mp4cYTzsOenxnIJASICpoEx9hrei5ANeU5dvTJBCDBZUxUjn2vKehAz6IkOMIL6cY8k jyFQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BArVVS5t; 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 h62si8586236pgc.764.2017.12.03.18.56.18; Sun, 03 Dec 2017 18:56:18 -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=BArVVS5t; 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 S1753301AbdLDC4Q (ORCPT + 28 others); Sun, 3 Dec 2017 21:56:16 -0500 Received: from mail-pf0-f194.google.com ([209.85.192.194]:35153 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753189AbdLDCzW (ORCPT ); Sun, 3 Dec 2017 21:55:22 -0500 Received: by mail-pf0-f194.google.com with SMTP id j124so7478331pfc.2 for ; Sun, 03 Dec 2017 18:55:22 -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=kgH8eyD3B1m7GIDQxEIGt4HtbnePSwan1FG7QEAsfeM=; b=BArVVS5tHalSvwgfM4SnA7e7mK37lBO48xy248ZhmBlq7I51gMPiCMBWYMxBP6CaSj pdivxLEZdRYJx56C9JOxesb5ig4VGuIkcUDDilOHXr9f/CZalvz5IA3f25djtMEA97Fh OwGvdgcPTGhmMqYyEj6wiKCbR/LvuxtByQ5pg= 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=kgH8eyD3B1m7GIDQxEIGt4HtbnePSwan1FG7QEAsfeM=; b=GCya1GFuNySRFXuSAW6tdwZeDbW/WzOadGPoZc4lipb5uJ/P18oj/MPqkuyJzcKQjr zam8fRP7qehHkDRE0awXHqtZy0eNkqHGwvzXSGWV0JREHdl6FKDgUfv3fzRmRCD1l7KJ VvP5COdRBxoCLp1iDpadgLSTW31B0SFXXMhIbIvIbtRB79UcgEVw90p8/bS3WEH9S0Yg kBGohl4zcZOg+kJqyYLoypQum8lZ5N0hWJPYuzylMxTX+JBweeDGgQgIQC5bhuVpasGO tZoaHV4J+A4GekAASMFtfKTAM+okMsJ6DGrWr9G464HsaHm1Szz0Qrjwob4ub+Xz0aMx H8pg== X-Gm-Message-State: AJaThX4jahkCsYb0e1zxE5pvAOrmJEkR3WBNJ4Fai9X3UhqJUbcRPObS B+j57yN0pu+7kXxIzgvVO5Agpdn+Hl4= X-Received: by 10.98.95.68 with SMTP id t65mr18008131pfb.45.1512356121858; Sun, 03 Dec 2017 18:55:21 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id s68sm22236683pfj.81.2017.12.03.18.55.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Dec 2017 18:55:21 -0800 (PST) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, bauerman@linux.vnet.ibm.com, dhowells@redhat.com, vgoyal@redhat.com, herbert@gondor.apana.org.au, davem@davemloft.net, akpm@linux-foundation.org, mpe@ellerman.id.au, dyoung@redhat.com, bhe@redhat.com, arnd@arndb.de, ard.biesheuvel@linaro.org, julien.thierry@arm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v7 09/11] arm64: kexec_file: add Image format support Date: Mon, 4 Dec 2017 11:57:59 +0900 Message-Id: <20171204025801.12161-10-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171204025801.12161-1-takahiro.akashi@linaro.org> References: <20171204025801.12161-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 "Image" binary will be loaded at the offset of TEXT_OFFSET from the start of system memory. TEXT_OFFSET is determined from the header of the image. This patch doesn't have CONFIG_KEXEC_VERIFY_SIG support. Nevertherless kernel verification will be supported by enabling IMA security subsystem. See more details about IMA here: https://sourceforge.net/p/linux-ima/wiki/Home/ You can sign(label) a kernel image binary to be kexec-ed on target filesystem with: $ evmctl ima_sign --key /path/to/private_key.pem Image On live system, you must have IMA enforced with, at least, the following security policy: "appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig" Signed-off-by: AKASHI Takahiro Cc: Catalin Marinas Cc: Will Deacon --- arch/arm64/Kconfig | 7 +++ arch/arm64/include/asm/kexec.h | 50 +++++++++++++++++++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/kexec_image.c | 90 ++++++++++++++++++++++++++++++++++ arch/arm64/kernel/machine_kexec_file.c | 3 ++ 5 files changed, 151 insertions(+) create mode 100644 arch/arm64/kernel/kexec_image.c -- 2.14.1 diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 865d110809f9..c0b021736c10 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -807,6 +807,13 @@ config KEXEC_FILE In addition to this option, you need to enable a specific type of image support. +config KEXEC_FILE_IMAGE_FMT + bool "Enable Image support" + default y + depends on KEXEC_FILE + ---help--- + Select this option to enable 'Image' kernel loading. + config CRASH_DUMP bool "Build kdump crash kernel" help diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h index edb702e64a8a..b6469bc64a89 100644 --- a/arch/arm64/include/asm/kexec.h +++ b/arch/arm64/include/asm/kexec.h @@ -104,6 +104,56 @@ struct kimage_arch { unsigned long elf_load_addr; }; +/** + * struct arm64_image_header - arm64 kernel image header + * + * @pe_sig: Optional PE format 'MZ' signature + * @branch_code: Instruction to branch to stext + * @text_offset: Image load offset, little endian + * @image_size: Effective image size, little endian + * @flags: + * Bit 0: Kernel endianness. 0=little endian, 1=big endian + * @reserved: Reserved + * @magic: Magic number, "ARM\x64" + * @pe_header: Optional offset to a PE format header + **/ + +struct arm64_image_header { + u8 pe_sig[2]; + u8 pad[2]; + u32 branch_code; + u64 text_offset; + u64 image_size; + u64 flags; + u64 reserved[3]; + u8 magic[4]; + u32 pe_header; +}; + +static const u8 arm64_image_magic[4] = {'A', 'R', 'M', 0x64U}; + +/** + * arm64_header_check_magic - Helper to check the arm64 image header. + * + * Returns non-zero if header is OK. + */ + +static inline int arm64_header_check_magic(const struct arm64_image_header *h) +{ + if (!h) + return 0; + + if (!h->text_offset) + return 0; + + return (h->magic[0] == arm64_image_magic[0] + && h->magic[1] == arm64_image_magic[1] + && h->magic[2] == arm64_image_magic[2] + && h->magic[3] == arm64_image_magic[3]); +} + +extern const struct kexec_file_ops kexec_image_ops; + struct kimage; #define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 2cd982b779b9..17906a62d795 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -50,6 +50,7 @@ arm64-obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o arm64-obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o \ cpu-reset.o arm64-obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o +arm64-obj-$(CONFIG_KEXEC_FILE_IMAGE_FMT) += kexec_image.o arm64-obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c new file mode 100644 index 000000000000..1c106237901d --- /dev/null +++ b/arch/arm64/kernel/kexec_image.c @@ -0,0 +1,90 @@ +/* + * Kexec image loader + + * Copyright (C) 2017 Linaro Limited + * Author: AKASHI Takahiro + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#define pr_fmt(fmt) "kexec_file(Image): " fmt + +#include +#include +#include +#include +#include +#include + +static int image_probe(const char *kernel_buf, unsigned long kernel_len) +{ + const struct arm64_image_header *h; + + h = (const struct arm64_image_header *)(kernel_buf); + + if ((kernel_len < sizeof(*h)) || !arm64_header_check_magic(h)) + return -EINVAL; + + return 0; +} + +static void *image_load(struct kimage *image, char *kernel, + unsigned long kernel_len, char *initrd, + unsigned long initrd_len, char *cmdline, + unsigned long cmdline_len) +{ + struct kexec_buf kbuf; + struct arm64_image_header *h = (struct arm64_image_header *)kernel; + unsigned long text_offset, kernel_load_addr; + int ret; + + /* Create elf core header segment */ + ret = load_crashdump_segments(image); + if (ret) + goto out; + + /* Load the kernel */ + kbuf.image = image; + if (image->type == KEXEC_TYPE_CRASH) { + kbuf.buf_min = crashk_res.start; + kbuf.buf_max = crashk_res.end + 1; + } else { + kbuf.buf_min = 0; + kbuf.buf_max = ULONG_MAX; + } + kbuf.top_down = 0; + + kbuf.buffer = kernel; + kbuf.bufsz = kernel_len; + kbuf.memsz = le64_to_cpu(h->image_size); + text_offset = le64_to_cpu(h->text_offset); + kbuf.buf_align = SZ_2M; + + /* Adjust kernel segment with TEXT_OFFSET */ + kbuf.memsz += text_offset; + + ret = kexec_add_buffer(&kbuf); + if (ret) + goto out; + + image->segment[image->nr_segments - 1].mem += text_offset; + image->segment[image->nr_segments - 1].memsz -= text_offset; + kernel_load_addr = kbuf.mem + text_offset; + + pr_debug("Loaded kernel at 0x%lx bufsz=0x%lx memsz=0x%lx\n", + kernel_load_addr, kbuf.bufsz, kbuf.memsz); + + /* Load additional data */ + ret = load_other_segments(image, kernel_load_addr, + initrd, initrd_len, cmdline, cmdline_len); + +out: + return ERR_PTR(ret); +} + +const struct kexec_file_ops kexec_image_ops = { + .probe = image_probe, + .load = image_load, +}; diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c index 012b2af4e27b..2b6d9164df8a 100644 --- a/arch/arm64/kernel/machine_kexec_file.c +++ b/arch/arm64/kernel/machine_kexec_file.c @@ -25,6 +25,9 @@ static int __dt_root_addr_cells; static int __dt_root_size_cells; const struct kexec_file_ops * const kexec_file_loaders[] = { +#ifdef CONFIG_KEXEC_FILE_IMAGE_FMT + &kexec_image_ops, +#endif NULL }; From patchwork Mon Dec 4 02:58:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 120481 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3919950qgn; Sun, 3 Dec 2017 18:55:35 -0800 (PST) X-Google-Smtp-Source: AGs4zMa4yp8E9YHzlvcXvvcEzpQGjgbUKETrC1Q3hXGFIQq++6nByfAuIx2SjRrRJTno6mAuBhDT X-Received: by 10.98.80.85 with SMTP id e82mr17546165pfb.87.1512356135018; Sun, 03 Dec 2017 18:55:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512356135; cv=none; d=google.com; s=arc-20160816; b=pJAG4dfb38zeVN/0kpELDSokoMRprHi7k/T6kXysjpPD2kSasuYfh2tAmih5fRMTK9 E7TxVAdkOZG0695xU0iIp50n2Jwmln1T6nM6nOWx0/YronsMzD4U0agLTI+JPFt1hZ8+ O04pysxeKSjBfzm17A1ROHjx1xtqppDy1pIslCyAONN5GbMxGoOO5mBidWZXqT3H8DPv DZ3HWaLWhHv16GHQGaJ/fuWiJKThIiTK5vF3C4XH5yAKDA+qRbrfVzzWz4lHqQ50mqlF VZCVwxx3BE2VhlhVkXjs3IgiWGBcqpSXdM72/qpX20YOQCJnRSUHpdyR/er1stb0nFbM 7KPA== 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=fVNkswW2F9Q2QI2ZTaY0vlW/IrEbCVf8dY1cNKokZF4=; b=zsKw++unoymYPgaiSKHEb+5wMhSzQw3M98dY3GmBrebJ5A65yy0XDbkU3OZxjDj6Xx OViWw7k7HCC6Ut8lVy925DBnqgBWJEEicHlAQNYUVMFba6ZMqnB2GRzDyZF4KIPaaA4V K1gwSl1VzUQijeQH7rGkYvsbzlaOmg1l2M8jHeLrNvL7pg0sJIEjHkyKXiDBC0zcYrxL JvfwZjK5rMcK+ib+FxnTbaBcZR4TYTmN96hYxStDATYnXq2AeoRsZ8+Uwd6J1IRXAE/p /HobY9koXYlWyt7szbphC6m/R7u0eDiuCWuZ8KHoyogdmGuS/pSCge1kUE1eF8hLkRpv IwHQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=atVlg/cp; 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 i35si1460748plg.614.2017.12.03.18.55.34; Sun, 03 Dec 2017 18:55:35 -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=atVlg/cp; 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 S1753262AbdLDCzd (ORCPT + 28 others); Sun, 3 Dec 2017 21:55:33 -0500 Received: from mail-pf0-f196.google.com ([209.85.192.196]:45457 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753194AbdLDCz0 (ORCPT ); Sun, 3 Dec 2017 21:55:26 -0500 Received: by mail-pf0-f196.google.com with SMTP id u19so7469585pfa.12 for ; Sun, 03 Dec 2017 18:55:26 -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=fVNkswW2F9Q2QI2ZTaY0vlW/IrEbCVf8dY1cNKokZF4=; b=atVlg/cp2DWGIvEAlghtAtkegOb5g8F3QeKRVymkA1Q/cQlqUh8v+CU5zoBeP4wAfz bv0Q8SOODS44fCXH80+stzem1pLF/07Q/GRoqm8pAUTXXJFJ8SOSMbdQZwjxVnn22aqk x+BLsfiLGI0VJTWIwAJUJn7QGccUXPlM8J7CQ= 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=fVNkswW2F9Q2QI2ZTaY0vlW/IrEbCVf8dY1cNKokZF4=; b=cQEe2A8+O174zGeUsJPilVaQrQ29h8vgzf7U0j0bch0Z0Tp2JgX+saNQZtexbz7FYc FE9m4jjU0qBbGY+OfsCnQOgljxZyVVmRGoq+4lq76Ybqz/7zBc+ZYo2SXF1LbtPTxe2J v62Wqf/cueB0oyw80hQ74IcIBpVX+NuAkuL7hXd1g4iSzc8QE4KPN42M62ZsKJn1fWP1 Yn57hYKSJYRh8TMrEuBZh/aTphuUUgnjkmaIGfUgnC7LMDcT7Xv9U2z8BNdPZF8/iWGo cNOLXCDUokQleWhTxTYfKs/k9LhQJ+3MBhsPSC1rpWto5ce5NGqiHfl6g6oV/DEr5s3O yatA== X-Gm-Message-State: AJaThX5V3sLa0lwS5nH7WVgr77AoSp7VV3qD1WsM8fcnKzRs+DrgDa1u 59wx2INsSUm287jW5CJVzHadPQ== X-Received: by 10.101.98.83 with SMTP id q19mr12298942pgv.71.1512356125775; Sun, 03 Dec 2017 18:55:25 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id x15sm18645991pfh.27.2017.12.03.18.55.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Dec 2017 18:55:25 -0800 (PST) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, bauerman@linux.vnet.ibm.com, dhowells@redhat.com, vgoyal@redhat.com, herbert@gondor.apana.org.au, davem@davemloft.net, akpm@linux-foundation.org, mpe@ellerman.id.au, dyoung@redhat.com, bhe@redhat.com, arnd@arndb.de, ard.biesheuvel@linaro.org, julien.thierry@arm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v7 10/11] include: pe.h: remove message[] from mz header definition Date: Mon, 4 Dec 2017 11:58:00 +0900 Message-Id: <20171204025801.12161-11-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171204025801.12161-1-takahiro.akashi@linaro.org> References: <20171204025801.12161-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org message[] field won't be part of the definition of mz header. This change is crucial for enabling kexec_file_load on arm64 because arm64's "Image" binary, as in PE format, doesn't have any data for it and accordingly the following check in pefile_parse_binary() will fail: chkaddr(cursor, mz->peaddr, sizeof(*pe)); Signed-off-by: AKASHI Takahiro Reviewed-by: Ard Biesheuvel Cc: David Howells Cc: Vivek Goyal Cc: Herbert Xu Cc: David S. Miller --- include/linux/pe.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- 2.14.1 diff --git a/include/linux/pe.h b/include/linux/pe.h index 143ce75be5f0..3482b18a48b5 100644 --- a/include/linux/pe.h +++ b/include/linux/pe.h @@ -166,7 +166,7 @@ struct mz_hdr { uint16_t oem_info; /* oem specific */ uint16_t reserved1[10]; /* reserved */ uint32_t peaddr; /* address of pe header */ - char message[64]; /* message to print */ + char message[]; /* message to print */ }; struct mz_reloc { From patchwork Mon Dec 4 02:58:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 120482 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3920224qgn; Sun, 3 Dec 2017 18:56:02 -0800 (PST) X-Google-Smtp-Source: AGs4zMZOq1EOOVjJ1tFd3uMBYsPQc9oWy7el/JW2qddy8L/Cy6QcOLNbkHJeJwckAJ5bn5sjkgSk X-Received: by 10.84.196.131 with SMTP id l3mr13046083pld.194.1512356162844; Sun, 03 Dec 2017 18:56:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512356162; cv=none; d=google.com; s=arc-20160816; b=hekYZPBCrc9DXgEW+BKJpUHOQDdrDMf/PtZfW/R9C+ADUnY/q5ameZKdvhVOHM4dII IsOV5td9ZyGqvsjA6jvn0tZEYKl+dJAdjJmCzQyt2felOU42jXVNjm8KLtnNg2El0Ici T6+w5R+8NmhBRhxwpVtZBEl9Lyp2UH9h7NdiwHUWPzbzYp2dyPuCKOYm+B1gU5nGbu5E OCTPEgrvqMQn7Ib7saEGsP7l8JALz9IilSkb1ifj05gPEC6ZJZpdk8q37gNkW6N2aQiL n7V6RytLau4tVsjL2Uer4n0WnZJHJkDTf4E7Qe7rlkUY8blWCR87OXuV+rUbN5mItVf5 8abg== 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=sCm+IZSF+5l8rR3IkQ0bBKGpYawqXAbN2wz6j7SCo+g=; b=wrY/ZIWSYkTvQ0HYtJQiVfkvkEtdMJEqJvTQIU2NYHkZYscOdKK37GC/pLlSvl2YpZ YUWv9knHRtKcqh4LrcSF4BPH3blcnQWTFmjfR7djxEGw6pHgV3gAuK5jbEDCJTqdaJLF bfGMyOnDG+s2MALlVuDvfD0FZtApr8AlwoAnsmDqXw+UPrkbEVsf8XkWoTvki9fRiS2K JGFVx9PwI+D95bUDcVfoQMFQyQudHyCr9KVUb7rCe65vMqUMsmJJU8kKZZTYvfw0Q0ps GQ2mnd2ZmPWbpGP8ofRhc8TufA/PEdnseifLlTc4Rky1CGZr5l7/iNaAtuUZJGWaYR3J 3pMA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FcIieWWm; 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 l81si9481109pfb.91.2017.12.03.18.56.02; Sun, 03 Dec 2017 18:56:02 -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=FcIieWWm; 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 S1753051AbdLDC4A (ORCPT + 28 others); Sun, 3 Dec 2017 21:56:00 -0500 Received: from mail-pg0-f68.google.com ([74.125.83.68]:36276 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753244AbdLDCza (ORCPT ); Sun, 3 Dec 2017 21:55:30 -0500 Received: by mail-pg0-f68.google.com with SMTP id k134so7217746pga.3 for ; Sun, 03 Dec 2017 18:55:30 -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=sCm+IZSF+5l8rR3IkQ0bBKGpYawqXAbN2wz6j7SCo+g=; b=FcIieWWm1j5dIxMQWmaNYEiq/cUtovzDJoEVCcrhjV4R2i4wNAI3+EGnIfFVVasZyv v34R17usIY7KdcHLcXSw3PvigxBZX79My8//7UjcrhA/wW1Yx35Tex3maHZSZB9vDG66 husT64Yyyn+BNCJnbcUX8JW3dr/rGnp4yIIzo= 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=sCm+IZSF+5l8rR3IkQ0bBKGpYawqXAbN2wz6j7SCo+g=; b=I6JUJa7ze9HU6VoVvI6a2crtkAebBRB3HLDtH5l2eFslldfrwGy3emHVx+Wrtf2AD2 h3ujqTl/6EJaB0JsMV+iDXyyyo6o5u934VYrQ4aOhU6jOSDd/hZFR11/ciXZz6dGVJP9 yJAjQsxUXWAAX8D61t8rbmUNj2C1k3V8LZB/DcSwtuTRl1D+s+PyIsoOSMPyb6ywhndZ 4xRrKPdyQ4xRKVuNNBUVjwaMhrYC7eBEve9TwUzzvWl1WuHBUxXl8fT8KEM3MTA850bg sdBJnZ0g458kSzowLArizwZQ8rRvugbqARd6UfBXLSQPY2FXv8A4LmEbJZmvpagGcWQI UFMA== X-Gm-Message-State: AJaThX7oijGVryi6id10yYY+t6vJLT25jdALeLY/6HLu5ctFJ6h9dZQl Xki7npnFmorzd/nDEPpb2fHn8A== X-Received: by 10.99.108.66 with SMTP id h63mr12721441pgc.362.1512356129586; Sun, 03 Dec 2017 18:55:29 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id i187sm21775305pfc.96.2017.12.03.18.55.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Dec 2017 18:55:29 -0800 (PST) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, bauerman@linux.vnet.ibm.com, dhowells@redhat.com, vgoyal@redhat.com, herbert@gondor.apana.org.au, davem@davemloft.net, akpm@linux-foundation.org, mpe@ellerman.id.au, dyoung@redhat.com, bhe@redhat.com, arnd@arndb.de, ard.biesheuvel@linaro.org, julien.thierry@arm.com Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH v7 11/11] arm64: kexec_file: enable KEXEC_VERIFY_SIG for Image Date: Mon, 4 Dec 2017 11:58:01 +0900 Message-Id: <20171204025801.12161-12-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171204025801.12161-1-takahiro.akashi@linaro.org> References: <20171204025801.12161-1-takahiro.akashi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org With this patch, kernel verification can be done without IMA security subsystem enabled. Turn on CONFIG_KEXEC_VERIFY_SIG instead. On x86, a signature is embedded into a PE file (Microsoft's format) header of binary. Since arm64's "Image" can also be seen as a PE file as far as CONFIG_EFI is enabled, we adopt this format for kernel signing. You can create a signed kernel image with: $ sbsign --key ${KEY} --cert ${CERT} Image Signed-off-by: AKASHI Takahiro Cc: Catalin Marinas Cc: Will Deacon --- arch/arm64/Kconfig | 10 ++++++++++ arch/arm64/include/asm/kexec.h | 16 ++++++++++++++++ arch/arm64/kernel/kexec_image.c | 15 +++++++++++++++ 3 files changed, 41 insertions(+) -- 2.14.1 diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index c0b021736c10..289c7bede593 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -814,6 +814,16 @@ config KEXEC_FILE_IMAGE_FMT ---help--- Select this option to enable 'Image' kernel loading. +config KEXEC_VERIFY_SIG + bool "Verify kernel signature during kexec_file_load() syscall" + depends on KEXEC_FILE + select SYSTEM_DATA_VERIFICATION + select SIGNED_PE_FILE_VERIFICATION if KEXEC_FILE_IMAGE_FMT + ---help--- + Select this option to verify a signature with loaded kernel + image. If configured, any attempt of loading a image without + valid signature will fail. + config CRASH_DUMP bool "Build kdump crash kernel" help diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h index b6469bc64a89..2a63bf5f32ea 100644 --- a/arch/arm64/include/asm/kexec.h +++ b/arch/arm64/include/asm/kexec.h @@ -131,6 +131,7 @@ struct arm64_image_header { }; static const u8 arm64_image_magic[4] = {'A', 'R', 'M', 0x64U}; +static const u8 arm64_image_pe_sig[2] = {'M', 'Z'}; /** * arm64_header_check_magic - Helper to check the arm64 image header. @@ -152,6 +153,21 @@ static inline int arm64_header_check_magic(const struct arm64_image_header *h) && h->magic[3] == arm64_image_magic[3]); } +/** + * arm64_header_check_pe_sig - Helper to check the arm64 image header. + * + * Returns non-zero if 'MZ' signature is found. + */ + +static inline int arm64_header_check_pe_sig(const struct arm64_image_header *h) +{ + if (!h) + return 0; + + return (h->pe_sig[0] == arm64_image_pe_sig[0] + && h->pe_sig[1] == arm64_image_pe_sig[1]); +} + extern const struct kexec_file_ops kexec_image_ops; struct kimage; diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c index 1c106237901d..b840b6ed6ed9 100644 --- a/arch/arm64/kernel/kexec_image.c +++ b/arch/arm64/kernel/kexec_image.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,9 @@ static int image_probe(const char *kernel_buf, unsigned long kernel_len) if ((kernel_len < sizeof(*h)) || !arm64_header_check_magic(h)) return -EINVAL; + pr_debug("PE format: %s\n", + (arm64_header_check_pe_sig(h) ? "yes" : "no")); + return 0; } @@ -84,7 +88,18 @@ static void *image_load(struct kimage *image, char *kernel, return ERR_PTR(ret); } +#ifdef CONFIG_KEXEC_VERIFY_SIG +static int image_verify_sig(const char *kernel, unsigned long kernel_len) +{ + return verify_pefile_signature(kernel, kernel_len, NULL, + VERIFYING_KEXEC_PE_SIGNATURE); +} +#endif + const struct kexec_file_ops kexec_image_ops = { .probe = image_probe, .load = image_load, +#ifdef CONFIG_KEXEC_VERIFY_SIG + .verify_sig = image_verify_sig, +#endif };