gasp_map()

Map a guest-physical address range into the qvm process address space for virtual hardware access

Synopsis:

#include <qvm/gasp.h>
errno_t gasp_map(const vdev_t *vdev,
                 uint64_t guest_paddr,
                 size_t length,
                 gasp_map_flags_t prot,
                 gasp_map_handle_t *h)

Arguments:

vdev
A pointer to a structure for a vdev that will make a DMA-like transaction.
guest_paddr
The starting guest-physical address to be mapped in.
length
The number of bytes to be mapped in.
prot
A bitfield of GMF_* constants specifying the access protection bits for the mapping, including possibly GMF_MAP_ANY.
h
A pointer to a gasp_map_handle_t object that is initialized upon a successful return.

Library:

Provided by qvm; no external library is required.

Description:

Use the gasp_map() function to emulate a device accessing memory. This function attempts to map length bytes from guest-physical memory beginning at guest_paddr into the address space of the current qvm process to provide access to virtual hardware in the VM.

If successful, the function fills in the object pointed to by h with a handle for this new mapping. You can then use this handle to obtain the virtual address for the mapped address range by calling gasp_get_vaddr().

When you're done using the address range, call gasp_unmap_handle() to unmap it.

Returns:

EOK on success, an error code on failure.

Errors:

EFAULT
The mapping isn't allowed for one of the following reasons:
  • the guest-physical address range indicated by guest_paddr and length isn't available for allocation based on the guest IOMMU configuration
  • the access type requested by prot isn't allowed for the vdev based on the guest IOMMU configuration
ENXIO
One of the following is true:
  • The guest-physical address is invalid
  • The prot flag combination is invalid
  • There's no contiguous guest-physical address range that can accommodate the requested mapping

In addition to the errors listed above, this function may return any error returned by mmap(). For more information, refer to the mmap() entry in the C Library Reference.

Example:

The following code demonstrates how to map a guest-physical address range into the address space of the current qvm process, get the virtual address from the handle obtained by the mapping call, and then unmap the address range when it's no longer needed:
  gasp_map_handle_t h;
  
  errno_t rc = gasp_map(vdev, guest_paddr, len, prot, &h);
  if (rc != EOK) {
    /* handle error */
  } else {
    void* const ptr = gasp_get_vaddr(&h);
    /* perform operations on the memory region */
    ...
    gasp_unmap_handle(&h);
  }

In this example, no data cache flush is done when the handle is unmapped. If a flush is required, in this code sequence, call qvm_dcache_operation(QDO_FLUSH|QDO_INVAL, ptr, len) immediately before calling gasp_unmap_handle(). For more information, refer to the qvm_dcache_operation() entry.

Page updated: