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
	 Xiao Guangrong
						Xiao Guangrong