From mboxrd@z Thu Jan 1 00:00:00 1970 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 3F21932720C for ; Tue, 11 Aug 2026 11:18:07 +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=1786447089; cv=none; b=d+ie+MWbzKShF4UzgoljOLx3C0h7l8QUFdS7uFPJIEmWNxla7gEpxv9KfaH6gfp0tUuZZG7rZdsh0cJPJFUrrXbSF0Dc+s1ZB/Wc0on/VmizGT1g77l+zCviKFAr8LRj5pRHhI8ZOv8qRm5xBubpmi6kGZlvBQjiIPZrgpQupMc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786447089; c=relaxed/simple; bh=2Wkes8hBsWKQteGUAYLgPDNybAxmpAg7ECAi1/TUrWs=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=rl6jN0FnYjLKtt3MPBsZ/B4EOzgMobo87zSS7aIHrxVywvrpro0nOKoWcABBnW3d4bbyYqqZgK0atg7HQF+6XsSwlJ2KksD4WdwsU21qxohxbzn+JvElFxalv1kUVYfr+bHECm7eovR0zxveNCBDGItpUXmjaQkISI77QcZdzNM= 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=m8UBuuRT; 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="m8UBuuRT" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:In-Reply-To:Content-Type:MIME-Version: References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=+5L98aL3Gaq0Oa3J1h7rtYhrwqEXKEC4NPIDmDwKQQE=; b=m8UBuuRTXedkiO3V4fRfUD2kbt a/SkK1GFzjp95gHT40ScUNlBcaU814L3AdjJBTbHWkC5gWRRJ2if6KKMEZ8AVvkn5ZT/aGxkWkYf9 xZG+IqWKsp4MwIqnczBmPDyt/nEiFhJn/JnypNDfJzgtZb8nPJY4XjtmvNgejzOYgqqxaTyZb6SjW hji09+ZiQiXSl12vNVnbcHzpU3c/qn65pOo1MFFZ92Z44WWrj6RehLL4/kTBWxkuKsCuy7RCJ0ixU b/qcVZvS7oYlFbATBAcJo1AGnoGpsubsaSlT9CKyqACjT5uAZab5EooNN97kq/Bresb6pTXTbGnDD /TubT9iw==; 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 1wtkUN-003Wad-2h; Tue, 11 Aug 2026 11:17:48 +0000 Date: Tue, 11 Aug 2026 04:17:41 -0700 From: Breno Leitao To: Mike Rapoport Cc: Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Suren Baghdasaryan , Michal Hocko , Baoquan He , Pasha Tatashin , Pratyush Yadav , Miaohe Lin , Naoya Horiguchi , linux-mm@kvack.org, linux-kernel@vger.kernel.org, kexec@lists.infradead.org, rmikey@meta.com, riel@surriel.com, kernel-team@meta.com, Kiryl Shutsemau Subject: Re: [PATCH v5] kexec: keep the next kernel off hardware-poisoned pages Message-ID: References: <20260810-kexec_posioned-v5-1-95e1b5e2e656@debian.org> 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=us-ascii Content-Disposition: inline In-Reply-To: X-Debian-User: leitao On Mon, Aug 10, 2026 at 07:32:41PM +0300, Mike Rapoport wrote: > Hi Breno, > > On Mon, Aug 10, 2026 at 06:32:04AM -0700, Breno Leitao wrote: > > Memory failures (such as unrecoverable ECCs errors) are getting more and > > more common. The kernel knows how to handle it while running, marking it > > as poisoned (and SIGBUS user tasks). > > > > Poisoned memory is removed from the buddy allocator, but, not from > > other places. A current problem is that kexec will load new kernel > > on top of a bad/poisoned memory, which is undesirable. > > > > If the next kernel's image, initrd or purgatory lands on poisoned frame, > > the relocation copy writes to the bad memory and the machine checks > > What does the machine check here? ;-) Not sure I got your question right. Did you mean: 1) that there is no machine check exception when *writing* to poisoned memory, or 2) just that "the machine checks" is a lousy way to write it? For 1) I think you are right, and I had not thought it through. The MCE (or a recurrent multi-bit ECC) would come from consuming the error, so a load or an instruction fetch, and a store may well pass silently and leave the poison sitting there. The read back is what gets us, though. So the sentence should hang on the read, not on the copy. Would something like makes more sense? If the next kernel's image, initrd or purgatory lands on a poisoned frame, the relocation copy puts them on memory that is known bad. The error is consumed on the first read back, whether that is purgatory checksumming the segments or the new kernel running from them, and that is what we want to avoid. > > Skip hardware-poisoned frames when placing segments: check them in the > > kexec_file hole finder so it lays the next kernel down on good memory, > > and reject a poisoned destination in sanity_check_segment_list() for > > the kexec_load path, which cannot relocate. > > > > The two hole finders walk in opposite directions, so each asks for the > > end of the poison it has to clear: the top-down walk for the first > > poisoned page in the window, the bottom-up walk for the last. A poisoned > > hugetlb folio counts in full, as hugetlb keeps the flag on the folio and > > the poisoned subpages on its raw hwpoison list. > > I had hard time parsing these two paragraphs. Can you please add more human > touch to them? Sure, but that would cost more. :-) What about something like: Skip hardware-poisoned frames that were detected by machine failure subssytem earlier when placing kexec segments. To do so, add a helper that reports the first or the last poisoned page in a range: memory is walked top-down by locate_mem_hole_top_down() and bottom-up by locate_mem_hole_bottom_up(), so each direction needs a different answer to jump clear of the poison. kexec_load() gets its destinations from userspace and cannot move them, so there sanity_check_segment_list() just rejects a a segument/memory block that happens to have a posioned page. is_page_hwpoison() also covers hugetlb, where the flag sits on the folio and the bad subpages on its raw hwpoison list, so a poisoned hugetlb folio is skipped as a whole. > > + poison = range_first_hwpoison(temp_start, kbuf->memsz); > > + if (poison != PHYS_ADDR_MAX) { > > + /* we hit a poisoned page */ > > + if (poison < kbuf->memsz) > > + return 0; > > Won't we break out on the next iteration boundaries check? I.e. > > if (temp_start < start || temp_start < kbuf->buf_min) > return 0; Kind-of. Sashiko keeps raising this underflow in the function, on every revision since v2. It dismisses it on this hunk because of the check, but reports it as a real one on the two "temp_start = temp_start - PAGE_SIZE" paths above, which do the same subtraction with nothing guarding them. Happy to remove it from here and send that as a separate patch. > > + for (pfn = PHYS_PFN(start); pfn <= end_pfn; pfn++) { > > + > > + cond_resched(); > > cond_resched() for every pfn is too much, isn't it? It is what the other pfn walkers do: the kpageflags read loop in fs/proc/page.c and read_page_owner() in mm/page_owner.c both call it once per pfn. But I honestly don't have a strong opinion here, though, happy to batch it if you prefer. Would this one look better?: if (!(pfn % MAX_ORDER_NR_PAGES)) cond_resched(); Thanks for the review, --breno