From 457afee959134319841bf25190b8897e0560d93e Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Wed, 18 Sep 2024 09:03:18 +0200 Subject: [PATCH 1/2] ace: mm: tlb: Ignore unmappig error in driver initalization The sys_mm_drv_unmap_region_initial function is responsible for unmapping all unused virtual memory during tlb driver initialization. Most addresses will not have a mapped page. Ignore the error code indicating unmapped memory that will occur when trying to unmap. Signed-off-by: Adrian Warecki --- drivers/mm/mm_drv_intel_adsp_mtl_tlb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c index 5b0bc5e576be05..244f10846f621b 100644 --- a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c +++ b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c @@ -478,7 +478,11 @@ static int sys_mm_drv_unmap_region_initial(void *virt_in, size_t size) int ret2 = sys_mm_drv_unmap_page_wflush(va, false); - if (ret2 != 0) { + /* -EFAULT means that this page is not mapped. + * This is not an error since we want to unmap all virtual memory without knowing + * which pages are mapped. + */ + if (ret2 != 0 && ret2 != -EFAULT) { __ASSERT(false, "cannot unmap %p\n", va); ret = ret2; From eba0eb7bb166ea3a489c435e2f122c9a11dbfc39 Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Tue, 10 Sep 2024 13:37:08 +0200 Subject: [PATCH 2/2] ace: mm: tlb: Check tlb translation enabled before flushing cache Before unmapping a memory page, the cache is flushed. If the given memory page is not mapped, this operation ends with a cpu exception on the ptl platform. Add check if tlb translation is active before flushing. Signed-off-by: Adrian Warecki --- drivers/mm/mm_drv_intel_adsp_mtl_tlb.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c index 244f10846f621b..67210505cb9c20 100644 --- a/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c +++ b/drivers/mm/mm_drv_intel_adsp_mtl_tlb.c @@ -338,6 +338,7 @@ static int sys_mm_drv_unmap_page_wflush(void *virt, bool flush_data) k_spinlock_key_t key; uint32_t entry_idx, bank_idx; uint16_t *tlb_entries = UINT_TO_POINTER(TLB_BASE); + uint16_t entry; uintptr_t pa; int ret = 0; @@ -359,6 +360,17 @@ static int sys_mm_drv_unmap_page_wflush(void *virt, bool flush_data) key = k_spin_lock(&tlb_lock); + entry_idx = get_tlb_entry_idx(va); + entry = tlb_entries[entry_idx]; + + /* Check if the translation is enabled in the TLB entry. + * Attempt to flush the cache of an inactive address will result in a cpu exception. + */ + if (!(entry & TLB_ENABLE_BIT)) { + ret = -EFAULT; + goto out_unlock; + } + /* * Flush the cache to make sure the backing physical page * has the latest data. @@ -371,8 +383,7 @@ static int sys_mm_drv_unmap_page_wflush(void *virt, bool flush_data) #endif } - entry_idx = get_tlb_entry_idx(va); - pa = tlb_entry_to_pa(tlb_entries[entry_idx]); + pa = tlb_entry_to_pa(entry); /* Restore default entry settings with cleared the enable bit. */ tlb_entries[entry_idx] = 0; @@ -395,6 +406,7 @@ static int sys_mm_drv_unmap_page_wflush(void *virt, bool flush_data) } } +out_unlock: k_spin_unlock(&tlb_lock, key); out: