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
|
||||
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):
|
||||
---------------------------------------------------------------
|
||||
0xa00:
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "hw/acpi/memory_hotplug.h"
|
||||
#include "hw/acpi/pc-hotplug.h"
|
||||
#include "hw/mem/pc-dimm.h"
|
||||
#include "hw/mem/nvdimm.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/qdev-core.h"
|
||||
#include "trace.h"
|
||||
@ -232,11 +233,8 @@ void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
MemStatus *mdev;
|
||||
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||
|
||||
if (!dc->hotpluggable) {
|
||||
return;
|
||||
}
|
||||
AcpiEventStatusBits event;
|
||||
bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
|
||||
|
||||
mdev = acpi_memory_slot_status(mem_st, dev, errp);
|
||||
if (!mdev) {
|
||||
@ -244,10 +242,23 @@ void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st,
|
||||
}
|
||||
|
||||
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) {
|
||||
mdev->is_inserting = true;
|
||||
acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS);
|
||||
if (!is_nvdimm) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* nvdimm device hot unplug is not supported yet. */
|
||||
assert(!object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM));
|
||||
mdev->is_removing = true;
|
||||
acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS);
|
||||
}
|
||||
@ -276,6 +289,8 @@ void acpi_memory_unplug_cb(MemHotplugState *mem_st,
|
||||
return;
|
||||
}
|
||||
|
||||
/* nvdimm device hot unplug is not supported yet. */
|
||||
assert(!object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM));
|
||||
mdev->is_enabled = false;
|
||||
mdev->dimm = NULL;
|
||||
}
|
||||
|
@ -2069,6 +2069,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
||||
method = aml_method("_E03", 0, AML_NOTSERIALIZED);
|
||||
aml_append(method, aml_call0(MEMORY_HOTPLUG_HANDLER_PATH));
|
||||
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);
|
||||
|
||||
|
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;
|
||||
}
|
||||
|
||||
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->unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
|
||||
|
||||
@ -1761,6 +1767,12 @@ static void pc_dimm_unplug(HotplugHandler *hotplug_dev,
|
||||
HotplugHandlerClass *hhc;
|
||||
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->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)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
PCDIMMDeviceClass *ddc = PC_DIMM_CLASS(oc);
|
||||
NVDIMMClass *nvc = NVDIMM_CLASS(oc);
|
||||
|
||||
/* nvdimm hotplug has not been supported yet. */
|
||||
dc->hotpluggable = false;
|
||||
|
||||
ddc->realize = nvdimm_realize;
|
||||
ddc->get_memory_region = nvdimm_get_memory_region;
|
||||
ddc->get_vmstate_memory_region = nvdimm_get_vmstate_memory_region;
|
||||
|
@ -10,6 +10,7 @@ typedef enum {
|
||||
ACPI_PCI_HOTPLUG_STATUS = 2,
|
||||
ACPI_CPU_HOTPLUG_STATUS = 4,
|
||||
ACPI_MEMORY_HOTPLUG_STATUS = 8,
|
||||
ACPI_NVDIMM_HOTPLUG_STATUS = 16,
|
||||
} AcpiEventStatusBits;
|
||||
|
||||
#define TYPE_ACPI_DEVICE_IF "acpi-device-interface"
|
||||
|
Loading…
x
Reference in New Issue
Block a user