BhyveでTPMを使ってみる

## はじめに
先日FreeBSD 14.0-RELEASEが公開されました。
その中の新機能にbhyveでのTPM passthrough、GPU passthroughのサポートがあります。ここでは早速TPM passthroughの方を使ってみたいと思います。

## TPMって何？
TPMとはTrusted Platform Moduleの略で、詳しい説明はWikipediaなどを見て頂くとして、簡単に言うとPCのセキュリティを向上させるための部品です。暗号キーの生成、ハッシュ値の計算、デジタル署名などの機能を持っています。昔はマザーボードに内蔵されていたり、後付けのチップとして装着するものでしたが、最近のCPUではCPU側にこの機能を持っています。

Windows 11ではこのTPM(2.0)が最小システム要件となっていて、TPMがないとインストールできません。スキップする方法もあるそうですが、基本的にはTPMが必要です。このためBhyveのゲストでWindows 11を使うことができませんでした。

TPM passthroughがbhyveでサポートされたことにより、ホストで認識したTPMをそのままゲストに見せることが可能になっています。

## ホスト側の設定
現状bhyveでサポートしているTPMはエミュレーションではなく、passthroughなので、基本的にホストで見えたデバイスをそのままゲストに見せるという方法になります。そのため、まずホストマシン側でTPMを使えるようにすることが必要です。

FreeBSDはTPMドライバを持っているため、ドライバをロードさせればTPMを利用できるようになります。ただし当然ですがハードウェア側がサポートしていることが条件です。どの辺りからサポートしているかはっきり分かりませんが、最近のCPUではCPU側に機能があるため、BIOS(UEFI)側で有効になっていれば使えます。
Windows 10時代のマザーボードではデフォルトで無効になっていることがありますが、Windows 11の最小要件になっていることもあって、Windows 11対応のマザーボードであればデフォルトで有効になっていると思います。

私の環境では第12世代Intel Core i9 12900Kを使用しています。

ドライバの名前はそのまま tpm なので、kldloadロードしてあげるだけです。

```
# kldload tpm
# dmesg | grep tpm
tpmcrb0: <Trusted Platform Module 2.0, CRB mode> iomem 0xfed40000-0xfed44fff on acpi0
```

はい、認識しましたね。
あとは /dev にデバイスファイルができていることを確認しましょう。

```
# ls -l /dev/tpm0
crw-------  1 root wheel 0x61 12月 12 13:25 /dev/tpm0
```

使えることが確認できたらOS起動した時から使えるように/boot/loader.confに書いておきましょう。

```
# echo 'tpm_load="YES"' >> /boot/loader.conf
````

## ゲスト側の設定
あらかじめインストール済みのWindows 10のゲストにtpmを追加することにします。
bhyveの起動オプションでtpm passthroughを設定します。
私はbhyveの管理にvm-bhyveを使用しているので、vm config ゲスト名 で設定ファイルを開きます。私の環境ではゲストの名前はwindowsなので、こうです。

```
# vm config windows
~~~
bhyve_options="-A -K jp -l tpm,passthru,/dev/tpm0"
~~~
```

エディタが開くので、bhyve_options=の列に -l tpm,passthru,/dev/tpm0 を追加します。

この後、ゲストを起動します。

```
# vm start windows
```

## ゲストのWindows 10でTPMを確認
デバイスマネージャを開くと、「トラステッド プラットフォーム モジュール2.0」を認識していることが確認できます。

![スクリーンショット 2023-12-12 102242.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373056/c956c968-aade-d148-0f77-f8015d3ab2d5.png)


これでTPMを認識できました。TPMがあればbitlockerなどドライブの暗号化なども使えるはずですが、私としてはそこはあまり考えていなくてWindows 11が使えればよいだけです。そこで Windows 11 へのアップデートを行ってみたいと思います。

## Windows 11へのアップデート要件を満たしたことを確認する
しばらく放置しておけば、システムが変更されTPMが追加されたことを認識してWindows 11へのアップデートが可能になるのですが、そのままだといつになるのか分からないので、手動で認識するように実行してみます。

次のマイクロソフトのページを参考にしました。
[デバイス ハードウェアの変更後にデバイスが Windows 11 のシステム必要条件を満たしているかどうかを確認する方法](https://support.microsoft.com/ja-jp/windows/%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9-%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E5%A4%89%E6%9B%B4%E5%BE%8C%E3%81%AB%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%81%8C-windows-11-%E3%81%AE%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E5%BF%85%E8%A6%81%E6%9D%A1%E4%BB%B6%E3%82%92%E6%BA%80%E3%81%9F%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%81%8B%E3%81%A9%E3%81%86%E3%81%8B%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95-f3bc0aeb-6884-41a1-ab57-88258df6812b)

このページの「Windows 11 の適格性評価を手動で更新する方法」に従って操作します。
すぐには反映されませんが、しばらく待つと、設定のアップデートの項目にWindows 11へのアップデートが追加されます。

このPCは現在、「Windows 11を実行するための最小システム要件を満たしていません」から...
![スクリーンショット 2023-12-14 234148.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373056/442d72a3-dae0-e6b6-857a-1b5ad5d7a4f8.png)

Windows 11へのアップデートが表示されました。
![スクリーンショット 2023-12-12 114401.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373056/0e24f7ce-6e32-46bc-6fac-331814729229.png)

## Windows 11へアップデート
後はアップデートするだけなのですが、もちろん事前にバックアップだったりスナップショットだったり取っておく方が安全です。テスト用の環境ならいいですが、重要なデータを扱っている場合には十分注意してください。

そして、アップデートボタンを押して準備ができたら再起動...ですが、あれ？？
起動してこない。何と、ブートローダー読み込んだところでハングアップしてしまいました。ホストOS側は普通に使えるので、単純にbhyveのプロセス側が固まっている状態です。

![スクリーンショット 2023-12-12 133552.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373056/bc97f81b-b5ec-5233-9caf-a2620f776cef.png)

vm poweroff -f windows などしても反応しないので、直接bhyveのプロセスをkill -9で終了させます。bhyveの起動オプションを変更して、tpm passthroughを外して再度ゲストを起動すると、問題なく起動しました。Window 11へのアップデートが失敗したとなってリカバリが入り、アップデート作業前の状態で起動してきます(ちょっと時間かかります)。面倒だったらスナップショットからrollbackで戻してしまえばいいと思います。

## 最後に
インストール済みのWindows 10のゲストに追加して認識されることまでは確認できましたが、肝心のWindows 11へのアップデートはできませんでした。
いきなりハングアップして、メッセージも何も出ないので、何が悪いか分からずお手上げ状態です。何か知っている人がいたら是非教えてください。