[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 01/55] hw/ppc: CAS reset on early device hotplug
From: |
Michael Roth |
Subject: |
[Qemu-stable] [PATCH 01/55] hw/ppc: CAS reset on early device hotplug |
Date: |
Wed, 6 Dec 2017 13:15:54 -0600 |
From: Daniel Henrique Barboza <address@hidden>
This patch is a follow up on the discussions made in patch
"hw/ppc: disable hotplug before CAS is completed" that can be
found at [1].
At this moment, we do not support CPU/memory hotplug in early
boot stages, before CAS. When a hotplug occurs, the event is logged
in an internal RTAS event log queue and an IRQ pulse is fired. In
regular conditions, the guest handles the interrupt by executing
check_exception, fetching the generated hotplug event and enabling
the device for use.
In early boot, this IRQ isn't caught (SLOF does not handle hotplug
events), leaving the event in the rtas event log queue. If the guest
executes check_exception due to another hotplug event, the re-assertion
of the IRQ ends up de-queuing the first hotplug event as well. In short,
a device hotplugged before CAS is considered coldplugged by SLOF.
This leads to device misbehavior and, in some cases, guest kernel
Ooops when trying to unplug the device.
A proper fix would be to turn every device hotplugged before CAS
as a colplugged device. This is not trivial to do with the current
code base though - the FDT is written in the guest memory at
ppc_spapr_reset and can't be retrieved without adding extra state
(fdt_size for example) that will need to managed and migrated. Adding
the hotplugged DT in the middle of CAS negotiation via the updated DT
tree works with CPU devs, but panics the guest kernel at boot. Additional
analysis would be necessary for LMBs and PCI devices. There are
questions to be made in QEMU/SLOF/kernel level about how we can make
this change in a sustainable way.
With Linux guests, a fix would be the kernel executing check_exception
at boot time, de-queueing the events that happened in early boot and
processing them. However, even if/when the newer kernels start
fetching these events at boot time, we need to take care of older
kernels that won't be doing that.
This patch works around the situation by issuing a CAS reset if a hotplugged
device is detected during CAS:
- the DRC conditions that warrant a CAS reset is the same as those that
triggers a DRC migration - the DRC must have a device attached and
the DRC state is not equal to its ready_state. With that in mind, this
patch makes use of 'spapr_drc_needed' to determine if a CAS reset
is needed.
- In the middle of CAS negotiations, the function
'spapr_hotplugged_dev_before_cas' goes through all the DRCs to see
if there are any DRC that requires a reset, using spapr_drc_needed. If
that happens, returns '1' in 'spapr_h_cas_compose_response' which will set
spapr->cas_reboot to true, causing the machine to reboot.
No changes are made for coldplug devices.
[1] http://lists.nongnu.org/archive/html/qemu-devel/2017-08/msg02855.html
Signed-off-by: Daniel Henrique Barboza <address@hidden>
Signed-off-by: David Gibson <address@hidden>
(cherry picked from commit 10f12e6450407b18b4d5a6b50d3852dcfd7fff75)
Signed-off-by: Michael Roth <address@hidden>
---
hw/ppc/spapr.c | 26 +++++++++++++++++++++++++-
hw/ppc/spapr_drc.c | 2 +-
include/hw/ppc/spapr_drc.h | 1 +
3 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index cec441cbf4..cc3901a790 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -790,6 +790,26 @@ out:
return ret;
}
+static bool spapr_hotplugged_dev_before_cas(void)
+{
+ Object *drc_container, *obj;
+ ObjectProperty *prop;
+ ObjectPropertyIterator iter;
+
+ drc_container = container_get(object_get_root(), "/dr-connector");
+ object_property_iter_init(&iter, drc_container);
+ while ((prop = object_property_iter_next(&iter))) {
+ if (!strstart(prop->type, "link<", NULL)) {
+ continue;
+ }
+ obj = object_property_get_link(drc_container, prop->name, NULL);
+ if (spapr_drc_needed(obj)) {
+ return true;
+ }
+ }
+ return false;
+}
+
int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
target_ulong addr, target_ulong size,
sPAPROptionVector *ov5_updates)
@@ -797,9 +817,13 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
void *fdt, *fdt_skel;
sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 };
+ if (spapr_hotplugged_dev_before_cas()) {
+ return 1;
+ }
+
size -= sizeof(hdr);
- /* Create sceleton */
+ /* Create skeleton */
fdt_skel = g_malloc0(size);
_FDT((fdt_create(fdt_skel, size)));
_FDT((fdt_begin_node(fdt_skel, "")));
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 605697d8bd..50df361187 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -460,7 +460,7 @@ static void drc_reset(void *opaque)
spapr_drc_reset(SPAPR_DR_CONNECTOR(opaque));
}
-static bool spapr_drc_needed(void *opaque)
+bool spapr_drc_needed(void *opaque)
{
sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
index a7958d0a8d..f8d9f5b231 100644
--- a/include/hw/ppc/spapr_drc.h
+++ b/include/hw/ppc/spapr_drc.h
@@ -257,6 +257,7 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object
*owner,
void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
int fdt_start_offset, Error **errp);
void spapr_drc_detach(sPAPRDRConnector *drc);
+bool spapr_drc_needed(void *opaque);
static inline bool spapr_drc_unplug_requested(sPAPRDRConnector *drc)
{
--
2.11.0
- [Qemu-stable] [PATCH 14/55] memory: Rename mem_begin/mem_commit/mem_add helpers, (continued)
- [Qemu-stable] [PATCH 14/55] memory: Rename mem_begin/mem_commit/mem_add helpers, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 12/55] memory: Switch memory from using AddressSpace to FlatView, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 16/55] memory: Alloc dispatch tree where topology is generared, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 18/55] memory: Share FlatView's and dispatch trees between address spaces, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 20/55] memory: Get rid of address_space_init_shareable, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 15/55] memory: Store physical root MR in FlatView, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 13/55] memory: Cleanup after switching to FlatView, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 17/55] memory: Move address_space_update_ioeventfds, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 19/55] memory: Do not allocate FlatView in address_space_init, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 21/55] memory: Create FlatView directly, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 01/55] hw/ppc: CAS reset on early device hotplug,
Michael Roth <=
- [Qemu-stable] [PATCH 22/55] memory: trace FlatView creation and destruction, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 23/55] memory: seek FlatView sharing candidates among children subregions, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 26/55] exec: simplify address_space_get_iotlb_entry, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 25/55] exec: add page_mask for flatview_do_translate, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 28/55] hw/sd: fix out-of-bounds check for multi block reads, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 30/55] qcow2: Always execute preallocate() in a coroutine, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 27/55] memory: fix off-by-one error in memory_region_notify_one(), Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 29/55] qcow2: Fix unaligned preallocated truncation, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 24/55] memory: Share special empty FlatView, Michael Roth, 2017/12/06
- [Qemu-stable] [PATCH 33/55] io: monitor encoutput buffer size from websocket GSource, Michael Roth, 2017/12/06