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

Kinsey Moore kinsey.moore at oarcorp.com
Wed Nov 16 15:22:34 UTC 2022


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 );
-- 
2.30.2



More information about the devel mailing list