diff mbox series

[RFC,07/10] arm64/mm: Detect and enable FEAT_LPA2

Message ID 1626229291-6569-8-git-send-email-anshuman.khandual@arm.com (mailing list archive)
State New
Headers show
Series arm64/mm: Enable FEAT_LPA2 (52 bits PA support on 4K|16K pages) | expand

Commit Message

Anshuman Khandual July 14, 2021, 2:21 a.m. UTC
Detect FEAT_LPA2 implementation early enough during boot when requested via
CONFIG_ARM64_PA_BITS_52_LPA2 and remember in a variable arm64_lpa2_enabled.
This variable could then be used to turn on TCR_EL1.TCR_DS effecting the 52
bits PA range or fall back to default 48 bits PA range if FEAT_LPA2 feature
was requested but found not to be implemented.

Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
 arch/arm64/include/asm/memory.h |  1 +
 arch/arm64/kernel/head.S        | 15 +++++++++++++++
 arch/arm64/mm/mmu.c             |  3 +++
 arch/arm64/mm/proc.S            |  9 +++++++++
 4 files changed, 28 insertions(+)

Comments

Suzuki K Poulose July 14, 2021, 8:21 a.m. UTC | #1
On 14/07/2021 03:21, Anshuman Khandual wrote:
> Detect FEAT_LPA2 implementation early enough during boot when requested via
> CONFIG_ARM64_PA_BITS_52_LPA2 and remember in a variable arm64_lpa2_enabled.
> This variable could then be used to turn on TCR_EL1.TCR_DS effecting the 52
> bits PA range or fall back to default 48 bits PA range if FEAT_LPA2 feature
> was requested but found not to be implemented.
> 
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
>   arch/arm64/include/asm/memory.h |  1 +
>   arch/arm64/kernel/head.S        | 15 +++++++++++++++
>   arch/arm64/mm/mmu.c             |  3 +++
>   arch/arm64/mm/proc.S            |  9 +++++++++
>   4 files changed, 28 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index 824a365..d0ca002 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -178,6 +178,7 @@
>   #include <asm/bug.h>
>   
>   extern u64			vabits_actual;
> +extern u64			arm64_lpa2_enabled;
>   
>   extern s64			memstart_addr;
>   /* PHYS_OFFSET - the physical address of the start of memory. */
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 6444147..9cf79ea 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -94,6 +94,21 @@ SYM_CODE_START(primary_entry)
>   	adrp	x23, __PHYS_OFFSET
>   	and	x23, x23, MIN_KIMG_ALIGN - 1	// KASLR offset, defaults to 0
>   	bl	set_cpu_boot_mode_flag
> +
> +#ifdef CONFIG_ARM64_PA_BITS_52_LPA2
> +	mrs     x10, ID_AA64MMFR0_EL1
> +	ubfx    x10, x10, #ID_AA64MMFR0_TGRAN_SHIFT, 4
> +	cmp     x10, #ID_AA64MMFR0_TGRAN_LPA2
> +	b.ne	1f

For the sake of forward compatibility, this should be "b.lt"

Suzuki
Anshuman Khandual July 16, 2021, 7:06 a.m. UTC | #2
On 7/14/21 1:51 PM, Suzuki K Poulose wrote:
> On 14/07/2021 03:21, Anshuman Khandual wrote:
>> Detect FEAT_LPA2 implementation early enough during boot when requested via
>> CONFIG_ARM64_PA_BITS_52_LPA2 and remember in a variable arm64_lpa2_enabled.
>> This variable could then be used to turn on TCR_EL1.TCR_DS effecting the 52
>> bits PA range or fall back to default 48 bits PA range if FEAT_LPA2 feature
>> was requested but found not to be implemented.
>>
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>> ---
>>   arch/arm64/include/asm/memory.h |  1 +
>>   arch/arm64/kernel/head.S        | 15 +++++++++++++++
>>   arch/arm64/mm/mmu.c             |  3 +++
>>   arch/arm64/mm/proc.S            |  9 +++++++++
>>   4 files changed, 28 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
>> index 824a365..d0ca002 100644
>> --- a/arch/arm64/include/asm/memory.h
>> +++ b/arch/arm64/include/asm/memory.h
>> @@ -178,6 +178,7 @@
>>   #include <asm/bug.h>
>>     extern u64            vabits_actual;
>> +extern u64            arm64_lpa2_enabled;
>>     extern s64            memstart_addr;
>>   /* PHYS_OFFSET - the physical address of the start of memory. */
>> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
>> index 6444147..9cf79ea 100644
>> --- a/arch/arm64/kernel/head.S
>> +++ b/arch/arm64/kernel/head.S
>> @@ -94,6 +94,21 @@ SYM_CODE_START(primary_entry)
>>       adrp    x23, __PHYS_OFFSET
>>       and    x23, x23, MIN_KIMG_ALIGN - 1    // KASLR offset, defaults to 0
>>       bl    set_cpu_boot_mode_flag
>> +
>> +#ifdef CONFIG_ARM64_PA_BITS_52_LPA2
>> +    mrs     x10, ID_AA64MMFR0_EL1
>> +    ubfx    x10, x10, #ID_AA64MMFR0_TGRAN_SHIFT, 4
>> +    cmp     x10, #ID_AA64MMFR0_TGRAN_LPA2
>> +    b.ne    1f
> 
> For the sake of forward compatibility, this should be "b.lt"
Right, I guess we could assume that the feature will be present from the
current ID_AA64MMFR0_TGRAN_LPA2 values onward in the future. But should
not this also be capped at ID_AA64MMFR0_TGRAN_SUPPORTED_MAX as the upper
limit is different for 4K and 16K page sizes.
Suzuki K Poulose July 16, 2021, 8:08 a.m. UTC | #3
On 16/07/2021 08:06, Anshuman Khandual wrote:
> 
> On 7/14/21 1:51 PM, Suzuki K Poulose wrote:
>> On 14/07/2021 03:21, Anshuman Khandual wrote:
>>> Detect FEAT_LPA2 implementation early enough during boot when requested via
>>> CONFIG_ARM64_PA_BITS_52_LPA2 and remember in a variable arm64_lpa2_enabled.
>>> This variable could then be used to turn on TCR_EL1.TCR_DS effecting the 52
>>> bits PA range or fall back to default 48 bits PA range if FEAT_LPA2 feature
>>> was requested but found not to be implemented.
>>>
>>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>>> ---
>>>    arch/arm64/include/asm/memory.h |  1 +
>>>    arch/arm64/kernel/head.S        | 15 +++++++++++++++
>>>    arch/arm64/mm/mmu.c             |  3 +++
>>>    arch/arm64/mm/proc.S            |  9 +++++++++
>>>    4 files changed, 28 insertions(+)
>>>
>>> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
>>> index 824a365..d0ca002 100644
>>> --- a/arch/arm64/include/asm/memory.h
>>> +++ b/arch/arm64/include/asm/memory.h
>>> @@ -178,6 +178,7 @@
>>>    #include <asm/bug.h>
>>>      extern u64            vabits_actual;
>>> +extern u64            arm64_lpa2_enabled;
>>>      extern s64            memstart_addr;
>>>    /* PHYS_OFFSET - the physical address of the start of memory. */
>>> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
>>> index 6444147..9cf79ea 100644
>>> --- a/arch/arm64/kernel/head.S
>>> +++ b/arch/arm64/kernel/head.S
>>> @@ -94,6 +94,21 @@ SYM_CODE_START(primary_entry)
>>>        adrp    x23, __PHYS_OFFSET
>>>        and    x23, x23, MIN_KIMG_ALIGN - 1    // KASLR offset, defaults to 0
>>>        bl    set_cpu_boot_mode_flag
>>> +
>>> +#ifdef CONFIG_ARM64_PA_BITS_52_LPA2
>>> +    mrs     x10, ID_AA64MMFR0_EL1
>>> +    ubfx    x10, x10, #ID_AA64MMFR0_TGRAN_SHIFT, 4
>>> +    cmp     x10, #ID_AA64MMFR0_TGRAN_LPA2
>>> +    b.ne    1f
>>
>> For the sake of forward compatibility, this should be "b.lt"
> Right, I guess we could assume that the feature will be present from the
> current ID_AA64MMFR0_TGRAN_LPA2 values onward in the future. But should
> not this also be capped at ID_AA64MMFR0_TGRAN_SUPPORTED_MAX as the upper
> limit is different for 4K and 16K page sizes.

Absolutely.

Cheers
Suzuki

>
Anshuman Khandual July 19, 2021, 4:47 a.m. UTC | #4
On 7/16/21 1:38 PM, Suzuki K Poulose wrote:
> On 16/07/2021 08:06, Anshuman Khandual wrote:
>>
>> On 7/14/21 1:51 PM, Suzuki K Poulose wrote:
>>> On 14/07/2021 03:21, Anshuman Khandual wrote:
>>>> Detect FEAT_LPA2 implementation early enough during boot when requested via
>>>> CONFIG_ARM64_PA_BITS_52_LPA2 and remember in a variable arm64_lpa2_enabled.
>>>> This variable could then be used to turn on TCR_EL1.TCR_DS effecting the 52
>>>> bits PA range or fall back to default 48 bits PA range if FEAT_LPA2 feature
>>>> was requested but found not to be implemented.
>>>>
>>>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>>>> ---
>>>>    arch/arm64/include/asm/memory.h |  1 +
>>>>    arch/arm64/kernel/head.S        | 15 +++++++++++++++
>>>>    arch/arm64/mm/mmu.c             |  3 +++
>>>>    arch/arm64/mm/proc.S            |  9 +++++++++
>>>>    4 files changed, 28 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
>>>> index 824a365..d0ca002 100644
>>>> --- a/arch/arm64/include/asm/memory.h
>>>> +++ b/arch/arm64/include/asm/memory.h
>>>> @@ -178,6 +178,7 @@
>>>>    #include <asm/bug.h>
>>>>      extern u64            vabits_actual;
>>>> +extern u64            arm64_lpa2_enabled;
>>>>      extern s64            memstart_addr;
>>>>    /* PHYS_OFFSET - the physical address of the start of memory. */
>>>> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
>>>> index 6444147..9cf79ea 100644
>>>> --- a/arch/arm64/kernel/head.S
>>>> +++ b/arch/arm64/kernel/head.S
>>>> @@ -94,6 +94,21 @@ SYM_CODE_START(primary_entry)
>>>>        adrp    x23, __PHYS_OFFSET
>>>>        and    x23, x23, MIN_KIMG_ALIGN - 1    // KASLR offset, defaults to 0
>>>>        bl    set_cpu_boot_mode_flag
>>>> +
>>>> +#ifdef CONFIG_ARM64_PA_BITS_52_LPA2
>>>> +    mrs     x10, ID_AA64MMFR0_EL1
>>>> +    ubfx    x10, x10, #ID_AA64MMFR0_TGRAN_SHIFT, 4
>>>> +    cmp     x10, #ID_AA64MMFR0_TGRAN_LPA2
>>>> +    b.ne    1f
>>>
>>> For the sake of forward compatibility, this should be "b.lt"
>> Right, I guess we could assume that the feature will be present from the
>> current ID_AA64MMFR0_TGRAN_LPA2 values onward in the future. But should
>> not this also be capped at ID_AA64MMFR0_TGRAN_SUPPORTED_MAX as the upper
>> limit is different for 4K and 16K page sizes.
> 
> Absolutely.

ID_AA64MMFR0_TGRAN_SUPPORTED_MAX check there is not required as __enable_mmu()
already performs the required boundary check for a given page size support.
diff mbox series

Patch

diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 824a365..d0ca002 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -178,6 +178,7 @@ 
 #include <asm/bug.h>
 
 extern u64			vabits_actual;
+extern u64			arm64_lpa2_enabled;
 
 extern s64			memstart_addr;
 /* PHYS_OFFSET - the physical address of the start of memory. */
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 6444147..9cf79ea 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -94,6 +94,21 @@  SYM_CODE_START(primary_entry)
 	adrp	x23, __PHYS_OFFSET
 	and	x23, x23, MIN_KIMG_ALIGN - 1	// KASLR offset, defaults to 0
 	bl	set_cpu_boot_mode_flag
+
+#ifdef CONFIG_ARM64_PA_BITS_52_LPA2
+	mrs     x10, ID_AA64MMFR0_EL1
+	ubfx    x10, x10, #ID_AA64MMFR0_TGRAN_SHIFT, 4
+	cmp     x10, #ID_AA64MMFR0_TGRAN_LPA2
+	b.ne	1f
+
+	mov	x10, #1
+	adr_l	x11, arm64_lpa2_enabled
+	str	x10, [x11]
+	dmb	sy
+	dc	ivac, x11
+1:
+#endif /* CONFIG_ARM64_PA_BITS_52_LPA2 */
+
 	bl	__create_page_tables
 	/*
 	 * The following calls CPU setup code, see arch/arm64/mm/proc.S for
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index d745865..00b7595 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -48,6 +48,9 @@  u64 idmap_ptrs_per_pgd = PTRS_PER_PGD;
 u64 __section(".mmuoff.data.write") vabits_actual;
 EXPORT_SYMBOL(vabits_actual);
 
+u64 __section(".mmuoff.data.write") arm64_lpa2_enabled;
+EXPORT_SYMBOL(arm64_lpa2_enabled);
+
 u64 kimage_voffset __ro_after_init;
 EXPORT_SYMBOL(kimage_voffset);
 
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 1ae0c2b..672880c 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -423,6 +423,15 @@  SYM_FUNC_START(__cpu_setup)
 			TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
 			TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS
 
+#ifdef CONFIG_ARM64_PA_BITS_52_LPA2
+	ldr_l   x10, arm64_lpa2_enabled
+	cmp	x10, #1
+	b.ne	1f
+	mov_q	x10, TCR_DS
+	orr	tcr, tcr, x10
+1:
+#endif /* CONFIG_ARM64_PA_BITS_52_LPA2 */
+
 #ifdef CONFIG_ARM64_MTE
 	/*
 	 * Update MAIR_EL1, GCR_EL1 and TFSR*_EL1 if MTE is supported