[PATCH v2 03/11] mm/filemap: add hwpoison handling to filemap_read()
From: Jane Chu
Date: Wed Jun 17 2026 - 13:27:52 EST
Add hwpoison handling to filemap_read() such that .read_iter() could
make best effort copying data out of clean pages without risking
MCE in case page cache contains HWpoison.
[1] https://lore.kernel.org/linux-mm/aeZwAz6PcdlqSnJ2@xxxxxxxxxxxxxxxxxxxx/
Suggested-by: Matthew Wilcox <willy@xxxxxxxxxxxxx>
Signed-off-by: Jane Chu <jane.chu@xxxxxxxxxx>
---
mm/filemap.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/mm/filemap.c b/mm/filemap.c
index a27ce4ad6247..df8543573570 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2475,6 +2475,8 @@ static void filemap_get_read_batch(struct address_space *mapping,
if (!folio_batch_add(fbatch, folio))
break;
+ if (folio_contain_hwpoisoned_page(folio))
+ break;
if (!folio_test_uptodate(folio))
break;
if (folio_test_readahead(folio))
@@ -2871,6 +2873,7 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter,
size_t offset = iocb->ki_pos & (fsize - 1);
size_t bytes = min_t(loff_t, end_offset - iocb->ki_pos,
fsize - offset);
+ size_t adjusted;
size_t copied;
if (end_offset < folio_pos(folio))
@@ -2885,13 +2888,22 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter,
if (writably_mapped)
flush_dcache_folio(folio);
- copied = copy_folio_to_iter(folio, offset, bytes, iter);
+ adjusted = bytes;
+ if (folio_contain_hwpoisoned_page(folio)) {
+ adjusted = adjust_range_hwpoison(folio, offset, bytes);
+ if (adjusted == 0) {
+ error = -EIO;
+ break;
+ }
+ }
+
+ copied = copy_folio_to_iter(folio, offset, adjusted, iter);
already_read += copied;
iocb->ki_pos += copied;
last_pos = iocb->ki_pos;
- if (copied < bytes) {
+ if (copied < adjusted) {
error = -EFAULT;
break;
}
--
2.43.5