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


Reply via email to