The Linux kernel will call set-indicator to move a DRC to 'unisolate' in the case a device removal fails. Setting a DRC that is already unisolated or configured to 'unisolate' is a no-op for the current hypervisors that supports pSeries guests, namely QEMU and phyp, and is being used to signal hotunplug errors if the hypervisor has the code for it.
This patch changes drc_unisolate_logical() to implement in the pSeries machine. For CPUs it's a simple matter of setting drc->unplug_requested to 'false', while for LMBs the process is similar to the rollback that is done in rtas_ibm_configure_connector(). Although at this moment the Linux kernel is only reporting CPU removal errors, let's get the code ready to handle LMBs as well. Signed-off-by: Daniel Henrique Barboza <danielhb...@gmail.com> --- hw/ppc/spapr_drc.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 9e16505fa1..6918e0c9d1 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -151,9 +151,32 @@ static uint32_t drc_isolate_logical(SpaprDrc *drc) static uint32_t drc_unisolate_logical(SpaprDrc *drc) { + SpaprMachineState *spapr = NULL; + switch (drc->state) { case SPAPR_DRC_STATE_LOGICAL_UNISOLATE: case SPAPR_DRC_STATE_LOGICAL_CONFIGURED: + /* + * Unisolating a logical DRC that was marked for unplug + * means that the kernel is refusing the removal. + */ + if (drc->unplug_requested && drc->dev) { + if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB) { + spapr = SPAPR_MACHINE(qdev_get_machine()); + + spapr_memory_unplug_rollback(spapr, drc->dev); + } + + drc->unplug_requested = false; + error_report("Device hotunplug rejected by the guest " + "for device %s", drc->dev->id); + + /* + * TODO: send a QAPI DEVICE_UNPLUG_ERROR event when + * it is implemented. + */ + } + return RTAS_OUT_SUCCESS; /* Nothing to do */ case SPAPR_DRC_STATE_LOGICAL_AVAILABLE: break; /* see below */ -- 2.30.2