|
|
9bac43 |
From b6e63f25b4569d9e7c48862f3363b7002feec76f Mon Sep 17 00:00:00 2001
|
|
|
9bac43 |
From: David Gibson <dgibson@redhat.com>
|
|
|
9bac43 |
Date: Wed, 4 Oct 2017 05:40:13 +0200
|
|
|
9bac43 |
Subject: [PATCH 06/34] hw/ppc: CAS reset on early device hotplug
|
|
|
9bac43 |
|
|
|
9bac43 |
RH-Author: David Gibson <dgibson@redhat.com>
|
|
|
9bac43 |
Message-id: <20171004054014.14159-4-dgibson@redhat.com>
|
|
|
9bac43 |
Patchwork-id: 76801
|
|
|
9bac43 |
O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 3/4] hw/ppc: CAS reset on early device hotplug
|
|
|
9bac43 |
Bugzilla: 1448344
|
|
|
9bac43 |
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
|
|
9bac43 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
From: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
|
|
|
9bac43 |
|
|
|
9bac43 |
This patch is a follow up on the discussions made in patch
|
|
|
9bac43 |
"hw/ppc: disable hotplug before CAS is completed" that can be
|
|
|
9bac43 |
found at [1].
|
|
|
9bac43 |
|
|
|
9bac43 |
At this moment, we do not support CPU/memory hotplug in early
|
|
|
9bac43 |
boot stages, before CAS. When a hotplug occurs, the event is logged
|
|
|
9bac43 |
in an internal RTAS event log queue and an IRQ pulse is fired. In
|
|
|
9bac43 |
regular conditions, the guest handles the interrupt by executing
|
|
|
9bac43 |
check_exception, fetching the generated hotplug event and enabling
|
|
|
9bac43 |
the device for use.
|
|
|
9bac43 |
|
|
|
9bac43 |
In early boot, this IRQ isn't caught (SLOF does not handle hotplug
|
|
|
9bac43 |
events), leaving the event in the rtas event log queue. If the guest
|
|
|
9bac43 |
executes check_exception due to another hotplug event, the re-assertion
|
|
|
9bac43 |
of the IRQ ends up de-queuing the first hotplug event as well. In short,
|
|
|
9bac43 |
a device hotplugged before CAS is considered coldplugged by SLOF.
|
|
|
9bac43 |
This leads to device misbehavior and, in some cases, guest kernel
|
|
|
9bac43 |
Ooops when trying to unplug the device.
|
|
|
9bac43 |
|
|
|
9bac43 |
A proper fix would be to turn every device hotplugged before CAS
|
|
|
9bac43 |
as a colplugged device. This is not trivial to do with the current
|
|
|
9bac43 |
code base though - the FDT is written in the guest memory at
|
|
|
9bac43 |
ppc_spapr_reset and can't be retrieved without adding extra state
|
|
|
9bac43 |
(fdt_size for example) that will need to managed and migrated. Adding
|
|
|
9bac43 |
the hotplugged DT in the middle of CAS negotiation via the updated DT
|
|
|
9bac43 |
tree works with CPU devs, but panics the guest kernel at boot. Additional
|
|
|
9bac43 |
analysis would be necessary for LMBs and PCI devices. There are
|
|
|
9bac43 |
questions to be made in QEMU/SLOF/kernel level about how we can make
|
|
|
9bac43 |
this change in a sustainable way.
|
|
|
9bac43 |
|
|
|
9bac43 |
With Linux guests, a fix would be the kernel executing check_exception
|
|
|
9bac43 |
at boot time, de-queueing the events that happened in early boot and
|
|
|
9bac43 |
processing them. However, even if/when the newer kernels start
|
|
|
9bac43 |
fetching these events at boot time, we need to take care of older
|
|
|
9bac43 |
kernels that won't be doing that.
|
|
|
9bac43 |
|
|
|
9bac43 |
This patch works around the situation by issuing a CAS reset if a hotplugged
|
|
|
9bac43 |
device is detected during CAS:
|
|
|
9bac43 |
|
|
|
9bac43 |
- the DRC conditions that warrant a CAS reset is the same as those that
|
|
|
9bac43 |
triggers a DRC migration - the DRC must have a device attached and
|
|
|
9bac43 |
the DRC state is not equal to its ready_state. With that in mind, this
|
|
|
9bac43 |
patch makes use of 'spapr_drc_needed' to determine if a CAS reset
|
|
|
9bac43 |
is needed.
|
|
|
9bac43 |
|
|
|
9bac43 |
- In the middle of CAS negotiations, the function
|
|
|
9bac43 |
'spapr_hotplugged_dev_before_cas' goes through all the DRCs to see
|
|
|
9bac43 |
if there are any DRC that requires a reset, using spapr_drc_needed. If
|
|
|
9bac43 |
that happens, returns '1' in 'spapr_h_cas_compose_response' which will set
|
|
|
9bac43 |
spapr->cas_reboot to true, causing the machine to reboot.
|
|
|
9bac43 |
|
|
|
9bac43 |
No changes are made for coldplug devices.
|
|
|
9bac43 |
|
|
|
9bac43 |
[1] http://lists.nongnu.org/archive/html/qemu-devel/2017-08/msg02855.html
|
|
|
9bac43 |
|
|
|
9bac43 |
Signed-off-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
|
|
|
9bac43 |
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
|
|
|
9bac43 |
(cherry picked from commit 10f12e6450407b18b4d5a6b50d3852dcfd7fff75)
|
|
|
9bac43 |
|
|
|
9bac43 |
Signed-off-by: David Gibson <dgibson@redhat.com>
|
|
|
9bac43 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9bac43 |
---
|
|
|
9bac43 |
hw/ppc/spapr.c | 26 +++++++++++++++++++++++++-
|
|
|
9bac43 |
hw/ppc/spapr_drc.c | 2 +-
|
|
|
9bac43 |
include/hw/ppc/spapr_drc.h | 1 +
|
|
|
9bac43 |
3 files changed, 27 insertions(+), 2 deletions(-)
|
|
|
9bac43 |
|
|
|
9bac43 |
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
|
|
|
9bac43 |
index a419aa7..d3db051 100644
|
|
|
9bac43 |
--- a/hw/ppc/spapr.c
|
|
|
9bac43 |
+++ b/hw/ppc/spapr.c
|
|
|
9bac43 |
@@ -790,6 +790,26 @@ out:
|
|
|
9bac43 |
return ret;
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
+static bool spapr_hotplugged_dev_before_cas(void)
|
|
|
9bac43 |
+{
|
|
|
9bac43 |
+ Object *drc_container, *obj;
|
|
|
9bac43 |
+ ObjectProperty *prop;
|
|
|
9bac43 |
+ ObjectPropertyIterator iter;
|
|
|
9bac43 |
+
|
|
|
9bac43 |
+ drc_container = container_get(object_get_root(), "/dr-connector");
|
|
|
9bac43 |
+ object_property_iter_init(&iter, drc_container);
|
|
|
9bac43 |
+ while ((prop = object_property_iter_next(&iter))) {
|
|
|
9bac43 |
+ if (!strstart(prop->type, "link<", NULL)) {
|
|
|
9bac43 |
+ continue;
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+ obj = object_property_get_link(drc_container, prop->name, NULL);
|
|
|
9bac43 |
+ if (spapr_drc_needed(obj)) {
|
|
|
9bac43 |
+ return true;
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+ return false;
|
|
|
9bac43 |
+}
|
|
|
9bac43 |
+
|
|
|
9bac43 |
int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
|
|
|
9bac43 |
target_ulong addr, target_ulong size,
|
|
|
9bac43 |
sPAPROptionVector *ov5_updates)
|
|
|
9bac43 |
@@ -797,9 +817,13 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
|
|
|
9bac43 |
void *fdt, *fdt_skel;
|
|
|
9bac43 |
sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 };
|
|
|
9bac43 |
|
|
|
9bac43 |
+ if (spapr_hotplugged_dev_before_cas()) {
|
|
|
9bac43 |
+ return 1;
|
|
|
9bac43 |
+ }
|
|
|
9bac43 |
+
|
|
|
9bac43 |
size -= sizeof(hdr);
|
|
|
9bac43 |
|
|
|
9bac43 |
- /* Create sceleton */
|
|
|
9bac43 |
+ /* Create skeleton */
|
|
|
9bac43 |
fdt_skel = g_malloc0(size);
|
|
|
9bac43 |
_FDT((fdt_create(fdt_skel, size)));
|
|
|
9bac43 |
_FDT((fdt_begin_node(fdt_skel, "")));
|
|
|
9bac43 |
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
|
|
|
9bac43 |
index 031ba7c..85c999d 100644
|
|
|
9bac43 |
--- a/hw/ppc/spapr_drc.c
|
|
|
9bac43 |
+++ b/hw/ppc/spapr_drc.c
|
|
|
9bac43 |
@@ -460,7 +460,7 @@ static void drc_reset(void *opaque)
|
|
|
9bac43 |
spapr_drc_reset(SPAPR_DR_CONNECTOR(opaque));
|
|
|
9bac43 |
}
|
|
|
9bac43 |
|
|
|
9bac43 |
-static bool spapr_drc_needed(void *opaque)
|
|
|
9bac43 |
+bool spapr_drc_needed(void *opaque)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
|
|
|
9bac43 |
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
|
|
9bac43 |
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
|
|
|
9bac43 |
index a7958d0..f8d9f5b 100644
|
|
|
9bac43 |
--- a/include/hw/ppc/spapr_drc.h
|
|
|
9bac43 |
+++ b/include/hw/ppc/spapr_drc.h
|
|
|
9bac43 |
@@ -257,6 +257,7 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
|
|
|
9bac43 |
void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
|
|
|
9bac43 |
int fdt_start_offset, Error **errp);
|
|
|
9bac43 |
void spapr_drc_detach(sPAPRDRConnector *drc);
|
|
|
9bac43 |
+bool spapr_drc_needed(void *opaque);
|
|
|
9bac43 |
|
|
|
9bac43 |
static inline bool spapr_drc_unplug_requested(sPAPRDRConnector *drc)
|
|
|
9bac43 |
{
|
|
|
9bac43 |
--
|
|
|
9bac43 |
1.8.3.1
|
|
|
9bac43 |
|