[RFC PATCH 3/4] arm64: mmu_change_region_attr() add an option not to break PTEs
Jerome Forissier
jerome.forissier at linaro.org
Thu Jan 30 10:31:59 CET 2025
On 1/30/25 10:20, Ilias Apalodimas wrote:
> Hi Jerome,
>
> On Thu, 30 Jan 2025 at 11:11, Jerome Forissier
> <jerome.forissier at linaro.org> wrote:
>>
>> Hi Ilias,
>>
>> On 1/30/25 08:20, Ilias Apalodimas wrote:
>>> The ARM ARM on section 8.17.1 describes the cases where
>>> break-before-make is required when changing live page tables.
>>> Since we can use this function to tweak block and page permssions,
>>> where BBM is not required add an extra argument to the function.
>>>
>>> While at it add a function we can use to change the attributes of normal
>>> memory without breaking the pages tables first
>>>
>>> Signed-off-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>
>>> ---
>>> arch/arm/cpu/armv8/cache_v8.c | 27 ++++++++++++++++++++++++-
>>> arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 10 ++++-----
>>> arch/arm/include/asm/system.h | 3 ++-
>>> arch/arm/mach-snapdragon/board.c | 2 +-
>>> 4 files changed, 34 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
>>> index a4ca56c8ed42..60d0870013e8 100644
>>> --- a/arch/arm/cpu/armv8/cache_v8.c
>>> +++ b/arch/arm/cpu/armv8/cache_v8.c
>>> @@ -968,11 +968,14 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
>>> * The procecess is break-before-make. The target region will be marked as
>>> * invalid during the process of changing.
>>> */
>>> -void mmu_change_region_attr(phys_addr_t addr, size_t siz, u64 attrs)
>>> +void mmu_change_region_attr(phys_addr_t addr, size_t siz, u64 attrs, bool bbm)
>>> {
>>> int level;
>>> u64 r, size, start;
>>>
>>> + if (!bbm)
>>> + goto skip_bbm;
>>> +
>>> start = addr;
>>> size = siz;
>>> /*
>>> @@ -997,6 +1000,7 @@ void mmu_change_region_attr(phys_addr_t addr, size_t siz, u64 attrs)
>>> gd->arch.tlb_addr + gd->arch.tlb_size);
>>> __asm_invalidate_tlb_all();
>>>
>>> +skip_bbm:
>>> /*
>>> * Loop through the address range until we find a page granule that fits
>>> * our alignment constraints, then set it to the new cache attributes
>>> @@ -1020,6 +1024,27 @@ void mmu_change_region_attr(phys_addr_t addr, size_t siz, u64 attrs)
>>> __asm_invalidate_tlb_all();
>>> }
>>>
>>> +void mmu_set_attrs(phys_addr_t addr, size_t size, int type)
>>
>> type should be an enum
>
> yea, I mentioned that in the cover letter.
...which for some reason I did not get :-/ I found it on the ML
archive.
Thanks,
--
Jerome
>
> Thanks!
> /Ilias
>>
>>> +{
>>> + u64 attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE | PTE_TYPE_VALID;
>>> +
>>> + switch (type) {
>>> + case 1:
>>> + /* RO */
>>> + attrs |= PTE_BLOCK_PXN | PTE_BLOCK_UXN | PTE_BLOCK_RO;
>>> + break;
>>> + case 2:
>>> + /* RX */
>>> + attrs |= PTE_BLOCK_RO;
>>> + break;
>>> + case 3:
>>> + /* RW */
>>> + attrs |= PTE_BLOCK_PXN | PTE_BLOCK_UXN;
>>> + }
>>> +
>>> + mmu_change_region_attr(addr, size, attrs, false);
>>> +}
>>> +
>>> #else /* !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */
>>>
>>> /*
>>> diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
>>> index d2d3e346a36f..caf1dab05936 100644
>>> --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
>>> +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
>>> @@ -1573,7 +1573,7 @@ void update_early_mmu_table(void)
>>> PTE_BLOCK_MEMTYPE(MT_NORMAL) |
>>> PTE_BLOCK_OUTER_SHARE |
>>> PTE_BLOCK_NS |
>>> - PTE_TYPE_VALID);
>>> + PTE_TYPE_VALID, true);
>>> } else {
>>> mmu_change_region_attr(
>>> CFG_SYS_SDRAM_BASE,
>>> @@ -1581,7 +1581,7 @@ void update_early_mmu_table(void)
>>> PTE_BLOCK_MEMTYPE(MT_NORMAL) |
>>> PTE_BLOCK_OUTER_SHARE |
>>> PTE_BLOCK_NS |
>>> - PTE_TYPE_VALID);
>>> + PTE_TYPE_VALID, true);
>>> #ifdef CONFIG_SYS_DDR_BLOCK3_BASE
>>> #ifndef CONFIG_SYS_DDR_BLOCK2_SIZE
>>> #error "Missing CONFIG_SYS_DDR_BLOCK2_SIZE"
>>> @@ -1594,7 +1594,7 @@ void update_early_mmu_table(void)
>>> PTE_BLOCK_MEMTYPE(MT_NORMAL) |
>>> PTE_BLOCK_OUTER_SHARE |
>>> PTE_BLOCK_NS |
>>> - PTE_TYPE_VALID);
>>> + PTE_TYPE_VALID, true);
>>> mmu_change_region_attr(
>>> CONFIG_SYS_DDR_BLOCK3_BASE,
>>> gd->ram_size -
>>> @@ -1603,7 +1603,7 @@ void update_early_mmu_table(void)
>>> PTE_BLOCK_MEMTYPE(MT_NORMAL) |
>>> PTE_BLOCK_OUTER_SHARE |
>>> PTE_BLOCK_NS |
>>> - PTE_TYPE_VALID);
>>> + PTE_TYPE_VALID, true);
>>> } else
>>> #endif
>>> {
>>> @@ -1614,7 +1614,7 @@ void update_early_mmu_table(void)
>>> PTE_BLOCK_MEMTYPE(MT_NORMAL) |
>>> PTE_BLOCK_OUTER_SHARE |
>>> PTE_BLOCK_NS |
>>> - PTE_TYPE_VALID);
>>> + PTE_TYPE_VALID, true);
>>> }
>>> }
>>> }
>>> diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
>>> index dbf9ab43e280..0a8ca19e45e9 100644
>>> --- a/arch/arm/include/asm/system.h
>>> +++ b/arch/arm/include/asm/system.h
>>> @@ -287,8 +287,9 @@ void flush_l3_cache(void);
>>> * @emerg: Also map the region in the emergency table
>>> */
>>> void mmu_map_region(phys_addr_t start, u64 size, bool emerg);
>>> -void mmu_change_region_attr(phys_addr_t start, size_t size, u64 attrs);
>>> +void mmu_change_region_attr(phys_addr_t start, size_t size, u64 attrs, bool bbm);
>>>
>>> +void mmu_set_attrs(phys_addr_t addr, size_t size, int type);
>>> /*
>>> * smc_call() - issue a secure monitor call
>>> *
>>> diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
>>> index 2ef936aab757..13f4e8e640ef 100644
>>> --- a/arch/arm/mach-snapdragon/board.c
>>> +++ b/arch/arm/mach-snapdragon/board.c
>>> @@ -577,7 +577,7 @@ static void carve_out_reserved_memory(void)
>>> if (i == count || start + size < res[i].start - SZ_2M) {
>>> debug(" 0x%016llx - 0x%016llx: reserved\n",
>>> start, start + size);
>>> - mmu_change_region_attr(start, size, PTE_TYPE_FAULT);
>>> + mmu_change_region_attr(start, size, PTE_TYPE_FAULT, true);
>>> /* If this is the final region then quit here before we index
>>> * out of bounds...
>>> */
More information about the U-Boot
mailing list