https://tinylab.org/riscv-kvm-virt-mode-switch/
https://tinylab.org/riscv-kvm-virt-trap/
特權模式
指令集中約定用虛擬化模式 V (virtualization mode) 來標記當前是否是在 Guest 系統中運行。V=1 表示當前確實運行在 Guest 系統中,V=0 則表示不運行在 Guest 中。
V | 虛擬化(H-Level Arch.) | V | 虛擬化特例 | 名義特權級 | 運行的程序 |
---|---|---|---|---|---|
1 | VU-mode | 0 | U-mode | U-0 | Guest OS的應用程序 |
1 | VS-mode | S-1 | Guest OS | ||
0 | HS-mode | 0 | HS-mode | S-1 | 宿主OS / Hypervisor |
0 | M-mode | 0 | M-mode | M-3 | opensbi |
在上述表格中,虛擬化特例指 hart 所指示的應用程序以 U-mode 直接運行在一個運行于 HS-mode 的 OS 上。
名義特權級(Nominal Privilege)是在 S-mode 基礎上的特權級約定,分為 U, S, M 三級,分別用 0,1,3 表示,各類指令集模擬器均以此標準實現。
相關CSR
mstatus寄存器
- MIE、SIE:當前中斷使能
- SPIE、MPIE:(previous) 記錄trap之前的中斷使能
- SPP、MPP:記錄trap之前的特權級別
- TSR(Trap SRet):攔截supervisor異常返回指令sret。TSR=1,在S-mode下支持sret會導致illegal instruction exception。TSR=0,則允許S-mode下執行sret。
hstatus寄存器
- SPV(supervisor previous Virtualization):sstatus.SPP 在 trap 時會被設置為 trap 對應的名義特權級,此時 hstatus.SPV 就會被設置為 trap 時的 V 值;當 V=0 時執行 sret 指令,SPV 置為 V。
- SPVP (Supervisor Previous Virtual Privilege):V=1 時,行為與 sstatus.SPP 相同,即置為 trap 時的名義特權級;V=0 時,保持不變。
- GVA (Guest Virtual Address):trap 到 HS-mode 時寫入:對于寫虛擬地址到 stval 的寄存器的 trap(breakpoint, address misaligned, access fault, page fault, or guest-page fault),hstatus.GVA 置 1,對于其他 trap 置 0。
sstatus
sstatus 是 mstatus 的一個子集。
- SPP:用于標識 trap 進入 S-mode 之前 hart 所在的特權級:來自 U-mode 則置 0,否則為 1。
- trap 處理過程中 sstatus 的行為
trap to S-mode: SPIE=SIE, SIE=0
sret: SIE=SPIE, SPIE=1
vsstatus
和sstauts一樣。
V=1 時,vsstatus 用于替代 sstatus,所以通常針對 sstatus 的操作會替換為 vsstatus。
中斷處理流程
中斷委托
從上圖可知,正常情況下 trap 都會導致 hart 的控制轉移至 M-mode,處理之后通過 mret 指令返回到原來的模式。
特殊情況下 trap 會經由 mdeleg 或 mideleg 委派從 HS-mode 或 VS-mode 轉移至 HS-mode,或再經由 hedeleg 或 hideleg 委派從 VU-mode 轉移至 VS-mode。
被委派至 HS-mode 和 VS-mode 的 trap 在處理完畢后,將通過 sret 指令返回至 trap 之前的模式。