Sv32
全称: Page-Based 32-bit Virtual-Memory Systems
当Sv32是被写入到satp.MODE时,s-mode是在一个32-bit的虚拟内存系统。在这种模式下,supervisor和user虚拟地址通过遍历基树页表转换为supervisor物理地址。
当 SXLEN=32 时支持 Sv32,并且旨在包含足以支持现代基于 Unix 的操作系统的机制。
Addressing and Memory Protection
(寻址和内存保护)
Sv32 实现支持 32 位虚拟地址空间,分为 4 KiB 页。将Sv32虚拟地址划分为VPN (virtual page number)和页面偏移量,如图所示。当satp.MODE被设置为Sv32虚拟地址模式时,supervisor虚拟地址通过两级页面转化为supervisor物理地址。20-bit VPN转化成22-bit PPN(physical page number),同时12-bit 页偏移(page offset)不用转换。在直接转换为machine-level物理地址之前,使用物理内存保护结构(physical memory protection structures PMP)检查supervisor-level 物理地址。如果有必须的话,supervisor-level物理地址是可以被zero-extended。
例如,当RV32系统支持34bit的物理地址。当satp.MODE是Sv32, 34 bit物理可以直接产生,不需要zero-extension。当satp.MODE为Bare, 32位虚拟地址被转换(不修改)为32位物理地址,然后这个物理地址被zero-extended为34位机器级物理地址
Sv32 page tables由1024(2^10) PTEs组成,每个PTE有4字节。page table(页表)正好是page的大小,并且必须始终与页边界对齐。root page table的PPN(physical page number)是被存储在satp寄存器中的。
V
PTE(page table entry)格式如上图4.18。V 比特位表示PTE是否有效。如果V=0, 就不需要关心PTE的其他位,可以被软件自由使用。
RWX
权限相关的比特位R/W/X,分别指明page是否可读,读写,可执行。
当X/W/R都等于0时,表示此PTE指向下一级的page table,否者它就是leaf PTE。可写页面也必须被标记为可读的。
试图从没有执行权限的页面获取指令会引发获取页面错误异常(fetch page-fault exception)。
试图在有效的只读地址上执行一个load或load-reserved指令,将触发一个load page-fault exception。
试图在有效的没有写权限的地址上执行一个store、store-conditional或AMO指令,将触发一个store page-fault exception。
注意:AMOs不会触发load page-fault exceptions,因为任何没有读权限的页面,也不会有写权限。所以AMO在操作一个没有读权限的页面时,会产生一个store page-fault exception。
U
U表示 u-mode是否可以访问该页面。u-mode只能在U=1时访问该页面。如果sstatus.SUM位设置为了1,则s-mode也可以访问该页面,然而,s-mode下的软件经常会将sstatus.SUM设置为0,这种情况下supervisor 代码访问u-mod pages将出错。在不考虑sstatus.SUM的情况下,U=1时,supervisor下不能执行代码。
G
G表示一个全局映射(global mapping)。全局映射是存在所有地址空间的。对于non-leaf PTEs,全局设置意味着页表的后续级别中的所有映射都是全局的。注意,没有将一个全局映射标记为global只会降低性能,而将非全局映射标记为全局是一个软件bug,在切换到具有该地址范围的不同非全局映射的地址空间后,可能会意外地导致使用任一映射。
全局映射不需要冗余地存储在多个 ASID 的地址转换缓存中。 此外,当使用 rs2̸=x0 执行 SFENCE.VMA 指令时,它们不需要刷新本地地址转换缓存
RSW
RSW字段被保留给supervisor软件使用,具体实现中应该忽略此字段。
A和D
每一个leaf page包含A(accessed)和D(dirty)比特位。
A比特位表示自上次清除后,虚拟page已经被读取、写入或fetched。
D比特位表示自上次清除后,虚拟page已经被写入。
两种方案管理A和D bits权限:
当虚拟page是被访问时,A bit被清除,或虚拟page被写入时,D bit被清除时,触发一个page-fault exception。
当虚拟page是被访问时,A bit被清除,或虚拟page被写入时,D bit被清除,相应的bit在PTE被设置。PTE 更新对于 PTE 的其他访问必须是原子的,并且必须原子地检查 PTE 是否有效并授予足够的权限。更新A位可能是预测的结果,但是更新D位必须是精确的,而且本地的hart能顺序的观察到A和D的改变。通过FENCE指令和acquire/release 提供的loads和stores 原子指令,在更新PTE是,可以保证loads和stores操作被其他harts观察到。相对于引起更新的显式内存访问而言,PTE更新不需要是原子的,并且序列是可中断的。然而,在PTE更新是全局可见的之前,hart不能执行显式内存访问。
系统中所有的harts必须使用相同的PTE-update方案。
该规范的先前版本要求 PTE A 位更新准确,但允许 A 位作为推测的结果进行更新简化了地址转换预取器的实现。 系统软件通常使用 A 位作为页面替换策略提示,但不要求功能的准确性。 另一方面,D 位更新仍然需要准确并按程序顺序执行,因为 D 位会影响页面删除的功能正确性。
当然,实现仍然允许以精确的方式执行A位和D位更新。
任何level的PTE都可以是leaf PTE,因此除了4KiB pages外,Sv32还支持4MiB megapages。megpage必须虚拟和物理对齐到4mib边界;如果物理地址没有充分对齐,则会引发页错误异常。
对于non-leaf PTEs,D、A和U位是保留给未来的标准使用的。在它们被标准扩展定义之前,它们必须被软件清除以获得前向兼容性。
对于同时具有基于页面的虚拟内存和“A”标准扩展的实现,LR/SC 操作必须完全位于单个基页内(即自然对齐的 4 KiB 区域)。
Virtual Address Translation Process
虚拟地址转换过程
虚拟地址(virtual address,简称va)转换成物理地址(physical address,简称pa)的步骤如下:
设 a 为 satp.ppn × PAGESIZE,令 i = LEVELS - 1。(对于 Sv32,PAGESIZE=2^12 和 LEVELS=2。) satp 寄存器必须处于活动状态,即有效特权模式必须是 S-mode 或 U -模式。
设pte的值为a+va.vpn[i]×PTESIZE。(对于Sv32, PTESIZE=4)。如果访问pte违反了PMA和PMP的检查,则触发一个原来访问类型的access-fault exception。
如果pte.v=0,或pte.r=0且pte.w=1,或如果pte中设置了为未来保留的编码,马上停止,并触发一个原来访问类型的access-fault exception。
到这里,说明PTE是有效的了。如果pte.r = 1或pte.x=1到第五步(注意这里r或x可以单独存在,但是w不能单独存在,所以可以直接判断r=1或x=1来确认是否为leaf page)。否则,这个PTE则是指向下一个level page table的指针。让i 减1。如果i小于0,则立即停止,触发一个原来访问类型的access-fault exception。否则,让a = pte.ppn ×PTESIZE 并且跳转到第2步。
一个leaf PTE是被找到。在给定的当前特权模式以及mstaus寄存器的SUM和MXR字段的值的情况下,确定pte.r,pte.w,pte.x和pte.u比特位,是否允许内存访问。如果不是,触发一个原来访问类型的access-fault exception。
如果i>0且pte.ppn[i-1:0]不等于0,这是一个不对齐的巨页(superpage);停止且触发一个原来访问类型的access-fault exception。
如果pte.a=0,或如果一个原始内存访问是一个store且pte.d=0,要么触发一个原来访问类型的access-fault exception,或:
如果store to pte违反了PMA或PMP的检查,触发一个原来访问类型的access-fault exception。
以原子方式执行下面的步骤:
比较pte和PTE在a+va.vpn[i]×PTESIZE的值。
如果值相等,设置pte.a为1且如果原始内存访问是store的话也设置pted.d为1。
如果不相等,跳转第2步骤。
虚拟地址转换物理地址成功,物理地址如下:
pa.pgoff = va.pgoff
如果i>0,这是一个巨页(supperpage)转换且pa.ppn[i-1:0] = va.vpn[i-1:0]
pa.ppn[LEVELS-1: i] = pte.ppn[LEVELS-1:i]
该算法中对地址转换数据结构的所有隐式访问都使用宽度PTESIZE执行
例如,对于Sv48的实现,不是分两次读4B,这是非原子访问单个8B PTE,并且具体实现中更新A/D位被视为原子的更新整个PTE,而不仅仅是单独更新A/D位(即使PTE值没有改变)。
第2步中的隐式地址转换结果是保存为只读的、不连续的地址转换缓存中的,但是不与其他hart共享。地址转换缓存可以保存任意数量的条目,包括相同地址和ASID的任意数量的条目。如果条目相关联的ASID和在步骤0中加载的ASID匹配,或者该条目被关联到一个全局映射(global mapping),则地址转换缓存可以满足第2步的读取。为了确保隐式读取观察到对相同内存位置的写入,必须在写入之后执行 SFENCE.VMA 指令以刷新相关的cached translations。
地址转换缓存不能用在步骤7中;A和D位只能在内存中直接更新。只要 satp 处于活动状态,实现也可以在任何时候为任何虚拟地址推测性地执行地址转换算法。 这种推测性的执行具有预先填充地址转换缓存的效果。地址转换算法的推测执行的行为与算法的非推测执行一样,除了它们不能为 PTE 设置脏位,它们不能触发异常,并且它们不能创建地址转换缓存条目,如果从算法的推测执行开始以来,这些条目将对hart 执行的任何 SFENCE.VMA 指令无效。
Sv32虚拟地址到物理地址转换图示:
Sv39
全称: Sv39: Page-Based 39-bit Virtual-Memory System
本节介绍一个简单的用于SXLEN=64的分页虚拟内存系统,它支持39位的虚拟地址空间。Sv39的设计遵循了Sv32的总体方案,本节仅详述两种方案之间的差异。
我们为 RV64 指定了多个虚拟内存系统,以缓解提供大地址空间和最小化地址转换成本之间的紧张关系。 对于许多系统来说,512 GiB 的虚拟地址空间就足够了,所以 Sv39 就足够了。 Sv48 将虚拟地址空间增加到 256 TiB,但增加了专用于页表的物理内存容量、页表遍历的延迟以及存储虚拟地址的硬件结构的大小。 Sv57 进一步增加了虚拟地址空间、页表容量要求和转换延迟。
Addressing and Memory Protection
寻址和内存保护
Sv39实现支持39-bit的虚拟地址空间,分割到4KiB的pages。Sv39的地址分区如图4.19。取指令的地址、load、store有效地址是64 bits,其中63-39比特位的值必须和第38比特位的值相同,否则会出现page-fault exception。27位的VPN通过三级页表转换为44位的PPN,同时12位的page-offset不需要转换。
当在较窄和较宽地址之间进行映射时,RISC-V 将较窄的物理地址零扩展为较宽的大小。 64 位虚拟地址和 Sv39 的 39 位可用地址空间之间的映射不是基于零扩展,而是遵循一个约定,允许操作系统使用一个或几个最高有效位 full-ize (64 位)虚拟地址,用于快速区分用户和supervisor地址区域。
Sv39的page tables包含512个page tables entries(PTEs),每一个PTE是8字节。页表正好是页的大小,并且必须始终与页边界对齐。root页表的物理页码存储在satp寄存器的PPN字段中。
Sv39 PTE的格式如上图4.21。9-0位和Sv32的中的意义相同。第63位保留给Svnapot扩展使用。如果没有实现Svnapot,则保留位63,并且为了向前兼容性,软件必须将其置零,否则将引发页面错误异常。62-61 bit也是被保留来给Svpbmt扩展使用的。如果Svpbmt没有实现,保留62-61位,为了向前兼容性,软件必须将其置零,否则会引发页面错误异常。位60-54被保留以供将来的标准使用,并且,在它们的使用被一些标准扩展定义之前,为了前向兼容性,软件必须将其归零。如果设置了这些位中的任何一个,就会引发页面错误异常。
任何级别的PTE都可能是leaf PTE,因此除了4KiB pages外,Sv39还支持2MiB pages和1GiB pages,每一个必须在虚拟和物理边界上与其大小对齐。如果物理地址没有充分对齐,则会引发页错误异常。
虚拟地址到物理地址的转换算法和Sv32的相同,不同之处在于LEVELS等于3,PTESIZE等于8。
Sv48
全称: Page-Based 48-bit Virtual-Memory System
本节介绍一个简单的用于SXLEN=64的分页虚拟内存系统,它支持48位的虚拟地址空间。Sv48适用于39位虚拟地址空间不足的系统。它紧跟Sv39的设计,只是添加了一个额外的页表级别,因此本章只详细说明了这两种方案之间的差异。
支持Sv48的实现也必须支持Sv39
Addressing and Memory Protection
寻址和内存保护
Sv48实现支持一个48位的虚拟地址空间,分为4个KiB页。Sv48的地址分区如图4.22所示。取指令的地址、load、store有效地址是64 bits,其中63-48比特位的值必须和第47比特位的值相同,否则会出现page-fault exception。36位的VPN通过四级页表转换为44位的PPN,同时12位的page-offset不需要转换。
Sv48的PTE格式如图4.24。63-54位和9-0位的含义和Sv39相同。任何一个级别的PTE都可能是leaf PTE, 因此除了4KiB pages以外,Sv48还支持2MiB、1GiB和512GiB。每一个必须在虚拟和物理边界上与其大小对齐。如果物理地址没有充分对齐,则会引发页错误异常。
虚拟地址到物理地址的转换算法和Sv32的相同,不同之处在于LEVELS等于4,PTESIZE等于8。
Sv57
全称:Page-Based 57-bit Virtual-Memory System
本节介绍一个为RV64系统设计的简单的分页虚拟内存系统,它支持57位的虚拟地址空间。Sv57适用于48位虚拟地址空间不足的系统。它紧跟Sv48的设计,只是添加了一个额外的页表级别,因此本章只详细说明了这两种方案之间的差异。
支持Sv57的实现也必须支持Sv48。
Addressing and Memory Protection
寻址和内存保护
Sv48实现支持一个57位的虚拟地址空间,分为4个KiB页。Sv48的地址分区如图4.25所示。取指令的地址、load、store有效地址是64 bits,其中63-57比特位的值必须和第56比特位的值相同,否则会出现page-fault exception。45位的VPN通过五级页表转换为44位的PPN,同时12位的page-offset不需要转换。
Sv57的PTE格式如图4.27。63-54位和9-0位的含义和Sv39相同。任何一个级别的PTE都可能是leaf PTE, 因此除了4KiB pages以外,Sv48还支持2MiB、1GiB、512GiB和256TiB。每一个必须在虚拟和物理边界上与其大小对齐。如果物理地址没有充分对齐,则会引发页错误异常。
虚拟地址到物理地址的转换算法和Sv32的相同,不同之处在于LEVELS等于5,PTESIZE等于8。