[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 44/55] spapr: reset DRCs after devices
From: |
Michael Roth |
Subject: |
[Qemu-stable] [PATCH 44/55] spapr: reset DRCs after devices |
Date: |
Wed, 6 Dec 2017 13:16:37 -0600 |
From: Greg Kurz <address@hidden>
A DRC with a pending unplug request releases its associated device at
machine reset time.
In the case of LMB, when all DRCs for a DIMM device have been reset,
the DIMM gets unplugged, causing guest memory to disappear. This may
be very confusing for anything still using this memory.
This is exactly what happens with vhost backends, and QEMU aborts
with:
qemu-system-ppc64: used ring relocated for ring 2
qemu-system-ppc64: qemu/hw/virtio/vhost.c:649: vhost_commit: Assertion
`r >= 0' failed.
The issue is that each DRC registers a QEMU reset handler, and we
don't control the order in which these handlers are called (ie,
a LMB DRC will unplug a DIMM before the virtio device using the
memory on this DIMM could stop its vhost backend).
To avoid such situations, let's reset DRCs after all devices
have been reset.
Reported-by: Mallesh N. Koti <address@hidden>
Signed-off-by: Greg Kurz <address@hidden>
Reviewed-by: Daniel Henrique Barboza <address@hidden>
Reviewed-by: Michael Roth <address@hidden>
Signed-off-by: David Gibson <address@hidden>
(cherry picked from commit 82512483940c756e2db1bd67ea91b02bc29c5e01)
Signed-off-by: Michael Roth <address@hidden>
---
hw/ppc/spapr.c | 21 +++++++++++++++++++++
hw/ppc/spapr_drc.c | 7 -------
2 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 954fd1a747..8630281d0e 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1393,6 +1393,19 @@ static void find_unknown_sysbus_device(SysBusDevice
*sbdev, void *opaque)
}
}
+static int spapr_reset_drcs(Object *child, void *opaque)
+{
+ sPAPRDRConnector *drc =
+ (sPAPRDRConnector *) object_dynamic_cast(child,
+ TYPE_SPAPR_DR_CONNECTOR);
+
+ if (drc) {
+ spapr_drc_reset(drc);
+ }
+
+ return 0;
+}
+
static void ppc_spapr_reset(void)
{
MachineState *machine = MACHINE(qdev_get_machine());
@@ -1416,6 +1429,14 @@ static void ppc_spapr_reset(void)
}
qemu_devices_reset();
+
+ /* DRC reset may cause a device to be unplugged. This will cause troubles
+ * if this device is used by another device (eg, a running vhost backend
+ * will crash QEMU if the DIMM holding the vring goes away). To avoid such
+ * situations, we reset DRCs after all devices have been reset.
+ */
+ object_child_foreach_recursive(object_get_root(), spapr_reset_drcs, NULL);
+
spapr_clear_pending_events(spapr);
/*
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 50df361187..85f4e7d324 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -455,11 +455,6 @@ void spapr_drc_reset(sPAPRDRConnector *drc)
}
}
-static void drc_reset(void *opaque)
-{
- spapr_drc_reset(SPAPR_DR_CONNECTOR(opaque));
-}
-
bool spapr_drc_needed(void *opaque)
{
sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
@@ -518,7 +513,6 @@ static void realize(DeviceState *d, Error **errp)
}
vmstate_register(DEVICE(drc), spapr_drc_index(drc), &vmstate_spapr_drc,
drc);
- qemu_register_reset(drc_reset, drc);
trace_spapr_drc_realize_complete(spapr_drc_index(drc));
}
@@ -529,7 +523,6 @@ static void unrealize(DeviceState *d, Error **errp)
char name[256];
trace_spapr_drc_unrealize(spapr_drc_index(drc));
- qemu_unregister_reset(drc_reset, drc);
vmstate_unregister(DEVICE(drc), &vmstate_spapr_drc, drc);
root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
snprintf(name, sizeof(name), "%x", spapr_drc_index(drc));
--
2.11.0
- [Qemu-stable] [PATCH 02/55] hw/usb/bus: Remove bad object_unparent() from usb_try_create_simple(), (continued)
- [Qemu-stable] [PATCH 02/55] hw/usb/bus: Remove bad object_unparent() from usb_try_create_simple(), Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 32/55] nios2: define tcg_env, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 36/55] hw/intc/arm_gicv3_its: Don't abort on table save failure, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 34/55] ppc: fix setting of compat mode, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 35/55] translate.c: Fix usermode big-endian AArch32 LDREXD and STREXD, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 37/55] net/socket: fix coverity issue, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 31/55] iotests: Add cluster_size=64k to 125, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 03/55] block/mirror: check backing in bdrv_mirror_top_flush, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 40/55] util/stats64: Fix min/max comparisons, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 42/55] vhost: restore avail index from vring used index on disconnection, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 44/55] spapr: reset DRCs after devices,
Michael Roth <=
- [Qemu-stable] [PATCH 38/55] net: fix check for number of parameters to -netdev socket, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 39/55] nbd/client: Use error_prepend() correctly, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 41/55] virtio: Add queue interface to restore avail index from vring used index, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 43/55] hw/ppc: clear pending_events on machine reset, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 46/55] block/nfs: fix nfs_client_open for filesize greater than 1TB, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 48/55] nbd/server: CVE-2017-15119 Reject options larger than 32M, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 45/55] scripts/make-release: ship u-boot source as a tarball, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 47/55] virtio-net: don't touch virtqueue if vm is stopped, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 04/55] kvmclock: use the updated system_timer_msr, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 49/55] nbd/server: CVE-2017-15118 Stack smash on large export name, Michael Roth, 2017/12/06