Using the shared memory vdev

The shmem vdev provides a simple mechanism for sharing memory regions between guests, or between guests and the hypervisor host.

For complete configuration information for the shared memory vdev, see vdev shmem in the Virtual Device Reference chapter.

shmem vdev driver

The shmem vdev appears to client application code running in a guest (or in the hypervisor host) as a device with a mapped register set in guest-physical memory and the ability to raise interrupts.

This client code is simply a driver for the shmem vdev, rather than for some physical device (see Devices in the Understanding QNX Virtual Environments chapter). The client running in a guest or in the host can use the shmem vdev register set to connect to a named shared memory region, or to create a new named shared memory region and connect to it.

Accessing the shared memory factory page

Two methods are available for specifying a shared memory factory page in the VM configuration: MMIO and PCI (see Factory and control pages). To locate a factory page, clients in a guest (or the host) must use the method that corresponds to the method that was used to specify the factory page:

MMIO
The factory page is directly mapped. Use the guest-physical address and the interrupt specified by the shmem vdev's loc and intr options in the VM configuration.
PCI
Default. The hypervisor assigns the factory page its location and interrupt. The factory page appears as a PCI device. The guest must run a PCI server, and clients can use the PCI server API to access the factory page and get location and interrupt information (see the API Reference chapter in the PCI Server User's Guide).

When your client application in the guest has obtained the factory page's base address in guest-physical memory, it can use mmap() to map the address into a virtual address for the guest. The relevant registers are in the guest_shm_factory data structure, defined in the <guest_shm.h> public header file.

Creating and connecting to a shared memory region

The shmem vdev is the factory; the client writes to virtual registers in the factory page, which causes the shmem vdev to create shared memory regions, if these regions don't already exist.

That is, the factory page client (i.e., the shmem vdev driver) writes a name and size to the factory page. This action prompts the shmem vdev: if the specified shared memory region doesn't already exist the shmem vdev creates it along with its control page, returning their location in guest-physical memory to the client; or, if the region already exists, the vdev simply returns the location. This create-on-first-use behavior allows guests to started in any order; whichever guest is first to attempt to access a shared memory region creates the region.

When accessing a named shared memory region, the client application needs to do the following with the guest_shm_factory data structure for the shared memory factory page:

  1. Write the shared memory name to guest_shm_factory.name, and the required size of the shared memory to guest_shm_factory.size; if the shared memory region of the specified name and size doesn't already exist, the shmem vdev will create it.
  2. Check factory.status for the status of the named shared memory region.
  3. Read factory.shmem, which holds the base guest-physical address of the guest_shm_control data structure. This structure provides the register layout for the shared memory region's control page, and the shared memory region itself.