I/O 请求处理¶
用户虚拟机(User VM)的 I/O 请求由虚拟机监控器构建,然后由 ACRN 虚拟机监控器服务模块分发给与 I/O 请求的地址范围对应的 I/O 客户端。I/O 请求处理的详细信息在以下章节中描述。
1. I/O 请求¶
对于每个用户虚拟机,都有一个共享的 4KB 内存区域,用于虚拟机监控器和服务虚拟机(Service VM)之间的 I/O 请求通信。I/O 请求是一个 256 字节的结构缓冲区,即 “struct acrn_io_request”,当用户虚拟机中发生捕获的 I/O 访问时,该缓冲区由虚拟机监控器的 I/O 处理程序填充。服务虚拟机中的 ACRN 用户空间首先分配一个 4KB 页面,并将缓冲区的 GPA(客户物理地址)传递给虚拟机监控器。该缓冲区用作 16 个 I/O 请求槽的数组,每个 I/O 请求槽为 256 字节。此数组由 vCPU ID 索引。
2. I/O 客户端¶
I/O 客户端负责处理用户虚拟机的 I/O 请求,这些请求访问的 GPA 落在某个范围内。多个 I/O 客户端可以与每个用户虚拟机关联。每个用户虚拟机都有一个特殊的客户端,称为默认客户端,它处理所有不属于任何其他客户端范围的 I/O 请求。ACRN 用户空间充当每个用户虚拟机的默认客户端。
下图显示了 I/O 请求共享缓冲区、I/O 请求和 I/O 客户端之间的关系。
+------------------------------------------------------+
| Service VM |
|+--------------------------------------------------+ |
|| +----------------------------------------+ | |
|| | shared page ACRN userspace | | |
|| | +-----------------+ +------------+ | | |
|| +----+->| acrn_io_request |<-+ default | | | |
|| | | | +-----------------+ | I/O client | | | |
|| | | | | ... | +------------+ | | |
|| | | | +-----------------+ | | |
|| | +-|--------------------------------------+ | |
||---|----|-----------------------------------------| |
|| | | kernel | |
|| | | +----------------------+ | |
|| | | | +-------------+ HSM | | |
|| | +--------------+ | | | |
|| | | | I/O clients | | | |
|| | | | | | | |
|| | | +-------------+ | | |
|| | +----------------------+ | |
|+---|----------------------------------------------+ |
+----|-------------------------------------------------+
|
+----|-------------------------------------------------+
| +-+-----------+ |
| | I/O handler | ACRN Hypervisor |
| +-------------+ |
+------------------------------------------------------+
3. I/O 请求状态转换¶
ACRN I/O 请求的状态转换如下所示。
FREE -> PENDING -> PROCESSING -> COMPLETE -> FREE -> ...
FREE: 此 I/O 请求槽为空
PENDING: 此槽中有一个有效的 I/O 请求正在等待
PROCESSING: 正在处理 I/O 请求
COMPLETE: I/O 请求已处理完毕
处于 COMPLETE 或 FREE 状态的 I/O 请求归虚拟机监控器所有。HSM 和 ACRN 用户空间负责处理其他状态。
4. I/O 请求的处理流程¶
当用户虚拟机中发生捕获的 I/O 访问时,虚拟机监控器的 I/O 处理程序将填充一个处于 PENDING 状态的 I/O 请求。
虚拟机监控器向服务虚拟机发出一个上调 (upcall),这是一个通知中断。
上调处理程序调度一个工作线程来分发 I/O 请求。
工作线程查找处于 PENDING 状态的 I/O 请求,根据 I/O 访问的地址将其分配给不同的已注册客户端,将其状态更新为 PROCESSING,并通知相应的客户端进行处理。
被通知的客户端处理分配的 I/O 请求。
HSM 将 I/O 请求的状态更新为 COMPLETE,并通过超调用通知虚拟机监控器完成。