diff options
author | John Levon <john.levon@nutanix.com> | 2020-12-15 10:35:30 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-15 10:35:30 +0000 |
commit | 1e9ce657a5050d56d48ac702afb9116efc5691d3 (patch) | |
tree | fc81bb0a7eb607acca4681d5d027ac04ea0024c4 /include | |
parent | 39a158b50590ca899e38d9c77a8508efcd0314ea (diff) | |
download | libvfio-user-1e9ce657a5050d56d48ac702afb9116efc5691d3.zip libvfio-user-1e9ce657a5050d56d48ac702afb9116efc5691d3.tar.gz libvfio-user-1e9ce657a5050d56d48ac702afb9116efc5691d3.tar.bz2 |
clean up the API header file (#197)
This is almost entirely re-ordering: first the basic lifecycle things, then
vfu_setup_*() group, then handlers and helpers, and finally PCI handling.
Signed-off-by: John Levon <john.levon@nutanix.com>
Reviewed-by: Swapnil Ingle <swapnil.ingle@nutanix.com>
Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/libvfio-user.h | 479 |
1 files changed, 237 insertions, 242 deletions
diff --git a/include/libvfio-user.h b/include/libvfio-user.h index 1aa5536..342f3e5 100644 --- a/include/libvfio-user.h +++ b/include/libvfio-user.h @@ -57,6 +57,8 @@ extern "C" { #define LIB_VFIO_USER_MAJOR 0 #define LIB_VFIO_USER_MINOR 1 +#define VFU_DMA_REGIONS 0x10 + // FIXME: too common a name? typedef uint64_t dma_addr_t; @@ -69,144 +71,18 @@ typedef struct { typedef struct vfu_ctx vfu_ctx_t; -/** - * Prototype for memory access callback. The program MUST first map device - * memory in its own virtual address space using vfu_mmap, do any additional work - * required, and finally return that memory. When a region is memory mapped, - * libvfio-user calls the previously registered callback with the following - * arguments: - * - * @pvt: private pointer - * @off: offset of memory area being memory mapped - * @len: length of memory area being memory mapped - * - * @returns the memory address returned by vfu_mmap, or MAP_FAILED on failure - */ -typedef unsigned long (vfu_map_region_cb_t) (void *pvt, unsigned long off, - unsigned long len); - -/** - * Creates a mapping of a device region into the caller's virtual memory. It - * must be called by vfu_map_region_cb_t. - * - * @vfu_ctx: the context to create mapping from - * @offset: offset of the region being mapped - * @length: size of the region being mapped - * - * @returns a pointer to the requested memory or MAP_FAILED on error. Sets errno. - */ -void * -vfu_mmap(vfu_ctx_t * vfu_ctx, off_t offset, size_t length); - /* - * Returns a pointer to the PCI configuration space. - * - * PCI config space consists of an initial 64-byte vfu_pci_hdr_t, plus - * additional space, either containing capabilities, or device-specific - * configuration. Standard confspace is 256 bytes; extended config space is - * 4096 bytes. - */ -vfu_pci_config_space_t * -vfu_pci_get_config_space(vfu_ctx_t *vfu_ctx); - -#define VFU_DMA_REGIONS 0x10 - -/** - * Callback function signature for log function - * @pvt: private pointer - * @level: log level as defined in syslog(3) - * @vfu_log_fn_t: typedef for log function. - * @msg: message + * Attaching to the transport is non-blocking. + * The caller must then manually call vfu_attach_ctx(), + * which is non-blocking, as many times as necessary. */ -typedef void (vfu_log_fn_t) (void *pvt, int level, const char *msg); +#define LIBVFIO_USER_FLAG_ATTACH_NB (1 << 0) typedef enum { VFU_TRANS_SOCK, VFU_TRANS_MAX } vfu_trans_t; -#define VFU_MAX_CAPS (PCI_CFG_SPACE_SIZE - PCI_STD_HEADER_SIZEOF) / PCI_CAP_SIZEOF - -/* - * FIXME the names of migration callback functions are probably far too long, - * but for now it helps with the implementation. - */ -/** - * Migration callback function. - * @pvt: private pointer - */ -typedef int (vfu_migration_callback_t)(void *pvt); - -typedef enum { - VFU_MIGR_STATE_STOP, - VFU_MIGR_STATE_RUNNING, - VFU_MIGR_STATE_STOP_AND_COPY, - VFU_MIGR_STATE_PRE_COPY, - VFU_MIGR_STATE_RESUME -} vfu_migr_state_t; - -typedef struct { - - /* migration state transition callback */ - /* TODO rename to vfu_migration_state_transition_callback */ - /* FIXME maybe we should create a single callback and pass the state? */ - int (*transition)(void *pvt, vfu_migr_state_t state); - - /* Callbacks for saving device state */ - - /* - * Function that is called to retrieve pending migration data. If migration - * data were previously made available (function prepare_data has been - * called) then calling this function signifies that they have been read - * (e.g. migration data can be discarded). If the function returns 0 then - * migration has finished and this function won't be called again. - */ - __u64 (*get_pending_bytes)(void *pvt); - - /* - * Function that is called to instruct the device to prepare migration data. - * The function must return only after migration data are available at the - * specified offset. - */ - int (*prepare_data)(void *pvt, __u64 *offset, __u64 *size); - - /* - * Function that is called to read migration data. offset and size can - * be any subrange on the offset and size previously returned by - * prepare_data. The function must return the amount of data read. This - * function can be called even if the migration data can be memory mapped. - * - * Does this mean that reading data_offset/data_size updates the values? - */ - size_t (*read_data)(void *pvt, void *buf, __u64 count, __u64 offset); - - /* Callbacks for restoring device state */ - - /* - * Function that is called when client has written some previously stored - * device state. - */ - int (*data_written)(void *pvt, __u64 count, __u64 offset); - - /* Fuction that is called for writing previously stored device state. */ - size_t (*write_data)(void *pvt, void *buf, __u64 count, __u64 offset); - -} vfu_migration_callbacks_t; - -typedef struct { - size_t size; - vfu_migration_callbacks_t callbacks; - struct iovec *mmap_areas; - uint32_t nr_mmap_areas; -} vfu_migration_t; - -/* - * Attaching to the transport is non-blocking. - * The caller must then manually call vfu_attach_ctx(), - * which is non-blocking, as many times as necessary. - */ -#define LIBVFIO_USER_FLAG_ATTACH_NB (1 << 0) - typedef enum { VFU_DEV_TYPE_PCI } vfu_dev_type_t; @@ -216,7 +92,7 @@ typedef enum { * * @trans: transport type * @path: path to socket file. - * @flags: context flag + * @flags: context flags * @pvt: private data * @dev_type: device type * @@ -226,6 +102,68 @@ vfu_ctx_t * vfu_create_ctx(vfu_trans_t trans, const char *path, int flags, void *pvt, vfu_dev_type_t dev_type); +/* + * Finalizes the device making it ready for vfu_attach_ctx(). This function is + * mandatory to be called before vfu_attach_ctx(). + * @vfu_ctx: the libvfio-user context + * + * @returns: 0 on success, -1 on error. Sets errno. + */ +int +vfu_realize_ctx(vfu_ctx_t *vfu_ctx); + +/* + * Attempts to attach to the transport. Attach is mandatory before + * vfu_run_ctx() and is non blocking if context is created + * with LIBVFIO_USER_FLAG_ATTACH_NB flag. + * Returns client's file descriptor on success and -1 on error. If errno is + * set to EAGAIN or EWOULDBLOCK then the transport is not ready to attach to and + * the operation must be retried. + * + * @vfu_ctx: the libvfio-user context + */ +int +vfu_attach_ctx(vfu_ctx_t *vfu_ctx); + +/** + * Polls the vfu_ctx and processes the command recieved from client. + * - Blocking vfu_ctx: + * Blocks until new request is received from client and continues processing + * the requests. Exits only in case of error or if the client disconnects. + * - Non-blocking vfu_ctx(LIBVFIO_USER_FLAG_ATTACH_NB): + * Processes one request from client if it's available, otherwise it + * immediatelly returns and the caller is responsible for periodically + * calling again. + * + * @vfu_ctx: The libvfio-user context to poll + * + * @returns 0 on success, -errno on failure. + */ +int +vfu_run_ctx(vfu_ctx_t *vfu_ctx); + +/** + * Destroys libvfio-user context. + * + * @vfu_ctx: the libvfio-user context to destroy + */ +void +vfu_destroy_ctx(vfu_ctx_t *vfu_ctx); + +/** + * Callback function signature for log function + * @pvt: private pointer + * @level: log level as defined in syslog(3) + * @vfu_log_fn_t: typedef for log function. + * @msg: message + */ +typedef void (vfu_log_fn_t) (void *pvt, int level, const char *msg); + +/** + * Log to the logging function configured for this context. + */ +void +vfu_log(vfu_ctx_t *vfu_ctx, int level, const char *fmt, ...); /** * Setup logging information. @@ -236,55 +174,34 @@ vfu_create_ctx(vfu_trans_t trans, const char *path, int vfu_setup_log(vfu_ctx_t *vfu_ctx, vfu_log_fn_t *log, int level); -//TODO: Check other PCI header registers suitable to be filled by device. -// Or should we pass whole vfu_pci_hdr_t to be filled by user. - -typedef enum { - VFU_PCI_TYPE_CONVENTIONAL, - VFU_PCI_TYPE_PCI_X_1, - VFU_PCI_TYPE_PCI_X_2, - VFU_PCI_TYPE_EXPRESS -} vfu_pci_type_t; - /** - * Setup PCI configuration space header data. This function must be called only - * once per libvfio-user context. + * Creates a mapping of a device region into the caller's virtual memory. It + * must be called by vfu_map_region_cb_t. * - * @vfu_ctx: the libvfio-user context - * @id: Device and vendor ID - * @ss: Subsystem vendor and device ID - * @cc: Class code - * @pci_type: PCI type (convention PCI, PCI-X mode 1, PCI-X mode2, PCI-Express) - * @revision: PCI/PCI-X/PCIe revision + * @vfu_ctx: the context to create mapping from + * @offset: offset of the region being mapped + * @length: size of the region being mapped * - * @returns 0 on success, -1 on failure and sets errno. + * @returns a pointer to the requested memory or MAP_FAILED on error. Sets errno. */ -int -vfu_pci_setup_config_hdr(vfu_ctx_t *vfu_ctx, vfu_pci_hdr_id_t id, - vfu_pci_hdr_ss_t ss, vfu_pci_hdr_cc_t cc, - vfu_pci_type_t pci_type, - int revision __attribute__((unused))); - -/* FIXME does it have to be packed as well? */ -typedef union { - struct msicap msi; - struct msixcap msix; - struct pmcap pm; - struct pxcap px; - struct vsc vsc; -} vfu_cap_t; - -//TODO: Support variable size capabilities. +void * +vfu_mmap(vfu_ctx_t * vfu_ctx, off_t offset, size_t length); /** - * Setup PCI capabilities. + * Prototype for memory access callback. The program MUST first map device + * memory in its own virtual address space using vfu_mmap, do any additional work + * required, and finally return that memory. When a region is memory mapped, + * libvfio-user calls the previously registered callback with the following + * arguments: * - * @vfu_ctx: the libvfio-user context - * @caps: array of (vfu_cap_t *) - * @nr_caps: number of elements in @caps + * @pvt: private pointer + * @off: offset of memory area being memory mapped + * @len: length of memory area being memory mapped + * + * @returns the memory address returned by vfu_mmap, or MAP_FAILED on failure */ -int -vfu_pci_setup_caps(vfu_ctx_t *vfu_ctx, vfu_cap_t **caps, int nr_caps); +typedef unsigned long (vfu_map_region_cb_t) (void *pvt, unsigned long off, + unsigned long len); #define VFU_REGION_FLAG_READ (1 << 0) #define VFU_REGION_FLAG_WRITE (1 << 1) @@ -307,20 +224,6 @@ vfu_pci_setup_caps(vfu_ctx_t *vfu_ctx, vfu_cap_t **caps, int nr_caps); typedef ssize_t (vfu_region_access_cb_t) (void *pvt, char *buf, size_t count, loff_t offset, bool is_write); -/* PCI regions */ -enum { - VFU_PCI_DEV_BAR0_REGION_IDX, - VFU_PCI_DEV_BAR1_REGION_IDX, - VFU_PCI_DEV_BAR2_REGION_IDX, - VFU_PCI_DEV_BAR3_REGION_IDX, - VFU_PCI_DEV_BAR4_REGION_IDX, - VFU_PCI_DEV_BAR5_REGION_IDX, - VFU_PCI_DEV_ROM_REGION_IDX, - VFU_PCI_DEV_CFG_REGION_IDX, - VFU_PCI_DEV_VGA_REGION_IDX, - VFU_PCI_DEV_NUM_REGIONS, -}; - /** * Set up a region. * @@ -353,6 +256,14 @@ vfu_setup_region(vfu_ctx_t *vfu_ctx, int region_idx, size_t size, */ typedef int (vfu_reset_cb_t) (void *pvt); +/** + * Setup device reset callback. + * @vfu_ctx: the libvfio-user context + * @reset: device reset callback (optional) + */ +int +vfu_setup_device_reset_cb(vfu_ctx_t *vfu_ctx, vfu_reset_cb_t *reset); + /* * Function that is called when the guest maps a DMA region. Optional. * @pvt: private pointer @@ -372,14 +283,6 @@ typedef void (vfu_map_dma_cb_t) (void *pvt, uint64_t iova, uint64_t len); typedef int (vfu_unmap_dma_cb_t) (void *pvt, uint64_t iova, uint64_t len); /** - * Setup device reset callback. - * @vfu_ctx: the libvfio-user context - * @reset: device reset callback (optional) - */ -int -vfu_setup_device_reset_cb(vfu_ctx_t *vfu_ctx, vfu_reset_cb_t *reset); - -/** * Setup device DMA map/unmap callbacks. * @vfu_ctx: the libvfio-user context * @map_dma: DMA region map callback (optional) @@ -409,6 +312,79 @@ int vfu_setup_device_nr_irqs(vfu_ctx_t *vfu_ctx, enum vfu_dev_irq_type type, uint32_t count); +/* + * FIXME the names of migration callback functions are probably far too long, + * but for now it helps with the implementation. + */ +/** + * Migration callback function. + * @pvt: private pointer + */ +typedef int (vfu_migration_callback_t)(void *pvt); + +typedef enum { + VFU_MIGR_STATE_STOP, + VFU_MIGR_STATE_RUNNING, + VFU_MIGR_STATE_STOP_AND_COPY, + VFU_MIGR_STATE_PRE_COPY, + VFU_MIGR_STATE_RESUME +} vfu_migr_state_t; + +typedef struct { + + /* migration state transition callback */ + /* TODO rename to vfu_migration_state_transition_callback */ + /* FIXME maybe we should create a single callback and pass the state? */ + int (*transition)(void *pvt, vfu_migr_state_t state); + + /* Callbacks for saving device state */ + + /* + * Function that is called to retrieve pending migration data. If migration + * data were previously made available (function prepare_data has been + * called) then calling this function signifies that they have been read + * (e.g. migration data can be discarded). If the function returns 0 then + * migration has finished and this function won't be called again. + */ + __u64 (*get_pending_bytes)(void *pvt); + + /* + * Function that is called to instruct the device to prepare migration data. + * The function must return only after migration data are available at the + * specified offset. + */ + int (*prepare_data)(void *pvt, __u64 *offset, __u64 *size); + + /* + * Function that is called to read migration data. offset and size can + * be any subrange on the offset and size previously returned by + * prepare_data. The function must return the amount of data read. This + * function can be called even if the migration data can be memory mapped. + * + * Does this mean that reading data_offset/data_size updates the values? + */ + size_t (*read_data)(void *pvt, void *buf, __u64 count, __u64 offset); + + /* Callbacks for restoring device state */ + + /* + * Function that is called when client has written some previously stored + * device state. + */ + int (*data_written)(void *pvt, __u64 count, __u64 offset); + + /* Fuction that is called for writing previously stored device state. */ + size_t (*write_data)(void *pvt, void *buf, __u64 count, __u64 offset); + +} vfu_migration_callbacks_t; + +typedef struct { + size_t size; + vfu_migration_callbacks_t callbacks; + struct iovec *mmap_areas; + uint32_t nr_mmap_areas; +} vfu_migration_t; + //TODO: Re-visit once migration support is done. /** * Enable support for device migration. @@ -419,31 +395,6 @@ int vfu_setup_device_migration(vfu_ctx_t *vfu_ctx, vfu_migration_t *migration); /** - * Destroys libvfio-user context. - * - * @vfu_ctx: the libvfio-user context to destroy - */ -void -vfu_destroy_ctx(vfu_ctx_t *vfu_ctx); - -/** - * Polls the vfu_ctx and processes the command recieved from client. - * - Blocking vfu_ctx: - * Blocks until new request is received from client and continues processing - * the requests. Exits only in case of error or if the client disconnects. - * - Non-blocking vfu_ctx(LIBVFIO_USER_FLAG_ATTACH_NB): - * Processes one request from client if it's available, otherwise it - * immediatelly returns and the caller is responsible for periodically - * calling again. - * - * @vfu_ctx: The libvfio-user context to poll - * - * @returns 0 on success, -errno on failure. - */ -int -vfu_run_ctx(vfu_ctx_t *vfu_ctx); - -/** * Triggers an interrupt. * * libvfio-user takes care of using the correct IRQ type (IRQ index: INTx or @@ -473,15 +424,6 @@ vfu_irq_trigger(vfu_ctx_t *vfu_ctx, uint32_t subindex); int vfu_irq_message(vfu_ctx_t *vfu_ctx, uint32_t subindex); -/* Helper functions */ - -/** - * Converts a guest physical address to a dma_sg_t element which can - * be later passed on to vfu_map_sg to memory map the GPA. It is the caller's - * responsibility to unmap it by calling vfu_unmap_sg. - * - */ - /** * Takes a guest physical address and returns a list of scatter/gather entries * than can be individually mapped in the program's virtual memory. A single @@ -576,27 +518,83 @@ int vfu_dma_write(vfu_ctx_t *vfu_ctx, dma_sg_t *sg, void *data); /* - * Finalizes the device making it ready for vfu_attach_ctx(). This function is - * mandatory to be called before vfu_attach_ctx(). + * Supported PCI regions. + * + * FIXME: update with CFG behaviour etc. + */ +enum { + VFU_PCI_DEV_BAR0_REGION_IDX, + VFU_PCI_DEV_BAR1_REGION_IDX, + VFU_PCI_DEV_BAR2_REGION_IDX, + VFU_PCI_DEV_BAR3_REGION_IDX, + VFU_PCI_DEV_BAR4_REGION_IDX, + VFU_PCI_DEV_BAR5_REGION_IDX, + VFU_PCI_DEV_ROM_REGION_IDX, + VFU_PCI_DEV_CFG_REGION_IDX, + VFU_PCI_DEV_VGA_REGION_IDX, + VFU_PCI_DEV_NUM_REGIONS, +}; + +typedef enum { + VFU_PCI_TYPE_CONVENTIONAL, + VFU_PCI_TYPE_PCI_X_1, + VFU_PCI_TYPE_PCI_X_2, + VFU_PCI_TYPE_EXPRESS +} vfu_pci_type_t; + +/** + * Setup PCI configuration space header data. This function must be called only + * once per libvfio-user context. + * * @vfu_ctx: the libvfio-user context + * @id: Device and vendor ID + * @ss: Subsystem vendor and device ID + * @cc: Class code + * @pci_type: PCI type (convention PCI, PCI-X mode 1, PCI-X mode2, PCI-Express) + * @revision: PCI/PCI-X/PCIe revision * - * @returns: 0 on success, -1 on error. Sets errno. + * @returns 0 on success, -1 on failure and sets errno. + * TODO: Check other PCI header registers suitable to be filled by device. + * Or should we pass whole vfu_pci_hdr_t to be filled by user. + */ int -vfu_realize_ctx(vfu_ctx_t *vfu_ctx); +vfu_pci_setup_config_hdr(vfu_ctx_t *vfu_ctx, vfu_pci_hdr_id_t id, + vfu_pci_hdr_ss_t ss, vfu_pci_hdr_cc_t cc, + vfu_pci_type_t pci_type, + int revision __attribute__((unused))); /* - * Attempts to attach to the transport. Attach is mandatory before - * vfu_run_ctx() and is non blocking if context is created - * with LIBVFIO_USER_FLAG_ATTACH_NB flag. - * Returns client's file descriptor on success and -1 on error. If errno is - * set to EAGAIN or EWOULDBLOCK then the transport is not ready to attach to and - * the operation must be retried. + * Returns a pointer to the PCI configuration space. + * + * PCI config space consists of an initial 64-byte vfu_pci_hdr_t, plus + * additional space, either containing capabilities, or device-specific + * configuration. Standard config space is 256 bytes; extended config space is + * 4096 bytes. + */ +vfu_pci_config_space_t * +vfu_pci_get_config_space(vfu_ctx_t *vfu_ctx); + +/* FIXME does it have to be packed as well? */ +typedef union { + struct msicap msi; + struct msixcap msix; + struct pmcap pm; + struct pxcap px; + struct vsc vsc; +} vfu_cap_t; + +//TODO: Support variable size capabilities. + +/** + * Setup PCI capabilities. * * @vfu_ctx: the libvfio-user context + * @caps: array of (vfu_cap_t *) + * @nr_caps: number of elements in @caps */ int -vfu_attach_ctx(vfu_ctx_t *vfu_ctx); +vfu_pci_setup_caps(vfu_ctx_t *vfu_ctx, vfu_cap_t **caps, int nr_caps); /* FIXME this function is broken as the can be multiples capabilities with the * same ID, e.g. the vendor-specific capability. @@ -606,9 +604,6 @@ vfu_attach_ctx(vfu_ctx_t *vfu_ctx); uint8_t * vfu_ctx_get_cap(vfu_ctx_t *vfu_ctx, uint8_t id); -void -vfu_log(vfu_ctx_t *vfu_ctx, int level, const char *fmt, ...); - #ifdef __cplusplus } #endif |