Message ID | 20230913201248.452081-5-zi.yan@sent.com (mailing list archive) |
---|---|
State | Handled Elsewhere |
Headers | show |
Series | Use nth_page() in place of direct struct page manipulation | expand |
On 13 Sep 2023, at 16:12, Zi Yan wrote: > From: Zi Yan <ziy@nvidia.com> > > When dealing with hugetlb pages, struct page is not guaranteed to be > contiguous on SPARSEMEM without VMEMMAP. Use nth_page() to handle it > properly. > > Fixes: 38c1ddbde6c6 ("hugetlbfs: improve read HWPOISON hugepage") > Cc: <stable@vger.kernel.org> > Signed-off-by: Zi Yan <ziy@nvidia.com> > Reviewed-by: Muchun Song <songmuchun@bytedance.com> > --- > fs/hugetlbfs/inode.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c > index 7083fa0caaab..14d3d28e41b0 100644 > --- a/fs/hugetlbfs/inode.c > +++ b/fs/hugetlbfs/inode.c > @@ -295,7 +295,7 @@ static size_t adjust_range_hwpoison(struct page *page, size_t offset, size_t byt > size_t res = 0; > > /* First subpage to start the loop. */ > - page += offset / PAGE_SIZE; > + page = nth_page(page, offset / PAGE_SIZE); > offset %= PAGE_SIZE; > while (1) { > if (is_raw_hwpoison_page_in_hugepage(page)) > @@ -309,7 +309,7 @@ static size_t adjust_range_hwpoison(struct page *page, size_t offset, size_t byt > break; > offset += n; > if (offset == PAGE_SIZE) { > - page++; > + page = nth_page(page, 1); > offset = 0; > } > } > -- > 2.40.1 Without the fix, a wrong subpage might be checked for HWPoison, causing wrong number of bytes of a page copied to user space. No bug is reported. The fix comes from code inspection. -- Best Regards, Yan, Zi
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 7083fa0caaab..14d3d28e41b0 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -295,7 +295,7 @@ static size_t adjust_range_hwpoison(struct page *page, size_t offset, size_t byt size_t res = 0; /* First subpage to start the loop. */ - page += offset / PAGE_SIZE; + page = nth_page(page, offset / PAGE_SIZE); offset %= PAGE_SIZE; while (1) { if (is_raw_hwpoison_page_in_hugepage(page)) @@ -309,7 +309,7 @@ static size_t adjust_range_hwpoison(struct page *page, size_t offset, size_t byt break; offset += n; if (offset == PAGE_SIZE) { - page++; + page = nth_page(page, 1); offset = 0; } }