0%

riscv 虚拟化中断相关

Hypervisor Status Register (hstatus)

When VTSR=1, an attempt in VS-mode to execute SRET raises a virtual instruction exception.
When VTW=1 (and assuming mstatus.TW=0), an attempt in VS-mode to execute WFI raises a virtual instruction exception if the WFI does not complete within an implementation-specific, bounded time limit.
When VTVM=1, an attempt in VS-mode to execute SFENCE.VMA or to access CSR satp raises a virtual instruction exception.

The VGEIN (Virtual Guest External Interrupt Number) field selects a guest external interrupt source for VS-level external interrupts. VGEIN is a WLRL field that must be able to hold values between zero and the maximum guest external interrupt number (known as GEILEN), inclusive.
When VGEIN=0, no guest external interrupt source is selected for VS-level external interrupts. GEILEN may be zero, in which case VGEIN may be hardwired to zero.
Guest external interrupts are explained in Section 1.2.4, and the use of VGEIN is covered further in Section 1.2.3.

Field HU (Hypervisor User mode) controls whether the virtual-machine load/store instructions, HLV, HLVX, and HSV, can be used also in U-mode. When HU=1, these instructions can be executed in U-mode the same as in HS-mode. When HU=0, all hypervisor instructions cause an illegal instruction trap in U-mode.

hip & hie

Registers hip and hie are HSXLEN-bit read/write registers that supplement HS-level’s sip and sie respectively. The hip register indicates pending VS-level and hypervisor-specific interrupts, while hie contains enable bits for the same interrupts. As with sip and sie, an interrupt i will be taken in HS-mode if bit i is set in both hip and hie, and if supervisor-level interrupts are globally enabled.

Bits hip.SGEIP and hie.SGEIE are the interrupt-pending and interrupt-enable bits for guest external interrupts at supervisor level (HS-level).
SGEIP is read-only in hip, and is 1 if and only if the bitwise logical-AND of CSRs hgeip and hgeie is nonzero in any bit.

Bits hip.VSEIP and hie.VSEIE are the interrupt-pending and interrupt-enable bits for VS-level external interrupts. VSEIP is read-only in hip, and is the logical-OR of these interrupt sources:

  • bit VSEIP of hvip;
  • bit of hgeip selected by hstatus.VGEIN
  • any other platform-specific external interrupt signal directed to VS-level.

Bits hip.VSTIP and hie.VSTIE are the interrupt-pending and interrupt-enable bits for VS-level timer interrupts. VSTIP is read-only in hip, and is the logical-OR of:

  • hvip.VSTIP
  • any other platform-specific timer interrupt signal directed to VS-level.

Bits hip.VSSIP and hie.VSSIE are the interrupt-pending and interrupt-enable bits for VS-level software interrupts. VSSIP in hip is an alias (writable) of the same bit in hvip.

Hypervisor Guest External Interrupt Registers (hgeip and hgeie)

hgeip indicates pending guest external interrupts for this hart.
hgeie contains enable bits for the guest external interrupts at this hart.
Guest external interrupts represent interrupts directed to individual virtual machines at VS-level.
只有在设备直通场景下使用

interrupts from the device are intended for a specific virtual machine. Each bit of hgeip summarizes all pending interrupts directed to one virtual hart, as collected and reported by an interrupt controller. To distinguish specific pending interrupts from multiple devices, software must query the interrupt controller.

Support for guest external interrupts requires an interrupt controller that can collect virtual-machine-directed interrupts separately from other interrupts.

中断控制器需要收集virtual guest external interrupt, 和 物理cpu的external interrupt 区分开, guest 只能接收virtual external guest interrupt

The number of bits implemented in hgeip and hgeie for guest external interrupts is GEILEN
bits GEILEN:1 shall be writable in hgeie, and all other bit positions shall be hardwired to zeros in both hgeip and hgeie.

Guest external interrupt number i at one physical hart is typically expected not to be the same as guest external interrupt i at any other hart.
For any one physical hart, the maximum number of virtual harts that may directly receive guest external interrupts is limited by GEILEN.

A hypervisor is always free to emulate devices for any number of virtual harts without being limited by GEILEN. Only direct pass-through (direct assignment) of interrupts is affected by the GEILEN limit, and the limit is on the number of virtual harts receiving such interrupts, not the number of distinct interrupts received. The number of distinct interrupts a single virtual hart may receive is determined by the interrupt controller.

The enable bits in hgeie do not affect the VS-level external interrupt signal selected from hgeip by hstatus.VGEIN.

vsip & vsie

hideleg not zero(bit 10/6/2 不为0时)

  • vsip.SEIP and vsie.SEIE are aliases of hip.VSEIP and hie.VSEIE.
  • vsip.STIP and vsie.STIE are aliases of hip.VSTIP and hie.VSTIE.
  • vsip.SSIP and vsie.SSIE are aliases of hip.VSSIP and hie.VSSIE.

小结

hideleg 开启时(bit 10/6/2 不为0时)

  • vsip.SEIP = hip.VSEIP vsip.STIP = hip.VSTIP vsip.SSIP = hip.VSSIP
    • VSEIP is read-only in hip, and is the logical-OR of these interrupt sources:
      • bit VSEIP of hvip;
      • bit of hgeip selected by hstatus.VGEIN
      • any other platform-specific external interrupt signal directed to VS-level.
    • VSTIP is read-only in hip, and is the logical-OR of:
      • hvip.VSTIP
      • any other platform-specific timer interrupt signal directed to VS-level.
    • VSSIP in hip is an alias (writable) of the same bit in hvip.
      • 即 vsip.SSIP = hip.VSSIP = hvip.VSSIP
  • vsie.SEIE = hie.VSEIE vsie.STIE = hie.VSTIE vsie.SSIE = hie.SSIE

真正影响guest os的是vsip , guest os 运行时处于V=1 mode, vsip被替换为sip,

  • vsip software 中断来自于hvip (来自于HS hypervisor), 或者guest os 自己.
  • vsip timer 中断来自于hvip (来自于 HS hypervisor), 或guest os 自己, 或 platform-specific timer interrupt signal directed to VS-level
  • vsip guest external 中断来自于hvip (来自于HS hypervisor), 或hstatus.VGEIN -> hgeip 或 any other platform-specific external interrupt signal directed to VS-level

下面这两句应该怎么理解?

  • Bits hip.SGEIP and hie.SGEIE are the interrupt-pending and interrupt-enable bits for guest external interrupts at supervisor level (HS-level).
  • Bits hip.VSEIP and hie.VSEIE are the interrupt-pending and interrupt-enable bits for VS-level external interrupts.

直译:
SGEIP 和 SGEIE 是给HS 用的, 重点看 SGEIP, 这个是hgeip & hgeie and的结果, 代表的有guest external 中断待处理.
hip.VSEIP 和 hie.VSEIE 是给VS 用的, 这个好理解, 这两个直接反应到vsip vsie的相应bit上了.

结合这句:
if GEILEN is nonzero, bits GEILEN:1 shall be writable in hgeie
Only direct pass-through (direct assignment) of interrupts is affected by the GEILEN limit, and the limit is on the number of virtual harts receiving such interrupts, not the number of distinct interrupts received

背景:
不同的vcpu可以运行不同guest os.
一个物理cpu 有三套寄存器

  • v 开头的 vsip vsie 等
  • h 开头的 hvip hip hie hgeie hgeip 等
  • s 开头的 sip sie 等
    当V=0 => V=1 时, v开头的寄存器会替换成 s 开头的寄存器, 此时变成vcpu的执行环境
    V=1 时, 只能访问 s 开头的寄存器.

大概猜测, 在设备直通场景时, 0 < hstatus.VGEIN <= GEILEN(物理cpu上托管的vcpu的数量),

需要HS vmm 对 hgeie hstatus操作, 对应物理cpu上托管的vcpu
如当前物理cpu上托管了8个vcpu, 正在运行的是第2个vcpu

  • 对 hstatus.VGEIN 设置为2
  • 对 hgeie 的前8个bit 置1, 表示物理cpu 管了8个ready vcpu 的中断状态, 这8个vcpu都要处理guest external interrupt.

在前面前提下, 硬件需要将hip.VSEIP 与 hgeip的状态区分.
前面hip.VSEIP 的来源处说的比较模糊: “bit of hgeip selected by hstatus.VGEIN

不太好理解, 大概猜测:

在设备直通场景(设置了hstatus.VGEIN时), 中断控制器需要判断给哪个vcpu, 导致的直接结果就是要设置hgeip 的哪个bit, 同时硬件应该将 hip.VSEIP 置为hgeip 与 hstatus.VGEIN 逻辑与 的结果. 而hip.SGEIP 置为 hgeip & hgeie 逻辑与的结果.

假如中断控制器要发给第三个vcpu, 就需要将hgeip 的第三个bit 置1

  • 情景1 : 假设物理cpu的状态 V=1 mode 正在运行第二个vcpu, hstatus.VGEIN = 2:

    此时因为正在运行的是第二个vcpu, hstatus.VGEIN=2, 则hip.VSEIP = 0, 而 hip.SGEIP 为 1, 因为vsip.SEIP->sip.SEIP = hip.VSEIP, 此时vsip.SEIP 没有置位(此时假设只有外部中断, SSIP STIP 都是0), 此时硬件根据vsip penging为无信号, 而hip.SGEIP 有信号, 不能将中断委托给vcpu, 而应将中断给到 host os HS-mode的vmm.

    从vcpu陷入到hypervisor vmm 后, vmm 需要check hip.SGEIP & hie SGEIE(或hip&hie), 有待处理的虚拟外部中断, 进而查hgeip, 查到是第三个vcpu的, 则切换到第三个vcpu 运行, 切换前将hstatus.VGEIN 设置为3. 此时vsip.SEIP = hip.VSEIP 会被置1(hgeip 逻辑与 hstatus.VGEIN) , 第三个vcpu 陷入V=1 mode, 处理虚拟外部中断. 如guest os kernel 将sie.SEIE 置过位, 则guest os 会处理external 中断(10号guest external中断会转换成9 号external 中断), guest os 需要查询中断控制器, 判断外部中断是谁的, 该由谁的中断处理函数处理. 处理完后将中断控制器的pending 清0(该操作导致中断控制器把hgeip清0), 返回到 hypervisor vmm 后, vsip.SEIP = hip.VSEIP 也会因hgeip 而清0.

  • 情景2: 假设物理cpu的状态 V=0 mode, 处于host下

    中断由host os接收
    hypervisor vmm 需要check hip.SGEIP & hie SGEIE (或hip&hie), 有待处理的虚拟外部中断, 进而查hgeip, 查到是第三个vcpu的, 则切换到第三个vcpu 运行, 切换前将hstatus.VGEIN 设置为3. 此时vsip.SEIP = hip.VSEIP 会被置1(hgeip 逻辑与 hstatus.VGEIN) , 第三个vcpu 陷入V=1 mode, 处理虚拟外部中断. 如guest os kernel 将sie.SEIE 置过位, 则guest os 会处理external 中断(10号guest external中断会转换成9 号external 中断), guest os 需要查询中断控制器, 判断外部中断是谁的, 该由谁的中断处理函数处理. 处理完后将中断控制器的pending 清0(该操作导致中断控制器把hgeip清0), 返回到 hypervisor vmm 后, vsip.SEIP = hip.VSEIP 也会因hgeip 而清0.

  • 情景3: 假设物理cpu的状态 V=1 mode 正在运行第三个vcpu, hstatus.VGEIN = 3:
    hgeip 逻辑与 hstatus.VGEIN 不为0, hip.VSEIP 置1.
    因为vsip.SEIP->sip.SEIP = hip.VSEIP, 此时vsip.SEIP 置位, 此时硬件根据vsip penging有信号, hip.SGEIP 有信号, 应将中断给到 vcpu guest os.
    vcpu处理虚拟外部中断. 如guest os kernel 将sie.SEIE 置过位, 则guest os 会处理external 中断(10号guest external中断会转换成9 号external 中断), guest os 需要查询中断控制器, 判断外部中断是谁的, 该由谁的中断处理函数处理. 处理完后将中断控制器的pending 清0(该操作导致中断控制器把hgeip清0), 返回到 hypervisor vmm 后, vsip.SEIP = hip.VSEIP 也会因hgeip 而清0.

备注

hgeip read-only csr, 由硬件操作
hgeie rw csr, 由软件操作
hip.SGEIP read-only bit, 由硬件操作
hip.VSEIP read-only bit, 由硬件操作
sip.SEIP read-only bit, 由硬件操作, typically through a platform-specific interrupt controller.

riscv 直通场景 AIA IMSIC

riscv 直通场景

IMSIC

hvictl

Hypervisor Virtual Interrupt Control

  • 触发VS major 中断(hvien 和 hvip 不支持的)
  • 支持配置VS-mode 中断优先级( hviprio1/hviprio2 之外的)
  • 模拟一个外部中断控制器, 没有使用IMSIC的 guest interrupt file. 同时支持为外部中断和virtual hart的major interrupts 配置中断优先级

hvien

guest 不需要配置major 中断的优先级, 除了硬件自定义实现的那些.
hvien 保留了低12位(ro 符合SPEC规范的), hvien 和 hvip 配合来表明注入对应的中断, 除了SPEC 规范的低12位外, 低12位由SPEC 定义, 如VSEIP/VSTIP/VSSIP. 而13:63 位用来实现硬件自定义实现的中断.

hideleg 开启后, vsip 的位等同于 sip的位

  • hideleg 的某 bit位为0时, 而hvien的对应bit位为1, 此时vsip 的该bit位等同于hvip的该bit位
  • hideleg 的某 bit位为0时, 而hvien的对应bit位为0, 此时vsip 的该bit位是ro的,