I/O リクエストの処理

ハイパーバイザが作成した User VM の I/O リクエストは、ACRN ハイパーバイザサービスモジュールが その I/O リクエストのアドレス範囲に対応する I/O クライアントに振り分ける。I/O リクエストの 処理の詳細は以降の節で説明する。

1. I/O リクエスト

User VM ごとに、ハイパーバイザと Service VM の間で I/O リクエストをやり取りするための 4K バイトの共有メモリ領域がある。I/O リクエストは 'struct acrn_io_request' という名前の 256 バイトの構造体バッファで、User VM でトラップされた I/O アクセスが発生したときに ハイパーバイザの I/O ハンドラが書き込む。Service VM 内の ACRN ユーザ空間がまず 4K バイトの ページを確保し、そのバッファの GPA(Guest Physical Address)をハイパーバイザに渡す。 このバッファは 16 個の I/O リクエストスロットの配列として使われ、各 I/O リクエスト スロットは 256 バイトである。この配列の添字は vCPU ID である。

2. I/O クライアント

I/O クライアントは、アクセスされた GPA が特定の範囲に入る User VM の I/O リクエストを 処理する役割を担う。各 User VM には複数の I/O クライアントを対応付けることができる。 各 User VM にはデフォルトクライアントと呼ばれる特別なクライアントが対応付けられ、 他のどのクライアントの範囲にも入らない I/O リクエストをすべて処理する。ACRN ユーザ空間が 各 User VM のデフォルトクライアントとして動作する。

以下の図に、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 リクエストはハイパーバイザが所有する。それ以外の状態の I/O リクエストの処理は HSM と ACRN ユーザ空間が担当する。

4. I/O リクエストの処理の流れ

  1. User VM でトラップされた I/O アクセスが発生すると、ハイパーバイザの I/O ハンドラが I/O リクエストを PENDING 状態にして書き込む。

  2. ハイパーバイザは Service VM に対してアップコール(通知割り込み)を行う。

  3. アップコールハンドラは、I/O リクエストを振り分けるワーカーをスケジュールする。

  4. ワーカーは PENDING の I/O リクエストを探し、I/O アクセスのアドレスに基づいて 登録済みの各クライアントに割り当て、状態を PROCESSING に更新して、対応する クライアントに処理を通知する。

  5. 通知を受けたクライアントが、割り当てられた I/O リクエストを処理する。

  6. HSM は I/O リクエストの状態を COMPLETE に更新し、完了したことをハイパーコールで ハイパーバイザに通知する。