diff options
author | Zhu Guihua <zhugh.fnst@cn.fujitsu.com> | 2015-04-27 16:47:21 +0800 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2015-04-27 21:09:07 +0200 |
commit | c06b2ffb02bfcc642c67300d2c4dffd5aa54932b (patch) | |
tree | 92df290e7b207f928e8e50cf298be347a391294e /hw/acpi | |
parent | 660e8ec70065c8b1fd68b2cb137de16d831959f4 (diff) |
acpi: add hardware implementation for memory hot unplug
- implements QEMU hardware part of memory hot unplug protocol
described at "docs/spec/acpi_mem_hotplug.txt"
- handles memory remove notification event
- handles device eject notification
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Zhu Guihua <zhugh.fnst@cn.fujitsu.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/acpi')
-rw-r--r-- | hw/acpi/memory_hotplug.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index 07e281f4a8..35bbfeb1d8 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -2,6 +2,7 @@ #include "hw/acpi/pc-hotplug.h" #include "hw/mem/pc-dimm.h" #include "hw/boards.h" +#include "hw/qdev-core.h" #include "trace.h" #include "qapi-event.h" @@ -91,6 +92,8 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data, MemHotplugState *mem_st = opaque; MemStatus *mdev; ACPIOSTInfo *info; + DeviceState *dev = NULL; + HotplugHandler *hotplug_ctrl = NULL; if (!mem_st->dev_count) { return; @@ -128,13 +131,29 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data, qapi_event_send_acpi_device_ost(info, &error_abort); qapi_free_ACPIOSTInfo(info); break; - case 0x14: + case 0x14: /* set is_* fields */ mdev = &mem_st->devs[mem_st->selector]; if (data & 2) { /* clear insert event */ mdev->is_inserting = false; trace_mhp_acpi_clear_insert_evt(mem_st->selector); + } else if (data & 4) { + mdev->is_removing = false; + trace_mhp_acpi_clear_remove_evt(mem_st->selector); + } else if (data & 8) { + if (!mdev->is_enabled) { + trace_mhp_acpi_ejecting_invalid_slot(mem_st->selector); + break; + } + + dev = DEVICE(mdev->dimm); + hotplug_ctrl = qdev_get_hotplug_handler(dev); + /* call pc-dimm unplug cb */ + hotplug_handler_unplug(hotplug_ctrl, dev, NULL); + trace_mhp_acpi_pc_dimm_deleted(mem_st->selector); } break; + default: + break; } } |