diff options
author | Kinsey Moore <kinsey.moore@oarcorp.com> | 2022-11-16 09:22:34 -0600 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2022-11-17 10:29:04 +1100 |
commit | a9861ceea052518d18e0431ad33548aedaec1b4c (patch) | |
tree | 9b824daed22a161c80945cd29e4bd8a52e53d690 | |
parent | testsuites/smptests: Change license to BSD-2 for files with Gaisler copyright (diff) | |
download | rtems-a9861ceea052518d18e0431ad33548aedaec1b4c.tar.bz2 |
aarch64/mmu: Prevent block descriptors at level -1
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.
-rw-r--r-- | bsps/aarch64/include/bsp/aarch64-mmu.h | 23 |
1 files 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 ); |