2024.10.10
将来は卵1パックの価格が2倍に? 多くの日本人が知らない世界の新潮流、「動物福祉」とは
リンクをコピー
記事をブックマーク
佐伯 学哉氏:入門セッション3つ目は『Armの仮想化支援機構』についての入門セッションです。どうぞよろしくお願いします。
本発表のスタートとゴールです。VMwareとかQemuとか使ったことあるけど仮想マシンの仕組みなんも知らんというところがまずスタートになっています。
1個目のゴールは、最近のVMのざっくりした仕組みとハードウェア仮想化支援とは何かということがわかること。そしてその話のあとに実際にArmの仮想化支援機構の概要を説明し、Armの仮想化支援機構の概要がわかるようになるというのが2つ目のゴールです。
最後におまけとして、Apple Hypervisor FrameworkというmacOSの組み込みのハイパーバイザーフレームワーク、KVMみたいなやつがあるんですけど、それのMac対応の話をします。
まず自己紹介です。@nullpo_head(ヌルポヘッド)と言います。本名は佐伯学哉です。最初のオープニングでも言ったんですけどソフトウェアエンジニアをやっています。MS(*)でWebエンジニアをやっていて……。仕事はWebのほうで低レイヤーのほうじゃないです。LegalScapeというベンチャーで副業のエンジニアもやっています。(* 発表当時。2021年現在、サンフランシスコのサービスメッシュに関するスタートアップ、Tetrate.io (https://www.tetrate.io/) に所属。)
過去のおもしろげなプロジェクトとしては、CPU実験でXv6をMIPSと自作CPUのアーキテクチャに移植したやつとか。未踏の2016年では、Noahという仮想化を乱用すればWSL1をカーネル空間じゃなくてユーザー空間だけで誰でも実装できるぞという手法をやりました。
VEEという著名な仮想化に関する国際会議で論文が通っていて、その話を2020年の8月22日のContainer Runtime Meetupでやるので、興味がある方はどうぞ聞いてください。それから小ネタとして、WSLでWindows Helloでsudoするやつとか書いているので、ぜひ使ってください。
さっそく本題に入っていこうと思います。まずハードウェア仮想化支援についてです。ハードウェア仮想化支援ってよく聞くんですけど、いったい何なんでしょう? という話から始めます。
ハードウェア仮想化支援とは、いわゆる仮想マシンの基盤技術にあたるものです。ここで言う「いわゆる仮想マシン」とは、ソフトウェアによって仮想的なハードウェア上で動く、別のOSをエミュレートすることとします。ただし別のOSというのは語弊がありまして、OS以外にいろいろなものが動き得るんですけれども、話を簡単にするために今回は別のOSだという話で統一していきますね。
具体的なソフトウェアとしてはQemu-KVM、VMware、そしてMacのParallelsとか、WindowsのHyper-Vとかがあります。現代の仮想マシンは、ハイパーバイザーを通じて、こうしたハードウェア仮想化支援機構を利用しています。
ハイパーバイザーというのはKVMとかHyper-Vのことなんですけど。仮想化支援機構としてはIntelのVT-Xとか、AMD-V……ヴイなんですかね、これ。読み方。それからArmのArm Virtualization Extensionsなどが存在します。
ここで仮想マシンの解剖というか、仮想マシンとは何なのかという話からします。現代の仮想マシンをざっくり2つに分けるなら、CPUの仮想化とハードウェアの仮想化に分かれます。CPUというのはメモリとか割り込みも含んでいて、ハードウェアというのは例えばディスクとかNIC、ネットワークカードとかですね。
このうちCPUの仮想化が重要でして、仮想マシンのコアの部分と言うことができます。CPUの仮想化とは何なのかと言うと、ソフトウェア的に別の仮想的なCPUをエミュレートすることだと言えます。この上でゲストOSがブートするのがいわゆる仮想マシンです。
一番わかりやすいCPUの仮想化の方法は、機械語のシミュレータを書いてしまうことです。例えばLinux kernelのバイナリがあったら、その機械語を1個1個読んでいってちまちまx86の状態をシミュレーションしていく。エミュレーションしていくっていう方式ですね。
性能がかなり悪いんですけど、これはわかりやすくたしかに仮想的なCPUができます。この方式で作られたソフトウェアがBochsというものですね。自作OSをする人はけっこう知っているやつです。
このCPUの仮想化支援機構……このような仮想CPUを作る際に1個1個シミュレーションをしていたらかなり効率が悪い。
実はCPUのハードウェア仮想化支援機構というものを使うと大半の命令はいちいちインタプリタで解釈する必要はなくて。実際に直接CPU上で実行してしまえばよくて。仮想化の必要がある命令というのはいくつかだけあって、そういう命令だけトラップしてKVMなどのハイパーバイザーで仮想化の必要がある命令をエミュレーションすることで高速な仮想CPUを実現します。
具体的に仮想化の必要がある命令とはどんなものかと言うと、例えばディスクのアクセス。IOとかは仮想化してディスクをエミュレーションしなければならないので、そのままCPUで実行するだけではうまく動きません。
それを踏まえたうえで最近のVMの仕組みを考えます。この図で真ん中にCPUがあります。これが最近のCPUだということにしまして、Qemu-KVMでゲストOSとしてLinux kernelを動かす場合を考えます。
仮想化された最近のCPUでは、ハードウェア仮想化支援機構のおかげで仮想CPUというものができていて、その中でゲストOSのLinuxとそのゲストOSのアプリケーションが存在して動いているわけですね。
この状態でQemu-KVMがゲストOSを動かすときに何をしているかと言うと、まずQemuは大半の命令をこの実CPUの上でそのまま実行しています。なのでKVMに対して仮想CPUでLinux kernelの実行をしてくれという要求を送信します。
するとKVMはハードウェア仮想化支援機構を利用して仮想CPUを実行します。すると仮想CPUが実行してくれて、このとき仮想CPUの中のゲストOS、ゲストLinux kernelとゲストLinux kernelのアプリとかの状態をどこかのメモリから持ってきて、自分の実行状況をその仮想化したものに変えて、そのまま中で実行してくれます。x86とかではこういうことがVMENTRYと呼ばれますね。
中でゲストプロセスがシステムコールなどを叩いたら、中のゲストOSのLinuxが対処します。どんどんどんどん動いていくんですけど、あるときシステムコールとかの影響でゲストOSのLinuxがデバイスIO、例えばディスクアクセスを発行しましたとしましょう。こういうのはあとで説明するセンシティブ命令と呼ばれます。このときハードウェア仮想化支援機構を使ったCPUは、このディスクIOをトラップして、ディスクIOを要求していますということをVMEXITという仕組みを通じてKVMに知らせます。
するとKVMは、ディスクのエミュレーションが必要らしいということを今度はQemuに教え直します。これはエミュレーションが必要な命令なので、ここでQemuがなにか〇〇させるディスクとかの動きを実際にデバイスシミュレーションして、その結果をまた同じくVCPUを実行するかたちで返すことになります。
これが現代の、おおまかな最近の仮想化の仕組みで、こうやって高速にゲストOSを動かすことができます。
さて、ここで先ほどから仮想化の必要がある命令ということを言っているんですけれども、具体的には仮想化の必要がある命令とは何だろうという話です。これはテクニカルタームでセンシティブ命令と呼ばれます。センシティブ命令とは仮想CPU上では実CPUと動作を変えなければいけない命令のことと定義できます。
これがちょっと堅くてわかりづらい定義なのですが、要は仮想CPUが自分を実マシン上のCPUだと思い込むために動作を細工する必要がある命令のことです。
例えばなんですけど、CoreファミリーCPU上でPentiumCPUマシンをエミュレートすることを考えます。
x86のCPUには、例えばCPUIDという命令があるんですが、この状態で普通にCPUIDの本当の値を返してしまうとCoreファミリーだという値が返ってしまうんですね。なのでこの値をPentiumのものに書き換えて仮想マシンに返してあげる必要があります。
CPUの仮想化支援機構はそういうセンシティブ命令をトラップする仕組みだと言うことができます。この仮想化支援機構を使ったCPUでは、ハイパーバイザーは普通の命令はCPUに直接実行させて、大抵の命令は直接実CPUで命令して、センシティブな命令だけ命令エミュレーションすればいいということができます。
またさらに最近の仮想化支援機構では、典型的なセンシティブ命令はハイパーバイザーのエミュレーションの力を借りずともCPUで完結することもできるようなものが多いです。例えばメモリマッピングの変更とかはハイパーバイザーがなにかしなくてもCPUの中で完結するIntel EPTとかが存在します。
ここでセンシティブ命令の話をしていたんですが、実はもともとすべてのセンシティブ命令がOSとかの特権レベルをトラップできるようなアーキテクチャなら、特別な仮想化支援機構がなくても効率的に仮想化を実現できるという話がありまして、これはPopekとGoldbergの仮想化要件という名前で知られています。
なんでこんな要件が満たされていたら仮想化が実現できるのかというと、ユーザーレベルでゲストOSを直接実行してセンシティブ命令をホストがトラップすれば、ハイパーバイザーが実現できてしまうからなんですね。
どういうことかと言うと、システムコールや割り込みがゲストOSのアプリケーションを発行したとします。ゲストOSのアプリケーションはユーザーレベルで動いているんですけど、本当はこのとき当然センシティブ命令はすべてトラップできるので、システムコールは一旦ホストカーネルに飛んでいきます。
ホストカーネルが今度はそれを受けてゲストOSのアプリケーションからゲストOSに割り込まれたようにうまく書き換えてゲストOSのカーネルにプロキシしてあげるとシステムコールのフックを実現できます。
ほかにも例えば、ゲストOSから権限レベルの読み取りがきたら、本当は今ユーザーレベルで動かしているんだけれど、特権レベルだと回答する必要があるんですね。こういうことをやってあげると仮想化されたCPUが実現できます。
ちなみにこの権限レベルの読み取りはx86だとセンシティブ命令なんですけど、特権レベル命令ではない。つまりOSがトラップできないので、これが実現できないです。具体的にはCSレジスタを見ると、今特権レベルで動いているのかユーザーレベルで動いているのかがわかるんですが、x86だとトラップできないので、それを書き換えられないんですね。ただし現代の仮想化支援機構はPopekとGoldbergの仮想化要件だけじゃなくて、こういう処理に相当することを全部ハードウェアがやってくれることもあるからもっと便利で高速です。
現代のハードウェア仮想化支援機構の簡単なまとめです。現代の仮想マシンは高速なCPUの実行のためにハードウェア仮想化支援機構を利用しています。CPUの仮想化支援機構は大半の命令を実際にCPUで直接実行しますが、センシティブ命令をトラップしてハイパーバイザーに処理を任せることで高速な仮想CPUを実現できます。
PopekとGoldbergの仮想化要件として、すべてのセンシティブ命令が特権命令であるようなアーキテクチャは、特別な支援機構がなくても割合高速な仮想化CPUが実現できることが知られています。
ただし現代の仮想化支援機構はハードウェアで仮想化が完結するセンシティブ命令がたくさんあって、ただの仮想化可能なCPUアーキテクチャよりもっと効率的に実現できるようになっています。
(後半へつづく)
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略