diff --git a/articles/20221120-riscv-kvm-int-impl-2.md b/articles/20221120-riscv-kvm-int-impl-2.md
new file mode 100644
index 0000000000000000000000000000000000000000..c42e4558b6cc3fa52bb021a56292ea95a46bb3a9
--- /dev/null
+++ b/articles/20221120-riscv-kvm-int-impl-2.md
@@ -0,0 +1,605 @@
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1 - [tounix]
+> Author:    XiakaiPan <13212017962@163.com>
+> Date:      20221201
+> Revisor:   Walimis 
+> Project:   [RISC-V Linux 内核剖析](https://gitee.com/tinylab/riscv-linux)
+> Proposal:  [RISC-V 虚拟化技术调研与分析](https://gitee.com/tinylab/riscv-linux/issues/I5E4VB)
+> Sponsor:   PLCT Lab, ISCAS
+
+# RISC-V 中断处理的实现(二)
+
+## 前言
+
+本文对于 kvmtool 以及 KVM 中的中断注入与处理、MMIO 设备注册与使用结合代码进行了分析和解读,主要以流程图的方式呈现上述过程中的代码实现。
+
+## 代码版本
+
+| Software          | Version                                  |
+|-------------------|------------------------------------------|
+| [Linux Kernel][1] | 6.0-rc6                                  |
+| [kvmtool][6]      | e17d182ad3f797f01947fc234d95c96c050c534b |
+
+## KVM 异常处理
+
+### RISC-V Trap 类型、编码及其关系
+
+在 RISC-V 中,CSR `mcause` / `scause` / `vscause` 用于记录具体的 Trap 编码,Interrupt 和 Exception 的区分是通过 CSR 的标志位实现的。最高位为 1 时表示当前 Trap 为 Interrupt,为 0 时则是 Exception。
+
+RISC-V 中的中断分为三类:软件中断、计时器中断和外部中断,来自不同特权级的各类中断具有各自的编码。Linux 中对这些中断编码如下:
+
+```cpp
+// arch/riscv/include/asm/csr.h: line 66
+/* Exception cause high bit - is an interrupt if set */
+#define CAUSE_IRQ_FLAG		(_AC(1, UL) << (__riscv_xlen - 1))
+
+/* Interrupt causes (minus the high bit) */
+#define IRQ_S_SOFT		1
+#define IRQ_VS_SOFT		2
+#define IRQ_M_SOFT		3
+#define IRQ_S_TIMER		5
+#define IRQ_VS_TIMER		6
+#define IRQ_M_TIMER		7
+#define IRQ_S_EXT		9
+#define IRQ_VS_EXT		10
+#define IRQ_M_EXT		11
+#define IRQ_PMU_OVF		13
+
+/* Exception causes */
+#define EXC_INST_MISALIGNED	0
+#define EXC_INST_ACCESS		1
+#define EXC_INST_ILLEGAL	2
+#define EXC_BREAKPOINT		3
+#define EXC_LOAD_ACCESS		5
+#define EXC_STORE_ACCESS	7
+#define EXC_SYSCALL		8
+#define EXC_HYPERVISOR_SYSCALL	9
+#define EXC_SUPERVISOR_SYSCALL	10
+#define EXC_INST_PAGE_FAULT	12
+#define EXC_LOAD_PAGE_FAULT	13
+#define EXC_STORE_PAGE_FAULT	15
+#define EXC_INST_GUEST_PAGE_FAULT	20
+#define EXC_LOAD_GUEST_PAGE_FAULT	21
+#define EXC_VIRTUAL_INST_FAULT		22
+#define EXC_STORE_GUEST_PAGE_FAULT	23
+```
+
+中断标记为 `IRQ`(Interrupt ReQuest),异常标记为 `EXC`(EXCeption)。
+
+### KVM 异常处理
+
+KVM 内部处理的是来自于 Hypervisor 以及 Guest 的异常,具体来说包括三类(分别对应于非虚拟化情况下的三类异常):
+
+- 指令异常:对应的就是虚拟指令异常
+- 内存异常:对应 Guest page-fault
+- 系统调用:对应来自于 VS-mode 的 ecall 指令
+
+详细代码分析参见 [此文][2]。
+
+## KVM 虚拟化相关的中断处理
+
+在 `arch/riscv/` 文件夹下的实现包含了 RISC-V 虚拟化扩展所用到的 CSR 以及机制的实现,此节将分析其中有关中断处理的代码实现。据代码可知,KVM 的架构相关的实现中仅包括了 VS-mode 对应的一系列中断的处理,其它中断的处理机制见下一节中断控制器分析。
+
+### 全局中断基准
+
+如果仅支持 M-Mode,那么默认的中断使能(Interrupt Enable)、Trap 向量、中断请求均以 M-Mode 为基准:
+
+- CSR 使用 `mstatus`, `mie`, `mtvec`, `mcause` 等
+- 状态寄存器标志以 `mstatus` 的为准:`mstatus.mie`, `mstatus.mpie`, `mstatus.mpp`
+- 中断编码均对应 M-Mode:`IRQ_M_SOFT/TIMER/EXT`
+
+否则,就以 S-Mode 为基准,如下方代码所示。
+
+```cpp
+// arch/riscv/include/asm/csr.h: line 300
+#ifdef CONFIG_RISCV_M_MODE
+/* CSR */
+# define CSR_STATUS	CSR_MSTATUS
+# define CSR_IE		CSR_MIE
+# define CSR_TVEC	CSR_MTVEC
+# define CSR_SCRATCH	CSR_MSCRATCH
+# define CSR_EPC	CSR_MEPC
+# define CSR_CAUSE	CSR_MCAUSE
+# define CSR_TVAL	CSR_MTVAL
+# define CSR_IP		CSR_MIP
+
+/* Status Register Flags */
+# define SR_IE		SR_MIE
+# define SR_PIE		SR_MPIE
+# define SR_PP		SR_MPP
+
+/* Interrupt Cause */
+# define RV_IRQ_SOFT		IRQ_M_SOFT
+# define RV_IRQ_TIMER	IRQ_M_TIMER
+# define RV_IRQ_EXT		IRQ_M_EXT
+#else /* CONFIG_RISCV_M_MODE */
+# define CSR_STATUS	CSR_SSTATUS
+# define CSR_IE		CSR_SIE
+# define CSR_TVEC	CSR_STVEC
+# define CSR_SCRATCH	CSR_SSCRATCH
+# define CSR_EPC	CSR_SEPC
+# define CSR_CAUSE	CSR_SCAUSE
+# define CSR_TVAL	CSR_STVAL
+# define CSR_IP		CSR_SIP
+
+# define SR_IE		SR_SIE
+# define SR_PIE		SR_SPIE
+# define SR_PP		SR_SPP
+
+# define RV_IRQ_SOFT		IRQ_S_SOFT
+# define RV_IRQ_TIMER	IRQ_S_TIMER
+# define RV_IRQ_EXT		IRQ_S_EXT
+# define RV_IRQ_PMU	IRQ_PMU_OVF
+# define SIP_LCOFIP     (_AC(0x1, UL) << IRQ_PMU_OVF)
+
+#endif /* !CONFIG_RISCV_M_MODE */
+
+/* IE/IP (Supervisor/Machine Interrupt Enable/Pending) flags */
+#define IE_SIE		(_AC(0x1, UL) << RV_IRQ_SOFT)
+#define IE_TIE		(_AC(0x1, UL) << RV_IRQ_TIMER)
+#define IE_EIE		(_AC(0x1, UL) << RV_IRQ_EXT)
+```
+
+M/S-Mode 的中断做统一处理,Guest 内部的 VS-Mode 中断将由 KVM 单独处理。下面将对三类中断的实现分别进行分析。
+
+### VS-Mode 软件中断
+
+所谓软件中断也称为 IPI(Inter-Processor Interrupt),即处理器间中断。对于 KVM 虚拟机来说,VS-mode 的软件中断是通过 SBI 进行处理的,如下图所示:
+
+- 创建 KVM 虚拟机及其 VCPU 时会通过一系列调用将 `IRQ_VS_SOFT` 注册进虚拟机(图右 `kvm_main.c`)
+- `kvm_riscv_vcpu_exit` 定义了 vCPU 的退出,Processor 间的中断即 IPI 的行为在此处定义,具体来说是通过调用 SBI(Supervisor Binary Interface)实现的(图左)
+
+```mermaid
+flowchart
+
+subgraph arch/riscv/include/asm/csr.h
+isft[IRQ_VS_SOFT]
+end
+
+subgraph arch/riscv/kvm/main.c
+hwen[kvm_arch_hardware_enable]
+end
+
+subgraph  virt/kvm/kvm_main.c
+startcpu[kvm_starting_cpu]-->hwennl
+hwenall[hardware_enable_all]-->hwennl
+mdl_init[module_kvm_init]-->
+rv_init[riscv_kvm_init]-->
+kvm_init[kvm_init]-->ops
+kvm_exit[kvm_exit]-->ops
+ops[kvm_syscore_ops]-->
+resume[kvm_resume]-->hwennl
+hwennl[hardware_enable_nolock]-->hwen
+
+vcpu[kvm_vcpu_ioctl]-->run
+
+dev_ioctl[kvm_dev_ioctl]-->
+dev_create_vm[kvm_dev_ioctl_create_vm]-->
+cvm[kvm_create_vm]-->hwenall
+kvm_init-->startcpu
+
+kvm_compat[kvm_vcpu_compat_ioctl]-->vcpu
+
+exp_exit[EXPORT_SYMBOL_GPL]-->kvm_exit
+
+vm[kvm_vm_ioctl]-->
+cvcpu[kvm_vm_ioctl_create_vcpu]-->
+vcpu_fd[create_vcpu_fd]-->
+fops[kvm_vcpu_fops]-->kvm_compat
+end
+
+subgraph arch/riscv/kvm/vcpu_sbi_replace.c
+ipi[kvm_sbi_ext_ipi_handler]
+sbi_ipi[vcpu_sbi_ext_ipi]-->ipi
+end
+
+subgraph  arch/riscv/kvm/vcpu_sbi.c
+ecall[kvm_riscv_vcpu_sbi_ecall]-->
+sbi[sbi_ext]-->sbi_ipi
+
+sbi-->sbiv01
+end
+
+subgraph arch/riscv/kvm/vcpu.c
+ustint[kvm_riscv_vcpu_unset_interrupt]
+stint[kvm_riscv_vcpu_set_interrupt]
+syncint[kvm_riscv_vcpu_sync_interrupts]-->isft
+run[kvm_arch_vcpu_ioctl_run]-->syncint
+end
+
+subgraph arch/riscv/kvm/vcpu_sbi_v01.c
+sbiv01[vcpu_sbi_ext_v01]-->
+v01[kvm_sbi_ext_v01_handler]-->stint
+v01-->ustint
+end
+
+ipi-->stint
+stint-->isft
+ustint-->isft
+hwen-->isft
+
+subgraph arch/riscv/kvm/vcpu_exit.c
+exit[kvm_riscv_vcpu_exit]-->ecall
+end
+```
+
+([下载由 Mermaid 生成的 PNG 图片][007])
+
+### VS-Mode 计时器中断
+
+与 VS-mode 软件中断类似,vCPU 的计时器中断处理接口在 `vcpu_timer.c` 中定义,而这些借口则是通过调用 `vcpu.c` 中统一的中断处理函数实现的(`kvm_riscv_vcpu_has/set/unset_interrupts`)。
+
+```mermaid
+flowchart LR
+
+subgraph arch/riscv/include/asm/csr.h
+itimer[IRQ_VS_TIMER]
+end
+
+subgraph arch/riscv/kvm/vcpu.c
+ustint[kvm_riscv_vcpu_unset_interrupt]-->itimer
+stint[kvm_riscv_vcpu_set_interrupt]-->itimer
+hasint[kvm_riscv_vcpu_has_interrupts]-->itimer
+end
+
+subgraph arch/riscv/kvm/vcpu_timer.c
+expired[kvm_riscv_vcpu_hrtimer_expired]-->stint
+update[kvm_riscv_vcpu_update_hrtimer]-->ustint
+pending[kvm_riscv_vcpu_timer_pending]-->hasint
+
+init[kvm_riscv_vcpu_timer_init]-->expired
+init-->update
+
+init-->
+vstimer_expired[kvm_riscv_vcpu_vstimer_expired]
+
+init-->
+vstimecmp_update[kvm_riscv_vcpu_update_vstimecmp]
+end
+
+subgraph arch/riscv/kvm/vcpu.c
+vcpu_create[kvm_arch_vcpu_create]-->init
+
+vcpu_pending[kvm_cpu_has_pending_timer]-->pending
+end
+
+subgraph virt/kvm/kvm_main.c
+check[kvm_vcpu_check_block]-->vcpu_pending
+end
+
+```
+
+([下载由 Mermaid 生成的 PNG 图片][008])
+
+### VS-Mode 外部中断
+
+对应的,在 KVM 内部有关 VS-mode 的外部中断仅在 KVM 兼容模式时才开启,以外部中断的方式配置 Guest。
+
+```mermaid
+flowchart LR
+
+subgraph arch/riscv/include/asm/csr.h
+ext[IRQ_VS_EXT]
+end
+
+subgraph arch/riscv/kvm/vcpu.c
+
+async[kvm_arch_vcpu_async_ioctl]-->
+int[kvm_riscv_vcpu_set/unset_interrupt]-->ext
+end
+
+subgraph virt/kvm/kvm_main.c
+compat[kvm_vcpu_compat_ioctl]-->
+vcpu[kvm_vcpu_ioctl]-->async
+end
+
+```
+
+([下载由 Mermaid 生成的 PNG 图片][009])
+
+```cpp
+// arch/riscv/kvm/vcpu.c: line 569
+
+long kvm_arch_vcpu_async_ioctl(struct file *filp,
+			       unsigned int ioctl, unsigned long arg)
+{
+	struct kvm_vcpu *vcpu = filp->private_data;
+	void __user *argp = (void __user *)arg;
+
+	if (ioctl == KVM_INTERRUPT) {
+		struct kvm_interrupt irq;
+
+		// 将用户态的由 argp 所指向的中断信息复制到 irq 中
+		if (copy_from_user(&irq, argp, sizeof(irq)))
+			return -EFAULT;
+
+		// 根据 irq 的中断操作类型,对指定的 vcpu 进行中断操作(set, unset)
+		if (irq.irq == KVM_INTERRUPT_SET)
+			return kvm_riscv_vcpu_set_interrupt(vcpu, IRQ_VS_EXT);
+		else
+			return kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT);
+	}
+
+	return -ENOIOCTLCMD;
+}
+
+```
+
+## RISC-V 中断在 Linux 中的实现
+
+### Timer 驱动
+
+参考 [此文][3] 对 RISC-V 计时器在 Linux 内核中的实现的分析,Linux Timer 的实现包含两个驱动文件:
+
+- 无 MMU 的 `drivers/clocksource/timer-riscv.c`:运行于 M-mode 下,可直接读取 `mtime` CSR 获取当前时间、通过 `mtimecmp` CSR 设置中断,考虑到虚拟化对于特权级的需求,该实现并不会在虚拟化系统中被调用。
+- 有 MMU 的 `drivers/clocksource/timer-clint.c`:支持 S-mode (S/HS/VS) 下的时钟访问,但因为权限问题,需要借助于 CSR 读写指令达成。在不支持 SSTC 扩展的情况下,需要通过 SBI 写入 `mtimecmp` 实现计时器中断。
+
+在添加了虚拟化扩展之后,VS-mode 的计时器中断操作需要通过 SBI 进入 HS-mode 再进入 M-mode,访问 `htimedelta`,`mtimecmp` 等 CSR,开销较大。后续有望通过添加 [SSTC 扩展][4] 实现对 `vstimecmp` 的直接访问进而简化虚拟情况下的中断开销。
+
+### 中断驱动与 PLIC 控制器
+
+[这篇文章][5] 基于一个 RTC(Real Time Clock)例程分析了 RISC-V 中断的申请、产生、处理流程。
+
+Linux 内核中涉及 RISC-V 中断相关的处理机制如下图所示,从左到右依次为 PLIC、INTC(INTerrupt Controller)和内核中断处理。
+
+```mermaid
+flowchart
+
+e[arch/riscv/kernel/entry.S]-->ghai
+
+subgraph kernel/irq/handle.c
+ghai[generic_handle_arch_irq]
+shi[set_handle_irq]
+end
+
+subgraph kernel/softirq.c
+ghai-->ie[irq_exit]
+ghai-.->so[others]
+end
+
+subgraph other
+end
+
+ghai-.->other
+
+subgraph drivers/irqchip/irq-riscv-intc.c
+direction
+ii[IRQCHIP_DECLARE:riscv_intc_init]-->shi-->
+rii[riscv_intc_irq]
+idm[[intc_domain]]
+end
+
+subgraph kernel/irq/irqdesc.c
+ghdi[generic_handle_domain_irq]
+end
+
+subgraph include/linux/irqdomain.h
+al[irq_domain_add_linear]
+end
+
+ii-->al-.return..->idm
+
+rii-->ghdi
+idm-.arg..->ghdi
+
+subgraph drivers/irqchip/irq-sifive-plic.c
+direction TB
+epid[IRQCHIP_DECLARE: plic_edge_init]-->pei[plic_edge_init]-->pi
+pid[IRQCHIP_DECLARE: plic_init]-->
+tpi[__plic_init]-->pi[plic_init]-->phi[plic_handle_irq]
+end
+```
+
+([下载由 Mermaid 生成的 PNG 图片][010])
+
+### 小结
+
+结合本节和上一节中有关 Linux 以及 KVM 对 RISC-V 中断的分析可知,KVM 内实现了将虚拟机内部 VS-mode 的中断与外部中断处理控制器的绑定,同时实现了特定于 VS-mode 的中断处理功能,从而完成了对于 RISC-V 虚拟化的支持。
+
+## MMIO 虚拟化
+
+### KVM
+
+通过用户态程序(如 kvmtool)创建了 vCPU 之后,vcpu 内部就包含了 MMIO 相关的项,如下图所示。如此,便实现了虚拟机 MMIO 的管理。所以 Guest 的 MMIO 操作都是基于下图所示的数据结构实现的。
+
+```mermaid
+flowchart BT
+
+subgraph v[kvm_vcpu]
+subgraph va[kvm_vcpu_arch]
+md[kvm_mmio_decode]
+vao[other arch states, ...]
+end
+
+subgraph r[kvm_run]
+m[mmio]
+ro[other run states, ...]
+end
+end
+```
+
+([下载由 Mermaid 生成的 PNG 图片][011])
+
+mmio 在 Host 一端的注册与销毁如下图所示:
+
+```mermaid
+flowchart LR
+subgraph kvm_main.c
+cv[kvm_create_vm]
+cd[kvm_destroy_vm]
+...
+end
+
+subgraph coalseced_mmio.c
+mi[kvm_coalesced_mmio_init]
+mf[kvm_coalesced_mmio_free]
+...,
+end
+
+cv-->mi
+cv-->mf
+cd-->mf
+```
+
+([下载由 Mermaid 生成的 PNG 图片][012])
+
+KVM 中的 MMIO 的访存操作有如下三个对应处理函数:
+
+```cpp
+// arch/riscv/include/asm/kvm_vcpu_insn.h: line 40
+int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run,
+			     unsigned long fault_addr,
+			     unsigned long htinst);
+int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run,
+			      unsigned long fault_addr,
+			      unsigned long htinst);
+int kvm_riscv_vcpu_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
+
+```
+
+下图展示了 MMIO 访存操作的具体实现,可以发现 LAOD/STORE 操作最终是通过调用 IO 设备中注册好的读写函数来实现的:
+
+```mermaid
+flowchart LR
+subgraph vi[arch/riscv/kvm/vcpu_insn.c]
+l[kvm_riscv_vcpu_mmio_load]-->r
+s[kvm_riscv_vcpu_mmio_store]-->r
+r[kvm_riscv_vcpu_mmio_return]
+end
+
+subgraph m[virt/kvm/kvm_main.c]
+rd[kvm_io_bus_read]
+wr[kvm_io_bus_write]
+end
+
+l-->rd
+s-->wr
+
+subgraph dv[include/kvm/iodev.h]
+subgraph iodev
+subgraph ops
+frd[*read]
+fwr[*write]
+end
+end
+end
+
+rd-.->frd
+wr-.->fwr
+```
+
+([下载由 Mermaid 生成的 PNG 图片][013])
+
+## kvmtool 中断注入及 MMIO 创建
+
+在 kvmtool 中 MMIO 是作为 VIRTIO 设备之一连带着中断处理函数一起被注册的。整个过程可以分为两个部分:
+
+- PLIC,设备树初始化
+- MMIO/PCI 等设备与 PLIC 以及中断处理函数的绑定
+- Console/Net 等设备与初始化时与 MMIO/PCI 设备的绑定
+
+执行完整个 Console 的创建过程就完成了 Guest 的 PLIC、IRQ 与设备的绑定,即实现了虚拟机的中断注入机制与 MMIO 创建。
+
+下图中左上的 `virtio_dev_init:virtio_console__init` 表示以 KVM 指定的方式初始化设备完成绑定。
+
+右边 RISC-V 模块左下方的 `late_init:setup_fdt` 则表示包含有 PLIC 的设备树的初始化。
+
+```mermaid
+flowchart LR
+
+subgraph riscv
+subgraph irq.c
+il[kvm__irq_line]
+it[kvm__irq_trigger]
+end
+
+subgraph plic.c
+pit[plic__irq_trig]
+pnd[pci__generate_fdt_nodes]
+end
+il-->pit
+it-->pit
+subgraph fdt.c
+li[late_init:setup_fdt]
+end
+li-->pnd
+end
+
+subgraph virtio
+
+subgraph unified_devices
+subgraph console.c
+cdi[virtio_dev_init:virtio_console__init]
+end
+subgraph net.c
+bdi[virtio_dev_init:virtio_net__init]
+end
+udo[other unified_devices, ...]
+end
+
+cdi-->vi
+bdi-->vi
+udo-.->vi
+
+subgraph pci.c
+pvq[virtio_pci__signal_vq]-->it
+pvq-->il
+pcfg[virtio_pci__signal_config]-->it
+po[other functions, ...]
+end
+
+subgraph mmio.c
+vq[virtio_mmio_signal_vq]-->it
+cfg[virtio_mmio_signal_config]-->it
+mo[other functions, ...]
+end
+
+pm[pci-modern.c]-->il
+pl[pci-legacy.c]-->il
+
+subgraph core.c
+vi[virtio_init: case VIRTIO_*]
+cm[mmio]
+cp[pci]
+end
+
+end
+
+cm-.->mmio.c
+cp-.->pci.c
+
+subgraph hw
+i8[i8042.c]-->il
+sr[serial.c]-->il
+end
+
+```
+
+([下载由 Mermaid 生成的 PNG 图片][014])
+
+## 总结
+
+RISC-V 中断通过 PLIC,CLINT 等驱动和控制器来实现,KVM 模块对于虚拟化的支持体现在两方面,一方面是 KVM 实现了与 Guest 外部的中断控制相关联的 VS-mode 的中断处理,另一方面则是通过为用户态程序如 kvmtool 提供接口,支持了虚拟机内部的设备与中断处理函数的注册与绑定,也实现了虚拟机与内核态的绑定,这使得 Guest 的 MMIO 访存等操作顺利进行。
+
+## 参考资料
+
+- [Linux Kernel][1]
+- [RISC-V 异常处理在 KVM 中的实现][2]
+- [RISC-V timer 在 Linux 中的实现][3]
+- [RISC-V SSTC Extension][4]
+- [RISC-V 中断子系统分析——PLIC 中断处理][5]
+- [kvmtool][6]
+
+[1]: https://www.kernel.org/
+[2]: 20221021-riscv-kvm-excp-impl.md
+[3]: https://tinylab.org/riscv-timer/#kvm-vcpu_timerc
+[4]: https://github.com/riscv/riscv-time-compare/releases/download/v0.5.4/Sstc.pdf
+[5]: https://gitee.com/tinylab/riscv-linux/blob/master/articles/20220919-riscv-irq-analysis-part2-interrupt-handling-plic.md
+[6]: https://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git
+[007]: images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-1.png
+[008]: images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-2.png
+[009]: images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-3.png
+[010]: images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-4.png
+[011]: images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-5.png
+[012]: images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-6.png
+[013]: images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-7.png
+[014]: images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-8.png
diff --git a/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-1.png b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-1.png
new file mode 100644
index 0000000000000000000000000000000000000000..2e27df96ff1bbabb100dfec8535d6081b7afa2f0
Binary files /dev/null and b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-1.png differ
diff --git a/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-2.png b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..280f1bca55ba9be8d3e240211a7f37e7a787ce58
Binary files /dev/null and b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-2.png differ
diff --git a/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-3.png b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-3.png
new file mode 100644
index 0000000000000000000000000000000000000000..fce9ae7a7c51c99040ee1ec28d588bed4e479c37
Binary files /dev/null and b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-3.png differ
diff --git a/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-4.png b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-4.png
new file mode 100644
index 0000000000000000000000000000000000000000..e7e6c2bb75878e982dbdf87fc9b2c6b24409de19
Binary files /dev/null and b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-4.png differ
diff --git a/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-5.png b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-5.png
new file mode 100644
index 0000000000000000000000000000000000000000..49ab6b415af437cb345cd57172e12af136bba345
Binary files /dev/null and b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-5.png differ
diff --git a/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-6.png b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-6.png
new file mode 100644
index 0000000000000000000000000000000000000000..cdcf0edef2f5886919370577eb59d0fcc5f74873
Binary files /dev/null and b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-6.png differ
diff --git a/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-7.png b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-7.png
new file mode 100644
index 0000000000000000000000000000000000000000..cefe6c3adb5081999510f474ecdb617ff9cb9cef
Binary files /dev/null and b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-7.png differ
diff --git a/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-8.png b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-8.png
new file mode 100644
index 0000000000000000000000000000000000000000..2c0783a76b813250fe540f9916c279dd9c51e0c6
Binary files /dev/null and b/articles/images/riscv-riscv_kvm_int_impl_2/mermaid-riscv-kvm-int-impl-2-8.png differ