multi-process: perform device reset in the remote process
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> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Message-id: 7cb220a51f565dc0817bd76e2f540e89c2d2b850.1611938319.git.jag.raman@oracle.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
1bec145cd9
commit
b6cc02d98f
@ -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, Error **errp);
|
||||
@ -26,6 +27,8 @@ static void process_config_read(QIOChannel *ioc, PCIDevice *dev,
|
||||
MPQemuMsg *msg, Error **errp);
|
||||
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)
|
||||
{
|
||||
@ -69,6 +72,9 @@ void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
|
||||
case MPQEMU_CMD_SET_IRQFD:
|
||||
process_set_irqfd_msg(pci_dev, &msg);
|
||||
break;
|
||||
case MPQEMU_CMD_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"
|
||||
@ -206,3 +212,19 @@ fail:
|
||||
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 = MPQEMU_CMD_RET;
|
||||
|
||||
mpqemu_msg_send(&ret, ioc, errp);
|
||||
}
|
||||
|
@ -26,6 +26,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_intx_update(PCIDevice *pci_dev)
|
||||
{
|
||||
@ -202,6 +203,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);
|
||||
}
|
||||
|
||||
@ -358,3 +361,19 @@ 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 = MPQEMU_CMD_DEVICE_RESET;
|
||||
msg.size = 0;
|
||||
|
||||
mpqemu_msg_send_and_await_reply(&msg, pdev, &local_err);
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ typedef enum {
|
||||
MPQEMU_CMD_BAR_WRITE,
|
||||
MPQEMU_CMD_BAR_READ,
|
||||
MPQEMU_CMD_SET_IRQFD,
|
||||
MPQEMU_CMD_DEVICE_RESET,
|
||||
MPQEMU_CMD_MAX,
|
||||
} MPQemuCmd;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user