Virtual machines

A running hypervisor comprises a QNX OS microkernel and one or more instances of the QNX 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:

  • Don't install two things that try to respond to the same physical address.
  • The environment your VM configuration assembles must be one that the software you will run (the guest OS) is prepared to deal with.

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:

  • Reads, parses and validates VM configuration files (*.qvmconf) and configuration information input with the process command line at startup, exiting if the configuration is invalid and printing a meaningful error message to a log.
  • Sets up intermediate stage tables (ARM: Stage 2 page tables, x86: Extended Page Tables (EPT)).
  • Creates (assembles) and configures its VM, including:

    • allocates RAM (r/w) and ROM (r only) to guests
    • provisions a thread for every virtual CPU (vCPU) it presents to the guest
    • provisions pass-through devices to make them available to the guest
    • defines and configures virtual devices (vdevs) for the hosted guest

VM operation

During VM operation, a qvm process instance does the following:

  • Traps outbound and inbound guest access attempts and determines what to do with them (i.e., if the address is to a vdev, invoke the vdev code (guest exit, then guest entrance when the vdev code completes); if the address is indeed out of bounds, treat it as such).
  • Saves its guest's context before relinquishing a physical CPU.
  • Restores its guest's context before putting the guest back into execution.
  • Looks after any fault handling.
  • Performs any maintenance activities required to ensure the integrity of the VM.

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 a non-virtualized 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 in the QNX Hypervisor GitLab Repository at https://gitlab.com/qnx/hypervisor 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: Protection Features 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 onto 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 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).

Page updated: