2025/05/17 07:46 Implementing a RISC-V Hypervisor

やっほー、ロボ子!今日はRISC-Vのハイパーバイザの話をするのじゃ!StarinaへのLinux統合のために、RISC-V H-extensionベースのハイパーバイザを実装したらしいぞ。

博士、こんにちは。RISC-Vのハイパーバイザですか。なんだか難しそうですが、面白そうですね!

QEMUがRISC-V H-extensionのエミュレーションをサポートしているから、試せるのじゃ。`-cpu rv64,h=true`をQEMUのコマンドラインに追加するだけだぞ。

なるほど、QEMUでエミュレーションできるんですね。ゲストに入る最初のステップは、`hstatus.SPV`を1に設定してから`sret`命令を実行すること、と。

そうそう!そして、ゲストモードで`ecall`を実行するには、ゲストのページテーブルを準備して、ゲスト物理アドレスをホスト物理アドレスにマップする必要があるのじゃ。

ページテーブルの準備とアドレスのマッピングですか。少し複雑ですね。

RISC-VはSv39x4/Sv48x4/Sv57x4というページングモードを定義していて、Sv39/Sv48/Sv57とほぼ同じだけど、カーネルページにもUビットを1に設定する必要があるんだぞ。

Uビットをカーネルページにも設定するんですね。これはどうしてでしょうか?

それは...私もまだ勉強中なのじゃ!でも、とにかくそういうことらしいぞ!

承知いたしました(笑)。ゲストでHello Worldプログラムを実行するためには、SBIを実装して`putchar` APIを呼び出す必要があるんですね。

`unimp`命令を呼び出してトラップを発生させるのも忘れずにのじゃ!

はい、`unimp`命令ですね。Linuxを起動するためには、カーネル設定オプションも重要ですね。

`CONFIG_SERIAL_EARLYCON_RISCV_SBI=y`、`CONFIG_RISCV_SBI_V01=y`、`CONFIG_HVC_RISCV_SBI=y`、`CONFIG_RISCV_TIMER=y`を有効にする必要があるぞ。

これらのオプションは、SBIやタイマーに関連するものですね。Linuxカーネルは`make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- Image`でビルドできる、と。

デバイスツリーも必要で、RustVMMプロジェクトの`vm-fdt`を使うと便利なのじゃ。

`vm-fdt`ですね。覚えておきます。

`rdtime`をサポートするために、`hcounteren` CSRを埋める必要があるぞ。タイマーサポートの実装には、SBIを呼び出す方法と`sstc`拡張を使う方法があるのじゃ。

`hcounteren` CSRとタイマーサポートの実装方法ですね。MMIOをサポートするためには、ゲストページフォールトをトリガーして、ハイパーバイザがMMIO操作をエミュレートする、と。

そう!`htval`に書き込まれたゲスト物理アドレスは2ビット右シフトされるから注意なのじゃ!

`htval`のアドレスシフトですね。`htinst`は圧縮された命令である可能性があり、命令幅は2バイトの場合もある、と。

virtio-fsを使ってルートファイルシステムを提供すると、Starinaとの統合がスムーズになるのじゃ。

virtio-fsですね。ゲストのカーネルスタックトレースをデバッグするには、GDBを使うんですね。

GDBは強力な味方なのじゃ!これでRISC-Vハイパーバイザも怖くないぞ!

なんだか盛りだくさんでしたが、少しずつ理解していきたいと思います。ありがとうございました、博士!

どういたしまして!最後に一つ、RISC-Vの「V」って何の略か知ってるかのじゃ?

えっと…なんでしょう?

「Very Important Stuff Coming」の略なのじゃ!…って、今考えたぞ!

博士、それ、今考えたでしょ!(笑)
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。