Page 66 - 《软件学报》2025年第9期
P. 66
李传东 等: RISC-V 架构下的懒惰影子页表模型 3977
懒惰影子页表模型的设计目标如下: 1) 在地址翻译效率和页表同步开销之间获得更好的权衡. 传统软硬件解
决方案无法在这二者间达到最佳权衡, 虚拟化技术的性能严重受限于内存虚拟化, 应该基于 RISC-V 架构的全新
特性寻求更佳的权衡; 2) 适配主流 RISC-V 架构规范而无需硬件修改. 当前的 RISC-V 架构基本已经形成较为成
熟和稳定的规范, 懒惰影子页表模型应当完全适配当前的硬件规范而无需任何的硬件修改. 同时, 考虑到一些硬件
受限场景可能并不会实现虚拟化扩展架构 [29] , 该方案应该能够在无虚拟化扩展的场景使用并获得性能提升; 3) 用
户透明. 云服务提供商对于方案的落地考虑最重要的因素就是是否对用户友好, 因此该方案不应该对客户机操作
系统做出任何限制. 懒惰影子页表模型是关于内存虚拟化的优化方案, 因此对于 IO 虚拟化、CPU 虚拟化和中断
虚拟化的实现, 我们不做任何限制和优化, 也并非我们的设计目标.
懒惰影子页表模型为了达到最佳的地址翻译效率, 与传统影子页表模型相同, 在 TLB 缺失后并不使用两级页
表遍历, 而是只启用一个页表基地址寄存器装载影子页表进行地址翻译. 当然, 为了保证虚拟机权限可控, hypervisor
需要拦截虚拟机内部任意对于页表基地址的访问, 任意读写页表基地址的指令都应该被视为敏感指令. 由于直接
使用影子页表, 虚拟机中任何对进程页表的更新都需要被同步到影子页表中.
传统影子页表模型在页表同步期间会导致严重的开销, 而懒惰影子页表模型通过 3 个部分降低页表同步造成
的开销, 如图 4 所示. 首先, 基于用户和操作系统对于页表的访问, 总结出页表同步以及 TLB 刷新之间的关系特征
并且对页表同步时机与 TLB 刷新进行绑定. 然后, 基于页面访问的局部性原理, 懒惰影子页表在页表同步的时候
仅无效化影子页表项, 真正同步操作推迟到具体访问时的页面错误进行. 最后, 基于 RISC-V 的特权级模型, 懒惰
影子页表对 TLB 刷新操作的拦截将使用快速路径, 直接在最高特权级进行页表项无效化.
VU mode
应用程序 应用程序 应用程序
GVA GVA GVA
VS mode vsatp
VM 操作系统
① 直写
② TLB 刷新
④ 页面错误
HS mode LSP
虚拟机监视器
⑤
页面 HPA
同步
M mode
③ 无效化
LSP 快速路径 handler
页表遍历路径 页表修改路径
图 4 基于 RISC-V 架构的懒惰影子页表模型框架图
3.1 页表同步时机绑定
对于传统影子页表的同步机制而言, 通常采用将虚拟机中的进程页表页进行写保护的方式完成同步. 当虚拟
机操作系统每次尝试更新进程页表的时候, 都将触发一次由写权限异常导致的 VM-exit 并在本次异常处理程序中
完成对相应影子页表的修改. 而在修改完成后, 虚拟机还会执行一次 TLB 刷新操作以保证正确性, 该操作会再触
发一次由敏感指令错误导致的 VM-exit.
而我们通过对页表修改行为的分析发现, 任何对于页表项的修改都会有与之绑定的后续操作, 即 TLB 刷新或
者页面错误. 如表 3 所示, 客户机操作系统对于进程页表的修改主要分为两大类, 一类是进行映射修改, 一类是进
行权限位修改. 映射修改操作又分为新增映射 (即 map 操作) 和删除/修改映射 (即 unmap/remap 操作), 权限位修改
操作又分为提升权限 (如从不可写修改为可写) 和降低权限 (如从可写修改为不可写). 若允许影子页表和进程页表
存在不一致, 即虚拟机可以随意修改进程页表, 但是这些修改不被同步到影子页表中, 那么新增映射操作和提升权
限操作实际上并不会导致虚拟机崩溃, 因为这些进程页表项对应的影子页表项总是无效或者具有更低权限的. 当
以高权限进行访问时, 会产生一次权限问题导致的虚拟机退出, hypervisor 可以在这里进行介入. 但是, 如果虚拟机

