This command is used to request the bar type info from remote device. Signed-off-by: Elena Ufimtseva <elena.ufimts...@oracle.com> --- include/hw/remote/ioregionfd.h | 2 ++ include/hw/remote/machine.h | 1 + include/hw/remote/mpqemu-link.h | 2 ++ hw/remote/ioregionfd.c | 28 ++++++++++++++++++++++++ hw/remote/message.c | 38 +++++++++++++++++++++++++++++++++ hw/remote/remote-obj.c | 1 + 6 files changed, 72 insertions(+)
diff --git a/include/hw/remote/ioregionfd.h b/include/hw/remote/ioregionfd.h index 85a2ef2c4f..66bb459f76 100644 --- a/include/hw/remote/ioregionfd.h +++ b/include/hw/remote/ioregionfd.h @@ -38,4 +38,6 @@ struct IORegionFDObject { typedef struct IORegionFDObject IORegionFDObject; GSList *ioregionfd_get_obj_list(void); +IORegionFD *ioregionfd_get_by_bar(GSList *list, uint32_t bar); +void ioregionfd_set_bar_type(GSList *list, uint32_t bar, bool memory); #endif /* IOREGIONFD_H */ diff --git a/include/hw/remote/machine.h b/include/hw/remote/machine.h index 2a2a33c4b2..71c53ba0d7 100644 --- a/include/hw/remote/machine.h +++ b/include/hw/remote/machine.h @@ -28,6 +28,7 @@ struct RemoteMachineState { typedef struct RemoteCommDev { PCIDevice *dev; QIOChannel *ioc; + GSList *ioregions_list; } RemoteCommDev; #define TYPE_REMOTE_MACHINE "x-remote-machine" diff --git a/include/hw/remote/mpqemu-link.h b/include/hw/remote/mpqemu-link.h index 4ec0915885..be546e4586 100644 --- a/include/hw/remote/mpqemu-link.h +++ b/include/hw/remote/mpqemu-link.h @@ -17,6 +17,7 @@ #include "exec/hwaddr.h" #include "io/channel-socket.h" #include "hw/remote/proxy.h" +#include "hw/remote/ioregionfd.h" #define REMOTE_MAX_FDS 8 @@ -41,6 +42,7 @@ typedef enum { MPQEMU_CMD_BAR_READ, MPQEMU_CMD_SET_IRQFD, MPQEMU_CMD_DEVICE_RESET, + MPQEMU_CMD_BAR_INFO, MPQEMU_CMD_MAX, } MPQemuCmd; diff --git a/hw/remote/ioregionfd.c b/hw/remote/ioregionfd.c index 85ec0f7d38..1d371357c6 100644 --- a/hw/remote/ioregionfd.c +++ b/hw/remote/ioregionfd.c @@ -63,6 +63,34 @@ GSList *ioregionfd_get_obj_list(void) return list; } +IORegionFD *ioregionfd_get_by_bar(GSList *list, uint32_t bar) +{ + IORegionFDObject *ioregionfd; + GSList *elem; + + for (elem = list; elem; elem = elem->next) { + ioregionfd = elem->data; + + if (ioregionfd->ioregfd.bar == bar) { + return &ioregionfd->ioregfd; + } + } + return NULL; +} + +void ioregionfd_set_bar_type(GSList *list, uint32_t bar, bool memory) +{ + IORegionFDObject *ioregionfd; + GSList *elem; + + for (elem = list; elem; elem = elem->next) { + ioregionfd = elem->data; + if (ioregionfd->ioregfd.bar == bar) { + ioregionfd->ioregfd.memory = memory; + } + } +} + static void ioregionfd_object_init(Object *obj) { IORegionFDObjectClass *k = IOREGIONFD_OBJECT_GET_CLASS(obj); diff --git a/hw/remote/message.c b/hw/remote/message.c index 11d729845c..a8fb9764ba 100644 --- a/hw/remote/message.c +++ b/hw/remote/message.c @@ -29,6 +29,8 @@ static void process_bar_write(QIOChannel *ioc, MPQemuMsg *msg, Error **errp); static void process_bar_read(QIOChannel *ioc, MPQemuMsg *msg, Error **errp); static void process_device_reset_msg(QIOChannel *ioc, PCIDevice *dev, Error **errp); +static void process_device_get_reg_info(QIOChannel *ioc, RemoteCommDev *com, + MPQemuMsg *msg, Error **errp); void coroutine_fn mpqemu_remote_msg_loop_co(void *data) { @@ -75,6 +77,9 @@ void coroutine_fn mpqemu_remote_msg_loop_co(void *data) case MPQEMU_CMD_DEVICE_RESET: process_device_reset_msg(com->ioc, pci_dev, &local_err); break; + case MPQEMU_CMD_BAR_INFO: + process_device_get_reg_info(com->ioc, com, &msg, &local_err); + break; default: error_setg(&local_err, "Unknown command (%d) received for device %s" @@ -91,6 +96,39 @@ void coroutine_fn mpqemu_remote_msg_loop_co(void *data) } } +static void process_device_get_reg_info(QIOChannel *ioc, RemoteCommDev *com, + MPQemuMsg *msg, Error **errp) +{ + ERRP_GUARD(); + uint32_t bar = (uint32_t)(msg->data.u64 & MAKE_64BIT_MASK(0, 32)); + bool memory; + + memory = (msg->data.u64 && MAKE_64BIT_MASK(32, 32)) == 1 ? true : false; + + IORegionFD *ioregfd; + MPQemuMsg ret = { 0 }; + + error_report("Bar is %d, mem %s", bar, memory ? "true" : "false"); + + memset(&ret, 0, sizeof(MPQemuMsg)); + ret.cmd = MPQEMU_CMD_RET; + ret.size = sizeof(ret.data.u64); + + ioregfd = ioregionfd_get_by_bar(com->ioregions_list, bar); + if (ioregfd) { + ret.data.u64 = ioregfd->bar; + if (ioregfd->memory != memory) { + ioregionfd_set_bar_type(com->ioregions_list, bar, memory); + } + } else { + ret.data.u64 = UINT64_MAX; + } + if (!mpqemu_msg_send(&ret, ioc, NULL)) { + error_prepend(errp, "Error returning code to proxy, pid "FMT_pid": ", + getpid()); + } +} + static void process_config_write(QIOChannel *ioc, PCIDevice *dev, MPQemuMsg *msg, Error **errp) { diff --git a/hw/remote/remote-obj.c b/hw/remote/remote-obj.c index 9bb61c3a2d..46c2e2a5bd 100644 --- a/hw/remote/remote-obj.c +++ b/hw/remote/remote-obj.c @@ -188,6 +188,7 @@ static void remote_object_machine_done(Notifier *notifier, void *data) *comdev = (RemoteCommDev) { .ioc = ioc, .dev = PCI_DEVICE(dev), + .ioregions_list = ioregions_list, }; co = qemu_coroutine_create(mpqemu_remote_msg_loop_co, comdev); -- 2.25.1