From f2e8f48cc30271089d769e18520b9198cf13b2be Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 30 Sep 2024 08:02:19 +0000 Subject: [PATCH] arm64: Clean up VMSAv8TranslationMap::ClearFlags * Save a TLB flush on the case where we only clear the accessed flag. Change-Id: Icd9210d616a2eca13a9be9497f2a787ab0eaf266 Reviewed-on: https://review.haiku-os.org/c/haiku/+/8422 Reviewed-by: waddlesplash --- .../arch/arm64/VMSAv8TranslationMap.cpp | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/system/kernel/arch/arm64/VMSAv8TranslationMap.cpp b/src/system/kernel/arch/arm64/VMSAv8TranslationMap.cpp index 33d92b4ae9..2a29703a13 100644 --- a/src/system/kernel/arch/arm64/VMSAv8TranslationMap.cpp +++ b/src/system/kernel/arch/arm64/VMSAv8TranslationMap.cpp @@ -964,39 +964,37 @@ VMSAv8TranslationMap::ClearFlags(addr_t va, uint32 flags) ThreadCPUPinner pinner(thread_get_current_thread()); - uint64_t oldPte = 0; ProcessRange(fPageTable, fInitialLevel, va, B_PAGE_SIZE, nullptr, - [=, &oldPte](uint64_t* ptePtr, uint64_t effectiveVa) { + [=](uint64_t* ptePtr, uint64_t effectiveVa) { if (clearAF && setRO) { // We need to use an atomic compare-swap loop because we must // need to clear one bit while setting the other. while (true) { - oldPte = atomic_get64((int64_t*)ptePtr); + uint64_t oldPte = atomic_get64((int64_t*)ptePtr); uint64_t newPte = oldPte & ~kAttrAF; newPte = set_pte_clean(newPte); - if ((uint64_t)atomic_test_and_set64((int64_t*)ptePtr, newPte, oldPte) == oldPte) + if ((uint64_t)atomic_test_and_set64((int64_t*)ptePtr, newPte, oldPte) == oldPte) { + FlushVAIfAccessed(oldPte, va); break; + } } } else if (clearAF) { - oldPte = atomic_and64((int64_t*)ptePtr, ~kAttrAF); + atomic_and64((int64_t*)ptePtr, ~kAttrAF); } else { while (true) { - oldPte = atomic_get64((int64_t*)ptePtr); - if (!is_pte_dirty(oldPte)) { - // Avoid a TLB flush - oldPte = 0; + uint64_t oldPte = atomic_get64((int64_t*)ptePtr); + if (!is_pte_dirty(oldPte)) return; - } uint64_t newPte = set_pte_clean(oldPte); - if ((uint64_t)atomic_test_and_set64((int64_t*)ptePtr, newPte, oldPte) == oldPte) + if ((uint64_t)atomic_test_and_set64((int64_t*)ptePtr, newPte, oldPte) == oldPte) { + FlushVAIfAccessed(oldPte, va); break; + } } } }); - FlushVAIfAccessed(oldPte, va); - return B_OK; }