[PATCH 1/3] arm64: Use FEAT_HAFDBS to track dirty pages when available
Chris Packham
judge.packham at gmail.com
Fri Oct 13 04:40:24 CEST 2023
Hi Marc, Paul,
On Sat, Mar 18, 2023 at 5:23 AM Ying-Chun Liu (PaulLiu)
<paul.liu at linaro.org> wrote:
>
> From: Marc Zyngier <maz at kernel.org>
>
> Some recent arm64 cores have a facility that allows the page
> table walker to track the dirty state of a page. This makes it
> really efficient to perform CMOs by VA as we only need to look
> at dirty pages.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> [ Paul: pick from the Android tree. Rebase to the upstream ]
> Signed-off-by: Ying-Chun Liu (PaulLiu) <paul.liu at linaro.org>
> Cc: Tom Rini <trini at konsulko.com>
> Link: https://android.googlesource.com/platform/external/u-boot/+/3c433724e6f830a6b2edd5ec3d4a504794887263
I think this may have caused a regression for the Marvell AC5X
board(s). I found that v2023.07 locked up at boot but v2023.01 was
fine. The lockup seemed to be in the 'Net:' init probably just as the
mvneta driver was being initialised.
A git bisect led me to this change although for this specific change
instead of the lockup I get a crash so maybe I'm actually hitting a
different issue.
Any thoughts as to why this may have caused problems?
> ---
> arch/arm/cpu/armv8/cache_v8.c | 16 +++++++++++++++-
> arch/arm/include/asm/armv8/mmu.h | 14 ++++++++++----
> arch/arm/include/asm/global_data.h | 1 +
> 3 files changed, 26 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
> index 697334086f..4760064ee1 100644
> --- a/arch/arm/cpu/armv8/cache_v8.c
> +++ b/arch/arm/cpu/armv8/cache_v8.c
> @@ -93,6 +93,8 @@ u64 get_tcr(u64 *pips, u64 *pva_bits)
>
> if (el == 1) {
> tcr = TCR_EL1_RSVD | (ips << 32) | TCR_EPD1_DISABLE;
> + if (gd->arch.has_hafdbs)
> + tcr |= TCR_HA | TCR_HD;
> } else if (el == 2) {
> tcr = TCR_EL2_RSVD | (ips << 16);
> } else {
> @@ -200,6 +202,9 @@ static void __cmo_on_leaves(void (*cmo_fn)(unsigned long, unsigned long),
> attrs != PTE_BLOCK_MEMTYPE(MT_NORMAL_NC))
> continue;
>
> + if (gd->arch.has_hafdbs && (pte & (PTE_RDONLY | PTE_DBM)) != PTE_DBM)
> + continue;
> +
> end = va + BIT(level2shift(level)) - 1;
>
> /* No intersection with RAM? */
> @@ -348,6 +353,9 @@ static void add_map(struct mm_region *map)
> if (va_bits < 39)
> level = 1;
>
> + if (gd->arch.has_hafdbs)
> + attrs |= PTE_DBM | PTE_RDONLY;
> +
> map_range(map->virt, map->phys, map->size, level,
> (u64 *)gd->arch.tlb_addr, attrs);
> }
> @@ -399,7 +407,13 @@ static int count_ranges(void)
> __weak u64 get_page_table_size(void)
> {
> u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64);
> - u64 size;
> + u64 size, mmfr1;
> +
> + asm volatile("mrs %0, id_aa64mmfr1_el1" : "=r" (mmfr1));
> + if ((mmfr1 & 0xf) == 2)
> + gd->arch.has_hafdbs = true;
> + else
> + gd->arch.has_hafdbs = false;
>
> /* Account for all page tables we would need to cover our memory map */
> size = one_pt * count_ranges();
> diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h
> index 9f58cedb65..98a27db316 100644
> --- a/arch/arm/include/asm/armv8/mmu.h
> +++ b/arch/arm/include/asm/armv8/mmu.h
> @@ -49,10 +49,13 @@
> #define PTE_TYPE_BLOCK (1 << 0)
> #define PTE_TYPE_VALID (1 << 0)
>
> -#define PTE_TABLE_PXN (1UL << 59)
> -#define PTE_TABLE_XN (1UL << 60)
> -#define PTE_TABLE_AP (1UL << 61)
> -#define PTE_TABLE_NS (1UL << 63)
> +#define PTE_RDONLY BIT(7)
> +#define PTE_DBM BIT(51)
> +
> +#define PTE_TABLE_PXN BIT(59)
> +#define PTE_TABLE_XN BIT(60)
> +#define PTE_TABLE_AP BIT(61)
> +#define PTE_TABLE_NS BIT(63)
>
> /*
> * Block
> @@ -99,6 +102,9 @@
> #define TCR_TG0_16K (2 << 14)
> #define TCR_EPD1_DISABLE (1 << 23)
>
> +#define TCR_HA BIT(39)
> +#define TCR_HD BIT(40)
> +
> #define TCR_EL1_RSVD (1U << 31)
> #define TCR_EL2_RSVD (1U << 31 | 1 << 23)
> #define TCR_EL3_RSVD (1U << 31 | 1 << 23)
> diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
> index 9e746e380a..eda99b5b41 100644
> --- a/arch/arm/include/asm/global_data.h
> +++ b/arch/arm/include/asm/global_data.h
> @@ -52,6 +52,7 @@ struct arch_global_data {
> #if defined(CONFIG_ARM64)
> unsigned long tlb_fillptr;
> unsigned long tlb_emerg;
> + bool has_hafdbs;
> #endif
> #endif
> #ifdef CFG_SYS_MEM_RESERVE_SECURE
> --
> 2.39.2
>
More information about the U-Boot
mailing list