aboutsummaryrefslogtreecommitdiff
path: root/lib/libvfio-user.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libvfio-user.c')
-rw-r--r--lib/libvfio-user.c183
1 files changed, 15 insertions, 168 deletions
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index 599b17f..6d75e15 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -51,11 +51,12 @@
#include "cap.h"
#include "dma.h"
+#include "irq.h"
#include "libvfio-user.h"
+#include "migration.h"
+#include "pci.h"
#include "private.h"
#include "tran_sock.h"
-#include "migration.h"
-#include "irq.h"
void
vfu_log(vfu_ctx_t *vfu_ctx, int level, const char *fmt, ...)
@@ -77,13 +78,6 @@ vfu_log(vfu_ctx_t *vfu_ctx, int level, const char *fmt, ...)
errno = _errno;
}
-static inline int
-ERROR(int err)
-{
- errno = err;
- return -1;
-}
-
static size_t
get_vfio_caps_size(bool is_migr_reg, struct vfu_sparse_mmap_areas *m)
{
@@ -171,21 +165,6 @@ dev_get_caps(vfu_ctx_t *vfu_ctx, vfu_reg_info_t *vfu_reg, bool is_migr_reg,
return 0;
}
-#define VFU_REGION_SHIFT 40
-#define VFU_REGION_MASK ((1ULL << VFU_REGION_SHIFT) - 1)
-
-uint64_t
-region_to_offset(uint32_t region)
-{
- return (uint64_t)region << VFU_REGION_SHIFT;
-}
-
-uint32_t
-offset_to_region(uint64_t offset)
-{
- return (offset >> VFU_REGION_SHIFT) & VFU_REGION_MASK;
-}
-
#ifdef VFU_VERBOSE_LOGGING
void
dump_buffer(const char *prefix, const char *buf, uint32_t count)
@@ -293,47 +272,6 @@ vfu_get_region(loff_t pos, size_t count, loff_t *off)
return r;
}
-static uint32_t
-region_size(vfu_ctx_t *vfu_ctx, int region)
-{
- assert(region >= VFU_PCI_DEV_BAR0_REGION_IDX && region <= VFU_PCI_DEV_VGA_REGION_IDX);
- return vfu_ctx->reg_info[region].size;
-}
-
-static uint32_t
-pci_config_space_size(vfu_ctx_t *vfu_ctx)
-{
- return region_size(vfu_ctx, VFU_PCI_DEV_CFG_REGION_IDX);
-}
-
-/*
- * Accesses the non-standard part (offset >= 0x40) of the PCI configuration
- * space.
- */
-static ssize_t
-handle_pci_config_space_access(vfu_ctx_t *vfu_ctx, char *buf, size_t count,
- loff_t pos, bool is_write)
-{
- int ret;
-
- count = MIN(pci_config_space_size(vfu_ctx), count);
- if (is_write) {
- ret = cap_maybe_access(vfu_ctx, vfu_ctx->pci.caps, buf, count, pos);
- if (ret < 0) {
- vfu_log(vfu_ctx, LOG_ERR, "bad access to capabilities %#lx-%#lx\n",
- pos, pos + count);
- return ret;
- }
- } else {
- /*
- * It is legitimate to read the non-standard part of the PCI config
- * space even if there are no capabilities.
- */
- memcpy(buf, vfu_ctx->pci.config_space->raw + pos, count);
- }
- return count;
-}
-
static ssize_t
do_access(vfu_ctx_t *vfu_ctx, char *buf, uint8_t count, uint64_t pos, bool is_write)
{
@@ -356,8 +294,7 @@ do_access(vfu_ctx_t *vfu_ctx, char *buf, uint8_t count, uint64_t pos, bool is_wr
}
if (idx == VFU_PCI_DEV_CFG_REGION_IDX) {
- return handle_pci_config_space_access(vfu_ctx, buf, count, offset,
- is_write);
+ return pci_config_space_access(vfu_ctx, buf, count, offset, is_write);
}
if (is_migr_reg(vfu_ctx, idx)) {
@@ -465,18 +402,21 @@ vfu_access(vfu_ctx_t *vfu_ctx, bool is_write, char *rwbuf, uint32_t count,
#endif
_count = count;
- ret = vfu_pci_hdr_access(vfu_ctx, &_count, pos, is_write, rwbuf);
- if (ret != 0) {
- /* FIXME shouldn't we fail here? */
- vfu_log(vfu_ctx, LOG_ERR, "failed to access PCI header: %s",
- strerror(-ret));
+
+ if (pci_is_hdr_access(*pos)) {
+ ret = pci_hdr_access(vfu_ctx, &_count, pos, is_write, rwbuf);
+ if (ret != 0) {
+ /* FIXME shouldn't we fail here? */
+ vfu_log(vfu_ctx, LOG_ERR, "failed to access PCI header: %s",
+ strerror(-ret));
#ifdef VFU_VERBOSE_LOGGING
- dump_buffer("buffer write", rwbuf, _count);
+ dump_buffer("buffer write", rwbuf, _count);
#endif
+ }
}
/*
- * count is how much has been processed by vfu_pci_hdr_access,
+ * count is how much has been processed by pci_hdr_access,
* _count is how much there's left to be processed by vfu_access
*/
processed = count - _count;
@@ -1151,7 +1091,7 @@ vfu_realize_ctx(vfu_ctx_t *vfu_ctx)
cfg_reg->size = PCI_CFG_SPACE_SIZE;
}
- // This maybe allocated by vfu_setup_pci_config_hdr().
+ // This may have been allocated by vfu_setup_pci_config_hdr().
if (vfu_ctx->pci.config_space == NULL) {
vfu_ctx->pci.config_space = calloc(1, cfg_reg->size);
if (vfu_ctx->pci.config_space == NULL) {
@@ -1285,12 +1225,6 @@ vfu_attach_ctx(vfu_ctx_t *vfu_ctx)
return vfu_ctx->trans->attach(vfu_ctx);
}
-bool
-is_valid_pci_type(vfu_pci_type_t t)
-{
- return t >= VFU_PCI_TYPE_CONVENTIONAL && t <= VFU_PCI_TYPE_EXPRESS;
-}
-
vfu_ctx_t *
vfu_create_ctx(vfu_trans_t trans, const char *path, int flags, void *pvt,
vfu_dev_type_t dev_type)
@@ -1380,83 +1314,6 @@ vfu_setup_log(vfu_ctx_t *vfu_ctx, vfu_log_fn_t *log, int log_level)
return 0;
}
-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)))
-{
- vfu_pci_config_space_t *config_space;
- size_t size;
-
- assert(vfu_ctx != NULL);
-
- /*
- * TODO there no real reason why we shouldn't allow this, we should just
- * clean up and redo it.
- */
- if (vfu_ctx->pci.config_space != NULL) {
- vfu_log(vfu_ctx, LOG_ERR, "PCI configuration space header already setup");
- return ERROR(EEXIST);
- }
-
- vfu_ctx->pci.type = pci_type;
- switch (vfu_ctx->pci.type) {
- case VFU_PCI_TYPE_CONVENTIONAL:
- case VFU_PCI_TYPE_PCI_X_1:
- size = PCI_CFG_SPACE_SIZE;
- break;
- case VFU_PCI_TYPE_PCI_X_2:
- case VFU_PCI_TYPE_EXPRESS:
- size = PCI_CFG_SPACE_EXP_SIZE;
- break;
- default:
- vfu_log(vfu_ctx, LOG_ERR, "invalid PCI type %d", pci_type);
- return ERROR(EINVAL);
- }
-
- // Allocate a buffer for the config space.
- config_space = calloc(1, size);
- if (config_space == NULL) {
- return ERROR(ENOMEM);
- }
-
- config_space->hdr.id = id;
- config_space->hdr.ss = ss;
- config_space->hdr.cc = cc;
- vfu_ctx->pci.config_space = config_space;
- vfu_ctx->reg_info[VFU_PCI_DEV_CFG_REGION_IDX].size = size;
-
- return 0;
-}
-
-int
-vfu_pci_setup_caps(vfu_ctx_t *vfu_ctx, vfu_cap_t **caps, int nr_caps)
-{
- int ret;
-
- assert(vfu_ctx != NULL);
-
- if (vfu_ctx->pci.caps != NULL) {
- vfu_log(vfu_ctx, LOG_ERR, "capabilities are already setup");
- return ERROR(EEXIST);
- }
-
- if (caps == NULL || nr_caps == 0) {
- vfu_log(vfu_ctx, LOG_ERR, "Invalid args passed");
- return ERROR(EINVAL);
- }
-
- vfu_ctx->pci.caps = caps_create(vfu_ctx, caps, nr_caps, &ret);
- if (vfu_ctx->pci.caps == NULL) {
- vfu_log(vfu_ctx, LOG_ERR, "failed to create PCI capabilities: %s",
- strerror(ret));
- return ERROR(ret);
- }
-
- return 0;
-}
-
static int
copy_sparse_mmap_areas(vfu_reg_info_t *reg_info,
struct iovec *mmap_areas, uint32_t nr_mmap_areas)
@@ -1633,16 +1490,6 @@ vfu_setup_device_migration(vfu_ctx_t *vfu_ctx, vfu_migration_t *migration)
return 0;
}
-/*
- * Returns a pointer to the PCI configuration space.
- */
-inline vfu_pci_config_space_t *
-vfu_pci_get_config_space(vfu_ctx_t *vfu_ctx)
-{
- assert(vfu_ctx != NULL);
- return vfu_ctx->pci.config_space;
-}
-
inline vfu_reg_info_t *
vfu_get_region_info(vfu_ctx_t *vfu_ctx)
{