maxbc
maxbc

Reputation: 1027

Why are ASID only in the TLB in ARMv8-A? How to avoid unauthorized access to memory present in tables but ejected from TLB?

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?

Upvotes: 2

Views: 4318

Answers (4)

user3764152
user3764152

Reputation: 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.

Upvotes: -1

simranjeet
simranjeet

Reputation: 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....

Upvotes: -1

maxbc
maxbc

Reputation: 1027

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).

Upvotes: 1

Zhifei
Zhifei

Reputation: 124

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.

Upvotes: 3

Related Questions