New Chat
Ctrl
K
Kimi+
Chat History

RISC-V 虚拟机CPU信息获取与安全风险

详细介绍一下“Hypervisor Virtual-Machine Load and Store Instructions”及其应用场景
Kimi tried searching the internet but found nothing.
下面按“它是什么 → 为什么需要 → 硬件做了哪些改动 → 软件怎么用 → 典型场景”五个层次,把 RISC-V 的 Hypervisor Virtual-Machine Load/Store Instructions(HLV/HLVX/HLSV) 一次讲透。

一、它是什么
  1. 指令格式(RV64 为例,名称统一以 hg 前缀助记)
    • hlv.b/h/w/d rd, rs1 // 从 Guest 物理地址读 1/2/4/8 字节
    • hlvx.hu/hu/hu/wu rd, rs1 // 与 hlv 相同,但走 直写不缓存 属性(cache-bypass)
    • hlsv.b/h/w/d rs1, rs2 // 向 Guest 物理地址写 1/2/4/8 字节
  2. 执行特权
    必须在 HS-mode(Hypervisor-ext.) 下执行;若在 S-mode 或 U-mode 直接触发 Illegal Instruction。
    地址计算:effective address = rs1(虚址或实址,由软件决定),硬件再把该地址 当作 GPA(Guest Physical Address) 走第二级地址翻译。

二、为什么需要单独搞一套“虚拟机加载/存储”
传统陷阱 + 影子页表也能干活,但存在三大痛点:
  1. 每次 Guest 访问 I/O 页都要 VM-Exit → 路径长、抖动大。
  2. 影子页表同步复杂,多 vCPU 要 TLB shoot-down。
  3. 无法安全地让 Hypervisor 直接读/写 Guest 内存 去做:
    • 网络/磁盘后端(vhost、virtio 后端在 host 里)
    • 在线 GC、快照、内存取证、热迁移迭代拷贝
    • 气球驱动(balloon)把 Guest 页换出到 hypervisor 文件
因此 RISC-V 在 1.0 版 Hypervisor Extension 里引入“让 Hypervisor 直接用 普通 Load/Store 访问 Guest 物理空间”的机制,这就是 HLV/HLVX/HLSV。

三、硬件做了什么改动
  1. 新增指令编码
    全部占用 custom-0/custom-1 空间,保证与老用户态/内核态二进制兼容。
  2. 地址翻译流水线
    当解码到 HLV/HLSV,地址翻译单元 强制进入 “G-stage only” 模式:
    GPA → (G-stage walk) → SPA(System Physical Address)
    不再经过 VS-stage,所以 不会触发 Guest 页故障,只有 Hypervisor 页故障(缺 SPA 映射或权限不足)。
  3. 页表项属性继承
    • HLVX 强制 直写、非缓存,方便驱动 DMA 缓冲区和 MMIO 寄存器。
    • HLV/HLSV 走默认属性,可缓存,可预取。
  4. 异常模型
    访问失败不抛 Guest Exception,而是 进入 HS-mode,scause=Load/Store Guest Page Fault,stval 给出出错的 GPA。
    这样 hypervisor 可以:
    • 动态给该 GPA 建页表;
    • 或者返回错误码给 Guest;
    • 或者把这一页本地锁定后重试。

四、软件怎么用(伪代码)
Copy
// 把 Guest 的 GPA gpa 处 4 字节读出来
static inline uint32_t hg_read_u32(uint64_t gpa) {
    uint64_t val;
    asm volatile("hlv.w %0, (%1)" : "=r"(val) : "r"(gpa));
    return val;
}

// 直写方式读网卡环形缓冲区描述符
desc = hg_read_u32(ring_base + idx * 16);

// 向 Guest 的 GPA 写 8 字节
static inline void hg_write_u64(uint64_t gpa, uint64_t v) {
    asm volatile("hlsv.d %0, (%1)" :: "r"(v), "r"(gpa));
}

// 批量拷贝:hypervisor 里做 memcpy(dst_spa, src_gpa, len)
for (; len; len -= 8, src_gpa += 8, dst_spa += 8) {
    uint64_t tmp = hg_read_u64(src_gpa);
    *(uint64_t *)dst_spa = tmp;
}
无需 mmap、无需 ioctl(KVM_TRANSLATE),一条指令就完成“读 Guest 物理页”。

五、典型应用场景
  1. vhost / vDPA backend
    virtio 环、描述符、packet payload 全部在 Guest 内存。
    后端驱动在 Host 里用 HLV/HLSV 直接取描述符、DMA 数据,零系统调用、零额外拷贝。
  2. 热迁移(live migration)
    迭代预拷贝阶段,source hypervisor 用 HLV 把 Guest 每一页读出来,计算差分 CRC 后发送到 target。
    因为不走 Guest 内核,Guest 完全感知不到被读,停机时间 < 30 ms。
  3. 气球驱动(virtio-balloon)
    Guest 通过 virtio 告诉 hypervisor “这 256 个 GPA 页我可以释放”。
    hypervisor 收到后用 HLSV 把这些页清零或换出到磁盘,无需 Guest 陷入。
  4. 在线快照 / 内存取证
    取证工具在 HS-mode 里扫描 Guest 的页表,遇到可疑 GPA 直接 HLV 读出内容,不会污染 Guest 的 Access/Dirty 位。
  5. 设备直通模拟
    某些只支持 GPA 的 DMA 引擎,hypervisor 先 HLVX 读出门铃寄存器,改完后再 HLSV 写回,全程 bypass cache,保证 MMIO 时序正确。

一句话总结
HLV/HLVX/HLSV 把 “Hypervisor 要像普通 Load/Store 那样直接访问 Guest 物理内存” 这一需求固化到指令集层面:
  • 硬件负责把 GPA 翻译成 SPA,异常只上报给 Hypervisor;
  • 软件拿到“一条指令就能跨世界读/写”的能力,从而把 virtio-backend、热迁移、气球、快照等高频路径做得又快又干净。
让 Hypervisor 直接访问 Guest 物理内存存在安全性问题吗
Hypervisor 直接访问 Guest 物理内存 安全性问题
是的,让 Hypervisor 直接访问 Guest 物理内存(GPA→HPA 一对一映射后读写)确实存在不可忽视的安全风险。下面把主要威胁、攻击面、已出现的真实漏洞和业界现有/应有的缓解措施一次性梳理清楚。

一、直接访问为何“危险”
  1. 打破了“Guest 内存只能由 Guest 自己 touching”这一根本隔离假设。
  2. Hypervisor 一旦能被攻陷(或本身有 bug),就可以:
    • 任意篡改 Guest 内核代码、敏感数据 → 完整性丧失;
    • 把机密数据拷走 → 机密性丧失;
    • 把同一 HPA 映射给多 Guest → 跨 VM 嗅探/注入。
  3. 即使 Hypervisor “可信”,Guest 也不知情——Access/Dirty 位不会置起,原有页表权限被完全绕过,给 Guest 侧的内核完整性监控、防篡改方案造成盲区。

二、真实攻击场景与已披露漏洞
  1. 内存重映射(aliasing)攻击
    恶意 Hypervisor 先把 Guest A 的 GPA 0x1000 映射到 P1,等 A 写完敏感数据,再把同一 GPA 改映射到 P2;A 再次读取时数据“凭空消失”,可导致安全检查被跳过、加密密钥被复用等逻辑错误
    。
  2. DMA 恶意重定向
    如果直通设备由 Guest 控制,而 Hypervisor 又能随意改 GPA→HPA 映射,Guest 可把 DMA 指向 Host 内核或其他 VM 的物理页——相当于“硬件级”越界读写
    。
  3. 拒绝服务/主机崩溃
    CVE-2019-3887:KVM 嵌套虚拟化代码对 x2APIC MSR 检查不充分,Guest 通过触发特定 MSR 序列即可让 Host 内核空指针解引用 → 宿主机崩溃,属于“Guest → Host”的拒绝服务逃逸
    。
  4. 重叠页(overlapping page)缺陷
    Hyper-V 的 VP-Assist Page 既算 Hypervisor 控制结构,又算 Guest GPA 范围。Guest 可故意把未初始化页面对齐到该 GPA,导致 Host 把随机数据当成控制结构,最终堆溢出或信息泄露(CVE-2020-0890)
    。

三、风险等级评估
Table
Copy
风险点危害出现条件是否可远程利用
任意读写 Guest 内存完整/机密性全失Hypervisor 被入侵或有 bug是(先攻破 Host)
重映射攻击逻辑绕过、数据损坏恶意/被诱骗的云平台管理员否(需控制 Host)
DMA 越界跨 VM 数据泄露直通设备 + 恶意 Guest是(Guest 侧发起)
拒绝服务Host 崩溃嵌套虚拟化配置下是(Guest 侧发起)

四、现有/推荐的缓解措施
  1. 硬件级
    • AMD SEV/SEV-SNP:引入 Reverse Map Table (RMP),每个 4 kB 页记录“唯一属主”。Hypervisor 再改映射前必须 RMPUPDATE + PVALIDATE;若该页已属另一 VM,CPU 会抛 #PF,直接堵死 aliasing
      。
    • Arm Realm Management Extension / SMMUv3:Per-VM 的 PAS(Physical Address Space)ID,Hypervisor 换映射后硬件会查表,非属主访问立即终止。
    • RISC-V 1.0 IOMMU 扩展:默认 禁止任意 GPA→HPA 修改,要求 Hypervisor 先对页做 “valid” 标记并绑定到特定设备/VM,才允许 DMA
      。
  2. Hypervisor 软件级
    • 最小化 TCB:把后端驱动、vhost、设备模型放到 非特权服务 VM(QEMU 隔离、seL4、pKVM),即使被攻破也无法直接改 GPA→HPA 映射。
    • 写时复制 & 引用计数:对每一张 Guest 页表维护 mapcount,>1 时触发 COW,防止静默 aliasing。
    • 运行时完整性监控:在 Host 内核里插桩 kvm_page_track,任何 GPA→HPA 变动都先走校验函数;Cloud/TEE 厂商可把策略下发到 BPF,禁止高危范围(0-1 M、内核代码段)被重新映射。
    • IOMMU 永不旁路:即使直通设备,也强制 DMA Remapping;禁止 BIOS 里关闭 IOMMU 的“兼容模式”
      。
  3. 云厂商运维流程
    • 宿主机内核/Hypervisor 走 签名启动(secure boot)+ 可信度量(TPM/RTMR),防止管理员植入 rootkit 再改映射。
    • 最小权限运营:只有 sealed 自动化组件 能调用 KVM_SET_USER_MEMORY_REGION;人工运维账号无法直接改 Guest 内存映射。

五、结论
“Hypervisor 直接访问 Guest 物理内存”在性能上不可或缺,但在安全上属于 高权限、高敏感 操作:
  • 一旦映射关系可被恶意/被攻破的 Hypervisor 随意改动,就会出现 跨 VM 越权、数据篡改、主机崩溃 等经典虚拟机逃逸场景;
  • 业界已给出 硬件 (RMP/PAS/IOMMU) + 软件 (TCB 缩小、引用计数、完整性监控) 的多层缓解方案;
  • 对公有云、机密计算场景,建议 默认开启 SEV/SEV-SNP 或等效扩展,并配合 IOMMU 永远在线 + 映射变更审计,才能把风险降到可接受水平。