VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

When is the bit updated to be dirty? Is that done during the check before the instruction is actually executed(when it's validated the memory accesses for that page to be valid to write to)? Or is that only done when all memory accesses are validated and the instruction actually writes data to the page frame contents(which will of course modify the TLB contents as well)?

What about the accessed bits? Do they follow the same principle? Or are they simply an indicator that the Paging Unit has loaded them for processing(thus being set whenever the Paging Unit loads them into the TLB, regardless if they're actually read or written to for the current instruction)?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 3, by Stenzek

User metadata
Rank Newbie
Rank
Newbie

The Intel SDM says:

Whenever the processor uses a paging-structure entry as part of linear-address translation, it sets the accessed flag in that entry (if it is not already set).Whenever there is a write to a linear address, the processor sets the dirty flag (if it is not already set) in the paging-structure entry that identifies the final physical address for the linear address (either a PTE or a paging-structure entry in which the PS flag is 1).

I have the accessed/dirty bits updated when it is inserted into the TLB, but I have seperate read and write TLBs, so an entry will be inserted on the first read/write, updating the bit. Note that the dirty bit is not set on the directory entry, only on the page entry.

Reply 2 of 3, by superfury

User metadata
Rank l33t++
Rank
l33t++

Well, even the directory entry seems to have a dirty bit on a Pentium and up? Bit 6 (value 0x40) of a PDE pointing to a 4MB entry(when bit 7 being set to indicate a 4MB PDE without 4KB PTE's inside it and the CR4 PSE bit(bit 4, value 0x10) being set to enable the large pages) is supposed to behave in the same way(duplicated functionality of the PTE handling?).

So on the Pentium with PSE enabled, there is a dirty bit at the same location as the PTE, but in the PDE instead(See also: https://en.wikipedia.org/wiki/PSE-36 ).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 3 of 3, by superfury

User metadata
Rank l33t++
Rank
l33t++

I had just implemented the dirty and accessed bits to be set when the actual memory accesses were approved(all memory accesses being verified to not error out) and the actual memory accesses were being invoked(the physical memory writes/reads).

I've for the moment changed this using a simple define(which is now disabled) which toggles the accessed bit setting being between either setting when the physical access is made(when the define is set, after being verified against the TLB entries for all memory access to be made and not erroring out and the entries aren't marked accessed yet(e.g. when in the TLB and valid for all memory access for the instruction only)) or when the memory is checked(i.e. when the checks for memory are made and the TLB is filled with new data for a valid memory access).

So in the case of e.g. PUSH EAX, the defined version(the define being set) causes it to check each byte in memory against the TLB, loading it into the TLB as needed(and erroring out otherwise), then when all is fine, the memory access is made. Only the latter memory access actually sets the accessed bit in the TLB and page tables PDE(and PTE if a 4KB entry)).
The undefined version makes it ignore the accessed bit in the TLB, instead setting the accessed bit when checking against memory accesses itself, before performing the actual memory accesses, even if the one after the first access errors out(so if the first byte is in a present page, the PDE(and PTE if used) are marked accessed, but the second page of the memory access isn't(since it errored out(page fault) when verifying it, either due to access rights violations or not being present).

And the dirty flag of course is always only set(when not set yet) when the actual memory is written (leaved unchanged when one of the checks errored out(page fault)).

So what would the correct behaviour be with regards to accessed/dirty? I'd assume accessed when having validated the PDE and PTE(only if 4KB) as being a valid access together, while dirty only is set when performing the actual write to memory with the bit in the TLB cleared?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io