Checking the guest's environment and the hypervisor's safety status

The QHS provides a mechanism that allows a guest to determine if it is running in a virtualized environment, and if this is a safety environment.

A guest in a QNX hypervisor VM can determine it is running in:

ARM platforms

On ARM platforms, check the model property in the FDT that describes the guest's system. If this property is set with QVM-*, then the system is hosted in a QNX hypervisor VM. This property is set differently for the safety and non-safety hypervisor variants:

Non-safety variant (QNX Hypervisor)
The FDT model property is set to QVM-v8A.
Safety variant (QHS)
The FDT model property is set to QVM-v8A-safety.

x86 platforms

For x86 platforms, see your hardware documentation for the CPUID register bit your guest needs to check to know if it is running in a hypervisor, and where in the register you need to look for the VM ID string. The ID string for QNX hypervisor VMs is “QNXQVMBS”.

On x86 platforms, the safety | non-safety variant information is stored in CPUID leaf 0x40000001 EAX bit 0:

Non-safety variant (QNX Hypervisor)
EAX bit 0 is set to 0 (zero).
Safety variant (QHS)
EAX bit 0 is set to 1 (one).

Below is an example of C code a QNX Neutrino OS guest or QOS guest might use in to check if it is running in a QNX hypervisor on an x86 hardware platform, as well as to check if the hypervisor variant is a safety variant (QHS):

#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(int argc, char *argv[])
{
       uint32_t regs[4];
 
       cpuid(1, regs);
       if ((regs[2] & (1 << 31)) == 0) {
             puts("We are not running in a hypervisor");
             return 1; /* not a hypervisor */
       }
 
       /* It is a hypervisor, but is it OUR hypervisor? */
       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; /* not ours :( */
       }
 
       /* It is a QNX hypervisor. */
       puts("This is a QNX QVM hypervisor system");
 
       /* Is it a QNX safety hypervisor running with safety turned on? */
       /* Check EAX bit 0 of CPUID leaf 0x40000001.
       If 0, then non-safety. If 1, then hypervisor is safety variant. */
 
       cpuid(0x40000001, regs);
 
       if ((regs[0] & (0x0001)) == 0)
             puts("Running in non-safety mode");
       else
             puts("Running in safety mode");
 
       return 0;
}

Linux and Android guests

You can adapt the C code above for Linux and Android guests on x86, or run the cpuid utility.