[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