A microTLB entry can be corrupted following an ASID switch, possibly corrupting subsequent MMU translations. The issue occurs when a speculative explicit memory access is executed under wrong speculation. This typically happens when the memory access occurs under a mispredicted branch or in case it is conditional and the condition fails.
The work-around is to add a DSB instruction in the ASID switch code sequence.
| Impact: | Minor. An MMU translation can get corrupted without the work-around. |
Work-around: |
Add a DSB in the ASID switch code sequences. Seethe Work-around Detailsfor more information. |
Configurations Affected: |
Systems that use the ARM processors MMU. |
| Device Revision(s) Affected: | All, no plan to fix. Refer to (Xilinx Answer 47916) - Zynq-7000 Design Advisory Master Answer Record. |
This speculative memory access can miss in the TLB, and cause a Page Table Walk. The issue occurs when the Page Table Walk starts prior to the ASID switch code sequence, but completes afterwards. The microTLB will get a new entry allocated with this new TLB entry, corresponding to the old ASID. The issue is that the microTLB does not register the ASID value, so that MMU translations which should happen with the new ASID following the ASID switch can hit in this stale microTLB entry, and get corrupted.
It is important to note that there is no Trustzone Security risks because the Security state of the access is registered in the microTLB, and consequently cannot be corrupted.
Work-around Details
Add a DSB in the ASID switch code sequence. The ARM architecture only mandates ISB before and after the ASID switch. Adding a DSB prior to the ASID switch ensures that the Page Table Walk completes prior to the ASID change and no stale entry can be allocated in the microTLB.
The examples in the ARM reference manual for synchronizing the change in the ASID and the Translation Table Base Register (TTBR) should be changed as follows:
| Original sequences: | New sequences: |
Sequence #1 | |
~ |
DSB |
Change ASID to 0 |
Change ASID to 0 |
ISB |
ISB |
Change Translation Table Base Register |
Change Translation Table Base Register |
ISB |
ISB |
~ |
DSB |
Change ASID to new value |
Change ASID to new value |
Sequence #2 | |
Change Translation Table Base Register to the global-only mappings |
Change Translation Table Base Register to the global-only mappings |
ISB |
ISB |
~ |
DSB |
Change ASID to new value |
Change ASID to new value |
ISB |
ISB |
Change Translation Table Base Register to new value |
Change Translation Table Base Register to new value |
Sequence #3 | |
Set TTBCR.PD0 = 1 |
Set TTBCR.PD0 = 1 |
ISB |
ISB |
~ |
DSB |
Change ASID to new value |
Change ASID to new value |
Change Translation Table Base Register to new value |
Change Translation Table Base Register to new value |
ISB |
ISB |
Set TTBCR.PD0 = 0 |
Set TTBCR.PD0 = 0 |