diff options
author | Thanos Makatos <thanos.makatos@nutanix.com> | 2020-12-08 10:58:29 -0500 |
---|---|---|
committer | Thanos Makatos <tmakatos@gmail.com> | 2020-12-11 12:54:21 +0000 |
commit | 90211fbd2c7c310df593736b18f1c99f053e2957 (patch) | |
tree | 03462a28541581cbf3ea6eb8f9fde05591c3e893 /lib | |
parent | a7ecdc3de9f237d600ceaaa44285115a4e790829 (diff) | |
download | libvfio-user-90211fbd2c7c310df593736b18f1c99f053e2957.zip libvfio-user-90211fbd2c7c310df593736b18f1c99f053e2957.tar.gz libvfio-user-90211fbd2c7c310df593736b18f1c99f053e2957.tar.bz2 |
add support PCI vendor-specific capability
The PCI vendor-specific capability is blindly read/written by the
library. It is possible that the user might want to intercept accesses
to it, in which case we'll have to add callback. The best way to do this
to introduce a new function that configures callbacks for the PCI
capabilities, e.g.
typedef ssize_t (vfu_cap_access_t) (void *pvt, uint8_t id,
char *buf, size_t count, loff_t offset, bool is_write);
vfu_pci_cap_set_cb(vfu_ctx-T *vfu_ctx, uint8_t cap_id,
vfu_cap_access_t *cb);
This way the existing API won't have to change.
Signed-off-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/cap.c | 23 |
1 files changed, 19 insertions, 4 deletions
@@ -373,12 +373,23 @@ handle_px_write(vfu_ctx_t *vfu_ctx, uint8_t *cap, char *const buf, return count; } +static ssize_t +handle_vsc_write(vfu_ctx_t *vfu_ctx __attribute__ ((unused)), uint8_t *cap, + char *const buf, const size_t count, const loff_t offset) +{ + /* FIXME we shouldn't allow then length field to be modified, right? */ + + memcpy(cap + offset, buf, count); + return count; +} + static const struct cap_handler { char *name; size_t size; cap_access *fn; } cap_handlers[PCI_CAP_ID_MAX + 1] = { [PCI_CAP_ID_PM] = {"PM", PCI_PM_SIZEOF, handle_pm_write}, + [PCI_CAP_ID_VNDR] = {"Vendor-Specific", 0, handle_vsc_write}, [PCI_CAP_ID_EXP] = {"PCI Express", PCI_CAP_EXP_ENDPOINT_SIZEOF_V2, handle_px_write}, [PCI_CAP_ID_MSIX] = {"MSI-X", PCI_CAP_MSIX_SIZEOF, handle_msix_write}, @@ -456,10 +467,14 @@ caps_create(vfu_ctx_t *vfu_ctx, vfu_cap_t **vfu_caps, int nr_caps, int *err) goto err_out; } - size = cap_handlers[id].size; - if (size == 0) { - *err = ENOTSUP; - goto err_out; + if (id == PCI_CAP_ID_VNDR) { + size = cap[PCI_CAP_LIST_NEXT + 1]; + } else { + size = cap_handlers[id].size; + if (size == 0) { + *err = ENOTSUP; + goto err_out; + } } caps->caps[i].start = next; |