qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

hw/arm/virt: Add nvdimm hotplug support

This adds support for nvdimm hotplug events through GED
and enables nvdimm for the arm/virt. Now Guests with ACPI
can have both cold and hot plug of nvdimms.

Hot removal functionality is not yet supported.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Message-Id: <20200421125934.14952-5-shameerali.kolothum.thodi@huawei.com>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

authored by

Shameer Kolothum and committed by
Michael S. Tsirkin
c2505d1c b5a60bee

+28 -7
+2 -1
docs/specs/acpi_hw_reduced_hotplug.rst
··· 63 63 bits: 64 64 0: Memory hotplug event 65 65 1: System power down event 66 - 2-31: Reserved 66 + 2: NVDIMM hotplug event 67 + 3-31: Reserved 67 68 68 69 **write_access:** 69 70
+14 -1
hw/acpi/generic_event_device.c
··· 16 16 #include "hw/acpi/generic_event_device.h" 17 17 #include "hw/irq.h" 18 18 #include "hw/mem/pc-dimm.h" 19 + #include "hw/mem/nvdimm.h" 19 20 #include "hw/qdev-properties.h" 20 21 #include "migration/vmstate.h" 21 22 #include "qemu/error-report.h" ··· 23 24 static const uint32_t ged_supported_events[] = { 24 25 ACPI_GED_MEM_HOTPLUG_EVT, 25 26 ACPI_GED_PWR_DOWN_EVT, 27 + ACPI_GED_NVDIMM_HOTPLUG_EVT, 26 28 }; 27 29 28 30 /* ··· 110 112 aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE), 111 113 aml_int(0x80))); 112 114 break; 115 + case ACPI_GED_NVDIMM_HOTPLUG_EVT: 116 + aml_append(if_ctx, 117 + aml_notify(aml_name("\\_SB.NVDR"), 118 + aml_int(0x80))); 119 + break; 113 120 default: 114 121 /* 115 122 * Please make sure all the events in ged_supported_events[] ··· 175 182 AcpiGedState *s = ACPI_GED(hotplug_dev); 176 183 177 184 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { 178 - acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp); 185 + if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { 186 + nvdimm_acpi_plug_cb(hotplug_dev, dev); 187 + } else { 188 + acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp); 189 + } 179 190 } else { 180 191 error_setg(errp, "virt: device plug request for unsupported device" 181 192 " type: %s", object_get_typename(OBJECT(dev))); ··· 192 203 sel = ACPI_GED_MEM_HOTPLUG_EVT; 193 204 } else if (ev & ACPI_POWER_DOWN_STATUS) { 194 205 sel = ACPI_GED_PWR_DOWN_EVT; 206 + } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) { 207 + sel = ACPI_GED_NVDIMM_HOTPLUG_EVT; 195 208 } else { 196 209 /* Unknown event. Return without generating interrupt. */ 197 210 warn_report("GED: Unsupported event %d. No irq injected", ev);
+11 -5
hw/arm/virt.c
··· 568 568 event |= ACPI_GED_MEM_HOTPLUG_EVT; 569 569 } 570 570 571 + if (ms->nvdimms_state->is_enabled) { 572 + event |= ACPI_GED_NVDIMM_HOTPLUG_EVT; 573 + } 574 + 571 575 dev = qdev_create(NULL, TYPE_ACPI_GED); 572 576 qdev_prop_set_uint32(dev, "ged-event", event); 573 577 ··· 2088 2092 Error **errp) 2089 2093 { 2090 2094 VirtMachineState *vms = VIRT_MACHINE(hotplug_dev); 2095 + const MachineState *ms = MACHINE(hotplug_dev); 2091 2096 const bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM); 2092 2097 2093 - if (is_nvdimm) { 2094 - error_setg(errp, "nvdimm is not yet supported"); 2098 + if (!vms->acpi_dev) { 2099 + error_setg(errp, 2100 + "memory hotplug is not enabled: missing acpi-ged device"); 2095 2101 return; 2096 2102 } 2097 2103 2098 - if (!vms->acpi_dev) { 2099 - error_setg(errp, 2100 - "memory hotplug is not enabled: missing acpi-ged device"); 2104 + if (is_nvdimm && !ms->nvdimms_state->is_enabled) { 2105 + error_setg(errp, "nvdimm is not enabled: add 'nvdimm=on' to '-M'"); 2101 2106 return; 2102 2107 } 2103 2108 ··· 2245 2250 hc->plug = virt_machine_device_plug_cb; 2246 2251 hc->unplug_request = virt_machine_device_unplug_request_cb; 2247 2252 mc->numa_mem_supported = true; 2253 + mc->nvdimm_supported = true; 2248 2254 mc->auto_enable_numa_with_memhp = true; 2249 2255 mc->default_ram_id = "mach-virt.ram"; 2250 2256
+1
include/hw/acpi/generic_event_device.h
··· 82 82 */ 83 83 #define ACPI_GED_MEM_HOTPLUG_EVT 0x1 84 84 #define ACPI_GED_PWR_DOWN_EVT 0x2 85 + #define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4 85 86 86 87 typedef struct GEDState { 87 88 MemoryRegion io;