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 | 22 ++++++++++++++++++++++ hw/pci/proxy.c | 20 ++++++++++++++++++++ include/io/mpqemu-link.h | 1 + 3 files changed, 43 insertions(+) diff --git a/hw/i386/remote-msg.c b/hw/i386/remote-msg.c index 2a4d7f1..55db631 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/remote/iohub.h" +#include "sysemu/reset.h" static void process_config_write(QIOChannel *ioc, PCIDevice *dev, MPQemuMsg *msg); @@ -27,6 +28,8 @@ static void process_config_read(QIOChannel *ioc, PCIDevice *dev, 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_proxy_ping_msg(QIOChannel *ioc, 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 PROXY_PING: process_proxy_ping_msg(ioc, &local_err); 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)", @@ -242,3 +248,19 @@ static void process_proxy_ping_msg(QIOChannel *ioc, Error **errp) "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 }; + + if (dc->reset) { + dc->reset(s); + } + + ret.cmd = RET_MSG; + + mpqemu_msg_send(&ret, ioc, errp); +} diff --git a/hw/pci/proxy.c b/hw/pci/proxy.c index 490093c..b6cc3fc 100644 --- a/hw/pci/proxy.c +++ b/hw/pci/proxy.c @@ -26,6 +26,7 @@ static void probe_pci_info(PCIDevice *dev, Error **errp); static void start_hb_timer(PCIProxyDev *dev); static void stop_hb_timer(PCIProxyDev *dev); +static void proxy_device_reset(DeviceState *dev); static void proxy_set_socket(PCIProxyDev *pdev, int fd, Error **errp) { @@ -191,6 +192,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); } @@ -395,3 +398,20 @@ static void stop_hb_timer(PCIProxyDev *dev) timer_del(dev->hb_timer); timer_free(dev->hb_timer); } + +static void proxy_device_reset(DeviceState *dev) +{ + PCIProxyDev *pdev = PCI_PROXY_DEV(dev); + MPQemuMsg msg = { 0 }; + Error *local_err = NULL; + + msg.bytestream = 0; + msg.size = sizeof(msg.data1); + msg.cmd = DEVICE_RESET; + + (void)mpqemu_msg_send_and_await_reply(&msg, pdev->ioc, &local_err); + if (local_err) { + error_report("Failed to send DEVICE_RESET to the remote process"); + } + +} diff --git a/include/io/mpqemu-link.h b/include/io/mpqemu-link.h index 5f2913f..28c68cb 100644 --- a/include/io/mpqemu-link.h +++ b/include/io/mpqemu-link.h @@ -41,6 +41,7 @@ typedef enum { SET_IRQFD, GET_PCI_INFO, PROXY_PING, + DEVICE_RESET, MAX = INT_MAX, } MPQemuCmd; -- 1.8.3.1