Virtual machines

A running hypervisor comprises the hypervisor microkernel and its virtualization library (libmod_qvm.a), and one or more instances of the virtual machine process (qvm).

What is a virtual machine?

In a QNX hypervisor environment, a VM is implemented in a qvm process instance. The qvm process is an OS process that runs in the hypervisor host, outside the kernel. Each instance has an identifier marking it so that the microkernel knows that it is a qvm process.

If you remember anything about VMs, remember that from the point of view of a guest OS, the VM hosting that guest is hardware. This means that, just as an OS running on a physical board expects certain hardware characteristics (architecture, board-specifics, memory and CPUs, devices, etc.) an OS running in a VM expects those characteristics: the VM in which a guest will run must match the guest's expectations.

When you configure a VM, you are assembling a hardware platform. The difference is that instead of assembling physical memory cards, CPUs, etc., you specify the virtual components of your machine, which a qvm process will create and configure according to your specifications.

The rules about where things appear are the same as for a real board:

The hardware analogy works in the other direction as well. A VM doesn't need to know what its guest is doing any more than hardware needs to know what an OS is doing. In fact, the VM can't know what a guest is doing (“the guest is a blob”; see the Terminology appendix).

For example, a VM can't know why a guest quit (i.e., if the guest quit because a user requested a shutdown or because it encountered a fatal error). If you need to know why a guest quits, you need to rely on the guest to tell you why. If the guest doesn't already have a mechanism to do so, you need to add an appropriate mechanism. For QNX guests, the “Shutdown” screen might provide the required functionality, depending on your requirements.

For more information about configuring VMs, see Assembling and configuring VMs in the Configuration chapter.

qvm services

Each qvm process instance provides key hypervisor services.

VM assembly and configuration

In order to create the virtual environment in which a guest OS can run, a qvm process instance does the following when it starts:

VM operation

During operation a qvm process instance does the following:

Guest startup and shutdown

A guest in a VM can start just like it does on hardware. From the perspective of the guest, it begins execution on a physical CPU. However, this CPU is in fact a qvm vCPU thread. The guest can enable its interrupts, just as it would if it were running in an unvirtualized system.

When the first vCPU thread in a guest's VM begins executing, the VM can know that that guest has booted.

Initiating guest shutdown is the responsibility of the guest. The qvm process detects shutdowns initiated through commonly used methods such as PSCI or ACPI. If you want to use a method that the qvm doesn't automatically recognize, you can write a vdev that detects the shutdown action and responds appropriately.

See the Virtual Device Developer's Guide for more information about writing vdevs.

Note: If the hypervisor detects an undefined condition in a VM, the hypervisor terminates that VM's qvm process instance, which terminates the guest (see Design Safe States in the QNX Hypervisor for Safety chapter).

Manage guest contexts

In a virtualized environment, it is the responsibility of the CPU virtualization extensions to recognize from a guest's actions when the guest needs to exit. When a CPU triggers a guest exit, however, it is the qvm process instance (i.e., the VM) hosting the guest that saves the guest's context. The qvm process instance completes the action initiated by the guest, then restores the guest's context before allowing it to re-enter (see Guest exits in the Performance Tuning chapter).

Manage privilege levels

The qvm process instances manage privilege levels at guest entrances and exits, to ensure that guests can run, and that the system is protected from errant code.

On a guest entrance, the qvm process instance asks the CPU to give the guest the privilege levels it needs to run, but no more. On a guest exit, the qvm process instance asks the CPU to return to the privilege levels it requires to run in the hypervisor host.

Only the CPU hardware can change privilege levels. The qvm process performs the operations required to have the CPU change privilege levels. This mechanism (hence the operations) is architecture-specific.

Guest access to virtual and physical resources

Each qvm process instance manages its hosted guest's access to both virtual and physical resources.

When a guest attempts to access an address in its guest-physical memory, this access can be one of the following, and the qvm process hosting the guest checks the access attempt and responds as described:

Permitted
The guest is attempting to access a memory region that it owns.
The qvm process instance doesn't do anything.
Pass-through device
The guest is attempting to access memory assigned to a physical device, and the guest's VM is configured to know that the guest has direct access to this device.
The qvm process instance doesn't do anything. The guest communicates directly with the device.
Virtual device
The guest is attempting to access an address that is assigned to a virtual device (either virtual or para-virtual).
The qvm process instance requests the appropriate privilege level changes, and passes execution on to its code for the requested device. For example, a guest CPUID request triggers the qvm process instance to emulate the hardware and respond to the guest exactly as the hardware would respond in a non-virtualized system.
Fault
The guest is attempting to access memory for which it does not have permission.
The qvm process instance returns an appropriate error to the guest.

The above are for access attempts that go through the CPU. DMA access control is managed by the SMMU manager (see DMA device containment (smmuman)).