Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64/mm: Simplify and document pte_to_phys() for 52 bit addresses

pte_to_phys() assembly definition does multiple bits field transformations
to derive physical address, embedded inside a page table entry. Unlike its
C counter part i.e __pte_to_phys(), pte_to_phys() is not very apparent. It
simplifies these operations via a new macro PTE_ADDR_HIGH_SHIFT indicating
how far the pte encoded higher address bits need to be left shifted. While
here, this also updates __pte_to_phys() and __phys_to_pte_val().

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Suggested-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
Link: https://lore.kernel.org/r/20221107141753.2938621-1-anshuman.khandual@arm.com
Signed-off-by: Will Deacon <will@kernel.org>

authored by

Anshuman Khandual and committed by
Will Deacon
a4ee2861 f0c4d9fc

+6 -7
+3 -5
arch/arm64/include/asm/assembler.h
··· 660 660 .endm 661 661 662 662 .macro pte_to_phys, phys, pte 663 - #ifdef CONFIG_ARM64_PA_BITS_52 664 - ubfiz \phys, \pte, #(48 - 16 - 12), #16 665 - bfxil \phys, \pte, #16, #32 666 - lsl \phys, \phys, #16 667 - #else 668 663 and \phys, \pte, #PTE_ADDR_MASK 664 + #ifdef CONFIG_ARM64_PA_BITS_52 665 + orr \phys, \phys, \phys, lsl #PTE_ADDR_HIGH_SHIFT 666 + and \phys, \phys, GENMASK_ULL(PHYS_MASK_SHIFT - 1, PAGE_SHIFT) 669 667 #endif 670 668 .endm 671 669
+1
arch/arm64/include/asm/pgtable-hwdef.h
··· 159 159 #ifdef CONFIG_ARM64_PA_BITS_52 160 160 #define PTE_ADDR_HIGH (_AT(pteval_t, 0xf) << 12) 161 161 #define PTE_ADDR_MASK (PTE_ADDR_LOW | PTE_ADDR_HIGH) 162 + #define PTE_ADDR_HIGH_SHIFT 36 162 163 #else 163 164 #define PTE_ADDR_MASK PTE_ADDR_LOW 164 165 #endif
+2 -2
arch/arm64/include/asm/pgtable.h
··· 77 77 static inline phys_addr_t __pte_to_phys(pte_t pte) 78 78 { 79 79 return (pte_val(pte) & PTE_ADDR_LOW) | 80 - ((pte_val(pte) & PTE_ADDR_HIGH) << 36); 80 + ((pte_val(pte) & PTE_ADDR_HIGH) << PTE_ADDR_HIGH_SHIFT); 81 81 } 82 82 static inline pteval_t __phys_to_pte_val(phys_addr_t phys) 83 83 { 84 - return (phys | (phys >> 36)) & PTE_ADDR_MASK; 84 + return (phys | (phys >> PTE_ADDR_HIGH_SHIFT)) & PTE_ADDR_MASK; 85 85 } 86 86 #else 87 87 #define __pte_to_phys(pte) (pte_val(pte) & PTE_ADDR_MASK)