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(
|
VMSAv8TranslationMap::ClearAccessedAndModified(
|
||||||
VMArea* area, addr_t address, bool unmapIfUnaccessed, bool& _modified)
|
VMArea* area, addr_t address, bool unmapIfUnaccessed, bool& _modified)
|
||||||
{
|
{
|
||||||
panic("VMSAv8TranslationMap::ClearAccessedAndModified not implemented\n");
|
RecursiveLocker locker(fLock);
|
||||||
return B_OK;
|
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