AVFアーキテクチャ

Android は、Android 仮想化フレームワークの実装に必要なすべてのコンポーネントのリファレンス実装を提供します。現在、この実装は ARM64 に限定されています。このページではフレームワークのアーキテクチャについて説明します。

バックグラウンド

Arm アーキテクチャでは最大 4 つの例外レベルが許可されており、例外レベル 0 (EL0) が最も権限が低く、例外レベル 3 (EL3) が最も権限が高くなります。 Android コードベースの大部分 (すべてのユーザー空間コンポーネント) は EL0 で実行されます。一般に「Android」と呼ばれるものの残りの部分は、EL1 で実行される Linux カーネルです。

EL2 レイヤーにより、強力な機密性と整合性が保証された状態で、メモリとデバイスを EL1/EL0 で個別の pVM に分離できるハイパーバイザーの導入が可能になります。

ハイパーバイザー

保護されたカーネルベースの仮想マシン (pKVM) は、 Linux KVM ハイパーバイザー上に構築されており、作成時に「保護」とマークされたゲスト仮想マシンで実行されているペイロードへのアクセスを制限する機能が拡張されています。

KVM/arm64 は、特定の CPU 機能、つまり仮想化ホスト拡張機能 (VHE) (ARMv8.1 以降) の可用性に応じて、さまざまな実行モードをサポートします。これらのモードの 1 つ (一般に非 VHE モードとして知られています) では、ハイパーバイザー コードはブート中にカーネル イメージから分割されて EL2 にインストールされますが、カーネル自体は EL1 で実行されます。 KVM の EL2 コンポーネントは Linux コードベースの一部ですが、複数の EL1 間の切り替えを担当する小さなコンポーネントであり、ホストのカーネルによって完全に制御されます。ハイパーバイザー コンポーネントは Linux でコンパイルされますが、 vmlinuxイメージの別の専用メモリ セクションに常駐します。 pKVM は、Android ホスト カーネルとユーザー空間に制限を加え、ゲスト メモリとハイパーバイザーへのホスト アクセスを制限できる新機能でハイパーバイザー コードを拡張することでこの設計を活用します。

起動手順

pKVM ブート手順を図 1 に示します。最初のステップは、ブートローダーが EL2 で pKVM 対応 Linux カーネルを入力することです。初期ブート中に、カーネルは EL2 で実行されていることを検出し、EL1 への権限を剥奪し、pKVM を残します。この時点から、Linux カーネルは通常どおりに起動し、ユーザー領域に到達するまで、必要なデバイス ドライバーをすべてロードします。これらの手順は、pKVM の制御下で行われます。

ブート プロシージャは、初期ブート中にのみブートローダーを信頼してカーネル イメージの整合性を維持します。カーネルの特権が剥奪されると、カーネルはハイパーバイザーによって信頼されなくなったとみなされ、カーネルが侵害された場合でもカーネル自体を保護する責任があります。

pKVM ブート手順

図 1. pKVM ブート手順

Android カーネルとハイパーバイザーを同じバイナリ イメージ内に配置することで、それらの間で非常に緊密に結合された通信インターフェイスが可能になります。この緊密な結合により、2 つのコンポーネントのアトミックな更新が保証され、コンポーネント間のインターフェイスを安定に保つ必要がなくなり、長期的な保守性を損なうことなく非常に高い柔軟性が得られます。また、ハイパーバイザーによって提供されるセキュリティ保証に影響を与えることなく両方のコンポーネントが連携できる場合、密結合によりパフォーマンスの最適化が可能になります。

さらに、Android エコシステムで GKI を採用すると、pKVM ハイパーバイザーをカーネルと同じバイナリで Android デバイスに自動的に展開できるようになります。

CPUメモリアクセス保護

Arm アーキテクチャでは、2 つの独立したステージに分割されたメモリ管理ユニット (MMU) が指定されており、両方のステージを使用してアドレス変換とメモリのさまざまな部分へのアクセス制御を実装できます。ステージ 1 MMU は EL1 によって制御され、第 1 レベルのアドレス変換が可能になります。ステージ 1 MMU は、各ユーザー空間プロセスおよび独自の仮想アドレス空間に提供される仮想アドレス空間を管理するために Linux によって使用されます。

ステージ 2 MMU は EL2 によって制御され、ステージ 1 MMU の出力アドレスに 2 番目のアドレス変換を適用できるようになり、結果として物理アドレス (PA) が得られます。ステージ 2 の変換は、ハイパーバイザーによって使用され、すべてのゲスト VM からのメモリ アクセスを制御および変換できます。図 2 に示すように、両方の変換ステージが有効な場合、ステージ 1 の出力アドレスは中間物理アドレス (IPA) と呼ばれます。 注: 仮想アドレス (VA) は IPA に変換され、次に PA に変換されます。

CPUメモリアクセス保護

図 2. CPU メモリ アクセス保護

従来、KVM はゲストの実行中はステージ 2 変換を有効にして実行され、ホスト Linux カーネルの実行中はステージ 2 を無効にして実行されていました。このアーキテクチャにより、ホスト ステージ 1 MMU からのメモリ アクセスがステージ 2 MMU を通過できるため、ホストからゲスト メモリ ページへの無制限のアクセスが可能になります。一方、pKVM はホスト コンテキストでもステージ 2 保護を有効にし、ホストの代わりにハイパーバイザーにゲスト メモリ ページの保護を担当させます。

KVM は、ステージ 2 でアドレス変換を最大限に活用して、ゲスト用の複雑な IPA/PA マッピングを実装します。これにより、物理的な断片化にもかかわらず、ゲストに対して連続したメモリのような錯覚が生じます。ただし、ホストのステージ 2 MMU の使用はアクセス制御のみに制限されます。ホスト ステージ 2 はアイデンティティ マップされており、ホスト IPA 空間内の連続したメモリが PA 空間内でも連続していることが保証されます。このアーキテクチャでは、ページ テーブルで大規模なマッピングを使用できるため、変換ルックアサイド バッファ (TLB) の負荷が軽減されます。 PA によって ID マッピングにインデックスを付けることができるため、ホスト ステージ 2 は、ページ テーブル内のページ所有権を直接追跡するためにも使用されます。

ダイレクト メモリ アクセス (DMA) 保護

前述したように、CPU ページ テーブル内の Linux ホストからゲスト ページのマッピングを解除することは、ゲスト メモリを保護するために必要な手順ではありますが、不十分です。また、pKVM は、ホスト カーネルの制御下にある DMA 対応デバイスによるメモリ アクセスや、悪意のあるホストによって開始される DMA 攻撃の可能性から保護する必要があります。このようなデバイスがゲスト メモリにアクセスできないようにするために、pKVM では、図 3 に示すように、システム内のすべての DMA 対応デバイスに対して入出力メモリ管理ユニット (IOMMU) ハードウェアが必要です。

DMAメモリアクセス保護

図 3. DMA メモリ アクセス保護

IOMMU ハードウェアは、少なくとも、ページ単位で物理メモリへのデバイスの読み取り/書き込みアクセスを許可および取り消す手段を提供します。ただし、この IOMMU ハードウェアは、アイデンティティ マップされたステージ 2 を想定しているため、pVM でのデバイスの使用を制限します。

仮想マシン間の分離を確保するには、適切なページ テーブルのセットを変換に使用できるように、さまざまなエンティティに代わって生成されたメモリ トランザクションが IOMMU によって区別可能である必要があります。

さらに、EL2 での SoC 固有のコードの量を減らすことは、pKVM の全体的なトラステッド コンピューティング ベース (TCB) を減らすための重要な戦略であり、ハイパーバイザーに IOMMU ドライバーを含めることに逆行します。この問題を軽減するために、EL1 のホストは、電源管理、初期化、および必要に応じて割り込み処理などの補助的な IOMMU 管理タスクを担当します。

ただし、ホストにデバイスの状態を制御させると、IOMMU ハードウェアのプログラミング インターフェイスに追加の要件が課され、他の手段 (デバイスのリセット後など) によって許可チェックがバイパスされないようにする必要があります。

分離と直接割り当ての両方を可能にする Arm デバイス用の標準で十分にサポートされている IOMMU は、Arm System Memory Management Unit (SMMU) アーキテクチャです。このアーキテクチャは、推奨されるリファレンス ソリューションです。

メモリの所有権

ブート時に、ハイパーバイザー以外のすべてのメモリーはホストによって所有されているとみなされ、ハイパーバイザーによってそのように追跡されます。 pVM が生成されると、ホストはブートできるようにメモリ ページを寄付し、ハイパーバイザーはそれらのページの所有権をホストから pVM に移行します。したがって、ハイパーバイザーは、ホストのステージ 2 ページ テーブルにアクセス制御制限を設けて、ホストがページに再度アクセスできないようにし、ゲストに機密性を提供します。

ホストとゲスト間の通信は、ホストとゲスト間のメモリ共有を制御することによって可能になります。ゲストは、ハイパーコールを使用してページの一部をホストと共有することができます。これにより、ホスト ステージ 2 のページ テーブルでそれらのページを再マップするようにハイパーバイザーに指示されます。同様に、ホストと TrustZone との通信は、メモリ共有および/または貸与操作によって可能になり、これらはすべてFirmware Framework for Arm (FF-A) 仕様を使用する pKVM によって厳密に監視および制御されます。

ハイパーバイザーは、システム内のすべてのメモリ ページの所有権と、メモリ ページが他のエンティティに共有されているか貸与されているかを追跡する責任があります。この状態追跡のほとんどは、ホストとゲストのステージ 2 ページ テーブルに添付されたメタデータを使用して行われ、ページ テーブル エントリ (PTE) 内の予約ビットを使用します。ページ テーブル エントリ (PTE) は、その名前が示すように、ソフトウェア用に予約されています。

ホストは、ハイパーバイザーによってアクセス不能になったページにアクセスしようとしないようにする必要があります。不正なホスト アクセスにより、ハイパーバイザーによって同期例外がホストに挿入され、責任のあるユーザー空間タスクが SEGV 信号を受信するか、ホスト カーネルがクラッシュする可能性があります。偶発的なアクセスを防ぐために、ゲストに提供されたページは、ホスト カーネルによるスワップまたはマージの対象外となります。

割り込み処理とタイマー

割り込みは、ゲストがデバイスと対話する方法や CPU 間の通信に不可欠な部分であり、プロセッサ間割り込み (IPI) が主な通信メカニズムです。 KVM モデルでは、すべての仮想割り込み管理を EL1 のホストに委任し、その目的のためにハイパーバイザーの信頼できない部分として動作します。

pKVM は、既存の KVM コードに基づいた完全な汎用割り込みコントローラ バージョン 3 (GICv3) エミュレーションを提供します。タイマーと IPI は、この信頼できないエミュレーション コードの一部として処理されます。

GICv3 のサポート

EL1 と EL2 の間のインターフェイスでは、割り込みに関連するハイパーバイザー レジスタのコピーを含め、完全な割り込み状態が EL1 ホストに表示されるようにする必要があります。この可視性は通常、仮想 CPU (vCPU) ごとに 1 つの共有メモリ領域を使用して実現されます。

システム レジスタ ランタイム サポート コードは、ソフトウェア生成割り込みレジスタ (SGIR) および非アクティブ割り込みレジスタ (DIR) レジスタ トラップのみをサポートするように簡素化できます。このアーキテクチャでは、これらのレジスタが常に EL2 にトラップすることが義務付けられていますが、他のトラップはこれまでのところ、エラータを軽減するためにのみ役立ちます。それ以外はすべてハードウェアで処理されます。

MMIO 側では、すべてが EL1 でエミュレートされ、KVM の現在のインフラストラクチャをすべて再利用します。最後に、割り込み待ち (WFI) は、 KVM が使用する基本的なスケジューリング プリミティブの 1 つであるため、常に EL1 に中継されます。

タイマーのサポート

vCPU がブロックされている間に EL1 がタイマー割り込みを挿入できるように、仮想タイマーのコンパレータ値を各トラップ WFI の EL1 に公開する必要があります。物理タイマーは完全にエミュレートされ、すべてのトラップは EL1 に中継されます。

MMIOの処理

仮想マシン モニター (VMM) と通信して GIC エミュレーションを実行するには、さらなる優先順位付けのために MMIO トラップを EL1 のホストに中継する必要があります。 pKVM には以下が必要です。

  • IPAとアクセスのサイズ
  • 書き込み時のデータ
  • トラップ時点での CPU のエンディアンネス

さらに、汎用レジスタ (GPR) を送信元/宛先とするトラップは、抽象転送疑似レジスタを使用して中継されます。

ゲストインターフェース

ゲストは、ハイパーコールとトラップされた領域へのメモリ アクセスを組み合わせて使用​​して、保護されたゲストと通信できます。ハイパーコールはSMCCC 標準に従って公開され、KVM によるベンダー割り当て用に予約された範囲が使用されます。次のハイパーコールは、pKVM ゲストにとって特に重要です。

汎用ハイパーコール

  • PSCI は、ゲストがオンライン、オフライン、システム シャットダウンなどの vCPU のライフサイクルを制御するための標準メカニズムを提供します。
  • TRNG は、ゲストが呼び出しを EL3 に中継する pKVM からのエントロピーを要求するための標準メカニズムを提供します。このメカニズムは、ホストがハードウェア乱数生成器 (RNG) の仮想化を信頼できない場合に特に役立ちます。

pKVM ハイパーコール

  • ホストとのメモリ共有。すべてのゲスト メモリは最初はホストからアクセスできませんが、共有メモリ通信や共有バッファに依存する準仮想化デバイスにはホスト アクセスが必要です。ホストとのページの共有および共有解除のためのハイパーコールにより、ゲストは、ハンドシェイクを必要とせずに、メモリのどの部分を Android の残りの部分にアクセス可能にするかを正確に決定できます。
  • ホストへのメモリ アクセス トラップ。従来、KVM ゲストが有効なメモリ領域に対応しないアドレスにアクセスすると、vCPU スレッドがホストに終了し、そのアクセスは通常 MMIO に使用され、ユーザー空間の VMM によってエミュレートされます。この処理を容易にするために、pKVM は、アドレス、レジスタ パラメータ、および場合によってはそれらの内容など、障害のある命令に関する詳細をホストに通知する必要があります。これにより、トラップが予期されなかった場合、保護されたゲストからの機密データが意図せず公開される可能性があります。 pKVM は、ゲストが事前にハイパーコールを発行して障害のある IPA 範囲をホストへのトラップバックが許可されている範囲として特定していない限り、これらの障害を致命的として扱うことでこの問題を解決します。このソリューションはMMIO ガードと呼ばれます。

仮想 I/O デバイス (virtio)

Virtio は、準仮想化デバイスの実装と操作のための、人気があり、移植可能で、成熟した標準です。保護されたゲストに公開されるデバイスの大部分は、virtio を使用して実装されています。 Virtio は、保護されたゲストと Android の残りの部分との間の通信に使用される vsock 実装もサポートします。

Virtio デバイスは通常、VMM によってホストのユーザー空間に実装されます。VMM は、ゲストから virtio デバイスの MMIO インターフェイスへのトラップされたメモリ アクセスをインターセプトし、予期される動作をエミュレートします。 MMIO アクセスは、デバイスへのアクセスごとに VMM との往復が必要なため、比較的コストがかかります。そのため、デバイスとゲスト間の実際のデータ転送のほとんどは、メモリ内の一連の virtqueue を使用して行われます。 virtio の重要な前提は、ホストがゲスト メモリに任意にアクセスできるということです。この前提は、デバイス エミュレーションが直接アクセスすることを目的としたゲスト内のバッファーへのポインターを含む可能性がある virtqueue の設計で明らかです。

前述のメモリ共有ハイパーコールを使用して、virtio データ バッファをゲストからホストに共有することもできますが、この共有は必然的にページ粒度で実行されるため、バッファ サイズがページのサイズより小さい場合、必要以上のデータが公開される可能性があります。 。代わりに、ゲストは virtqueue とそれに対応するデータ バッファーの両方を共有メモリの固定ウィンドウから割り当てるように構成され、必要に応じてデータがウィンドウとの間でコピー (バウンス) されます。

仮想デバイス

図 4. Virtio デバイス

TrustZoneとの対話

ゲストは TrustZone と直接対話することはできませんが、ホストは安全な世界に SMC 呼び出しを発行できる必要があります。これらの呼び出しでは、ホストからアクセスできない物理的にアドレス指定されたメモリ バッファを指定できます。安全なソフトウェアは一般にバッファへのアクセス可能性を認識しないため、悪意のあるホストがこのバッファを使用して混乱した代理攻撃 (DMA 攻撃に類似) を実行する可能性があります。このような攻撃を防ぐために、pKVM は EL2 へのすべてのホスト SMC 呼び出しをトラップし、ホストと EL3 のセキュア モニターの間のプロキシとして機能します。

ホストからの PSCI 呼び出しは、最小限の変更を加えて EL3 ファームウェアに転送されます。具体的には、オンラインになるかサスペンドから再開する CPU のエントリ ポイントは、EL1 でホストに戻る前にステージ 2 ページ テーブルが EL2 にインストールされるように書き換えられます。ブート中に、この保護は pKVM によって適用されます。

このアーキテクチャは、できれば EL3 ファームウェアとしてTF-Aの最新バージョンを使用することにより、PSCI をサポートする SoC に依存します。

Arm 用ファームウェア フレームワーク (FF-A) は、特に安全なハイパーバイザーの存在下で、通常の世界と安全な世界の間の相互作用を標準化します。仕様の主要な部分は、共通のメッセージ形式と基礎となるページの明確に定義されたアクセス許可モデルの両方を使用して、安全な世界とメモリを共有するためのメカニズムを定義します。 pKVM は FF-A メッセージをプロキシして、ホストが十分な権限を持たないセキュア側とメモリを共有しようとしていないことを確認します。

このアーキテクチャは、メモリ アクセス モデルを強制するセキュア ワールド ソフトウェアに依存しており、セキュア ワールドで排他的に所有されているか、FF を使用してセキュア ワールドと明示的に共有されている場合にのみ、セキュア ワールドで実行されている信頼できるアプリやその他のソフトウェアがメモリにアクセスできるようにします。 -A. S-EL2 を備えたシステムでは、メモリ アクセス モデルの適用は、安全な世界のためにステージ 2 ページ テーブルを維持するHafniumなどの Secure Partition Manager Core (SPMC) によって実行する必要があります。 S-EL2 のないシステムでは、TEE は代わりにステージ 1 ページ テーブルを通じてメモリ アクセス モデルを強制できます。

EL2 への SMC 呼び出しが PSCI 呼び出しまたは FF-A 定義のメッセージではない場合、未処理の SMC は EL3 に転送されます。ファームウェアは pVM 分離を維持するために必要な予防措置を理解しているため、(必然的に信頼できる) セキュア ファームウェアが未処理の SMC を安全に処理できることが前提となります。

仮想マシンモニター

crosvm は、Linux の KVM インターフェイスを通じて仮想マシンを実行する仮想マシン モニター (VMM) です。 crosvm のユニークな点は、Rust プログラミング言語と、ホスト カーネルを保護するための仮想デバイス周囲のサンドボックスの使用により、安全性に重点を置いている点です。

ファイル記述子と ioctl

KVM は、KVM API を構成する ioctl を使用して/dev/kvmキャラクター デバイスをユーザー空間に公開します。 ioctl は次のカテゴリに属します。

  • System ioctls は、KVM サブシステム全体に影響するグローバル属性をクエリして設定し、pVM を作成します。
  • VM ioctls は、仮想 CPU (vCPU) とデバイスを作成する属性をクエリして設定し、メモリ レイアウトや仮想 CPU (vCPU) とデバイスの数などの pVM 全体に影響を与えます。
  • vCPU ioctls は、単一の仮想 CPU の動作を制御する属性をクエリおよび設定します。
  • デバイス ioctl は、単一の仮想デバイスの動作を制御する属性をクエリおよび設定します。

各 crosvm プロセスは、仮想マシンのインスタンスを 1 つだけ実行します。このプロセスでは、 KVM_CREATE_VMシステム ioctl を使用して、pVM ioctl の発行に使用できる VM ファイル記述子を作成します。 VM FD 上のKVM_CREATE_VCPUまたはKVM_CREATE_DEVICE ioctl は、vCPU/デバイスを作成し、新しいリソースを指すファイル記述子を返します。 vCPU またはデバイス FD 上の ioctl を使用して、VM FD 上の ioctl を使用して作成されたデバイスを制御できます。 vCPU の場合、これにはゲスト コードを実行するという重要なタスクが含まれます。

内部的には、crosvm はエッジ トリガーのepollインターフェイスを使用して VM のファイル記述子をカーネルに登録します。その後、カーネルは、いずれかのファイル記述子に保留中の新しいイベントがあるたびに、crosvm に通知します。

pKVM には、新しい機能KVM_CAP_ARM_PROTECTED_VMが追加されており、これを使用して、pVM 環境に関する情報を取得し、VM に保護モードを設定できます。 --protected-vmフラグが渡された場合、crosvm は pVM の作成中にこれを使用して、pVM ファームウェアに適切な量のメモリをクエリして予約し、保護モードを有効にします。

メモリ割り当て

VMM の主な役割の 1 つは、VM のメモリを割り当て、そのメモリ レイアウトを管理することです。 crosvm は、次の表に大まかに説明されている固定メモリ レイアウトを生成します

通常モードのFDT PHYS_MEMORY_END - 0x200000
フリースペース...
ラムディスクALIGN_UP(KERNEL_END, 0x1000000)
カーネル0x80080000
ブートローダー0x80200000
BIOS モードの FDT 0x80000000
物理メモリベース0x80000000
pVMファームウェア0x7FE00000
デバイスメモリ0x10000 - 0x40000000

物理メモリはmmapで割り当てられ、そのメモリは VM に提供されて、 memslotsと呼ばれるそのメモリ領域にKVM_SET_USER_MEMORY_REGION ioctl を設定します。したがって、すべてのゲスト pVM メモリはそれを管理する crosvm インスタンスに帰属し、ホストの空きメモリが不足し始めるとプロセスが強制終了 (VM の終了) する可能性があります。 VM が停止すると、メモリはハイパーバイザーによって自動的に消去され、ホスト カーネルに戻されます。

通常の KVM では、VMM はすべてのゲスト メモリへのアクセスを保持します。 pKVM を使用すると、ゲスト メモリがゲストに提供されるときに、ホストの物理アドレス空間からマッピングが解除されます。唯一の例外は、virtio デバイスなど、ゲストによって明示的に共有されるメモリです。

ゲストのアドレス空間内の MMIO 領域はマップされないままになります。ゲストによるこれらの領域へのアクセスはトラップされ、VM FD 上で I/O イベントが発生します。このメカニズムは、仮想デバイスを実装するために使用されます。保護モードでは、ゲストは、偶発的な情報漏洩のリスクを軽減するために、ハイパーコールを使用してアドレス空間の領域が MMIO に使用されていることを認識する必要があります。

スケジュール設定

各仮想 CPU は POSIX スレッドによって表され、ホスト Linux スケジューラによってスケジュールされます。スレッドは vCPU FD 上でKVM_RUN ioctl を呼び出し、その結果、ハイパーバイザーがゲスト vCPU コンテキストに切り替わります。ホスト スケジューラは、ゲスト コンテキストで費やされた時間を、対応する vCPU スレッドで使用された時間として考慮します。 KVM_RUN I/O、割り込みの終了、vCPU の停止など、VMM によって処理する必要があるイベントがあるときに返されます。 VMM はイベントを処理し、 KVM_RUN再度呼び出します。

KVM_RUNの間、スレッドは、プリエンプティブルではない EL2 ハイパーバイザー コードの実行を除き、ホスト スケジューラによってプリエンプティブルなままになります。ゲスト pVM 自体には、この動作を制御するメカニズムがありません。

すべての vCPU スレッドは他のユーザー空間タスクと同様にスケジュールされるため、すべての標準 QoS メカニズムの影響を受けます。具体的には、各 vCPU スレッドを物理 CPU に関連付けたり、cpuset に配置したり、使用率クランプを使用してブーストまたは上限を設定したり、優先順位/スケジューリング ポリシーを変更したりすることができます。

仮想デバイス

crosvm は、次のような多数のデバイスをサポートします。

  • 複合ディスクイメージ用の virtio-blk (読み取り専用または読み取り/書き込み)
  • ホストとの通信用の vhost-vsock
  • virtio トランスポートとしての virtio-pci
  • pl030 リアルタイムクロック (RTC)
  • 16550a シリアル通信用 UART

pVMファームウェア

pVM ファームウェア (pvmfw) は、物理デバイスのブート ROM と同様に、pVM によって実行される最初のコードです。 pvmfw の主な目的は、セキュア ブートをブートストラップし、pVM の一意の秘密を取得することです。 pvmfw は、OS が crosvm でサポートされ、適切に署名されている限り、 Microdroidなどの特定の OS での使用に限定されません。

pvmfw バイナリは同じ名前のフラッシュ パーティションに保存され、 OTA を使用して更新されます。

デバイスのブート

次の一連のステップが、pKVM 対応デバイスのブート手順に追加されます。

  1. Android ブートローダー (ABL) は、pvmfw をそのパーティションからメモリにロードし、イメージを検証します。
  2. ABL は、ルート オブ トラストからデバイス識別子構成エンジン (DICE) シークレット (複合デバイス識別子 (CDI) およびブート証明書チェーン (BCC)) を取得します。
  3. ABL は、pvmfw のシークレット (CDI) の測定と DICE 導出を実行し、それらを pvmfw バイナリに追加します。
  4. ABL はlinux,pkvm-guest-firmware-memory予約メモリ領域ノードを DT に追加し、pvmfw バイナリの場所とサイズ、および前の手順で導出した秘密を記述します。
  5. ABL は制御を Linux に渡し、Linux は pKVM を初期化します。
  6. pKVM は、ホストのステージ 2 ページ テーブルから pvmfw メモリ領域のマップを解除し、デバイスの稼働時間全体にわたってホスト (およびゲスト) から領域を保護します。

デバイスの起動後、 Microdroidドキュメントの「起動シーケンス」セクションの手順に従って Microdroid が起動します。

pVMブート

pVM を作成する場合、crosvm (または別の VMM) は、ハイパーバイザーによって pvmfw イメージが設定されるのに十分な大きさの memslot を作成する必要があります。 VMM は、初期値を設定できるレジスタのリストでも制限されています (プライマリ vCPU の場合は x0 ~ x14、セカンダリ vCPU の場合はなし)。残りのレジスタは予約されており、hypervisor-pvmfw ABI の一部です。

pVM が実行されると、ハイパーバイザーはまずプライマリ vCPU の制御を pvmfw に渡します。ファームウェアは、crosvm が AVB 署名付きカーネル (ブートローダーまたはその他のイメージ) と未署名の FDT を既知のオフセットでメモリにロードしていることを期待します。 pvmfw は AVB 署名を検証し、成功した場合は、受信した FDT から信頼できるデバイス ツリーを生成し、その秘密をメモリから消去して、ペイロードのエントリ ポイントに分岐します。検証手順の 1 つが失敗した場合、ファームウェアは PSCI SYSTEM_RESETハイパーコールを発行します。

起動と起動の間に、pVM インスタンスに関する情報はパーティション (virtio-blk デバイス) に保存され、pvmfw のシークレットで暗号化され、再起動後にシークレットが正しいインスタンスにプロビジョニングされるようになります。