1

I have a quick question about TLBs and ASIDs in ARMv8-A.
From what I understand (from ARM's programmer guide and Architecture Reference Manual) :
- Page/block descriptors (leaf MMU table entries) do not contain an ASID identifier, only a nG (non-global) bit, which says the ASID should be used for this page.
- The actual ASID value that is matched against the register value resides in the TLB. It is set when a page walk occurs and the corresponding entry is added to the TLB (with the current ASID, so that subsequent TLB lookups will check that the new ASID matches).

Say I want to use ASIDs to avoid updating tables when context switching. Each process has a resident ASID value. Process 1 some data at vaddr a1, process 2 at vaddr a2. I context switch from 1 to 2. During execution the TLB entry corresponding to a1 gets ejected (for some reason). Process 2 accesses a1, a TLB miss occurs, and a page walk happens, succeeds and stores process 1's entry using ASID2 value, giving process 2 access to process 1's data.

What am I not understanding? Shouldn't the ASID mechanic provide security between process 1 and 2 while avoiding updating tables?

Optional question: if all my programs have .text section at the same virtual address (at least, all programs have the same entry point address), do I need to update tables every time I context switch or can I have several entries matching the same vaddr, using different ASIDs?

blueshit
  • 23
  • 5
maxbc
  • 949
  • 1
  • 8
  • 18

4 Answers4

3

Process 1 some data at vaddr a1, process 2 at vaddr a2. I context switch from 1 to 2. During execution the TLB entry corresponding to a1 gets ejected (for some reason). Process 2 accesses a1, a TLB miss occurs, and a page walk happens, succeeds and stores process 1's entry using ASID2 value, giving process 2 access to process 1's data.

When Process 1 want to access vaddr a1, it is actually an address marked as vaddr_a1_with_asid_P1. When Process 2 wants to access vaddr a1, it is actually an address marked as vaddr_a1_with_asid_P2. So in TLB, each TLB entry contains both vaddr and process ASID information.

Then "Process 2 accesses a1, a TLB miss occurs, and a page walk happens, succeeds and stores process 2's entry using ASID2 value" will not happen.

Even for the same vaddr a1, two different processes access a1 will generate two different TLB entries. One is marked with ASID P1, the other is marked with ASID P2.

Optional question: if all my programs have .text section at the same virtual address (at least, all programs have the same entry point address), do I need to update tables every time I context switch or can I have several entries matching the same vaddr, using different ASIDs?

Actullay, OS will take care that. For example, Linux OS will assign an unique ASID to a process. For 8-bit or 16-bit ASID register, the total ASID range is limited.

So when all ASIDs are used out, Linux OS will invalidate the whole TLB and re-assign ASID number from 0 as the beginning of the second loop.

Zhifei
  • 124
  • 5
  • Quoting ARMv8-A PG (page 12-4) : "The [...] TLB is a cache of recently accessed pages translations". So, like any cache, an entry can be ejected at any time, losing its specific ASID binding (which only exists in the TLB). If thereafter the TLB entry is missing, a table walk occurs and assigns the CURRENT asid to the newly-added TLB entry (see also page 12-27). NB: I'm writing an OS – maxbc Mar 14 '17 at 10:23
  • @maxbc The answer and your comment are both correct. The TLB is a 'content addressable cache'. The tags are not just the 'a1' address, but also the ASID. If your p1/p2 both access 'a1', then the TLB has two entries allocated. Your OS must take care to set the ASID correctly if you intend to access a specific version. Another way is to have a 3rd mapping that is only privilege accessed; you would have 'super VA' alias mapping for each of the process 'a1' addresses in this case. You also need to update the page tables on a process change. First level entries are cached as well. – artless noise Mar 14 '17 at 17:50
  • 2
    The benefit of the ASID is that the TLB and the D/I caches do not need to be flushed/invalidated to maintain consistent data. The OS still needs to manage them on a context switch, as I understand.... 'do I need to update tables every time I context switch'; Yes absolutely. How do you know if they are in the TLB/cache or not? You do not need to create the tables each time, just the L1 entries need changing. See; [MMU and page tables](http://stackoverflow.com/questions/9929755/do-multi-core-cpus-share-the-mmu-and-page-tables/33239191#33239191) – artless noise Mar 14 '17 at 17:55
  • @artlessnoise 'do I need to update tables [...]' -> thanks, that's the answer I was looking for. It makes sense now. – maxbc Mar 15 '17 at 13:48
1

It seems I had a misconception about ASIDs. I got the answer thanks to @artlessnoise's comment.

In the case I was describing, I missed the fact that we have to map process 2's pages at some point.

So what we actually do is this:
- Update tables: add process 2's pages, and remove any page process 2 must not see (including, in my example, page at address a1)
- Change the ASID so any cached value with an old ASID cannot be used in TLB
- Start process 2. If process 1's corresponding page is still cached in TLB, it is ignored (since ASIDs mismatch). In both cases, a page walk happens, with the updated table containing only process-2-accessible pages.

So the (main) security is provided by the tables present when process 2 is running. And additional security in the TLB only is provided by the ASID mechanic, allowing us to not flush the TLB at every context switch.

EDIT: Another (far-fetched) solution would be to disable page walks for non-cached pages (trigger a MMU fault instead), and to manually check (from the kernel) process permissions every time a process accesses a non-cached page. It seems horrible performance-wise (as well as design-wise).

maxbc
  • 949
  • 1
  • 8
  • 18
  • ASID in TLB is not security, but optimization to now flush full TLB on context switch. Every **process have its own virtual-to-physical memory mapping**, and without ASID OS will delete all TLB entries from TLB at process switch. With ASID OS may keep old TLB entries for some cases. – osgx Mar 15 '17 at 14:07
  • 1
    @osgx That's exactly what I mean in my answer. The reason why I did not understand it earlier is that I overestimated the cost of switching pages (very low - only a couple L1 requests) vs the cost of flushing TLB (very high - triggers many subsequent page walks). – maxbc Mar 15 '17 at 14:11
  • maxbc, yes, the point is that is *an optimisation*, read more in ["Operating Systems: Three Easy Pieces"](http://pages.cs.wisc.edu/~remzi/OSTEP/) (Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau) ch. 19 "vm-tlb": http://pages.cs.wisc.edu/~remzi/OSTEP/vm-tlbs.pdf#page=9 "*To reduce this overhead .. address space identifier (ASID) field in the TLB*" – osgx Mar 15 '17 at 14:49
  • TLB is not as expensive as compared to the I/D caches (both L1 and L2) should be ASID aware? One TLB entry represents ~4k of L1/L2 cache (making it ~4000x less important). However the act of 'flushing' on a short context switch maybe as expensive. Where little is done (socket polling) on the P1/P2/P1 context switch sequence. – artless noise Mar 15 '17 at 18:32
-1

TLB protection using ASID

The TLB flushing can be avoided by using the above mechanism, but what about the cache enrties. The cache is not flushed on a context switch (when the ASID bits change). Neither the cache contains the ASID bits. Eg.

  1. Process 1 and process 2 are there.
  2. First the process 1 was executing and TLB had ASID bits pertaining to process 1.
  3. This caused the cache to get populated with data of process 1(suppose the process 1 populated the cache with pa1 and pa2 entries as per PAGE TABLE).
  4. Now there is a context switch.
  5. The va from core for process 2 will have different ASID bits in TLB, so it will be a TLB miss an there will be a page table walk.
  6. New PTE pertaining to process 2 comes into TLB, so now its a TLB hit.
  7. The TLB hit causes the search for data in cache (which contains data pertaining to process 1 that has not been invalidated or flushed)
  8. So there may be a case when pa of process 1 may overlap with pa of process 2 and thus there dosent seem to be protection of data between processes, even though TLB protection is there

--Am i wrong somewhere, or am i not considering some basic thing, kindly tell....

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
-1

There will be PA comparison in the VIPT cache which will fail for Process2 with VA1 mapping to PA_process_2_with_asid_proc2.

So it will be a cache miss for Process2 access.

DiskJunky
  • 4,750
  • 3
  • 37
  • 66