path: root/lib
diff options
authorMatthew Wilcox (Oracle) <>2021-05-14 17:27:24 -0700
committerLinus Torvalds <>2021-05-14 19:41:32 -0700
commit9ddb3c14afba8bc5950ed297f02d4ae05ff35cd1 (patch)
tree53f0c1f2e01987f463fa05267ba7efefa5710672 /lib
parent628622904b8d229591134e44efd6608a7541eb89 (diff)
mm: fix struct page layout on 32-bit systems
32-bit architectures which expect 8-byte alignment for 8-byte integers and need 64-bit DMA addresses (arm, mips, ppc) had their struct page inadvertently expanded in 2019. When the dma_addr_t was added, it forced the alignment of the union to 8 bytes, which inserted a 4 byte gap between 'flags' and the union. Fix this by storing the dma_addr_t in one or two adjacent unsigned longs. This restores the alignment to that of an unsigned long. We always store the low bits in the first word to prevent the PageTail bit from being inadvertently set on a big endian platform. If that happened, get_user_pages_fast() racing against a page which was freed and reallocated to the page_pool could dereference a bogus compound_head(), which would be hard to trace back to this cause. Link: Fixes: c25fff7171be ("mm: add dma_addr_t to struct page") Signed-off-by: Matthew Wilcox (Oracle) <> Acked-by: Ilias Apalodimas <> Acked-by: Jesper Dangaard Brouer <> Acked-by: Vlastimil Babka <> Tested-by: Matteo Croce <> Cc: <> Signed-off-by: Andrew Morton <> Signed-off-by: Linus Torvalds <>
Diffstat (limited to 'lib')
0 files changed, 0 insertions, 0 deletions