检查guest环境

Posted by Underdog Linux on October 15, 2023

hypervisor 提供了一种机制,允许guest 确定它是否在虚拟化环境中运行,特别是 QNX hypervisor 环境。

ARM platforms

在 ARM 平台上,检查Flattened Device Tree (FDT) 中描述guest 系统的模型属性。 如果使用 QVM-v8A 设置此属性,则系统托管在 QNX hypervisor 虚拟机中。

x86 platforms

对于 x86 平台,请参阅硬件文档,了解guest 需要检查哪个 CPUID 寄存器位,以了解它是否在hypervisor中运行,以及需要在寄存器中的哪个位置查找虚拟机 ID 字符串。 QNX hypervisor 虚拟机的 ID 字符串是“QNXQVMBS”。

以下是 QNX guest 可能用来检查其是否在 x86 平台上的 QNX hypervisor 中运行的 C 代码示例:

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <arpa/inet.h>

int cpuid(uint32_t id, uint32_t* regs)
{
    asm volatile ("cpuid"
        : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
        : "a" (id), "c" (0));
   return 0;
}

static const char* const qnxstr = "QNXQVMBS";

int main()
{
    uint32_t regs[4];

    cpuid(1, regs);
    if ((regs[2] & (1 << 31)) == 0) {
        puts("We are not running in a hypervisor");
        return 1;
    }

    cpuid(0x40000000, regs);
    regs[1] = htonl(regs[1]);
    regs[2] = htonl(regs[2]);

    if (memcmp(&regs[1], qnxstr, 4) != 0 || memcmp(&regs[2], qnxstr+4, 4) != 0) {
        puts("This is a hypervisor but not a QNX hypervisor system");
        return 1;
    }

    puts("This is a QNX QVM hypervisor system");

    return 0;
}

译者注:
在Virtual Box Ubuntu环境中运行结果如下:
🐮./a.out
This is a hypervisor but not a QNX hypervisor system

Linux and Android guests

您可以在 x86 上为 Linux 和 Android 客户机调整上述 C 代码,或运行 cpuid 实用程序。