On Dec 17, 2019, at 10:21 PM, Andrew Wesie awesie@gmail.com wrote:
On Tue, Dec 17, 2019 at 8:31 PM Andrew Wesie awesie@gmail.com wrote:
On Tue, Dec 17, 2019 at 8:07 PM Ken Thomases ken@codeweavers.com wrote:
Are the semantics of the fields of MEMORY_WORKING_SET_EX_BLOCK documented or explained somewhere? It's hard to comment intelligently without that.
Not really. My knowledge is limited to what my test has shown:
- Demand-zero page is "Invalid"
- Once you read from a demand-zero page (or write to it), it is now "Valid"
- If you change a page protection to NOACCESS or GUARD, it is "Invalid"
- If you change a page protection from NOACCESS or GUARD to
READ_ONLY, READWRITE, ... without GUARD, it is still "Invalid"
- If you then read from that page (or write to it), it is now "Valid"
One additional hint that I just found in VirtualQuery documentation is: "To detect whether copy-on-write has occurred for a specific page, either access the page or lock it using the VirtualLock function to make sure the page is resident in memory, then use the QueryWorkingSetEx function ...".
This seems to imply that when pages are mapped into a process, they are not resident (e.g. "Valid") until they are accessed or locked. Additionally, from my previous email, pages become non-resident when their protection changes to PAGE_NOACCESS or PAGE_GUARD. The page will then only become resident once it is accessed (read or write) again.
The Linux kernel supports the concept of a "soft dirty" bit in the PTE that is accessible to user space with pagemaps. This is almost what we need, except it only handles writes and we need it to mark pages on read as well.
I wonder if it wouldn't be good enough to just use the current page protection. If a page allows access, you have to assume another thread could access it at any time. So, we could just pretend one has.
NOACCESS or GUARD -> invalid anything else -> valid
Do you happen to know if that would satisfy League of Legends?
-Ken