Re: [RFC 06/10] arm64/mm: Add FEAT_LPA2 specific encoding
From: Anshuman Khandual <hidden>
Date: 2021-07-16 07:20:07
Also in:
linux-arm-kernel, lkml
On 7/14/21 9:08 PM, Steven Price wrote:
On 14/07/2021 03:21, Anshuman Khandual wrote:quoted
FEAT_LPA2 requires different PTE representation formats for both 4K and 16K page size config. This adds FEAT_LPA2 specific new PTE encodings as per ARM ARM (0487G.A) which updates [pte|phys]_to_[phys|pte](). The updated helpers would be used when FEAT_LPA2 gets enabled via CONFIG_ARM64_PA_BITS_52 on 4K and 16K page size. Although TTBR encoding and phys_to_ttbr() helper remains the same as FEAT_LPA for FEAT_LPA2 as well. It updates 'phys_to_pte' helper to accept a temporary variable and changes impacted call sites. Signed-off-by: Anshuman Khandual <redacted> --- arch/arm64/include/asm/assembler.h | 23 +++++++++++++++++++---- arch/arm64/include/asm/pgtable-hwdef.h | 4 ++++ arch/arm64/include/asm/pgtable.h | 4 ++++ arch/arm64/kernel/head.S | 25 +++++++++++++------------ 4 files changed, 40 insertions(+), 16 deletions(-)diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index fedc202..0492543 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h@@ -606,7 +606,7 @@ alternative_endif #endif .endm - .macro phys_to_pte, pte, phys + .macro phys_to_pte, pte, phys, tmp #ifdef CONFIG_ARM64_PA_BITS_52_LPA /* * We assume \phys is 64K aligned and this is guaranteed by only@@ -614,6 +614,17 @@ alternative_endif */ orr \pte, \phys, \phys, lsr #36 and \pte, \pte, #PTE_ADDR_MASK +#elif defined(CONFIG_ARM64_PA_BITS_52_LPA2) + orr \pte, \phys, \phys, lsr #42 + + /* + * The 'tmp' is being used here to just prepare + * and hold PTE_ADDR_MASK which cannot be passed + * to the subsequent 'and' instruction. + */ + mov \tmp, #PTE_ADDR_LOW + orr \tmp, \tmp, #PTE_ADDR_HIGH + and \pte, \pte, \tmpRather than adding an extra temporary register (and the fallout of various other macros needing an extra register), this can be done with two AND instructions:
I would really like to get rid of the 'tmp' variable here as well but did not figure out any method of accomplishing it.
/* PTE_ADDR_MASK cannot be encoded as an immediate, so
* mask off all but two bits, followed by masking the
* extra two bits
*/
and \pte, \pte, #PTE_ADDR_MASK | (3 << 10)
and \pte, \pte, #~(3 << 10)Did this change as suggested
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h@@ -626,9 +626,8 @@ alternative_endif * and hold PTE_ADDR_MASK which cannot be passed * to the subsequent 'and' instruction. */ - mov \tmp, #PTE_ADDR_LOW - orr \tmp, \tmp, #PTE_ADDR_HIGH - and \pte, \pte, \tmp + and \pte, \pte, #PTE_ADDR_MASK | (0x3 << 10) + and \pte, \pte, #~(0x3 << 10) .Lskip_lpa2\@: mov \pte, \phys
but still fails to build (tested on 16K) arch/arm64/kernel/head.S: Assembler messages: arch/arm64/kernel/head.S:377: Error: immediate out of range at operand 3 -- `and x6,x6,#((((1<<(50-14))-1)<<14)|(0x3<<8))|(0x3<<10)' arch/arm64/kernel/head.S:390: Error: immediate out of range at operand 3 -- `and x12,x12,#((((1<<(50-14))-1)<<14)|(0x3<<8))|(0x3<<10)' arch/arm64/kernel/head.S:390: Error: immediate out of range at operand 3 -- `and x12,x12,#((((1<<(50-14))-1)<<14)|(0x3<<8))|(0x3<<10)' arch/arm64/kernel/head.S:404: Error: immediate out of range at operand 3 -- `and x12,x12,#((((1<<(50-14))-1)<<14)|(0x3<<8))|(0x3<<10)' arch/arm64/kernel/head.S:404: Error: immediate out of range at operand 3 -- `and x12,x12,#((((1<<(50-14))-1)<<14)|(0x3<<8))|(0x3<<10)'