Message ID | 791f5f9a010b14844e5210c4390c8628ffefb80d.1626722742.git.jag.raman@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | vfio-user server in QEMU | expand |
On Mon, Jul 19, 2021 at 04:00:08PM -0400, Jagannathan Raman wrote: > Define and register handlers for PCI config space accesses > > Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com> > Signed-off-by: John G Johnson <john.g.johnson@oracle.com> > Signed-off-by: Jagannathan Raman <jag.raman@oracle.com> > --- > hw/remote/vfio-user-obj.c | 41 +++++++++++++++++++++++++++++++++++++++++ > hw/remote/trace-events | 2 ++ > 2 files changed, 43 insertions(+) > > diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c > index 6a2d0f5..60d9fa8 100644 > --- a/hw/remote/vfio-user-obj.c > +++ b/hw/remote/vfio-user-obj.c > @@ -36,6 +36,7 @@ > #include "sysemu/runstate.h" > #include "qemu/notify.h" > #include "qemu/thread.h" > +#include "qemu/main-loop.h" > #include "qapi/error.h" > #include "sysemu/sysemu.h" > #include "hw/qdev-core.h" > @@ -131,6 +132,35 @@ static void *vfu_object_ctx_run(void *opaque) > return NULL; > } > > +static ssize_t vfu_object_cfg_access(vfu_ctx_t *vfu_ctx, char * const buf, > + size_t count, loff_t offset, > + const bool is_write) > +{ > + VfuObject *o = vfu_get_private(vfu_ctx); > + uint32_t val = 0; > + int i; > + > + qemu_mutex_lock_iothread(); > + > + for (i = 0; i < count; i++) { > + if (is_write) { > + val = *((uint8_t *)(buf + i)); > + trace_vfu_cfg_write((offset + i), val); > + pci_default_write_config(PCI_DEVICE(o->pci_dev), > + (offset + i), val, 1); > + } else { > + val = pci_default_read_config(PCI_DEVICE(o->pci_dev), > + (offset + i), 1); > + *((uint8_t *)(buf + i)) = (uint8_t)val; > + trace_vfu_cfg_read((offset + i), val); > + } > + } Is it always OK to split up the access into single bytes like this? regards john
diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c index 6a2d0f5..60d9fa8 100644 --- a/hw/remote/vfio-user-obj.c +++ b/hw/remote/vfio-user-obj.c @@ -36,6 +36,7 @@ #include "sysemu/runstate.h" #include "qemu/notify.h" #include "qemu/thread.h" +#include "qemu/main-loop.h" #include "qapi/error.h" #include "sysemu/sysemu.h" #include "hw/qdev-core.h" @@ -131,6 +132,35 @@ static void *vfu_object_ctx_run(void *opaque) return NULL; } +static ssize_t vfu_object_cfg_access(vfu_ctx_t *vfu_ctx, char * const buf, + size_t count, loff_t offset, + const bool is_write) +{ + VfuObject *o = vfu_get_private(vfu_ctx); + uint32_t val = 0; + int i; + + qemu_mutex_lock_iothread(); + + for (i = 0; i < count; i++) { + if (is_write) { + val = *((uint8_t *)(buf + i)); + trace_vfu_cfg_write((offset + i), val); + pci_default_write_config(PCI_DEVICE(o->pci_dev), + (offset + i), val, 1); + } else { + val = pci_default_read_config(PCI_DEVICE(o->pci_dev), + (offset + i), 1); + *((uint8_t *)(buf + i)) = (uint8_t)val; + trace_vfu_cfg_read((offset + i), val); + } + } + + qemu_mutex_unlock_iothread(); + + return count; +} + static void vfu_object_machine_done(Notifier *notifier, void *data) { VfuObject *o = container_of(notifier, VfuObject, machine_done); @@ -167,6 +197,17 @@ static void vfu_object_machine_done(Notifier *notifier, void *data) pci_get_word(o->pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID), pci_get_word(o->pci_dev->config + PCI_SUBSYSTEM_ID)); + ret = vfu_setup_region(o->vfu_ctx, VFU_PCI_DEV_CFG_REGION_IDX, + pci_config_size(o->pci_dev), &vfu_object_cfg_access, + VFU_REGION_FLAG_RW | VFU_REGION_FLAG_ALWAYS_CB, + NULL, 0, -1, 0); + if (ret < 0) { + error_setg(&error_abort, + "vfu: Failed to setup config space handlers for %s- %s", + o->devid, strerror(errno)); + return; + } + qemu_thread_create(&o->vfu_ctx_thread, "VFU ctx runner", vfu_object_ctx_run, o, QEMU_THREAD_JOINABLE); } diff --git a/hw/remote/trace-events b/hw/remote/trace-events index 7da12f0..2ef7884 100644 --- a/hw/remote/trace-events +++ b/hw/remote/trace-events @@ -5,3 +5,5 @@ mpqemu_recv_io_error(int cmd, int size, int nfds) "failed to receive %d size %d, # vfio-user-obj.c vfu_prop(const char *prop, const char *val) "vfu: setting %s as %s" +vfu_cfg_read(uint32_t offset, uint32_t val) "vfu: cfg: 0x%u -> 0x%x" +vfu_cfg_write(uint32_t offset, uint32_t val) "vfu: cfg: 0x%u <- 0x%x"