RISC-V 中的地址指定

Address designation in RISC-V

我是 运行 QEMU 中的模拟 RV64GC 核心,正在努力更好地理解 RISC-V 中的虚拟内存子系统和地址转换过程。我的模拟系统使用 OpenSBI、Linux Kernal v5.5 和最小的 rootfs 运行。

在 QEMU 调试跟踪中,我看到有时(最常见的是 ecalls)控制被传递给 SBI,地址从偏移量为 0xffffffe000000000 的内核(虚拟?)地址变为看起来像真实的物理地址, RAM 中的地址。例如,

...

0xffffffe00003a192: 00000073 ecall

...

IN: sbi_ecall_0_1_handler

0x0000000080004844: 00093603 ld a2,0(s2)

0x0000000080004848: 4785 addi a5,zero,1

0x000000008000484a: 00a797b3 sll a5,a5,a0

...

在 RISC-V 特权规范版本 1.11 的第 4.1.12 节中,satp CSR(控制和状态寄存器)被定义为具有确定地址转换指定的 MODE 字段。 MODE 为 0 意味着转换是裸露的(地址被认为是物理地址),MODE 为 8 或 9 分别需要基于页面的 Sv39 或 Sv48 虚拟寻址,并且保留任何其他 MODE 值。

现在,RISC-V 特权和非特权规范似乎都没有提到何时可以更改 satp(csrrw 除外),所以这让我想到以下问题:

当控制权交给 SBI 时(与上面的 ecall 一样),satp MODE 是否变为 0?如果是,这是否意味着应该在 u/s/mret 指令上重置 satp 模式?是否有其他情况(除了 csrrw)satp 应该改变?

如果不是,是否有一些其他机制可以将地址解释并指定为物理地址?或者地址(上面的 0x80XXXXXX 地址)是否被认为是虚拟的,应该经过通常的虚拟地址转换过程(如 RISC-V 特权规范第 4.3.2 节所述)?如果是这种情况,何时为此创建页面 table 条目?

RISC-V 的内存模型按以下方式工作:

M 模式有自己的内存保护系统,在特权规范第 3.6 节中描述,称为 PMP(物理内存保护)。这是为了对较低特权级别以及 M 模式本身(如果使用锁定位)施加内存保护。 M模式下没有虚拟内存系统

现在在 S 模式下,它有基于页面的虚拟内存系统,S 模式可以使用它来设置虚拟地址到物理地址的映射,并对 S 模式本身和 U 模式施加内存限制。

所以每个权限级别都可以控制自己的资源和低于它的资源,但不能控制高于它的权限级别的资源。这就是事情的运作方式。

M模式可以控制M、S、U模式可访问的内存,S模式可以控制S、U模式的内存视图(虚拟内存)和可访问性,M模式不行。所以当移动到 M 模式时,satp 模式甚至都不会改变。由于它指向的映射甚至永远不适用于 M 模式。它有内存保护单元。

如果较低的权限级别可以对较高的权限级别施加内存限制,这将是一个巨大的安全漏洞。