From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 43CEFC00A89 for ; Fri, 30 Oct 2020 18:19:57 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AF07520A8B for ; Fri, 30 Oct 2020 18:19:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="mcq71hFO"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="h83oh7SW" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AF07520A8B Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe :List-Id:MIME-Version:Message-ID:Subject:To:From:Date:Reply-To:Cc:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Owner; bh=mbHWywERbAPQD5sPmLXsu/cH7Rg64j0ttfvd+0R3e4c=; b=mcq71hFOsz3b93fiprpt9QzSyY UUdGFi5gOl2g+uWXS+CZJipHZbg0OAF5yS9FgGkdr398bA7kTP+3Ehkoi3ryggqlkzrAAekkjx1Qq Pw60ZsqI6f8aylYdXdDJWhFwxVWPkf0DidNW4GYS+J8M8doYBXMx2pHcX9Ix64Vgx+w+HY1tZLgKX lf5RkiEP/p8Qqqc7fzP9JE+2VpOw1Mln6+bfIBSCY3k3JJO1WIaluafF2z4NkrLCkR1Yf8FbOGfd2 TCwBbCi9IE30UjnJYtXZj+7+2HPnJ2pLT2e2ry4SwUN+S479wPzv3ILKwtoyO+qdAzdSqJIdowdK+ 7w6a6etg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kYYyu-0000gU-Jd; Fri, 30 Oct 2020 18:18:32 +0000 Received: from mail-pg1-x541.google.com ([2607:f8b0:4864:20::541]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kYYyr-0000e6-9Q for linux-arm-kernel@lists.infradead.org; Fri, 30 Oct 2020 18:18:30 +0000 Received: by mail-pg1-x541.google.com with SMTP id r10so5893442pgb.10 for ; Fri, 30 Oct 2020 11:18:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:from:to:subject:message-id:mime-version:content-disposition; bh=dnqAT4NSJ0rBktHqXF9ZDrY9g8I+f5GxWcopcH9u3HM=; b=h83oh7SWHsZyg/9UKM0ppF9wkFNXnVCHSM0msMd6jFL7WAaK3MDnErGFDkf//bHnDp YFPfN9BktKyN4XkLf2uFVt8tJqNKZ2K2wmroNqjrWADFoPJVD3Zk5tkBkdZqVw86QASt wIdxMt6ZKHKMDz5MPfjzAwtJtGS1SmgnA21GwgRT1ZQzbFvabxiUrgUq9L0Gugds1Cix R1e3vcrHLPNRmtKbcqOtrRXhVXlQnJeACkxQ8jtV3ESFeukRSa02XYd/Z9iOzJTvEh2m 7RvulAc+l1owSgunsEh13oEtMWcfdlW5Mcd+KXcO61VurjEfvJ0c3kdYPArGdKbrNSG7 kWgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition; bh=dnqAT4NSJ0rBktHqXF9ZDrY9g8I+f5GxWcopcH9u3HM=; b=WzZn+0RMnM6aGmIM8VkFBSQ2TRWaEMcRTkSjjFv+dTogw9jw2eUpC1tBs2Nx6vOe+v 2YecbTuktlwTFPIRTazEl19k6fsjD9NdmtJOyAW+Av2cVwTj0Bl9mVOilWuYt4c+mZm5 TsJxqoFTBH7MdRq0RUp5Qu9H1g3O30JoxvOkEvByVro7NFOXW2PUGaJxwLXw4QlwxPx0 zX0n9XnnZhdvgOjT55k/UBhujEED4o4Q3gxrDzyHr5pygc1PhNDiAoVB+SSZe+Z6+pUh ilw0INfUgbSipTopcDk89ePlrqhbnP4EuDGiUGsn+wertYpT1z8tudDETOK3o4pfvvrs 9sjw== X-Gm-Message-State: AOAM531XqT70D8XcSck+bZN1pqVwaKbwrv75Nx+gGVDETblMGTRa7qxZ 5LVppxocRqZkrsm8rEhRwIdJtYH9i/YlsA== X-Google-Smtp-Source: ABdhPJwKKFNbew8QIibOBmIQGThhUliFWCKkux79RSgXyKtIIJi4rctxYxMtatpJ45hrRIht/G12VA== X-Received: by 2002:aa7:96ce:0:b029:155:8c02:e74a with SMTP id h14-20020aa796ce0000b02901558c02e74amr10210359pfq.32.1604081904976; Fri, 30 Oct 2020 11:18:24 -0700 (PDT) Received: from google.com ([2620:15c:2a3:0:cad3:ffff:feb1:5ce5]) by smtp.gmail.com with ESMTPSA id q8sm6851584pff.18.2020.10.30.11.18.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Oct 2020 11:18:24 -0700 (PDT) Date: Fri, 30 Oct 2020 11:18:20 -0700 From: Benjamin Gwin To: will@kernel.org, catalin.marinas@arm.com, linux-arm-kernel@lists.infradead.org, takahiro.akashi@linaro.org, ryanoleary@google.com Subject: [PATCH] arm64: kexec_file: try more regions if loading segments fails Message-ID: <20201030181820.GA3292599@google.com> MIME-Version: 1.0 Content-Disposition: inline X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201030_141829_366727_36B12701 X-CRM114-Status: GOOD ( 21.20 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org It's possible that the first region picked for the new kernel will make it impossible to fit the other segments in the required 32GB window, especially if we have a very large initrd. Instead of giving up, we can keep testing other regions for the kernel until we find one that works. Signed-off-by: Benjamin Gwin Suggested-by: Ryan O'Leary --- arch/arm64/kernel/kexec_image.c | 41 +++++++++++++++++++------- arch/arm64/kernel/machine_kexec_file.c | 9 +++++- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c index af9987c154ca..e2251d61ea35 100644 --- a/arch/arm64/kernel/kexec_image.c +++ b/arch/arm64/kernel/kexec_image.c @@ -43,7 +43,7 @@ static void *image_load(struct kimage *image, u64 flags, value; bool be_image, be_kernel; struct kexec_buf kbuf; - unsigned long text_offset; + unsigned long text_offset, kernel_segment_number; struct kexec_segment *kernel_segment; int ret; @@ -88,11 +88,37 @@ static void *image_load(struct kimage *image, /* Adjust kernel segment with TEXT_OFFSET */ kbuf.memsz += text_offset; - ret = kexec_add_buffer(&kbuf); - if (ret) + kernel_segment_number = image->nr_segments; + + /* + * The location of the kernel segment may make it impossible to satisfy + * the other segment requirements, so we try repeatedly to find a + * location that will work. + */ + while ((ret = kexec_add_buffer(&kbuf)) == 0) { + /* Try to load additional data */ + kernel_segment = &image->segment[kernel_segment_number]; + ret = load_other_segments(image, + kernel_segment->mem, kernel_segment->memsz, + initrd, initrd_len, cmdline); + if (!ret) + break; + + /* + * We couldn't find space for the other segments; erase the + * kernel segment and try the next available hole. + * */ + image->nr_segments -= 1; + kbuf.buf_min = kernel_segment->mem + kernel_segment->memsz; + kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; + } + + if (ret) { + pr_err("Could not find any suitable kernel location!"); return ERR_PTR(ret); + } - kernel_segment = &image->segment[image->nr_segments - 1]; + kernel_segment = &image->segment[kernel_segment_number]; kernel_segment->mem += text_offset; kernel_segment->memsz -= text_offset; image->start = kernel_segment->mem; @@ -101,12 +127,7 @@ static void *image_load(struct kimage *image, kernel_segment->mem, kbuf.bufsz, kernel_segment->memsz); - /* Load additional data */ - ret = load_other_segments(image, - kernel_segment->mem, kernel_segment->memsz, - initrd, initrd_len, cmdline); - - return ERR_PTR(ret); + return 0; } #ifdef CONFIG_KEXEC_IMAGE_VERIFY_SIG diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c index 5b0e67b93cdc..03210f644790 100644 --- a/arch/arm64/kernel/machine_kexec_file.c +++ b/arch/arm64/kernel/machine_kexec_file.c @@ -240,6 +240,11 @@ static int prepare_elf_headers(void **addr, unsigned long *sz) return ret; } +/* + * Tries to add the initrd and DTB to the image. If it is not possible to find + * valid locations, this function will undo changes to the image and return non + * zero. + */ int load_other_segments(struct kimage *image, unsigned long kernel_load_addr, unsigned long kernel_size, @@ -248,7 +253,8 @@ int load_other_segments(struct kimage *image, { struct kexec_buf kbuf; void *headers, *dtb = NULL; - unsigned long headers_sz, initrd_load_addr = 0, dtb_len; + unsigned long headers_sz, initrd_load_addr = 0, dtb_len, + orig_segments = image->nr_segments; int ret = 0; kbuf.image = image; @@ -334,6 +340,7 @@ int load_other_segments(struct kimage *image, return 0; out_err: + image->nr_segments = orig_segments; vfree(dtb); return ret; } -- 2.29.1.341.ge80a0c044ae-goog _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel