From patchwork Mon Jul 10 12:56:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ioanna Alifieraki X-Patchwork-Id: 1805807 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=bGlYdqx9; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R03sv1ZCYz20Ph for ; Mon, 10 Jul 2023 22:56:33 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1qIqR9-0000l6-DI; Mon, 10 Jul 2023 12:56:19 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1qIqR7-0000kS-Kl for kernel-team@lists.ubuntu.com; Mon, 10 Jul 2023 12:56:17 +0000 Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 4AA513F730 for ; Mon, 10 Jul 2023 12:56:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1688993777; bh=PrO7ghvYysa5zySN8nx/nNizBc6qeOPgTo28lNAGiwA=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bGlYdqx9dAiki3YM+1G/AS2JMsRt9Yd9zk5bkBlFQPOPFBwQHuz1+xW6j+ZqDpCiP BZ7ZemyKYa5J+5+4UewlYdnaApR+WZjLN6Px4/w7+Svjnfr9tRD42IWzOxFH96QHHO 3KzfE36rgYVEysJiwRguOTtBsNvftmNhohNhNFndv3B+SnoqT+dAcCGPfOzfwBiyCZ Zfi+tsw+os1rcJ4M7kTqTyJzVgM+pNMr4K0n07he5ddJyTR7+mP9isrGKCw/Gc9O9/ /5MfokdC1sAn9o1bkFSfHVCoAVlkD7/wTLwz0KvXtsDiKPbuxWJ5DO3TG5cSFGQHUE NGN6LxtNRDlYQ== Received: by mail-ej1-f72.google.com with SMTP id a640c23a62f3a-992e684089aso259374866b.0 for ; Mon, 10 Jul 2023 05:56:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688993776; x=1691585776; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PrO7ghvYysa5zySN8nx/nNizBc6qeOPgTo28lNAGiwA=; b=fVhPVgsOcbOrEi3Es1Hv+gjD+gJak4TY0kjjekWfsxePr223b7BhXftbecpUSHT58J KG9qBsUsYZetN3oOv+YPvYHQIQNjMP6ZxPr46cuwLoqwY7bd3DMjXp648Pp0WrmkWvC/ 4HYj9qoYvvJz1HnRfFnFuMN8UYTD4stMzqoOsW3WLTAYA0NR6v/XilCpsnTAk6CduRqU FRprh86lpXAEbNc7bVO5s9/pZXNwQPK1ycoFVuETqeTVNTWsY1TKMHeo8qG8PBLhLrHI /X3mSvDxGikXlt3/8mk8D3F1lhSjIyURgjsI0p+3mR21yVdAkH77hk7EuQxOsIynxwKa jGZQ== X-Gm-Message-State: ABy/qLaBfZTvkEfr15IX8ArbEGowIljDRzQzqFj/bIOx2POwCXxIT0Fw DynKCYu2nouipx0pLxevw/pGtpfHk/eyY4YvjE6oopMecXQ4QSpBsnZfOtc4RAxBMMMSXuBVKKl Pvl7ompUSiWPP+dYymIW89wDj4jiBKtMembR6+A9efl9CS3L9Eg== X-Received: by 2002:a17:906:9d86:b0:973:cc48:f19c with SMTP id fq6-20020a1709069d8600b00973cc48f19cmr9472544ejc.56.1688993776738; Mon, 10 Jul 2023 05:56:16 -0700 (PDT) X-Google-Smtp-Source: APBJJlGIjJlLeo2YAzs0cvf+BrUjsio3LsDvgGqJkVlYPB1oYKayc9sIR4yxZhdcEU6YGzLkvIShSw== X-Received: by 2002:a17:906:9d86:b0:973:cc48:f19c with SMTP id fq6-20020a1709069d8600b00973cc48f19cmr9472528ejc.56.1688993776357; Mon, 10 Jul 2023 05:56:16 -0700 (PDT) Received: from t14s.. ([212.251.14.163]) by smtp.gmail.com with ESMTPSA id m4-20020a170906258400b00992025654c4sm6133605ejb.182.2023.07.10.05.56.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Jul 2023 05:56:15 -0700 (PDT) From: Ioanna Alifieraki To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 2/7] arm64: kdump: Reimplement crashkernel=X Date: Mon, 10 Jul 2023 15:56:07 +0300 Message-Id: <20230710125612.37735-3-ioanna-maria.alifieraki@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230710125612.37735-1-ioanna-maria.alifieraki@canonical.com> References: <20230710125612.37735-1-ioanna-maria.alifieraki@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Chen Zhou BugLink: https://bugs.launchpad.net/bugs/2024479 There are following issues in arm64 kdump: 1. We use crashkernel=X to reserve crashkernel in DMA zone, which will fail when there is not enough low memory. 2. If reserving crashkernel above DMA zone, in this case, crash dump kernel will fail to boot because there is no low memory available for allocation. To solve these issues, introduce crashkernel=X,[high,low]. The "crashkernel=X,high" is used to select a region above DMA zone, and the "crashkernel=Y,low" is used to allocate specified size low memory. Signed-off-by: Chen Zhou Co-developed-by: Zhen Lei Signed-off-by: Zhen Lei Link: https://lore.kernel.org/r/20220506114402.365-4-thunder.leizhen@huawei.com Signed-off-by: Catalin Marinas (backported from commit 944a45abfabc171fd121315ff0d5e62b11cb5d6f) [Changed memblock_phys_free() to memblock_free() because the first is not present in this kernel.] Signed-off-by: Ioanna Alifieraki --- arch/arm64/kernel/machine_kexec.c | 9 +++- arch/arm64/kernel/machine_kexec_file.c | 12 ++++- arch/arm64/mm/init.c | 63 +++++++++++++++++++++++--- 3 files changed, 74 insertions(+), 10 deletions(-) diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c index 213d56c14f60..6ea4dd1a6517 100644 --- a/arch/arm64/kernel/machine_kexec.c +++ b/arch/arm64/kernel/machine_kexec.c @@ -320,8 +320,13 @@ bool crash_is_nosave(unsigned long pfn) /* in reserved memory? */ addr = __pfn_to_phys(pfn); - if ((addr < crashk_res.start) || (crashk_res.end < addr)) - return false; + if ((addr < crashk_res.start) || (crashk_res.end < addr)) { + if (!crashk_low_res.end) + return false; + + if ((addr < crashk_low_res.start) || (crashk_low_res.end < addr)) + return false; + } if (!kexec_crash_image) return true; diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c index 59c648d51848..889951291cc0 100644 --- a/arch/arm64/kernel/machine_kexec_file.c +++ b/arch/arm64/kernel/machine_kexec_file.c @@ -65,10 +65,18 @@ static int prepare_elf_headers(void **addr, unsigned long *sz) /* Exclude crashkernel region */ ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end); + if (ret) + goto out; + + if (crashk_low_res.end) { + ret = crash_exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end); + if (ret) + goto out; + } - if (!ret) - ret = crash_prepare_elf64_headers(cmem, true, addr, sz); + ret = crash_prepare_elf64_headers(cmem, true, addr, sz); +out: kfree(cmem); return ret; } diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 8c3ffcfc3b58..9fd61dfd9289 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -90,6 +90,32 @@ phys_addr_t __ro_after_init arm64_dma_phys_limit; phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1; #endif +/* Current arm64 boot protocol requires 2MB alignment */ +#define CRASH_ALIGN SZ_2M + +#define CRASH_ADDR_LOW_MAX arm64_dma_phys_limit +#define CRASH_ADDR_HIGH_MAX (PHYS_MASK + 1) + +static int __init reserve_crashkernel_low(unsigned long long low_size) +{ + unsigned long long low_base; + + low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 0, CRASH_ADDR_LOW_MAX); + if (!low_base) { + pr_err("cannot allocate crashkernel low memory (size:0x%llx).\n", low_size); + return -ENOMEM; + } + + pr_info("crashkernel low memory reserved: 0x%08llx - 0x%08llx (%lld MB)\n", + low_base, low_base + low_size, low_size >> 20); + + crashk_low_res.start = low_base; + crashk_low_res.end = low_base + low_size - 1; + insert_resource(&iomem_resource, &crashk_low_res); + + return 0; +} + /* * reserve_crashkernel() - reserves memory for crash kernel * @@ -100,17 +126,35 @@ phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1; static void __init reserve_crashkernel(void) { unsigned long long crash_base, crash_size; - unsigned long long crash_max = arm64_dma_phys_limit; + unsigned long long crash_low_size = 0; + unsigned long long crash_max = CRASH_ADDR_LOW_MAX; + char *cmdline = boot_command_line; int ret; if (!IS_ENABLED(CONFIG_KEXEC_CORE)) return; - ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(), + /* crashkernel=X[@offset] */ + ret = parse_crashkernel(cmdline, memblock_phys_mem_size(), &crash_size, &crash_base); - /* no crashkernel= or invalid value specified */ - if (ret || !crash_size) + if (ret == -ENOENT) { + ret = parse_crashkernel_high(cmdline, 0, &crash_size, &crash_base); + if (ret || !crash_size) + return; + + /* + * crashkernel=Y,low can be specified or not, but invalid value + * is not allowed. + */ + ret = parse_crashkernel_low(cmdline, 0, &crash_low_size, &crash_base); + if (ret && (ret != -ENOENT)) + return; + + crash_max = CRASH_ADDR_HIGH_MAX; + } else if (ret || !crash_size) { + /* The specified value is invalid */ return; + } crash_size = PAGE_ALIGN(crash_size); @@ -118,8 +162,7 @@ static void __init reserve_crashkernel(void) if (crash_base) crash_max = crash_base + crash_size; - /* Current arm64 boot protocol requires 2MB alignment */ - crash_base = memblock_phys_alloc_range(crash_size, SZ_2M, + crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN, crash_base, crash_max); if (!crash_base) { pr_warn("cannot allocate crashkernel (size:0x%llx)\n", @@ -127,6 +170,11 @@ static void __init reserve_crashkernel(void) return; } + if (crash_low_size && reserve_crashkernel_low(crash_low_size)) { + memblock_free(crash_base, crash_size); + return; + } + pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n", crash_base, crash_base + crash_size, crash_size >> 20); @@ -135,6 +183,9 @@ static void __init reserve_crashkernel(void) * map. Inform kmemleak so that it won't try to access it. */ kmemleak_ignore_phys(crash_base); + if (crashk_low_res.end) + kmemleak_ignore_phys(crashk_low_res.start); + crashk_res.start = crash_base; crashk_res.end = crash_base + crash_size - 1; }