Apple Siliconで仮想マシン2台制限を回避する方法(2023年)
(khronokernel.com)- Apple SiliconベースのmacOSでは、Virtualization.framework で実行可能な macOS VMは最大2台に制限されており、これはmacOS使用許諾契約の条項に基づく
- 分析の結果、この制限は XNUカーネル内部の非公開変数
hv_apple_isa_vm_quotaによって管理されており、ブート引数で上書き可能であることが確認された - System Integrity Protection の
AppleInternalチェックを回避するため、開発用カーネル(Development Kernel) をビルド・起動する手順が使われる - 設定後、UTM、Viable、Parallels などで 最大9台のmacOS VM を同時実行することに成功した
- Appleがカーネル内部に VM制限の上書き機能を残していた点 が注目されており、今後は自動化ツールやカーネル拡張による改善の可能性が示されている
Apple SiliconのmacOS仮想マシン2台制限を解除する過程
- Apple Silicon搭載Macで Virtualization.framework を使ってmacOS仮想マシンを実行する際、最大2台までしか起動できない制限 が存在する
- この制限は macOSソフトウェア使用許諾契約(SLA)2.B.iii条項に従って設定されている
- この条項では、開発、テスト、macOS Serverの利用、非商用の個人用途に限り、最大2つのmacOSインスタンスの実行を許可している
- 分析の結果、この制限は ユーザー空間ではなくカーネル(XNU)の非公開領域 に実装されている
- Intelカーネルには同じコードはなく、Apple Siliconカーネルの
hv_vm_*関数群 が仮想化スタックを担当する hv_init()初期化コード内のhv_apple_isa_vm_quota変数 がVM数を管理しており、VM作成・削除時に増減処理される- カーネルには
hypervisor=およびhv_apple_isa_vm_quota=ブート引数が存在し、後者はVM制限を上書きできる
- Intelカーネルには同じコードはなく、Apple Siliconカーネルの
- リリースカーネルでは
hypervisor引数の代わりに、System Integrity Protection(SIP) のAppleInternalチェック によって制限されているCSR_ALLOW_APPLE_INTERNALフラグが有効な場合にのみhv_apple_isa_vm_quota引数が適用される- これを回避するため、Appleの開発用カーネル(Development Kernel) を起動する方法が使われる
開発用カーネルコレクションのビルド
- Apple Developerサイトから Kernel Debug Kit(KDK) をダウンロードしてインストールする必要がある
- KDKはホストmacOSのビルドと正確に一致していなければならず、不一致の場合はカーネル・kextのリンクや起動エラーが発生する可能性がある
unameコマンドでカーネルアーキテクチャを確認した後、kmutil createコマンドを使って 開発用カーネルコレクション(VirtualMachine.kc) を生成する- 例では macOS 14.0(ビルド 23A5301h)および T6020 カーネルを使用
--variant-suffix developmentオプションで開発用カーネルを指定し、複数のシステム拡張ストアを含める
開発用カーネルの起動設定
- Macを終了後、復旧モード(recoveryOS) で起動してターミナルから次の設定を行う
- System Integrity Protectionを無効化 (
csrutil disable) - ブート引数制限を解除 (
bputil --disable-boot-args-restriction) - カスタムカーネルコレクションを指定 (
kmutil configure-boot) - ブート引数を設定 (
nvramコマンドで渡す)kcsuffix=development: 開発用カーネルを起動hypervisor=0x1: 仮想化スタックの特殊機能を有効化hv_apple_isa_vm_quota=0xFF: VMの最大数を255に設定
- System Integrity Protectionを無効化 (
- 再起動後、
sysctl kern.osbuildconfigおよびnvram boot-argsで適用有無を確認できる
複数VMの実行結果
- 設定完了後、UTM、Viable、Parallels などのVirtualization.frameworkベースのソリューションでテストを実施
- M2 Pro MacBook Proで 同時に9台のmacOS VM を実行することに成功
- システムはなおテスト可能な水準で動作した
機能追加時期と内部構造
- macOS 12 Monterey から
hv_apple_isa_vm_quotaブート引数がVirtualizationスタックとともに追加された- その後のバージョン(macOS Sonomaを含む)でも
AppleInternalチェックは依然として存在する - AppleがXNU内部に複数の非公開機能を維持していることが確認された
- その後のバージョン(macOS Sonomaを含む)でも
OSアップデート時の注意事項
- カスタムカーネルコレクションを使用すると 自動OSアップデート機能が無効化 される
- アップデート後にエラーが発生するため、標準のカーネルコレクションへ復元 する必要がある
- 復旧モードで
bputilを使って新しいブートポリシーを作成すれば標準カーネルに戻せる - 例:
bputil --full-securityまたは--disable-boot-args-restrictionオプションを使用
まとめと今後の改善アイデア
- AppleのVM制限実装方式を確認し、非公式ではあるが制限解除方法 を実験的に検証した
- Virtualizationチームが公式に文書化していないにもかかわらず、VM制限の上書き機能をカーネルに残していた点 が注目される
- 今後の改善構想
- KCビルドと起動の自動化ツール の開発
- ホストごとの開発用カーネルコレクションの自動生成と復旧モード設定を支援
- カーネル拡張(kext) を通じた
hv_apple_isa_vm_quota変数上書き機能の実装- 開発用カーネルを起動せずに制限解除できる可能性を探る
- KCビルドと起動の自動化ツール の開発
- 次の研究テーマとして、Apple Silicon VMのDEP登録とシリアル番号オーバーライドの可能性 を探る予定である
1件のコメント
Hacker Newsのコメント
すべてのMacに一律で適用されるこういう制限はあまりにも不合理
より高性能なMacを買ったなら、より多くのmacOSインスタンスを仮想化できるべき
たとえばM5は2台、M5 Proは4台、M5 Maxは8台程度に制限するほうが合理的だと思う
ハードウェア性能が自然な限界になるのだから、ユーザーは自分で止まるはず
低価格Mac VPSサービスを防ぐための措置である可能性が高い
Hyper‑Vはハードウェアが耐えられるなら最大1024台のVMを同時実行できる
自分の小型Windows ARMノートでも4台は問題なく動かせる
openclawをテストしようとしてVMを動かしたら、iCloudとApp Storeへのアクセスが制限されていて面食らった
Mykola Grymalyukがこのブログ記事を書いてから2年後にAppleへ入社したのは興味深い
「英雄として死ぬか……」というミームを思い出す
M3以降ではHypervisor.framework / Virtualization.frameworkを使ってnested VMを動かせる
これで制限を回避できるならかなり面白そう
macOSは1段階までしかできないので、macOSゲストの中でさらに別のmacOSゲストを起動することはできない
面倒なので誰か実験してほしい
Appleがなぜこんな制限をかけたのか本当に気になる
ハードウェア販売がソフトウェア開発を支えているので、ハードウェアを買っていない人にmacOSを使ってほしくない
ユーザーの自由よりAppleがコントロールを維持することが優先される
カスタムカーネルをコンパイルして起動し、GUIまで立ち上げられるのは驚き
記事そのものはとても興味深いが、こうした恣意的な制限のあるプラットフォームを開発用途に使うのは奇妙
高性能ハードウェア目当てで使う開発者は多いが、macOSはずっと「ほぼLinuxだが、iTunes中心の会社が支配するOS」だった
Apple Siliconでカスタムカーネルコレクションを使うと自動OSアップデートができなくなるらしい
でもこれはむしろ隠れた恩恵かもしれない
lumeでもこれが動くのか気になる
現在は似たような制限がある
lumeはAppleのVirtualization.frameworkを包む薄いラッパーだと理解している
SIPを無効にしてブート引数を設定すれば、カスタムカーネルなしでも可能だと聞いた
AppleがVMを2台に制限したって?
他のOSゲストは制限なく実行できる