diff mbox series

[v5,03/12] hw/i386/pc: Move IOMMU singleton into PCMachineState

Message ID 20211020172745.620101-4-jean-philippe@linaro.org
State Superseded
Headers show
Series virtio-iommu: Add ACPI support | expand

Commit Message

Jean-Philippe Brucker Oct. 20, 2021, 5:27 p.m. UTC
We're about to support a third vIOMMU for x86, virtio-iommu which
doesn't inherit X86IOMMUState. Move the IOMMU singleton into
PCMachineState, so it can be shared between all three vIOMMUs.

The x86_iommu_get_default() helper is still needed by KVM and IOAPIC to
fetch the default IRQ-remapping IOMMU. Since virtio-iommu doesn't
support IRQ remapping, this interface doesn't need to change for the
moment. We could later replace X86IOMMUState with an "IRQ remapping
IOMMU" interface if necessary.

Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>

---
 include/hw/i386/pc.h |  1 +
 hw/i386/pc.c         | 12 +++++++++++-
 hw/i386/x86-iommu.c  | 26 ++++++++------------------
 3 files changed, 20 insertions(+), 19 deletions(-)

-- 
2.33.0

Comments

Eric Auger Oct. 21, 2021, 9:02 a.m. UTC | #1
On 10/20/21 7:27 PM, Jean-Philippe Brucker wrote:
> We're about to support a third vIOMMU for x86, virtio-iommu which

> doesn't inherit X86IOMMUState. Move the IOMMU singleton into

> PCMachineState, so it can be shared between all three vIOMMUs.

>

> The x86_iommu_get_default() helper is still needed by KVM and IOAPIC to

> fetch the default IRQ-remapping IOMMU. Since virtio-iommu doesn't

> support IRQ remapping, this interface doesn't need to change for the

> moment. We could later replace X86IOMMUState with an "IRQ remapping

> IOMMU" interface if necessary.

>

> Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>

Reviewed-by: Eric Auger <eric.auger@redhat.com>


Eric

> ---

>  include/hw/i386/pc.h |  1 +

>  hw/i386/pc.c         | 12 +++++++++++-

>  hw/i386/x86-iommu.c  | 26 ++++++++------------------

>  3 files changed, 20 insertions(+), 19 deletions(-)

>

> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h

> index 11426e26dc..b72e5bf9d1 100644

> --- a/include/hw/i386/pc.h

> +++ b/include/hw/i386/pc.h

> @@ -35,6 +35,7 @@ typedef struct PCMachineState {

>      I2CBus *smbus;

>      PFlashCFI01 *flash[2];

>      ISADevice *pcspk;

> +    DeviceState *iommu;

>  

>      /* Configuration options: */

>      uint64_t max_ram_below_4g;

> diff --git a/hw/i386/pc.c b/hw/i386/pc.c

> index 54e4c00dce..fcbf328e8d 100644

> --- a/hw/i386/pc.c

> +++ b/hw/i386/pc.c

> @@ -1330,6 +1330,15 @@ static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,

>      } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) ||

>                 object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {

>          pc_virtio_md_pci_pre_plug(hotplug_dev, dev, errp);

> +    } else if (object_dynamic_cast(OBJECT(dev), TYPE_X86_IOMMU_DEVICE)) {

> +        PCMachineState *pcms = PC_MACHINE(hotplug_dev);

> +

> +        if (pcms->iommu) {

> +            error_setg(errp, "QEMU does not support multiple vIOMMUs "

> +                       "for x86 yet.");

> +            return;

> +        }

> +        pcms->iommu = dev;

>      }

>  }

>  

> @@ -1384,7 +1393,8 @@ static HotplugHandler *pc_get_hotplug_handler(MachineState *machine,

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

>          object_dynamic_cast(OBJECT(dev), TYPE_CPU) ||

>          object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) ||

> -        object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {

> +        object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI) ||

> +        object_dynamic_cast(OBJECT(dev), TYPE_X86_IOMMU_DEVICE)) {

>          return HOTPLUG_HANDLER(machine);

>      }

>  

> diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c

> index dc968c7a53..01d11325a6 100644

> --- a/hw/i386/x86-iommu.c

> +++ b/hw/i386/x86-iommu.c

> @@ -77,25 +77,17 @@ void x86_iommu_irq_to_msi_message(X86IOMMUIrq *irq, MSIMessage *msg_out)

>      msg_out->data = msg.msi_data;

>  }

>  

> -/* Default X86 IOMMU device */

> -static X86IOMMUState *x86_iommu_default = NULL;

> -

> -static void x86_iommu_set_default(X86IOMMUState *x86_iommu)

> +X86IOMMUState *x86_iommu_get_default(void)

>  {

> -    assert(x86_iommu);

> +    MachineState *ms = MACHINE(qdev_get_machine());

> +    PCMachineState *pcms =

> +        PC_MACHINE(object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE));

>  

> -    if (x86_iommu_default) {

> -        error_report("QEMU does not support multiple vIOMMUs "

> -                     "for x86 yet.");

> -        exit(1);

> +    if (pcms &&

> +        object_dynamic_cast(OBJECT(pcms->iommu), TYPE_X86_IOMMU_DEVICE)) {

> +        return X86_IOMMU_DEVICE(pcms->iommu);

>      }

> -

> -    x86_iommu_default = x86_iommu;

> -}

> -

> -X86IOMMUState *x86_iommu_get_default(void)

> -{

> -    return x86_iommu_default;

> +    return NULL;

>  }

>  

>  static void x86_iommu_realize(DeviceState *dev, Error **errp)

> @@ -131,8 +123,6 @@ static void x86_iommu_realize(DeviceState *dev, Error **errp)

>      if (x86_class->realize) {

>          x86_class->realize(dev, errp);

>      }

> -

> -    x86_iommu_set_default(X86_IOMMU_DEVICE(dev));

>  }

>  

>  static Property x86_iommu_properties[] = {
Igor Mammedov Oct. 21, 2021, 1:34 p.m. UTC | #2
On Wed, 20 Oct 2021 18:27:37 +0100
Jean-Philippe Brucker <jean-philippe@linaro.org> wrote:

> We're about to support a third vIOMMU for x86, virtio-iommu which

> doesn't inherit X86IOMMUState. Move the IOMMU singleton into

> PCMachineState, so it can be shared between all three vIOMMUs.

> 

> The x86_iommu_get_default() helper is still needed by KVM and IOAPIC to

> fetch the default IRQ-remapping IOMMU. Since virtio-iommu doesn't

> support IRQ remapping, this interface doesn't need to change for the

> moment. We could later replace X86IOMMUState with an "IRQ remapping

> IOMMU" interface if necessary.

> 

> Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>


Reviewed-by: Igor Mammedov <imammedo@redhat.com>


> ---

>  include/hw/i386/pc.h |  1 +

>  hw/i386/pc.c         | 12 +++++++++++-

>  hw/i386/x86-iommu.c  | 26 ++++++++------------------

>  3 files changed, 20 insertions(+), 19 deletions(-)

> 

> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h

> index 11426e26dc..b72e5bf9d1 100644

> --- a/include/hw/i386/pc.h

> +++ b/include/hw/i386/pc.h

> @@ -35,6 +35,7 @@ typedef struct PCMachineState {

>      I2CBus *smbus;

>      PFlashCFI01 *flash[2];

>      ISADevice *pcspk;

> +    DeviceState *iommu;

>  

>      /* Configuration options: */

>      uint64_t max_ram_below_4g;

> diff --git a/hw/i386/pc.c b/hw/i386/pc.c

> index 54e4c00dce..fcbf328e8d 100644

> --- a/hw/i386/pc.c

> +++ b/hw/i386/pc.c

> @@ -1330,6 +1330,15 @@ static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,

>      } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) ||

>                 object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {

>          pc_virtio_md_pci_pre_plug(hotplug_dev, dev, errp);

> +    } else if (object_dynamic_cast(OBJECT(dev), TYPE_X86_IOMMU_DEVICE)) {

> +        PCMachineState *pcms = PC_MACHINE(hotplug_dev);

> +

> +        if (pcms->iommu) {

> +            error_setg(errp, "QEMU does not support multiple vIOMMUs "

> +                       "for x86 yet.");

> +            return;

> +        }

> +        pcms->iommu = dev;

>      }

>  }

>  

> @@ -1384,7 +1393,8 @@ static HotplugHandler *pc_get_hotplug_handler(MachineState *machine,

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

>          object_dynamic_cast(OBJECT(dev), TYPE_CPU) ||

>          object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) ||

> -        object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {

> +        object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI) ||

> +        object_dynamic_cast(OBJECT(dev), TYPE_X86_IOMMU_DEVICE)) {

>          return HOTPLUG_HANDLER(machine);

>      }

>  

> diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c

> index dc968c7a53..01d11325a6 100644

> --- a/hw/i386/x86-iommu.c

> +++ b/hw/i386/x86-iommu.c

> @@ -77,25 +77,17 @@ void x86_iommu_irq_to_msi_message(X86IOMMUIrq *irq, MSIMessage *msg_out)

>      msg_out->data = msg.msi_data;

>  }

>  

> -/* Default X86 IOMMU device */

> -static X86IOMMUState *x86_iommu_default = NULL;

> -

> -static void x86_iommu_set_default(X86IOMMUState *x86_iommu)

> +X86IOMMUState *x86_iommu_get_default(void)

>  {

> -    assert(x86_iommu);

> +    MachineState *ms = MACHINE(qdev_get_machine());

> +    PCMachineState *pcms =

> +        PC_MACHINE(object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE));

>  

> -    if (x86_iommu_default) {

> -        error_report("QEMU does not support multiple vIOMMUs "

> -                     "for x86 yet.");

> -        exit(1);

> +    if (pcms &&

> +        object_dynamic_cast(OBJECT(pcms->iommu), TYPE_X86_IOMMU_DEVICE)) {

> +        return X86_IOMMU_DEVICE(pcms->iommu);

>      }

> -

> -    x86_iommu_default = x86_iommu;

> -}

> -

> -X86IOMMUState *x86_iommu_get_default(void)

> -{

> -    return x86_iommu_default;

> +    return NULL;

>  }

>  

>  static void x86_iommu_realize(DeviceState *dev, Error **errp)

> @@ -131,8 +123,6 @@ static void x86_iommu_realize(DeviceState *dev, Error **errp)

>      if (x86_class->realize) {

>          x86_class->realize(dev, errp);

>      }

> -

> -    x86_iommu_set_default(X86_IOMMU_DEVICE(dev));

>  }

>  

>  static Property x86_iommu_properties[] = {
diff mbox series

Patch

diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 11426e26dc..b72e5bf9d1 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -35,6 +35,7 @@  typedef struct PCMachineState {
     I2CBus *smbus;
     PFlashCFI01 *flash[2];
     ISADevice *pcspk;
+    DeviceState *iommu;
 
     /* Configuration options: */
     uint64_t max_ram_below_4g;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 54e4c00dce..fcbf328e8d 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1330,6 +1330,15 @@  static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) ||
                object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
         pc_virtio_md_pci_pre_plug(hotplug_dev, dev, errp);
+    } else if (object_dynamic_cast(OBJECT(dev), TYPE_X86_IOMMU_DEVICE)) {
+        PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+
+        if (pcms->iommu) {
+            error_setg(errp, "QEMU does not support multiple vIOMMUs "
+                       "for x86 yet.");
+            return;
+        }
+        pcms->iommu = dev;
     }
 }
 
@@ -1384,7 +1393,8 @@  static HotplugHandler *pc_get_hotplug_handler(MachineState *machine,
     if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
         object_dynamic_cast(OBJECT(dev), TYPE_CPU) ||
         object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) ||
-        object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
+        object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI) ||
+        object_dynamic_cast(OBJECT(dev), TYPE_X86_IOMMU_DEVICE)) {
         return HOTPLUG_HANDLER(machine);
     }
 
diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c
index dc968c7a53..01d11325a6 100644
--- a/hw/i386/x86-iommu.c
+++ b/hw/i386/x86-iommu.c
@@ -77,25 +77,17 @@  void x86_iommu_irq_to_msi_message(X86IOMMUIrq *irq, MSIMessage *msg_out)
     msg_out->data = msg.msi_data;
 }
 
-/* Default X86 IOMMU device */
-static X86IOMMUState *x86_iommu_default = NULL;
-
-static void x86_iommu_set_default(X86IOMMUState *x86_iommu)
+X86IOMMUState *x86_iommu_get_default(void)
 {
-    assert(x86_iommu);
+    MachineState *ms = MACHINE(qdev_get_machine());
+    PCMachineState *pcms =
+        PC_MACHINE(object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE));
 
-    if (x86_iommu_default) {
-        error_report("QEMU does not support multiple vIOMMUs "
-                     "for x86 yet.");
-        exit(1);
+    if (pcms &&
+        object_dynamic_cast(OBJECT(pcms->iommu), TYPE_X86_IOMMU_DEVICE)) {
+        return X86_IOMMU_DEVICE(pcms->iommu);
     }
-
-    x86_iommu_default = x86_iommu;
-}
-
-X86IOMMUState *x86_iommu_get_default(void)
-{
-    return x86_iommu_default;
+    return NULL;
 }
 
 static void x86_iommu_realize(DeviceState *dev, Error **errp)
@@ -131,8 +123,6 @@  static void x86_iommu_realize(DeviceState *dev, Error **errp)
     if (x86_class->realize) {
         x86_class->realize(dev, errp);
     }
-
-    x86_iommu_set_default(X86_IOMMU_DEVICE(dev));
 }
 
 static Property x86_iommu_properties[] = {