From patchwork Fri Sep 8 03:16:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 111998 Delivered-To: patch@linaro.org Received: by 10.140.94.239 with SMTP id g102csp939657qge; Thu, 7 Sep 2017 20:15:17 -0700 (PDT) X-Received: by 10.98.79.157 with SMTP id f29mr1612667pfj.9.1504840517521; Thu, 07 Sep 2017 20:15:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504840517; cv=none; d=google.com; s=arc-20160816; b=cqOj4iZmdP50+uwsdLNb1TLbE03QNSPAIw1FvM6rNwA7w8rkYLe6n+gVuzcpTiN7L/ nfyzZXhhuq4T7QyUPTLmPFKj/KwwhvTG5PBx+HfNOWuFThb1ElIUziQmcyb50K0I+h71 N05bz56PAG2Eqjtfqc8PxomesqQjiH8byyqkYuNekd67LetvOU3o9V6o2+GjLViplw8P cconUqMa4XDd0GKFU/RU9tza8LEyvyCsRMHQphrov9izIS6b5FfSADgKDOgCnyctoB0i 9Ie5XeRSnDpguDLFHOkq5v8VstN9cVkc1MZAeYVa4wwrESWsimynNFeR4nWbuw158xAH Rq/Q== 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=l1tnzYtMdvu57RQwBEkmc/w41fsiU8kih3dqNTi6qfMetzXzTHrhAS1+zArMlWNldS UjgwCa/WyJoSVmtiEDNV4F242/Dq6MUQ8yxBbrrymRrQEwFeVN9C+eGEPwJ0Xgmwep/T vnwEAdYOvigisWh1+VClMQYuw2MQWGAF9ipLOTP4uPcsAQiPWyY5KBSmSxirxMvkgi+S 8LfTgJ7Da1y5xWySVPzvFBQB4WZClc/BE/GwRxGnQa5oW3y5qJRsEEB0UP7Z/8sIgK9J zIXid4MfosqMK0er/k1v6Cty1LmW++BWzl59pAcJrumuP/c7/gs/XDJlm5hGRVwxTBEQ bSPQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UVuutmYg; 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 w76si346354pfi.609.2017.09.07.20.15.17; Thu, 07 Sep 2017 20:15:17 -0700 (PDT) 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=UVuutmYg; 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 S1754187AbdIHDPD (ORCPT + 26 others); Thu, 7 Sep 2017 23:15:03 -0400 Received: from mail-pf0-f181.google.com ([209.85.192.181]:35061 "EHLO mail-pf0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754133AbdIHDPA (ORCPT ); Thu, 7 Sep 2017 23:15:00 -0400 Received: by mail-pf0-f181.google.com with SMTP id g13so2548140pfm.2 for ; Thu, 07 Sep 2017 20:15:00 -0700 (PDT) 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=UVuutmYgb38KJeGlT/mw6Lc0PeD+YjsEIYh35ghtkJCz2W7oBUVgIfHKVkHq5oNw3i o2eDdeoxJ2KC9w72+ZGrvYUhGNu7Jx8/trrObZ5gGkLQCOOzvVf3CtHp8o4fMELHuV+y 6orJa1zvmS2NKIVpbQDX8v9dIbCk57KHPCxSs= 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=Pug6fBanh/hJeKCUb4pK75luEnNAkmiWWcK9KzwAADCq5eRt1G2jIkevJRlLcxSpr6 i2YO+5p3qZrASrVED5XJiz/rdWHvsEqgC/o2l7ip2SaOdvXSimlL/52Bb3xZ+0Q4bvIM DH7IpjWAck0UnGweHHWRZ5C+dAzP6iLKJq0DkN4KV6p8IPP/aZQY4Z/FbVDW4c/qH4mx 9nGFBZZrXumDN4ILyhFVHDwZzY96OIsttjeC/wpOUyY4DCjiZZStErtxVMAPqyf8mSNs bXTXArgQuXxayNyZi1E2o5nYqEGgi6a+bDaSM6E8IrKo/UAt2OJUz7j93TCmJZQry3Mu rnJg== X-Gm-Message-State: AHPjjUgQKEqYk87r7mqHN0TSyisvBcfnJQlhRTlxiBwDRyQc6HBDQPOm GOCgxcl3xUXqFA3T X-Google-Smtp-Source: ADKCNb58+KK7PUsWB5i05hgR0/vttUqMUauv1P93Hm7c2Dx5P/ACr8HzcAdNX+5mUP1sUefU4Jdjtw== X-Received: by 10.84.231.202 with SMTP id g10mr1692028pln.407.1504840500195; Thu, 07 Sep 2017 20:15:00 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id y68sm1198795pfk.145.2017.09.07.20.14.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Sep 2017 20:14:59 -0700 (PDT) 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 Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH 1/9] include: pe.h: remove message[] from mz header definition Date: Fri, 8 Sep 2017 12:16:08 +0900 Message-Id: <20170908031616.17916-2-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170908031616.17916-1-takahiro.akashi@linaro.org> References: <20170908031616.17916-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 Fri Sep 8 03:16:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 111999 Delivered-To: patch@linaro.org Received: by 10.140.94.239 with SMTP id g102csp939665qge; Thu, 7 Sep 2017 20:15:18 -0700 (PDT) X-Received: by 10.84.216.75 with SMTP id f11mr1806244plj.236.1504840518135; Thu, 07 Sep 2017 20:15:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504840518; cv=none; d=google.com; s=arc-20160816; b=r7+Qr2tpFHLFY+/8bFoquA9jxhxLapkWzcDmlQLSr9tBQHoniaG0Zz0QgdsFIN/7YB Qk8Re5sAJtOsceKVIlyfgSLKY33Wn1W/WUlBUqOa1V+PVwW6FaKw1SgnZbsmmZDBMiAL laUz47tQHYABWYk4ekL+q65NIIoBDKw+N3+fZwX9mlQyqOcnyTznSffDnM8pfRJMWkEQ qIBnSaEuTg3SoJtQG6y/C7+QPg6QpFEGc9Cw1O1upcnzrSu2n0A8CqxXd9lYy51SYiBI NPO2uZ3kV6aDhKq1WSGw8GxqLC5xvU/U7sE36rd4ain+NGjGHOmHy2UjZZv6GszV65BQ iDEw== 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=Ni1zv4TS4KemAcbZg/ZChqjjHLQWmaU1Iruz6cZLyuY=; b=VcQv6wwOVnoEx5vy1y9h20B0Q2lQgP8fqeQyLpCSzjEAAf6TCU3/STDtK9pErCXaH2 n98xXIfWqgmWz1K5h6iFS6uFIuUSbK0ahXsWeMhZpNjrI/ti3+2rRx/j+Yf1q8Q717fB GAtCFm7IIeF6Qs7VbW6lQAUUHYsSUbBBhPyP1fF4Pcl+GHmoyKMk7Mm1V4BhIHRt0/US tdiE1dJ3juAvCZhBYYgVUYi5IO9x446XSlovd8XvSI5u5izwzVVXUKtlKmhTm/86/j2S jiAfq+CWDImj0dJiwzRshQ7V8ZWNtaOybnpSYJk4wIHF9UVBsYXFrPlP/JmtCoei6riu gyGA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=TLB3E5I9; 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 w76si346354pfi.609.2017.09.07.20.15.17; Thu, 07 Sep 2017 20:15:18 -0700 (PDT) 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=TLB3E5I9; 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 S1754245AbdIHDPK (ORCPT + 26 others); Thu, 7 Sep 2017 23:15:10 -0400 Received: from mail-pg0-f43.google.com ([74.125.83.43]:33289 "EHLO mail-pg0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754133AbdIHDPH (ORCPT ); Thu, 7 Sep 2017 23:15:07 -0400 Received: by mail-pg0-f43.google.com with SMTP id t3so2792199pgt.0 for ; Thu, 07 Sep 2017 20:15:07 -0700 (PDT) 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=Ni1zv4TS4KemAcbZg/ZChqjjHLQWmaU1Iruz6cZLyuY=; b=TLB3E5I9DsnzrvST1PN+1ao5M8Ez1tXS5Z3Btwg3WWh622MYr5SjF9M5KN8g8SXEMs TXuVdFzXZ/yVTSmgt9IJ/ttv4A5joEq1iGVTUKCFM/o1n0/kBwE0XDFQqes2Ky47atup jonHffxXzv2ISIu4DTCvOnfVJwP/NknQ0kWk0= 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=Ni1zv4TS4KemAcbZg/ZChqjjHLQWmaU1Iruz6cZLyuY=; b=R7v5N4HWVTmL0V26PreCFUcfAs83iBhbrgKEL1o3vgnozpTp1ZaeoIzeSTIjBvx/WA vBEYe31Ikw6VSy76bFLLa3Y6C8DJu0sXukjs42uP+3ZuSFxW95WqremvHZQukhojKcyC IOFxfG4CeJsFckHKEVbmF7ovyr4taUllD4o0rF8dlbkVeNQ+fzSLscY1rEnYJ+7Fb4F/ 27ZgNepLkcQJi09iOtoW9L93cMR/1sFXq1LkAysCkFoub6xiR35CsoTgqMClWR5Omj4t X7WFSnFZxiUPw6mHpcbtTvKx3Qs3PM4W8y8buPv+KL/HLWlmiM+t3qTSuoaf+lfQZAA3 t4kg== X-Gm-Message-State: AHPjjUiTyWXTpMvYSif1SUBtNbHSfWpb21luQD2luc7hT3jsIowbp8pI m+wvuyLiuenzJ30L X-Google-Smtp-Source: ADKCNb6xkkeLUjNHhkSUqxF/Z8M4fWW0s1qgPwVArnb6tdh5KLOQQaqLmbG1NKcCeCw5SzDN0sbtkg== X-Received: by 10.84.132.2 with SMTP id 2mr1726952ple.381.1504840506704; Thu, 07 Sep 2017 20:15:06 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id u31sm996106pgn.70.2017.09.07.20.15.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Sep 2017 20:15:06 -0700 (PDT) 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 Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro , Linus Torvalds Subject: [PATCH 2/9] resource: add walk_system_ram_res_rev() Date: Fri, 8 Sep 2017 12:16:09 +0900 Message-Id: <20170908031616.17916-3-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170908031616.17916-1-takahiro.akashi@linaro.org> References: <20170908031616.17916-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 | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) -- 2.14.1 diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 6230064d7f95..9a212266299f 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -271,6 +271,9 @@ extern int walk_system_ram_res(u64 start, u64 end, void *arg, int (*func)(u64, u64, void *)); extern int +walk_system_ram_res_rev(u64 start, u64 end, void *arg, + int (*func)(u64, u64, void *)); +extern int walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end, void *arg, int (*func)(u64, u64, void *)); diff --git a/kernel/resource.c b/kernel/resource.c index 9b5f04404152..572f2f91ce9c 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include @@ -469,6 +471,63 @@ int walk_system_ram_res(u64 start, u64 end, void *arg, return ret; } +int walk_system_ram_res_rev(u64 start, u64 end, void *arg, + int (*func)(u64, u64, void *)) +{ + struct resource res, *rams; + u64 orig_end; + int count, i; + int ret = -1; + + count = 16; /* initial */ + + /* create a list */ + rams = vmalloc(sizeof(struct resource) * count); + if (!rams) + return ret; + + res.start = start; + res.end = end; + res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; + orig_end = res.end; + i = 0; + while ((res.start < res.end) && + (!find_next_iomem_res(&res, IORES_DESC_NONE, true))) { + if (i >= count) { + /* re-alloc */ + struct resource *rams_new; + int count_new; + + count_new = count + 16; + rams_new = vmalloc(sizeof(struct resource) * count_new); + if (!rams_new) + goto out; + + memcpy(rams_new, rams, count); + vfree(rams); + rams = rams_new; + count = count_new; + } + + rams[i].start = res.start; + rams[i++].end = res.end; + + res.start = res.end + 1; + res.end = orig_end; + } + + /* go reverse */ + for (i--; i >= 0; i--) { + ret = (*func)(rams[i].start, rams[i].end, arg); + if (ret) + break; + } + +out: + vfree(rams); + return ret; +} + #if !defined(CONFIG_ARCH_HAS_WALK_MEMORY) /* From patchwork Fri Sep 8 03:16:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 112000 Delivered-To: patch@linaro.org Received: by 10.140.94.239 with SMTP id g102csp939769qge; Thu, 7 Sep 2017 20:15:26 -0700 (PDT) X-Received: by 10.98.157.73 with SMTP id i70mr1586487pfd.268.1504840525907; Thu, 07 Sep 2017 20:15:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504840525; cv=none; d=google.com; s=arc-20160816; b=a0B6sqpMkeGRLlWN1qbmCU91lmQUHKRs1HRnMeJfSqBiTS1XluiHbvTGTzZ9txsY1v 59pHBG06D7dYGUaclQa3fJJ9hklK1gVOIz7NylU2h5PkOTl0U5fWfcAZtLN8Xr9l5nCr 0bvj/1fEBXPB8ZyuGgfRhCxMoEZE2aOaapDiNZPqaf8P3FwVGZXAfOwJTq+efQ+t94Nb YaaQdh36HIPBf5PXtsJmRgOIjqlZO2YGe4k5L+ugn8/ePlXTRy9l3FN2cPEChlXY1NZg yBE8jJCtNfsj30+8WQuTWap9aUwgvfA5TSpqtrdbHZk+NUTcZmm6x3i9RD7dLk1wimVv /tZQ== 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=ZrfOMBd1U2xAPU1Pxz339I5kFLeEqbbIis2tsZrlK8w=; b=eEi4ZkrUx55d/kqelf+mmFWW9+iONmCFdeQVqxDUjXAnCoWVMDQiQbKbPv4wp3Agvh BD9NKBk5e0TuThvxKRitVk6f/Nko08pdn4Z5KV4FUP6b6jZlOw354bSOBNPzVdUYdH52 HUUYBDFrH3on8SPCEYCS9DJor7kiwGIdM59c0KdhjQVSEkZnRdhawbr63GkEuz4EE4NO IF6+MwduXfs52ndZG2SjOxRjDii+/KY+DIysS2dUgMtfHikEshScXMGNZxO/crlbuCjI bwRQ7KCihc/J+wM3+oZhGL30at4G60C7UodK1VA/gMXJ3uU6aleMk1BE1KlLX5g/YyLq t/6g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=N5gqMeSj; 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 i2si74920pgo.496.2017.09.07.20.15.25; Thu, 07 Sep 2017 20:15:25 -0700 (PDT) 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=N5gqMeSj; 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 S1754327AbdIHDPU (ORCPT + 26 others); Thu, 7 Sep 2017 23:15:20 -0400 Received: from mail-pf0-f176.google.com ([209.85.192.176]:33326 "EHLO mail-pf0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754255AbdIHDPR (ORCPT ); Thu, 7 Sep 2017 23:15:17 -0400 Received: by mail-pf0-f176.google.com with SMTP id y29so1777273pff.0 for ; Thu, 07 Sep 2017 20:15:16 -0700 (PDT) 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=ZrfOMBd1U2xAPU1Pxz339I5kFLeEqbbIis2tsZrlK8w=; b=N5gqMeSj2kGcl5BN2Be0kSeTFg4IPj1KTWISIWrYbUa8woaKhdeIOXzklU+8RiGumx ws5B4HKOfYcj2/pIBKNYK9J/m910hg4ipKmdA42mDClKyCSc0Txd7SBB/Lx6XYUgFU0W z1XHSqODrIIPnRlHiyiKCj7PnYexl9dyHKgnQ= 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=ZrfOMBd1U2xAPU1Pxz339I5kFLeEqbbIis2tsZrlK8w=; b=PMuEqUHCjKBPbm6G7+ScqK9U/DOAGSUnRRMouGVE1C14oO/fugpKSQd0JVfWbHjT3p +FNYyssLPLx6zoxvOjcbUPkpE2H+MuO5pxscEFMFhsfjbWLKrjwpLmUCPzRYGC8vw6ns hUGwjILh1cq47mMprycRQrFX/pBJPHpJ8/RPoxxJMUHoRMCp4RDmrxeBcISucuCC0e1C QhmkZQnLXws4SkMIHo+TGGS73d18JFCTATbZIcC9AKDozOidyTJhsz8k5wFImFTmYSVj aO59CAwyT3jkSErCcEMQiYJtgWb0JdXhxb8ZJlVjvT0hIlpjc/5NJJdOrcaYtAsHkc/E ze9g== X-Gm-Message-State: AHPjjUhVPLIcalqgZEyeHyqncSdfsXcM4+IoEIDCfiia71T1+wdAfdKT rqB7J4RgakUaUxWX X-Google-Smtp-Source: ADKCNb72rBt6GSAFgfO9Qtdu1reGfbEIgyZpidVPQRmMVrts6NJMJ5gCIEZuukG7rLy60XIKBgS6nQ== X-Received: by 10.99.115.93 with SMTP id d29mr1626878pgn.333.1504840516500; Thu, 07 Sep 2017 20:15:16 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id f5sm1235326pfg.128.2017.09.07.20.15.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Sep 2017 20:15:15 -0700 (PDT) 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 Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH 3/9] kexec_file: factor out crashdump elf header function from x86 Date: Fri, 8 Sep 2017 12:16:10 +0900 Message-Id: <20170908031616.17916-4-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170908031616.17916-1-takahiro.akashi@linaro.org> References: <20170908031616.17916-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 | 19 +++ kernel/kexec_file.c | 329 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 348 insertions(+), 324 deletions(-) -- 2.14.1 diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 44404e2307bb..3c6b880f6dbf 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(u64 start, u64 end, 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(u64 start, u64 end, 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, start, 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 dd056fab9e35..65897af3125c 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -162,6 +162,25 @@ int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf, int (*func)(u64, u64, void *)); extern int kexec_add_buffer(struct kexec_buf *kbuf); int kexec_locate_mem_hole(struct kexec_buf *kbuf); +#ifdef CONFIG_CRASH_CORE +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_CRASH_CORE */ #endif /* CONFIG_KEXEC_FILE */ struct kimage { diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 9f48f4412297..20565eae6bd5 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" @@ -1021,3 +1026,327 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name, return 0; } + +#ifdef CONFIG_CRASH_CORE +/* 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; +}; + +static int get_nr_ram_ranges_callback(u64 start, u64 end, 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(u64 start, u64 end, 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, start, 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; +} +#endif /* CONFIG_CRASH_CORE */ From patchwork Fri Sep 8 03:16:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 112001 Delivered-To: patch@linaro.org Received: by 10.140.94.239 with SMTP id g102csp939801qge; Thu, 7 Sep 2017 20:15:28 -0700 (PDT) X-Received: by 10.99.98.131 with SMTP id w125mr1630930pgb.214.1504840528207; Thu, 07 Sep 2017 20:15:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504840528; cv=none; d=google.com; s=arc-20160816; b=IsQNgj9jGKJ99GvbNvTbEkTAO+C+I5IqEE0nQA0i+ChDdhK/edHvmn+uKbGiwBR4cG Gkw5qROrcsElS06NzGF9dZeVisa4qQS3QyAzy2mifCSbjmj1b889LMY5NiISMP35iocS n1XHyrzGrniI+g85q1ugJ2MSsA2gjp7mg8mLiUWWHhw4O68BgorJ7dTTMdHgOjGdqd0C sp4hEDvmZSBL2oxAjPKEYJyDR/dGfhAHtM7esSIp8o6jp8FX3tdqi3SoRI6W4RgCdiAl KUyuaR3KopLTLoDEoL5fvDZIn/yL0O6DTPM4BeX+dXibEgeFieZ5ovippO4aGd4DS+AS Ib6w== 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=XQ2hfwuqOxZtO/79mPkNiInqsdauHyfcRiwhgMReb/c=; b=r1RkuLKiM1vvr/jCMic7BdKNl1ntPDZjvhuGtJRZXZSjy9BCYGDsJKGb0y67PYvIEl idjBfgRR1hNDBolKfhkY9uHXmgvw1viA4HgL1Jhg8eTBNJ205DSl0DCxGYo4hDCBeZgs NzCCEAR6NNAawMEBqZf7lIwIKZvYToZSEZ4Pi3aXOJPDnkqS1AcxTq6wQ/24/cuQhDg6 3vhjkAfgo1p5lpo3QcGid8EkYiebxvRn4gwZ48pC2s8sLIqdV8LajFcNlUHBsbZReGy4 FLnHOf1q/snbNiLoMl9RocE6C8YtQUW+NFRuc9EtvtN5lpE2ZUZwCT7GgVD8Q6lMJDir 5AIg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=g6jihWYQ; 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 n9si805110plk.34.2017.09.07.20.15.27; Thu, 07 Sep 2017 20:15:28 -0700 (PDT) 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=g6jihWYQ; 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 S1754382AbdIHDPY (ORCPT + 26 others); Thu, 7 Sep 2017 23:15:24 -0400 Received: from mail-pf0-f180.google.com ([209.85.192.180]:33339 "EHLO mail-pf0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753804AbdIHDPV (ORCPT ); Thu, 7 Sep 2017 23:15:21 -0400 Received: by mail-pf0-f180.google.com with SMTP id y29so1777552pff.0 for ; Thu, 07 Sep 2017 20:15:21 -0700 (PDT) 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=XQ2hfwuqOxZtO/79mPkNiInqsdauHyfcRiwhgMReb/c=; b=g6jihWYQ7YB97et1lIHP24BQtQNDk+z35RLU50oc3l3ea0d3iJSofyZmO7en8NsG1S pW1kdJBOSXnb874oBbux7DqeUPAPxSZmxxK1E08IcRaqTvAaocbRi5PswLURjgf1FMed r5/PTpimzHeuXUzkgVq0ea5If1tlYij0G4Cso= 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=XQ2hfwuqOxZtO/79mPkNiInqsdauHyfcRiwhgMReb/c=; b=ewVbF0zZ3gd/wUO6kh/oi39I+49DKeOZit9YbgkQYAIBvmEnntGMfkXG5z376a8q+9 +G/1qM4exkWzVN1oDXa15t+t3h/n7/FnHYFSvr9lwh4ytmuVyOeh4dzE/8FgUdTubpft Whb4oSJcu0d0hTtjcepsBRXMSlgYHVYhMSKlzR4UZ7fBNHLt6MeJb6v0ZnOlU+zkQE3s h9dc5LzzrM3CUlSYrAMW1j3nVKGr5LKP8Ye3L3lOY2aEOP3QMRMxvJdIKLQDsNjkJRxv VeHYNo1Twb2Tf9hj+L7WTPfX1hL3DJyO0/PFBiZlpR3hzw+uU6MW+77i3lZvSjsAk8oZ baTA== X-Gm-Message-State: AHPjjUjo+3/sat5PmZstNH7MiXV2vrsA/cHjMhJugmvZbZRlg8keq5BN jTHiE5JiraQHrNXV X-Google-Smtp-Source: ADKCNb753r09A02Elz/xfE14oxcOUKuGEYNaTL4sHDnvOGRRUJJtnOyHt+DxxGjahHe18AgWbS4zBw== X-Received: by 10.84.179.67 with SMTP id a61mr1745609plc.230.1504840521132; Thu, 07 Sep 2017 20:15:21 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id b1sm976275pgn.55.2017.09.07.20.15.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Sep 2017 20:15:20 -0700 (PDT) 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 Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH 4/9] asm-generic: add kexec_file_load system call to unistd.h Date: Fri, 8 Sep 2017 12:16:11 +0900 Message-Id: <20170908031616.17916-5-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170908031616.17916-1-takahiro.akashi@linaro.org> References: <20170908031616.17916-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 061185a5eb51..086697fe3917 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -731,9 +731,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 Fri Sep 8 03:16:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 112002 Delivered-To: patch@linaro.org Received: by 10.140.94.239 with SMTP id g102csp939872qge; Thu, 7 Sep 2017 20:15:33 -0700 (PDT) X-Received: by 10.98.252.150 with SMTP id e144mr1657265pfh.148.1504840533767; Thu, 07 Sep 2017 20:15:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504840533; cv=none; d=google.com; s=arc-20160816; b=OMbot6BqHZY4ENak1bi4lEyXT6e6sPIr8tBrqB6NZ8DfgmZAB4kQ7Le/rJNwELGZYb bH0GXR+EQgD0sxpFTe97+HplKicwNa3Ka6sV2kS6r5SXoNa+BJGRiSqXtPE4J6qT/6i9 RIBRX2wR/jrVv2VF6mbi8YctERk2HEI8PnYj0PdzblAsGoJIxgBjx1j+A8HkaltdeEjw vSrAhzT4NDGvtKI5Pr2c8Ih4pFKiOOee1bBOP5E5NwV2QvcuoeRzmoWODwy7tV2zqQ7H LAMMBcUe5G8OEERAV/Kb2tei+oIMGgmKwDNu9qWZu9C2iJLHdJOa1+OcEiOspAHJh4RA eNCQ== 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=NSjHwXn+tfTD758pxg7Zazb8a28hjhqimLLE7KC9lkg=; b=OHD4qc4nBv2Ed6cX0Wtl3IpoKWKV9sUxUuav21XQsrP7jEhYEa3fARe2PwUdy371PM nGMB4m6tKQFhUKJiEN9W0Wi+n+5uwhr8CmfD8bRnOgBlxyGKgh1MU5ZS8XM980D05hAE RL0SSnmOktuR4Eafk1P9GykmOxQfjHMfsXTCCNwWnIrUl1lEmxCjtR9DjVEaoXPSwLHG CMDCPNjlDsw6N7NJ78BVPfPY9hMEH/GkR8kWaBxxrYz2oLmXTVpTmnDPYs6GQDFXiqx+ nz1E+083IH+ppHWGRVME6/B5doIKkNmi1GYa96Jhif7QCFQC2i7GaO25M0g2w/g9mhbI x5mw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=H7N3/nJU; 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 n9si805110plk.34.2017.09.07.20.15.33; Thu, 07 Sep 2017 20:15:33 -0700 (PDT) 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=H7N3/nJU; 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 S1754434AbdIHDPa (ORCPT + 26 others); Thu, 7 Sep 2017 23:15:30 -0400 Received: from mail-pg0-f46.google.com ([74.125.83.46]:36985 "EHLO mail-pg0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753804AbdIHDPZ (ORCPT ); Thu, 7 Sep 2017 23:15:25 -0400 Received: by mail-pg0-f46.google.com with SMTP id d8so2760834pgt.4 for ; Thu, 07 Sep 2017 20:15:25 -0700 (PDT) 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=NSjHwXn+tfTD758pxg7Zazb8a28hjhqimLLE7KC9lkg=; b=H7N3/nJUjfoax+Fs3sJwtqJh5iXyBPPIC6VqDWGscz5CKUTliOaj/fz6hsXrtODMGF A1MdcYy8nQuQWORb2o2bMaNPvWtXDH2jmKuLVH6yHLTaSvgX7hSJBq3fpKzz/jFaUlmO t5e98LNYZWiMWzRWYISCfXSagtrrWtFaBwORw= 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=NSjHwXn+tfTD758pxg7Zazb8a28hjhqimLLE7KC9lkg=; b=jRtWCX2weFKwCzi1RTR4TCNtK8RfBP2C2wPrMldaWJjHND1GuMk8UWj92SSr09JCiQ 4E3kItg5mppg3slJpL5xdaYY6vTNWWIbGGdRoahB7yGsF9rHLhCbBW7lWHy2bsjzQQWb lOJAUYf5yTKJB01qAIJEBXW+YHJ4DrcXhTBf3BJOVv3ppC/eE9eMJ4rCsxghBxx0jhAT aDoIeEI8rOHJtqwJBQpDQerbYBBvfSvmbB4RmcSVN+NPW/clNy7GwGbg2CO1Mo34ia1S aXx/7ZV0dAHGGRTTWettE85HxS1+VaYZ0DbNVxAXQfrJ5P87g4fJZf1GbjkpKzPHsl2x Zc8Q== X-Gm-Message-State: AHPjjUh873MK5uWJA7PIWeQ2cUsZlSClsPxTNaK/yty7CXlpiD52swiB +bYxcsCtv+OLykuS X-Google-Smtp-Source: ADKCNb6LGkoIQuZpQ/i8LKgwiiIUYbGutPvFhANcv0rN9QzDJTiBEdZrqXQBGZU9RX1t0dRpKxIBlA== X-Received: by 10.98.149.68 with SMTP id p65mr1543562pfd.301.1504840525121; Thu, 07 Sep 2017 20:15:25 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id y6sm1225074pfg.150.2017.09.07.20.15.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Sep 2017 20:15:24 -0700 (PDT) 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 Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH 5/9] arm64: kexec_file: create purgatory Date: Fri, 8 Sep 2017 12:16:12 +0900 Message-Id: <20170908031616.17916-6-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170908031616.17916-1-takahiro.akashi@linaro.org> References: <20170908031616.17916-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. Signed-off-by: AKASHI Takahiro Cc: Catalin Marinas Cc: Will Deacon --- arch/arm64/Makefile | 1 + arch/arm64/kernel/Makefile | 1 + arch/arm64/purgatory/Makefile | 24 +++++++++++++++++++ arch/arm64/purgatory/entry.S | 55 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 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 9b41f1e3b1a0..429f60728c0a 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -105,6 +105,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/kernel/Makefile b/arch/arm64/kernel/Makefile index f2b4e816b6de..16e9f56b536a 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -50,6 +50,7 @@ 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 \ 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/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 Fri Sep 8 03:16:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 112003 Delivered-To: patch@linaro.org Received: by 10.140.94.239 with SMTP id g102csp939918qge; Thu, 7 Sep 2017 20:15:38 -0700 (PDT) X-Received: by 10.84.131.111 with SMTP id 102mr1747177pld.98.1504840538822; Thu, 07 Sep 2017 20:15:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504840538; cv=none; d=google.com; s=arc-20160816; b=K8e8cR44VO2zTIEkHI9rmaNtsVEmDh6VN632+GHyiXa9MLdYk+L9VN+pMCjXEDhup4 0hzjAVIRQ7ksFHUNBwPgOVnxCNjIxdisxf83sea/yEhWORtry/hdnN5p2wL/Nk8qYvpI qGFqHgi/kxbQYaQpSSJcVlVmXgCF86VwKaBrGlFMl+Pndg2z4dGVDoU3r8iruZNiGIRC PduoiUs261lcv9uhL7opAwqSj7GcHBgaKfWLjO3+F/v8hILkm2dF8TNRw90I3yUrp8EG FXB+6rRRo8lh3B2w8Grs6fs8FEJvPw7t9SWd0zZlfpg1ehFJF5DWNJwv7dlZMRvX02QK TNNw== 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=dhR4mPCFMuzIMI40YJiAekWEI+Wo60pz6i5/anuWF3o=; b=0peOPaV9fzJa3sdcUGKBJ24jtJqa2W5OGTJ14BghyykowhfqTwqbspzz8WiIGZf4O4 DLYF2hnIuMeCuas7QDXiwMYpgmvTKv2Kufi1FYL+8CaTldgWnNp4UE6rpnu+XXPirSHL z+d2XuWMMuCRa6CSYkx73+9I7LpiTPZaYlBEGkst1oJLOPgBdMpw7mm+ujxA3NGSb3QU KZ8V/ivrL/RcVe25xZou1wcqTgVJpKFxYDwgf1gqpCMpPoC5YByqyh8qwU7fiSCv53CI y29engv/3n4xjwWPJ5XInD2Fd9S6eMxTmvfnhOhokj/wG7Z5HLCuA3OL+xch1akzXvR+ p0qw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KxLj79UI; 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 n69si808100pfk.442.2017.09.07.20.15.38; Thu, 07 Sep 2017 20:15:38 -0700 (PDT) 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=KxLj79UI; 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 S1754481AbdIHDPe (ORCPT + 26 others); Thu, 7 Sep 2017 23:15:34 -0400 Received: from mail-pf0-f175.google.com ([209.85.192.175]:34803 "EHLO mail-pf0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754411AbdIHDPa (ORCPT ); Thu, 7 Sep 2017 23:15:30 -0400 Received: by mail-pf0-f175.google.com with SMTP id e1so2559563pfk.1 for ; Thu, 07 Sep 2017 20:15:29 -0700 (PDT) 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=dhR4mPCFMuzIMI40YJiAekWEI+Wo60pz6i5/anuWF3o=; b=KxLj79UIpgUR1F2eoT6c9fiYdKXyaiq5a5ni0QG1GhYIxW5YinBifO2vaDZlPiE6Eg kF+e31fpSuUTlyXPAMoKe/FfZmpg8AMD8iccdfddUpawXKdNioNxj2810R/ohmpHn5Oi F2mwmJt2ft6N6JcVZ6qds+ikYSgmeKTTmcz9c= 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=dhR4mPCFMuzIMI40YJiAekWEI+Wo60pz6i5/anuWF3o=; b=J7ky+sY/cIhNdveS+4+BdCM7fmUzGlWowlskm07w1CcPKXdmsfRF9TrK33dI+n7WEj 6+Ebky4Cf+SQmeV1HNdMuB0GxJeld1ewPC2uprAkasMNQ5/VG5v5SUCZT/JweyWzRstj jAMXmSEwd4rjxrQhVRaRTbZJBvhGs0eq5UC4CfjEOefVI6hV998koOdkXHscJTUXHO1g Mg41BdHN5KWpjvz9DIG8eoifsRTzMu/qLJcMjWsuhTuq8BGOzOQinQaQC+OdNoTjJNrp R13ziHhk827ZOVkijGpRZUT6WkaTJGkVsKp+9W5rB4MsLszkjxnddPpXSw3en45mTzqO NTBw== X-Gm-Message-State: AHPjjUjWs5RgJfUkTx2YVcpNpLRupeZF1J6zH2uRZO12Nl2LCOEdLGiY r20EeUcm1vIp32r7 X-Google-Smtp-Source: ADKCNb5BOlfdbp1h+Y1wULovGlC6XIbdobF9Gl6dJABR0L8Oscee+9ECjbiHHwI8oLpsTRLl1zOgSg== X-Received: by 10.98.67.134 with SMTP id l6mr1593460pfi.165.1504840529147; Thu, 07 Sep 2017 20:15:29 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id t2sm1331025pfe.85.2017.09.07.20.15.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Sep 2017 20:15:28 -0700 (PDT) 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 Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH 6/9] arm64: kexec_file: load initrd, device-tree and purgatory segments Date: Fri, 8 Sep 2017 12:16:13 +0900 Message-Id: <20170908031616.17916-7-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170908031616.17916-1-takahiro.akashi@linaro.org> References: <20170908031616.17916-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. In addition, arch_kexec_image_probe(), arch_kexec_image_load() and arch_kexec_kernel_verify_sig() are added as stubs for supporting multiple types of kernel image formats. Signed-off-by: AKASHI Takahiro Cc: Catalin Marinas Cc: Will Deacon --- arch/arm64/include/asm/kexec.h | 19 +++ arch/arm64/kernel/machine_kexec_file.c | 264 +++++++++++++++++++++++++++++++++ 2 files changed, 283 insertions(+) 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..d74dc49670ad 100644 --- a/arch/arm64/include/asm/kexec.h +++ b/arch/arm64/include/asm/kexec.h @@ -93,6 +93,25 @@ 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; + +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/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c new file mode 100644 index 000000000000..a6d2c006b4f7 --- /dev/null +++ b/arch/arm64/kernel/machine_kexec_file.c @@ -0,0 +1,264 @@ +/* + * 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 +#include + +static int __dt_root_addr_cells; +static int __dt_root_size_cells; + +static struct kexec_file_ops *kexec_file_loaders[0]; + +int arch_kexec_kernel_image_probe(struct kimage *image, void *buf, + unsigned long buf_len) +{ + struct kexec_file_ops *fops; + int i, ret; + + 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 0; + } + } + + return -ENOEXEC; +} + +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) +{ + 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; + + 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.\n"); + return -EKEYREJECTED; + } + + return image->fops->verify_sig(kernel, kernel_len); +} +#endif + +int arch_kexec_walk_mem(struct kexec_buf *kbuf, int (*func)(u64, u64, 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 Fri Sep 8 03:16:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 112004 Delivered-To: patch@linaro.org Received: by 10.140.94.239 with SMTP id g102csp939952qge; Thu, 7 Sep 2017 20:15:42 -0700 (PDT) X-Received: by 10.98.60.220 with SMTP id b89mr1587429pfk.82.1504840542339; Thu, 07 Sep 2017 20:15:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504840542; cv=none; d=google.com; s=arc-20160816; b=gW2792XR/uJhYlUv3QjsXXhvgq1abiT/B6EKV2pBvnOPKw2rddeQfNDZcH0hAID0xD FzToW92LG6K+iAHqGAz+vbKAXObYxYy5n69PS1uw90EaEBQVzT9S6n2pUk/n4MOCmaUD jsAuKCUukOj7bMdFHcq4U0L24UC4wf7LrXm7VHvKgblrEjjZc3QCpfGcV1i8awho0P0U qkiYmuTza0GzRbK3LZ35PZqdBg2aIQg52Yt9DO35cq23nuqgZfk8n8GQ1bHyl1ZqLbvM CNPtA97/XR5jhCzXKUZpDQHhWMUAOYYcm5cLPbE0s+xqFRkBwwaAwcIwqVW1FWqLEJn3 m0YQ== 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=ZO7Txyt9h+yWUlN5tfcJbAmZdgMn7tCdFjqhxBDNmTM=; b=y91d4lSUGTDjk0iBf6VCE06yq08XQIxq6B4rFNuBY/GJnuYW73lWM0OSHxaUSqLe0c v1A7bIJiwn9KHY0qS4e/D6yDrkxx1gHlZin1B2uLb/qNjtALYXjrjMV28iuQmVQHQyLU fzjzzWPdKj/OjcnA2Sdd/n2npW2iAVRZcb3Tas61F3r1SH20/I14uZa56gE7hzEEJQ0b zMtEBfYDOoCCIDya8EIcQ7X2BX/fMC1dL0j49FyjQqIct7UmO1LCgOojnVwLP50P6VDK SMy98x5aTP0QA89SSTJGy1Y2mtUpuIvLv+AOdarLb5IvFvuxy2P18AcrQXOh6qpvBlUn 82Zg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=LlTsNIB9; 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 n69si808100pfk.442.2017.09.07.20.15.42; Thu, 07 Sep 2017 20:15:42 -0700 (PDT) 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=LlTsNIB9; 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 S932169AbdIHDPj (ORCPT + 26 others); Thu, 7 Sep 2017 23:15:39 -0400 Received: from mail-pg0-f51.google.com ([74.125.83.51]:34901 "EHLO mail-pg0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753804AbdIHDPg (ORCPT ); Thu, 7 Sep 2017 23:15:36 -0400 Received: by mail-pg0-f51.google.com with SMTP id 188so2774686pgb.2 for ; Thu, 07 Sep 2017 20:15:35 -0700 (PDT) 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=ZO7Txyt9h+yWUlN5tfcJbAmZdgMn7tCdFjqhxBDNmTM=; b=LlTsNIB9GlqJrNRxpgNlYcE0FuaLO8snkDOjdqz6OisLwO8FpYksMMT5OnHkd2vYEF im0/dbcVVs+ArAfreHlsXWyYWttYyJ924oz7S9bPc8WGfo2uyKVxaNMZAMXOygw40yfY 3G1qJ8iWFSw2Y3BXX1WZFqGo+7qoJjsdDEz9w= 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=ZO7Txyt9h+yWUlN5tfcJbAmZdgMn7tCdFjqhxBDNmTM=; b=A06l0o99SMznZqPsW4zEajVHeaHSg+k0Cpgg7H1OXPrc2OUiTL1hSc5q2A4WNtauaZ PlBuYJ+kWwgiPvJTmQ1H+9Qf1ic8bAGMb7VWAR9pyfFzzWIA58CcKqOGnlBqad8IhcFs llv09E+Q5xQ10ESRR7Cf/2UzFMURrMd4wn6ygjF/JyYd/iKzFVFy5nT0M0YgL/D9sasO vFu60XCFCP7CmbfbpIRxg70+YWZsjgzBEYsWzz3TM3gzLhtsDyceeT6rV1g+BDWMRAoc k+FCxtGtLqUDQYBHvTaZNf5kDNErJZp6FJOtdX1xCRUpwiPHWJwbxuoVopaEX513VdMO /nAQ== X-Gm-Message-State: AHPjjUgjlu86ePMXGBg+Kv0oyWAk/1Ofs4Wf+peR7Xgt/1r57JoXRL9F 44/jizVtdh/MWp3K X-Google-Smtp-Source: ADKCNb6yPmuBRjnU3zqsZVWj58VsL7ueOc0WDB/cLkCSsHYVrLhvq+2WbEinF5ESEhtj7mSW8OQUyw== X-Received: by 10.84.216.69 with SMTP id f5mr1744342plj.212.1504840535506; Thu, 07 Sep 2017 20:15:35 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id m87sm1279013pfi.122.2017.09.07.20.15.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Sep 2017 20:15:35 -0700 (PDT) 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 Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH 7/9] arm64: kexec_file: set up for crash dump adding elf core header Date: Fri, 8 Sep 2017 12:16:14 +0900 Message-Id: <20170908031616.17916-8-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170908031616.17916-1-takahiro.akashi@linaro.org> References: <20170908031616.17916-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 | 145 +++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) -- 2.14.1 diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h index d74dc49670ad..66537de588fa 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; @@ -110,6 +114,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 a6d2c006b4f7..62627f5440ff 100644 --- a/arch/arm64/kernel/machine_kexec_file.c +++ b/arch/arm64/kernel/machine_kexec_file.c @@ -99,6 +99,77 @@ int arch_kexec_walk_mem(struct kexec_buf *kbuf, int (*func)(u64, u64, void *)) 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; + int i; + + if (cells == 1) { + val32 = cpu_to_fdt32((u32)val64); + memcpy(buf, &val32, sizeof(val32)); + } else { + for (i = 0; i < (cells * sizeof(u32) - sizeof(u64)); i++) + *(char *)buf++ = 0; + + 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) +{ + u64 range[2]; + void *prop; + size_t buf_size; + int result; + + prop = range; + buf_size = (__dt_root_addr_cells + __dt_root_size_cells) * sizeof(u32); + + fill_property(prop, addr, __dt_root_addr_cells); + prop += __dt_root_addr_cells * sizeof(u32); + + fill_property(prop, size, __dt_root_size_cells); + prop += __dt_root_size_cells * sizeof(u32); + + result = fdt_setprop(fdt, nodeoffset, name, range, buf_size); + + return result; +} + int setup_dtb(struct kimage *image, unsigned long initrd_load_addr, unsigned long initrd_len, char *cmdline, unsigned long cmdline_len, @@ -111,10 +182,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)); @@ -136,6 +223,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", @@ -262,3 +366,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; +} From patchwork Fri Sep 8 03:16:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 112005 Delivered-To: patch@linaro.org Received: by 10.140.94.239 with SMTP id g102csp940023qge; Thu, 7 Sep 2017 20:15:49 -0700 (PDT) X-Received: by 10.99.144.68 with SMTP id a65mr1642214pge.429.1504840549202; Thu, 07 Sep 2017 20:15:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504840549; cv=none; d=google.com; s=arc-20160816; b=vq7xrdRnT6SlOXlkeKOwUfX/wbp8gyyHkpSwYbmS8skusZoMJxRWVjHTwFnj82B9Yc +T7GZrER6zEVqQimZ7S4AUJT0CvKIoY1tk0wV0o82DlIECeUy7WpS2xHCrQLjzW4DiPH w/mmfagcHu+BcY+jTjHip2AaGowCjb5NulmDjxUhv0v4l8f7qp0B0RmrsauZcHi1zqOz 4jREeFDZmGjwSPuRsdhmHzPwyyNFlKwn4ZMEkVS11bRJaekY367UN+Ol0JtpCnskZ+R8 MWNcXRHIEG1+aSFphui4SoTRC2XTkr9vim5ts8CPs2NbCQ/tppkPdcKuUJmuP7xGNipD YWmg== 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=KqX0BsMbS9Cv2qoFihcQ2IXSLBOMtvB0eXUfuPBhk9o=; b=gUlMSibgNIMgdF34yE/ntoNaY1PyfWzs/fOFn1gl+i56VXTUpJjB9s9eQ8MbXwg86O T4NnTzHbTROjKl48cC1tytW1Wj9BQMXypcOp4hs5U7rTVrvZx5h0KTromV0rEBXe4fXh vK4zUtPUdj83/PvGy0+Issabk1A88v6Ap6LJcHu4//c+X5Ic84A/bTvLfmqdYH5IXmQL H/StLupckFM22qeRQui5iOizf7FnqUzQePwSJ4UFiDdxbWDVzriio7L2XHCcZuSNU31I R6N6wR6NtOjjn2+jHLURRKEPJyDSF9CXqEpmHm4C1K8yG6+IyZeCRDsgKh78F/dY3+38 psmw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=WsL6K5GY; 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 9si854774ple.632.2017.09.07.20.15.48; Thu, 07 Sep 2017 20:15:49 -0700 (PDT) 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=WsL6K5GY; 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 S1754541AbdIHDPp (ORCPT + 26 others); Thu, 7 Sep 2017 23:15:45 -0400 Received: from mail-pg0-f49.google.com ([74.125.83.49]:38698 "EHLO mail-pg0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753052AbdIHDPk (ORCPT ); Thu, 7 Sep 2017 23:15:40 -0400 Received: by mail-pg0-f49.google.com with SMTP id v66so2747285pgb.5 for ; Thu, 07 Sep 2017 20:15:40 -0700 (PDT) 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=KqX0BsMbS9Cv2qoFihcQ2IXSLBOMtvB0eXUfuPBhk9o=; b=WsL6K5GYhcqPw5/PzWWQv/sGOMbhs8xkl0pC1WNDr6ffG91o76G8zmMbt7J2/5WAmm XUyoXBVezczLPdZVJMxQ1hiL++uZQNxx8g2HXur2oTGvYLHZs44p6hHKM5Rt9QfwnVid oryr9Gf3LUzYHuabYdf+CgfxazedGZyTvyPvk= 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=KqX0BsMbS9Cv2qoFihcQ2IXSLBOMtvB0eXUfuPBhk9o=; b=hEzxt7js4XPiRdw3MGyduwrqok4TF0nhUZWegCNGnzvbRnqTCfDBoGi0clJkKWtECG uylnJR1FAzyIVIDleR0hy20H615HzhV/5EeejyP5dwh71vfuE94tGxXqCYPlTGcTUXkD ER6DARSU2a+/rRHCfVe2ygyURcETvT85iXjPHnx/c2QzmsUjW6Ko+0kzKXksCcEG222n vtHXrIXZ47xL0jdTP5ZjSFKJQM42OBc3KWQCH+q6ZrYScrOqriQqun7Yq9tQ4fE6l7v6 dGznmF7agnxyR0FcvUJX8ttCxQ5QPCo0ca9pRtEy/1OXC7iARJH+YOkAMz7x4zpSUbku iH9Q== X-Gm-Message-State: AHPjjUja3oFfrTdKBTt9/FrqrZbJHQJiqgF8aE0Z/6XC2Bv/sAAz6t+t wZA0WjEfFuTM5bnp X-Google-Smtp-Source: ADKCNb4Z9912LTCIG9bF04xy0ym/55l+2lFlzgr6PqceV+QCLIwKVnVNpuagMuWdvBnAQUuPKnd3YQ== X-Received: by 10.84.216.69 with SMTP id f5mr1744544plj.212.1504840540347; Thu, 07 Sep 2017 20:15:40 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id b68sm1334670pfk.23.2017.09.07.20.15.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Sep 2017 20:15:39 -0700 (PDT) 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 Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH 8/9] arm64: enable KEXEC_FILE config Date: Fri, 8 Sep 2017 12:16:15 +0900 Message-Id: <20170908031616.17916-9-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170908031616.17916-1-takahiro.akashi@linaro.org> References: <20170908031616.17916-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. Signed-off-by: AKASHI Takahiro Cc: Catalin Marinas Cc: Will Deacon --- arch/arm64/Kconfig | 22 ++++++++++++++++++++++ arch/arm64/kernel/Makefile | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) -- 2.14.1 diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index dfd908630631..fa7299f08cc6 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -756,6 +756,28 @@ 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 KEXEC_VERIFY_SIG + bool "Verify kernel signature during kexec_file_load() syscall" + depends on KEXEC_FILE + select SYSTEM_DATA_VERIFICATION + ---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/kernel/Makefile b/arch/arm64/kernel/Makefile index 16e9f56b536a..5df003d6157c 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -48,7 +48,7 @@ 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 From patchwork Fri Sep 8 03:16:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 112006 Delivered-To: patch@linaro.org Received: by 10.140.94.239 with SMTP id g102csp940080qge; Thu, 7 Sep 2017 20:15:53 -0700 (PDT) X-Received: by 10.84.172.131 with SMTP id n3mr1767243plb.408.1504840553313; Thu, 07 Sep 2017 20:15:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504840553; cv=none; d=google.com; s=arc-20160816; b=WttMHZQ/WYE/1INVcoWNlQ/Emui6XKtJICLkHrRtB4YTATsWWfdDkh1WlEG1an3jWB ZA/Nelkhv9MHrDsv7MPjYOnubvaD/xfVdoUUPcUp0/QmbjP0p0D5RYce0HMpPLwSe6YU I0bYzWV4sH7rf0YHIgAi8H1ad0ugoPGszJkLisA31s01AvHOri8BK7q/n267GlMKhGMq fTsBKnIXPpq/YSueq9durWAg4tiP9Z2zBSw01Wz6hoy8QVQwLHcL8VKaja1ct1+/Frsw 6wtqD9X/bKagsfWO5PjInmYbn40g9ZspCKvq9ir13xbHvwuzBfFmjNnHbg65ArBaSSWD ZpJg== 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=oHZiYDvbRu87XG2jeZxitcwBQTDCvUZUfLTXHf2E5CE=; b=HxjsNDMNiwvGup/JTHclBJikE+Vs9g1nibF6WM1SUb4ja+Fj9tTBIOBL7lAyTXVXGQ 2vVmAV/oPT92qWi7Lo/c1cjp5qoszNIgSLQr9KvQuMm8RqNYw06l9yV6C1/QwfRrG25I KpTrmy8Ij3j8kywo31oSGmtqYLcsz2D9/C/NNkPXjO/ZOfJHnr26a7mX5Grbq3wdRX0w NsOyNIQDX1RBBSu1RbSJ63ZzGjBDEkSrSO6nRk6hQ7s0mT7HlZoONreOpmukp5tf+1T6 zEwD88VnylBGUvI90JssBdJn2dmE361uYl02L0yBmViPE3qazdKspGCZV7gwiENP6f55 4PBw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=SKV5joVl; 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 9si854774ple.632.2017.09.07.20.15.51; Thu, 07 Sep 2017 20:15:53 -0700 (PDT) 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=SKV5joVl; 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 S1754570AbdIHDPs (ORCPT + 26 others); Thu, 7 Sep 2017 23:15:48 -0400 Received: from mail-pg0-f54.google.com ([74.125.83.54]:37042 "EHLO mail-pg0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754532AbdIHDPp (ORCPT ); Thu, 7 Sep 2017 23:15:45 -0400 Received: by mail-pg0-f54.google.com with SMTP id d8so2762000pgt.4 for ; Thu, 07 Sep 2017 20:15:45 -0700 (PDT) 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=oHZiYDvbRu87XG2jeZxitcwBQTDCvUZUfLTXHf2E5CE=; b=SKV5joVlsrdXNFG98Gse5tf6ZrJQhpsnGQLQeRnXWMtNhyRG1t7i4hO7Lo9XygqW8t /X4MNTNFiZGlrgdW2+FvGJtKBJhLnG/yL6X+A0JJXiA5JuuLh6bnPCZKG8bIjKtmmXrE JhnT1JamFvBGj6P3QoapSlMV1BcldAD1iLSlQ= 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=oHZiYDvbRu87XG2jeZxitcwBQTDCvUZUfLTXHf2E5CE=; b=RjcDc3jUqTrzT6Zn6Hf2HG098/+D9ETLin0LC7hm5ag/ADmylC+AiFpewlA5YA1CWj IbSCoPGHvcHHdduBbubDkPQnbYiLqskfGvjLFEWCBmU69TH9ayvMYmLJYzALVgSuTP5L HFh/4jnX9MMZIATH+jgvHZFrcZTOBUp2Y9avh5EQLsbRvezT2GfNPxrqJBPyse+lvrn8 wxX/5w6CcwZzohC+DerDG4OVNEsUvL9u51AJ0iLCKpVPRYpk0yEF3yyF1bV1UKhIKxoC 38waqqAw1qh+YI5+f5VqtDkGLnUBidM3taw4sfFssoxEyKZ2v/0Xn4TQrqWjmWcgv3/b urFg== X-Gm-Message-State: AHPjjUg/juGiTzz1udAEDArFNvDwMu/zT201WPAOAnBH8bEgCMF4zmJK 94TWWKSdnbACl3t8 X-Google-Smtp-Source: ADKCNb67Fqy8xZwNxj5Z+mhDwYxJWmv32SZVvpxo6CfmS0+MeXbQ8WHkgEcBz8/jdoTPz6V8NMqipw== X-Received: by 10.99.2.208 with SMTP id 199mr1573416pgc.441.1504840544624; Thu, 07 Sep 2017 20:15:44 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id r76sm797449pfl.15.2017.09.07.20.15.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Sep 2017 20:15:44 -0700 (PDT) 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 Cc: kexec@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH 9/9] arm64: kexec_file: add Image format support Date: Fri, 8 Sep 2017 12:16:16 +0900 Message-Id: <20170908031616.17916-10-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170908031616.17916-1-takahiro.akashi@linaro.org> References: <20170908031616.17916-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. Regarding kernel signature verification, it will be done through verify_pefile_signature() as arm64's "Image" binary can be seen as in PE format. This approach is consistent with x86 implementation. we can sign an image with sbsign command. Signed-off-by: AKASHI Takahiro Cc: Catalin Marinas Cc: Will Deacon --- arch/arm64/Kconfig | 7 +++ arch/arm64/include/asm/kexec_file.h | 69 +++++++++++++++++++++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/kexec_image.c | 106 +++++++++++++++++++++++++++++++++ arch/arm64/kernel/machine_kexec_file.c | 6 +- 5 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/include/asm/kexec_file.h create mode 100644 arch/arm64/kernel/kexec_image.c -- 2.14.1 diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index fa7299f08cc6..b7f1a760434a 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -769,10 +769,17 @@ 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" + depends on KEXEC_FILE + ---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 diff --git a/arch/arm64/include/asm/kexec_file.h b/arch/arm64/include/asm/kexec_file.h new file mode 100644 index 000000000000..a9397296e548 --- /dev/null +++ b/arch/arm64/include/asm/kexec_file.h @@ -0,0 +1,69 @@ +#ifndef _ASM_KEXEC_FILE_H +#define _ASM_KEXEC_FILE_H + +extern struct kexec_file_ops kexec_image_ops; + +/** + * struct arm64_image_header - arm64 kernel image header. + * + * @pe_sig: Optional PE format 'MZ' signature. + * @branch_code: Reserved for instructions to branch to stext. + * @text_offset: The image load offset in LSB byte order. + * @image_size: An estimated size of the memory image size in LSB byte order. + * @flags: Bit flags: + * Bit 7.0: Image byte order, 1=MSB. + * @reserved_1: Reserved. + * @magic: Magic number, "ARM\x64". + * @pe_header: Optional offset to a PE format header. + **/ + +struct arm64_image_header { + u8 pe_sig[2]; + u16 branch_code[3]; + u64 text_offset; + u64 image_size; + u8 flags[8]; + u64 reserved_1[3]; + u8 magic[4]; + u32 pe_header; +}; + +static const u8 arm64_image_magic[4] = {'A', 'R', 'M', 0x64U}; +static const u8 arm64_image_pe_sig[2] = {'M', 'Z'}; +static const u64 arm64_image_flag_7_be = 0x01U; + +/** + * 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]); +} + +/** + * 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]); +} +#endif /* _ASM_KEXEC_FILE_H */ diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 5df003d6157c..a1161bab6810 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -51,6 +51,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..c2c3d436fff3 --- /dev/null +++ b/arch/arm64/kernel/kexec_image.c @@ -0,0 +1,106 @@ +/* + * 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 +#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; + + pr_debug("PE format: %s\n", + (arm64_header_check_pe_sig(h) ? "yes" : "no")); + + 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); +} + +#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 + +struct kexec_file_ops kexec_image_ops = { + .probe = image_probe, + .load = image_load, +#ifdef CONFIG_KEXEC_VERIFY_SIG + .verify_sig = image_verify_sig, +#endif +}; diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c index 62627f5440ff..aa1b27dd012c 100644 --- a/arch/arm64/kernel/machine_kexec_file.c +++ b/arch/arm64/kernel/machine_kexec_file.c @@ -24,7 +24,11 @@ static int __dt_root_addr_cells; static int __dt_root_size_cells; -static struct kexec_file_ops *kexec_file_loaders[0]; +static struct kexec_file_ops *kexec_file_loaders[] = { +#ifdef CONFIG_KEXEC_FILE_IMAGE_FMT + &kexec_image_ops, +#endif +}; int arch_kexec_kernel_image_probe(struct kimage *image, void *buf, unsigned long buf_len)