Commit c1090bb1 authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Catalin Marinas
Browse files

arm64: mm: don't assume struct page is always 64 bytes



Commit 8c96400d simplified the page-to-virt and virt-to-page
conversions, based on the assumption that struct page is always 64
bytes in size, in which case we can use a single signed shift to
perform the conversion (provided that the vmemmap array is placed
appropriately in the kernel VA space)

Unfortunately, this assumption turns out not to hold, and so we need
to revert part of this commit, and go back to an affine transformation.
Given that all the quantities involved are compile time constants,
this should not make any practical difference.

Fixes: 8c96400d ("arm64: mm: make vmemmap region a projection of the linear region")
Reported-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20201110180511.29083-1-ardb@kernel.org


Tested-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 68af6d24
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -308,13 +308,15 @@ static inline void *phys_to_virt(phys_addr_t x)
#else
#define page_to_virt(x)	({						\
	__typeof__(x) __page = x;					\
	u64 __addr = (u64)__page << VMEMMAP_SHIFT;			\
	u64 __idx = ((u64)__page - VMEMMAP_START) / sizeof(struct page);\
	u64 __addr = PAGE_OFFSET + (__idx * PAGE_SIZE);			\
	(void *)__tag_set((const void *)__addr, page_kasan_tag(__page));\
})

#define virt_to_page(x)	({						\
	u64 __addr = __tag_reset((u64)(x)) & PAGE_MASK;			\
	(struct page *)((s64)__addr >> VMEMMAP_SHIFT);			\
	u64 __idx = (__tag_reset((u64)x) - PAGE_OFFSET) / PAGE_SIZE;	\
	u64 __addr = VMEMMAP_START + (__idx * sizeof(struct page));	\
	(struct page *)__addr;						\
})
#endif /* !CONFIG_SPARSEMEM_VMEMMAP || CONFIG_DEBUG_VIRTUAL */

+0 −2
Original line number Diff line number Diff line
@@ -502,8 +502,6 @@ static void __init free_unused_memmap(void)
 */
void __init mem_init(void)
{
	BUILD_BUG_ON(!is_power_of_2(sizeof(struct page)));

	if (swiotlb_force == SWIOTLB_FORCE ||
	    max_pfn > PFN_DOWN(arm64_dma_phys_limit ? : arm64_dma32_phys_limit))
		swiotlb_init(1);