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> --- V4 -> v5: - Device reset wait for remote hw/proxy/qemu-proxy.c | 25 +++++++++++++++++++++++++ include/io/mpqemu-link.h | 1 + remote/remote-main.c | 14 ++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c index 68517aa..741f02a 100644 --- a/hw/proxy/qemu-proxy.c +++ b/hw/proxy/qemu-proxy.c @@ -431,14 +431,39 @@ static void pci_proxy_write_config(PCIDevice *d, uint32_t addr, uint32_t val, config_op_send(PCI_PROXY_DEV(d), addr, &val, l, PCI_CONFIG_WRITE); } +static void proxy_device_reset(DeviceState *dev) +{ + PCIProxyDev *pdev = PCI_PROXY_DEV(dev); + MPQemuMsg msg; + int wait = -1; + + memset(&msg, 0, sizeof(MPQemuMsg)); + + msg.bytestream = 0; + msg.size = sizeof(msg.data1); + msg.cmd = DEVICE_RESET; + + wait = eventfd(0, EFD_CLOEXEC); + msg.num_fds = 1; + msg.fds[0] = wait; + + mpqemu_msg_send(&msg, pdev->mpqemu_link->com); + + wait_for_remote(wait); + close(wait); +} + static void pci_proxy_dev_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->realize = pci_proxy_dev_realize; k->exit = pci_dev_exit; k->config_read = pci_proxy_read_config; k->config_write = pci_proxy_write_config; + + dc->reset = proxy_device_reset; } static const TypeInfo pci_proxy_dev_type_info = { diff --git a/include/io/mpqemu-link.h b/include/io/mpqemu-link.h index 3962630..d2234ca 100644 --- a/include/io/mpqemu-link.h +++ b/include/io/mpqemu-link.h @@ -62,6 +62,7 @@ typedef enum { RET_PCI_INFO, PROXY_PING, MMIO_RETURN, + DEVICE_RESET, MAX, } mpqemu_cmd_t; diff --git a/remote/remote-main.c b/remote/remote-main.c index 6cfc446..5284ee9 100644 --- a/remote/remote-main.c +++ b/remote/remote-main.c @@ -53,8 +53,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; @@ -241,6 +244,11 @@ fail: PUT_REMOTE_WAIT(wait); } +static void process_device_reset_msg(MPQemuMsg *msg) +{ + qemu_devices_reset(); +} + static int setup_device(MPQemuMsg *msg, Error **errp) { QObject *obj; @@ -395,6 +403,12 @@ static void process_msg(GIOCondition cond, MPQemuChannel *chan) wait = msg->fds[0]; notify_proxy(wait, (uint32_t)getpid()); break; + case DEVICE_RESET: + process_device_reset_msg(msg); + if (msg->num_fds == 1) { + notify_proxy(msg->fds[0], 0); + } + break; default: error_setg(&err, "Unknown command"); goto finalize_loop; -- 1.8.3.1