mirror of https://github.com/xemu-project/xemu.git
pc: memhp: enable nvdimm device hotplug
_GPE.E04 is dedicated for nvdimm device hotplug Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
806864d9a8
commit
b097cc52fc
|
@ -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 @@
|
||||||
#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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
mdev->dimm = dev;
|
mdev->dimm = dev;
|
||||||
mdev->is_enabled = true;
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
event = ACPI_MEMORY_HOTPLUG_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
if (dev->hotplugged) {
|
if (dev->hotplugged) {
|
||||||
mdev->is_inserting = true;
|
if (!is_nvdimm) {
|
||||||
acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS);
|
mdev->is_inserting = true;
|
||||||
|
}
|
||||||
|
acpi_send_event(DEVICE(hotplug_dev), event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
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,
|
||||||
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);
|
||||||
|
|
||||||
|
|
12
hw/i386/pc.c
12
hw/i386/pc.c
|
@ -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,
|
||||||
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)
|
||||||
|
|
||||||
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 {
|
||||||
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"
|
||||||
|
|
Loading…
Reference in New Issue