[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