Virtually indexed tag storage (Svatag and Smvatag)

Svatag (for S/HS/VS/U/VU) and Smvatag (for M) extensions defines that tag storage and tag lookups for memory chunks (mc) as defined by Zimt (see Memory tagging extension (Zimt)) extension is in virtual address space of execution environment. Tag storage can be viewed as a large array (hereafter referred to as virtually indexed tag table or VITT) of the tags (mc_tag) with each tag width = mc_tag_width (see Memory tagging extension (Zimt) for mc_tag and mc_tag_width). Base virtual address of this large array is determined differently depending on privilege mode (see Tag table base address CSRs) and hereafter referred as xVITT_BASE.

Tag look up in virtually indexed tag table

Virtual address location (mc_tag_va) of mc_tag for a given memory chunk located at virtual address va is looked up in VITT using the following formula

mc_tag_va = VITT_BASE + (((va >> 4) * mc_tag_width) >> 3)
Table 1. mc_tag_va for each mc_tag_width
mc_tag_width mc_tag_va

4

VITT_BASE + (va >> 5)

8

VITT_BASE + (va >> 4)

When a regular load/store is performed on a virtual address va with tag checks (see tag checks and privilege modes) enforced then hart performs tag look up by performing a load tag operation on mc_tag_va for the corresponding va and extracts mc_tag from the loaded value at the virtual address mc_tag_va.

Tag loads are part of tag look up and can raise load page fault on mc_tag_va, if it doesn’t have read permissions in page tables.

In case of mc_tag_width = 4 bit, each single byte in tag storage is packed with two mc_tag for two consecutive memory chunks. Thus extracting a mc_tag requires masking and shifting of bits after the value is loaded from mc_tag_va.

When settag instruction is executed for memory chunks(s) starting at the virtual address va (see set tag(s) for memory chunk(s)) and memory tagging is enabled for current execution environment, then hart performs tag store by performing a store on mc_tag_va for the corresponding va.

Tag stores are generated from settag and can raise store page fault on mc_tag_va address, if it doesn’t have write permissions in page tables.

In case of mc_tag_width = 4 bit, each single byte in tag storage is packed with two mc_tag for two consecutive memory chunks. Thus storing a mc_tag requires read, modify (masking and shifting of bits) and store back to mc_tag_va.

Tag table base address CSRs

Tag storage base virtual address (xVITT_BASE) is defined using privileged CSRs. Tag table base address must be 4K aligned. Following table list the privileged CSRs.

Table 2. Privileged tag base address CSRs
Privilege level CSR

U

svittu

S / HS

svitts

VS

vsvitts

VU

vsvittu

M

mvitt

Svatag defines the svittu, svitts, vsvittu` and vsvitts CSRs while Smvatag defines mvitt.

Accessibility of Svatag CSRs

CSR access to svittu, svitts, vsvitts, and vsvittu from modes less privileged than M causes illegal instruction exception if Smstateen is implemented and mstateen0.MT=0.

CSR access to svitts and svittu from VS mode causes virtual instruction exception if Ssstateen is implemented, hstateen0.MT=0, and mstateen0.MT=1 or Smstateen is not implemented.

The CSR access from VS mode, if allowed, uses the state of vsvitts and vsvittu CSRs, respectively.
The position of the MT bit in [mh]stateen must be specified before ratification.

Protection of tag storage

Hart must raise access faults on regular loads and stores to virtual addresses spanning VITT range. Hart must also raise access fault on settag instruction if the memory chunk specified in rs1 overlaps with VITT range. VITT range is defined as below

tag_memory_region_start = mc_tag_va(LOWEST_VADDR_CURR_PRIV)
tag_memory_region_end = mc_tag_va(HIGHEST_VADDR_CURR_PRIV)
LOWEST_VADDR_CURR_PRIV: Lowest virtual address in current privilege.
HIGHEST_VADDR_CURR_PRIV: Highest virtual address in current privilege.
Table 3. Lowest and highest virtual addresses
Privilege level LOWEST_VADDR_CURR_PRIV HIGHEST_VADDR_CURR_PRIV

U

0

2 ^ (VADDR_BITS - 1) - 1

S / HS / VS

2 ^ (VADDR_BITS - 1)

2 ^ (VADDR_BITS) - 1

M

Impl. defined

Impl. defined

VADDR_BITS is virtual addressing bits. VADDR_BITS can be 39, 48 or 57 depending on Sv39, Sv48 or Sv57 virtual addressing mode in satp CSR. In bare mode and M-mode, LOWEST_VADDR_CURR_PRIV and HIGHEST_VADDR_CURR_PRIV are implementation defined.

Svatag depends on Svukte extension and thus assumes an even split in address space between user and supervisor with user address space spanning from zero to maxium positive address while supervisor address space spanning from minimum negative value to maximum negative value.

HLV* and HSV* instructions use vsvittu or vsvitts as base of the tag table depending on if hstatus.SPVP=0 or hstatus.SPVP=1, respectively.

Note on speculative execution

RISC-V memory tagging is intended to provide probabilistic detection of memory-safety errors through tag checks on memory accesses. It does not assume that pointer tags or memory tags are confidential architectural secrets.

Implementations may allow speculative execution to proceed before a tag check is fully resolved, provided that any failing checked access is handled according to the architectural exception rules before retirement. A speculative oracle that reveals whether a tag check would pass can reduce the probabilistic protection provided by tag guessing, but this is not, by itself, a violation of the memory-tagging model.

Mitigation of speculative-execution side channels may be addressed by separate RISC-V mechanisms or task groups, such as speculation barriers, timing fences, or other platform-specific security extensions, and is not required as part of the memory-tagging extension itself. For more information on RISC-V’s primitives to handle secure assets refer to the Security Model.