diff mbox series

[RFC,v4,33/49] multi-process: perform device reset in the remote process

Message ID 7579c5df98f9c09933685209395aa4a0e0ceb857.1571905346.git.jag.raman@oracle.com (mailing list archive)
State New, archived
Headers show
Series Initial support of multi-process qemu | expand

Commit Message

Jag Raman Oct. 24, 2019, 9:09 a.m. UTC
Perform device reset in the remote process when QEMU performs
device reset. This is required to reset the internal state
(like registers, etc...) of emulated devices

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>
---
 New patch in v3

 hw/proxy/proxy-lsi53c895a.c   |  6 ++++++
 hw/proxy/qemu-proxy.c         | 14 ++++++++++++++
 include/hw/proxy/qemu-proxy.h |  2 ++
 include/io/mpqemu-link.h      |  1 +
 remote/remote-main.c          | 11 +++++++++++
 5 files changed, 34 insertions(+)

Comments

Stefan Hajnoczi Nov. 11, 2019, 4:19 p.m. UTC | #1
On Thu, Oct 24, 2019 at 05:09:14AM -0400, Jagannathan Raman wrote:
> +void proxy_device_reset(DeviceState *dev)
> +{
> +    PCIProxyDev *pdev = PCI_PROXY_DEV(dev);
> +    MPQemuMsg msg;
> +
> +    memset(&msg, 0, sizeof(MPQemuMsg));
> +
> +    msg.bytestream = 0;
> +    msg.size = sizeof(msg.data1);
> +    msg.cmd = DEVICE_RESET;
> +
> +    mpqemu_msg_send(pdev->mpqemu_link, &msg, pdev->mpqemu_link->com);
> +}

Device reset must wait for the remote process to finish reset, otherwise
the remote device could still be running after proxy_device_reset()
returns from sending the message.

Stefan
Jag Raman Nov. 13, 2019, 4:15 p.m. UTC | #2
On 11/11/2019 11:19 AM, Stefan Hajnoczi wrote:
> On Thu, Oct 24, 2019 at 05:09:14AM -0400, Jagannathan Raman wrote:
>> +void proxy_device_reset(DeviceState *dev)
>> +{
>> +    PCIProxyDev *pdev = PCI_PROXY_DEV(dev);
>> +    MPQemuMsg msg;
>> +
>> +    memset(&msg, 0, sizeof(MPQemuMsg));
>> +
>> +    msg.bytestream = 0;
>> +    msg.size = sizeof(msg.data1);
>> +    msg.cmd = DEVICE_RESET;
>> +
>> +    mpqemu_msg_send(pdev->mpqemu_link, &msg, pdev->mpqemu_link->com);
>> +}
> 
> Device reset must wait for the remote process to finish reset, otherwise
> the remote device could still be running after proxy_device_reset()
> returns from sending the message.

Thanks for feedback. We will wait for the reset to complete.

--
Jag

> 
> Stefan
>
diff mbox series

Patch

diff --git a/hw/proxy/proxy-lsi53c895a.c b/hw/proxy/proxy-lsi53c895a.c
index 7734ae2..f6bd8a1 100644
--- a/hw/proxy/proxy-lsi53c895a.c
+++ b/hw/proxy/proxy-lsi53c895a.c
@@ -57,6 +57,11 @@  static void proxy_lsi_realize(PCIProxyDev *dev, Error **errp)
                           &dev->region[2], "proxy-lsi-ram", 0x2000);
 }
 
+static void proxy_lsi_reset(DeviceState *dev)
+{
+    proxy_device_reset(dev);
+}
+
 static void proxy_lsi_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -74,6 +79,7 @@  static void proxy_lsi_class_init(ObjectClass *klass, void *data)
     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 
     dc->desc = "LSI Proxy Device";
+    dc->reset = proxy_lsi_reset;
 }
 
 static const TypeInfo lsi_proxy_dev_type_info = {
diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index 74aecd3..5aada67 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -577,3 +577,17 @@  const MemoryRegionOps proxy_default_ops = {
         .max_access_size = 1,
     },
 };
+
+void proxy_device_reset(DeviceState *dev)
+{
+    PCIProxyDev *pdev = PCI_PROXY_DEV(dev);
+    MPQemuMsg msg;
+
+    memset(&msg, 0, sizeof(MPQemuMsg));
+
+    msg.bytestream = 0;
+    msg.size = sizeof(msg.data1);
+    msg.cmd = DEVICE_RESET;
+
+    mpqemu_msg_send(pdev->mpqemu_link, &msg, pdev->mpqemu_link->com);
+}
diff --git a/include/hw/proxy/qemu-proxy.h b/include/hw/proxy/qemu-proxy.h
index 5e858cc..672303c 100644
--- a/include/hw/proxy/qemu-proxy.h
+++ b/include/hw/proxy/qemu-proxy.h
@@ -112,4 +112,6 @@  void proxy_default_bar_write(void *opaque, hwaddr addr, uint64_t val,
 
 uint64_t proxy_default_bar_read(void *opaque, hwaddr addr, unsigned size);
 
+void proxy_device_reset(DeviceState *dev);
+
 #endif /* QEMU_PROXY_H */
diff --git a/include/io/mpqemu-link.h b/include/io/mpqemu-link.h
index 4911eea..6fcc6f5 100644
--- a/include/io/mpqemu-link.h
+++ b/include/io/mpqemu-link.h
@@ -74,6 +74,7 @@  typedef enum {
     DEVICE_DEL,
     PROXY_PING,
     MMIO_RETURN,
+    DEVICE_RESET,
     MAX,
 } mpqemu_cmd_t;
 
diff --git a/remote/remote-main.c b/remote/remote-main.c
index 0a1326d..4459d26 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -66,8 +66,11 @@ 
 #include "qemu/log.h"
 #include "qemu/cutils.h"
 #include "remote-opts.h"
+#include "monitor/monitor.h"
+#include "sysemu/reset.h"
 
 static MPQemuLinkState *mpqemu_link;
+
 PCIDevice *remote_pci_dev;
 bool create_done;
 
@@ -237,6 +240,11 @@  fail:
     PUT_REMOTE_WAIT(wait);
 }
 
+static void process_device_reset_msg(MPQemuMsg *msg)
+{
+    qemu_devices_reset();
+}
+
 static int init_drive(QDict *rqdict, Error **errp)
 {
     QemuOpts *opts;
@@ -441,6 +449,9 @@  static void process_msg(GIOCondition cond, MPQemuChannel *chan)
         notify_proxy(wait, (uint32_t)getpid());
         PUT_REMOTE_WAIT(wait);
         break;
+    case DEVICE_RESET:
+        process_device_reset_msg(msg);
+        break;
     default:
         error_setg(&err, "Unknown command");
         goto finalize_loop;