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 6C4FCC3ABBC for ; Fri, 9 May 2025 07:47:09 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id E5B456B00BC; Fri, 9 May 2025 03:47:04 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id DE5C66B00BE; Fri, 9 May 2025 03:47:04 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id AADB66B00C1; Fri, 9 May 2025 03:47:04 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 73CCE6B00BC for ; Fri, 9 May 2025 03:47:04 -0400 (EDT) Received: from smtpin28.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 9EB68CBA46 for ; Fri, 9 May 2025 07:47:05 +0000 (UTC) X-FDA: 83422588410.28.54AFE63 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.202]) by imf29.hostedemail.com (Postfix) with ESMTP id D0656120002 for ; Fri, 9 May 2025 07:47:03 +0000 (UTC) Authentication-Results: imf29.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=vErJWZ09; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf29.hostedemail.com: domain of 39rIdaAoKCBs381E7PL1EC7FF7C5.3FDC9ELO-DDBM13B.FI7@flex--changyuanl.bounces.google.com designates 209.85.210.202 as permitted sender) smtp.mailfrom=39rIdaAoKCBs381E7PL1EC7FF7C5.3FDC9ELO-DDBM13B.FI7@flex--changyuanl.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1746776823; a=rsa-sha256; cv=none; b=e6lBJiGkyLuAW1f8nSydw299J9wj/h4Xs1g186xUeg0+d2l1NtSdtRxjaWsdT/5Wh5Eyn6 Nghi40uIrGkohLei66lQVeuZCWQEWcYJmXFdX6bQCVsG4S81jpCh/V1CUG0IJLSjCtNM9M SzQeGlGfPFaJjWZl8Axebllr/OKSWuc= ARC-Authentication-Results: i=1; imf29.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=vErJWZ09; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf29.hostedemail.com: domain of 39rIdaAoKCBs381E7PL1EC7FF7C5.3FDC9ELO-DDBM13B.FI7@flex--changyuanl.bounces.google.com designates 209.85.210.202 as permitted sender) smtp.mailfrom=39rIdaAoKCBs381E7PL1EC7FF7C5.3FDC9ELO-DDBM13B.FI7@flex--changyuanl.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1746776823; 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=wqZ/LMVUIexBccat841AMmJztq2TGQ9rs5gX6EhC3VY=; b=OYKs7ZhFcWjdlUljxgdloG6NCwjx7zWvKYLbqXis/1JybdcNxLeiW5SAjQ+RVgx2Qa+yS3 h9d2mL3H7Cf9kS/94YCSe0pCU5fM2E0xJ9Z1Gv/f3MhpYQs6USNAe9nH0CH39u5WLQ8g0j w8hD7PdlIgOcDViKONFNNxUoogzV214= Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-74243ab539dso59363b3a.3 for ; Fri, 09 May 2025 00:47:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746776823; x=1747381623; 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=wqZ/LMVUIexBccat841AMmJztq2TGQ9rs5gX6EhC3VY=; b=vErJWZ09ViMAjPsmbL1B/twPFkkTtrHI9T/QdoREhgIohodWXJbmeJcPR4CpSHKC+S StRW9yCFScRGUUo1xGb4o8K1sfFHep5PmT70T1gozb2SX0c7KDwQc/LCxflvqYLDrmO0 skmxfcUf/hgVWNGwOmYcX2kb7T/BWpjJjAbZ8MU5qsz6dz/abWJiUSkb7b14AiLxCF9W VPFDhNgFLasrgkFmc4nDnQBf+1W9zQ2/+z046tEfl9uKY0UnHoHZCLWQH3k+nSY8W8D8 yARKcbY0DFscRo4Nhj2MhL8R3emHnBzXzKkWfANvppCC8zU2Rz5T2VXY7wA8Gpe2l1hh 27DA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746776823; x=1747381623; 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=wqZ/LMVUIexBccat841AMmJztq2TGQ9rs5gX6EhC3VY=; b=IXDVUbpGVSGQgDg9oDg12kvLFFaWmKaAags1mmHOsgXaVQ24im5Rwh20zRCU+bRdsE tLsibP9WwvcNtmYPc87Fz5+SosraBEhRClO/lwRPV8sQVNvuCtpvpmqg38lwKmvhTqI3 YSITDxRezhIJAUskdjJBh3M1A4cQ6mKvd8ypD2pZoQd0J/hi4u0eTOCqC3OHp3MOYfkK rNMEeXVdPxLit3nIQNNq8M62+QmO7rzTBb/GOXx90tHXk3BvFpReyAC94aeuqkd8jgHX r+cswExagJpg1+bsRgzUK8xP50egibfj6zLyyL4ok1Y/4AFGsWcOpVYRMZP7mkOIO4os vrYQ== X-Forwarded-Encrypted: i=1; AJvYcCV1/Ieo/33sTDJ4Dkq29O5SWOMozkN1NvvBIGLSasSpyYCUanzwx5RSX+8T6gVCQ5MtDKTG4vNcEQ==@kvack.org X-Gm-Message-State: AOJu0YwJo+JCFy9tRSTRaGk9hlrfWUVnyu9XuTsrgZfUheen9Ky/bZQX yHnBj8Doo4etDVdQQn9JU/VjC3JAldaLmtdtGlP0aVXvtRESTLPmmnMe9xSugfTMevVMpy9m9xR vWfeSmrUbI7vL16mqBQ== X-Google-Smtp-Source: AGHT+IHKqSVutKeNYLWyP6sC5tlz+ty21eEvwjrDNs3QbU+OREsI4XiHb8dFNRZwPZweJP8k4l3lRdHa5KS1De4J X-Received: from pgmn24.prod.google.com ([2002:a63:5c58:0:b0:b1f:9534:4f55]) (user=changyuanl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:6f07:b0:203:addb:5a29 with SMTP id adf61e73a8af0-215abc78929mr3789624637.40.1746776822730; Fri, 09 May 2025 00:47:02 -0700 (PDT) Date: Fri, 9 May 2025 00:46:23 -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-6-changyuanl@google.com> Subject: [PATCH v8 05/17] kexec: add KHO parsing support 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-Rspamd-Queue-Id: D0656120002 X-Rspam-User: X-Rspamd-Server: rspam07 X-Stat-Signature: 51brxyitwqbsqcs4qohkdxp7bkxrxzpz X-HE-Tag: 1746776823-213458 X-HE-Meta: U2FsdGVkX1+JFO9Z8v2zPZPjN+gLcoAMiAWfihy7MvCtMG/bewhKyvvCjN00He1P1tIptKhW73SuE2BFccGTT8ZfPAWVxm+w25L87t7xN9zGSZ85sxajNiC0Wj845GFFhmdyhuhwQ5RfgHaB73AD0nUBSQJFvoRxE1U3vnst+4qPE1lbBRN2A1S+o+AuDT4pRY6fTXVjblUvdo4TNYVRa5TT+VFCuKpV9pJt0LRUJvx9NiLqwdCCmYihayKUuQB02ml1+z/otcUChwNowWZELkTULqN8d4PMcMCM7SlPWGMezdCufr/QrACSuW2dxwG41HGbxqCQ3XoZBAX89tv1G+yxaZFu2uSky6jy9xCTjMax4gmDca5ZmVvBkV+BfRVeRPff3FGOj87nKe7XW+0YwE9SOI3kxZ/NLfxi4V73BhWgvwdTdv5JHGgJJnRNycBnlaAcKBThWErRRWlrwLr8fMNx0EiWIp0WcG2AazgFXAZB6iVRkref1koJoShZ3zbwj4x3Mswp4NcvFDSe5cObqSnmvH6E1qY8taD/yvEIevXW0X1wHW7jbgTtvY/hJpZw0QTeVZmcIqJJe+0esSdOFJSdGCaMovpI63dRgGY85FnR4KoZ8v52QNejl58IOaeCq6UtzSZhs19+l43/Kti861Ag1zp0XgubivBksItVbRbZjbziFIkNpUUj9742Dh5Gyz7W5hFyL2z3WuVAj5WrHzWcwZCazOrBFrr0WIG3SpWjgjVQDFHw7NMOViBavvcZU704saNLxv2UApQdH66qTk9Txo7+W0xUSAoPAF/shX3yYMiwECdyo+oY2qjqalnG/sVsIIMNKkwABW2gBBCL7Fp3L094OovAabpXFvrwaujtTi/JZclkPHt1u1Tv3Kr8GSyUMdYYmcHZXCUi6fdvLk41W0XzBxT24KjszTCEwW++U9TP3XXkStfxlRKNQ/WMmvS6ngdC++BCs1GDJWe sv7BHpjO 2DLxmjdBI3E20H5KCD4QzShBcHBJsIk7v4YiyFG6qgk5Joy8+ObHd0vMvZ6C/lKLD6rh/JBCntPg2iyEOEufUdVf9QaSyEh+6hwdQHfiZNZcRoVm+50alkwREbipUD0R/MMPriXZ8JSuOkno8bkCWTj3JgDj6Jc2HdV394BOBcxdMQF3NWTxuyYz8t+zCmaHoZS5508MtF6aHIEp7ZTPqNx4+8etV7s2D6gMnl1xoT3bgplBaPIWZ4iIE+1W62PulW8O2AEP4MO8DsECJl44MDlfbBQ4PDocI6ZRn7BKcPN5Fk8Cp/G+lHcfKXVaaHNxyNP3lSkglIJeYM2DrRHTWQMWTq7Sd/AQRa/ZaY0ba7QJ67AeyjfzSksczmRE0NQ3eSTtANTmT1/KIuTbVNRDChw9pI1Do18de4FzbkcRU04bmhh6rV2ZN2e//xWlh9IB+Wl1d4yTXDvagY1bl4EAKzjY8m6Rm/ZXZXoUb8GmshqDVT+akDOUwlRYkf57xL/HXMPNLCjIjeZGtxLq9SPxO7Atmetv2QzPoBbaXlbQ2NDeQzHmKpe1hTI08j6ENIEPbenr2k6lBlnXHeb0LsgPbo84dzLc70Yd5e08WTfsxnIyZewoiujObCmijRA== 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 When we have a KHO kexec, we get an FDT blob and scratch region to populate the state of the system. Provide helper functions that allow architecture code to easily handle memory reservations based on them and give device drivers visibility into the KHO FDT and memory reservations so they can recover their own state. Include a fix from Arnd Bergmann https://lore.kernel.org/lkml/20250424093302.3894961-1-arnd@kernel.org/. Signed-off-by: Alexander Graf Signed-off-by: Arnd Bergmann Co-developed-by: Mike Rapoport (Microsoft) Signed-off-by: Mike Rapoport (Microsoft) Co-developed-by: Changyuan Lyu Signed-off-by: Changyuan Lyu --- include/linux/kexec_handover.h | 14 ++ kernel/kexec_handover.c | 233 ++++++++++++++++++++++++++++++++- mm/memblock.c | 1 + 3 files changed, 247 insertions(+), 1 deletion(-) diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h index 2e19004776f6b..02dcfc8c427e3 100644 --- a/include/linux/kexec_handover.h +++ b/include/linux/kexec_handover.h @@ -24,11 +24,15 @@ struct kho_serialization; bool kho_is_enabled(void); int kho_add_subtree(struct kho_serialization *ser, const char *name, void *fdt); +int kho_retrieve_subtree(const char *name, phys_addr_t *phys); int register_kho_notifier(struct notifier_block *nb); int unregister_kho_notifier(struct notifier_block *nb); void kho_memory_init(void); + +void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_phys, + u64 scratch_len); #else static inline bool kho_is_enabled(void) { @@ -41,6 +45,11 @@ static inline int kho_add_subtree(struct kho_serialization *ser, return -EOPNOTSUPP; } +static inline int kho_retrieve_subtree(const char *name, phys_addr_t *phys) +{ + return -EOPNOTSUPP; +} + static inline int register_kho_notifier(struct notifier_block *nb) { return -EOPNOTSUPP; @@ -54,6 +63,11 @@ static inline int unregister_kho_notifier(struct notifier_block *nb) static inline void kho_memory_init(void) { } + +static inline void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, + phys_addr_t scratch_phys, u64 scratch_len) +{ +} #endif /* CONFIG_KEXEC_HANDOVER */ #endif /* LINUX_KEXEC_HANDOVER_H */ diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index e541d3d5003d1..59f3cf9557f50 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -17,6 +17,9 @@ #include #include #include + +#include + /* * KHO is tightly coupled with mm init and needs access to some of mm * internal APIs. @@ -501,9 +504,112 @@ static __init int kho_out_debugfs_init(void) return -ENOENT; } +struct kho_in { + struct dentry *dir; + phys_addr_t fdt_phys; + phys_addr_t scratch_phys; + struct list_head fdt_list; +}; + +static struct kho_in kho_in = { + .fdt_list = LIST_HEAD_INIT(kho_in.fdt_list), +}; + +static const void *kho_get_fdt(void) +{ + return kho_in.fdt_phys ? phys_to_virt(kho_in.fdt_phys) : NULL; +} + +/** + * kho_retrieve_subtree - retrieve a preserved sub FDT by its name. + * @name: the name of the sub FDT passed to kho_add_subtree(). + * @phys: if found, the physical address of the sub FDT is stored in @phys. + * + * Retrieve a preserved sub FDT named @name and store its physical + * address in @phys. + * + * Return: 0 on success, error code on failure + */ +int kho_retrieve_subtree(const char *name, phys_addr_t *phys) +{ + const void *fdt = kho_get_fdt(); + const u64 *val; + int offset, len; + + if (!fdt) + return -ENOENT; + + if (!phys) + return -EINVAL; + + offset = fdt_subnode_offset(fdt, 0, name); + if (offset < 0) + return -ENOENT; + + val = fdt_getprop(fdt, offset, PROP_SUB_FDT, &len); + if (!val || len != sizeof(*val)) + return -EINVAL; + + *phys = (phys_addr_t)*val; + + return 0; +} +EXPORT_SYMBOL_GPL(kho_retrieve_subtree); + +/* Handling for debugfs/kho/in */ + +static __init int kho_in_debugfs_init(const void *fdt) +{ + struct dentry *sub_fdt_dir; + int err, child; + + kho_in.dir = debugfs_create_dir("in", debugfs_root); + if (IS_ERR(kho_in.dir)) + return PTR_ERR(kho_in.dir); + + sub_fdt_dir = debugfs_create_dir("sub_fdts", kho_in.dir); + if (IS_ERR(sub_fdt_dir)) { + err = PTR_ERR(sub_fdt_dir); + goto err_rmdir; + } + + err = kho_debugfs_fdt_add(&kho_in.fdt_list, kho_in.dir, "fdt", fdt); + if (err) + goto err_rmdir; + + fdt_for_each_subnode(child, fdt, 0) { + int len = 0; + const char *name = fdt_get_name(fdt, child, NULL); + const u64 *fdt_phys; + + fdt_phys = fdt_getprop(fdt, child, "fdt", &len); + if (!fdt_phys) + continue; + if (len != sizeof(*fdt_phys)) { + pr_warn("node `%s`'s prop `fdt` has invalid length: %d\n", + name, len); + continue; + } + err = kho_debugfs_fdt_add(&kho_in.fdt_list, sub_fdt_dir, name, + phys_to_virt(*fdt_phys)); + if (err) { + pr_warn("failed to add fdt `%s` to debugfs: %d\n", name, + err); + continue; + } + } + + return 0; + +err_rmdir: + debugfs_remove_recursive(kho_in.dir); + return err; +} + static __init int kho_init(void) { int err = 0; + const void *fdt = kho_get_fdt(); if (!kho_enable) return 0; @@ -524,6 +630,20 @@ static __init int kho_init(void) if (err) goto err_free_fdt; + if (fdt) { + err = kho_in_debugfs_init(fdt); + /* + * Failure to create /sys/kernel/debug/kho/in does not prevent + * reviving state from KHO and setting up KHO for the next + * kexec. + */ + if (err) + pr_err("failed exposing handover FDT in debugfs: %d\n", + err); + + return 0; + } + for (int i = 0; i < kho_scratch_cnt; i++) { unsigned long base_pfn = PHYS_PFN(kho_scratch[i].addr); unsigned long count = kho_scratch[i].size >> PAGE_SHIFT; @@ -551,7 +671,118 @@ static __init int kho_init(void) } late_initcall(kho_init); +static void __init kho_release_scratch(void) +{ + phys_addr_t start, end; + u64 i; + + memmap_init_kho_scratch_pages(); + + /* + * Mark scratch mem as CMA before we return it. That way we + * ensure that no kernel allocations happen on it. That means + * we can reuse it as scratch memory again later. + */ + __for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE, + MEMBLOCK_KHO_SCRATCH, &start, &end, NULL) { + ulong start_pfn = pageblock_start_pfn(PFN_DOWN(start)); + ulong end_pfn = pageblock_align(PFN_UP(end)); + ulong pfn; + + for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) + set_pageblock_migratetype(pfn_to_page(pfn), + MIGRATE_CMA); + } +} + void __init kho_memory_init(void) { - kho_reserve_scratch(); + if (kho_in.scratch_phys) { + kho_scratch = phys_to_virt(kho_in.scratch_phys); + kho_release_scratch(); + } else { + kho_reserve_scratch(); + } +} + +void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len, + phys_addr_t scratch_phys, u64 scratch_len) +{ + void *fdt = NULL; + struct kho_scratch *scratch = NULL; + int err = 0; + unsigned int scratch_cnt = scratch_len / sizeof(*kho_scratch); + + /* Validate the input FDT */ + fdt = early_memremap(fdt_phys, fdt_len); + if (!fdt) { + pr_warn("setup: failed to memremap FDT (0x%llx)\n", fdt_phys); + err = -EFAULT; + goto out; + } + err = fdt_check_header(fdt); + if (err) { + pr_warn("setup: handover FDT (0x%llx) is invalid: %d\n", + fdt_phys, err); + err = -EINVAL; + goto out; + } + err = fdt_node_check_compatible(fdt, 0, KHO_FDT_COMPATIBLE); + if (err) { + pr_warn("setup: handover FDT (0x%llx) is incompatible with '%s': %d\n", + fdt_phys, KHO_FDT_COMPATIBLE, err); + err = -EINVAL; + goto out; + } + + scratch = early_memremap(scratch_phys, scratch_len); + if (!scratch) { + pr_warn("setup: failed to memremap scratch (phys=0x%llx, len=%lld)\n", + scratch_phys, scratch_len); + err = -EFAULT; + goto out; + } + + /* + * We pass a safe contiguous blocks of memory to use for early boot + * purporses from the previous kernel so that we can resize the + * memblock array as needed. + */ + for (int i = 0; i < scratch_cnt; i++) { + struct kho_scratch *area = &scratch[i]; + u64 size = area->size; + + memblock_add(area->addr, size); + err = memblock_mark_kho_scratch(area->addr, size); + if (WARN_ON(err)) { + pr_warn("failed to mark the scratch region 0x%pa+0x%pa: %d", + &area->addr, &size, err); + goto out; + } + pr_debug("Marked 0x%pa+0x%pa as scratch", &area->addr, &size); + } + + memblock_reserve(scratch_phys, scratch_len); + + /* + * Now that we have a viable region of scratch memory, let's tell + * the memblocks allocator to only use that for any allocations. + * That way we ensure that nothing scribbles over in use data while + * we initialize the page tables which we will need to ingest all + * memory reservations from the previous kernel. + */ + memblock_set_kho_scratch_only(); + + kho_in.fdt_phys = fdt_phys; + kho_in.scratch_phys = scratch_phys; + kho_scratch_cnt = scratch_cnt; + pr_info("found kexec handover data. Will skip init for some devices\n"); + +out: + if (fdt) + early_memunmap(fdt, fdt_len); + if (scratch) + early_memunmap(scratch, scratch_len); + if (err) + pr_warn("disabling KHO revival: %d\n", err); } diff --git a/mm/memblock.c b/mm/memblock.c index b9148822db7aa..9202c3412bb19 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -2377,6 +2377,7 @@ void __init memblock_free_all(void) free_unused_memmap(); reset_all_zones_managed_pages(); + memblock_clear_kho_scratch_only(); pages = free_low_memory_core_early(); totalram_pages_add(pages); } -- 2.49.0.1015.ga840276032-goog