From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57023) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yrn85-0002nG-0v for qemu-devel@nongnu.org; Mon, 11 May 2015 08:48:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yrn83-0002aP-Dg for qemu-devel@nongnu.org; Mon, 11 May 2015 08:48:16 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55316) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yrn83-0002aG-6p for qemu-devel@nongnu.org; Mon, 11 May 2015 08:48:15 -0400 Date: Mon, 11 May 2015 14:48:07 +0200 From: "Michael S. Tsirkin" Message-ID: <1431329108-2605-19-git-send-email-mst@redhat.com> References: <1431329108-2605-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1431329108-2605-1-git-send-email-mst@redhat.com> Subject: [Qemu-devel] [PULL 18/28] acpi, mem-hotplug: add unplug request cb for memory device List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , Zhu Guihua , Tang Chen , Paolo Bonzini , Igor Mammedov , Richard Henderson From: Tang Chen This patch adds unplug request cb for memory device, and adds the is_removing boolean field to MemStatus. This field is used to indicate whether the memory device in slot has been requested to be ejected. This field is set to true in acpi_memory_unplug_request_cb(). Reviewed-by: Igor Mammedov Signed-off-by: Tang Chen Signed-off-by: Zhu Guihua Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/acpi/memory_hotplug.h | 10 ++++++++++ hw/acpi/ich9.c | 10 ++++++++-- hw/acpi/memory_hotplug.c | 19 +++++++++++++++++++ hw/acpi/piix4.c | 6 +++++- hw/i386/pc.c | 28 ++++++++++++++++++++++++++-- 5 files changed, 68 insertions(+), 5 deletions(-) diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h index 7bbf8a0..9d7eee9 100644 --- a/include/hw/acpi/memory_hotplug.h +++ b/include/hw/acpi/memory_hotplug.h @@ -7,10 +7,17 @@ #define ACPI_MEMORY_HOTPLUG_STATUS 8 +/** + * MemStatus: + * @is_removing: the memory device in slot has been requested to be ejected. + * + * This structure stores memory device's status. + */ typedef struct MemStatus { DeviceState *dimm; bool is_enabled; bool is_inserting; + bool is_removing; uint32_t ost_event; uint32_t ost_status; } MemStatus; @@ -28,6 +35,9 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner, void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, DeviceState *dev, Error **errp); +void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq, + MemHotplugState *mem_st, + DeviceState *dev, Error **errp); extern const VMStateDescription vmstate_memory_hotplug; #define VMSTATE_MEMORY_HOTPLUG(memhp, state) \ diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 5352e19..b85eed4 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -400,8 +400,14 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp) void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp) { - error_setg(errp, "acpi: device unplug request for not supported device" - " type: %s", object_get_typename(OBJECT(dev))); + if (pm->acpi_memory_hotplug.is_enabled && + object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + acpi_memory_unplug_request_cb(&pm->acpi_regs, pm->irq, + &pm->acpi_memory_hotplug, dev, errp); + } else { + error_setg(errp, "acpi: device unplug request for not supported device" + " type: %s", object_get_typename(OBJECT(dev))); + } } void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index 6af9303..42fe668 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -75,6 +75,7 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr, case 0x14: /* pack and return is_* fields */ val |= mdev->is_enabled ? 1 : 0; val |= mdev->is_inserting ? 2 : 0; + val |= mdev->is_removing ? 4 : 0; trace_mhp_acpi_read_flags(mem_st->selector, val); break; default: @@ -218,6 +219,24 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, return; } +void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq, + MemHotplugState *mem_st, + DeviceState *dev, Error **errp) +{ + MemStatus *mdev; + + mdev = acpi_memory_slot_status(mem_st, dev, errp); + if (!mdev) { + return; + } + + mdev->is_removing = true; + + /* Do ACPI magic */ + ar->gpe.sts[0] |= ACPI_MEMORY_HOTPLUG_STATUS; + acpi_update_sci(ar, irq); +} + static const VMStateDescription vmstate_memhp_sts = { .name = "memory hotplug device state", .version_id = 1, diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index d1f1179..f716e91 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -361,7 +361,11 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev, { PIIX4PMState *s = PIIX4_PM(hotplug_dev); - if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { + if (s->acpi_memory_hotplug.is_enabled && + object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + acpi_memory_unplug_request_cb(&s->ar, s->irq, &s->acpi_memory_hotplug, + dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { acpi_pcihp_device_unplug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev, errp); } else { diff --git a/hw/i386/pc.c b/hw/i386/pc.c index a8e6be1..9b0859c 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1677,6 +1677,26 @@ out: error_propagate(errp, local_err); } +static void pc_dimm_unplug_request(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + HotplugHandlerClass *hhc; + Error *local_err = NULL; + PCMachineState *pcms = PC_MACHINE(hotplug_dev); + + if (!pcms->acpi_dev) { + error_setg(&local_err, + "memory hotplug is not enabled: missing acpi device"); + goto out; + } + + hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); + hhc->unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); + +out: + error_propagate(errp, local_err); +} + static void pc_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -1719,8 +1739,12 @@ static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev, static void pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - error_setg(errp, "acpi: device unplug request for not supported device" - " type: %s", object_get_typename(OBJECT(dev))); + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + pc_dimm_unplug_request(hotplug_dev, dev, errp); + } else { + error_setg(errp, "acpi: device unplug request for not supported device" + " type: %s", object_get_typename(OBJECT(dev))); + } } static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev, -- MST