arm64: pgtable: make __pte_to_phys/__phys_to_pte_val inline functions
[ Upstream commit c7c386fbc20262c1d911c615c65db6a58667d92c ]
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.
Cc: Matthew Wilcox <willy@infradead.org>
Fixes: 75387b9263
("arm64: handle 52-bit physical addresses in page table entries")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/r/20211105075414.2553155-1-arnd@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
572599cbf1
commit
180a9b539c
@ -54,9 +54,15 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
|
|||||||
* page table entry, taking care of 52-bit addresses.
|
* page table entry, taking care of 52-bit addresses.
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_ARM64_PA_BITS_52
|
#ifdef CONFIG_ARM64_PA_BITS_52
|
||||||
#define __pte_to_phys(pte) \
|
static inline phys_addr_t __pte_to_phys(pte_t 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)
|
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
|
#else
|
||||||
#define __pte_to_phys(pte) (pte_val(pte) & PTE_ADDR_MASK)
|
#define __pte_to_phys(pte) (pte_val(pte) & PTE_ADDR_MASK)
|
||||||
#define __phys_to_pte_val(phys) (phys)
|
#define __phys_to_pte_val(phys) (phys)
|
||||||
|
Loading…
Reference in New Issue
Block a user