diff options
author | Jag Raman <jraman567@gmail.com> | 2021-07-13 12:18:33 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-13 17:18:33 +0100 |
commit | e0c15dfd087f8093ee6aab697e9ac2a252ab42bb (patch) | |
tree | f853f527ae541c03b16055cc1efc5c53e3382ec2 | |
parent | f44091db918d54211cb43683b091c61a6177d450 (diff) | |
download | libvfio-user-e0c15dfd087f8093ee6aab697e9ac2a252ab42bb.zip libvfio-user-e0c15dfd087f8093ee6aab697e9ac2a252ab42bb.tar.gz libvfio-user-e0c15dfd087f8093ee6aab697e9ac2a252ab42bb.tar.bz2 |
add VFU_REGION_FLAG_ALWAYS_CB to receive callback always (#583)
-rw-r--r-- | include/libvfio-user.h | 3 | ||||
-rw-r--r-- | lib/libvfio-user.c | 11 | ||||
-rw-r--r-- | test/py/libvfio_user.py | 1 | ||||
-rw-r--r-- | test/py/test_setup_region.py | 35 |
4 files changed, 48 insertions, 2 deletions
diff --git a/include/libvfio-user.h b/include/libvfio-user.h index 75de04e..4b08c22 100644 --- a/include/libvfio-user.h +++ b/include/libvfio-user.h @@ -221,6 +221,7 @@ typedef ssize_t (vfu_region_access_cb_t)(vfu_ctx_t *vfu_ctx, char *buf, #define VFU_REGION_FLAG_WRITE (1 << 1) #define VFU_REGION_FLAG_RW (VFU_REGION_FLAG_READ | VFU_REGION_FLAG_WRITE) #define VFU_REGION_FLAG_MEM (1 << 2) // if unset, bar is IO +#define VFU_REGION_FLAG_ALWAYS_CB (1 << 3) /** * Set up a device region. @@ -262,6 +263,8 @@ typedef ssize_t (vfu_region_access_cb_t)(vfu_ctx_t *vfu_ctx, char *buf, * - if no callback is provided, reads to other areas are a simple memcpy(), * and writes are an error * - otherwise, the callback is expected to handle the access + * - if VFU_REGION_FLAG_ALWAYS_CB flag is set, all accesses to the config + * space are forwarded to the callback * * Regions VFU_PCI_DEV_MIGR_REGION_IDX and VFU_GENERIC_DEV_MIGR_REG_IDX, * corresponding to the migration region, enable live migration support for diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c index a90d9c2..1ee4026 100644 --- a/lib/libvfio-user.c +++ b/lib/libvfio-user.c @@ -208,7 +208,8 @@ region_access(vfu_ctx_t *vfu_ctx, size_t region_index, char *buf, dump_buffer("buffer write", buf, count); } - if (region_index == VFU_PCI_DEV_CFG_REGION_IDX) { + if ((region_index == VFU_PCI_DEV_CFG_REGION_IDX) && + !(vfu_ctx->reg_info[region_index].flags & VFU_REGION_FLAG_ALWAYS_CB)) { ret = pci_config_space_access(vfu_ctx, buf, count, offset, is_write); if (ret == -1) { return ret; @@ -1445,7 +1446,13 @@ vfu_setup_region(vfu_ctx_t *vfu_ctx, int region_idx, size_t size, * PCI config space is never mappable or of type mem. */ if (region_idx == VFU_PCI_DEV_CFG_REGION_IDX && - flags != VFU_REGION_FLAG_RW) { + (((flags & VFU_REGION_FLAG_RW) != VFU_REGION_FLAG_RW) || + (flags & VFU_REGION_FLAG_MEM))) { + return ERROR_INT(EINVAL); + } + + if ((flags & VFU_REGION_FLAG_ALWAYS_CB) && (cb == NULL)) { + vfu_log(vfu_ctx, LOG_ERR, "VFU_REGION_FLAG_ALWAYS_CB needs callback"); return ERROR_INT(EINVAL); } diff --git a/test/py/libvfio_user.py b/test/py/libvfio_user.py index 70986fa..ff5c1cd 100644 --- a/test/py/libvfio_user.py +++ b/test/py/libvfio_user.py @@ -156,6 +156,7 @@ VFU_REGION_FLAG_READ = 1 VFU_REGION_FLAG_WRITE = 2 VFU_REGION_FLAG_RW = (VFU_REGION_FLAG_READ | VFU_REGION_FLAG_WRITE) VFU_REGION_FLAG_MEM = 4 +VFU_REGION_FLAG_ALWAYS_CB = 8 VFIO_USER_F_DMA_REGION_READ = (1 << 0) VFIO_USER_F_DMA_REGION_WRITE = (1 << 1) diff --git a/test/py/test_setup_region.py b/test/py/test_setup_region.py index 0bf120d..c42100f 100644 --- a/test/py/test_setup_region.py +++ b/test/py/test_setup_region.py @@ -114,5 +114,40 @@ def test_setup_region_bad_migr(): assert ret == -1 assert c.get_errno() == errno.EINVAL +def test_setup_region_cfg_always_cb_nocb(): + ret = vfu_setup_region(ctx, index=VFU_PCI_DEV_CFG_REGION_IDX, + size=PCI_CFG_SPACE_EXP_SIZE, cb=None, + flags=(VFU_REGION_FLAG_RW | + VFU_REGION_FLAG_ALWAYS_CB)) + assert ret == -1 + assert c.get_errno() == errno.EINVAL + +@vfu_region_access_cb_t +def pci_cfg_region_cb(ctx, buf, count, offset, is_write): + if not is_write: + for i in range(count): + buf[i] = 0xcc + + return count + +def test_setup_region_cfg_always_cb(): + global ctx + + ret = vfu_setup_region(ctx, index=VFU_PCI_DEV_CFG_REGION_IDX, + size=PCI_CFG_SPACE_EXP_SIZE, cb=pci_cfg_region_cb, + flags=(VFU_REGION_FLAG_RW | + VFU_REGION_FLAG_ALWAYS_CB)) + assert ret == 0 + + ret = vfu_realize_ctx(ctx) + assert ret == 0 + + sock = connect_client(ctx) + + payload = read_region(ctx, sock, VFU_PCI_DEV_CFG_REGION_IDX, offset=0, count=2) + assert payload == b'\xcc\xcc' + + disconnect_client(ctx, sock) + def test_setup_region_cleanup(): vfu_destroy_ctx(ctx) |