VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've been reading https://pdos.csail.mit.edu/6.828/2016/reading … i386/s10_06.htm

This shows that the 80386 is using some four-way lookup TLB? How is this used on a 80386+? What do those four entries do? Does it contain protection data as well? So when a memory access is made(giving read/write, user/supervisor and page frame address(4KB block in memory)), how does this handle page faults and fault codes pushed on the stack?

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

Reply 1 of 8, by superfury

User metadata
Rank l33t++
Rank
l33t++

Thinking about it, it's not too difficult. The only remaining problem for implementation is this: it says it's divided into four blocks(sets). How is the set to use with a memory address chosen? Is it bits 31-30? Or 13-12? Or something else entirely?

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

Reply 2 of 8, by peterferrie

User metadata
Rank Oldbie
Rank
Oldbie

When a request is successful, the address and protection bits go into the TLB.
The top 'x' bits (ways) are used to index into the array of 'y' entries (sets).
Find the appropriate set, search within it for a match.
The regular protection checks are still performed afterwards.

Reply 3 of 8, by superfury

User metadata
Rank l33t++
Rank
l33t++

So the sets are the big memory area spaces(0-1GB, 1-2GB, 2-3GB and 3-4GB linear memory). Each of those areas(sets) owns 8 entries to store and load entries(struct containing tag(consists of user(CPL being 3 or not), RW(access being a write or not) and linear 4KB block(bits 12-31 of the linear address)), physical address(of the frame) and age(counters are cleared on access and increase over time(update function in paging.c). The lowest age(or first unused TLB entry unused) are used for saving new entries.

https://bitbucket.org/superfury/unipcemu/src/ … ing.c?at=master

In UniPCemu(current commit above), the highest two bits are used for the Set lookup, then looking within the Set(8 entries) for a match.
The Page protection and translation scheme works as follows: (Assuming 80386)
1. A TLB lookup is executed. If it succeeds(hits), the returned address is used and no errors are thrown(TLB lookup means that no further checking is required: U/S and R/W are OK, otherwise it wouldn't be hit(due to TLB only containing valid memory accesses)).
2. If the TLB lookup failed, fetch PDE/PTE from memory, throwing Page Faults when not present. After loading, verify U/S and R/W rights. If not allowed, Page Fault. Otherwise, add entry to TLB and access memory(mappage reads TLB and gives translated address).

Is that behaviour correct? More bits could be added to the tag and/or physical address(data in TLB) for adding security checks(protection). It currently assumes: TLB HIT=Protection OK. Otherwise, fetch PDE/PTE and check as described.

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

Reply 4 of 8, by peterferrie

User metadata
Rank Oldbie
Rank
Oldbie

1. is not correct. Even if the address is in the TLB, you still need the protection check. If supervisor mode accessed a page that only supervisor can read, then user-mode accesses the same page, it should fail even though it's in the TLB. The TLB simply avoids the translation overhead.

Reply 5 of 8, by superfury

User metadata
Rank l33t++
Rank
l33t++

Not exactly. When user mode accesses the TLB, it does a lookup with the user bit set to 1. That will fail, as it's never addes(as the protection bits cause a fault when it's first loaded, thus it cannot be in the TLB). So the TLB lookup fails in user mode(U bit being 1, which generates a tag that doesn't match). Since those protection bits are included in the tag(U/S bit, R/W bit and Dirty bit), user mode cannot fetch it from the TLB(since it only has the supervisor entry stored). As the lookup fails, the DPE and DTE are loaded. Then the data is checked for exceptions, which triggers an #PF fault. Since the #PF fault is triggered, the lookup isn't added to the TLB. This way, since the tag includes the U/S of the memory access, R/W(reading ) of the and Linear Frame Address, any invalid combination not stored automatically makes it check all those bits against the entries in memory. That way, the TLB never contains invalid memory accesses(invalid U/S and R/W combinations not allowed by the entry), while valid TLB lookups(where Hit literally means the U/S and R/W is allowed according to the PDE/PTE entries) contain entries that are allowed with the software's protection rights. The dirty bit is set on TLB lookups, when writing. Cleared or Set when reading the Tag(unknown which one)?

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

Reply 6 of 8, by peterferrie

User metadata
Rank Oldbie
Rank
Oldbie

The address has to be matched in the TLB before the protection check can happe nbecause there can be a mixture of supervisor and user addresses in the TLBs.
Otherwise you are performing the address lookup that should be avoided by using the TLB in order to find the corresponding protection bits.

Reply 7 of 8, by superfury

User metadata
Rank l33t++
Rank
l33t++

What I mean, is that the TLB is looked up with the Tag consisting of R/W being whether an access is a read or a write. The Tag's Dirty bit is looked up as 1(during writes only) and 0 always. The Tag's U/S bit is looked up as CPL being 3 or not. Thus, the method described in my last post will make exception checks always with actions that cause faults(invalid accesses), while valid protection accesses always manage to read a valid TLB entry after thr first protection check(after which it's added to the TLB, making future accesses succeed automatically until the entry is flushed).

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

Reply 8 of 8, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've modified the TLB lookup from the MMU to not retrieve non-dirty entries during writes, now handling dirty frames and their writeback into memory correctly:
https://bitbucket.org/superfury/unipcemu/src/ … ing.c?at=master

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