my_knowledge.ko

Linux | Debug, Analyze, Trace | Tech | etc...

Linux 仮想マシンの Hypervisor を手っ取り早く確認する方法

今まで Linux 仮想マシンの Hypervisor を確認する (Hypervisor を使っているかどうかの確認) 方法として、dmidecode コマンドを使っていたが、より簡単に確認する方法を知ったのでメモ。

手順

次のように仮想マシン上で dmesg | grep 'Hypervisor detected' を実行するだけ。

# dmesg | grep 'Hypervisor detected'
[    0.000000] Hypervisor detected: Xen HVM

なお、dmidecode では次のように表示される。

# dmidecode
...
Handle 0x0100, DMI type 1, 27 bytes
System Information
        Manufacturer: Xen ★
        Product Name: HVM domU
        Version: 4.2.amazon
...

KVM の表示例

比較のため、KVM の例も記載する。

# dmesg | grep 'Hypervisor detected'
[    0.000000] Hypervisor detected: KVM

dmidecode では次のように表示される。

# dmidecode
...
Handle 0x0100, DMI type 1, 27 bytes
System Information
        Manufacturer: QEMU ★
        Product Name: Standard PC (Q35 + ICH9, 2009)
        Version: pc-q35-4.2
...

物理環境の表示例

同様に物理環境の例も記載する。

# dmesg | grep 'Hypervisor detected'
(何も表示されない)

dmidecode では次のように表示される。

# dmidecode
...
Handle 0x000C, DMI type 1, 27 bytes
System Information
    Manufacturer: Apple Inc. ★
    Product Name: Macmini7,1
    Version: 1.0
...

おまけ

Hypervisor detected: がどこのカーネル関数でで出力されるのか気になったので、調べた。

これは、detect_hypervisor_vendor() 関数で出力していると判明。何をしていかなど詳細は未調査。

linux/hypervisor.c at v5.9 · torvalds/linux · GitHub

 29 static const __initconst struct hypervisor_x86 * const hypervisors[] =
 30 {
 31 #ifdef CONFIG_XEN_PV
 32         &x86_hyper_xen_pv,
 33 #endif
 34 #ifdef CONFIG_XEN_PVHVM
 35         &x86_hyper_xen_hvm,
 36 #endif
 37         &x86_hyper_vmware,
 38         &x86_hyper_ms_hyperv,
 39 #ifdef CONFIG_KVM_GUEST
 40         &x86_hyper_kvm,
 41 #endif
 42 #ifdef CONFIG_JAILHOUSE_GUEST
 43         &x86_hyper_jailhouse,
 44 #endif
 45 #ifdef CONFIG_ACRN_GUEST
 46         &x86_hyper_acrn,
 47 #endif
 48 };
...
 53 bool __initdata nopv;
 54 static __init int parse_nopv(char *arg)
 55 {
 56         nopv = true;
 57         return 0;
 58 }
 59 early_param("nopv", parse_nopv);
...
 61 static inline const struct hypervisor_x86 * __init
 62 detect_hypervisor_vendor(void)
 63 {
 64         const struct hypervisor_x86 *h = NULL, * const *p;
 65         uint32_t pri, max_pri = 0;
 66 
 67         for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) {
 68                 if (unlikely(nopv) && !(*p)->ignore_nopv)
 69                         continue;
 70 
 71                 pri = (*p)->detect();
 72                 if (pri > max_pri) {
 73                         max_pri = pri;
 74                         h = *p;
 75                 }
 76         }
 77 
 78         if (h)
 79                 pr_info("Hypervisor detected: %s\n", h->name); ★
 80 
 81         return h;
 82 }

なお、detect_hypervisor_vendor() は、init_hypervisor_platform() から呼び出されている。

 95 void __init init_hypervisor_platform(void)
 96 {
 97         const struct hypervisor_x86 *h;
 98 
 99         h = detect_hypervisor_vendor();
100 
101         if (!h)
102                 return;
103 
104         copy_array(&h->init, &x86_init.hyper, sizeof(h->init));
105         copy_array(&h->runtime, &x86_platform.hyper, sizeof(h->runtime));
106 
107         x86_hyper_type = h->type;
108         x86_init.hyper.init_platform();
109 }

参考