diff mbox series

[5/5] hw/arm/virt: Add nvdimm hotplug support

Message ID 20191004155302.4632-6-shameerali.kolothum.thodi@huawei.com
State New
Headers show
Series ARM virt: Add NVDIMM support | expand

Commit Message

Shameerali Kolothum Thodi Oct. 4, 2019, 3:53 p.m. UTC
This adds support for nvdimm hotplug events through GED
and enables nvdimm for the arm/virt. Now Guests with DT boot
can have nvdimm cold plug and with ACPI both cold/hot plug.

Hot removal functionality is not yet supported.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>

---
 docs/specs/acpi_hw_reduced_hotplug.rst |  1 +
 hw/acpi/generic_event_device.c         | 13 +++++++++++++
 hw/arm/virt.c                          | 20 +++++++++++++++-----
 include/hw/acpi/generic_event_device.h |  1 +
 4 files changed, 30 insertions(+), 5 deletions(-)

-- 
2.17.1

Comments

Igor Mammedov Nov. 12, 2019, 1:01 p.m. UTC | #1
On Fri, 4 Oct 2019 16:53:02 +0100
Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> wrote:

> This adds support for nvdimm hotplug events through GED

> and enables nvdimm for the arm/virt. Now Guests with DT boot

> can have nvdimm cold plug and with ACPI both cold/hot plug.

> 

> Hot removal functionality is not yet supported.

> 

> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>


I'd move out DT cold-plug out of this patch is it's not related
to this patch at all

otherwise patch looks good, so 
Reviewed-by: Igor Mammedov <imammedo@redhat.com>


> ---

>  docs/specs/acpi_hw_reduced_hotplug.rst |  1 +

>  hw/acpi/generic_event_device.c         | 13 +++++++++++++

>  hw/arm/virt.c                          | 20 +++++++++++++++-----

>  include/hw/acpi/generic_event_device.h |  1 +

>  4 files changed, 30 insertions(+), 5 deletions(-)

> 

> diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst b/docs/specs/acpi_hw_reduced_hotplug.rst

> index 911a98255b..e3abe975bf 100644

> --- a/docs/specs/acpi_hw_reduced_hotplug.rst

> +++ b/docs/specs/acpi_hw_reduced_hotplug.rst

> @@ -63,6 +63,7 @@ GED IO interface (4 byte access)

>      bits:

>         0: Memory hotplug event

>         1: System power down event

> +       2: NVDIMM hotplug event

>      2-31: Reserved

>  

>  **write_access:**

> diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c

> index 9cee90cc70..ad1b684304 100644

> --- a/hw/acpi/generic_event_device.c

> +++ b/hw/acpi/generic_event_device.c

> @@ -16,6 +16,7 @@

>  #include "hw/acpi/generic_event_device.h"

>  #include "hw/irq.h"

>  #include "hw/mem/pc-dimm.h"

> +#include "hw/mem/nvdimm.h"

>  #include "hw/qdev-properties.h"

>  #include "migration/vmstate.h"

>  #include "qemu/error-report.h"

> @@ -23,6 +24,7 @@

>  static const uint32_t ged_supported_events[] = {

>      ACPI_GED_MEM_HOTPLUG_EVT,

>      ACPI_GED_PWR_DOWN_EVT,

> +    ACPI_GED_NVDIMM_HOTPLUG_EVT,

>  };

>  

>  /*

> @@ -110,6 +112,11 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,

>                             aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),

>                                        aml_int(0x80)));

>                  break;

> +            case ACPI_GED_NVDIMM_HOTPLUG_EVT:

> +                aml_append(if_ctx,

> +                           aml_notify(aml_name("\\_SB.NVDR"),

> +                                      aml_int(0x80)));

> +                break;

>              default:

>                  /*

>                   * Please make sure all the events in ged_supported_events[]

> @@ -175,7 +182,11 @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,

>      AcpiGedState *s = ACPI_GED(hotplug_dev);

>  

>      if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {

> +        if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {

> +            nvdimm_acpi_plug_cb(hotplug_dev, dev);

> +        } else {

>              acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp);

> +        }

>      } else {

>          error_setg(errp, "virt: device plug request for unsupported device"

>                     " type: %s", object_get_typename(OBJECT(dev)));

> @@ -192,6 +203,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)

>          sel = ACPI_GED_MEM_HOTPLUG_EVT;

>      } else if (ev & ACPI_POWER_DOWN_STATUS) {

>          sel = ACPI_GED_PWR_DOWN_EVT;

> +    } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {

> +        sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;

>      } else {

>          /* Unknown event. Return without generating interrupt. */

>          warn_report("GED: Unsupported event %d. No irq injected", ev);

> diff --git a/hw/arm/virt.c b/hw/arm/virt.c

> index 30bc8a7803..acdcba9638 100644

> --- a/hw/arm/virt.c

> +++ b/hw/arm/virt.c

> @@ -543,6 +543,10 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)

>          event |= ACPI_GED_MEM_HOTPLUG_EVT;

>      }

>  

> +    if (ms->nvdimms_state->is_enabled) {

> +        event |= ACPI_GED_NVDIMM_HOTPLUG_EVT;

> +    }

> +

>      dev = qdev_create(NULL, TYPE_ACPI_GED);

>      qdev_prop_set_uint32(dev, "ged-event", event);

>  

> @@ -1938,9 +1942,12 @@ static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,

>      }

>  

>      if (!vms->acpi_dev) {

> -        error_setg(errp,

> -                   "memory hotplug is not enabled: missing acpi-ged device");

> -        return;

> +        /* Allow nvdimm DT or cold plug */

> +        if (!(is_nvdimm && !dev->hotplugged)) {

> +            error_setg(errp,

> +                       "memory hotplug is not enabled: missing acpi-ged device");

> +            return;

> +         }




>      }

>  

>      pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp);

> @@ -1964,8 +1971,10 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev,

>          nvdimm_plug(ms->nvdimms_state);

>      }

>  

> -    hhc = HOTPLUG_HANDLER_GET_CLASS(vms->acpi_dev);

> -    hhc->plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &error_abort);

> +    if (vms->acpi_dev) {

> +        hhc = HOTPLUG_HANDLER_GET_CLASS(vms->acpi_dev);

> +        hhc->plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &error_abort);

> +    }

>  out:

>      error_propagate(errp, local_err);

>  }

> @@ -2073,6 +2082,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)

>      hc->plug = virt_machine_device_plug_cb;

>      hc->unplug_request = virt_machine_device_unplug_request_cb;

>      mc->numa_mem_supported = true;

> +    mc->nvdimm_supported = true;

>      mc->auto_enable_numa_with_memhp = true;

>  }

>  

> diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h

> index d157eac088..9eb86ca4fd 100644

> --- a/include/hw/acpi/generic_event_device.h

> +++ b/include/hw/acpi/generic_event_device.h

> @@ -82,6 +82,7 @@

>   */

>  #define ACPI_GED_MEM_HOTPLUG_EVT   0x1

>  #define ACPI_GED_PWR_DOWN_EVT      0x2

> +#define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4

>  

>  typedef struct GEDState {

>      MemoryRegion io;
diff mbox series

Patch

diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst b/docs/specs/acpi_hw_reduced_hotplug.rst
index 911a98255b..e3abe975bf 100644
--- a/docs/specs/acpi_hw_reduced_hotplug.rst
+++ b/docs/specs/acpi_hw_reduced_hotplug.rst
@@ -63,6 +63,7 @@  GED IO interface (4 byte access)
     bits:
        0: Memory hotplug event
        1: System power down event
+       2: NVDIMM hotplug event
     2-31: Reserved
 
 **write_access:**
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 9cee90cc70..ad1b684304 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -16,6 +16,7 @@ 
 #include "hw/acpi/generic_event_device.h"
 #include "hw/irq.h"
 #include "hw/mem/pc-dimm.h"
+#include "hw/mem/nvdimm.h"
 #include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
 #include "qemu/error-report.h"
@@ -23,6 +24,7 @@ 
 static const uint32_t ged_supported_events[] = {
     ACPI_GED_MEM_HOTPLUG_EVT,
     ACPI_GED_PWR_DOWN_EVT,
+    ACPI_GED_NVDIMM_HOTPLUG_EVT,
 };
 
 /*
@@ -110,6 +112,11 @@  void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
                            aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
                                       aml_int(0x80)));
                 break;
+            case ACPI_GED_NVDIMM_HOTPLUG_EVT:
+                aml_append(if_ctx,
+                           aml_notify(aml_name("\\_SB.NVDR"),
+                                      aml_int(0x80)));
+                break;
             default:
                 /*
                  * Please make sure all the events in ged_supported_events[]
@@ -175,7 +182,11 @@  static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
     AcpiGedState *s = ACPI_GED(hotplug_dev);
 
     if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+        if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
+            nvdimm_acpi_plug_cb(hotplug_dev, dev);
+        } else {
             acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp);
+        }
     } else {
         error_setg(errp, "virt: device plug request for unsupported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
@@ -192,6 +203,8 @@  static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
         sel = ACPI_GED_MEM_HOTPLUG_EVT;
     } else if (ev & ACPI_POWER_DOWN_STATUS) {
         sel = ACPI_GED_PWR_DOWN_EVT;
+    } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) {
+        sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
     } else {
         /* Unknown event. Return without generating interrupt. */
         warn_report("GED: Unsupported event %d. No irq injected", ev);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 30bc8a7803..acdcba9638 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -543,6 +543,10 @@  static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
         event |= ACPI_GED_MEM_HOTPLUG_EVT;
     }
 
+    if (ms->nvdimms_state->is_enabled) {
+        event |= ACPI_GED_NVDIMM_HOTPLUG_EVT;
+    }
+
     dev = qdev_create(NULL, TYPE_ACPI_GED);
     qdev_prop_set_uint32(dev, "ged-event", event);
 
@@ -1938,9 +1942,12 @@  static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
     }
 
     if (!vms->acpi_dev) {
-        error_setg(errp,
-                   "memory hotplug is not enabled: missing acpi-ged device");
-        return;
+        /* Allow nvdimm DT or cold plug */
+        if (!(is_nvdimm && !dev->hotplugged)) {
+            error_setg(errp,
+                       "memory hotplug is not enabled: missing acpi-ged device");
+            return;
+         }
     }
 
     pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp);
@@ -1964,8 +1971,10 @@  static void virt_memory_plug(HotplugHandler *hotplug_dev,
         nvdimm_plug(ms->nvdimms_state);
     }
 
-    hhc = HOTPLUG_HANDLER_GET_CLASS(vms->acpi_dev);
-    hhc->plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &error_abort);
+    if (vms->acpi_dev) {
+        hhc = HOTPLUG_HANDLER_GET_CLASS(vms->acpi_dev);
+        hhc->plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &error_abort);
+    }
 out:
     error_propagate(errp, local_err);
 }
@@ -2073,6 +2082,7 @@  static void virt_machine_class_init(ObjectClass *oc, void *data)
     hc->plug = virt_machine_device_plug_cb;
     hc->unplug_request = virt_machine_device_unplug_request_cb;
     mc->numa_mem_supported = true;
+    mc->nvdimm_supported = true;
     mc->auto_enable_numa_with_memhp = true;
 }
 
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
index d157eac088..9eb86ca4fd 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -82,6 +82,7 @@ 
  */
 #define ACPI_GED_MEM_HOTPLUG_EVT   0x1
 #define ACPI_GED_PWR_DOWN_EVT      0x2
+#define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4
 
 typedef struct GEDState {
     MemoryRegion io;