arm64: pgtable: make __pte_to_phys/__phys_to_pte_val inline functions
PATCH 1/1 arm64: pgtable: make __pte_to_phys/__phys_to_pte_val inline functions
From: Arnd Bergmann <[email protected]>
gcc warns about undefined behavior the vmalloc code when building with CONFIG_ARM64_PA_BITS_52, when the 'idx++' in the argument to __phys_to_pte_val() is evaluated twice:
mm/vmalloc.c: In function 'vmap_pfn_apply':mm/vmalloc.c:2800:58: error: operation on 'data->idx' may be undefined [-Werror=sequence-point]
2800 | *pte = pte_mkspecial(pfn_pte(data->pfns[data->idx++], data->prot));
| ~~~~~~~~~^~arch/arm64/include/asm/pgtable-types.h:25:37: note: in definition of macro '__pte'
25 | #define __pte(x) ((pte_t) { (x) } )
| ^arch/arm64/include/asm/pgtable.h:80:15: note: in expansion of macro '__phys_to_pte_val'
80 | __pte(__phys_to_pte_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
| ^~~~~~~~~~~~~~~~~
mm/vmalloc.c:2800:30: note: in expansion of macro 'pfn_pte'
2800 | *pte = pte_mkspecial(pfn_pte(data->pfns[data->idx++], data->prot));
| ^~~~~~~
I have no idea why this never showed up earlier, but the safest workaround appears to be changing those macros into inline functions so the arguments get evaluated only once.
--- arch/arm64/include/asm/pgtable.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
arch/arm64/include/asm/pgtable.h +9 -3
@@ -67,9 +67,15 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];* page table entry, taking care of 52-bit addresses. */ #ifdef CONFIG_ARM64_PA_BITS_52 -#define __pte_to_phys (pte) \ - ((pte_val(pte) & PTE_ADDR_LOW) | ((pte_val(pte) & PTE_ADDR_HIGH) << 36)) -#define __phys_to_pte_val (phys) (((phys) | ((phys) >> 36)) & PTE_ADDR_MASK) +static inline phys_addr_t __pte_to_phys (pte_t pte) +{ +return (pte_val (pte) &PTE_ADDR_LOW ) | + ((pte_val (pte) &PTE_ADDR_HIGH ) <<36 ); +} +static inline pteval_t __phys_to_pte_val (phys_addr_t phys) +{ +return (phys | (phys >>36 )) &PTE_ADDR_MASK ; +}#else #define __pte_to_phys (pte) (pte_val(pte) & PTE_ADDR_MASK)#define __phys_to_pte_val (phys) (phys)
Signature · 1 line
2.29.2
Quoted 15 lines · Arnd Bergmann
From: Arnd Bergmann <[email protected]>
gcc warns about undefined behavior the vmalloc code when building with
CONFIG_ARM64_PA_BITS_52, when the 'idx++' in the argument to__phys_to_pte_val()is evaluated twice:
mm/vmalloc.c: In function 'vmap_pfn_apply':mm/vmalloc.c:2800:58: error: operation on 'data->idx' may be undefined [-Werror=sequence-point]
2800 | *pte =pte_mkspecial(pfn_pte(data->pfns[data->idx++], data->prot));
| ~~~~~~~~~^~arch/arm64/include/asm/pgtable-types.h:25:37: note: in definition of macro '__pte'
25 | #define__pte(x)((pte_t) { (x) } )
| ^arch/arm64/include/asm/pgtable.h:80:15: note: in expansion of macro '__phys_to_pte_val'
80 |__pte(__phys_to_pte_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
Quoted 6 lines
| ^~~~~~~~~~~~~~~~~
mm/vmalloc.c:2800:30: note: in expansion of macro 'pfn_pte'
2800 | *pte =pte_mkspecial(pfn_pte(data->pfns[data->idx++], data->prot));
| ^~~~~~~[...]
Applied to arm64 (for-next/core), thanks!
[1/1] arm64: pgtable: make __pte_to_phys/__phys_to_pte_val inline functions
https://git.kernel.org/arm64/c/c7c386fbc202
Cheers,
Signature · 5 lines
Will https://fixes.arm64.dev https://next.arm64.dev https://will.arm64.dev