Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp3118298pxf; Mon, 5 Apr 2021 03:51:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwopBPAyoZ+TFlL2QG3l79Y6e3xY/2eCpM8iiCWyYtwz5o6+JgptxgbmZvnuT7Fvf87mrHO X-Received: by 2002:a05:6602:2056:: with SMTP id z22mr19694492iod.21.1617619867085; Mon, 05 Apr 2021 03:51:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617619867; cv=none; d=google.com; s=arc-20160816; b=Qfyu1Kb6i+DQ9/fl56atY1TcSTSoMwPOSwMnGevdHuXODnk3VrLBBF+SxWhmBRNYHG c9o6LutKeFxl71dd/kkVxWoy714lLtSS/SX1VparMLJg2Byy9DsKjE25+2p7uyM5uuzz +avaW6//JOWyCqzQhrNLHLO1fUPXKF4P9Bx5Q7y7nP5Pfc5CbsTqRc6kbYVazDhTgQ1Z ZQeVgsblpWSJ7H9g/jekwxuCRY4jntzUbNF8ejGGbJUslhKKKRKhWoLQnm7ySQJgazDw W4gyryzmXao3oZWAMhBToBD4Z3ogNN70ViwbHCIbCACW9jDvjO8cplFmDvney/YtxJd1 +llA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=7JM9oj3kiYATPjfcNtGnMReKkMdeKKpdmW4pJln53QI=; b=TLWZ+iuVeInAVHZTpYjWjN5FSFow4GtVXnP7Za+MBcUt2hkvcuSFgwXFvZGXQLyBic pBe8J3OZjqBcRKNOtXPeeMSQitLkYkwuiXhWGYxeoe+z/ctPjDuRJaLyM1Ats6MyBuJC rBf2XnmJb8eXNhQ0IXSIepuQid5gnPBSMbvrJ9fynJyLl70UFjXrUReiixw9N4Ti1oJH VjgDsHDbAGdCAlN48eRRI1tWTRiwu8hX3U+yd8PuEg6Pbb/vLuH3llKjwfs8vSbML+Pa mdHLydx5wtRwTtQ5L/lJvAvAyHjcQ2AM5lV8oQYk7UznPAqzUbT5FiJ3jMYjrCtw87X+ Dg0Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail (test mode) header.i=@ics.forth.gr header.s=av header.b="H2M4qk/j"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ics.forth.gr Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k23si15057708ioh.25.2021.04.05.03.50.55; Mon, 05 Apr 2021 03:51:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=fail (test mode) header.i=@ics.forth.gr header.s=av header.b="H2M4qk/j"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ics.forth.gr Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233540AbhDEI6I (ORCPT + 99 others); Mon, 5 Apr 2021 04:58:08 -0400 Received: from mailgate.ics.forth.gr ([139.91.1.2]:56931 "EHLO mailgate.ics.forth.gr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233282AbhDEI5m (ORCPT ); Mon, 5 Apr 2021 04:57:42 -0400 Received: from av3.ics.forth.gr (av3in.ics.forth.gr [139.91.1.77]) by mailgate.ics.forth.gr (8.15.2/ICS-FORTH/V10-1.8-GATE) with ESMTP id 1358vWDK079890 for ; Mon, 5 Apr 2021 11:57:32 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; d=ics.forth.gr; s=av; c=relaxed/simple; q=dns/txt; i=@ics.forth.gr; t=1617613047; x=1620205047; h=From:Sender:Reply-To:Subject:Date:Message-Id:To:Cc:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=BH9rkqbpEw6Ux/YR+romPrZxgh0AN8grObdmfeP55TM=; b=H2M4qk/jCJV7AM9vJ/DAyI42X+1w9WX4+GuCSkgZzNwRZXsWNUkMtl5HYYQuZFa3 XztAcVOpw7zE3on8hIFNb57kxdbTMLEJ4VSKpFb3yzGSDC6ZA36pGzeoF1xtAQPw 3W5x0gmFLJpcICbPkTkdzYcgx1QErghrORL1LWiOD3BJNMDWQ6cV6689iAA1MF32 iyKJpCcniolEDwF4Gkf1q6vs6QgE+I0h71EPgIelNgZeImzKqtgTQMB2knZdtCpI fbp97qMdT7bULWaGEwRcMuN+87PdBHDtMzcvDQpP5nkPzIRu1k+koMtuVH4K/kAb XPwxDiTsD6JffEf5MkPE+Q==; X-AuditID: 8b5b014d-a4c337000000209f-dc-606ad0f78f2b Received: from enigma.ics.forth.gr (enigma.ics.forth.gr [139.91.151.35]) by av3.ics.forth.gr (Symantec Messaging Gateway) with SMTP id 19.77.08351.7F0DA606; Mon, 5 Apr 2021 11:57:27 +0300 (EEST) X-ICS-AUTH-INFO: Authenticated user: mick@ics.forth.gr at ics.forth.gr From: Nick Kossifidis To: linux-riscv@lists.infradead.org, palmer@dabbelt.com Cc: paul.walmsley@sifive.com, linux-kernel@vger.kernel.org, Nick Kossifidis , Nick Kossifidis Subject: [PATCH v3 5/5] RISC-V: Add crash kernel support Date: Mon, 5 Apr 2021 11:57:12 +0300 Message-Id: <20210405085712.1953848-6-mick@ics.forth.gr> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210405085712.1953848-1-mick@ics.forth.gr> References: <20210405085712.1953848-1-mick@ics.forth.gr> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrCLMWRmVeSWpSXmKPExsXSHT1dWff7hawEg5adhhaXd81hs9j2uYXN ovndOXaL1Rd2slq8vNzDbNE2i9+BzePNy5csHjtn3WX3eLjpEpPH5iX1Hpear7N7fN4kF8AW xWWTkpqTWZZapG+XwJXx9dIsloKDJhXvNzxgb2B8rtXFyMkhIWAicWz+erYuRi4OIYGjjBJt 866yQiTcJG7f3wlmswloSsy/dJAFxBYRMJdonvmaEaSBWWAGo8S6W1MZQRLCAhYSRz42s4HY LAKqEhs272UCsXmB4m8/PoMaKi/Rvnw7WA2ngKXEtvOLwGqEgGquH+thhKgXlDg58wnYMmag +uats5knMPLNQpKahSS1gJFpFaNAYpmxXmZysV5aflFJhl560SZGcEAy+u5gvL35rd4hRiYO xkOMEhzMSiK8DxuyEoR4UxIrq1KL8uOLSnNSiw8xSnOwKInz8upNiBcSSE8sSc1OTS1ILYLJ MnFwSjUwtQjxbFg5s3Huk/J1C8IkW62rM+fE8oU2eCz7FlhTun7FazXTwhiDjtfpOzY4nrVx OrlW8YaRQHUO05ljR7cWfX361TlWkGObjWrT1+oL+7P2i/y90/34paypc8tV4+LkT5wrZ4Xe F3NpWs+i9HXJuY6bz9oZ/t/NS9K5/uLHxs97RRfyZ7Pf/VyQOXXaFpE03rD4Xe8TDuyZPSfI 6KB25Nbg/rY9M3ks2ZenxcaWqi1XUNJf7LZB8c5r/p1JLFynRCZNPlo+RV3/XGmO5p/PBxjY 5/rMkTPVeBfTF1r/p2kpM+ezA0WfZEyNX3guY1vjbmVZfPlLcVRiZ5us1tTi57O2TDuZcXjF PxELg/pZSizFGYmGWsxFxYkA3e0lhLcCAAA= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Nick Kossifidis This patch allows Linux to act as a crash kernel for use with kdump. Userspace will let the crash kernel know about the memory region it can use through linux,usable-memory property on the /memory node (overriding its reg property), and about the memory region where the elf core header of the previous kernel is saved, through a reserved-memory node with a compatible string of "linux,elfcorehdr". This approach is the least invasive and re-uses functionality already present. I tested this on riscv64 qemu and it works as expected, you may test it by retrieving the dmesg of the previous kernel through /proc/vmcore, using the vmcore-dmesg utility from kexec-tools. v3: * Rebase v2: * Use linux,usable-memory on /memory instead of a new binding * Use a reserved-memory node for ELF core header Signed-off-by: Nick Kossifidis --- arch/riscv/Kconfig | 10 ++++++++ arch/riscv/kernel/Makefile | 1 + arch/riscv/kernel/crash_dump.c | 46 ++++++++++++++++++++++++++++++++++ arch/riscv/kernel/setup.c | 12 +++++++++ arch/riscv/mm/init.c | 33 ++++++++++++++++++++++++ 5 files changed, 102 insertions(+) create mode 100644 arch/riscv/kernel/crash_dump.c diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 3716262ef..553c2dced 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -403,6 +403,16 @@ config KEXEC The name comes from the similarity to the exec system call. +config CRASH_DUMP + bool "Build kdump crash kernel" + help + Generate crash dump after being started by kexec. This should + be normally only set in special crash dump kernels which are + loaded in the main kernel with kexec-tools into a specially + reserved region and then later executed after a crash by + kdump/kexec. + + For more details see Documentation/admin-guide/kdump/kdump.rst endmenu diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index 07f676ad3..bd66d2ce0 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -59,6 +59,7 @@ endif obj-$(CONFIG_HOTPLUG_CPU) += cpu-hotplug.o obj-$(CONFIG_KGDB) += kgdb.o obj-${CONFIG_KEXEC} += kexec_relocate.o crash_save_regs.o machine_kexec.o +obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o diff --git a/arch/riscv/kernel/crash_dump.c b/arch/riscv/kernel/crash_dump.c new file mode 100644 index 000000000..86cc0ada5 --- /dev/null +++ b/arch/riscv/kernel/crash_dump.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * This code comes from arch/arm64/kernel/crash_dump.c + * Created by: AKASHI Takahiro + * Copyright (C) 2017 Linaro Limited + */ + +#include +#include + +/** + * copy_oldmem_page() - copy one page from old kernel memory + * @pfn: page frame number to be copied + * @buf: buffer where the copied page is placed + * @csize: number of bytes to copy + * @offset: offset in bytes into the page + * @userbuf: if set, @buf is in a user address space + * + * This function copies one page from old kernel memory into buffer pointed by + * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes + * copied or negative error in case of failure. + */ +ssize_t copy_oldmem_page(unsigned long pfn, char *buf, + size_t csize, unsigned long offset, + int userbuf) +{ + void *vaddr; + + if (!csize) + return 0; + + vaddr = memremap(__pfn_to_phys(pfn), PAGE_SIZE, MEMREMAP_WB); + if (!vaddr) + return -ENOMEM; + + if (userbuf) { + if (copy_to_user((char __user *)buf, vaddr + offset, csize)) { + memunmap(vaddr); + return -EFAULT; + } + } else + memcpy(buf, vaddr + offset, csize); + + memunmap(vaddr); + return csize; +} diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 31866dce9..ff398a3d8 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -66,6 +66,9 @@ static struct resource code_res = { .name = "Kernel code", }; static struct resource data_res = { .name = "Kernel data", }; static struct resource rodata_res = { .name = "Kernel rodata", }; static struct resource bss_res = { .name = "Kernel bss", }; +#ifdef CONFIG_CRASH_DUMP +static struct resource elfcorehdr_res = { .name = "ELF Core hdr", }; +#endif static int __init add_resource(struct resource *parent, struct resource *res) @@ -169,6 +172,15 @@ static void __init init_resources(void) } #endif +#ifdef CONFIG_CRASH_DUMP + if (elfcorehdr_size > 0) { + elfcorehdr_res.start = elfcorehdr_addr; + elfcorehdr_res.end = elfcorehdr_addr + elfcorehdr_size - 1; + elfcorehdr_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; + add_resource(&iomem_resource, &elfcorehdr_res); + } +#endif + for_each_reserved_mem_region(region) { res = &mem_res[res_idx--]; diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index e71b35cec..f66011816 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -606,6 +607,18 @@ static void __init reserve_crashkernel(void) int ret = 0; + /* + * Don't reserve a region for a crash kernel on a crash kernel + * since it doesn't make much sense and we have limited memory + * resources. + */ +#ifdef CONFIG_CRASH_DUMP + if (is_kdump_kernel()) { + pr_info("crashkernel: ignoring reservation request\n"); + return; + } +#endif + ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(), &crash_size, &crash_base); if (ret || !crash_size) @@ -660,6 +673,26 @@ static void __init reserve_crashkernel(void) } #endif /* CONFIG_KEXEC_CORE */ +#ifdef CONFIG_CRASH_DUMP +/* + * We keep track of the ELF core header of the crashed + * kernel with a reserved-memory region with compatible + * string "linux,elfcorehdr". Here we register a callback + * to populate elfcorehdr_addr/size when this region is + * present. Note that this region will be marked as + * reserved once we call early_init_fdt_scan_reserved_mem() + * later on. + */ +static int elfcore_hdr_setup(struct reserved_mem *rmem) +{ + elfcorehdr_addr = rmem->base; + elfcorehdr_size = rmem->size; + return 0; +} + +RESERVEDMEM_OF_DECLARE(elfcorehdr, "linux,elfcorehdr", elfcore_hdr_setup); +#endif + void __init paging_init(void) { setup_vm_final(); -- 2.26.2