diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2021-03-12 11:30:55 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2021-03-12 11:30:55 +0000 |
| commit | 1941858448e76f83eb00614c4f34ac29e9a8e792 (patch) | |
| tree | 4d3bafbd64a5b337d56beb28a1fcd28bd9cc3001 /hw/ppc/spapr.c | |
| parent | 6f34661b6c97a37a5efc27d31c037ddeda4547e2 (diff) | |
| parent | eb7f80fd26d73e7e1af105431da58971b1dba517 (diff) | |
| download | focaccia-qemu-1941858448e76f83eb00614c4f34ac29e9a8e792.tar.gz focaccia-qemu-1941858448e76f83eb00614c4f34ac29e9a8e792.zip | |
Merge remote-tracking branch 'remotes/dg-gitlab/tags/ppc-for-6.0-20210310' into staging
ppc patch queue for 2021-03-10 Next batch of patches for the ppc target and machine types. Includes: * Several cleanups for sm501 from Peter Maydell * An update to the SLOF guest firmware * Improved handling of hotplug failures in spapr, associated cleanups to the hotplug handling code * Several etsec fixes and cleanups from Bin Meng * Assorted other fixes and cleanups # gpg: Signature made Wed 10 Mar 2021 04:08:53 GMT # gpg: using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full] # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full] # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full] # gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown] # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dg-gitlab/tags/ppc-for-6.0-20210310: spapr.c: send QAPI event when memory hotunplug fails spapr.c: remove duplicated assert in spapr_memory_unplug_request() target/ppc: fix icount support on Book-e vms accessing SPRs qemu_timer.c: add timer_deadline_ms() helper spapr_pci.c: add 'unplug already in progress' message for PCI unplug spapr.c: add 'unplug already in progress' message for PHB unplug hw/ppc: e500: Add missing <ranges> in the eTSEC node hw/net: fsl_etsec: Fix build error when HEX_DUMP is on spapr_drc.c: use DRC reconfiguration to cleanup DIMM unplug state spapr_drc.c: add hotunplug timeout for CPUs spapr_drc.c: introduce unplug_timeout_timer target/ppc: Fix bcdsub. emulation when result overflows docs/system: Extend PPC section spapr: rename spapr_drc_detach() to spapr_drc_unplug_request() spapr_drc.c: use spapr_drc_release() in isolate_physical/set_unusable pseries: Update SLOF firmware image spapr_drc.c: do not call spapr_drc_detach() in drc_isolate_logical() hw/display/sm501: Inline template header into C file hw/display/sm501: Expand out macros in template header hw/display/sm501: Remove dead code for non-32-bit RGB surfaces Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/ppc/spapr.c')
| -rw-r--r-- | hw/ppc/spapr.c | 67 |
1 files changed, 63 insertions, 4 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 85fe65f894..d56418ca29 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -28,6 +28,7 @@ #include "qemu-common.h" #include "qemu/datadir.h" #include "qapi/error.h" +#include "qapi/qapi-events-machine.h" #include "qapi/visitor.h" #include "sysemu/sysemu.h" #include "sysemu/hostmem.h" @@ -3575,6 +3576,57 @@ static SpaprDimmState *spapr_recover_pending_dimm_state(SpaprMachineState *ms, return spapr_pending_dimm_unplugs_add(ms, avail_lmbs, dimm); } +void spapr_memory_unplug_rollback(SpaprMachineState *spapr, DeviceState *dev) +{ + SpaprDimmState *ds; + PCDIMMDevice *dimm; + SpaprDrc *drc; + uint32_t nr_lmbs; + uint64_t size, addr_start, addr; + g_autofree char *qapi_error = NULL; + int i; + + if (!dev) { + return; + } + + dimm = PC_DIMM(dev); + ds = spapr_pending_dimm_unplugs_find(spapr, dimm); + + /* + * 'ds == NULL' would mean that the DIMM doesn't have a pending + * unplug state, but one of its DRC is marked as unplug_requested. + * This is bad and weird enough to g_assert() out. + */ + g_assert(ds); + + spapr_pending_dimm_unplugs_remove(spapr, ds); + + size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &error_abort); + nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE; + + addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP, + &error_abort); + + addr = addr_start; + for (i = 0; i < nr_lmbs; i++) { + drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, + addr / SPAPR_MEMORY_BLOCK_SIZE); + g_assert(drc); + + drc->unplug_requested = false; + addr += SPAPR_MEMORY_BLOCK_SIZE; + } + + /* + * Tell QAPI that something happened and the memory + * hotunplug wasn't successful. + */ + qapi_error = g_strdup_printf("Memory hotunplug rejected by the guest " + "for device %s", dev->id); + qapi_event_send_mem_unplug_error(dev->id, qapi_error); +} + /* Callback to be called during DRC release. */ void spapr_lmb_release(DeviceState *dev) { @@ -3654,13 +3706,12 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev, addr / SPAPR_MEMORY_BLOCK_SIZE); g_assert(drc); - spapr_drc_detach(drc); + spapr_drc_unplug_request(drc); addr += SPAPR_MEMORY_BLOCK_SIZE; } drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, addr_start / SPAPR_MEMORY_BLOCK_SIZE); - g_assert(drc); spapr_hotplug_req_remove_by_count_indexed(SPAPR_DR_CONNECTOR_TYPE_LMB, nr_lmbs, spapr_drc_index(drc)); } @@ -3722,8 +3773,12 @@ void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev, g_assert(drc); if (!spapr_drc_unplug_requested(drc)) { - spapr_drc_detach(drc); + spapr_drc_unplug_request(drc); spapr_hotplug_req_remove_by_index(drc); + } else { + error_setg(errp, "core-id %d unplug is still pending, %d seconds " + "timeout remaining", + cc->core_id, spapr_drc_unplug_timeout_remaining_sec(drc)); } } @@ -3985,8 +4040,12 @@ static void spapr_phb_unplug_request(HotplugHandler *hotplug_dev, assert(drc); if (!spapr_drc_unplug_requested(drc)) { - spapr_drc_detach(drc); + spapr_drc_unplug_request(drc); spapr_hotplug_req_remove_by_index(drc); + } else { + error_setg(errp, + "PCI Host Bridge unplug already in progress for device %s", + dev->id); } } |