mbox series

[0/8] pci/iommu: Fail early if vfio-pci detected before vIOMMU

Message ID 20211021104259.57754-1-peterx@redhat.com
Headers show
Series pci/iommu: Fail early if vfio-pci detected before vIOMMU | expand

Message

Peter Xu Oct. 21, 2021, 10:42 a.m. UTC
This series overrides one previous patchset:

https://lore.kernel.org/qemu-devel/20210818194217.110451-1-peterx@redhat.com/

I started from v1 because obviously it's completely different way of doing the
same thing, hence versioning upon it would be weird.

Patches 1-7 are majorly cleanups for current pci code to finally provide a
clean way to loop over all the pci devices on the system.

Patch 8 uses the last helper pci_for_each_device_all() to loop over all the
devices during x86 vIOMMU realize() function to fail early if e.g. vfio-pci
devices are detected.  Although this is not exactly what Igor suggested but it
should be mostly the same approach, so I kept the Suggested-by credit.

Please review, thanks.

Peter Xu (8):
  pci: Define pci_bus_dev_fn type
  pci: Export pci_for_each_device_under_bus*()
  pci: Use pci_for_each_device_under_bus*()
  pci: Define pci_bus_fn/pci_bus_ret_fn type
  pci: Add pci_for_each_root_bus()
  pci: Use pci_for_each_root_bus() in current code
  pci: Add pci_for_each_device_all()
  x86-iommu: Fail early if vIOMMU specified after vfio-pci

 hw/arm/virt-acpi-build.c   | 31 ++++++---------
 hw/i386/acpi-build.c       | 39 +++++--------------
 hw/i386/x86-iommu.c        | 18 +++++++++
 hw/pci/pci.c               | 77 +++++++++++++++++++++++++++++---------
 hw/pci/pcie.c              |  4 +-
 hw/ppc/spapr_pci.c         | 12 +++---
 hw/ppc/spapr_pci_nvlink2.c |  7 ++--
 hw/ppc/spapr_pci_vfio.c    |  4 +-
 hw/s390x/s390-pci-bus.c    |  5 +--
 hw/xen/xen_pt.c            |  4 +-
 include/hw/pci/pci.h       | 28 +++++++++-----
 11 files changed, 132 insertions(+), 97 deletions(-)

Comments

Michael S. Tsirkin Oct. 21, 2021, 10:49 a.m. UTC | #1
On Thu, Oct 21, 2021 at 06:42:59PM +0800, Peter Xu wrote:
> Scan the pci bus to make sure there's no vfio-pci device attached before vIOMMU
> is realized.
> 
> Suggested-by: Igor Mammedov <imammedo@redhat.com>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
>  hw/i386/x86-iommu.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c
> index 86ad03972e..58abce7edc 100644
> --- a/hw/i386/x86-iommu.c
> +++ b/hw/i386/x86-iommu.c
> @@ -21,6 +21,7 @@
>  #include "hw/sysbus.h"
>  #include "hw/i386/x86-iommu.h"
>  #include "hw/qdev-properties.h"
> +#include "hw/vfio/pci.h"
>  #include "hw/i386/pc.h"
>  #include "qapi/error.h"
>  #include "qemu/error-report.h"
> @@ -103,6 +104,16 @@ IommuType x86_iommu_get_type(void)
>      return x86_iommu_default->type;
>  }
>  
> +static void x86_iommu_pci_dev_hook(PCIBus *bus, PCIDevice *dev, void *opaque)
> +{
> +    Error **errp = (Error **)opaque;
> +
> +    if (object_dynamic_cast(OBJECT(dev), TYPE_VFIO_PCI)) {
> +        error_setg(errp, "Device '%s' must be specified before vIOMMUs",
> +                   TYPE_VFIO_PCI);
> +    }
> +}
> +
>  static void x86_iommu_realize(DeviceState *dev, Error **errp)
>  {
>      X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
> @@ -120,6 +131,12 @@ static void x86_iommu_realize(DeviceState *dev, Error **errp)
>          return;
>      }
>  
> +    /* Make sure there's no special device plugged before vIOMMU */
> +    pci_for_each_device_all(x86_iommu_pci_dev_hook, (void *)errp);

cast not needed here.

> +    if (*errp) {
> +        return;
> +    }
> +
>      /* If the user didn't specify IR, choose a default value for it */
>      if (x86_iommu->intr_supported == ON_OFF_AUTO_AUTO) {
>          x86_iommu->intr_supported = irq_all_kernel ?
> @@ -151,6 +168,7 @@ static Property x86_iommu_properties[] = {
>  static void x86_iommu_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> +
>      dc->realize = x86_iommu_realize;
>      device_class_set_props(dc, x86_iommu_properties);
>  }
> -- 
> 2.32.0