summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKinsey Moore <kinsey.moore@oarcorp.com>2022-11-16 09:22:34 -0600
committerChris Johns <chrisj@rtems.org>2022-11-17 10:29:04 +1100
commita9861ceea052518d18e0431ad33548aedaec1b4c (patch)
tree9b824daed22a161c80945cd29e4bd8a52e53d690
parenttestsuites/smptests: Change license to BSD-2 for files with Gaisler copyright (diff)
downloadrtems-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.h23
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 );