提交 b097cc52 编写于 作者: X Xiao Guangrong 提交者: Michael S. Tsirkin

pc: memhp: enable nvdimm device hotplug

_GPE.E04 is dedicated for nvdimm device hotplug
Signed-off-by: NXiao Guangrong <guangrong.xiao@linux.intel.com>
Reviewed-by: NMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: NMichael S. Tsirkin <mst@redhat.com>
上级 806864d9
...@@ -4,6 +4,9 @@ QEMU<->ACPI BIOS memory hotplug interface ...@@ -4,6 +4,9 @@ QEMU<->ACPI BIOS memory hotplug interface
ACPI BIOS GPE.3 handler is dedicated for notifying OS about memory hot-add ACPI BIOS GPE.3 handler is dedicated for notifying OS about memory hot-add
and hot-remove events. and hot-remove events.
ACPI BIOS GPE.4 handler is dedicated for notifying OS about nvdimm device
hot-add and hot-remove events.
Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access): Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access):
--------------------------------------------------------------- ---------------------------------------------------------------
0xa00: 0xa00:
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "hw/acpi/memory_hotplug.h" #include "hw/acpi/memory_hotplug.h"
#include "hw/acpi/pc-hotplug.h" #include "hw/acpi/pc-hotplug.h"
#include "hw/mem/pc-dimm.h" #include "hw/mem/pc-dimm.h"
#include "hw/mem/nvdimm.h"
#include "hw/boards.h" #include "hw/boards.h"
#include "hw/qdev-core.h" #include "hw/qdev-core.h"
#include "trace.h" #include "trace.h"
...@@ -232,11 +233,8 @@ void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st, ...@@ -232,11 +233,8 @@ void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st,
DeviceState *dev, Error **errp) DeviceState *dev, Error **errp)
{ {
MemStatus *mdev; MemStatus *mdev;
DeviceClass *dc = DEVICE_GET_CLASS(dev); AcpiEventStatusBits event;
bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
if (!dc->hotpluggable) {
return;
}
mdev = acpi_memory_slot_status(mem_st, dev, errp); mdev = acpi_memory_slot_status(mem_st, dev, errp);
if (!mdev) { if (!mdev) {
...@@ -244,10 +242,23 @@ void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st, ...@@ -244,10 +242,23 @@ void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st,
} }
mdev->dimm = dev; mdev->dimm = dev;
/*
* do not set is_enabled and is_inserting if the slot is plugged with
* a nvdimm device to stop OSPM inquires memory region from the slot.
*/
if (is_nvdimm) {
event = ACPI_NVDIMM_HOTPLUG_STATUS;
} else {
mdev->is_enabled = true; mdev->is_enabled = true;
event = ACPI_MEMORY_HOTPLUG_STATUS;
}
if (dev->hotplugged) { if (dev->hotplugged) {
if (!is_nvdimm) {
mdev->is_inserting = true; mdev->is_inserting = true;
acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS); }
acpi_send_event(DEVICE(hotplug_dev), event);
} }
} }
...@@ -262,6 +273,8 @@ void acpi_memory_unplug_request_cb(HotplugHandler *hotplug_dev, ...@@ -262,6 +273,8 @@ void acpi_memory_unplug_request_cb(HotplugHandler *hotplug_dev,
return; return;
} }
/* nvdimm device hot unplug is not supported yet. */
assert(!object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM));
mdev->is_removing = true; mdev->is_removing = true;
acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS); acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS);
} }
...@@ -276,6 +289,8 @@ void acpi_memory_unplug_cb(MemHotplugState *mem_st, ...@@ -276,6 +289,8 @@ void acpi_memory_unplug_cb(MemHotplugState *mem_st,
return; return;
} }
/* nvdimm device hot unplug is not supported yet. */
assert(!object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM));
mdev->is_enabled = false; mdev->is_enabled = false;
mdev->dimm = NULL; mdev->dimm = NULL;
} }
......
...@@ -2069,6 +2069,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, ...@@ -2069,6 +2069,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
method = aml_method("_E03", 0, AML_NOTSERIALIZED); method = aml_method("_E03", 0, AML_NOTSERIALIZED);
aml_append(method, aml_call0(MEMORY_HOTPLUG_HANDLER_PATH)); aml_append(method, aml_call0(MEMORY_HOTPLUG_HANDLER_PATH));
aml_append(scope, method); aml_append(scope, method);
if (pcms->acpi_nvdimm_state.is_enabled) {
method = aml_method("_E04", 0, AML_NOTSERIALIZED);
aml_append(method, aml_notify(aml_name("\\_SB.NVDR"),
aml_int(0x80)));
aml_append(scope, method);
}
} }
aml_append(dsdt, scope); aml_append(dsdt, scope);
......
...@@ -1744,6 +1744,12 @@ static void pc_dimm_unplug_request(HotplugHandler *hotplug_dev, ...@@ -1744,6 +1744,12 @@ static void pc_dimm_unplug_request(HotplugHandler *hotplug_dev,
goto out; goto out;
} }
if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
error_setg(&local_err,
"nvdimm device hot unplug is not supported yet.");
goto out;
}
hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
hhc->unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); hhc->unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
...@@ -1761,6 +1767,12 @@ static void pc_dimm_unplug(HotplugHandler *hotplug_dev, ...@@ -1761,6 +1767,12 @@ static void pc_dimm_unplug(HotplugHandler *hotplug_dev,
HotplugHandlerClass *hhc; HotplugHandlerClass *hhc;
Error *local_err = NULL; Error *local_err = NULL;
if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
error_setg(&local_err,
"nvdimm device hot unplug is not supported yet.");
goto out;
}
hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
hhc->unplug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); hhc->unplug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
......
...@@ -148,13 +148,9 @@ static MemoryRegion *nvdimm_get_vmstate_memory_region(PCDIMMDevice *dimm) ...@@ -148,13 +148,9 @@ static MemoryRegion *nvdimm_get_vmstate_memory_region(PCDIMMDevice *dimm)
static void nvdimm_class_init(ObjectClass *oc, void *data) static void nvdimm_class_init(ObjectClass *oc, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(oc);
PCDIMMDeviceClass *ddc = PC_DIMM_CLASS(oc); PCDIMMDeviceClass *ddc = PC_DIMM_CLASS(oc);
NVDIMMClass *nvc = NVDIMM_CLASS(oc); NVDIMMClass *nvc = NVDIMM_CLASS(oc);
/* nvdimm hotplug has not been supported yet. */
dc->hotpluggable = false;
ddc->realize = nvdimm_realize; ddc->realize = nvdimm_realize;
ddc->get_memory_region = nvdimm_get_memory_region; ddc->get_memory_region = nvdimm_get_memory_region;
ddc->get_vmstate_memory_region = nvdimm_get_vmstate_memory_region; ddc->get_vmstate_memory_region = nvdimm_get_vmstate_memory_region;
......
...@@ -10,6 +10,7 @@ typedef enum { ...@@ -10,6 +10,7 @@ typedef enum {
ACPI_PCI_HOTPLUG_STATUS = 2, ACPI_PCI_HOTPLUG_STATUS = 2,
ACPI_CPU_HOTPLUG_STATUS = 4, ACPI_CPU_HOTPLUG_STATUS = 4,
ACPI_MEMORY_HOTPLUG_STATUS = 8, ACPI_MEMORY_HOTPLUG_STATUS = 8,
ACPI_NVDIMM_HOTPLUG_STATUS = 16,
} AcpiEventStatusBits; } AcpiEventStatusBits;
#define TYPE_ACPI_DEVICE_IF "acpi-device-interface" #define TYPE_ACPI_DEVICE_IF "acpi-device-interface"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册