LIBNVMM(3)              NetBSD Library Functions Manual             LIBNVMM(3)

NAME
     libnvmm -- NetBSD Virtualization API

LIBRARY
     library ``libnvmm''

SYNOPSIS
     #include <nvmm.h>

     int
     nvmm_capability(struct nvmm_capability *cap);

     int
     nvmm_machine_create(struct nvmm_machine *mach);

     int
     nvmm_machine_destroy(struct nvmm_machine *mach);

     int
     nvmm_machine_configure(struct nvmm_machine *mach, uint64_t op,
         void *conf);

     int
     nvmm_vcpu_create(struct nvmm_machine *mach, nvmm_cpuid_t cpuid);

     int
     nvmm_vcpu_destroy(struct nvmm_machine *mach, nvmm_cpuid_t cpuid);

     int
     nvmm_vcpu_getstate(struct nvmm_machine *mach, nvmm_cpuid_t cpuid,
         void *state, uint64_t flags);

     int
     nvmm_vcpu_setstate(struct nvmm_machine *mach, nvmm_cpuid_t cpuid,
         void *state, uint64_t flags);

     int
     nvmm_vcpu_inject(struct nvmm_machine *mach, nvmm_cpuid_t cpuid,
         struct nvmm_event *event);

     int
     nvmm_vcpu_run(struct nvmm_machine *mach, nvmm_cpuid_t cpuid,
         struct nvmm_exit *exit);

     int
     nvmm_hva_map(struct nvmm_machine *mach, uintptr_t hva, size_t size);

     int
     nvmm_hva_unmap(struct nvmm_machine *mach, uintptr_t hva, size_t size);

     int
     nvmm_gpa_map(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
         size_t size, int prot);

     int
     nvmm_gpa_unmap(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
         size_t size);

     int
     nvmm_gva_to_gpa(struct nvmm_machine *mach, nvmm_cpuid_t cpuid,
         gvaddr_t gva, gpaddr_t *gpa, nvmm_prot_t *prot);

     int
     nvmm_gpa_to_hva(struct nvmm_machine *mach, gpaddr_t gpa, uintptr_t *hva);

     void
     nvmm_callbacks_register(const struct nvmm_callbacks *cbs);

     int
     nvmm_assist_io(struct nvmm_machine *mach, nvmm_cpuid_t cpuid,
         struct nvmm_exit *exit);

     int
     nvmm_assist_mem(struct nvmm_machine *mach, nvmm_cpuid_t cpuid,
         struct nvmm_exit *exit);

DESCRIPTION
     libnvmm provides a library for VMM software to handle hardware-acceler-
     ated virtual machines in NetBSD.  A virtual machine is described by an
     opaque structure, nvmm_machine.  VMM software should not attempt to mod-
     ify this structure directly, and should use the API provided by libnvmm
     to manage virtual machines.

     nvmm_capability() gets the capabilities of NVMM.  See NVMM Capability
     below for details.

     nvmm_machine_create() creates a virtual machine in the kernel.  The mach
     structure is initialized, and describes the machine.

     nvmm_machine_destroy() destroys the virtual machine described in mach.

     nvmm_machine_configure() configures, on the machine mach, the parameter
     indicated in op.  conf describes the value of the parameter.

     nvmm_vcpu_create() creates a virtual CPU in the machine mach, giving it
     the CPU id cpuid.

     nvmm_vcpu_destroy() destroys the virtual CPU identified by cpuid in the
     machine mach.

     nvmm_vcpu_getstate() gets the state of the virtual CPU identified by
     cpuid in the machine mach.  The state argument is the address of a state
     area, and flags is the bitmap of the components that are to be retrieved.
     See VCPU State Area below for details.

     nvmm_vcpu_setstate() sets the state of the virtual CPU identified by
     cpuid in the machine mach.  The state argument is the address of a state
     area, and flags is the bitmap of the components that are to be set.  See
     VCPU State Area below for details.

     nvmm_vcpu_inject() injects into the CPU identified by cpuid of the
     machine mach an event described by event.  See Event Injection below for
     details.

     nvmm_vcpu_run() runs the CPU identified by cpuid in the machine mach,
     until a VM exit is triggered.  The exit structure is filled to indicate
     the exit reason, and the associated parameters if any.

     nvmm_hva_map() maps at address hva a buffer of size size in the calling
     process' virtual address space.  This buffer is allowed to be subse-
     quently mapped in a virtual machine.

     nvmm_hva_unmap() unmaps the buffer of size size at address hva from the
     calling process' virtual address space.

     nvmm_gpa_map() maps into the guest physical memory beginning on address
     gpa the buffer of size size located at address hva of the calling
     process' virtual address space.  The hva parameter must point to a buffer
     that was previously mapped with nvmm_hva_map().

     nvmm_gpa_unmap() removes the guest physical memory area beginning on
     address gpa and of size size from the machine mach.

     nvmm_gva_to_gpa() translates, on the CPU cpuid from the machine mach, the
     guest virtual address given in gva into a guest physical address returned
     in gpa.  The associated page premissions are returned in prot.  gva must
     be page-aligned.

     nvmm_gpa_to_hva() translates, on the machine mach, the guest physical
     address indicated in gpa into a host virtual address returned in hva.
     gpa must be page-aligned.

     nvmm_callbacks_register() registers in libnvmm the callbacks descriptor
     passed as argument.

     nvmm_assist_io() emulates the I/O operation described in exit on CPU
     cpuid from machine mach.  See I/O Assist below for details.

     nvmm_assist_mem() emulates the Mem operation described in exit on CPU
     cpuid from machine mach.  See Mem Assist below for details.

   NVMM Capability
     The nvmm_capability structure helps VMM software identify the capabili-
     ties offered by NVMM on the host:

     struct nvmm_capability {
             uint64_t version;
             uint64_t state_size;
             uint64_t max_machines;
             uint64_t max_vcpus;
             uint64_t max_ram;
             union {
                     struct {
                             ...
                     } x86;
                     uint64_t rsvd[8];
             } u;
     };

     For example, the max_machines field indicates the maximum number of vir-
     tual machines supported, while max_vcpus indicates the maximum number of
     VCPUs supported per virtual machine.

   Guest-Host Mappings
     Each virtual machine has an associated guest physical memory.  VMM soft-
     ware is allowed to modify this guest physical memory by mapping it into
     some parts of its virtual address space.

     VMM software should follow the following steps to achieve that:

              Call nvmm_hva_map() to create in the host's virtual address
               space an area of memory that can be shared with a guest.  Typi-
               cally, the hva parameter will be a pointer to an area that was
               previously mapped via mmap().  nvmm_hva_map() will replace the
               content of the area, and will make it read-write (but not exe-
               cutable).
              Make available in the guest an area of guest physical memory,
               by calling nvmm_gpa_map() and passing in the hva parameter the
               value that was previously given to nvmm_hva_map().
               nvmm_gpa_map() does not replace the content of any memory, it
               only creates a direct link from gpa into hva.  nvmm_gpa_unmap()
               removes this link without modifying hva.

     The guest will then be able to use the guest physical address passed in
     the gpa parameter of nvmm_gpa_map().  Each change the guest makes in gpa
     will be reflected in the host's hva, and vice versa.

     It is illegal for VMM software to use munmap() on an area that was mapped
     via nvmm_hva_map().

   VCPU State Area
     A VCPU state area is a structure that entirely defines the content of the
     registers of a VCPU.  Only one such structure exists, for x86:

     struct nvmm_x64_state {
             struct nvmm_x64_state_seg segs[NVMM_X64_NSEG];
             uint64_t gprs[NVMM_X64_NGPR];
             uint64_t crs[NVMM_X64_NCR];
             uint64_t drs[NVMM_X64_NDR];
             uint64_t msrs[NVMM_X64_NMSR];
             uint64_t misc[NVMM_X64_NMISC];
             struct fxsave fpu;
     };

     Refer to functional examples to see precisely how to use this structure.

     A VCPU state area is divided in sub-states.  A flags parameter is used to
     set and get the VCPU state; it acts as a bitmap which indicates which
     sub-states to set or get.

     During VM exits, a partial VCPU state area is provided in exitstate, see
     Exit Reasons below for details.

   Exit Reasons
     The nvmm_exit structure is used to handle VM exits:

     enum nvmm_exit_reason {
             NVMM_EXIT_NONE          = 0x0000000000000000,

             /* General. */
             NVMM_EXIT_MEMORY        = 0x0000000000000001,
             NVMM_EXIT_IO            = 0x0000000000000002,
             NVMM_EXIT_MSR           = 0x0000000000000003,
             NVMM_EXIT_INT_READY     = 0x0000000000000004,
             NVMM_EXIT_NMI_READY     = 0x0000000000000005,
             NVMM_EXIT_HALTED        = 0x0000000000000006,
             NVMM_EXIT_SHUTDOWN      = 0x0000000000000007,

             /* Instructions (x86). */
             ...

             NVMM_EXIT_INVALID       = 0xFFFFFFFFFFFFFFFF
     };

     struct nvmm_exit {
             enum nvmm_exit_reason reason;
             union {
                     ...
             } u;
             uint64_t exitstate[8];
     };

     The reason field indicates the reason of the VM exit.  Additional parame-
     ters describing the exit can be present in u.  exitstate contains a par-
     tial, implementation-specific VCPU state, usable as a fast-path to
     retrieve certain state values.

     It is possible that a VM exit was caused by a reason internal to the host
     kernel, and that VMM software should not be concerned with.  In this
     case, the exit reason is set to NVMM_EXIT_NONE.  This gives a chance for
     VMM software to halt the VM in its tracks.

     Refer to functional examples to see precisely how to handle VM exits.

   Event Injection
     It is possible to inject an event into a VCPU.  An event can be a hard-
     ware interrupt, a software interrupt, or a software exception, defined
     by:

     enum nvmm_event_type {
             NVMM_EVENT_INTERRUPT_HW,
             NVMM_EVENT_INTERRUPT_SW,
             NVMM_EVENT_EXCEPTION
     };

     struct nvmm_event {
             enum nvmm_event_type type;
             uint64_t vector;
             union {
                     uint64_t error;
                     uint64_t prio;
             } u;
     };

     This describes an event of type type, to be sent to vector number vector,
     with a possible additional error or prio code that is implementation-spe-
     cific.

     It is possible that the VCPU is in a state where it cannot receive this
     event, if:

              the event is a hardware interrupt, and the VCPU runs with
               interrupts disabled, or
              the event is a non-maskable interrupt (NMI), and the VCPU is
               already in a in-NMI context.

     In this case, nvmm_vcpu_inject() will return EAGAIN, and NVMM will cause
     a VM exit with reason NVMM_EXIT_INT_READY or NVMM_EXIT_NMI_READY to indi-
     cate that VMM software can now reinject the desired event.

   Assist Callbacks
     In order to assist emulation of certain operations, libnvmm requires VMM
     software to register, via nvmm_callbacks_register(), a set of callbacks
     described in the following structure:

     struct nvmm_callbacks {
             void (*io)(struct nvmm_io *);
             void (*mem)(struct nvmm_mem *);
     };

     These callbacks are used by libnvmm each time nvmm_assist_io() or
     nvmm_assist_mem() are invoked.  VMM software that does not intend to use
     either of these assists can put NULL in the callbacks.

   I/O Assist
     When a VM exit occurs with reason NVMM_EXIT_IO, it is necessary for VMM
     software to emulate the associated I/O operation.  libnvmm provides an
     easy way for VMM software to perform that.

     nvmm_assist_io() will call the registered io callback function and give
     it a nvmm_io structure as argument.  This structure describes an I/O
     transaction:

     struct nvmm_io {
             uint64_t port;
             bool in;
             size_t size;
             uint8_t *data;
     };

     The callback can emulate the operation using this descriptor, following
     two unique cases:

              The operation is an input.  In this case, the callback should
               fill data with the desired value.
              The operation is an output.  In this case, the callback should
               read data to retrieve the desired value.

     In either case, port will indicate the I/O port, in will indicate if the
     operation is an input, and size will indicate the size of the access.

   Mem Assist
     When a VM exit occurs with reason NVMM_EXIT_MEMORY, it is necessary for
     VMM software to emulate the associated memory operation.  libnvmm pro-
     vides an easy way for VMM software to perform that, similar to the I/O
     Assist.

     nvmm_assist_mem() will call the registered mem callback function and give
     it a nvmm_mem structure as argument.  This structure describes a Mem
     transaction:

     struct nvmm_mem {
             gpaddr_t gpa;
             bool write;
             size_t size;
             uint8_t *data;
     };

     The callback can emulate the operation using this descriptor, following
     two unique cases:

              The operation is a read.  In this case, the callback should
               fill data with the desired value.
              The operation is a write.  In this case, the callback should
               read data to retrieve the desired value.

     In either case, gpa will indicate the guest physical address, write will
     indicate if the access is a write, and size will indicate the size of the
     access.

RETURN VALUES
     Upon successful completion, each of these functions returns zero.  Other-
     wise, a value of -1 is returned and the global variable errno is set to
     indicate the error.

FILES
     https://www.netbsd.org/~maxv/nvmm/nvmm-demo.zip
           Functional example (demonstrator).  Contains a virtualizer that
           uses the libnvmm API, and a small kernel that exercises this virtu-
           alizer.
     src/sys/dev/nvmm/
           Source code of the kernel NVMM driver.
     src/lib/libnvmm/
           Source code of the libnvmm library.

ERRORS
     These functions will fail if:

     [EEXIST]   An attempt was made to create a machine or a VCPU that already
                exists.

     [EFAULT]   An attempt was made to emulate a memory-based operation in a
                guest, and the guest page tables did not have the permissions
                necessary for the operation to complete successfully.

     [EINVAL]   An inappropriate parameter was used.

     [ENOBUFS]  The maximum number of machines or VCPUs was reached.

     [ENOENT]   A query was made on a machine or a VCPU that does not exist.

     [EPERM]    An attempt was made to access a machine that does not belong
                to the process.

     In addition, nvmm_vcpu_inject() uses the following error codes:

     [EAGAIN]   The VCPU cannot receive the event immediately.

SEE ALSO
     nvmm(4)

AUTHORS
     NVMM was designed and implemented by Maxime Villard.

NetBSD 8.0                      March 19, 2019                      NetBSD 8.0

You can also request any man page by name and (optionally) by section:

Command: 
Section: 
Architecture: 
Collection: 
 

Use the DEFAULT collection to view manual pages for third-party software.


©1994 Man-cgi 1.15, Panagiotis Christias
©1996-2019 Modified for NetBSD by Kimmo Suominen