• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisionb1b87327a903e298b3b4c79da0beed31b57fb594 (tree)
Time2022-01-20 20:47:52
AuthorGavin Shan <gshan@redh...>
CommiterPeter Maydell

Log Message

hw/arm/virt: Support for virtio-mem-pci

This supports virtio-mem-pci device on "virt" platform, by simply
following the implementation on x86.

    • This implements the hotplug handlers to support virtio-mem-pci
      device hot-add, while the hot-remove isn't supported as we have
      on x86.
    • The block size is 512MB on ARM64 instead of 128MB on x86.
    • It has been passing the tests with various combinations like 64KB
      and 4KB page sizes on host and guest, different memory device
      backends like normal, transparent huge page and HugeTLB, plus
      migration.

Co-developed-by: David Hildenbrand <david@redhat.com>
Co-developed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-id: 20220111063329.74447-3-gshan@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Change Summary

Incremental Difference

--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -28,6 +28,7 @@ config ARM_VIRT
2828 select ACPI_HW_REDUCED
2929 select ACPI_APEI
3030 select ACPI_VIOT
31+ select VIRTIO_MEM_SUPPORTED
3132
3233 config CHEETAH
3334 bool
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -71,9 +71,11 @@
7171 #include "hw/arm/smmuv3.h"
7272 #include "hw/acpi/acpi.h"
7373 #include "target/arm/internals.h"
74+#include "hw/mem/memory-device.h"
7475 #include "hw/mem/pc-dimm.h"
7576 #include "hw/mem/nvdimm.h"
7677 #include "hw/acpi/generic_event_device.h"
78+#include "hw/virtio/virtio-mem-pci.h"
7779 #include "hw/virtio/virtio-iommu.h"
7880 #include "hw/char/pl011.h"
7981 #include "qemu/guest-random.h"
@@ -2501,6 +2503,64 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev,
25012503 dev, &error_abort);
25022504 }
25032505
2506+static void virt_virtio_md_pci_pre_plug(HotplugHandler *hotplug_dev,
2507+ DeviceState *dev, Error **errp)
2508+{
2509+ HotplugHandler *hotplug_dev2 = qdev_get_bus_hotplug_handler(dev);
2510+ Error *local_err = NULL;
2511+
2512+ if (!hotplug_dev2 && dev->hotplugged) {
2513+ /*
2514+ * Without a bus hotplug handler, we cannot control the plug/unplug
2515+ * order. We should never reach this point when hotplugging on ARM.
2516+ * However, it's nice to add a safety net, similar to what we have
2517+ * on x86.
2518+ */
2519+ error_setg(errp, "hotplug of virtio based memory devices not supported"
2520+ " on this bus.");
2521+ return;
2522+ }
2523+ /*
2524+ * First, see if we can plug this memory device at all. If that
2525+ * succeeds, branch of to the actual hotplug handler.
2526+ */
2527+ memory_device_pre_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev), NULL,
2528+ &local_err);
2529+ if (!local_err && hotplug_dev2) {
2530+ hotplug_handler_pre_plug(hotplug_dev2, dev, &local_err);
2531+ }
2532+ error_propagate(errp, local_err);
2533+}
2534+
2535+static void virt_virtio_md_pci_plug(HotplugHandler *hotplug_dev,
2536+ DeviceState *dev, Error **errp)
2537+{
2538+ HotplugHandler *hotplug_dev2 = qdev_get_bus_hotplug_handler(dev);
2539+ Error *local_err = NULL;
2540+
2541+ /*
2542+ * Plug the memory device first and then branch off to the actual
2543+ * hotplug handler. If that one fails, we can easily undo the memory
2544+ * device bits.
2545+ */
2546+ memory_device_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
2547+ if (hotplug_dev2) {
2548+ hotplug_handler_plug(hotplug_dev2, dev, &local_err);
2549+ if (local_err) {
2550+ memory_device_unplug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
2551+ }
2552+ }
2553+ error_propagate(errp, local_err);
2554+}
2555+
2556+static void virt_virtio_md_pci_unplug_request(HotplugHandler *hotplug_dev,
2557+ DeviceState *dev, Error **errp)
2558+{
2559+ /* We don't support hot unplug of virtio based memory devices */
2560+ error_setg(errp, "virtio based memory devices cannot be unplugged.");
2561+}
2562+
2563+
25042564 static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
25052565 DeviceState *dev, Error **errp)
25062566 {
@@ -2508,6 +2568,8 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
25082568
25092569 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
25102570 virt_memory_pre_plug(hotplug_dev, dev, errp);
2571+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
2572+ virt_virtio_md_pci_pre_plug(hotplug_dev, dev, errp);
25112573 } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
25122574 hwaddr db_start = 0, db_end = 0;
25132575 char *resv_prop_str;
@@ -2559,6 +2621,11 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
25592621 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
25602622 virt_memory_plug(hotplug_dev, dev, errp);
25612623 }
2624+
2625+ if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
2626+ virt_virtio_md_pci_plug(hotplug_dev, dev, errp);
2627+ }
2628+
25622629 if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
25632630 PCIDevice *pdev = PCI_DEVICE(dev);
25642631
@@ -2615,6 +2682,8 @@ static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
26152682 {
26162683 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
26172684 virt_dimm_unplug_request(hotplug_dev, dev, errp);
2685+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
2686+ virt_virtio_md_pci_unplug_request(hotplug_dev, dev, errp);
26182687 } else {
26192688 error_setg(errp, "device unplug request for unsupported device"
26202689 " type: %s", object_get_typename(OBJECT(dev)));
@@ -2639,6 +2708,7 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
26392708
26402709 if (device_is_dynamic_sysbus(mc, dev) ||
26412710 object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
2711+ object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI) ||
26422712 object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
26432713 return HOTPLUG_HANDLER(machine);
26442714 }
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -146,7 +146,7 @@ static bool virtio_mem_has_shared_zeropage(RAMBlock *rb)
146146 * The memory block size corresponds mostly to the section size.
147147 *
148148 * This allows e.g., to add 20MB with a section size of 128MB on x86_64, and
149- * a section size of 1GB on arm64 (as long as the start address is properly
149+ * a section size of 512MB on arm64 (as long as the start address is properly
150150 * aligned, similar to ordinary DIMMs).
151151 *
152152 * We can change this at any time and maybe even make it configurable if
@@ -155,6 +155,8 @@ static bool virtio_mem_has_shared_zeropage(RAMBlock *rb)
155155 */
156156 #if defined(TARGET_X86_64) || defined(TARGET_I386)
157157 #define VIRTIO_MEM_USABLE_EXTENT (2 * (128 * MiB))
158+#elif defined(TARGET_ARM)
159+#define VIRTIO_MEM_USABLE_EXTENT (2 * (512 * MiB))
158160 #else
159161 #error VIRTIO_MEM_USABLE_EXTENT not defined
160162 #endif