KVM における s390 の DIAGNOSE 呼び出し
s390 の KVM は、ハイパーコールを行うための DIAGNOSE 呼び出しに対応している。 ネイティブのハイパーコールと、他の s390 ハイパーバイザにある一部の ハイパーコールの両方に対応する。
ビットの番号は、s390 の通例どおり(最上位ビットが左)に付けている点に注意する。
全般的な注意
ゲストによる DIAGNOSE 呼び出しは必須のインターセプトを引き起こす。 したがって、対応するすべての DIAGNOSE 呼び出しは、KVM かそのユーザ空間の どちらかで処理する必要がある。
KVM が対応するすべての DIAGNOSE 呼び出しは、RS-a 形式を使う:
--------------------------------------
| '83' | R1 | R3 | B2 | D2 |
--------------------------------------
0 8 12 16 20 31
第 2 オペランドアドレス(ベース/ディスプレースメントの計算で求まる)は、 データのアドレス指定には使わない。代わりに、このアドレスのビット 48〜63 が ファンクションコードを指定し、ビット 0〜47 は無視される。
対応する DIAGNOSE ファンクションコードは、使うユーザ空間によって異なる。 KVM 固有でない DIAGNOSE ファンクションコードについては、それを定義している s390 ハイパーバイザのドキュメントを参照する。
DIAGNOSE ファンクションコード 'X'500' - KVM ファンクション
ファンクションコードが 0x500 を指定している場合、virtio のファンクションを 含む、さまざまな KVM 固有のファンクションを実行する。
汎用レジスタ 1 にサブファンクションコードが入る。対応するサブファンクションは KVM のユーザ空間に依存する。virtio のサブファンクションについて言えば、通常 ユーザ空間は s390-virtio(サブコード 0〜2)か virtio-ccw(サブコード 3)の どちらかを提供する。
DIAGNOSE 命令が完了すると、汎用レジスタ 2 にはこのファンクションの戻り値が 入る。値は戻りコードか、サブコード固有の値のいずれかになる。
指定したサブファンクションに対応していない場合は、SPECIFICATION 例外が 発生する。
- サブコード 0 - s390-virtio の通知とアーリーコンソール printk
ユーザ空間が処理する。
- サブコード 1 - s390-virtio のリセット
ユーザ空間が処理する。
- サブコード 2 - s390-virtio のステータス設定
ユーザ空間が処理する。
- サブコード 3 - virtio-ccw の通知
ユーザ空間または KVM(ioeventfd の場合)のどちらかが処理する。
汎用レジスタ 2 には、通知先の virtio-ccw プロキシデバイスのサブチャネルを 示すサブチャネル識別ワードが入る。
汎用レジスタ 3 には、通知先の virtqueue の番号が入る。
汎用レジスタ 4 には、KVM が使う 64 ビットの識別子(kvm_io_bus クッキー)が 入る。汎用レジスタ 4 に有効な識別子が入っていなければ、それは無視される。
DIAGNOSE 呼び出しの完了後、汎用レジスタ 2 には 64 ビットの識別子 (kvm_io_bus クッキーの場合)か、内部エラーが起きたときは負のエラー値が 入る場合がある。
このハイパーコールの議論については、virtio 標準も参照する。
- サブコード 4 - ストレージリミット
ユーザ空間が処理する。
DIAGNOSE 呼び出しの完了後、汎用レジスタ 2 にはストレージリミットが入る。 これは VM の存続期間中にストレージに使われる可能性がある最大の物理 アドレスである。
ストレージリミットは、現在使用可能なストレージを示すものではない。穴、 スタンバイストレージ、メモリホットプラグや virtio-mem デバイスなど別の 用途のために予約された領域が含まれる場合がある。実際に使用可能な ストレージを調べる SCLP などの他のインターフェースは、このサブファンクションと 組み合わせて使わなければならない。
ストレージリミットは、SCLP が「最大ストレージ増分」と「増分サイズ」で 示す最大ストレージアドレスより大きくなることはあるが、小さくなることはない 点に注意する。
DIAGNOSE ファンクションコード 'X'501 - KVM ブレークポイント
ファンクションコードが 0x501 を指定している場合、ブレークポイントの ファンクションを実行する場合がある。このファンクションコードはユーザ空間が 処理する。
この diagnose ファンクションコードにはサブファンクションがなく、 パラメータも使わない。
DIAGNOSE ファンクションコード 'X'9C - 自主的なタイムスライス譲渡
汎用レジスタ 1 にターゲット CPU のアドレスが入る。
ホスト CPU を共有する LPAR、KVM、z/VM などのハイパーバイザのゲストでは、 ファンクションコード 0x9c の DIAGNOSE を使うとシステム性能が向上する場合が ある。ゲスト CPU が動いているホスト CPU を譲ることで、それが別のゲスト CPU、 できれば指定したターゲット CPU を含む論理 CPU に割り当てられるためである。
DIAG 'X'9C の転送
ゲストは、特定の他の vCPU に譲るために DIAGNOSE 0x9c を送る場合がある。 例として、現在スピンロックを保持していて動いていない vCPU に譲ろうとする Linux ゲストがある。
しかし、ホスト側では、その vCPU の背後にある実 CPU 自体が動いていない場合が ある。ゲストが最初に送った、背後 CPU へ譲るための DIAGNOSE 0x9c を転送すれば、 その CPU、ひいてはゲストの vCPU がスケジュールされることが期待できる。
- diag9c_forwarding_hz
1 秒あたりの DIAGNOSE 0x9c 転送の最大数を指定できる KVM のカーネル パラメータ。DIAGNOSE 0x9c 転送の嵐を避けるためのものである。 値 0 は転送を無効にする。