aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShameer Kolothum <shameerali.kolothum.thodi@huawei.com>2020-06-22 13:41:57 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-06-23 11:39:48 +0100
commit539533b85fbd269f777bed931de8ccae1dd837e9 (patch)
treea91d3257294064f9548995edcc9a8b14388ad486
parent92a70997ad6dcff865b0071475a878a4fa478da5 (diff)
downloadqemu-arm-pull-target-arm-20200623.tar.gz
arm/virt: Add memory hot remove supportpull-target-arm-20200623
This adds support for memory(pc-dimm) hot remove on arm/virt that uses acpi ged device. NVDIMM hot removal is not yet supported. Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> Message-id: 20200622124157.20360-1-shameerali.kolothum.thodi@huawei.com Reviewed-by: Eric Auger <eric.auger@redhat.com> Tested-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/acpi/generic_event_device.c29
-rw-r--r--hw/arm/virt.c62
2 files changed, 89 insertions, 2 deletions
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 1cb34111e5..b8abdefa1c 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -193,6 +193,33 @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
}
}
+static void acpi_ged_unplug_request_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
+
+ if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
+ !(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)))) {
+ acpi_memory_unplug_request_cb(hotplug_dev, &s->memhp_state, dev, errp);
+ } else {
+ error_setg(errp, "acpi: device unplug request for unsupported device"
+ " type: %s", object_get_typename(OBJECT(dev)));
+ }
+}
+
+static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
+
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+ acpi_memory_unplug_cb(&s->memhp_state, dev, errp);
+ } else {
+ error_setg(errp, "acpi: device unplug for unsupported device"
+ " type: %s", object_get_typename(OBJECT(dev)));
+ }
+}
+
static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
{
AcpiGedState *s = ACPI_GED(adev);
@@ -318,6 +345,8 @@ static void acpi_ged_class_init(ObjectClass *class, void *data)
dc->vmsd = &vmstate_acpi_ged;
hc->plug = acpi_ged_device_plug_cb;
+ hc->unplug_request = acpi_ged_unplug_request_cb;
+ hc->unplug = acpi_ged_unplug_cb;
adevc->send_event = acpi_ged_send_event;
}
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 8b6e6aa7b1..402c362c14 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2177,11 +2177,68 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
}
}
+static void virt_dimm_unplug_request(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
+ Error *local_err = NULL;
+
+ if (!vms->acpi_dev) {
+ error_setg(&local_err,
+ "memory hotplug is not enabled: missing acpi-ged device");
+ goto out;
+ }
+
+ if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
+ error_setg(&local_err,
+ "nvdimm device hot unplug is not supported yet.");
+ goto out;
+ }
+
+ hotplug_handler_unplug_request(HOTPLUG_HANDLER(vms->acpi_dev), dev,
+ &local_err);
+out:
+ error_propagate(errp, local_err);
+}
+
+static void virt_dimm_unplug(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
+ Error *local_err = NULL;
+
+ hotplug_handler_unplug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &local_err);
+ if (local_err) {
+ goto out;
+ }
+
+ pc_dimm_unplug(PC_DIMM(dev), MACHINE(vms));
+ qdev_unrealize(dev);
+
+out:
+ error_propagate(errp, local_err);
+}
+
static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
- error_setg(errp, "device unplug request for unsupported device"
- " type: %s", object_get_typename(OBJECT(dev)));
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+ virt_dimm_unplug_request(hotplug_dev, dev, errp);
+ } else {
+ error_setg(errp, "device unplug request for unsupported device"
+ " type: %s", object_get_typename(OBJECT(dev)));
+ }
+}
+
+static void virt_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+ virt_dimm_unplug(hotplug_dev, dev, errp);
+ } else {
+ error_setg(errp, "virt: device unplug for unsupported device"
+ " type: %s", object_get_typename(OBJECT(dev)));
+ }
}
static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
@@ -2262,6 +2319,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
hc->pre_plug = virt_machine_device_pre_plug_cb;
hc->plug = virt_machine_device_plug_cb;
hc->unplug_request = virt_machine_device_unplug_request_cb;
+ hc->unplug = virt_machine_device_unplug_cb;
mc->numa_mem_supported = true;
mc->nvdimm_supported = true;
mc->auto_enable_numa_with_memhp = true;