Skip to content

Commit fd24359

Browse files
committed
aarch64: force TLB flush when mprotect changes permission
When testing the tst-map.cc and tst-elf-permissions.cc with the upcoming patch to add signals support on aarch64, I noticed that sometimes they would kind of "hang" for a while and eventually complete successfully. This would happen especially when running in non-SMP mode (1 CPU). After more investigation I discovered that the tests would actually get into a page fault "loop" after calling mprotect() in the signal handler and stay like so until the page table changes were flushed which I am explaining below. Analysis of the mmu::protect() and the protection vma operation made me realize that it has an optimization to trigger full TLB flush only if pemissions are reduced for any of the relevant pages (see eefcb08). The problem is that on ARM any change to the page entry table (regardless if reduction or expansion) needs a forced completion of writes achieved by the sequence of `dsb ishst` followed by `isb`. Full flush of TLB on ARM does that but on top of the expensive `tlbi vmalle1is`. So to fix this problem, this patch changes change_perm() to return true if permission changes on aarch64 which would then trigger TLB flush when the protection vma operation completes. In future we may optimize it. Signed-off-by: Waldemar Kozaczuk <[email protected]>
1 parent a26f0b2 commit fd24359

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

core/mmu.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,15 @@ bool change_perm(hw_ptep<N> ptep, unsigned int perm)
242242
pte.set_rsvd_bit(0, !perm);
243243
ptep.write(pte);
244244

245+
#ifdef __x86_64__
245246
return old & ~perm;
247+
#endif
248+
#ifdef __aarch64__
249+
//TODO: This will trigger full tlb flush in slightly more cases than on x64
250+
//and in future we should investigate more precise and hopefully lighter
251+
//mechanism. But for now it will do it.
252+
return old != perm;
253+
#endif
246254
}
247255

248256
template<int N>

0 commit comments

Comments
 (0)