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> Reviewed-by: Stefan Hajnoczi <stefa...@redhat.com> --- include/hw/remote/mpqemu-link.h | 1 + hw/remote/message.c | 23 ++++++++++++++++++++++- hw/remote/proxy.c | 20 ++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/include/hw/remote/mpqemu-link.h b/include/hw/remote/mpqemu-link.h index a0c5c5d..0b87293 100644 --- a/include/hw/remote/mpqemu-link.h +++ b/include/hw/remote/mpqemu-link.h @@ -39,6 +39,7 @@ typedef enum { BAR_WRITE, BAR_READ, SET_IRQFD, + DEVICE_RESET, MPQEMU_CMD_MAX, } MPQemuCmd; diff --git a/hw/remote/message.c b/hw/remote/message.c index a1b1018..f3af4c5 100644 --- a/hw/remote/message.c +++ b/hw/remote/message.c @@ -19,6 +19,7 @@ #include "exec/memattrs.h" #include "hw/remote/memory.h" #include "hw/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); void coroutine_fn mpqemu_remote_msg_loop_co(void *data) { @@ -72,7 +75,9 @@ void coroutine_fn mpqemu_remote_msg_loop_co(void *data) case SET_IRQFD: process_set_irqfd_msg(pci_dev, &msg); break; - + case DEVICE_RESET: + process_device_reset_msg(com->ioc, pci_dev, &local_err); + break; default: error_setg(&local_err, "Unknown command (%d) received for device %s (pid=%d)", @@ -218,3 +223,19 @@ 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 }; + + if (dc->reset) { + dc->reset(s); + } + + ret.cmd = RET_MSG; + + mpqemu_msg_send(&ret, ioc, errp); +} diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c index a68ee66..5b7b14c 100644 --- a/hw/remote/proxy.c +++ b/hw/remote/proxy.c @@ -25,6 +25,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) { @@ -199,6 +200,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); } @@ -356,3 +359,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); + } + +} -- 1.8.3.1