[PATCH] aarch64/mmu: Prevent block descriptors at level -1

Chris Johns chrisj at rtems.org
Wed Nov 16 23:39:38 UTC 2022


Tested on Versal (A72) and large mappings are now working. I have pushed the patch.

Thanks for this. :)

Chris

On 17/11/2022 2:22 am, Kinsey Moore wrote:
> In the original implementation, level -1 was unused and all levels could
> have block-like descriptors (level 2 block descriptors are called page
> descriptors). When support for level -1 page tables was added the
> constraint on level -1 block descriptors was not honored. This prevents
> block descriptors from being mapped at level -1 since the hardware will
> not map them properly.
> ---
>  bsps/aarch64/include/bsp/aarch64-mmu.h | 23 +++++++++++++----------
>  1 file changed, 13 insertions(+), 10 deletions(-)
> 
> diff --git a/bsps/aarch64/include/bsp/aarch64-mmu.h b/bsps/aarch64/include/bsp/aarch64-mmu.h
> index 1287c67016..ebc224b9e1 100644
> --- a/bsps/aarch64/include/bsp/aarch64-mmu.h
> +++ b/bsps/aarch64/include/bsp/aarch64-mmu.h
> @@ -243,26 +243,29 @@ BSP_START_TEXT_SECTION static inline rtems_status_code aarch64_mmu_map_block(
>      /* check for perfect block match */
>      if ( block_bottom == addr ) {
>        if ( size >= chunk_size ) {
> -        /* when page_flag is set the last level must be a page descriptor */
> -        if ( page_flag || ( page_table[index] & MMU_DESC_TYPE_TABLE ) != MMU_DESC_TYPE_TABLE ) {
> -          /* no sub-table, apply block properties */
> -          page_table[index] = addr | flags | page_flag;
> -          size -= chunk_size;
> -          addr += chunk_size;
> -          continue;
> +        /* level -1 can't contain block descriptors, fall through to subtable */
> +        if ( level != -1 ) {
> +          /* when page_flag is set the last level must be a page descriptor */
> +          if ( page_flag || ( page_table[index] & MMU_DESC_TYPE_TABLE ) != MMU_DESC_TYPE_TABLE ) {
> +            /* no sub-table, apply block properties */
> +            page_table[index] = addr | flags | page_flag;
> +            size -= chunk_size;
> +            addr += chunk_size;
> +            continue;
> +          }
>          }
>        } else {
>          /* block starts on a boundary, but is short */
>          chunk_size = size;
>  
> -	/* it isn't possible to go beyond page table level 2 */
> -	if ( page_flag ) {
> +        /* it isn't possible to go beyond page table level 2 */
> +        if ( page_flag ) {
>            /* no sub-table, apply block properties */
>            page_table[index] = addr | flags | page_flag;
>            size -= chunk_size;
>            addr += chunk_size;
>            continue;
> -	}
> +        }
>        }
>      } else {
>        uintptr_t block_top = RTEMS_ALIGN_UP( addr, granularity );


More information about the devel mailing list