arm64: Implement VMSAv8TranslationMap::ClearAccessedAndModified
* Heavily inspired by the RISC-V equivalent. Change-Id: I7d2ed14fb0a246223a23f7df659b6006326a7013 Reviewed-on: https://review.haiku-os.org/c/haiku/+/8155 Reviewed-by: Fredrik Holmqvist <[email protected]> Haiku-Format: Haiku-format Bot <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
baf574c96a
commit
bb67bf75fb
@@ -840,8 +840,52 @@ bool
|
||||
VMSAv8TranslationMap::ClearAccessedAndModified(
|
||||
VMArea* area, addr_t address, bool unmapIfUnaccessed, bool& _modified)
|
||||
{
|
||||
panic("VMSAv8TranslationMap::ClearAccessedAndModified not implemented\n");
|
||||
return B_OK;
|
||||
RecursiveLocker locker(fLock);
|
||||
ThreadCPUPinner pinner(thread_get_current_thread());
|
||||
|
||||
uint64_t pageMask = (1UL << fPageBits) - 1;
|
||||
uint64_t vaMask = (1UL << fVaBits) - 1;
|
||||
|
||||
ASSERT((address & pageMask) == 0);
|
||||
ASSERT(ValidateVa(address));
|
||||
|
||||
uint64_t oldPte = 0;
|
||||
ProcessRange(fPageTable, 0, address & vaMask, B_PAGE_SIZE, nullptr,
|
||||
[=, &_modified, &oldPte](uint64_t* ptePtr, uint64_t effectiveVa) {
|
||||
// We need to use an atomic compare-swap loop because we must
|
||||
// first read the old PTE and make decisions based on the AF
|
||||
// bit to proceed.
|
||||
while (true) {
|
||||
oldPte = atomic_get64((int64_t*)ptePtr);
|
||||
uint64_t newPte = oldPte & ~kAttrAF;
|
||||
newPte |= kAttrAPReadOnly;
|
||||
|
||||
// If the page has been not be accessed, then unmap it.
|
||||
if (unmapIfUnaccessed && (oldPte & kAttrAF) == 0)
|
||||
newPte = 0;
|
||||
|
||||
if ((uint64_t)atomic_test_and_set64((int64_t*)ptePtr, newPte, oldPte) == oldPte)
|
||||
break;
|
||||
}
|
||||
asm("dsb ishst"); // Ensure PTE write completed
|
||||
});
|
||||
|
||||
pinner.Unlock();
|
||||
_modified = (oldPte & kAttrAPReadOnly) == 0;
|
||||
if ((oldPte & kAttrAF) != 0) {
|
||||
FlushVAFromTLBByASID(address);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!unmapIfUnaccessed)
|
||||
return false;
|
||||
|
||||
fMapCount--;
|
||||
|
||||
locker.Detach(); // UnaccessedPageUnmapped takes ownership
|
||||
phys_addr_t oldPa = oldPte & kPteAddrMask;
|
||||
UnaccessedPageUnmapped(area, oldPa >> fPageBits);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user