doc: update virtio related functions doc comments

Update some virtio, VBS-K, vhost APIs documents.

Tracked-On: #1595
Signed-off-by: Shuo Liu <shuo.a.liu@intel.com>
This commit is contained in:
Shuo Liu 2018-10-29 15:07:58 +08:00 committed by David Kinder
parent ea801a1672
commit d261b4bce2
13 changed files with 647 additions and 89 deletions

View File

@ -209,6 +209,15 @@ pincpu_parse(const char *opt)
return 0; return 0;
} }
/**
* @brief Convert guest physical address to host virtual address
*
* @param ctx Pointer to to struct vmctx representing VM context.
* @param gaddr Guest physical address base.
* @param len Guest physical address length.
*
* @return NULL on convert failed and host virtual address on successful.
*/
void * void *
paddr_guest2host(struct vmctx *ctx, uintptr_t gaddr, size_t len) paddr_guest2host(struct vmctx *ctx, uintptr_t gaddr, size_t len)
{ {

View File

@ -1638,6 +1638,14 @@ pci_msix_enabled(struct pci_vdev *dev)
return (dev->msix.enabled && !dev->msi.enabled); return (dev->msix.enabled && !dev->msi.enabled);
} }
/**
* @brief Generate a MSI-X interrupt to guest
*
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
* @param index MSIx table entry index.
*
* @return N/A
*/
void void
pci_generate_msix(struct pci_vdev *dev, int index) pci_generate_msix(struct pci_vdev *dev, int index)
{ {
@ -1659,6 +1667,14 @@ pci_generate_msix(struct pci_vdev *dev, int index)
} }
} }
/**
* @brief Generate a MSI interrupt to guest
*
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
* @param index Message data index.
*
* @return N/A
*/
void void
pci_generate_msi(struct pci_vdev *dev, int index) pci_generate_msi(struct pci_vdev *dev, int index)
{ {
@ -1760,6 +1776,13 @@ pci_lintr_route(struct pci_vdev *dev)
pci_set_cfgdata8(dev, PCIR_INTLINE, pirq_irq(ii->ii_pirq_pin)); pci_set_cfgdata8(dev, PCIR_INTLINE, pirq_irq(ii->ii_pirq_pin));
} }
/**
* @brief Assert INTx pin of virtual PCI device
*
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
*
* @return N/A
*/
void void
pci_lintr_assert(struct pci_vdev *dev) pci_lintr_assert(struct pci_vdev *dev)
{ {
@ -1776,6 +1799,13 @@ pci_lintr_assert(struct pci_vdev *dev)
pthread_mutex_unlock(&dev->lintr.lock); pthread_mutex_unlock(&dev->lintr.lock);
} }
/**
* @brief Deassert INTx pin of virtual PCI device
*
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
*
* @return N/A
*/
void void
pci_lintr_deassert(struct pci_vdev *dev) pci_lintr_deassert(struct pci_vdev *dev)
{ {

View File

@ -581,6 +581,22 @@ vhost_set_mem_table(struct vhost_dev *vdev)
return 0; return 0;
} }
/**
* @brief vhost_dev initialization.
*
* This interface is called to initialize the vhost_dev. It must be called
* before the actual feature negotiation with the guest OS starts.
*
* @param vdev Pointer to struct vhost_dev.
* @param base Pointer to struct virtio_base.
* @param fd fd of the vhost chardev.
* @param vq_idx The first virtqueue which would be used by this vhost dev.
* @param vhost_features Subset of vhost features which would be enabled.
* @param vhost_ext_features Specific vhost internal features to be enabled.
* @param busyloop_timeout Busy loop timeout in us.
*
* @return 0 on success and -1 on failure.
*/
int int
vhost_dev_init(struct vhost_dev *vdev, vhost_dev_init(struct vhost_dev *vdev,
struct virtio_base *base, struct virtio_base *base,
@ -645,6 +661,15 @@ fail:
return -1; return -1;
} }
/**
* @brief vhost_dev cleanup.
*
* This interface is called to cleanup the vhost_dev.
*
* @param vdev Pointer to struct vhost_dev.
*
* @return 0 on success and -1 on failure.
*/
int int
vhost_dev_deinit(struct vhost_dev *vdev) vhost_dev_deinit(struct vhost_dev *vdev)
{ {
@ -661,6 +686,15 @@ vhost_dev_deinit(struct vhost_dev *vdev)
return 0; return 0;
} }
/**
* @brief start vhost data plane.
*
* This interface is called to start the data plane in vhost.
*
* @param vdev Pointer to struct vhost_dev.
*
* @return 0 on success and -1 on failure.
*/
int int
vhost_dev_start(struct vhost_dev *vdev) vhost_dev_start(struct vhost_dev *vdev)
{ {
@ -736,6 +770,15 @@ fail:
return -1; return -1;
} }
/**
* @brief stop vhost data plane.
*
* This interface is called to stop the data plane in vhost.
*
* @param vdev Pointer to struct vhost_dev.
*
* @return 0 on success and -1 on failure.
*/
int int
vhost_dev_stop(struct vhost_dev *vdev) vhost_dev_stop(struct vhost_dev *vdev)
{ {
@ -758,6 +801,17 @@ vhost_dev_stop(struct vhost_dev *vdev)
return rc; return rc;
} }
/**
* @brief set backend fd of vhost net.
*
* This interface is called to set the backend fd (for example tap fd)
* to vhost.
*
* @param vdev Pointer to struct vhost_dev.
* @param backend_fd fd of backend (for example tap fd).
*
* @return 0 on success and -1 on failure.
*/
int int
vhost_net_set_backend(struct vhost_dev *vdev, int backend_fd) vhost_net_set_backend(struct vhost_dev *vdev, int backend_fd)
{ {

View File

@ -45,9 +45,17 @@
*/ */
#define DEV_STRUCT(vs) ((void *)(vs)) #define DEV_STRUCT(vs) ((void *)(vs))
/* /**
* Link a virtio_base to its constants, the virtio device, and * @brief Link a virtio_base to its constants, the virtio device,
* the PCI emulation. * and the PCI emulation.
*
* @param base Pointer to struct virtio_base.
* @param vops Pointer to struct virtio_ops.
* @param pci_virtio_dev Pointer to instance of certain virtio device.
* @param dev Pointer to struct pci_vdev which emulates a PCI device.
* @param queues Pointer to struct virtio_vq_info, normally an array.
*
* @return NULL
*/ */
void void
virtio_linkup(struct virtio_base *base, struct virtio_ops *vops, virtio_linkup(struct virtio_base *base, struct virtio_ops *vops,
@ -69,14 +77,19 @@ virtio_linkup(struct virtio_base *base, struct virtio_ops *vops,
} }
} }
/* /**
* Reset device (device-wide). This erases all queues, i.e., * @brief Reset device (device-wide).
* all the queues become invalid (though we don't wipe out the *
* internal pointers, we just clear the VQ_ALLOC flag). * This erases all queues, i.e., all the queues become invalid.
* But we don't wipe out the internal pointers, by just clearing
* the VQ_ALLOC flag.
* *
* It resets negotiated features to "none". * It resets negotiated features to "none".
*
* If MSI-X is enabled, this also resets all the vectors to NO_VECTOR. * If MSI-X is enabled, this also resets all the vectors to NO_VECTOR.
*
* @param base Pointer to struct virtio_base.
*
* @return N/A
*/ */
void void
virtio_reset_dev(struct virtio_base *base) virtio_reset_dev(struct virtio_base *base)
@ -114,8 +127,13 @@ virtio_reset_dev(struct virtio_base *base)
base->config_generation = 0; base->config_generation = 0;
} }
/* /**
* Set I/O BAR (usually 0) to map PCI config registers. * @brief Set I/O BAR (usually 0) to map PCI config registers.
*
* @param base Pointer to struct virtio_base.
* @param barnum Which BAR[0..5] to use.
*
* @return N/A
*/ */
void void
virtio_set_io_bar(struct virtio_base *base, int barnum) virtio_set_io_bar(struct virtio_base *base, int barnum)
@ -131,12 +149,19 @@ virtio_set_io_bar(struct virtio_base *base, int barnum)
base->legacy_pio_bar_idx = barnum; base->legacy_pio_bar_idx = barnum;
} }
/* /**
* Initialize MSI-X vector capabilities if we're to use MSI-X, * @brief Initialize MSI-X vector capabilities if we're to use MSI-X,
* or MSI capabilities if not. * or MSI capabilities if not.
* *
* We assume we want one MSI-X vector per queue, here, plus one * We assume we want one MSI-X vector per queue, here, plus one
* for the config vec. * for the config vec.
*
*
* @param base Pointer to struct virtio_base.
* @param barnum Which BAR[0..5] to use.
* @param use_msix If using MSI-X.
*
* @return 0 on success and non-zero on fail.
*/ */
int int
virtio_intr_init(struct virtio_base *base, int barnum, int use_msix) virtio_intr_init(struct virtio_base *base, int barnum, int use_msix)
@ -163,12 +188,17 @@ virtio_intr_init(struct virtio_base *base, int barnum, int use_msix)
return 0; return 0;
} }
/* /**
* Initialize MSI-X vector capabilities if we're to use MSI-X, * @brief Initialize MSI-X vector capabilities if we're to use MSI-X,
* or MSI capabilities if not. * or MSI capabilities if not.
* *
* Wrapper function for virtio_intr_init() since by default we * Wrapper function for virtio_intr_init() for cases we directly use
* will use bar 1 for MSI-X. * BAR 1 for MSI-X capabilities.
*
* @param base Pointer to struct virtio_base.
* @param use_msix If using MSI-X.
*
* @return 0 on success and non-zero on fail.
*/ */
int int
virtio_interrupt_init(struct virtio_base *base, int use_msix) virtio_interrupt_init(struct virtio_base *base, int use_msix)
@ -1006,6 +1036,18 @@ virtio_set_modern_pio_bar(struct virtio_base *base, int barnum)
return 0; return 0;
} }
/**
* @brief Set modern BAR (usually 4) to map PCI config registers.
*
* Set modern MMIO BAR (usually 4) to map virtio 1.0 capabilities and optional
* set modern PIO BAR (usually 2) to map notify capability. This interface is
* only valid for modern virtio.
*
* @param base Pointer to struct virtio_base.
* @param use_notify_pio Whether use pio for notify capability.
*
* @return 0 on success and non-zero on fail.
*/
int int
virtio_set_modern_bar(struct virtio_base *base, bool use_notify_pio) virtio_set_modern_bar(struct virtio_base *base, bool use_notify_pio)
{ {
@ -1027,6 +1069,17 @@ virtio_set_modern_bar(struct virtio_base *base, bool use_notify_pio)
return rc; return rc;
} }
/**
* @brief Indicate the device has experienced an error.
*
* This is called when the device has experienced an error from which it
* cannot re-cover. DEVICE_NEEDS_RESET is set to the device status register
* and a config change intr is sent to the guest driver.
*
* @param base Pointer to struct virtio_base.
*
* @return N/A
*/
void void
virtio_dev_error(struct virtio_base *base) virtio_dev_error(struct virtio_base *base)
{ {
@ -1604,6 +1657,21 @@ virtio_pci_modern_pio_write(struct vmctx *ctx, int vcpu, struct pci_vdev *dev,
pthread_mutex_unlock(base->mtx); pthread_mutex_unlock(base->mtx);
} }
/**
* @brief Handle PCI configuration space reads.
*
* Handle virtio standard register reads, and dispatch other reads to
* actual virtio device driver.
*
* @param ctx Pointer to struct vmctx representing VM context.
* @param vcpu VCPU ID.
* @param dev Pointer to struct pci_vdev which emulates a PCI device.
* @param baridx Which BAR[0..5] to use.
* @param offset Register offset in bytes within a BAR region.
* @param size Access range in bytes.
*
* @return register value.
*/
uint64_t uint64_t
virtio_pci_read(struct vmctx *ctx, int vcpu, struct pci_vdev *dev, virtio_pci_read(struct vmctx *ctx, int vcpu, struct pci_vdev *dev,
int baridx, uint64_t offset, int size) int baridx, uint64_t offset, int size)
@ -1634,6 +1702,22 @@ virtio_pci_read(struct vmctx *ctx, int vcpu, struct pci_vdev *dev,
return size == 1 ? 0xff : size == 2 ? 0xffff : 0xffffffff; return size == 1 ? 0xff : size == 2 ? 0xffff : 0xffffffff;
} }
/**
* @brief Handle PCI configuration space writes.
*
* Handle virtio standard register writes, and dispatch other writes to
* actual virtio device driver.
*
* @param ctx Pointer to struct vmctx representing VM context.
* @param vcpu VCPU ID.
* @param dev Pointer to struct pci_vdev which emulates a PCI device.
* @param baridx Which BAR[0..5] to use.
* @param offset Register offset in bytes within a BAR region.
* @param size Access range in bytes.
* @param value Data value to be written into register.
*
* @return N/A
*/
void void
virtio_pci_write(struct vmctx *ctx, int vcpu, struct pci_vdev *dev, virtio_pci_write(struct vmctx *ctx, int vcpu, struct pci_vdev *dev,
int baridx, uint64_t offset, int size, uint64_t value) int baridx, uint64_t offset, int size, uint64_t value)
@ -1670,6 +1754,22 @@ virtio_pci_write(struct vmctx *ctx, int vcpu, struct pci_vdev *dev,
base->vops->name, baridx); base->vops->name, baridx);
} }
/**
* @brief Handle PCI configuration space reads.
*
* Handle virtio PCI configuration space reads. Only the specific registers
* that need speical operation are handled in this callback. For others just
* fallback to pci core. This interface is only valid for virtio modern.
*
* @param ctx Pointer to struct vmctx representing VM context.
* @param vcpu VCPU ID.
* @param dev Pointer to struct pci_vdev which emulates a PCI device.
* @param coff Register offset in bytes within PCI configuration space.
* @param bytes Access range in bytes.
* @param rv The value returned as read.
*
* @return 0 on handled and non-zero on non-handled.
*/
int int
virtio_pci_modern_cfgread(struct vmctx *ctx, int vcpu, struct pci_vdev *dev, virtio_pci_modern_cfgread(struct vmctx *ctx, int vcpu, struct pci_vdev *dev,
int coff, int bytes, uint32_t *rv) int coff, int bytes, uint32_t *rv)
@ -1719,6 +1819,22 @@ virtio_pci_modern_cfgread(struct vmctx *ctx, int vcpu, struct pci_vdev *dev,
return -1; return -1;
} }
/**
* @brief Handle PCI configuration space writes.
*
* Handle virtio PCI configuration space writes. Only the specific registers
* that need speical operation are handled in this callback. For others just
* fallback to pci core. This interface is only valid for virtio modern.
*
* @param ctx Pointer to struct vmctx representing VM context.
* @param vcpu VCPU ID.
* @param dev Pointer to struct pci_vdev which emulates a PCI device.
* @param coff Register offset in bytes within PCI configuration space.
* @param bytes Access range in bytes.
* @param val The value to write.
*
* @return 0 on handled and non-zero on non-handled.
*/
int int
virtio_pci_modern_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_vdev *dev, virtio_pci_modern_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_vdev *dev,
int coff, int bytes, uint32_t val) int coff, int bytes, uint32_t val)

View File

@ -28,7 +28,13 @@ vbs_vqs_info_set(int fd, void *arg)
} }
/* VBS-K common ops */ /* VBS-K common ops */
/* VBS-K reset */ /**
* @brief Virtio kernel module reset.
*
* @param fd File descriptor representing virtio backend in kernel module.
*
* @return 0 on OK and non-zero on error.
*/
int int
vbs_kernel_reset(int fd) vbs_kernel_reset(int fd)
{ {
@ -40,7 +46,15 @@ vbs_kernel_reset(int fd)
* change the configuration of the virtio device after VBS-K has been * change the configuration of the virtio device after VBS-K has been
* initialized. * initialized.
*/ */
/* VBS-K start/stop */ /**
* @brief Virtio kernel module start.
*
* @param fd File descriptor representing virtio backend in kernel module.
* @param dev Pointer to struct vbs_dev_info.
* @param vqs Pointer to struct vbs_vqs_info.
*
* @return 0 on OK and non-zero on error.
*/
int int
vbs_kernel_start(int fd, struct vbs_dev_info *dev, struct vbs_vqs_info *vqs) vbs_kernel_start(int fd, struct vbs_dev_info *dev, struct vbs_vqs_info *vqs)
{ {
@ -66,6 +80,13 @@ vbs_kernel_start(int fd, struct vbs_dev_info *dev, struct vbs_vqs_info *vqs)
return VIRTIO_SUCCESS; return VIRTIO_SUCCESS;
} }
/**
* @brief Virtio kernel module stop.
*
* @param fd File descriptor representing virtio backend in kernel module.
*
* @return 0 on OK and non-zero on error.
*/
int int
vbs_kernel_stop(int fd) vbs_kernel_stop(int fd)
{ {

View File

@ -45,7 +45,17 @@ extern bool stdio_in_use;
int vmexit_task_switch(struct vmctx *ctx, struct vhm_request *vhm_req, int vmexit_task_switch(struct vmctx *ctx, struct vhm_request *vhm_req,
int *vcpu); int *vcpu);
void *paddr_guest2host(struct vmctx *ctx, uintptr_t addr, size_t len);
/**
* @brief Convert guest physical address to host virtual address
*
* @param ctx Pointer to to struct vmctx representing VM context.
* @param gaddr Guest physical address base.
* @param len Guest physical address length.
*
* @return NULL on convert failed and host virtual address on successful.
*/
void *paddr_guest2host(struct vmctx *ctx, uintptr_t gaddr, size_t len);
int virtio_uses_msix(void); int virtio_uses_msix(void);
void ptdev_no_reset(bool enable); void ptdev_no_reset(bool enable);
void init_debugexit(void); void init_debugexit(void);

View File

@ -252,10 +252,45 @@ int pci_emul_find_capability(struct pci_vdev *dev, uint8_t capid,
int *p_capoff); int *p_capoff);
int pci_emul_add_msicap(struct pci_vdev *pi, int msgnum); int pci_emul_add_msicap(struct pci_vdev *pi, int msgnum);
int pci_emul_add_pciecap(struct pci_vdev *pi, int pcie_device_type); int pci_emul_add_pciecap(struct pci_vdev *pi, int pcie_device_type);
void pci_generate_msi(struct pci_vdev *pi, int msgnum);
void pci_generate_msix(struct pci_vdev *pi, int msgnum); /**
void pci_lintr_assert(struct pci_vdev *pi); * @brief Generate a MSI interrupt to guest
void pci_lintr_deassert(struct pci_vdev *pi); *
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
* @param index Message data index.
*
* @return N/A
*/
void pci_generate_msi(struct pci_vdev *dev, int index);
/**
* @brief Generate a MSI-X interrupt to guest
*
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
* @param index MSIs table entry index.
*
* @return N/A
*/
void pci_generate_msix(struct pci_vdev *dev, int index);
/**
* @brief Assert INTx pin of virtual PCI device
*
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
*
* @return N/A
*/
void pci_lintr_assert(struct pci_vdev *dev);
/**
* @brief Deassert INTx pin of virtual PCI device
*
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
*
* @return N/A
*/
void pci_lintr_deassert(struct pci_vdev *dev);
void pci_lintr_request(struct pci_vdev *pi); void pci_lintr_request(struct pci_vdev *pi);
void pci_lintr_release(struct pci_vdev *pi); void pci_lintr_release(struct pci_vdev *pi);
int pci_msi_enabled(struct pci_vdev *pi); int pci_msi_enabled(struct pci_vdev *pi);
@ -282,46 +317,97 @@ int check_gsi_sharing_violation(void);
int pciaccess_init(void); int pciaccess_init(void);
void pciaccess_cleanup(void); void pciaccess_cleanup(void);
/**
* @brief Set virtual PCI device's configuration space in 1 byte width
*
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
* @param offset Offset in configuration space.
* @param val Value in 1 byte.
*
* @return N/A
*/
static inline void static inline void
pci_set_cfgdata8(struct pci_vdev *pi, int offset, uint8_t val) pci_set_cfgdata8(struct pci_vdev *dev, int offset, uint8_t val)
{ {
assert(offset <= PCI_REGMAX); assert(offset <= PCI_REGMAX);
*(uint8_t *)(pi->cfgdata + offset) = val; *(uint8_t *)(dev->cfgdata + offset) = val;
} }
/**
* @brief Set virtual PCI device's configuration space in 2 bytes width
*
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
* @param offset Offset in configuration space.
* @param val Value in 2 bytes.
*
* @return N/A
*/
static inline void static inline void
pci_set_cfgdata16(struct pci_vdev *pi, int offset, uint16_t val) pci_set_cfgdata16(struct pci_vdev *dev, int offset, uint16_t val)
{ {
assert(offset <= (PCI_REGMAX - 1) && (offset & 1) == 0); assert(offset <= (PCI_REGMAX - 1) && (offset & 1) == 0);
*(uint16_t *)(pi->cfgdata + offset) = val; *(uint16_t *)(dev->cfgdata + offset) = val;
} }
/**
* @brief Set virtual PCI device's configuration space in 4 bytes width
*
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
* @param offset Offset in configuration space.
* @param val Value in 4 bytes.
*
* @return N/A
*/
static inline void static inline void
pci_set_cfgdata32(struct pci_vdev *pi, int offset, uint32_t val) pci_set_cfgdata32(struct pci_vdev *dev, int offset, uint32_t val)
{ {
assert(offset <= (PCI_REGMAX - 3) && (offset & 3) == 0); assert(offset <= (PCI_REGMAX - 3) && (offset & 3) == 0);
*(uint32_t *)(pi->cfgdata + offset) = val; *(uint32_t *)(dev->cfgdata + offset) = val;
} }
/**
* @brief Get virtual PCI device's configuration space in 1 byte width
*
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
* @param offset Offset in configuration space.
*
* @return The configuration value in 1 byte.
*/
static inline uint8_t static inline uint8_t
pci_get_cfgdata8(struct pci_vdev *pi, int offset) pci_get_cfgdata8(struct pci_vdev *dev, int offset)
{ {
assert(offset <= PCI_REGMAX); assert(offset <= PCI_REGMAX);
return (*(uint8_t *)(pi->cfgdata + offset)); return (*(uint8_t *)(dev->cfgdata + offset));
} }
/**
* @brief Get virtual PCI device's configuration space in 2 byte width
*
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
* @param offset Offset in configuration space.
*
* @return The configuration value in 2 bytes.
*/
static inline uint16_t static inline uint16_t
pci_get_cfgdata16(struct pci_vdev *pi, int offset) pci_get_cfgdata16(struct pci_vdev *dev, int offset)
{ {
assert(offset <= (PCI_REGMAX - 1) && (offset & 1) == 0); assert(offset <= (PCI_REGMAX - 1) && (offset & 1) == 0);
return (*(uint16_t *)(pi->cfgdata + offset)); return (*(uint16_t *)(dev->cfgdata + offset));
} }
/**
* @brief Get virtual PCI device's configuration space in 4 byte width
*
* @param dev Pointer to struct pci_vdev representing virtual PCI device.
* @param offset Offset in configuration space.
*
* @return The configuration value in 4 bytes.
*/
static inline uint32_t static inline uint32_t
pci_get_cfgdata32(struct pci_vdev *pi, int offset) pci_get_cfgdata32(struct pci_vdev *dev, int offset)
{ {
assert(offset <= (PCI_REGMAX - 3) && (offset & 3) == 0); assert(offset <= (PCI_REGMAX - 3) && (offset & 3) == 0);
return (*(uint32_t *)(pi->cfgdata + offset)); return (*(uint32_t *)(dev->cfgdata + offset));
} }
#endif /* _PCI_CORE_H_ */ #endif /* _PCI_CORE_H_ */

View File

@ -117,113 +117,117 @@
#define IC_EVENT_IRQFD _IC_ID(IC_ID, IC_ID_EVENT_BASE + 0x01) #define IC_EVENT_IRQFD _IC_ID(IC_ID, IC_ID_EVENT_BASE + 0x01)
/** /**
* struct vm_memmap - EPT memory mapping info for guest * @brief EPT memory mapping info for guest
*/ */
struct vm_memmap { struct vm_memmap {
/** @type: memory mapping type */ /** memory mapping type */
uint32_t type; uint32_t type;
/** @using_vma: using vma_base to get vm0_gpa, /** using vma_base to get vm0_gpa,
* only for type == VM_MEMMAP_SYSMEM * only for type == VM_MEMMAP_SYSMEM
*/ */
uint32_t using_vma; uint32_t using_vma;
/** @gpa: user OS guest physical start address of memory mapping */ /** user OS guest physical start address of memory mapping */
uint64_t gpa; uint64_t gpa;
/** union */
union { union {
/** @hpa: host physical start address of memory, /** host physical start address of memory,
* only for type == VM_MMIO * only for type == VM_MMIO
*/ */
uint64_t hpa; uint64_t hpa;
/** @vma_base: service OS user virtual start address of /** service OS user virtual start address of
* memory, only for type == VM_MEMMAP_SYSMEM && * memory, only for type == VM_MEMMAP_SYSMEM &&
* using_vma == true * using_vma == true
*/ */
uint64_t vma_base; uint64_t vma_base;
}; };
/** @len: the length of memory range mapped */ /** the length of memory range mapped */
uint64_t len; /* mmap length */ uint64_t len; /* mmap length */
/** @prot: memory mapping attribute */ /** memory mapping attribute */
uint32_t prot; /* RWX */ uint32_t prot; /* RWX */
}; };
/** /**
* struct ic_ptdev_irq - pass thru device irq data structure * @brief pass thru device irq data structure
*/ */
struct ic_ptdev_irq { struct ic_ptdev_irq {
#define IRQ_INTX 0 #define IRQ_INTX 0
#define IRQ_MSI 1 #define IRQ_MSI 1
#define IRQ_MSIX 2 #define IRQ_MSIX 2
/** @type: irq type */ /** irq type */
uint32_t type; uint32_t type;
/** @virt_bdf: virtual bdf description of pass thru device */ /** virtual bdf description of pass thru device */
uint16_t virt_bdf; /* IN: Device virtual BDF# */ uint16_t virt_bdf; /* IN: Device virtual BDF# */
/** @phy_bdf: physical bdf description of pass thru device */ /** physical bdf description of pass thru device */
uint16_t phys_bdf; /* IN: Device physical BDF# */ uint16_t phys_bdf; /* IN: Device physical BDF# */
/** union */
union { union {
/** struct intx - info of IOAPIC/PIC interrupt */ /** info of IOAPIC/PIC interrupt */
struct { struct {
/** @virt_pin: virtual IOAPIC pin */ /** virtual IOAPIC pin */
uint32_t virt_pin; uint32_t virt_pin;
/** @phys_pin: physical IOAPIC pin */ /** physical IOAPIC pin */
uint32_t phys_pin; uint32_t phys_pin;
/** @pic_pin: PIC pin */ /** PIC pin */
uint32_t is_pic_pin; uint32_t is_pic_pin;
} intx; } intx;
/** struct msix - info of MSI/MSIX interrupt */ /** info of MSI/MSIX interrupt */
struct { struct {
/* Keep this filed on top of msix */ /* Keep this filed on top of msix */
/** @vector_cnt: vector count of MSI/MSIX */ /** vector count of MSI/MSIX */
uint32_t vector_cnt; uint32_t vector_cnt;
/** @table_size: size of MSIX table(round up to 4K) */ /** size of MSIX table(round up to 4K) */
uint32_t table_size; uint32_t table_size;
/** @table_paddr: physical address of MSIX table */ /** physical address of MSIX table */
uint64_t table_paddr; uint64_t table_paddr;
} msix; } msix;
}; };
}; };
/** /**
* struct ioreq_notify - data strcture to notify hypervisor ioreq is handled * @brief data strcture to notify hypervisor ioreq is handled
*
* @client_id: client id to identify ioreq client
* @vcpu: identify the ioreq submitter
*/ */
struct ioreq_notify { struct ioreq_notify {
/** client id to identify ioreq client */
int32_t client_id; int32_t client_id;
/** identify the ioreq submitter */
uint32_t vcpu; uint32_t vcpu;
}; };
/** /**
* struct api_version - data structure to track VHM API version * @brief data structure to track VHM API version
*
* @major_version: major version of VHM API
* @minor_version: minor version of VHM API
*/ */
struct api_version { struct api_version {
/** major version of VHM API */
uint32_t major_version; uint32_t major_version;
/** minor version of VHM API */
uint32_t minor_version; uint32_t minor_version;
}; };
struct acrn_ioeventfd {
#define ACRN_IOEVENTFD_FLAG_PIO 0x01 #define ACRN_IOEVENTFD_FLAG_PIO 0x01
#define ACRN_IOEVENTFD_FLAG_DATAMATCH 0x02 #define ACRN_IOEVENTFD_FLAG_DATAMATCH 0x02
#define ACRN_IOEVENTFD_FLAG_DEASSIGN 0x04 #define ACRN_IOEVENTFD_FLAG_DEASSIGN 0x04
struct acrn_ioeventfd { /** file descriptor of the eventfd of this ioeventfd */
int32_t fd; int32_t fd;
/** flag for ioeventfd ioctl */
uint32_t flags; uint32_t flags;
/** base address to be monitored */
uint64_t addr; uint64_t addr;
/** address length */
uint32_t len; uint32_t len;
uint32_t reserved; uint32_t reserved;
/** data to be matched */
uint64_t data; uint64_t data;
}; };
#define ACRN_IRQFD_FLAG_DEASSIGN 0x01
struct acrn_irqfd { struct acrn_irqfd {
#define ACRN_IRQFD_FLAG_DEASSIGN 0x01
/** file descriptor of the eventfd of this irqfd */
int32_t fd; int32_t fd;
/** flag for irqfd ioctl */
uint32_t flags; uint32_t flags;
/** MSI interrupt to be injected */
struct acrn_msi_entry msi; struct acrn_msi_entry msi;
}; };
#endif /* VHM_IOCTL_DEFS_H */ #endif /* VHM_IOCTL_DEFS_H */

View File

@ -5,12 +5,25 @@
* *
*/ */
/**
* @file vhost.h
*
* @brief VHOST APIs for ACRN Project
*/
#ifndef __VHOST_H__ #ifndef __VHOST_H__
#define __VHOST_H__ #define __VHOST_H__
#include "virtio.h" #include "virtio.h"
#include "mevent.h" #include "mevent.h"
/**
* @brief vhost APIs
*
* @addtogroup acrn_virtio
* @{
*/
struct vhost_vq { struct vhost_vq {
int kick_fd; /**< fd of kick eventfd */ int kick_fd; /**< fd of kick eventfd */
int call_fd; /**< fd of call eventfd */ int call_fd; /**< fd of call eventfd */
@ -71,7 +84,7 @@ struct vhost_dev {
* @brief vhost_dev initialization. * @brief vhost_dev initialization.
* *
* This interface is called to initialize the vhost_dev. It must be called * This interface is called to initialize the vhost_dev. It must be called
* before the actual feature negoitiation with the guest OS starts. * before the actual feature negotiation with the guest OS starts.
* *
* @param vdev Pointer to struct vhost_dev. * @param vdev Pointer to struct vhost_dev.
* @param base Pointer to struct virtio_base. * @param base Pointer to struct virtio_base.
@ -133,4 +146,7 @@ int vhost_dev_stop(struct vhost_dev *vdev);
*/ */
int vhost_net_set_backend(struct vhost_dev *vdev, int backend_fd); int vhost_net_set_backend(struct vhost_dev *vdev, int backend_fd);
/**
* @}
*/
#endif #endif

View File

@ -698,15 +698,15 @@ struct iovec;
* @brief Link a virtio_base to its constants, the virtio device, * @brief Link a virtio_base to its constants, the virtio device,
* and the PCI emulation. * and the PCI emulation.
* *
* @param vb Pointer to struct virtio_base. * @param base Pointer to struct virtio_base.
* @param vo Pointer to struct virtio_ops. * @param vops Pointer to struct virtio_ops.
* @param pci_virtio_dev Pointer to instance of certain virtio device. * @param pci_virtio_dev Pointer to instance of certain virtio device.
* @param dev Pointer to struct pci_vdev which emulates a PCI device. * @param dev Pointer to struct pci_vdev which emulates a PCI device.
* @param queues Pointer to struct virtio_vq_info, normally an array. * @param queues Pointer to struct virtio_vq_info, normally an array.
* *
* @return NULL * @return NULL
*/ */
void virtio_linkup(struct virtio_base *vb, struct virtio_ops *vo, void virtio_linkup(struct virtio_base *base, struct virtio_ops *vops,
void *pci_virtio_dev, struct pci_vdev *dev, void *pci_virtio_dev, struct pci_vdev *dev,
struct virtio_vq_info *queues); struct virtio_vq_info *queues);
@ -717,24 +717,27 @@ void virtio_linkup(struct virtio_base *vb, struct virtio_ops *vo,
* Wrapper function for virtio_intr_init() for cases we directly use * Wrapper function for virtio_intr_init() for cases we directly use
* BAR 1 for MSI-X capabilities. * BAR 1 for MSI-X capabilities.
* *
* @param vb Pointer to struct virtio_base. * @param base Pointer to struct virtio_base.
* @param use_msix If using MSI-X. * @param use_msix If using MSI-X.
* *
* @return 0 on success and non-zero on fail. * @return 0 on success and non-zero on fail.
*/ */
int virtio_interrupt_init(struct virtio_base *vb, int use_msix); int virtio_interrupt_init(struct virtio_base *base, int use_msix);
/** /**
* @brief Initialize MSI-X vector capabilities if we're to use MSI-X, * @brief Initialize MSI-X vector capabilities if we're to use MSI-X,
* or MSI capabilities if not. * or MSI capabilities if not.
* *
* @param vb Pointer to struct virtio_base. * We assume we want one MSI-X vector per queue, here, plus one
* for the config vec.
*
* @param base Pointer to struct virtio_base.
* @param barnum Which BAR[0..5] to use. * @param barnum Which BAR[0..5] to use.
* @param use_msix If using MSI-X. * @param use_msix If using MSI-X.
* *
* @return 0 on success and non-zero on fail. * @return 0 on success and non-zero on fail.
*/ */
int virtio_intr_init(struct virtio_base *vb, int barnum, int use_msix); int virtio_intr_init(struct virtio_base *base, int barnum, int use_msix);
/** /**
* @brief Reset device (device-wide). * @brief Reset device (device-wide).
@ -743,21 +746,24 @@ int virtio_intr_init(struct virtio_base *vb, int barnum, int use_msix);
* But we don't wipe out the internal pointers, by just clearing * But we don't wipe out the internal pointers, by just clearing
* the VQ_ALLOC flag. * the VQ_ALLOC flag.
* *
* @param vb Pointer to struct virtio_base. * It resets negotiated features to "none".
* If MSI-X is enabled, this also resets all the vectors to NO_VECTOR.
*
* @param base Pointer to struct virtio_base.
* *
* @return N/A * @return N/A
*/ */
void virtio_reset_dev(struct virtio_base *vb); void virtio_reset_dev(struct virtio_base *base);
/** /**
* @brief Set I/O BAR (usually 0) to map PCI config registers. * @brief Set I/O BAR (usually 0) to map PCI config registers.
* *
* @param vb Pointer to struct virtio_base. * @param base Pointer to struct virtio_base.
* @param barnum Which BAR[0..5] to use. * @param barnum Which BAR[0..5] to use.
* *
* @return N/A * @return N/A
*/ */
void virtio_set_io_bar(struct virtio_base *vb, int barnum); void virtio_set_io_bar(struct virtio_base *base, int barnum);
/** /**
* @brief Walk through the chain of descriptors involved in a request * @brief Walk through the chain of descriptors involved in a request

View File

@ -12,6 +12,13 @@
#include "vbs_common_if.h" /* data format between VBS-U & VBS-K */ #include "vbs_common_if.h" /* data format between VBS-U & VBS-K */
/**
* @brief APIs for virtio backend in kernel module
*
* @addtogroup acrn_virtio
* @{
*/
enum VBS_K_STATUS { enum VBS_K_STATUS {
VIRTIO_DEV_INITIAL = 1, /* initial status */ VIRTIO_DEV_INITIAL = 1, /* initial status */
VIRTIO_DEV_PRE_INIT, /* detected thru cmdline option */ VIRTIO_DEV_PRE_INIT, /* detected thru cmdline option */
@ -30,12 +37,37 @@ enum VBS_K_STATUS {
#define VIRTIO_ERROR_GENERAL 5 #define VIRTIO_ERROR_GENERAL 5
/* VBS-K common ops */ /* VBS-K common ops */
/* VBS-K reset*/ /**
* @brief Virtio kernel module reset.
*
* @param fd File descriptor representing virtio backend in kernel module.
*
* @return 0 on OK and non-zero on error.
*/
int vbs_kernel_reset(int fd); int vbs_kernel_reset(int fd);
/* VBS-K start/stop */ /**
* @brief Virtio kernel module start.
*
* @param fd File descriptor representing virtio backend in kernel module.
* @param dev Pointer to struct vbs_dev_info.
* @param vqs Pointer to struct vbs_vqs_info.
*
* @return 0 on OK and non-zero on error.
*/
int vbs_kernel_start(int fd, struct vbs_dev_info *dev, int vbs_kernel_start(int fd, struct vbs_dev_info *dev,
struct vbs_vqs_info *vqs); struct vbs_vqs_info *vqs);
/**
* @brief Virtio kernel module stop.
*
* @param fd File descriptor representing virtio backend in kernel module.
*
* @return 0 on OK and non-zero on error.
*/
int vbs_kernel_stop(int fd); int vbs_kernel_stop(int fd);
/**
* @}
*/
#endif #endif

View File

@ -812,7 +812,12 @@ INPUT = custom-doxygen/mainpage.md \
../hypervisor/include/arch/x86/ioapic.h \ ../hypervisor/include/arch/x86/ioapic.h \
../hypervisor/include/arch/x86/irq.h \ ../hypervisor/include/arch/x86/irq.h \
../hypervisor/include/arch/x86/lapic.h \ ../hypervisor/include/arch/x86/lapic.h \
../hypervisor/include/common/irq.h ../hypervisor/include/common/irq.h \
../devicemodel/include/virtio_kernel.h \
../devicemodel/include/vhost.h \
../devicemodel/include/dm.h \
../devicemodel/include/pci_core.h \
../devicemodel/include/public/vhm_ioctl_defs.h
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses

View File

@ -383,13 +383,55 @@ common to all VBS-K modules, are the counterparts to preserve the
related information. The related information is necessary to kernel-land related information. The related information is necessary to kernel-land
vring service API helpers. vring service API helpers.
VHOST Key Data Structures
=========================
The key data structures for vhost are listed as follows.
.. doxygenstruct:: vhost_dev
:project: Project ACRN
.. doxygenstruct:: vhost_vq
:project: Project ACRN
DM APIs DM APIs
======= =======
The DM APIs are exported by DM, and they should be used when realizing The DM APIs are exported by DM, and they should be used when realizing
BE device drivers on ACRN. BE device drivers on ACRN.
[API Material from doxygen comments] .. doxygenfunction:: paddr_guest2host
:project: Project ACRN
.. doxygenfunction:: pci_set_cfgdata8
:project: Project ACRN
.. doxygenfunction:: pci_set_cfgdata16
:project: Project ACRN
.. doxygenfunction:: pci_set_cfgdata32
:project: Project ACRN
.. doxygenfunction:: pci_get_cfgdata8
:project: Project ACRN
.. doxygenfunction:: pci_get_cfgdata16
:project: Project ACRN
.. doxygenfunction:: pci_get_cfgdata32
:project: Project ACRN
.. doxygenfunction:: pci_lintr_assert
:project: Project ACRN
.. doxygenfunction:: pci_lintr_deassert
:project: Project ACRN
.. doxygenfunction:: pci_generate_msi
:project: Project ACRN
.. doxygenfunction:: pci_generate_msix
:project: Project ACRN
VBS APIs VBS APIs
======== ========
@ -404,7 +446,41 @@ VBS-U APIs
These APIs provided by VBS-U are callbacks to be registered to DM, and These APIs provided by VBS-U are callbacks to be registered to DM, and
the virtio framework within DM will invoke them appropriately. the virtio framework within DM will invoke them appropriately.
[API Material from doxygen comments] .. doxygenstruct:: virtio_ops
:project: Project ACRN
.. doxygenfunction:: virtio_pci_read
:project: Project ACRN
.. doxygenfunction:: virtio_pci_write
:project: Project ACRN
.. doxygenfunction:: virtio_dev_error
:project: Project ACRN
.. doxygenfunction:: virtio_interrupt_init
:project: Project ACRN
.. doxygenfunction:: virtio_linkup
:project: Project ACRN
.. doxygenfunction:: virtio_reset_dev
:project: Project ACRN
.. doxygenfunction:: virtio_set_io_bar
:project: Project ACRN
.. doxygenfunction:: virtio_set_modern_bar
:project: Project ACRN
.. doxygenfunction:: virtio_pci_modern_cfgread
:project: Project ACRN
.. doxygenfunction:: virtio_pci_modern_cfgwrite
:project: Project ACRN
.. doxygenfunction:: virtio_config_changed
:project: Project ACRN
VBS-K APIs VBS-K APIs
---------- ----------
@ -415,12 +491,92 @@ the following APIs to implement their VBS-K modules.
APIs provided by DM APIs provided by DM
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
[API Material from doxygen comments] .. doxygenfunction:: vbs_kernel_reset
:project: Project ACRN
.. doxygenfunction:: vbs_kernel_start
:project: Project ACRN
.. doxygenfunction:: vbs_kernel_stop
:project: Project ACRN
APIs provided by VBS-K modules in service OS APIs provided by VBS-K modules in service OS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[API Material from doxygen comments] .. kernel-doc:: include/linux/vbs/vbs.h
:functions: virtio_dev_init
virtio_dev_ioctl
virtio_vqs_ioctl
virtio_dev_register
virtio_dev_deregister
virtio_vqs_index_get
virtio_dev_reset
VHOST APIS
==========
APIs provided by DM
-------------------
.. doxygenfunction:: vhost_dev_init
:project: Project ACRN
.. doxygenfunction:: vhost_dev_deinit
:project: Project ACRN
.. doxygenfunction:: vhost_dev_start
:project: Project ACRN
.. doxygenfunction:: vhost_dev_stop
:project: Project ACRN
Linux vhost IOCTLs
------------------
``#define VHOST_GET_FEATURES _IOR(VHOST_VIRTIO, 0x00, __u64)``
This IOCTL is used to get the supported feature flags by vhost kernel driver.
``#define VHOST_SET_FEATURES _IOW(VHOST_VIRTIO, 0x00, __u64)``
This IOCTL is used to set the supported feature flags to vhost kernel driver.
``#define VHOST_SET_OWNER _IO(VHOST_VIRTIO, 0x01)``
This IOCTL is used to set current process as the exclusive owner of the vhost
char device. It must be called before any other vhost commands.
``#define VHOST_RESET_OWNER _IO(VHOST_VIRTIO, 0x02)``
This IOCTL is used to give up the ownership of the vhost char device.
``#define VHOST_SET_MEM_TABLE _IOW(VHOST_VIRTIO, 0x03, struct vhost_memory)``
This IOCTL is used to convey the guest OS memory layout to vhost kernel driver.
``#define VHOST_SET_VRING_NUM _IOW(VHOST_VIRTIO, 0x10, struct vhost_vring_state)``
This IOCTL is used to set the number of descriptors in virtio ring. It cannot
be modified while the virtio ring is running.
``#define VHOST_SET_VRING_ADDR _IOW(VHOST_VIRTIO, 0x11, struct vhost_vring_addr)``
This IOCTL is used to set the address of the virtio ring.
``#define VHOST_SET_VRING_BASE _IOW(VHOST_VIRTIO, 0x12, struct vhost_vring_state)``
This IOCTL is used to set the base value where virtqueue looks for available
descriptors.
``#define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state)``
This IOCTL is used to get the base value where virtqueue looks for available
descriptors.
``#define VHOST_SET_VRING_KICK _IOW(VHOST_VIRTIO, 0x20, struct vhost_vring_file)``
This IOCTL is used to set the eventfd on which vhost can poll for guest
virtqueue kicks.
``#define VHOST_SET_VRING_CALL _IOW(VHOST_VIRTIO, 0x21, struct vhost_vring_file)``
This IOCTL is used to set the eventfd which is used by vhost do inject
virtual interrupt.
VHM eventfd IOCTLs
------------------
.. doxygenstruct:: acrn_ioeventfd
:project: Project ACRN
``#define IC_EVENT_IOEVENTFD _IC_ID(IC_ID, IC_ID_EVENT_BASE + 0x00)``
This IOCTL is used to register/unregister ioeventfd with appropriate address,
length and data value.
.. doxygenstruct:: acrn_irqfd
:project: Project ACRN
``#define IC_EVENT_IRQFD _IC_ID(IC_ID, IC_ID_EVENT_BASE + 0x01)``
This IOCTL is used to register/unregister irqfd with appropriate MSI information.
VQ APIs VQ APIs
======= =======
@ -433,7 +589,20 @@ to be identical between VBS-U and VBS-K, so that users don't need to
learn different APIs when implementing BE drivers based on VBS-U and learn different APIs when implementing BE drivers based on VBS-U and
VBS-K. VBS-K.
[API Material from doxygen comments] .. doxygenfunction:: vq_interrupt
:project: Project ACRN
.. doxygenfunction:: vq_getchain
:project: Project ACRN
.. doxygenfunction:: vq_retchain
:project: Project ACRN
.. doxygenfunction:: vq_relchain
:project: Project ACRN
.. doxygenfunction:: vq_endchains
:project: Project ACRN
Below is an example showing a typical logic of how a BE driver handles Below is an example showing a typical logic of how a BE driver handles
requests from a FE driver. requests from a FE driver.