From nobody Mon Sep 28 13:18:32 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7543D4756D4; Fri, 21 Aug 2026 10:06:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787306829; cv=none; b=hCzo23xQxYa1ezZsBd0todCwrlaGDo3BrfXA1iysS3sRkk5bib6dN2keF0vX3jyLOOB7pdqSW4tv64GgquMjCVH7vRLK0KaHSaVMVZuZD3jshSOn+NaRzH014Ya2+mzkSLJ/4k3vwFVqE0Hu/DEH0qD5JxzS6iZhz3MRIAbrWps= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787306829; c=relaxed/simple; bh=zsnCaEJjr4WDYRVIG0kIJ3bs7R9uvNp2xzudAoWoA6U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=o/PUIDLRM7Wg1rs2XrB000/2xWee4gT6KqmK+XEUILm7uMrg/CqOR8eRwdB4HRy3OYlXB5lpjzV1yOxg18JBKuamptCiG/xEOCSkCCrw5QJP1TpG+A4/gt+p8mBiL59zjAEkl0uJ9c5D2jfPODOO8fgSkrGmtEWmZz7H1pwKWOg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org; spf=pass smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=JpgEkXdv; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="JpgEkXdv" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=uSbfStPdbr5U0zykVDsBNKewNVAMS5oNdmlQT4Yzkm4=; b=JpgEkXdvDryDyqfLO0w6yqBV2Y po9ZYmBcuuqI6K+8Bngw5grb44nVueQqJqyMib3N12wBXWSTP3kfjJpViJ/KqsWS10+pKLtQXroux 3zs72OdNSfraFY5tvnzRIMOPasTACbKrv7irFHssTWRMwqkrZqxqF0MgtrFDskCuCuzMiWDGyv6n9 11trmB9cEpvrFyXbSHx4T5gRUqghgL+4kERDaojynRBBe69+Mh5YZDRTMfp6hEMJx1f42y+Cp4faK Ve9zBMAX0DYXQaEPNx1lahDGe0fDgiLNriggWzRHsW40wDi10ol3DFJsI0eC7vYI9TeACJDS9Xezb OgZtd8zg==; Received: from authenticated-user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wxM8p-00BGBE-2w; Fri, 21 Aug 2026 10:06:28 +0000 From: Breno Leitao Date: Fri, 21 Aug 2026 03:06:01 -0700 Subject: [PATCH v2 1/6] efi/libstub: add a helper for the top of usable RAM Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-hwpoison-kho-v2-1-5743791e48e6@debian.org> References: <20260821-hwpoison-kho-v2-0-5743791e48e6@debian.org> In-Reply-To: <20260821-hwpoison-kho-v2-0-5743791e48e6@debian.org> To: Ard Biesheuvel , Ilias Apalodimas , Miaohe Lin , Naoya Horiguchi , Andrew Morton Cc: linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, rmikey@meta.com, kas@kernel.org, riel@surriel.com, kexec@lists.infradead.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.16-dev-f8e9d X-Developer-Signature: v=1; a=openpgp-sha256; l=3412; i=leitao@debian.org; h=from:subject:message-id; bh=zsnCaEJjr4WDYRVIG0kIJ3bs7R9uvNp2xzudAoWoA6U=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqiCMa+W8jcyD0u0SyGOn1kbwZALutc1lA3Zhhy qAmTakDK4KJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCaogjGgAKCRA1o5Of/Hh3 bT35D/9SVn4DqMGqAj5kaAZRL6R7KVMcpYT4xdA1bnQ36xXLRr6PlPIy3/U/Avm8oLzAWW8h0/T dSpko6t2GqNkpZYSY8IuELnOGbhlzMtTySVLrEXxcH4gCWWYdxgetVxBTgtJj+9bAiLd3dUhji0 hg7W+VVaskZGhLAenosUqpF3/mwgIO8JWuf55/DrJj9ZY05EBcaU/eWyyZqDvRNX9ENWezAHfYW gDXz2Ib7cyRJSknqb1J0FAFM+xUaiV2P0X0wq2+jyk0COyMd5wWOAMGUc764hQXhmEV2MlVr+Qi LXWEpp9encGy7VnT7uDYRXg8kWsAK/19ivwcBlYO+tuXOmRb7RiB+OkURRv2nqb7Azd0XmlItJn CvbWlmSOoS06/vNZhmzAIFuJ5yf8tZaJEmEkuRa1q7MMcNJtIdA0YDceKm2kt/bbf+hoDgqJz2K qNYqHn1BWMoR4VIbM+ZrpSSTAr3OCpuXF2le6KrbP0PHb+SG1MPSGJTPKIr5TMJAUR+/jrX04xV 9WUeW4FasYe5O9C/izHkbKCql1JrHv2/q2cUPN4rCwjPhPW9QA6eVgETQ/8hXeAf7V/YxYojrlY GkMu0GuBk6f3sfjOtJfAKfXRyVu6l4ljhLKWQ3v54aBtxVD8PKnUSLn91ZD6FH6E6PwfWdVKIYu kW1eajB8O7w2lFg== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao The stub has no way to ask how far RAM reaches, which is useful to create a bitmap that covers the whole memory. max_pfn answers that for the kernel, but it is only set in setup_arch(), long after the stub has handed off, so, unfortunately we cannot use it here.. Add efi_get_ram_top(), which returns the highest address reached by the entry types that become usable RAM. Unaccepted memory is counted as well, as suggested by Kiryl. Memory the firmware hot-adds later is *not* in the memory map, so it is not covered; that matches max_pfn, which is likewise the top of the memory present at boot. Signed-off-by: Breno Leitao --- drivers/firmware/efi/libstub/efistub.h | 2 ++ drivers/firmware/efi/libstub/mem.c | 53 ++++++++++++++++++++++++++++++= ++++ 2 files changed, 55 insertions(+) diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/= libstub/efistub.h index fd91fc15ec810..77ba576779aca 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -1094,6 +1094,8 @@ char *efi_convert_cmdline(efi_loaded_image_t *image); efi_status_t efi_get_memory_map(struct efi_boot_memmap **map, bool install_cfg_tbl); =20 +efi_status_t efi_get_ram_top(u64 *top); + efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr, unsigned long max); =20 diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libs= tub/mem.c index 59f3f83de50c2..777f1f180c66e 100644 --- a/drivers/firmware/efi/libstub/mem.c +++ b/drivers/firmware/efi/libstub/mem.c @@ -64,6 +64,59 @@ efi_status_t efi_get_memory_map(struct efi_boot_memmap *= *map, return EFI_SUCCESS; } =20 +/** + * efi_get_ram_top() - find the top of usable RAM + * @top: on return, the end of the highest memory map entry that becomes + * usable RAM + * + * Walk the UEFI memory map for the entry types that become usable RAM, th= e set + * setup_e820() maps to E820_TYPE_RAM, and return the highest address any = of + * them reaches. Memory a confidential guest has not accepted yet counts as + * well, since it becomes RAM once accepted. This is what the stub has in = place + * of max_pfn, which is only set once the kernel proper is up. + * + * Memory the firmware hot-adds later is not described by the memory map a= nd so + * is not accounted for here. + * + * Return: status code + */ +efi_status_t efi_get_ram_top(u64 *top) +{ + struct efi_boot_memmap *map __free(efi_pool) =3D NULL; + efi_status_t status; + u64 ram_top =3D 0; + int i, nr_desc; + + status =3D efi_get_memory_map(&map, false); + if (status !=3D EFI_SUCCESS) + return status; + + nr_desc =3D map->map_size / map->desc_size; + for (i =3D 0; i < nr_desc; i++) { + efi_memory_desc_t *d; + + d =3D efi_memdesc_ptr((unsigned long)map->map, map->desc_size, i); + switch (d->type) { + case EFI_LOADER_CODE: + case EFI_LOADER_DATA: + case EFI_BOOT_SERVICES_CODE: + case EFI_BOOT_SERVICES_DATA: + case EFI_CONVENTIONAL_MEMORY: + case EFI_UNACCEPTED_MEMORY: + ram_top =3D max(ram_top, + d->phys_addr + d->num_pages * EFI_PAGE_SIZE); + break; + default: + break; + } + } + if (!ram_top) + return EFI_NOT_FOUND; + + *top =3D ram_top; + return EFI_SUCCESS; +} + /** * efi_allocate_pages() - Allocate memory pages * @size: minimum number of bytes to allocate --=20 2.53.0-Meta From nobody Mon Sep 28 13:18:32 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 72747472F9B; Fri, 21 Aug 2026 10:06:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787306826; cv=none; b=E6Sj38oFftAMiXZerUT+JGqVEfD5W7q78d7Khb/oSMi0IK71E/IojPZunYuxP3ISpVm/nVz1aYNlm+qY+lxdEDG34b+WjjFAiMKYS9HA+7Y3GC1QE0R82XZ1YM1rsYu9e+YMJPA+0ZPYULEQY17IER+IBEEB0hQnzMLRzfihzak= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787306826; c=relaxed/simple; bh=Z/vnT9K1G8JkfMrXbm/2Q9zXt1siFCixL2PK45FYBZE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ebtabbN+idt3IhLXQuqMa0lSlQTgK9MxOxtybkdnPgQOmhLdtAbmiratUakTDpcD5kHKEFWsYrJlU6afOB3MNDM7b7o1SE/Hy65zTiYdvfx6hFiD3833cZPjvZOJKRS0qtLBjfWhqI9PJcBIcE6E+J0zRqSDfc/I6npiwnVcb1M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org; spf=pass smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=iGManAEd; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="iGManAEd" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=GijpPHV/MlnALkvostyEz/qvgq+mkhNTyT2lnEH+3cc=; b=iGManAEdaf1RslOR2kQtj60Uau 2cPekOu/rvVOIMx+a/RdULWoQqOizOXh9q2ResBctGch27Ylb26QCtMYYfgmdE0XpZOAsBFzMamnL 6BFmHMrcpmbyp1X293U+Dzi56na2S7mreb8TCnLeDRv7lIvfYUztITa+wd8S28EnULOIjsdp6zCz2 ygwkTFKI7KZ1LE+ByVAiwUyKRgo+NDY87YkDiTYcgxtzTT7FUH1OThNQG2yKJFvJORcEbRjnbmn6T jH/d5KqWpDiJzP6Q6SQwrbQbOOIDievRHSFNWQHnRifdGuRIe3jS17kLLO4AF8VTd6MJ3x+TDNTWS DjHeOyLw==; Received: from authenticated-user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wxM8u-00BGBG-16; Fri, 21 Aug 2026 10:06:32 +0000 From: Breno Leitao Date: Fri, 21 Aug 2026 03:06:02 -0700 Subject: [PATCH v2 2/6] efi: add the LINUX_EFI_POISONED_MEMORY configuration table Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-hwpoison-kho-v2-2-5743791e48e6@debian.org> References: <20260821-hwpoison-kho-v2-0-5743791e48e6@debian.org> In-Reply-To: <20260821-hwpoison-kho-v2-0-5743791e48e6@debian.org> To: Ard Biesheuvel , Ilias Apalodimas , Miaohe Lin , Naoya Horiguchi , Andrew Morton Cc: linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, rmikey@meta.com, kas@kernel.org, riel@surriel.com, kexec@lists.infradead.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.16-dev-f8e9d X-Developer-Signature: v=1; a=openpgp-sha256; l=4479; i=leitao@debian.org; h=from:subject:message-id; bh=Z/vnT9K1G8JkfMrXbm/2Q9zXt1siFCixL2PK45FYBZE=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqiCMaQOgra0AgIH7Fhhk615ZgT/EKbr1P24x+f vcF/X/ROlaJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCaogjGgAKCRA1o5Of/Hh3 bbwQD/9xKGVGX5YWvlXXOMyaxbNwxB6OkudoXxGeuMi480JxdrtEbNG9MKwYTTv+hBls5nFsxOs PCOU1GsJSwPEqeByAAOJUv9WCo/izqKh7nERh7ft/ZdZSwd8SroxpkL/5ZQ8U8HRRq7D6leBHUp eK7J1vgRdboT7WVSt4sU8iG9psRa35T4D++40LNwoH9WrlHsw94+tRils2g6fS2DmaRBbitQGDG 0BVBo1RFRhYRxH8Fmjcb6Ll633456uZzbvD5KmUrH1bJRfvJeLHBn7cu345txlsZHRwWj4640bS R47Ayqj5pV/UCuBoUskVSeud8qf2bIr0Q3KWKxc92biz9d4tBTZOZ4O4JvX+r0OQ8qCu1q1bpe7 GAf9iuKPhgjSHvozRIKj0k+qvmdowhOOt9gYieCf4WvuYp396iJ6xIOUptwyRURhZg1Ys7w5Yyj TPIwogIuh8fVqZQO6LaBQMcxVGvpkZSaOzw2kMwDFMRV2YXibFj9jUlZzTaGJBkso/dIe5AijRh yciexX3E9NOeG/eY9g3FHxM0vcg4JvyTaNdkxw/GR6S9LvTgDVlolK4TUmkFrbv/JmgJRkntw08 2lznEos9GOe4K1+6lmLvcIlLKXZaGAmxi4tCyMoLhzdbwpne9cjplDV+9h0qLABHoxqIvOvpXu7 5eFmHY2Z6fn+Eaw== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao Hardware-poisoned page frames are tracked only in the running kernel's data structures, so a kexec loses them and the next kernel doesn't have this information, thus, tripping into them again. Add an EFI configuration table to carry that information across kexec. It is a bitmap with one bit per EFI_POISON_UNIT_SIZE (2MiB) of physical memory, modeled on the LINUX_EFI_UNACCEPTED_MEMORY table, and it rides the EFI system table to every kernel in the chain. Suggested-by: Kiryl Shutsemau Signed-off-by: Breno Leitao --- drivers/firmware/efi/Kconfig | 10 ++++++++++ drivers/firmware/efi/efi.c | 6 ++++++ include/linux/efi.h | 13 +++++++++++++ 3 files changed, 29 insertions(+) diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 29e0729299f5b..69c0dc02bc112 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -263,6 +263,16 @@ config EFI_COCO_SECRET virt/coco/efi_secret module to access the secrets, which in turn allows userspace programs to access the injected secrets. =20 +config EFI_POISONED_MEMORY + bool "Carry hardware-poisoned pages across kexec" + depends on EFI_STUB && MEMORY_FAILURE && 64BIT + help + Record page frames that are hardware-poisoned while this kernel runs + into an EFI configuration table, and honor that table early on the + next kernel so a kexec does not hand known-bad RAM back out. + + If unsure, say N. + config OVMF_DEBUG_LOG bool "Expose OVMF firmware debug log via sysfs" depends on EFI diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 0327a39d31fa5..111e60479211a 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -55,6 +55,9 @@ struct efi __read_mostly efi =3D { #ifdef CONFIG_UNACCEPTED_MEMORY .unaccepted =3D EFI_INVALID_TABLE_ADDR, #endif +#ifdef CONFIG_EFI_POISONED_MEMORY + .poisoned_memory =3D EFI_INVALID_TABLE_ADDR, +#endif }; EXPORT_SYMBOL(efi); =20 @@ -646,6 +649,9 @@ static const efi_config_table_type_t common_tables[] __= initconst =3D { #ifdef CONFIG_UNACCEPTED_MEMORY {LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID, &efi.unaccepted, "Unaccepted" }, #endif +#ifdef CONFIG_EFI_POISONED_MEMORY + {LINUX_EFI_POISONED_MEMORY_TABLE_GUID, &efi.poisoned_memory, "POISON" }, +#endif #ifdef CONFIG_EFI_GENERIC_STUB {LINUX_EFI_PRIMARY_DISPLAY_TABLE_GUID, &primary_display_table }, #endif diff --git a/include/linux/efi.h b/include/linux/efi.h index b3c83516593d1..ce0980a5bb81b 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -23,6 +23,7 @@ #include #include #include +#include #include =20 #include @@ -422,6 +423,7 @@ void efi_native_runtime_setup(void); #define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x48= 4c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47) #define LINUX_EFI_BOOT_MEMMAP_GUID EFI_GUID(0x800f683f, 0xd08b, 0x423a, = 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4) #define LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID EFI_GUID(0xd5d1de3c, 0x105c, 0= x44f9, 0x9e, 0xa9, 0xbc, 0xef, 0x98, 0x12, 0x00, 0x31) +#define LINUX_EFI_POISONED_MEMORY_TABLE_GUID EFI_GUID(0x78a5bf07, 0x7d2a, = 0x2889, 0x16, 0x31, 0x63, 0xd4, 0x56, 0xf2, 0x83, 0x50) =20 #define RISCV_EFI_BOOT_PROTOCOL_GUID EFI_GUID(0xccd15fec, 0x6f73, 0x4eec,= 0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf) =20 @@ -650,6 +652,7 @@ extern struct efi { unsigned long mokvar_table; /* MOK variable config table */ unsigned long coco_secret; /* Confidential computing secret table */ unsigned long unaccepted; /* Unaccepted memory table */ + unsigned long poisoned_memory; /* Hardware-poisoned memory table */ =20 efi_get_time_t *get_time; efi_set_time_t *set_time; @@ -1271,6 +1274,16 @@ struct linux_efi_memreserve { #define EFI_MEMRESERVE_COUNT(size) (((size) - sizeof(struct linux_efi_memr= eserve)) \ / sizeof_field(struct linux_efi_memreserve, entry[0])) =20 +struct linux_efi_poisoned_memory { + u32 version; + u32 unit_size; /* bytes of phys space per bitmap bit */ + u64 phys_base; /* phys address covered by bit 0 */ + u64 size; /* bitmap size in bytes */ + unsigned long bitmap[]; +}; + +#define EFI_POISON_UNIT_SIZE SZ_2M + void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size); =20 /* --=20 2.53.0-Meta From nobody Mon Sep 28 13:18:32 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8B4BB47605C; Fri, 21 Aug 2026 10:06:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787306821; cv=none; b=VSmwq3q6YFr9eH2FEfnU75iTA7hkgqucwaEmGuHbTSDuaeRSoncdVJftSiYxMFta4aQRWqwm1qbXBWI1Zv1ojXBbja0l3y2/c51OrmlFitcdENjL4oyaViUOypgrRzZf1ECVEHEMNwgbSSwz45rKHtqzw/unqPQuPvbcUPaGoLA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787306821; c=relaxed/simple; bh=PTHqnbiTjtXvlEVFVF9aFX37DcM4Tdef+z9pkL5DEHI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gWglZUzY+zbfjTRKIVjaDHbeZbZU8bZg2UYW28pTpnpQnuy/wGTm9PncNQzvApuJla9PYLRhavnOz/k7LSd5XkIJdVoHn2B4S8TIs0wqlpzjczcwOUkd1eLKRCUiDssotRdXAFyV0Uu/Zl3yFjKcVOn+pseu2JZgDxRzYcVm0/g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org; spf=pass smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=d3fGZ/2J; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="d3fGZ/2J" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=J9aqNAg5ul6RSq/FAIbOKx+XdwPAzQxJAO/zzCdAwHg=; b=d3fGZ/2JK5ycFLowGuvx2sagko DBQC52aw4xCgc1cWiJbV9UIZom2VHDYnjCdzz4+Zs7vfUzWC9oWMy2wvhCXLPtTXVohubf+jl/8WL GHZg1C1sKs1U3I72psWlyb1VIr8I8nGdzyhcCjny5UKMt5NbHxQE3xz5N88QiCGoDXM/tpGnyK+cc xLaGOF2RhrWVCKNwptPd7+DLoWzAZBVXhrkHmY+v97JsTUtYNJZvlWZpRj/iRqnGYH1PQppHiKjGg o6/LHvG9QSGIWKWMiwCM4iOQAgFT7FiefMM38b7sNMdTIS/LfBwbyRB5XgvU8YpvTZEJNzdU9wrJa aFMZU6UQ==; Received: from authenticated-user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wxM8z-00BGBQ-0B; Fri, 21 Aug 2026 10:06:37 +0000 From: Breno Leitao Date: Fri, 21 Aug 2026 03:06:03 -0700 Subject: [PATCH v2 3/6] efi/libstub: add the poisoned-memory EFI table Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-hwpoison-kho-v2-3-5743791e48e6@debian.org> References: <20260821-hwpoison-kho-v2-0-5743791e48e6@debian.org> In-Reply-To: <20260821-hwpoison-kho-v2-0-5743791e48e6@debian.org> To: Ard Biesheuvel , Ilias Apalodimas , Miaohe Lin , Naoya Horiguchi , Andrew Morton Cc: linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, rmikey@meta.com, kas@kernel.org, riel@surriel.com, kexec@lists.infradead.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.16-dev-f8e9d X-Developer-Signature: v=1; a=openpgp-sha256; l=4996; i=leitao@debian.org; h=from:subject:message-id; bh=PTHqnbiTjtXvlEVFVF9aFX37DcM4Tdef+z9pkL5DEHI=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqiCMaNchcVhpLMCWBvw7ck5ypAhOqMQ6wjKKz4 yvqQ/qq1eiJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCaogjGgAKCRA1o5Of/Hh3 bVD/D/0cN7PIq53NaWJ3IfCKiuNgIT98qPysaWAKjlETFbTUAQ1ql+39PrqBCdKE+THtkfP67Er DvsnOCjOXbWvAmFm9gqHdKX1dA4ugJHZRNFITE4uN2q7cDGFOeFVyzojQIuflFeCoRc9GovH8KH 6BGU1quCuQWBocXDYLzILv//F3gXL47DO4IdI211yz+4jsOO0xPFEslQNQGXL7Q7UbRs46a3RzO P2jNzMggLWP9v8QbyM10ERON/iKEdxowGYdsQThd1STszA4xWHwQ+nZ30INvFCdxL4v2+SvsT8e JHxJbFjLeLDGkHMaK0+YmWF9JvjU7iInpO2zDVfNr2DE9u0wWALpZXDq/gYWDwh2rNozVXcfx7q 1bWpej1lcTO/Z/lTjdbOay1iEv+xkyM+R3FaFB0K4EjzTfn2BqQItmwe1kLKKLSYNOCKO42PyrZ Snor5pRDsihsAxDXXhf+KQTdfCDwdvsqZfSiQA9ubP4qadteH22Uw7pQ7HaZXDqnZtvR4W34Bnh EoRFa3fF8JMIPuPsw47d1tVtXUOjXmfIV3dVQ43KGcc6UpwvPNNY0aDTOOksGdZynw8s0PxstCt tD3psHOQMQDZTO0vlqHTfhW4guGQZFmQJzyHzjyaaY7cExTdWGYEMeiXarWgg0IYHN0Apn3YomL uzN/V/b6T+Gbreg== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao A EFI config table can only be installed while boot services are still up, so the stub has to create it; the running kernel can only flip bits in a table that already exists. Size the bitmap from efi_get_ram_top(): bit N covers unit N counting from address 0, up to the top of usable RAM, so the table tracks max_pfn. Memory the firmware hot-adds later sits above it and is not carried across a kexec. At one bit per 2M that is 64K per TiB. The 2M granule is called "unit" here. Cap the bitmap at 1M to make sure this doesn't get too big. The next kernel reads unit_size back out of the table, so a wider unit only costs precision: more memory withheld per poisoned frame, nothing lost. Allocate it as EFI_ACPI_RECLAIM_MEMORY so the next kernel does not take it for free RAM, and install it empty. A table installed by an earlier boot rides the system table across kexec and is reused as-is. Nothing calls it yet; the stub entry paths pick it up next. Signed-off-by: Breno Leitao --- drivers/firmware/efi/libstub/efi-stub-helper.c | 89 ++++++++++++++++++++++= ++++ drivers/firmware/efi/libstub/efistub.h | 6 ++ 2 files changed, 95 insertions(+) diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmw= are/efi/libstub/efi-stub-helper.c index f27f2e1f00199..7258ecdf1f7c2 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -774,3 +774,92 @@ void efi_remap_image(unsigned long image_base, unsigne= d alloc_size, efi_warn("Failed to remap data region non-executable\n"); } } + +#ifdef CONFIG_EFI_POISONED_MEMORY +/* Cap on the bitmap; a span too wide to fit gets a coarser unit instead. = */ +#define EFI_POISON_MAX_TABLE_SIZE SZ_1M +#define EFI_POISON_MAX_UNIT_SIZE SZ_1G + +/* + * Bitmap geometry for a given top of RAM. The bitmap starts at address 0,= so + * bit N covers unit N. + * In the following code, a "unit" is granule of physical address space th= at one + * bitmap bit covers. + */ +static u32 efi_poison_geometry(u64 ram_top, u64 *bitmap_size) +{ + u64 nr_units =3D DIV_ROUND_UP(ram_top, EFI_POISON_UNIT_SIZE); + u32 unit_size =3D EFI_POISON_UNIT_SIZE; + + while (DIV_ROUND_UP(nr_units, BITS_PER_BYTE) > EFI_POISON_MAX_TABLE_SIZE = && + unit_size < EFI_POISON_MAX_UNIT_SIZE) { + nr_units =3D DIV_ROUND_UP(nr_units, 2); + unit_size *=3D 2; + } + + *bitmap_size =3D DIV_ROUND_UP(nr_units, BITS_PER_BYTE); + return unit_size; +} + +/* ACPI reclaim memory, so the next kernel does not treat it as free RAM. = */ +static struct linux_efi_poisoned_memory *efi_poison_alloc(u64 bitmap_size, + u32 unit_size) +{ + struct linux_efi_poisoned_memory *pm; + efi_status_t status; + + status =3D efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY, + sizeof(*pm) + bitmap_size, (void **)&pm); + if (status !=3D EFI_SUCCESS) + return NULL; + + pm->version =3D 1; + pm->unit_size =3D unit_size; + pm->phys_base =3D 0; + pm->size =3D bitmap_size; + memset(pm->bitmap, 0, bitmap_size); + + return pm; +} + +/* + * Allocate and install the poisoned-memory bitmap while boot services are + * available + */ +void install_poisoned_memory_table(void) +{ + efi_guid_t poisoned_memory_table_guid =3D LINUX_EFI_POISONED_MEMORY_TABLE= _GUID; + struct linux_efi_poisoned_memory *pm; + u64 ram_top, bitmap_size; + efi_status_t status; + u32 unit_size; + + /* A table installed by an earlier boot rides the system table across kex= ec. */ + pm =3D get_efi_config_table(poisoned_memory_table_guid); + if (pm) { + if (pm->version !=3D 1) + efi_err("Unknown version of poisoned-memory table\n"); + return; + } + + if (efi_get_ram_top(&ram_top) !=3D EFI_SUCCESS) { + efi_err("Failed to size the poisoned-memory table!\n"); + return; + } + + unit_size =3D efi_poison_geometry(ram_top, &bitmap_size); + + pm =3D efi_poison_alloc(bitmap_size, unit_size); + if (!pm) { + efi_err("Failed to allocate poisoned-memory table!\n"); + return; + } + + status =3D efi_bs_call(install_configuration_table, + &poisoned_memory_table_guid, pm); + if (status !=3D EFI_SUCCESS) { + efi_bs_call(free_pool, pm); + efi_err("Failed to install poisoned-memory config table!\n"); + } +} +#endif diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/= libstub/efistub.h index 77ba576779aca..b5e19ba50ddae 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -1171,6 +1171,12 @@ efi_enable_reset_attack_mitigation(void) { } =20 void efi_retrieve_eventlog(void); =20 +#ifdef CONFIG_EFI_POISONED_MEMORY +void install_poisoned_memory_table(void); +#else +static inline void install_poisoned_memory_table(void) { } +#endif + struct sysfb_display_info *alloc_primary_display(void); struct sysfb_display_info *__alloc_primary_display(void); void free_primary_display(struct sysfb_display_info *dpy); --=20 2.53.0-Meta From nobody Mon Sep 28 13:18:32 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 72346470136; Fri, 21 Aug 2026 10:06:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787306824; cv=none; b=UVc5HKd+2yfEEnd0RoGJ6yS6Tt1/1WVM98CkYTvVrdjs9Eu6DIBdzPdqplMysunfXydp6DAlulDRDPVuir1OqXwbZgDvq8lE6Py3Qj4S5PZHojisVJiYLBSfE9BGJxJnMOpCpww3Xy2BTH36VXWi9K3sckPOrSvVAfuvJIy7St8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787306824; c=relaxed/simple; bh=C5EuuwpNY5nvk98hyZjVmVyrfx8vi+SqUwzV/WPLKts=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=g4wTz+XzPQrKTa82/ZZh9ofxWkFJrZtnSS0HvVeTFpPHCiZTwjtfUUGG9bkdW8SUj7LaQUPTQAGprkBNCa9FKxhOTFsyZGxrQrR+WtP4U7VQxb4sLf9SV5WECwHB5gHmGqka5jyJlik+zM+REmk1YcRGvRgtvfMi4wkrWcAbgGE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org; spf=pass smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=AXjvKfsH; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="AXjvKfsH" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=TWUgrg2oyif/z+3LRHUgpEMONMbKe31piyu+fjgyTPk=; b=AXjvKfsHRrlUy/85X/g+r0/wvs 5DG0fiowafk/zPk/acmEyRjV/KlM0elacpnox/ob9oO4uYc9hMcPv65xjjvaFX+BlCwGv4qjSHfgG QcKUnWafqX86nz5TtczUQiiYj23FMHpWyQULqnrjQJvyhk4ZWA71Hf4AUds80tndb9SS7qe9gyZTk 9ItsYoDjdbWfEV4gW4oUlvYJVx5ApWYXPWULFzErttrczEy4ireCV+JE0+nzLA3keuSuw7jGV0Cth pMjviVHvQXA4yoh85zKSWLYNr0IFNNaCQW4+x0sc4r8ZEHyNrU4L19EHSL8UT+7Wv1tr7wENCmoaJ yfLn94gQ==; Received: from authenticated-user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wxM93-00BGBj-1G; Fri, 21 Aug 2026 10:06:41 +0000 From: Breno Leitao Date: Fri, 21 Aug 2026 03:06:04 -0700 Subject: [PATCH v2 4/6] efi/libstub: install the poisoned-memory table from the stub Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-hwpoison-kho-v2-4-5743791e48e6@debian.org> References: <20260821-hwpoison-kho-v2-0-5743791e48e6@debian.org> In-Reply-To: <20260821-hwpoison-kho-v2-0-5743791e48e6@debian.org> To: Ard Biesheuvel , Ilias Apalodimas , Miaohe Lin , Naoya Horiguchi , Andrew Morton Cc: linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, rmikey@meta.com, kas@kernel.org, riel@surriel.com, kexec@lists.infradead.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.16-dev-f8e9d X-Developer-Signature: v=1; a=openpgp-sha256; l=1559; i=leitao@debian.org; h=from:subject:message-id; bh=C5EuuwpNY5nvk98hyZjVmVyrfx8vi+SqUwzV/WPLKts=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqiCMaDftorVUDCaUHLSwpSUmd8hWjXyWY4oOXI ryUjhDKDbGJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCaogjGgAKCRA1o5Of/Hh3 bRrvD/9HZjdZmiXO+WacXh65YCVhn2MyGUVpEgcGoMQfmso15ErjMO93KJzMYBcz8nP2MoN3RQT ExgpjFq5TgjmMtn6kixUuJeMoNauEYJURdhfoxEFOmtKvceN6vGs8Gv+dMV4ioklRcWhcUBvKd+ UkLqi1X/Cjy1Iba0aIUSsQhpx6ZH7NEB6JfksmbevOOgarNY50zL/QQr3o6AlhTJyFPeA2L0vkr Gr79L6/Q/sJR5gVU+95frI7uXA76JqMFzfm1nue7jylyEVig7bMPuY2i1trHbvLhFtcL4u9sWcU M+J6cQy/zzEFdmPZJZHT1zWLAUMOj/oy+hH1Nxbf8HHsG38KOiaTNrU3gJNWrusKEY98hGkHZoX 0gSH62z9uJiEzmecV6xmgHINCQ2CeVuEtTxZYnKaR/j9UQeO+Rs3sXHT9lbyOgup0buRbfjMpc1 BXH9RqFXPREaI493li88NNGxGP6LqZpxlG/NNMAWHgGItNzGd0/fPcI13VSt0gbKNIhOAH7MFdb d1QpHTrRQ/HS2o0RvLmD9X0unM1Pec1ZjEmctBULGlesSOrMr9eP4rU1miCgL0BjSVYgOulVuyH CxRmEjr4iBFnxO0er4olzAwigHnSbbkSlwyLGeUAiF4SK5lDoopcMDHxu/sfrlkQXSlErXTTMLk mYILtAkfNfZh8eQ== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao Call install_poisoned_memory_table() while boot services are still up, so the table exists before the kernel that will flip bits in it runs. x86 does not go through efi_stub_common(), so the generic stub and the x86 stub each need the call; on x86 it has to come before exit_boot(), which is the last point a configuration table can be installed. Signed-off-by: Breno Leitao --- drivers/firmware/efi/libstub/efi-stub.c | 1 + drivers/firmware/efi/libstub/x86-stub.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi= /libstub/efi-stub.c index 42d6073bcd062..008635eb5027a 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -179,6 +179,7 @@ efi_status_t efi_stub_common(efi_handle_t handle, EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP); =20 install_memreserve_table(); + install_poisoned_memory_table(); =20 status =3D efi_boot_kernel(handle, image, image_addr, cmdline_ptr); =20 diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi= /libstub/x86-stub.c index cef32e2c82d8f..f90de11bc8855 100644 --- a/drivers/firmware/efi/libstub/x86-stub.c +++ b/drivers/firmware/efi/libstub/x86-stub.c @@ -1023,6 +1023,8 @@ void __noreturn efi_stub_entry(efi_handle_t handle, =20 setup_unaccepted_memory(); =20 + install_poisoned_memory_table(); + status =3D exit_boot(boot_params, handle); if (status !=3D EFI_SUCCESS) { efi_err("exit_boot() failed!\n"); --=20 2.53.0-Meta From nobody Mon Sep 28 13:18:32 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 788503932F0; Fri, 21 Aug 2026 10:07:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787306833; cv=none; b=lkHaMat3cMIkrcbvzR4HiBTJjh2yAti548qXlJXtLDb0Yfzd5AhEPzbyplk3Mzu0eZbuC9XQOH+FOBK0w3EGwG8suA1PGFlsBBZde9pXKGUJMGepG7VQhy82APUIixC7NqMPQOWjk5fQMT/BJh2I63reSYBVBKgUR9ExCaHVAGQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787306833; c=relaxed/simple; bh=lWWIEjhuVgXrSedCC6Ci+SxjCAerQM0bIwFhF7iWBwk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tEEzcmnFDu6Xjf7Gx0Bvj0QX1Z3uw9TL5lI8r4elb8xDE5S0+tE+7561T9l7XCex5BenJkGG82MUJkJ1fSfxeILX2T8HGyKmjqjeduEL6mabPRF5IT6/bYgGewvnX8+Qa2M79Lpfq/dTkCxo9PYOWdkR1naWkJLPe8P3xLR+ePE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org; spf=pass smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=mKXagGDK; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="mKXagGDK" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=Da1CWZALucIaRBUeETb+igOf65zQLydAHdg2K0GnubI=; b=mKXagGDKJLVneYlwEdigYndfQw 1mEFjLB9WKlOEcBzknkiea42hyXZun3ERd29AthAl/3Aw4rbOHdv28xtug/V4e7y9pVZ62dcnCMyZ eTTBTIo/nX8l++3Fs1yagZAdSjAesjdbpns5gWeYtFxj8blWazG5AKmvPFpK2PUwIEzLycWHf+Ewj /N1+8W8GicZYDbFapUYUiiBWA3c2KQOodGCesHjgrN7cIX+IYOk0PLbkKPtrQsiZ/fyH4uZf2OEm6 d9BuIchhIxKcUx5t2ytHBA0uj/94nBcGy9d4iLWyyhVbmapQte1KQxEBFfrvQ2n9dTsLXQwjWLFjW oCTPSoTA==; Received: from authenticated-user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wxM97-00BGBw-2h; Fri, 21 Aug 2026 10:06:46 +0000 From: Breno Leitao Date: Fri, 21 Aug 2026 03:06:05 -0700 Subject: [PATCH v2 5/6] efi: record hardware-poisoned frames into the poisoned-memory table Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-hwpoison-kho-v2-5-5743791e48e6@debian.org> References: <20260821-hwpoison-kho-v2-0-5743791e48e6@debian.org> In-Reply-To: <20260821-hwpoison-kho-v2-0-5743791e48e6@debian.org> To: Ard Biesheuvel , Ilias Apalodimas , Miaohe Lin , Naoya Horiguchi , Andrew Morton Cc: linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, rmikey@meta.com, kas@kernel.org, riel@surriel.com, kexec@lists.infradead.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.16-dev-f8e9d X-Developer-Signature: v=1; a=openpgp-sha256; l=6912; i=leitao@debian.org; h=from:subject:message-id; bh=lWWIEjhuVgXrSedCC6Ci+SxjCAerQM0bIwFhF7iWBwk=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqiCMagImGhYCNupSzFcmMTFpU0hwmHaEe+j5ab QCBtZQBztyJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCaogjGgAKCRA1o5Of/Hh3 bdlKD/0R0D67QRzyfCB/qpVSpAVO6PMBhhDYOyWsLrycnJcm98PDAO68wuR9JXf/04LbHxJaKUx GXWLPITI60/ULF6LdZCzpYaUf4rpnK6vraM9t4M0bpqUkF14+lc6HxjcKo59OgtacBxcVlJhFXx g7OO5swDEgwkcgVHq0Ig810rGo2ZscSgtX8Di52kdRnbFd5gLMJBev8bL6uPQuel5VXwUNaeuVN Ca9jj3mhO9czJAvTmb0ITOQS/V3/cKoewetvWvoi223H8bx7nOy1QOsvRTecq5ifuAzhmmGuDrv lNucuKLFJAy61TNdGHxmGbqbusYwNMgVvOihC9Br0VnUWQeMDi6UwESzDcXnFT+qiF4sFD5ooHc aexaH2V+h4tTbJ2s2+w+fwoKhE1yExSRdAwLrUqG95xC9LecO8mf5AQlsPV3R1dyh0r9G/rNlHm 5LJtAIfiaa2rDS37nOyK5UOuHz3AUX75oe2ylckY5P46YEtj79/nmN7PYQWucNr7Z6DCZZQTbWV tVkU7ofwJ4heMBCDgEYr+zg8L0ZoOtfe8xs8x84xIZGI8deQ+m10aAVL02DqP0fey9RRrWspZOr t0YygL2bI7CT21rF+ZamVC3w/vG4kLHuMzFNqEWdMCL2Hqci0SO2d2NchiqC8v2FirssI0O6ITu 6xsFQY2jdQSCUkA== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao action_result() is where memory_failure() reports the outcome of a hard offline, so hook it to set the frame's bit in the LINUX_EFI_POISONED_MEMORY bitmap. Soft-offlined pages reach num_poisoned_pages_inc() through page_handle_poison() and are deliberately left out: they are still functional and were offlined predictively, so recording them would turn a prediction into a permanent loss for every kernel further down the kexec chain. A bit is only ever set, never cleared, given that multiple pages can set the same bit, and it is not trivial to decide if the bit should be unset when a page is unrecorded. Unpoisoning a frame therefore does not hand its unit back to the next kernel. That is a known limitation. memory_failure() has already taken the frame out of this kernel's allocator, so only the cross-kexec record happens here. Suggested-by: Kiryl Shutsemau Signed-off-by: Breno Leitao --- drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/poison.c | 130 ++++++++++++++++++++++++++++++++++++++= ++++ include/linux/efi.h | 6 ++ mm/memory-failure.c | 3 + 4 files changed, 140 insertions(+) diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index 8efbcf699e4ff..05d0a490923e5 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile @@ -43,4 +43,5 @@ obj-$(CONFIG_EFI_EARLYCON) +=3D earlycon.o obj-$(CONFIG_UEFI_CPER_ARM) +=3D cper-arm.o obj-$(CONFIG_UEFI_CPER_X86) +=3D cper-x86.o obj-$(CONFIG_UNACCEPTED_MEMORY) +=3D unaccepted_memory.o +obj-$(CONFIG_EFI_POISONED_MEMORY) +=3D poison.o obj-$(CONFIG_TEE_STMM_EFI) +=3D stmm/tee_stmm_efi.o diff --git a/drivers/firmware/efi/poison.c b/drivers/firmware/efi/poison.c new file mode 100644 index 0000000000000..2f47293a4e45f --- /dev/null +++ b/drivers/firmware/efi/poison.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Runtime handling for the LINUX_EFI_POISONED_MEMORY configuration table:= a + * bitmap with one bit per EFI_POISON_UNIT_SIZE of physical memory that re= cords + * hardware-poisoned frames so the next kexec kernel can keep them out of = its + * allocator. The stub installs the (empty) bitmap; this kernel sets bits = at + * runtime. + * + * Copyright (c) 2026 Meta Platforms, Inc. and affiliates. + * Copyright (c) 2026 Breno Leitao + */ + +#define pr_fmt(fmt) "efi: " fmt + +#include +#include +#include +#include +#include +#include + +static struct linux_efi_poisoned_memory *efi_poison __ro_after_init; + +/* A non-empty bitmap on a power-of-2 grid that phys_base actually sits on= . */ +static bool __init +efi_poison_geometry_valid(const struct linux_efi_poisoned_memory *pm) +{ + if (!pm->size) + return false; + if (pm->unit_size < PAGE_SIZE || !is_power_of_2(pm->unit_size)) + return false; + + return IS_ALIGNED(pm->phys_base, pm->unit_size); +} + +/* The range the bitmap claims to describe has to fit in a u64. */ +static bool __init +efi_poison_range_valid(const struct linux_efi_poisoned_memory *pm) +{ + u64 nbits, span; + + if (check_mul_overflow(pm->size, (u64)BITS_PER_BYTE, &nbits)) + return false; + if (check_mul_overflow(nbits, (u64)pm->unit_size, &span)) + return false; + + return !check_add_overflow(pm->phys_base, span, &span); +} + +/* + * The table may have been installed by an earlier kernel in the kexec cha= in, + * so check its geometry before doing any arithmetic with it. + */ +static bool __init +efi_poison_table_valid(const struct linux_efi_poisoned_memory *pm) +{ + if (pm->version !=3D 1) { + pr_warn("Ignoring poisoned-memory table with version %u\n", + pm->version); + return false; + } + + if (!efi_poison_geometry_valid(pm) || !efi_poison_range_valid(pm)) { + pr_warn("Ignoring malformed poisoned-memory table\n"); + return false; + } + + return true; +} + +static int __init efi_poison_init(void) +{ + struct linux_efi_poisoned_memory *pm; + u64 size; + + if (efi.poisoned_memory =3D=3D EFI_INVALID_TABLE_ADDR) + return 0; + + /* Map the header to learn the bitmap size, then map the whole table. */ + pm =3D memremap(efi.poisoned_memory, sizeof(*pm), MEMREMAP_WB); + if (WARN_ON_ONCE(!pm)) + return 0; + if (!efi_poison_table_valid(pm)) { + memunmap(pm); + return 0; + } + size =3D pm->size; + memunmap(pm); + + efi_poison =3D memremap(efi.poisoned_memory, sizeof(*pm) + size, + MEMREMAP_WB); + WARN_ON_ONCE(!efi_poison); + return 0; +} +early_initcall(efi_poison_init); + +/* Bitmap unit covering @pfn, or -1 if the pfn falls outside the table. */ +static long efi_poison_unit(unsigned long pfn) +{ + phys_addr_t addr =3D PFN_PHYS(pfn); + u64 unit; + + if (addr < efi_poison->phys_base) + return -1; + unit =3D (addr - efi_poison->phys_base) / efi_poison->unit_size; + if (unit >=3D (u64)efi_poison->size * BITS_PER_BYTE) + return -1; + return unit; +} + +/* + * Record a hardware-poisoned frame so the next kernel keeps its unit out = of the + * allocator. memory_failure() has already removed the frame from this ker= nel. + * + * A bit is never cleared: one bit stands for a whole EFI_POISON_UNIT_SIZE= , so + * an unpoison cannot tell whether the unit as a whole is good again. + */ +void efi_hwpoison_record_pfn(unsigned long pfn) +{ + long unit; + + if (!efi_poison) + return; + + unit =3D efi_poison_unit(pfn); + if (unit < 0) + return; + + set_bit(unit, efi_poison->bitmap); +} diff --git a/include/linux/efi.h b/include/linux/efi.h index ce0980a5bb81b..f03b1bb576133 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1284,6 +1284,12 @@ struct linux_efi_poisoned_memory { =20 #define EFI_POISON_UNIT_SIZE SZ_2M =20 +#ifdef CONFIG_EFI_POISONED_MEMORY +void efi_hwpoison_record_pfn(unsigned long pfn); +#else +static inline void efi_hwpoison_record_pfn(unsigned long pfn) { } +#endif + void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size); =20 /* diff --git a/mm/memory-failure.c b/mm/memory-failure.c index aaf14608b30e2..357a72ffda625 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -1286,6 +1287,8 @@ static int action_result(unsigned long pfn, enum mf_a= ction_page_type type, if (type !=3D MF_MSG_ALREADY_POISONED && type !=3D MF_MSG_PFN_MAP) { num_poisoned_pages_inc(pfn); update_per_node_mf_stats(pfn, result); + /* Only hard offlines are carried over to the next kernel. */ + efi_hwpoison_record_pfn(pfn); } =20 pr_err("%#lx: recovery action for %s: %s\n", --=20 2.53.0-Meta From nobody Mon Sep 28 13:18:32 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 71EDC474258; Fri, 21 Aug 2026 10:07:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787306835; cv=none; b=AuLk+f8+mkYXfsaw451LeQM0hqju7JXStEoFR8+B3TvWg0Pu7LG8tPBihuIBo12oA6YN9M/E1v9SZLiIU3XOmRl6jmNaDkCa0T0IMlzSVYNiKmfhXWCYrrHFC+qjJlZWxtDqpoIGSmsyUvxDt3Mg50QgEZbUWWouvFybQ5EqExg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787306835; c=relaxed/simple; bh=Xsp5t/AjlrO67qweZEiBvofZ/A1yR4ej/H2a8cEi3f8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CmXwtbPkOGHAueGMCByDJ8DUyS6OHZhISAlquo9VYRtDtUwq5nz1PMdXOLN6zdxcp2o576R0/RXVDTC2n8KNwrlbh7LKMWmg9Cwy/QvPldVlrzxPwWQfyMID9oHhU7BsKmfXGe3y6BKKzHrEsF0tblUR0HUZBwpKa2vHWQkBBJw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org; spf=pass smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=MlayavnH; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="MlayavnH" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=clgEu5ocwrJ3/2sMRprXhyjnlGpexA9HwN+YHsN7hWE=; b=MlayavnHGn93lBnpvs956q0XXD CVT+1RGs2pahyXBKzbABxG5K9HCaqueKoaMRMlRJlxoYTruWY+ViP9hC9ggDwSa7p/xp6CVXfiYBF Vkb/5h/+iGhZ0SMb/usYLoXRqfu8B/Uv5ZRg4+wIA5XCYg/Moojlgz9XZyHEOHSQzTYImSZLRx0gp ndgIoMz1pVbt7Q/NTZCvVtwgLmRdkToCfEc3gneLx1YnsXyu7jJvSRBwaA80QVPm4VIZeECOFIYgV 6D5EmSzBV7DP1LTe+NSG1FAB2NfipYX1D4LlenITVvl8Y97FvZBFlyDnkEvEVhayB86P05bQZwG0D tPbmeQvQ==; Received: from authenticated-user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wxM9C-00BGCh-0e; Fri, 21 Aug 2026 10:06:50 +0000 From: Breno Leitao Date: Fri, 21 Aug 2026 03:06:06 -0700 Subject: [PATCH v2 6/6] efi: respect the poisoned pages coming from previous kernel Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260821-hwpoison-kho-v2-6-5743791e48e6@debian.org> References: <20260821-hwpoison-kho-v2-0-5743791e48e6@debian.org> In-Reply-To: <20260821-hwpoison-kho-v2-0-5743791e48e6@debian.org> To: Ard Biesheuvel , Ilias Apalodimas , Miaohe Lin , Naoya Horiguchi , Andrew Morton Cc: linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, rmikey@meta.com, kas@kernel.org, riel@surriel.com, kexec@lists.infradead.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.16-dev-f8e9d X-Developer-Signature: v=1; a=openpgp-sha256; l=4736; i=leitao@debian.org; h=from:subject:message-id; bh=Xsp5t/AjlrO67qweZEiBvofZ/A1yR4ej/H2a8cEi3f8=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqiCMaLD0gMUB4x31WYY7Fkyu5rCsTlY48ZbsVw Nj6u6XVr3uJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCaogjGgAKCRA1o5Of/Hh3 bX8cD/kBHVlSr41tBzDeV+jCDztGEjkDtT4IWUNxuOkogpCQezn/v6qS40A8wDFiNHJFSXDbAKx rtgqpRfApNGBuCI3kw6A1v/hmQGPaqdIo7Z4qSwy0ThsszkBZ2I2TBvDwL8C/eEEV9NklYeiF0y Jaav/ViHoSnLsaq77+gX3G1vLYYA8BhkRFazDF9imjYp8+vT+WTEIblxYzXG2B/a0ptHQaLn2VB ig/KL/jhwH7ncyfMig0bC0z/LbmQa7s0JdTXUSM7amzpllpgNW5yiV/CBIJ2xxcJtJnnRceU9dG BeInri9f9Ph27Zhyw2kRB7vVC/7uDGw/s1r6RjAUrCTeamf5sB2vdGl3Zg2xJ8bpYBXHkyBNFb8 sGmmVIRJw+aZNplMEtGSUMceZoWGFXnrmaOCi3TUNxUfGtuZMF8Zc6ZrJBOpJ6fYW6/WqmRrKBA uqIsr0cE4uNUxBWSzO5YsTeuutpBfJYmulEBwIQSZjQAbeoNHjtIZLuMSAzAgPeJMdxOEaVLalc IzWFCsG0L/dTguYbx7Jxm9sWwP4krI3vzqYy/yKaLtwTCFg26qY8oJKydmVGZWNgapQsXjyj/cL blpYLbmyzaDkOL8RomhW5VZxKMKR079hL+ZT0EklfZwjKhv1vLLVsoLfc8nr05AY6n8KZemvcaD G5RQ0RnqrD7GxtQ== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao On kexec next kernel, walk the LINUX_EFI_POISONED_MEMORY bitmap during EFI init -- before memblock hands memory to the buddy allocator -- and memblock_reserve() every unit whose bit is set. So a frame poisoned under a previous kernel is never handed back out across a kexec. This runs from efi_config_parse_tables(), early enough to keep the frames out of memblock and the buddy allocator. Signed-off-by: Breno Leitao --- drivers/firmware/efi/efi.c | 2 ++ drivers/firmware/efi/poison.c | 71 +++++++++++++++++++++++++++++++++++++++= ++-- include/linux/efi.h | 2 ++ 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 111e60479211a..7474eeebb0add 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -812,6 +812,8 @@ int __init efi_config_parse_tables(const efi_config_tab= le_t *config_tables, } } =20 + efi_reserve_poisoned_memory(); + if (rt_prop !=3D EFI_INVALID_TABLE_ADDR) { efi_rt_properties_table_t *tbl; =20 diff --git a/drivers/firmware/efi/poison.c b/drivers/firmware/efi/poison.c index 2f47293a4e45f..e418c6b3aab81 100644 --- a/drivers/firmware/efi/poison.c +++ b/drivers/firmware/efi/poison.c @@ -3,8 +3,9 @@ * Runtime handling for the LINUX_EFI_POISONED_MEMORY configuration table:= a * bitmap with one bit per EFI_POISON_UNIT_SIZE of physical memory that re= cords * hardware-poisoned frames so the next kexec kernel can keep them out of = its - * allocator. The stub installs the (empty) bitmap; this kernel sets bits = at - * runtime. + * allocator. The stub allocates and installs the (empty) bitmap; this ker= nel + * sets bits at runtime; the next kernel reserves the set units before the + * allocator comes up. * * Copyright (c) 2026 Meta Platforms, Inc. and affiliates. * Copyright (c) 2026 Breno Leitao @@ -16,6 +17,8 @@ #include #include #include +#include +#include #include #include =20 @@ -128,3 +131,67 @@ void efi_hwpoison_record_pfn(unsigned long pfn) =20 set_bit(unit, efi_poison->bitmap); } + +void __init efi_reserve_poisoned_memory(void) +{ + u64 ppm =3D efi.poisoned_memory, phys_base, unit_size, bitmap_size, off; + struct linux_efi_poisoned_memory *pm; + unsigned int nr_units =3D 0; + + if (ppm =3D=3D EFI_INVALID_TABLE_ADDR) + return; + + pm =3D early_memremap(ppm, sizeof(*pm)); + if (!pm) { + pr_warn("Could not map poisoned-memory table\n"); + return; + } + + if (!efi_poison_table_valid(pm)) { + /* Keep the runtime side off a table this pass rejected. */ + efi.poisoned_memory =3D EFI_INVALID_TABLE_ADDR; + early_memunmap(pm, sizeof(*pm)); + return; + } + + phys_base =3D pm->phys_base; + unit_size =3D pm->unit_size; + bitmap_size =3D pm->size; + + early_memunmap(pm, sizeof(*pm)); + + /* Reserve the table itself so it survives a further kexec. */ + memblock_reserve(PAGE_ALIGN_DOWN(ppm), + PAGE_ALIGN(ppm + sizeof(*pm) + bitmap_size) - + PAGE_ALIGN_DOWN(ppm)); + + /* + * Walk the bitmap a page at a time and reserve each poisoned unit. + * memblock.memory is not populated this early, so memblock_remove() + * and memblock_mark_nomap() would be no-ops; a reservation is what + * keeps the units away from the allocator. + */ + for (off =3D 0; off < bitmap_size; off +=3D PAGE_SIZE) { + u64 chunk =3D min_t(u64, PAGE_SIZE, bitmap_size - off); + unsigned long bit, nbits =3D chunk * BITS_PER_BYTE; + unsigned long *map; + + map =3D early_memremap(ppm + offsetof(struct linux_efi_poisoned_memory, + bitmap) + off, chunk); + if (!map) { + pr_warn("Could not map poisoned-memory bitmap\n"); + return; + } + for_each_set_bit(bit, map, nbits) { + u64 unit =3D off * BITS_PER_BYTE + bit; + + memblock_reserve(phys_base + unit * unit_size, unit_size); + nr_units++; + } + early_memunmap(map, chunk); + } + + if (nr_units) + pr_info("reserved %u poisoned unit(s) (%lluK each) inherited across kexe= c\n", + nr_units, unit_size >> 10); +} diff --git a/include/linux/efi.h b/include/linux/efi.h index f03b1bb576133..350a3cb0babdd 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1285,8 +1285,10 @@ struct linux_efi_poisoned_memory { #define EFI_POISON_UNIT_SIZE SZ_2M =20 #ifdef CONFIG_EFI_POISONED_MEMORY +void efi_reserve_poisoned_memory(void); void efi_hwpoison_record_pfn(unsigned long pfn); #else +static inline void efi_reserve_poisoned_memory(void) { } static inline void efi_hwpoison_record_pfn(unsigned long pfn) { } #endif =20 --=20 2.53.0-Meta