Re: [PATCH v5 7/9] drivers/base/memory: count inherited poisoned frames into the block
From: David Hildenbrand (Arm)
Date: Tue Sep 22 2026 - 07:36:03 EST
On 9/21/26 16:31, Breno Leitao wrote:
> On Fri, Sep 18, 2026 at 10:16:25PM +0200, David Hildenbrand (Arm) wrote:
>> On 9/18/26 17:22, Breno Leitao wrote:
>>>
>>> Right, we have two source for poisoned page information, today.
>>>
>>> 1) LINUX_EFI_POISONED_MEMORY: Used to track memory block that got
>>> poisioned, and will be passed around during kexec.
>>> 2) PG_hwpoison on struct page: Used by the memory subsystem to avoid
>>> touching it.
>>
>> How are both kept in sync? See below.
>
> The EFI table is only written when there is a memory failure. That is
> the only thing that writes to it:
>
> action_result() -> efi_hwpoison_record_pfn() -> set_bit()
>
> You can see it on patch "mm/memory-failure: efi: record
> hardware-poisoned frames into the poisoned-memory table"
>
> Then, when the kernel kexecs into a second kernel, the EFI config table
> is queried and the pages are poisoned from it at boot, as they are
> getting into the buddy allocator, in __free_pages_core().
I am not sure that is really the right place. That means we only poison free
memory. Shouldn't we poison as soon as we initialize the memmap, and check
whether any memblock allocations ended up on that poisoned memory and bail out?
[...]
>
>>> You might ask why I do not just count the bits set in the bitmape and
>>> multiply by the frames a unit covers.
>>>
>>> That was my first try. It over-counts: a bit stands for a whole 2M unit,
>>> but only the frames that reach __free_pages_core() get flagged -- CMA
>>> comes back through __free_pages(), the initrd and __init memory through
>>> free_reserved_pages(), and KHO-preserved frames never get an initialised
>>> struct page at all.
>>
>> Why are other hwpoisoned pages not flagged? If initrd or anything else is
>> hwpoisoned, we should not be running this kernel?
>
> For the initrd and the image, the previous kernel's record cannot stop
> this kernel's loader from placing them on a bad frame. If that happens
> we consumed the poison in the relocation memcpy, long before any of this
> code runs. That is the kexec segment placement problem, which Kiryl
> raised on the RFC and which I split into its own series, which is landed
> in some mm tree already.
>
> https://lore.kernel.org/all/20260812-kexec_posioned-v6-0-e477887086f0@xxxxxxxxxx/
>
>
>>>
>>> And the over-count cannot be undone later.
>>
>> The inconsistency is worrisome.
>> I wouldn't say that I hate it but it certainly has "great, more hwpoison hacks"
>> smell to it.
>>
>> We have enough semi-broken hwpoison ... stuff ... in our code base already. So
>> I'm hoping we're not adding more to it?
>>
>>> If the walk itself is what bothers you, the way out is not the bitmap
>>> but counting as we flag: hwpoison_boot_page() already knows the pfn, so
>>> it can bump a per-block-id counter in a small memblock array that
>>> memblk_nr_poison_init() then just reads.
>>
>> The inconsistency is what worries me.
>>
>> And that we have pages we are told are hwpoisoned but we seem to ignore that and
>> carry on with our kernel letting it boot?
>
> The walk exists precisely because of that inconsistency: the counter has
> to match the frames that actually carry the flag, and the bitmap says
> more than that.
>
> If we drop the page walk, then there is change for inconsistency, but,
> as-is, there is no inconsistency.
>
> So, I am planning to keep the page walk above, when there is a poisoned
> page in the memory block, avoiding any inconsitency.
How about we keep it very simple and don't mix information from two different
sources? That is, remove that bitmap scan here entirely. We should process the
bitmap exactly once when initializing the memmap.
>From that point on, the memmap should be our reliable source of information.
For this code here, just remember globally whether we hwpoisoned any page. If
so, just walk the memmap. If not (the 99.9999% of all systems, no need to scan
anything).
--
Cheers,
David