/// <inheritdoc/> public void TrackingReprotect(ulong va, ulong size, MemoryPermission protection) { AssertValidAddressAndSize(va, size); // Protection is inverted on software pages, since the default value is 0. protection = (~protection) & MemoryPermission.ReadAndWrite; long tag = protection switch { MemoryPermission.None => 0L, MemoryPermission.Write => 2L << PointerTagBit, _ => 3L << PointerTagBit }; int pages = GetPagesCount(va, (uint)size, out va); ulong pageStart = va >> PageBits; long invTagMask = ~(0xffffL << 48); for (int page = 0; page < pages; page++) { ref long pageRef = ref _pageTable.GetRef <long>(pageStart * PteSize); long pte; do { pte = Volatile.Read(ref pageRef); }while (pte != 0 && Interlocked.CompareExchange(ref pageRef, (pte & invTagMask) | tag, pte) != pte); pageStart++; } }