arm64: memory: Rewrite default page_to_virt()/virt_to_page()
authorWill Deacon <will@kernel.org>
Tue, 13 Aug 2019 15:46:11 +0000 (16:46 +0100)
committerWill Deacon <will@kernel.org>
Wed, 14 Aug 2019 12:05:35 +0000 (13:05 +0100)
The default implementations of page_to_virt() and virt_to_page() are
fairly confusing to read and the former evaluates its 'page' parameter
twice in the macro

Rewrite them so that the computation is expressed as 'base + index' in
both cases and the parameter is always evaluated exactly once.

Tested-by: Steve Capper <steve.capper@arm.com>
Reviewed-by: Steve Capper <steve.capper@arm.com>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/memory.h

index 243e05ad4a6740b244230b7847e53abc065a8855..636d414608cb145059a87b90c9667d19696ca8a0 100644 (file)
@@ -313,19 +313,18 @@ static inline void *phys_to_virt(phys_addr_t x)
 #if !defined(CONFIG_SPARSEMEM_VMEMMAP) || defined(CONFIG_DEBUG_VIRTUAL)
 #define virt_to_page(kaddr)    pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 #else
-#define __virt_to_pgoff(kaddr) (((u64)(kaddr) - PAGE_OFFSET) / PAGE_SIZE * sizeof(struct page))
-#define __page_to_voff(kaddr)  (((u64)(kaddr) - VMEMMAP_START) * PAGE_SIZE / sizeof(struct page))
-
-#define page_to_virt(page)     ({                                      \
-       unsigned long __addr =                                          \
-               ((__page_to_voff(page)) + PAGE_OFFSET);                 \
-       const void *__addr_tag =                                        \
-               __tag_set((void *)__addr, page_kasan_tag(page));        \
-       ((void *)__addr_tag);                                           \
+#define page_to_virt(x)        ({                                              \
+       __typeof__(x) __page = x;                                       \
+       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(vaddr)    \
-       ((struct page *)((__virt_to_pgoff(__tag_reset(vaddr))) + VMEMMAP_START))
+#define virt_to_page(x)        ({                                              \
+       u64 __idx = (__tag_reset((u64)x) - PAGE_OFFSET) / PAGE_SIZE;    \
+       u64 __addr = VMEMMAP_START + (__idx * sizeof(struct page));     \
+       (struct page *)__addr;                                          \
+})
 #endif
 
 #define virt_addr_valid(addr)  ({                                      \