必须禁止不可信的代码执行特权指令(如 mret)和访问特权控制状态寄存器(如 mstatus),因为这将允许程序控制系统。这样的限制很容易实现,只要加入一种额外的权 限模式:用户模式(U 模式)。这种模式拒绝使用这些功能,并在尝试执行 M 模式指令或 访问 CSR 的时候产生非法指令异常。其它时候,U 模式和 M 模式的表现十分相似。通过 将 mstatus.MPP 设置为 U(编码为 0),然后执行 mret 指令,软件可以 从 M 模式进入 U 模式。如果在 U 模式下发生异常,则把控制移交给 M 模式。
这些不可信的代码还必须被限制只能访问自己那部分内存。实现了 M 和 U 模式的处 理器具有一个叫做物理内存保护(PMP,Physical Memory Protection)的功能,允许 M 模 式指定 U 模式可以访问的内存地址。PMP 包括几个地址寄存器(通常为 8 到 16 个)和相 应的配置寄存器。这些配置寄存器可以授予或拒绝读、写和执行权限。当处于 U 模式的处 理器尝试取指或执行 load 或 store 操作时,将地址和所有的 PMP 地址寄存器比较。如果地 址大于等于 PMP 地址 i,但小于 PMP 地址 i+1,则 PMP i+1 的配置寄存器决定该访问是否 可以继续,如果不能将会引发访问异常。
更复杂的 RISC-V 处理器用和几乎所有通用架构相同的方式处理这些问题:使用基于 页面的虚拟内存。这个功能构成了*<u>监管者模式</u>*(S 模式)的核心,这是一种可选的权限模 式,旨在支持现代类 Unix 操作系统,如 Linux,FreeBSD 和 Windows。S 模式比 U 模式权 限更高,但比 M 模式低。与 U 模式一样,S 模式下运行的软件不能使用 M 模式的 CSR 和 指令,并且受到 PMP 的限制。
默认情况下,发生所有异常(不论在什么权限模式下)的时候,控制权都会被移交到 M 模式的异常处理程序。但是 Unix 系统中的大多数例外都应该进行 S 模式下的系统调 用。M 模式的异常处理程序可以将异常重新导向 S 模式,但这些额外的操作会减慢大多数 异常的处理速度。因此,RISC-V 提供了一种*<u>异常委托机制</u>*。通过该机制可以选择性地将中 断和同步异常交给 S 模式处理,而完全绕过 M 模式。
mideleg(Machine Interrupt Delegation,机器中断委托)CSR 控制将哪些中断委托给 S 模式。
委托给 S 模式的任何中断都可以被 S 模式的软件屏蔽。sie(Supervisor Interrupt Enable,监管者中断使能)和 sip(Supervisor Interrupt Pending,监管者中断待处理)CSR 是 S 模式的控制状态寄存器,他们是 mie 和 mip 的子集。它们有着和 M 模式下相同的布 局,但在 sie 和 sip 中只有与由 mideleg 委托的中断对应的位才能读写。那些没有被委派 的中断对应的位始终为零。
S 模式有几个异常处理 CSR:sepc、stvec、scause、sscratch、stval 和 sstatus,它 们执行与 10.2 中描述的 M 模式 CSR 相同的功能。
**补充说明**:为什么不无条件地将中 断委托给 S 模式? 一 个原因是虚拟化:如果 M 模式想要虚拟一个 S 模式的设备,其中断应 该转到 M 模式,而不是 S 模式。