Más contenido relacionado
La actualidad más candente (20)
Similar a Kernel vm#9 powerkvm-dist-20131208 (20)
Kernel vm#9 powerkvm-dist-20131208
- 2. 特記事項および商標
• 本⽂文書の内容は、特に記載の無い限り、2013年年8⽉月27⽇日現在に公開されている⽂文書に基づいています。
• 本⽂文書において、IBM 製品、プログラム、およびサービスについて⾔言及する場合がありますが、このことはこのような IBM 製品、プログラ ム、
およびサービスが IBM が企業活動を⾏行行っているすべての国で使⽤用できることを意味するものではありません。本⽂文書で、IBM 製品、プログラ
ム⼜又はサービスに⾔言及する部分があっても、このことは当該製品、プログラム、またはサービスのみが使⽤用可能であることを意味するものでは
ありません。これらのIBM製品、プログラム、またはサービスに代えて、IBM の知的所有権を侵害することのない機能的に同等のプログラムを
使⽤用することができます。
• 本⽂文書に記載されている情報の使⽤用または⼿手法の実施は、お客様の評価および使⽤用している動作環境への統合能⼒力力にしたがって、お客様の責任
で⾏行行っていただきます。記載されている情報はいずれもIBMにより、特定の状況における正確さは確認されているはずですが、いかなる環境に
おいてもそれと同じ、あるいは同様な結果が得られるとは限りません。お客様独⾃自の環境において、これらの⼿手法を適⽤用する場合は、お客様の
責任で⾏行行っていただきます。
• 商標
2
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
AIX は International Business Machines Corporation の登録商標
AIX 5L はInternational Business Machines Corporation の商標
AIX 6 はInternational Business Machines Corporation の商標
AIX 7 はInternational Business Machines Corporation の商標
IBM はInternational Business Machines Corporation の登録商標
UNIX は、 The Open Group の⽶米国ならびに他の国における登録商標
PowerPC は International Business Machines Corporation の登録商標
POWER4 は International Business Machines Corporation の商標
POWER5 は International Business Machines Corporation の商標
POWER6 は International Business Machines Corporation の商標
POWER7 は International Business Machines Corporation の商標
IBM System は International Business Machines Corporation の商標
IBM eServer は International Business Machines Corporation の商標
Power Systems は International Business Machines Corporation の商標
pSeries は International Business Machines Corporation の商標
BladeCenter は International Business Machines Corporation の商標
IBM i5/OS は International Business Machines Corporation の商標
Systems Director VMControl は International Business Machines Corporation の商標
IBM Systems Director Active Energy Managerは International Business Machines Corporation の商標
Intel, Pentium は Intel Corporation の⽶米国およびその他の国における登録商標
Linux は、Linus Torvalds の⽶米国およびその他の国における登録商標
その他、本⽂文書で使⽤用するシステム名、製品名、会社・団体の名称はそれぞれ各社の商標または登録商標です
2013/12/16
© 2013 IBM Corporation
- 3. ⾃自⼰己紹介
•
•
•
•
名前: 織 学 (おり まなぶ)
Twitter: @orimanabu
所属: ⽇日本IBM
仕事: LinuxとかOSSとかをいじっているエンジニア
– 本業はサーバー屋さん
• 表立った活動...
– PostgreSQL on ppc64 でのスケーラビリティ改善
– http://www.slideshare.net/orimanabu/pgcon2012ori20120224
PostgreSQL 9.2 release notes
http://www.postgresql.org/docs/9.2/static/release-‐‑‒9-‐‑‒2.html
© 2013 IBM Corporation
- 6. x86 の仮想化
• 古典的な “仮想化可能” (PopekとGoldbergの
仮想化要件)
– 理理想的なシステムの仮定
• システムに影響を及ぼすセンシティブ命令令は全
て特権命令令
仮想マシンをユーザー権限で実⾏行行することで、
センシティブ命令令をトラップ可能
すべての命令令
特権命令令
センシティブ命令令
– センシティブでない命令令は直接 CPU で実⾏行行
– センシティブな命令令はトラップしてエミュレー
ション
• x86 の実際
– 昔...気合で頑張る
• ⼿手で明⽰示的に書き換える (Xen)
• コンパイル時に⾃自動的に書き換える (LilyVM)
• 実⾏行行時に⾃自動的に書き換える (VMware)
すべての命令令
特権命令令
センシティブ命令令
– 今...仮想化専⽤用命令令が追加された!
• Intel-‐‑‒VT
• AMD-‐‑‒V
6
2013/12/16
© 2013 IBM Corporation
- 7. Intel の仮想化⽀支援機能
• VMX root mode
– ハイパーバイザーモード
• VMX non-‐‑‒root mode
– ゲストモード
ハイパーバイザー
ゲスト
User
User
VMEntry
Priviledge
Priviledge
VMExit
User
User
センシティブ命令
Priviledge
Priviledge
トラップ!
7
2013/12/16
© 2013 IBM Corporation
- 8. KVM
• KVM: Kernel-‐‑‒based Virtual Machine
• Intel-‐‑‒VT/AMD-‐‑‒V 必須
• Qemu による /dev/kvm への ioctl(2)
によってハイパーバイザーに制御が移る
• Qemu は基本的に、実 CPU 上で仮想マ
シンを直接実⾏行行する
• 仮想マシンの仮想デバイスへの I/O は
Qemu がエミュレート
ハイパーバイザー
User
Program
Qemu
ioctl
Linux
Kernel
ゲスト
センシティブ命令令
Guest
Kernel
KVM
vmlaunch
vmresume
8
2013/12/16
© 2013 IBM Corporation
- 10. 仮想マシンで I/O を発⾏行行すると...
ハイパーバイザー
⑤ どのハードウェアに I/O が
来たかを判断してエミュレート
User
Program
Qemu
⑥ I/O が終わったら
ioctl でゲストに処理理を戻す
④ I/O なので
Qemu に処理理を移す
① I/O 発⾏行行
⑦ vmresume
Linux
Kernel
2013/12/16
Guest
Kernel
KVM
③ 遷移理理由を特定
10
ゲスト
② I/O 命令令をトラップして
VMX root mode に遷移
© 2013 IBM Corporation
- 12. POWER Architecture とは
• POWER: Performance Optimized With Enhanced RISC
• RISC プロセッサー
–
–
–
–
–
–
命令令⻑⾧長は固定
ロード・ストア命令令によるメモリアクセス
多くの汎⽤用レジスタ
Memory mapped I/O
Power ISA で定義
複数のカテゴリー
Blue Gene
Wii
• Server (Book 3s)
• Embedded (Book 3e)
Playstation3
• 利利⽤用形態
–
–
–
–
–
12
サーバー、スパコン
ルータ
RAID コントローラ
ゲーム端末
⽕火星のコンピュータ
2013/12/16
Pathfinder
Spirit
Phoenix
© 2013 IBM Corporation
- 13. Power Instruction Set Architecture
•
PowerPC Architecture Book
– v2.01
• http://cseweb.ucsd.edu/classes/wi07/cse240b/Assignments/es-‐‑‒archpub1.pdf
• http://cseweb.ucsd.edu/classes/wi07/cse240b/Assignments/es-‐‑‒archpub2.pdf
• http://cseweb.ucsd.edu/classes/wi07/cse240b/Assignments/es-‐‑‒archpub3.pdf
– v2.02
•
• http://www.ibm.com/developerworks/systems/library/es-‐‑‒archguide-‐‑‒v2.html
Power ISA
– v2.03
• https://www.power.org/documentation/power-‐‑‒isa-‐‑‒version-‐‑‒2-‐‑‒03/
– v2.04
• https://www.power.org/documentation/power-‐‑‒isa-‐‑‒version-‐‑‒2-‐‑‒04/
– v2.05
• https://www.power.org/documentation/power-‐‑‒isa-‐‑‒version-‐‑‒2-‐‑‒05-‐‑‒2/
– v2.06 Revision B
• https://www.power.org/documentation/power-‐‑‒isa-‐‑‒version-‐‑‒2-‐‑‒06-‐‑‒revision-‐‑‒b/
– v2.06 Revision B Addendum
• https://www.power.org/documentation/power-‐‑‒isa-‐‑‒version-‐‑‒2-‐‑‒06-‐‑‒revision-‐‑‒b-‐‑‒addendum/
– v2.07
• https://www.power.org/documentation/power-‐‑‒isa-‐‑‒version-‐‑‒2-‐‑‒07/
13
2013/12/16
© 2013 IBM Corporation
- 15. PowerPC やばげ
In cores, IBM's Power dominates in networking and comms,
but Intel and ARM are on the rise. (Source: Linley Group)
In chips, Freescale dominates in networking and comms,
but will lose some share to Intel. (Source: Linley Group)
http://www.eetimes.com/document.asp?doc_̲id=1262633
15
2013/12/16
© 2013 IBM Corporation
- 19. “Server” vs “Embedded”
• Server (Book 3s)
– MMU
• hardware walked hash table
• Real mode (MMU disabled)
• Segmentation differenciates address space
– 割り込みハンドラは固定アドレスに配置
– 仮想化機能 (sPAPR)
• 仮想化⽤用の特権モード
• 仮想化⽤用の命令令 (hypervisor call)
POWER は「Popek と
Goldberg の仮想化要
件」を満たす仮想化支
援機能を持っています
• User mode
• Supervisor mode
• Hypervisor mode
• Embedded (Book 3e)
– MMU
• Software controlled TLB
– On-‐‑‒chip array, no hardware page walker
• No real mode
• PID register differenciates address space
– 割り込みハンドラはプログラマブルなアドレスに配置可能
– 仮想化機能 (ePAPR)
19
2013/12/16
© 2013 IBM Corporation
- 20. メモリ管理理
• 2 段階の変換
– Effective address ⇒ Virtual address ⇒ Real address
• Effective ⇒ Virtual
–
–
–
–
OS 環境下 (supervisor) で制御
SLB
粗い粒粒度度: 256MB or 1TB
Linuxでは、プロセスごとの仮想メモリ空間の提供に使⽤用
–
–
–
–
ハイパーバイザーで制御
MMU hash table
1 区画 1 ハッシュテーブル
複数ページサイズのサポート: 4KB, 64KB, 16MB, 16GB
• Virtual ⇒ Real
20
2013/12/16
© 2013 IBM Corporation
- 22. PowerVM とは
• 現在の Power System における仮想化の仕組み
– 旧称 Advanced Power Virtualization
– HMC (Hardware Management Console) による統合管理理
– ファームウェアに実装されたハイパーバイザー (Power Hypervisor, PHYP, pHyp)
• 準仮想化
– 全ての OS はハイパーバイザー前提 (AIX, Linux, IBM i)
– OS ⇔ ハイパーバイザー間のインターフェースは “PAPR” で定義
• POWER Architecture Platform Requirements
– 特権操作は Hypervisor Call (Hcall) によりハイパーバイザーへ
• 仮想マシン = 論論理理区画 (LPAR, Logical Partition)
22
2013/12/16
© 2013 IBM Corporation
- 23. PowerVM の特徴
• ファームウェアによるLPAR(論論理理分割)= 仮想マシン
• 動的なリソース割当変更更が可能なDynamic Logical Partitioning
•
•
•
•
– CPU、メモリ、アダプター
1/100 単位のCPU割当が可能なMicro-‐‑‒Partitioning
稼働中に物理理マシン間の移動が可能なLive Partition Mobility
I/O仮想化を提供する Virtual I/O Server (VIOS)と仮想イーサネット
x86 32ビット Linuxアプリケーションを無修正でPOWER上で実⾏行行でき
る Lx86
– Transitive 社の技術
• Rosetta (Intel Mac で PowerPC コードを動かす機能) も同じ
– IBM が Transitive を買収 ⇒ Lx86の誕⽣生 ⇒ 闇に葬り去られる...
23
2013/12/16
© 2013 IBM Corporation
- 24. Power7 LPAR
• pHyp が hypervisor mode で稼働
– ハイパーバイザーで制御すること
• 各区画がどのページのメモリを使い、どの I/O デバイスにアクセスするか
– MMU hash table の操作は hypervisor mode のみ
• 思想
• どの割り込みをゲストで処理理して、どの割り込みをハイパーバイザーで処理理するか
• 各区画に割り当てるタイムスライス (HDECR レジスタ)
– エミュレーションではなくパーティショニング
– 完全仮想化ではなく準仮想化
– PowerVM で実現できないこと
• Processor version register
• Priviledged instructionsn and registers
– あるコア上の全ての SMT スレッドは同じ区画で実⾏行行する必要がある
– (仮想化ではなく) ハードウェアの仕組みで古い世代のプロセッサーをエミュレートす
ることは可能
• Power5+, Power6
• VSX
24
2013/12/16
© 2013 IBM Corporation
- 26. 突然の発表 @ Red Hat Summit
それは 2013 年夏のことだった...
© 2013 IBM Corporation
- 27. OpenPower Consortium
• POWER プロセッサーを⽤用いたデータセンター技術
の開発を⽬目指す
– クラウド型データセンターの選択肢を増やす
– 管理理性、柔軟性の向上
– ⾼高度度なサーバー、ネットワーク、ストレージ、GPU ア
クセラレーション技術の開発
IBM
• 参加企業
– IBM, Google, NVIDIA, Mellanox, Tyan
• IBM 的視点だと...
OpenPower Google
Mellanox
Open
Innovation NVIDIA
TYAN
– POWER 関連の知的財産のライセンス供与
– POWER 搭載サーバーのオープンソース版ファームウ
ェアの提供
27
2013/12/16
© 2013 IBM Corporation
- 28. KVM on Power -‐‑‒ Overview -‐‑‒
• KVM を x86 から Power にポーティングしたもの
– 基本的なアーキテクチャと ioctl(2) インターフェースは KVM on x86 と同じ
• POWER7 プロセッサのハードウェア仮想化機能を使⽤用 (HV mode KVM)
– プロセッサの “ハイパーバイザモード” を使⽤用
– PowerVM (PHYP) とは異異なる仕組み
– POWER7 プロセッサ搭載マシンと専⽤用ファームウェア が必要
• OPAL (Open Power Abstraction Layer): PHYP が動かない特別なファームウェア
• コードネーム Sapphire
– 仮想化の基本機能は実装済み
• x86 と⽐比べていくつかの機能は未実装
• Qemu、カーネルともに upstream マージ済み
28
2013/12/16
© 2013 IBM Corporation
- 29. 2 種類の仮想化⽅方式
• “HV” モードの KVM
– CPU の仮想化機能を使⽤用
– PPC970, POWER7, FSL
– パフォーマンスがいい
• “PR” モードの KVM
– ユーザーモードでゲストを実⾏行行
• ほとんど全ての特権命令令をエミュレート
– ほとんどの環境で稼働
– 遅い
このセッションでは、断りがない限り、
基本的に HV mode KVM について⾔言及しています
29
2013/12/16
© 2013 IBM Corporation
- 30. KVM on Power -‐‑‒ Architecture -‐‑‒
• ホスト Linux カーネルは “素” のハードウェア上で稼働する
– pHyp は存在しない
• kvm カーネルモジュールがプロセッサの仮想化機能を制御
• OPAL ファームウェアがハードウェアへのインターフェースを抽象化
• Qemu プロセスがデバイスモデルと制御インターフェースを提供
QEMU emulates
RTAS call
Guest
Hypercall
QEMU
Return control
to guest
Hypervisor
RTAS/OPAL
Open Firmware
30
2013/12/16
© 2013 IBM Corporation
- 31. KVM on Power -‐‑‒ Technology -‐‑‒
• ゲスト OS は PAPR インターフェースを使って準仮想化
– PowerVM (pHyp) と同じインターフェース
– PowerVM (pHyp) の区画で動く OS がそのまま稼働
• RHEL, SLES
• 現時点では AIX、IBM i は現時点では未サポート
– PAPR のハイパーバイザコールのサブセットを実装
• Linux カーネルを動かすのに必要な分は実装済み
• ゲスト OS の I/O
–
–
–
–
31
KVM on x86 と同様、Qemu がエミュレート
PAPR インターフェース (Virtual I/O)、Linux virtio の両⽅方をサポート
I/O は Qemu およびカーネルで完結
PCI パススルーをサポート
2013/12/16
© 2013 IBM Corporation
- 32. PowerVM vs PowerKVM ⽐比較
PowerVM
• ハイパーバイザは Firmware に
組み込まれたもの
– PCI アダプタは区画にアサインしな
いと使⽤用できない
– I/O 仮想化は VIOS 区画が担当
• 区画の活性化は⽐比較的 “重い” 操
作
– HMC/IVM、FSP、pHyp、VIOS 間
の通信が必要
• 根本思想は “パーティショニン
グ”
32
2013/12/16
PowerKVM
• ハイパーバイザは 通常の Linux
カーネル + KVM カーネルモジ
ュール
– PCI アダプタはホストカーネルが認
識識し操作する
– I/O 仮想化は Qemu で実現
• ゲストの実⾏行行は⽐比較的 “軽い” 操
作
– Qemu プロセスの実⾏行行
• 根本思想は “仮想マシンの実⾏行行”
© 2013 IBM Corporation
- 33. Power(PC) ⽤用 KVM の歴史
• 2007-‐‑‒2008
– PowerPC 4xx support by IBM (Hollis Blanchard, Christian Ehrhardt)
• 2009
– Preliminary port to e500v2 by Freescale (Yu Liu)
– Port to server Book III S (Alexander Graf)
• 2010-‐‑‒2011
– improve e500v2 support and port to 500mc
– HV KVM support on POWER7, PowerPC970
33
2013/12/16
© 2013 IBM Corporation
- 34. KVM on POWER7
• ホストカーネルは hypervisor、ゲストカーネルは supervisorで稼働
–
–
–
–
ホストは全てのリソースにアクセス可能
ゲスト内でトラップを発⾏行行したり特権命令令をエミュレートする必要はない
ゲストは最⼩小のオーバーヘッドで稼働
特別なファームウェアが必要
• ゲストへの entry/exit で区画切切り替えが発⽣生
– それぞれのゲストは⾃自分の MMU ハッシュテーブルを持つ
– ホストは区画 #0 で稼働し、別の MMU ハッシュテーブルを持つ
• ゲストは PAPR インターフェースを使って準仮想化される
– PowerVM の区画として使う通常の Linux ディストリビューション
(RHEL6, SLES11SP1 等) が、KVM ゲストとしても稼働する
Guest
Userspace
User mode
Qemu
Hypervisor
Call
Guest
Kernel
Supervisor mode
KVM
Host
Linux Kernel
34
2013/12/16
Hypervisor mode
© 2013 IBM Corporation
- 35. KVM on POWER7
• Qemu
– “pseries” という新しいマシンタイプ
• KVM
– “book3s_̲hv” flavor: ハイパーバイザーモードで稼働
– “book3s_̲pr” flavor: ユーザーモードで稼働
• Virtual I/O
– PAPR インターフェース
• VSCSI, VETH, console
– virtio インターフェース
• virtio-‐‑‒blk, virtio-‐‑‒net
• SLOF (Slim-‐‑‒Line Open Firmware)
– 仮想マシン⽤用の軽量量ファームウェア
• ホストカーネル
– 新しいプラットフォームタイプ “powernv” (Power non-‐‑‒virtualized)
• CONFIG_̲PPC_̲POWERNV
• arch/powerpc/platforms/powernv
35
2013/12/16
© 2013 IBM Corporation
- 36. KVM on POWER7
• ホストは POWER7 もしくは PPC970 をサポート
– IBM Power System, IBM PowerLinux, YDL PowerStation
– G5 Macは NG!!
• ハードウェア的に仮想化モードが殺されている...
• スーパーバイザーモードでゲストを実効
• large pages (16MB, not pageable/swappable)
• ゲストは SMT4 で実⾏行行可能
– ホストは ST のみ
• 「全ての CPU スレッドは同じ区画上で実⾏行行しなければならない」というハード
ウェア上の制限のため
• PAPR、virtio による I/O の仮想化
36
2013/12/16
© 2013 IBM Corporation
- 37. ホストプロセッサーの種類
• “Server” Processors
– PPC970, POWER7
– sPAPR による準仮想化
• ハイパーバイザー (pHyp) 前提
– PR KVM による完全仮想化も実⾏行行可能
• “Embedded” Processors
– ePAPR による準仮想化
• sPAPR とは結構違うらしい
• sPAPR ゲストは実⾏行行できない
– PR KVM による完全仮想化
37
2013/12/16
© 2013 IBM Corporation
- 39. Book3s プロセッサーと sPAPR -‐‑‒ kernel -‐‑‒
• upstream マージ済み
–
–
–
–
HV KVM
基本機能は稼働、MMU も仮想化
ゲストでは SMT4、ホストでは ST
MMIO エミュレーション
• coalescing はまだ
– MMU notifiers
• POWER7 のみ (PPC970 は不不可)
– ハードウェア的に使える全てのページサイズをサポート
• 未マージな機能
– in-‐‑‒kernel 割り込みコントローラー
• XICS エミュレーション
– ICP presentation controllers in real mode
» No exits for IPIs
» No exits for MSIs in most cases
– ICS source controllers in kernel virtual mode
– マイグレーション
• Complete CPU State save/restore
• MMU Hash table save/restore
39
– VFIO サポート
2013/12/16
© 2013 IBM Corporation
- 40. Book3s プロセッサーと sPAPR -‐‑‒ Qemu -‐‑‒
• upstream マージ済み
– IOMMU 制御
– sPAPR インターフェースによる I/O 仮想化
• vscsi, veth, vterm (pSeries でのデフォルト)
– PCI エミュレーション
• virtio-‐‑‒pci
• OHCH, e1000, ...
– VGA サポート
– SLOF による起動メディアのサポート
• vscsi, veth
• virtio-‐‑‒blk, virtio-‐‑‒net
• 未マージ
– SLOF での virtio-‐‑‒scsi サポート
– NVRAM サポート
– マイグレーション
• MMU hash table save/restore のカーネルインターフェースの詰め
– VFIO
– xHCIfixes
40
2013/12/16
© 2013 IBM Corporation
- 41. Book3e & ePAPR
• 特徴
– 汎⽤用ではないデバイス
– 標準化されていないハードウェアプラットフォーム
• BIOS, ACPI, UEFI 的なものはない
– リアルタイム制御
– OS もいろいろ
• VDC Research の 2011 年年のレポートによると、約 50% は OS なし、もしくは
in-‐‑‒house OS
• “仮想化” に求める機能も限定的
– 同時実⾏行行可能 VM 数はそんなに多くなくてもいい
– ライブマイグレーションもいらない?
41
2013/12/16
© 2013 IBM Corporation
- 42. Book3e & ePAPR
• ステータス
–
–
–
–
–
–
e500mc (32bit) サポートは upstream にマージ済み
e5500 (64bit) サポートは実装済み、レビュー中
SMP サポート
hugetlbfs サポート
e500 マシンタイプは Qemu に実装
Freescale IOMMU (PAMU) ドライバーは開発中
• To Do
– パフォーマンス解析
– e6500 コアのサポート
• LRAT (Logical-‐‑‒to-‐‑‒Real Address Translation)
– Qemu gdb stub
– VFIO
–
–
–
–
42
• Datapath Acceleration Architecture (DPAA)
in-‐‑‒kernel 割り込みコントローラー (MPIC)
リアルタイム
libvirt
デバイスパススルー
2013/12/16
© 2013 IBM Corporation
- 43. HV mode KVM で必要となるファームウェア
• “Sapphire” ファームウェア
– OPAL のコードネーム
– KVM on Power のための専⽤用ファームウェア
• pHyp がない
– ファームウェアも Linux
• ファーストステージカーネルがハードウェアを初期化し、デバイスツリーを構成
• “Petitboot” ブートローダーから、kexec でホストカーネルをロードして起動
– ホストカーネルに対して低レベル・ランタイムサービスを提供
• FSP (サービスプロセッサー) との通信
–
–
–
–
コンソール
電源制御
時計
ハードウェアのイベントログ
• エラー検知、⾃自動回復復
43
2013/12/16
© 2013 IBM Corporation
- 44. リトルエンディアンのサポート
• OpenPower コンソーシアム
– IBM, Google, Tyan, Nvidia, Mellanox
• リトルエンディアンのサポート
• OpenStack と仲良良し
– libvirt, libguestfs の Power 対応
– LE/BE を区別できるようイメージカタログを拡張
– Nested Virtualization
• OpenStack CI で必要
– ゲストの PCI ホットプラグ
44
2013/12/16
© 2013 IBM Corporation
- 45. Nested Virtualization
• OpenStack CI テストで必要
– full emulation or “PR” style KVM
• Full emulation
– 遅い!
– POWER6/7/8 の全ての命令令が Qemu で実装されているわけではない
• PR KVM
– PR KVM: ゲストをユーザーモードで実⾏行行し、特権命令令と MMU を全てエミ
ュレート
– HV KVM よりは遅い、でも full emulation よりは全然速い
– PR KVM でできないこと
• Data breakpoint (watchpoint) サポート
• パフォーマンスモニター
• POWER8 の新機能 (transactional memory)
– 現時点では、PR KVM と HV KVM をひとつのカーネルでコンパイルするこ
とはできない
45
2013/12/16
© 2013 IBM Corporation
- 46. その他
•
libvirt
•
oVirt
•
OpenStack
46
– virsh, virt-‐‑‒manager, virt-‐‑‒install
– RHEV-‐‑‒H
– nova-‐‑‒compute
2013/12/16
<domain type='kvm'>�
<name>tmp</name>�
<uuid>aa94bbbe-750d-c841-6198-c58399e4a0ad</uuid>�
<memory unit='KiB'>1048576</memory>�
<currentMemory unit='KiB'>1048576</currentMemory>�
<vcpu placement='static'>1</vcpu>�
<os>�
<type arch='ppc64' machine='pseries'>hvm</type>�
<boot dev='hd'/>�
</os>�
<features>�
<acpi/>�
<apic/>�
<pae/>�
</features>�
<clock offset='utc'/>�
<on_poweroff>destroy</on_poweroff>�
<on_reboot>restart</on_reboot>�
<on_crash>restart</on_crash>�
<devices>�
<emulator>/usr/bin/qemu-system-ppc64</emulator>�
<disk type='file' device='disk'>�
<driver name='qemu' type='raw'/>�
<source file='/var/lib/libvirt/images/tmp.img'/>�
<target dev='vda' bus='virtio'/>�
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>�
</disk>�
<controller type='usb' index='0'>�
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>�
</controller>�
<controller type='pci' index='0' model='pci-root'/>�
<controller type='scsi' index='0'>�
<address type='spapr-vio' reg='0x2000'/>�
</controller>�
<interface type='network'>�
<mac address='52:54:00:34:37:5f'/>�
<source network='default'/>�
<model type='virtio'/>�
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>�
</interface>�
<serial type='pty'>�
<target port='0'/>�
<address type='spapr-vio' reg='0x30000000'/>�
</serial>�
<console type='pty'>�
<target type='serial' port='0'/>�
<address type='spapr-vio' reg='0x30000000'/>�
</console>�
<memballoon model='virtio'>�
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>�
</memballoon>�
</devices>�
</domain>�
© 2013 IBM Corporation
- 47. arch/powerpc/kvm/powerpc.c
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)�
{
�
virt/kvm/kvm_̲main.c
int r;�
sigset_t sigsaved;�
static long kvm_vcpu_ioctl(struct file *filp,�
�
unsigned int ioctl, unsigned long arg) �
if (vcpu->sigset_active)�
{�
sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);�
struct kvm_vcpu *vcpu = filp->private_data;�
�
void __user *argp = (void __user *)arg;�
if (vcpu->mmio_needed) {�
int r;�
if (!vcpu->mmio_is_write)�
struct kvm_fpu *fpu = NULL;�
kvmppc_complete_mmio_load(vcpu, run);�
struct kvm_sregs *kvm_sregs = NULL;�
vcpu->mmio_needed = 0;�
�
} else if (vcpu->arch.dcr_needed) {�
if (vcpu->kvm->mm != current->mm)�
if (!vcpu->arch.dcr_is_write)�
return -EIO;�
kvmppc_complete_dcr_load(vcpu, run);�
�
vcpu->arch.dcr_needed = 0;�
#if defined(CONFIG_S390) || defined(CONFIG_PPC) || defined(CONFIG_MIPS)� (vcpu->arch.osi_needed) {�
} else if
/* �
u64 *gprs = run->osi.gprs;�
* Special cases: vcpu ioctls that are asynchronous to vcpu execution,�int i;�
* so vcpu_load() would break it.�
�
*/�
for (i = 0; i < 32; i++)�
if (ioctl == KVM_S390_INTERRUPT || ioctl == KVM_INTERRUPT)�
kvmppc_set_gpr(vcpu, i, gprs[i]);�
return kvm_arch_vcpu_ioctl(filp, ioctl, arg);�
vcpu->arch.osi_needed = 0;�
#endif�
} else if (vcpu->arch.hcall_needed) {�
�
int i; �
�
�
r = vcpu_load(vcpu);�
kvmppc_set_gpr(vcpu, 3, run->papr_hcall.ret);�
if (r)�
for (i = 0; i < 9; ++i)�
return r;�
kvmppc_set_gpr(vcpu, 4 + i, run->papr_hcall.args[i]);�
switch (ioctl) {�
arch/powerpc/kvm/book3s.c
vcpu->arch.hcall_needed = 0;�
case KVM_RUN:�
#ifdef CONFIG_BOOKE�
r = -EINVAL;�
} else if (vcpu->arch.epr_needed) {� int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)�
{
�
if (arg)�
kvmppc_set_epr(vcpu, run->epr.epr);�
struct kvm *kvm = vcpu->kvm;�
goto out; �
vcpu->arch.epr_needed = 0;�
�
r = kvm_arch_vcpu_ioctl_run(vcpu, vcpu->run);�
#endif
�
/*
�
trace_kvm_userspace_exit(vcpu->run->exit_reason, r);�
}
�
* If HV mode hasn't been selected by now, make it PR mode�
break;�
�
* from now on.�
case KVM_GET_REGS: {�
r = kvmppc_vcpu_run(run, vcpu);�
*/ �
struct kvm_regs *kvm_regs;�
�
if (kvm->arch.kvm_mode == KVM_MODE_UNKNOWN) {�
if (vcpu->sigset_active)�
mutex_lock(&kvm->lock); �
sigprocmask(SIG_SETMASK, &sigsaved, NULL);�
if (kvm->arch.kvm_mode == KVM_MODE_UNKNOWN)�
�
kvm->arch.kvm_mode = KVM_MODE_PR;�
return r;�
mutex_unlock(&kvm->lock); �
}�
}�
�
VCPU_DO_PR(vcpu, return kvmppc_vcpu_run_pr(kvm_run, vcpu));�
VCPU_DO_HV(vcpu, return kvmppc_vcpu_run_hv(kvm_run, vcpu));�
return -EINVAL;�
}�
47
2013/12/16
© 2013 IBM Corporation
- 48. arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/book3s.c
int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)�
{
�
struct kvm *kvm = vcpu->kvm;�
�
/*
�
* If HV mode hasn't been selected by now, make it PR mode�
* from now on.�
*/ �
if (kvm->arch.kvm_mode == KVM_MODE_UNKNOWN) {�
mutex_lock(&kvm->lock); �
if (kvm->arch.kvm_mode == KVM_MODE_UNKNOWN)�
kvm->arch.kvm_mode = KVM_MODE_PR;�
mutex_unlock(&kvm->lock); �
}�
�
VCPU_DO_PR(vcpu, return kvmppc_vcpu_run_pr(kvm_run, vcpu));�
VCPU_DO_HV(vcpu, return kvmppc_vcpu_run_hv(kvm_run, vcpu));�
return -EINVAL;�
}�
int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)�
{
�
int r; �
int srcu_idx;�
�
if (!vcpu->arch.sane) {�
run->exit_reason = KVM_EXIT_INTERNAL_ERROR;�
return -EINVAL;�
}�
�
kvmppc_core_prepare_to_enter(vcpu);�
�
/* No need to go into the guest when all we'll do is come back out */�
if (signal_pending(current)) {�
run->exit_reason = KVM_EXIT_INTR;�
return -EINTR;�
}�
�
atomic_inc(&vcpu->kvm->arch.vcpus_running);�
/* Order vcpus_running vs. rma_setup_done, see kvmppc_alloc_reset_hpt */�
smp_mb();�
�
/* On the first time here, set up HTAB and VRMA or RMA */�
if (!vcpu->kvm->arch.rma_setup_done) {�
r = kvmppc_hv_setup_htab_rma(vcpu);�
if (r)�
goto out;�
}�
�
flush_fp_to_thread(current);�
flush_altivec_to_thread(current);�
flush_vsx_to_thread(current);�
vcpu->arch.wqp = &vcpu->arch.vcore->wq;�
vcpu->arch.pgdir = current->mm->pgd;�
vcpu->arch.state = KVMPPC_VCPU_BUSY_IN_HOST;�
�
do {�
r = kvmppc_run_vcpu(run, vcpu);�
�
�
if (run->exit_reason == KVM_EXIT_PAPR_HCALL &&�
!(vcpu->arch.shregs.msr & MSR_PR)) {�
r = kvmppc_pseries_do_hcall(vcpu);�
kvmppc_core_prepare_to_enter(vcpu);�
} else if (r == RESUME_PAGE_FAULT) {�
srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);�
r = kvmppc_book3s_hv_page_fault(run, vcpu,�
vcpu->arch.fault_dar, vcpu->arch.fault_dsisr);�
srcu_read_unlock(&vcpu->kvm->srcu, srcu_idx);�
}�
} while (r == RESUME_GUEST);�
out:�
}�
48
2013/12/16
vcpu->arch.state = KVMPPC_VCPU_NOTREADY;�
atomic_dec(&vcpu->kvm->arch.vcpus_running);�
return r;�
© 2013 IBM Corporation
- 49. arch/powerpc/kvm/book3s.c
int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)�
{
�
int r; �
int srcu_idx;�
�
if (!vcpu->arch.sane) {�
run->exit_reason = KVM_EXIT_INTERNAL_ERROR;�
return -EINVAL;�
}�
�
kvmppc_core_prepare_to_enter(vcpu);�
�
/* No need to go into the guest when all we'll do is come back out */�
if (signal_pending(current)) {�
run->exit_reason = KVM_EXIT_INTR;�
return -EINTR;�
}�
�
atomic_inc(&vcpu->kvm->arch.vcpus_running);�
/* Order vcpus_running vs. rma_setup_done, see kvmppc_alloc_reset_hpt */�
smp_mb();�
�
/* On the first time here, set up HTAB and VRMA or RMA */�
if (!vcpu->kvm->arch.rma_setup_done) {�
r = kvmppc_hv_setup_htab_rma(vcpu);�
if (r)�
goto out;�
}�
�
flush_fp_to_thread(current);�
flush_altivec_to_thread(current);�
flush_vsx_to_thread(current);�
vcpu->arch.wqp = &vcpu->arch.vcore->wq;�
vcpu->arch.pgdir = current->mm->pgd;�
vcpu->arch.state = KVMPPC_VCPU_BUSY_IN_HOST;�
�
do {�
r = kvmppc_run_vcpu(run, vcpu);�
�
�
if (run->exit_reason == KVM_EXIT_PAPR_HCALL &&�
!(vcpu->arch.shregs.msr & MSR_PR)) {�
r = kvmppc_pseries_do_hcall(vcpu);�
kvmppc_core_prepare_to_enter(vcpu);�
} else if (r == RESUME_PAGE_FAULT) {�
srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);�
r = kvmppc_book3s_hv_page_fault(run, vcpu,�
vcpu->arch.fault_dar, vcpu->arch.fault_dsisr);�
srcu_read_unlock(&vcpu->kvm->srcu, srcu_idx);�
}�
} while (r == RESUME_GUEST);�
out:�
}�
49
arch/powerpc/kvm/book3s_̲hv.c
static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)�
{�
(snip)�
/*
* This happens the first time this is called for a vcpu.
* If the vcore is already running, we may be able to start
* this thread straight away and have it join in.
*/
if (!signal_pending(current)) {
if (vc->vcore_state == VCORE_RUNNING &&
VCORE_EXIT_COUNT(vc) == 0) {
kvmppc_create_dtl_entry(vcpu, vc);
kvmppc_start_thread(vcpu);
} else if (vc->vcore_state == VCORE_SLEEPING) {
wake_up(&vc->wq);
}
}
while (vcpu->arch.state == KVMPPC_VCPU_RUNNABLE &&
!signal_pending(current)) {
(snip)
if (!vc->n_runnable || vcpu->arch.state != KVMPPC_VCPU_RUNNABLE)
break;
vc->runner = vcpu;
vcpu->arch.is_master = 1;
n_ceded = 0;
list_for_each_entry(v, &vc->runnable_threads, arch.run_list) {
if (!v->arch.pending_exceptions)
n_ceded += v->arch.ceded;
else
v->arch.ceded = 0;
}
if (n_ceded == vc->n_runnable)
kvmppc_vcore_blocked(vc);
else
kvmppc_run_core(vc);
vc->runner = NULL;
vcpu->arch.is_master = 0;
}
(snip)�
vcpu->arch.state = KVMPPC_VCPU_NOTREADY;�
atomic_dec(&vcpu->kvm->arch.vcpus_running);�
return r;�
2013/12/16
© 2013 IBM Corporation
- 50. static void kvmppc_run_core(struct kvmppc_vcore *vc)�
{
�
struct kvm_vcpu *vcpu, *vnext;�
static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)�
long ret;�
{�
u64 now;�
(snip)�
int i, need_vpa_update;�
/* �
int srcu_idx;�
arch/powerpc/kvm/book3s_̲hv_̲interrupts.S
* This happens the first time this is called for a vcpu.�
struct kvm_vcpu *vcpus_to_update[threads_per_core];�
* If the vcore is already running, we may be able to start�
�
_GLOBAL(__kvmppc_vcore_entry)�
* this thread straight away and have it join in.�
/* don't start if any threads have a signal pending */�
�
*/ �
need_vpa_update = 0;�
/* Write correct stack frame */�
if (!signal_pending(current)) {�
list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) {�
mflr r0�
if (vc->vcore_state == VCORE_RUNNING &&�
if (signal_pending(vcpu->arch.run_task))� std r0,PPC_LR_STKOFF(r1)�
VCORE_EXIT_COUNT(vc) == 0) {�
return;�
�
kvmppc_create_dtl_entry(vcpu, vc);�
if (vcpu->arch.vpa.update_pending ||�
/* Save host state to the stack */
�
kvmppc_start_thread(vcpu);�
vcpu->arch.slb_shadow.update_pending stdu r1, -SWITCH_FRAME_SIZE(r1)�
||�
} else if (vc->vcore_state == VCORE_SLEEPING) {�
vcpu->arch.dtl.update_pending)�
�
wake_up(&vc->wq);�
vcpus_to_update[need_vpa_update++] = vcpu;�
/* Save non-volatile registers (r14 - r31) and CR */�
}�
}�
SAVE_NVGPRS(r1)�
�
(snip)�
mfcr r3�
}�
/*�
std r3, _CCR(r1)�
�
* Make sure we are running on thread 0, and that�
�
while (vcpu->arch.state == KVMPPC_VCPU_RUNNABLE &&�
* secondary threads are offline.�
/* Save host DSCR */�
!signal_pending(current)) {�
*/�
BEGIN_FTR_SECTION�
(snip)�
if (threads_per_core > 1 && !on_primary_thread()) {� r3, SPRN_DSCR�
mfspr
if (!vc->n_runnable || vcpu->arch.state != KVMPPC_VCPU_RUNNABLE)�
list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list)�
std r3, HSTATE_DSCR(r13)�
break;�
vcpu->arch.ret = -EBUSY;�
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)�
vc->runner = vcpu;�
goto out;�
�
vcpu->arch.is_master = 1;�
}�
(snip)�
n_ceded = 0;�
�
�
list_for_each_entry(v, &vc->runnable_threads, arch.run_list) {�
vc->pcpu = smp_processor_id();�
/* Jump to partition switch code */�
if (!v->arch.pending_exceptions)�
list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) {�
bl
.kvmppc_hv_entry_trampoline�
n_ceded += v->arch.ceded;�
kvmppc_start_thread(vcpu);�
nop�
else�
kvmppc_create_dtl_entry(vcpu, vc);� �
v->arch.ceded = 0;�
}�
/*�
}�
�
* We return here in virtual mode after the guest exits�
if (n_ceded == vc->n_runnable)�
/* Set this explicitly in case thread 0 doesn't with something that we can't handle in real mode.�
* have a vcpu */�
kvmppc_vcore_blocked(vc);�
get_paca()->kvm_hstate.kvm_vcore = vc;� * Interrupts are enabled again at this point.�
else�
get_paca()->kvm_hstate.ptid = 0;�
*/�
kvmppc_run_core(vc);�
�
�
vc->runner = NULL;�
vc->vcore_state = VCORE_RUNNING;�
/*�
vcpu->arch.is_master = 0;�
preempt_disable();�
* Register usage at this point:�
}�
spin_unlock(&vc->lock);�
*�
(snip)�
�
* R1
= host R1�
kvm_guest_enter();�
* R2
= host R2�
�
* R12
= exit handler id�
srcu_idx = srcu_read_lock(&vc->kvm->srcu);� * R13
= PACA�
�
*/�
__kvmppc_vcore_entry();�
�
�
/* Restore non-volatile host registers (r14 - r31) and CR */�
spin_lock(&vc->lock);�
REST_NVGPRS(r1)�
/* disable sending of IPIs on virtual external irqs ld
*/� r4, _CCR(r1)�
list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list)�
mtcr r4�
vcpu->cpu = -1;�
�
/* wait for secondary threads to finish writing their state to memory */�
addi r1, r1, SWITCH_FRAME_SIZE�
if (vc->nap_count < vc->n_woken)�
ld
r0, PPC_LR_STKOFF(r1)�
kvmppc_wait_for_nap(vc);�
mtlr r0�
(snip)�
blr�
arch/powerpc/kvm/book3s_̲hv.c
© 2013 IBM Corporation
- 51. arch/powerpc/kvm/book3s_̲hv_̲interrupts.S
.global kvmppc_hv_entry�
kvmppc_hv_entry:�
�
/* Required state:�
*�
* R4 = vcpu pointer�
* MSR = ~IR|DR�
* R13 = PACA�
_GLOBAL(kvmppc_hv_entry_trampoline)�
* R1 = host R1�
mflr r0�
�
* R2 = TOC�
/* Save host state to the stack */
�
std r0, PPC_LR_STKOFF(r1)�
* all other volatile GPRS = free�
stdu r1, -112(r1)�
stdu r1, -SWITCH_FRAME_SIZE(r1)�
*/�
mfmsr r10�
�
mflr r0�
/* Save non-volatile registers (r14 - r31) and CR */�
LOAD_REG_ADDR(r5, kvmppc_call_hv_entry)�
std r0, PPC_LR_STKOFF(r1)�
li
r0,MSR_RI�
SAVE_NVGPRS(r1)�
stdu r1, -112(r1)�
andc r0,r10,r0�
mfcr r3�
�
std r3, _CCR(r1)�
li
r6,MSR_IR | MSR_DR�
BEGIN_FTR_SECTION�
andc r6,r10,r6�
�
/* Set partition DABR */�
/* Save host DSCR */�
mtmsrd r0,1
/* clear RI in MSR */�
/* Do this before re-enabling PMU to avoid P7 DABR corruption bug */�
BEGIN_FTR_SECTION�
mtsrr0 r5�
lwz r5,VCPU_DABRX(r4)�
mtsrr1 r6�
mfspr r3, SPRN_DSCR�
ld
r6,VCPU_DABR(r4)�
std r3, HSTATE_DSCR(r13)�
RFI �
mtspr SPRN_DABRX,r5�
�
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)�
mtspr SPRN_DABR,r6�
kvmppc_call_hv_entry:
�
�
�
(snip)�
/* Indicate that we are now in real mode */�
(snip)�
ld
r5, HSTATE_KVM_VCORE(r13)�
�
�
li
r0, 1
�
/* Jump to partition switch code */�
/* �
bl
.kvmppc_hv_entry_trampoline�
stw r0, VCORE_RM_THREADS(r5)�
* POWER7 host -> guest partition switch code.�
�
nop�
* We don't have to lock against concurrent tlbies,�
�
/* any guest vcpu to run? */�
* but we do have to coordinate across hardware threads.�
/*�
ld
r4, HSTATE_KVM_VCPU(r13)�
*/�
cmpdi r4, 0�
* We return here in virtual mode after the guest exits�
/* Increment entry count iff exit count is zero. */�
* with something that we can't handle in real mode.�
beq kvmppc_call_no_guest�
ld
r5,HSTATE_KVM_VCORE(r13)�
kvmppc_got_guest:�
* Interrupts are enabled again at this point.�
addi r9,r5,VCORE_ENTRY_EXIT�
bl
kvmppc_hv_entry�
*/�
21: lwarx r3,0,r9�
�
�
cmpwi r3,0x100
/* any threads starting to exit? */�
/* Back from guest - restore host state and return to caller */�
/*�
bge secondary_too_late
/* if so we're too late to the party */�
�
* Register usage at this point:�
addi r3,r3,1�
*�
BEGIN_FTR_SECTION�
stwcx. r3,0,r9�
/* Restore host DABR and DABRX */�
* R1
= host R1�
bne 21b �
ld
r5,HSTATE_DABR(r13)�
* R2
= host R2�
�
* R12
= exit handler id�
li
r6,7�
/* Primary thread switches to guest partition. */�
mtspr SPRN_DABR,r5�
* R13
= PACA�
ld
r9,VCPU_KVM(r4)
/* pointer to struct kvm */�
*/�
mtspr SPRN_DABRX,r6�
lbz r6,VCPU_IS_MASTER(r4)�
�
END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)�
cmpwi r6,0 �
/* Restore non-volatile host registers (r14 - r31) and CR� */�
beq 20f �
REST_NVGPRS(r1)�
/* Restore SPRG3 */�
/* wait for thread 0 to get into real mode */�
ld
r3,PACA_SPRG3(r13)�
ld
r4, _CCR(r1)�
HMT_LOW�
mtspr SPRN_SPRG3,r3�
mtcr r4�
50: lwz r6,VCORE_RM_THREADS(r5)�
�
cmpwi r6,0 �
addi r1, r1, SWITCH_FRAME_SIZE�
beq 50b �
ld
r0, PPC_LR_STKOFF(r1)�
HMT_MEDIUM�
mtlr r0�
ld
r6,KVM_SDR1(r9)�
blr�
lwz r7,KVM_LPID(r9)�
li
r0,LPID_RSVD
/* switch to reserved LPID */�
mtspr SPRN_LPID,r0�
ptesync�
mtspr SPRN_SDR1,r6
/* switch to partition page table */�
mtspr SPRN_LPID,r7�
isync�
© 2013 IBM Corporation
_GLOBAL(__kvmppc_vcore_entry)�
�
/* Write correct stack frame */�
mflr r0�
std r0,PPC_LR_STKOFF(r1)�
arch/powerpc/kvm/
book3s_̲hv_̲rmhandlers.S
- 52. まとめ
• POWER/PowerPC がんばれ
• KVM はほとんどが機種依存コード (Intel-‐‑‒VT/AMD-‐‑‒V 前提のコード) な
ので、ポーティングは⼤大変そう
• KVM on Power で遊びたい⽅方いらっしゃいましたら声かけてください
52
2013/12/16
© 2013 IBM Corporation