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 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94F30C3ABC9 for ; Fri, 9 May 2025 07:47:38 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id D95396B00D2; Fri, 9 May 2025 03:47:24 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id CF90A6B00D4; Fri, 9 May 2025 03:47:24 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B46BD6B00D5; Fri, 9 May 2025 03:47:24 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 8E6136B00D2 for ; Fri, 9 May 2025 03:47:24 -0400 (EDT) Received: from smtpin17.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id DB6CF5EBD7 for ; Fri, 9 May 2025 07:47:25 +0000 (UTC) X-FDA: 83422589250.17.DA2FDD8 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.201]) by imf08.hostedemail.com (Postfix) with ESMTP id 04042160002 for ; Fri, 9 May 2025 07:47:23 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=Ja3ruDyE; spf=pass (imf08.hostedemail.com: domain of 3CrMdaAoKCC8NSLYRjfLYWRZZRWP.NZXWTYfi-XXVgLNV.ZcR@flex--changyuanl.bounces.google.com designates 209.85.214.201 as permitted sender) smtp.mailfrom=3CrMdaAoKCC8NSLYRjfLYWRZZRWP.NZXWTYfi-XXVgLNV.ZcR@flex--changyuanl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1746776844; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=ltOzPxd5cb014aNqOQJOhRAOAasmd6Qqt/PpxvB5qBk=; b=KOHOM/KlnZ8GnRVFOyrs0v27U/DZsePLW+A9pFi2C5mnpmipKmZU7gyfsyi5DB5jYgaQ0Z SAf9xIi/POB3A09/IMVuVVwyoFJaklNw+hysD9HSAvGsbMUwIaOgQ6w8A1bGTsVTSQS2vj W7NWAkrdCnOb5SK+v1BA0Kq+5FsYMWg= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=Ja3ruDyE; spf=pass (imf08.hostedemail.com: domain of 3CrMdaAoKCC8NSLYRjfLYWRZZRWP.NZXWTYfi-XXVgLNV.ZcR@flex--changyuanl.bounces.google.com designates 209.85.214.201 as permitted sender) smtp.mailfrom=3CrMdaAoKCC8NSLYRjfLYWRZZRWP.NZXWTYfi-XXVgLNV.ZcR@flex--changyuanl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1746776844; a=rsa-sha256; cv=none; b=x8/IOirB+g5GC/NJET7p5Q5sM6m9Uvx/hdANmANagnVwSxZvzpJYdebAHkQf7nhoD2kDE9 YkZEaiw8JMAWH5p1AjcNytIsSPiQ8NfDc+1VdiWA9FXSCzbEI22dtTeFkDRFPfO+KX7vP9 vnnQePYp2LAokN6pB0BZRAZ5hGoHdkg= Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-22e68e50f80so13656705ad.1 for ; Fri, 09 May 2025 00:47:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746776843; x=1747381643; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=ltOzPxd5cb014aNqOQJOhRAOAasmd6Qqt/PpxvB5qBk=; b=Ja3ruDyE61Ni1+i5uKY5TTfcp6tfJc4KCkndM45RaaNyjmw0WMJEHwKeND+F690VDu +jWAYzNuxCLV5dQdPLsXGDDCQhbZ93XjF0tPCQxe0RmCgJX6pRRukLt7PrUe03sny1TT 84blXRdujjoigKv+hhtlvWC4L+toJcpjMJ08VuUu0LB9B/FfqI/l9dQkOCgyhMrkzQls vbNbiPQxbhHtJB+Qrmbai6AIN0Fy+sQe7Ulxs1FR9VwRrtOIFnwuRZ0uu6BTJUUPOdFp wenoo9GWOpNGSAmykk6fCVAUiJOYnkoPesYifgCFov6cPl2l1ppP2QjwDF0rSitBvZ4V 3Esw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746776843; x=1747381643; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ltOzPxd5cb014aNqOQJOhRAOAasmd6Qqt/PpxvB5qBk=; b=IHlc8T2nsAU6nBK+zj5B2MVx38+tWIa5VMnyV9slN6xmvN0HEMmVsfaj4yd4jPfJHn 0Dh/5xSMAebXA52I7SwStOx5Om3P2jDKWwlpR9zJikt/lDkkhB6WyrcL6Adpi5rHLd6p UOwgYhu52IRlNrX5lqY9Td5mV0lAFOK8cYISTsJlOH/ci1cgq30RBlj3OTMPmIT/hzJr zDkMutmFjXVeHiu22kqnJz2GyfZTgKbEftRW7fdH7rhgxv0nyH8YGqFNKe50KIb70skg Jb4etCo1oY/pfDGIlI/zVdcSIBkRHf1a0C7XbbVCVYFT6R3Z4WNlcpoXubIoXhNw+oL6 98yw== X-Forwarded-Encrypted: i=1; AJvYcCXJG87gte7ljnkUVdhVw0M6kohjgy3e+4rsM/t/2UCwpaD5MhEAS/lBIJuXdmoNLSn1cw3lVjMYOw==@kvack.org X-Gm-Message-State: AOJu0YxDHevJJbEDroEWjBVg3dKkq86qHJifWjV82h8SdEvt+u9ragnE Gh0MioFtQKHFVfsuU2D525BgiFQTlaRt27byUDzvd1b+fccBRBzc8tqHT1kl8IfJm1OxA573TiE hkpmunUQzIdbXuj0E6w== X-Google-Smtp-Source: AGHT+IEmGBTS05A8WCtEMDiSHI9TQ0XKQ9En6nya4Iyyn0DN/q/frpBUdoFmx0xItQXSJArNnWrRzV24KfjtMJ+7 X-Received: from plke15.prod.google.com ([2002:a17:903:194f:b0:223:f441:fcaa]) (user=changyuanl job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:ce8b:b0:22e:b21c:98de with SMTP id d9443c01a7336-22fc8d98436mr33473415ad.39.1746776842872; Fri, 09 May 2025 00:47:22 -0700 (PDT) Date: Fri, 9 May 2025 00:46:33 -0700 In-Reply-To: <20250509074635.3187114-1-changyuanl@google.com> Mime-Version: 1.0 References: <20250509074635.3187114-1-changyuanl@google.com> X-Mailer: git-send-email 2.49.0.1015.ga840276032-goog Message-ID: <20250509074635.3187114-16-changyuanl@google.com> Subject: [PATCH v8 15/17] memblock: add KHO support for reserve_mem From: Changyuan Lyu To: akpm@linux-foundation.org, linux-kernel@vger.kernel.org Cc: anthony.yznaga@oracle.com, arnd@arndb.de, ashish.kalra@amd.com, benh@kernel.crashing.org, bp@alien8.de, catalin.marinas@arm.com, corbet@lwn.net, dave.hansen@linux.intel.com, devicetree@vger.kernel.org, dwmw2@infradead.org, ebiederm@xmission.com, graf@amazon.com, hpa@zytor.com, jgowans@amazon.com, kexec@lists.infradead.org, krzk@kernel.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-mm@kvack.org, luto@kernel.org, mark.rutland@arm.com, mingo@redhat.com, pasha.tatashin@soleen.com, pbonzini@redhat.com, peterz@infradead.org, ptyadav@amazon.de, robh@kernel.org, rostedt@goodmis.org, rppt@kernel.org, saravanak@google.com, skinsburskii@linux.microsoft.com, tglx@linutronix.de, thomas.lendacky@amd.com, will@kernel.org, x86@kernel.org, Changyuan Lyu Content-Type: text/plain; charset="UTF-8" X-Stat-Signature: r34izdrq3wewc3srqtn6iu6kcb446p6h X-Rspamd-Server: rspam01 X-Rspamd-Queue-Id: 04042160002 X-Rspam-User: X-HE-Tag: 1746776843-631231 X-HE-Meta: U2FsdGVkX18RBjcc5VZvqWi4FBYxrOMb+IHWMgb0zWuwu8nFu6n/RlFFx3qZEXpxrrs/O+PkhYEgGNAHuveyUoLWnorY66yTyzgDuEOfQNMzJMKyukOXetXQIlPK41yutvAVe9ln9gCnl05IrjRJj9fOmaq9/goC+yVsBj0HF8osEI5y9+OYb0kUDk9g8CSg7om9Or9bxFweyXBtAwBKoVcF81rjDV1Yarbkg7PualcmBGUE2yi/5rJTA0MHisMok+PyUOXCaNapeUvAGvIv3kKWCwETufL38jDPKv6XycGS5ag0mH2w3HzhbcaRlUN0NvAiTEJu5+SmNGYQVL/6m4AHeEGEbkxnpgxC7XT9HCnHOcgD9lQ3G8xP6dvwc3m4oMM/dzXW4Lpx4TIfCcFmr8b+/wTvzqVK/+YsPNHZZ2toaDuDQ/Zpdef5FZk2KCT5csm4us15UE3MgCSR9ZrILp0UdbUat4Mra2G6E6i5lLZAJd8Eu3VDYfL7IE0MG9uEQcGV6YSmMDdmkJ87FWtOkPVB0OwyYGi5CDrpCunZE+Jf1DvmraUb97O5jDDUulFu2K5OHJRpBFdQ3H7ZHVNJXdGls85D7HpCbCGmgF6zu9k71vY5O1mw5oN8svsfgHT3CDNyreu5XIt4CvVlJ1jHnVnQXk6CBSRpqF6T8JZHVKjocX2Wgbi8MTDHzfKqHMHTkQNbbwukcwyAiJv/yWq2YJlMhOSqmQgHSQvcejFhpI2aQY1pXM3oiRbjGVbUEOD6Acik6yA4oePbIPBqhji1P9TmUd0y8Ndefeq222HRjbBlIV3Sy2QRq20GGZ1xmIK53p3vQxL6DlRCK6LXrI5mzoUhALpcJvPLhXnJrojhb4GykvpUQf7T4z8hDPOD+B/8TnZ1BiJuNLvPPFvX97Y+sjC6nRJR4UEfKuZr47RkPZXrdIaYa/nJBdfNjADCzI+r+55CKi+ScJkhESldX+B SZy7fIMO GjO2Qr5qz/zFz6RqKDG3vTkZHMLIoQ3dmUG9xxoNgG8dNtJp7Qz0DPDKpomsq0sZ9iVxkTIdqpnExMu9R5bhj980LZHRCQtUFzcRB9a1tp60LyBWWpX8uJNeZXt+MuDjp2T0CuuSAr70qlkDkMozrSKgIssdae+LbCIYMbPpjJLkfo6ZsNIRX1OWZ2P9KTaFDtIPCIijow5DNun4lUM4ZFHocjcKYITeYqhxnhUHDqK9GYiCm90shyG+gt864qVS/H0r0Y/UgsNOnjWKrJ5VtUQlqplk6KziAeKWu6mxw5FsOa1B+1HTxllyXfTSvW+zbh+9bnfzkz86qdwCj2uxC8UOKQidkHpiq80krtGpT2OVeErsVQdVTO2dNPRG4ZFqYBxcdfJM5lGONCjxjZwF/0KXCNyUvDsa/Xw7OD9SSWSYR8MCB78FP2LuLUDrqhxq7Gbuzqpcyb/tSjTFEJzUuIE0Mms+oTZtBBtHnO5no4WE+atQzfc4gLLl9Cyg81sqIfxFbc12A+/jEhCBVRYBEUI19jBS0mn7HtfIFOfgFztt3FfQeqtgymPZoaLBq+xDtLJ3FmAc8KYweJiy7Wsaqzq3zr3+5nurnRq/aoLsWosNDjLU9BlMncv+0hpAR0ZphDrkmEljzW+ZQvzTHZUzcYZpNBqglYrtUHfFlVT5LpGCvv/o= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: From: Alexander Graf Linux has recently gained support for "reserve_mem": A mechanism to allocate a region of memory early enough in boot that we can cross our fingers and hope it stays at the same location during most boots, so we can store for example ftrace buffers into it. Thanks to KASLR, we can never be really sure that "reserve_mem" allocations are static across kexec. Let's teach it KHO awareness so that it serializes its reservations on kexec exit and deserializes them again on boot, preserving the exact same mapping across kexec. This is an example user for KHO in the KHO patch set to ensure we have at least one (not very controversial) user in the tree before extending KHO's use to more subsystems. Signed-off-by: Alexander Graf Co-developed-by: Mike Rapoport (Microsoft) Signed-off-by: Mike Rapoport (Microsoft) Co-developed-by: Changyuan Lyu Signed-off-by: Changyuan Lyu --- mm/memblock.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) diff --git a/mm/memblock.c b/mm/memblock.c index 9202c3412bb19..71f3bd943f383 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -18,6 +18,11 @@ #include #include +#ifdef CONFIG_KEXEC_HANDOVER +#include +#include +#endif /* CONFIG_KEXEC_HANDOVER */ + #include #include @@ -2475,6 +2480,189 @@ int reserve_mem_release_by_name(const char *name) return 1; } +#ifdef CONFIG_KEXEC_HANDOVER +#define MEMBLOCK_KHO_FDT "memblock" +#define MEMBLOCK_KHO_NODE_COMPATIBLE "memblock-v1" +#define RESERVE_MEM_KHO_NODE_COMPATIBLE "reserve-mem-v1" +static struct page *kho_fdt; + +static int reserve_mem_kho_finalize(struct kho_serialization *ser) +{ + int err = 0, i; + + for (i = 0; i < reserved_mem_count; i++) { + struct reserve_mem_table *map = &reserved_mem_table[i]; + + err |= kho_preserve_phys(map->start, map->size); + } + + err |= kho_preserve_folio(page_folio(kho_fdt)); + err |= kho_add_subtree(ser, MEMBLOCK_KHO_FDT, page_to_virt(kho_fdt)); + + return notifier_from_errno(err); +} + +static int reserve_mem_kho_notifier(struct notifier_block *self, + unsigned long cmd, void *v) +{ + switch (cmd) { + case KEXEC_KHO_FINALIZE: + return reserve_mem_kho_finalize((struct kho_serialization *)v); + case KEXEC_KHO_ABORT: + return NOTIFY_DONE; + default: + return NOTIFY_BAD; + } +} + +static struct notifier_block reserve_mem_kho_nb = { + .notifier_call = reserve_mem_kho_notifier, +}; + +static int __init prepare_kho_fdt(void) +{ + int err = 0, i; + void *fdt; + + kho_fdt = alloc_page(GFP_KERNEL); + if (!kho_fdt) + return -ENOMEM; + + fdt = page_to_virt(kho_fdt); + + err |= fdt_create(fdt, PAGE_SIZE); + err |= fdt_finish_reservemap(fdt); + + err |= fdt_begin_node(fdt, ""); + err |= fdt_property_string(fdt, "compatible", MEMBLOCK_KHO_NODE_COMPATIBLE); + for (i = 0; i < reserved_mem_count; i++) { + struct reserve_mem_table *map = &reserved_mem_table[i]; + + err |= fdt_begin_node(fdt, map->name); + err |= fdt_property_string(fdt, "compatible", RESERVE_MEM_KHO_NODE_COMPATIBLE); + err |= fdt_property(fdt, "start", &map->start, sizeof(map->start)); + err |= fdt_property(fdt, "size", &map->size, sizeof(map->size)); + err |= fdt_end_node(fdt); + } + err |= fdt_end_node(fdt); + + err |= fdt_finish(fdt); + + if (err) { + pr_err("failed to prepare memblock FDT for KHO: %d\n", err); + put_page(kho_fdt); + kho_fdt = NULL; + } + + return err; +} + +static int __init reserve_mem_init(void) +{ + int err; + + if (!kho_is_enabled() || !reserved_mem_count) + return 0; + + err = prepare_kho_fdt(); + if (err) + return err; + + err = register_kho_notifier(&reserve_mem_kho_nb); + if (err) { + put_page(kho_fdt); + kho_fdt = NULL; + } + + return err; +} +late_initcall(reserve_mem_init); + +static void *__init reserve_mem_kho_retrieve_fdt(void) +{ + phys_addr_t fdt_phys; + static void *fdt; + int err; + + if (fdt) + return fdt; + + err = kho_retrieve_subtree(MEMBLOCK_KHO_FDT, &fdt_phys); + if (err) { + if (err != -ENOENT) + pr_warn("failed to retrieve FDT '%s' from KHO: %d\n", + MEMBLOCK_KHO_FDT, err); + return NULL; + } + + fdt = phys_to_virt(fdt_phys); + + err = fdt_node_check_compatible(fdt, 0, MEMBLOCK_KHO_NODE_COMPATIBLE); + if (err) { + pr_warn("FDT '%s' is incompatible with '%s': %d\n", + MEMBLOCK_KHO_FDT, MEMBLOCK_KHO_NODE_COMPATIBLE, err); + fdt = NULL; + } + + return fdt; +} + +static bool __init reserve_mem_kho_revive(const char *name, phys_addr_t size, + phys_addr_t align) +{ + int err, len_start, len_size, offset; + const phys_addr_t *p_start, *p_size; + const void *fdt; + + fdt = reserve_mem_kho_retrieve_fdt(); + if (!fdt) + return false; + + offset = fdt_subnode_offset(fdt, 0, name); + if (offset < 0) { + pr_warn("FDT '%s' has no child '%s': %d\n", + MEMBLOCK_KHO_FDT, name, offset); + return false; + } + err = fdt_node_check_compatible(fdt, offset, RESERVE_MEM_KHO_NODE_COMPATIBLE); + if (err) { + pr_warn("Node '%s' is incompatible with '%s': %d\n", + name, RESERVE_MEM_KHO_NODE_COMPATIBLE, err); + return false; + } + + p_start = fdt_getprop(fdt, offset, "start", &len_start); + p_size = fdt_getprop(fdt, offset, "size", &len_size); + if (!p_start || len_start != sizeof(*p_start) || !p_size || + len_size != sizeof(*p_size)) { + return false; + } + + if (*p_start & (align - 1)) { + pr_warn("KHO reserve-mem '%s' has wrong alignment (0x%lx, 0x%lx)\n", + name, (long)align, (long)*p_start); + return false; + } + + if (*p_size != size) { + pr_warn("KHO reserve-mem '%s' has wrong size (0x%lx != 0x%lx)\n", + name, (long)*p_size, (long)size); + return false; + } + + reserved_mem_add(*p_start, size, name); + pr_info("Revived memory reservation '%s' from KHO\n", name); + + return true; +} +#else +static bool __init reserve_mem_kho_revive(const char *name, phys_addr_t size, + phys_addr_t align) +{ + return false; +} +#endif /* CONFIG_KEXEC_HANDOVER */ + /* * Parse reserve_mem=nn:align:name */ @@ -2530,6 +2718,11 @@ static int __init reserve_mem(char *p) if (reserve_mem_find_by_name(name, &start, &tmp)) return -EBUSY; + /* Pick previous allocations up from KHO if available */ + if (reserve_mem_kho_revive(name, size, align)) + return 1; + + /* TODO: Allocation must be outside of scratch region */ start = memblock_phys_alloc(size, align); if (!start) return -ENOMEM; -- 2.49.0.1015.ga840276032-goog