プログラミング
Asahi Linux Progress Report 7.2
Progress Linux 7.2 – Asahi Linux (asahilinux.org)
要約
Asahi Linuxプロジェクトは、Apple SiliconデバイスにおけるLinuxの電力管理の進捗について報告しています。特に、CPUコアの省電力化におけるWFI(Wait For Interrupt)命令やPSCI(Power State Coordination Interface)の利用、そしてApple独自のハードウェア仕様への対応が課題となっています。UEFI Runtime Serviceを利用した新しいPSCI実装や、M4シリーズでのコア状態保持問題への対応についても触れられています。
全文翻訳
ブログ / 進捗レポート: Linux 7.2
進捗レポート: Linux 7.2
Linux 7.2 がリリースされました!非常に速かったです。いつもの Asahi Linux の進捗レポートに飛び込みましょう。今日は多くの興味深い開発についてお話ししますので、お茶でも用意して楽しんでください。
Think Different… again
Apple Silicon プラットフォームの電力管理インフラストラクチャは複雑です。SMC、PMGR、PMP など、以前にもこのブログで取り上げたことのある複数のハードウェアブロックに責任が分散されています。これらのブロックをサポートすることは電力使用量にとって重要ですが、バッテリー寿命を改善する上での最大の障害の1つは、アプリケーションコア自体でした。
CPU コアを「スリープ」させるには複数の方法があり、それぞれが特定のコンテキストで使用されるべきです。ARM CPU コアをスリープさせる最も基本的な方法は、Wait For Interrupt (WFI) 命令を使用することです。これは、割り込みソースからの割り込みによって起動されるまで、コアに処理を停止するように指示します。これにより、コアがコードを実行するのを停止するため電力を節約できますが、コアは電源がオンのままで、作業を非常に迅速に再開できるだけの状態を保持します。そのため、WFI は通常、実行中のシステムでコアを一時停止するためにのみ使用されます。Apple のコアには「ディープ」WFI モードが含まれており、状態を失う代わりにコアのより多くの部分をシャットダウンします。当社のダウンストリーム cpuidle ドライバーは、このモードで WFI を設定し、コアの状態を保存してから WFI ループを発行することで動作します。
このようなベンダー固有の電力管理の奇妙な点は非常に一般的です。幸いなことに、カーネルメンテナーにとって、それらを処理する標準的な方法があります。それが Power State Coordination Interface です。PSCI は、オペレーティングシステムがシステムファームウェアによって実装された CPU コア電力管理機能の定義されたセットを呼び出すことを可能にする標準インターフェースを定義しており、スリープの準備を含みます。
Linux カーネル内にベンダー固有の電力管理ハックが広がるのを避けるため、arm64 アーキテクチャ固有コードのメンテナーは、すべてのアップストリームハードウェアが電力管理に PSCI を使用することを義務付けています。そのため、Apple 固有の cpuidle ドライバーをアップストリームできません。では、なぜまだそれを使用しているのでしょうか?
PSCI は、カーネルからファームウェアへの呼び出しをディスパッチするための「コンジット」を定義しています。カーネルで現在サポートされている2つのコンジットは、SMC (Secure Monitor Call) および HVC (Hypervisor Call) 命令であり、これらはより高い例外レベルへの実行を譲渡するために使用されます。Linux カーネルは EL2 で実行されることを期待しており、これは PSCI 呼び出しが EL3 で実行されているファームウェアに譲渡する必要があることを意味します。ただし、Apple のコアは EL3 を実装していません…
カーネルがすでに EL2 で実行されており、通信する EL3 ファームウェアがないため、私たちは行き詰まっています。Linux は EL3 に実行を譲渡する場所がないため、SMC または HVC 命令を発行できません。これは、PSCI を利用できないことを意味します。CPU コアを適切に電力管理できることは、バッテリー寿命と効率にとって不可欠であるため、現状維持では済まされません。1つの迅速で汚い解決策は、m1n1 がカーネルを EL1 にロードし、EL2 で PSCI 実装をホストすることです。これは理論的には機能しますが、仮想化などの多くのアーキテクチャ機能を壊すことにもなります。他に何かできるはずです…
考えてみれば、m1n1 は Apple Silicon 用の私たち自身のファームウェアのようなものです。mBoot (旧 iBoot) はそれを EL2 で開始し、そのジョブを実行してから、それにアタッチされたペイロードにジャンプします。m1n1 は自身のためにメモリを予約せず、常駐する必要のあるコードも持っていないため、そのペイロードはそれらのメモリを再利用して上書きすることができます。
本番の Asahi Linux システムでは、m1n1 はカーネルを直接ロードするのではなく、U-Boot をロードします。これは、U-Boot の UEFI 実装を利用するためであり、ディストリビューションやユーザーが好きな標準 UEFI ブートローダー(GRUB、systemd-boot など)を使用できるようにするためです。UEFI は、Runtime Services という別の機能も提供します。古い BIOS 割り込みのように、UEFI Runtime Services はオペレーティングシステムがシステムファームウェアに由来するコードにアクセスする方法を提供します。
Arm が公開している PSCI 標準を読むと、API が特定のコンジットを参照せずに意図的に定義されており、SMC と HVC のみを例としてリストしていることに気づくでしょう。これを広く解釈すれば、仕様では他のコンジットも許可されていると結論付けることができます…
この目的のため、Sven は UEFI Runtime Service ベースの PSCI コンジットの実装に取り組んでいます。m1n1 のメモリ領域は他のファームウェア領域のように切り分けられるため、カーネルが同じ例外レベルで実行されていても、PSCI サービスのためにカーネルがそれにコールバックできるようになります。Sven はすでに m1n1 を変更してメモリを予約し、PSCI 実装を残しており、カーネルで使用を可能にするパッチはすでに RFC としてメーリングリストにあります!
Think Different はもうやめてください
cpuidle の状況が最近まで進展がなかったことを考えると、何らかの出来事がこの分野での作業を触媒したと仮定するかもしれません。それは正しいでしょう。
ARM 仕様では、WFI ループ内のコアはすべての状態を保持することが義務付けられています。これは Apple Silicon のデフォルトモードではありません。M1 から M3 シリーズ SoC では、状態保持はコアごとにチキンビットを使用して設定できます。
言及する価値のない多くの理由により、Apple は現在、mBoot で各コアのチキンビットを設定し、M4 シリーズから始まるそれらを制御するレジスタをロックダウンしています。これにより、m1n1 の作業量がわずかに減るため、私たちの生活は少し楽になりますが、低レベルの CPU 動作を微調整することもできなくなります。これは特に M4 では問題です。WFI を呼び出すとコアが状態を失い、実行中のものをクラッシュさせるためです。
Yurkea は M4 の起動作業中にこれを noticed し、アイドルループの動作を設定可能にするカーネルコマンドラインパラメータを追加しました。このパラメータにより、カーネルにアイドルループでコアをどのように駐車するかを伝えることができます。これには、基本的な no-op ループを実行することも含まれます。これにより、ドライバーがロードされる前に、M4 マシンが初期カーネル初期化中にクラッシュするのを防ぎます。ドライバーが引き継ぐと、WFI を発行する前に失われた状態を保存します。これを有効にするパッチはすでに linux-next にあります。
彼らは Think Different を止めないでしょう
Apple はプラットフォームセキュリティにおける評判を非常に真剣に受け止めています。そのため、最も洗練された攻撃者以外には、エコシステム内の脆弱性を悪用することを不可能にする機能に多くのエンジニアリング努力が注がれています。そのような機能の1つが、Secure Page Table Monitor、または SPTM です。伝統的に、オペレーティングシステムカーネルはメモリ管理に直接責任を負っていました。これには、メモリ割り当て、物理アドレスへの仮想マッピング、および MMU/IOMMU 管理の処理が含まれます。これらの操作を担当するコードの脆弱性は、攻撃者にプラットフォームの全アドレス空間へのアクセス権を与える可能性があります。言い換えれば、あなたは終わりです。
当然、これはメモリ管理コードを攻撃者の一般的なターゲットにしますが、そのジョブは基本的に安全ではない(アプリケーションはほぼ何にでも任意の割り当てを要求したい場合があります)ため、正しくロックダウンするのは非常に困難です。
何年も前に、Apple は XNU に Page Protection Layer を導入しました。PPL は Apple のハードウェアセキュリティ機能を使用して、ハードウェアレベルでページテーブル管理をカーネルの残りの部分から分離します。これは非常によく機能しますが、攻撃者は最終的に追いつき、PPL 内でシステム全体へのフルアクセスを許可する経路を見つけました。
Apple は過去に IOMobileFramebuffer でも同様の問題を抱えていました。以前のブログ投稿で述べたように、Apple は(主に)IOMFB を DCP のファームウェア内に、IOMMU の背後に配置することで問題を解決しました。macOS ユーザー空間や XNU の何も、定義された IPC 関数セットを経由しない限り、それに到達できません。このアプローチからインスピレーションを得て、PPL は最終的に SPTM になりました。SPTM は PPL を取り、それを Apple の Guarded Execution Framework (GXF) の中に配置します。GXF は、標準の ARM64 EL1 および EL2(GL0 はありません)と並行して実行される例外レベルのセットです。GXF には S も付属しています。