From: Elena Ufimtseva <elena.ufimts...@oracle.com> 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.ufimts...@oracle.com> Signed-off-by: John G Johnson <john.g.john...@oracle.com> Signed-off-by: Jagannathan Raman <jag.ra...@oracle.com> --- hw/i386/remote-msg.c | 25 +++++++++++++++++++++++++ hw/pci/proxy.c | 20 ++++++++++++++++++++ include/io/mpqemu-link.h | 1 + 3 files changed, 46 insertions(+) diff --git a/hw/i386/remote-msg.c b/hw/i386/remote-msg.c index 2707fe81c4..b255a7e299 100644 --- a/hw/i386/remote-msg.c +++ b/hw/i386/remote-msg.c @@ -19,6 +19,7 @@ #include "exec/memattrs.h" #include "hw/i386/remote-memory.h" #include "hw/i386/remote-iohub.h" +#include "sysemu/reset.h" static void process_config_write(QIOChannel *ioc, PCIDevice *dev, MPQemuMsg *msg); @@ -26,6 +27,8 @@ static void process_config_read(QIOChannel *ioc, PCIDevice *dev, MPQemuMsg *msg); 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); gboolean mpqemu_process_msg(QIOChannel *ioc, GIOCondition cond, gpointer opaque) @@ -79,6 +82,9 @@ gboolean mpqemu_process_msg(QIOChannel *ioc, GIOCondition cond, case SET_IRQFD: process_set_irqfd_msg(pci_dev, &msg); break; + case DEVICE_RESET: + process_device_reset_msg(ioc, pci_dev, &local_err); + break; default: error_setg(&local_err, "Unknown command (%d) received for device %s (pid=%d)", @@ -236,3 +242,22 @@ fail: "in remote process pid=%d", getpid()); } } + +static void process_device_reset_msg(QIOChannel *ioc, PCIDevice *dev, + Error **errp) +{ + DeviceClass *dc = DEVICE_GET_CLASS(dev); + DeviceState *s = DEVICE(dev); + MPQemuMsg ret = { 0 }; + MPQemuRequest req = { 0 }; + + if (dc->reset) { + dc->reset(s); + } + + ret.cmd = RET_MSG; + req.msg = &ret; + req.ioc = ioc; + + mpqemu_msg_send_in_co(&req, ioc, errp); +} diff --git a/hw/pci/proxy.c b/hw/pci/proxy.c index 6acfdd7c3e..3b277cffc4 100644 --- a/hw/pci/proxy.c +++ b/hw/pci/proxy.c @@ -24,6 +24,7 @@ #include "util/event_notifier-posix.c" static void probe_pci_info(PCIDevice *dev, Error **errp); +static void proxy_device_reset(DeviceState *dev); static void proxy_set_socket(PCIProxyDev *pdev, int fd, Error **errp) { @@ -184,6 +185,8 @@ static void pci_proxy_dev_class_init(ObjectClass *klass, void *data) k->config_read = pci_proxy_read_config; k->config_write = pci_proxy_write_config; + dc->reset = proxy_device_reset; + device_class_set_props(dc, proxy_properties); } @@ -341,3 +344,20 @@ static void probe_pci_info(PCIDevice *dev, Error **errp) } } } + +static void proxy_device_reset(DeviceState *dev) +{ + PCIProxyDev *pdev = PCI_PROXY_DEV(dev); + MPQemuMsg msg = { 0 }; + Error *local_err = NULL; + + msg.cmd = DEVICE_RESET; + msg.size = 0; + + (void)mpqemu_msg_send_and_await_reply(&msg, pdev, &local_err); + if (local_err) { + error_report("Failed to send DEVICE_RESET to the remote process"); + error_free(local_err); + } + +} diff --git a/include/io/mpqemu-link.h b/include/io/mpqemu-link.h index abcd89a588..0703d4d90f 100644 --- a/include/io/mpqemu-link.h +++ b/include/io/mpqemu-link.h @@ -39,6 +39,7 @@ typedef enum { BAR_WRITE, BAR_READ, SET_IRQFD, + DEVICE_RESET, MAX = INT_MAX, } MPQemuCmd; -- 2.25.GIT