On Tue, 17 Dec 2019 16:06:44 -0300
Daniel Henrique Barboza <danielhb...@gmail.com> wrote:

> Today, to use a PCI hostdev "A" in a domain, all PCI devices
> that belongs to the same IOMMU group must also be declared in
> the domain XML, meaning that all IOMMU devices are detached
> from the host and all of them are visible to the guest.

This is not accurate.  All endpoint devices in the IOMMU group need to
be "viable" (ie. bound to vfio-pci, pci-stub, unbound) for any device
within the group to be used through vfio.  There is absolutely no
requirement that they all be declared in the XML or assigned to the
guest.  Also please clarify "IOMMU devices".  Is that all devices
within the IOMMU group?
 
> The result is that the guest will have access to all devices,
> but this is not necessarily what the administrator wanted. If only
> the hostdev "A" was intended for guest usage, but hostdevs "B" and
> "C" happened to be in the same IOMMU group of "A", the guest will
> gain access to all 3 devices. This makes the administrator rely
> on alternative solutions, such as use all hostdevs with un-managed
> mode and detached all the IOMMU before the guest starts. If
> use un-managed mode is not an option, the only alternative left is
> an ACS patch to deny guest access to "B" and "C".

Also not accurate.  The libvirt hooks interface can be used to manage
the additional devices ad-hoc, the additional devices might not need
management if they're not endpoints, they might be statically bound to
vfio-pci at boot time, etc.  I don't think the scenario is nearly as
dire as presented here.  "detached all the IOMMU" doesn't make sense.

> This patch introduces a new address type called "unassigned" to
> handle this situation where a hostdev will be owned by a domain, but
> not visible to the guest OS. This allows the administrator to
> declare all the IOMMU while also choosing which hostdevs will be

"declare all the IOMMU" doesn't make sense.

> usable by the guest. This new mechanic applies to all PCI hostdevs,
> regardless of whether they are a PCI multifunction hostdev or not.
> Using <address type='unassigned'/> in any case other than a PCI
> hostdev will result in error.

Regardless of my comments above, I think this support is worthwhile,
but let's not pretend there aren't solutions, this just makes it easier
to accomplish in a supported and dynamic way.  Thanks,

Alex

> Next patch will use this new address type in the QEMU driver to
> avoid adding unassigned devices to the QEMU launch command line.
> 
> Signed-off-by: Daniel Henrique Barboza <danielhb...@gmail.com>
> ---
>  docs/schemas/domaincommon.rng                 |  5 ++
>  src/conf/device_conf.c                        |  2 +
>  src/conf/device_conf.h                        |  1 +
>  src/conf/domain_conf.c                        |  7 ++-
>  src/qemu/qemu_command.c                       |  1 +
>  src/qemu/qemu_domain.c                        |  1 +
>  src/qemu/qemu_domain_address.c                |  5 ++
>  .../hostdev-pci-address-unassigned.xml        | 42 ++++++++++++++
>  .../hostdev-pci-address-unassigned.xml        | 58 +++++++++++++++++++
>  tests/qemuxml2xmltest.c                       |  1 +
>  10 files changed, 122 insertions(+), 1 deletion(-)
>  create mode 100644 tests/qemuxml2argvdata/hostdev-pci-address-unassigned.xml
>  create mode 100644 
> tests/qemuxml2xmloutdata/hostdev-pci-address-unassigned.xml
> 
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index e964773f5e..5f1d4a34a4 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -5502,6 +5502,11 @@
>            </attribute>
>            <ref name="dimmaddress"/>
>          </group>
> +        <group>
> +          <attribute name="type">
> +            <value>unassigned</value>
> +          </attribute>
> +        </group>
>        </choice>
>      </element>
>    </define>
> diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
> index 4c57f0995f..4dbd5c1ac9 100644
> --- a/src/conf/device_conf.c
> +++ b/src/conf/device_conf.c
> @@ -45,6 +45,7 @@ VIR_ENUM_IMPL(virDomainDeviceAddress,
>                "virtio-mmio",
>                "isa",
>                "dimm",
> +              "unassigned",
>  );
>  
>  static int
> @@ -120,6 +121,7 @@ virDomainDeviceInfoAddressIsEqual(const 
> virDomainDeviceInfo *a,
>      /* address types below don't have any specific data */
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390:
> +    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED:
>          break;
>  
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI:
> diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
> index d98fae775c..e091d7cfe2 100644
> --- a/src/conf/device_conf.h
> +++ b/src/conf/device_conf.h
> @@ -45,6 +45,7 @@ typedef enum {
>      VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO,
>      VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA,
>      VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM,
> +    VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED,
>  
>      VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
>  } virDomainDeviceAddressType;
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index e46f423b19..afa072e17d 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -6352,9 +6352,11 @@ virDomainHostdevDefValidate(const virDomainHostdevDef 
> *hostdev)
>          switch ((virDomainHostdevSubsysType) hostdev->source.subsys.type) {
>          case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
>              if (hostdev->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
> +                hostdev->info->type != 
> VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED &&
>                  hostdev->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
>                  virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> -                               _("PCI host devices must use 'pci' address 
> type"));
> +                               _("PCI host devices must use 'pci' or "
> +                                 "'unassigned' address type"));
>                  return -1;
>              }
>              break;
> @@ -7371,6 +7373,7 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
>  
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390:
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE:
> +    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED:
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST:
>          break;
>      }
> @@ -7571,6 +7574,7 @@ virDomainDeviceAddressParseXML(xmlNodePtr address,
>          break;
>  
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE:
> +    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED:
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST:
>          break;
>      }
> @@ -21951,6 +21955,7 @@ 
> virDomainDeviceInfoCheckABIStability(virDomainDeviceInfoPtr src,
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW:
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE:
> +    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED:
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST:
>          break;
>      }
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 836057a4ff..864967f375 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -459,6 +459,7 @@ qemuBuildVirtioDevStr(virBufferPtr buf,
>          return -1;
>  
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE:
> +    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED:
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST:
>      default:
>          virReportEnumRangeError(virDomainDeviceAddressType, info->type);
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 20a9629760..cce99f831f 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -8242,6 +8242,7 @@ qemuDomainDeviceDefValidateAddress(const 
> virDomainDeviceDef *dev,
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA:
>      case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM:
> +    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED:
>          /* No validation for these address types yet */
>          break;
>  
> diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
> index 605984f80f..b077240899 100644
> --- a/src/qemu/qemu_domain_address.c
> +++ b/src/qemu/qemu_domain_address.c
> @@ -2313,6 +2313,11 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def,
>              continue;
>          }
>  
> +        /* do not reserve address for info->type='unassigned' */
> +        if (def->hostdevs[i]->info->type ==
> +            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED)
> +            continue;
> +
>          if (qemuDomainPCIAddressReserveNextAddr(addrs,
>                                                  def->hostdevs[i]->info) < 0)
>              goto error;
> diff --git a/tests/qemuxml2argvdata/hostdev-pci-address-unassigned.xml 
> b/tests/qemuxml2argvdata/hostdev-pci-address-unassigned.xml
> new file mode 100644
> index 0000000000..9a2685ca0e
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/hostdev-pci-address-unassigned.xml
> @@ -0,0 +1,42 @@
> +<domain type='kvm'>
> +  <name>delete</name>
> +  <uuid>583a8e8e-f0ce-4f53-89ab-092862148b25</uuid>
> +  <memory unit='KiB'>262144</memory>
> +  <vcpu placement='static'>4</vcpu>
> +  <os>
> +    <type arch='x86_64' machine='pc'>hvm</type>
> +  </os>
> +  <devices>
> +    <emulator>/usr/bin/qemu-system-x86_64</emulator>
> +    <controller type='usb' index='0'/>
> +    <controller type='ide' index='0'/>
> +    <controller type='pci' index='0' model='pci-root'/>
> +    <input type='mouse' bus='ps2'/>
> +    <input type='keyboard' bus='ps2'/>
> +    <hostdev mode='subsystem' type='pci' managed='yes'>
> +      <driver name='vfio'/>
> +      <source>
> +        <address domain='0x0005' bus='0x90' slot='0x01' function='0x0'/>
> +      </source>
> +    </hostdev>
> +     <hostdev mode='subsystem' type='pci' managed='yes'>
> +      <driver name='vfio'/>
> +      <source>
> +        <address domain='0x0005' bus='0x90' slot='0x01' function='0x1'/>
> +      </source>
> +      <address type='unassigned'/>
> +    </hostdev>
> +   <hostdev mode='subsystem' type='pci' managed='yes'>
> +      <driver name='vfio'/>
> +      <source>
> +        <address domain='0x0005' bus='0x90' slot='0x01' function='0x2'/>
> +      </source>
> +    </hostdev>
> +    <hostdev mode='subsystem' type='pci' managed='yes'>
> +      <driver name='vfio'/>
> +      <source>
> +        <address domain='0x0005' bus='0x90' slot='0x01' function='0x3'/>
> +      </source>
> +    </hostdev>
> +  </devices>
> +</domain>
> diff --git a/tests/qemuxml2xmloutdata/hostdev-pci-address-unassigned.xml 
> b/tests/qemuxml2xmloutdata/hostdev-pci-address-unassigned.xml
> new file mode 100644
> index 0000000000..2341e8432b
> --- /dev/null
> +++ b/tests/qemuxml2xmloutdata/hostdev-pci-address-unassigned.xml
> @@ -0,0 +1,58 @@
> +<domain type='kvm'>
> +  <name>delete</name>
> +  <uuid>583a8e8e-f0ce-4f53-89ab-092862148b25</uuid>
> +  <memory unit='KiB'>262144</memory>
> +  <currentMemory unit='KiB'>262144</currentMemory>
> +  <vcpu placement='static'>4</vcpu>
> +  <os>
> +    <type arch='x86_64' machine='pc'>hvm</type>
> +    <boot dev='hd'/>
> +  </os>
> +  <clock offset='utc'/>
> +  <on_poweroff>destroy</on_poweroff>
> +  <on_reboot>restart</on_reboot>
> +  <on_crash>destroy</on_crash>
> +  <devices>
> +    <emulator>/usr/bin/qemu-system-x86_64</emulator>
> +    <controller type='usb' index='0'>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' 
> function='0x2'/>
> +    </controller>
> +    <controller type='ide' index='0'>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' 
> function='0x1'/>
> +    </controller>
> +    <controller type='pci' index='0' model='pci-root'/>
> +    <input type='mouse' bus='ps2'/>
> +    <input type='keyboard' bus='ps2'/>
> +    <hostdev mode='subsystem' type='pci' managed='yes'>
> +      <driver name='vfio'/>
> +      <source>
> +        <address domain='0x0005' bus='0x90' slot='0x01' function='0x0'/>
> +      </source>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' 
> function='0x0'/>
> +    </hostdev>
> +    <hostdev mode='subsystem' type='pci' managed='yes'>
> +      <driver name='vfio'/>
> +      <source>
> +        <address domain='0x0005' bus='0x90' slot='0x01' function='0x1'/>
> +      </source>
> +      <address type='unassigned'/>
> +    </hostdev>
> +    <hostdev mode='subsystem' type='pci' managed='yes'>
> +      <driver name='vfio'/>
> +      <source>
> +        <address domain='0x0005' bus='0x90' slot='0x01' function='0x2'/>
> +      </source>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' 
> function='0x0'/>
> +    </hostdev>
> +    <hostdev mode='subsystem' type='pci' managed='yes'>
> +      <driver name='vfio'/>
> +      <source>
> +        <address domain='0x0005' bus='0x90' slot='0x01' function='0x3'/>
> +      </source>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' 
> function='0x0'/>
> +    </hostdev>
> +    <memballoon model='virtio'>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' 
> function='0x0'/>
> +    </memballoon>
> +  </devices>
> +</domain>
> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
> index 55bbd924fb..d0a91df2ad 100644
> --- a/tests/qemuxml2xmltest.c
> +++ b/tests/qemuxml2xmltest.c
> @@ -491,6 +491,7 @@ mymain(void)
>  
>      DO_TEST("hostdev-usb-address", NONE);
>      DO_TEST("hostdev-pci-address", NONE);
> +    DO_TEST("hostdev-pci-address-unassigned", QEMU_CAPS_DEVICE_VFIO_PCI);
>      DO_TEST("hostdev-pci-multifunction", QEMU_CAPS_DEVICE_VFIO_PCI);
>      DO_TEST("hostdev-vfio", QEMU_CAPS_DEVICE_VFIO_PCI);
>      DO_TEST("hostdev-vfio-zpci",

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to