[libvirt] [RFC PATCH] qemu: Add suport for pci-assign.configfd option

Chris Wright chrisw at redhat.com
Thu May 20 05:34:40 UTC 2010


* Alex Williamson (alex.williamson at redhat.com) wrote:
> @@ -1378,6 +1420,9 @@ int qemudExtractVersionInfo(const char *qemu,
>                            &version, &is_kvm, &kvm_version) == -1)
>          goto cleanup2;
>  
> +    if (flags & QEMUD_CMD_FLAG_DEVICE)
> +        qemudParsePCIDeviceStrs(qemu, &flags);
> +

looks like this is called early enough for both cmdline and monitor
interface

>      if (retversion)
>          *retversion = version;
>      if (retflags)
> @@ -2887,8 +2932,29 @@ error:
>  }
>  
>  
> +int
> +qemudOpenPCIConfig(virDomainHostdevDefPtr dev)
> +{
> +    char *path = NULL;
> +    int configfd = -1;
> +
> +    /* XXX don't hard code segment */

You don't need to, just...

> +    if (virAsprintf(&path, "/sys/bus/pci/devices/0000:%02x:%02x.%01x/config",
                                                   /
s/0000/%04x/ --------------------------------------

> +                    dev->source.subsys.u.pci.bus, dev->source.subsys.u.pci.slot,

and add dev->source.subsys.u.pci.domain 

> +                    dev->source.subsys.u.pci.function) < 0) {
> +        virReportOOMError();
> +        return -1;
> +    }
> +
> +    configfd = open(path, O_RDWR, 0);

Should probably report an open failure to aid debugging.

> +    VIR_FREE(path);
> +
> +    return configfd;
> +}
> +
>  char *
> -qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev)
> +qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, int configfd)
>  {
>      virBuffer buf = VIR_BUFFER_INITIALIZER;
>  
> @@ -2898,6 +2964,8 @@ qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev)
>                        dev->source.subsys.u.pci.slot,
>                        dev->source.subsys.u.pci.function);
>      virBufferVSprintf(&buf, ",id=%s", dev->info.alias);
> +    if (configfd >= 0)
> +        virBufferVSprintf(&buf, ",configfd=%d", configfd);
>      if (qemuBuildDeviceAddressStr(&buf, &dev->info) < 0)
>          goto error;
>  
> @@ -4600,8 +4668,21 @@ int qemudBuildCommandLine(virConnectPtr conn,
>          if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
>              hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
>              if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
> +                int configfd = -1;
> +                if (qemuCmdFlags & QEMUD_CMD_FLAG_PCI_CONFIGFD) {
> +                    configfd = qemudOpenPCIConfig(hostdev);
> +
> +                    if (configfd >= 0) {
> +                        if (VIR_REALLOC_N(*vmfds, (*nvmfds)+1) < 0) {
> +                            close(configfd);
> +                            goto no_memory;
> +                        }
> +
> +                        (*vmfds)[(*nvmfds)++] = configfd;
> +                    }
> +                }
>                  ADD_ARG_LIT("-device");
> -                if (!(devstr = qemuBuildPCIHostdevDevStr(hostdev)))
> +                if (!(devstr = qemuBuildPCIHostdevDevStr(hostdev, configfd)))
>                      goto error;
>                  ADD_ARG(devstr);
>              } else if (qemuCmdFlags & QEMUD_CMD_FLAG_PCIDEVICE) {
> diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
> index a101e47..64fab60 100644
> --- a/src/qemu/qemu_conf.h
> +++ b/src/qemu/qemu_conf.h
> @@ -88,6 +88,7 @@ enum qemud_cmd_flags {
>      QEMUD_CMD_FLAG_NO_HPET       = (1LL << 33), /* -no-hpet flag is supported */
>      QEMUD_CMD_FLAG_NO_KVM_PIT    = (1LL << 34), /* -no-kvm-pit-reinjection supported */
>      QEMUD_CMD_FLAG_TDF           = (1LL << 35), /* -tdf flag (user-mode pit catchup) */
> +    QEMUD_CMD_FLAG_PCI_CONFIGFD  = (1LL << 36), /* pci-assign.configfd */
>  };
>  
>  /* Main driver state */
> @@ -190,6 +191,9 @@ int         qemudParseHelpStr           (const char *qemu,
>                                           unsigned int *is_kvm,
>                                           unsigned int *kvm_version);
>  
> +void        qemudParsePCIDeviceStrs     (const char *qemu,
> +                                         unsigned long long *qemuCmdFlags);
> +
>  int         qemudBuildCommandLine       (virConnectPtr conn,
>                                           struct qemud_driver *driver,
>                                           virDomainDefPtr def,
> @@ -242,7 +246,9 @@ char * qemuBuildSoundDevStr(virDomainSoundDefPtr sound);
>  /* Legacy, pre device support */
>  char * qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev);
>  /* Current, best practice */
> -char * qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev);
> +char * qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, int configfd);
> +
> +int qemudOpenPCIConfig(virDomainHostdevDefPtr dev);
>  
>  /* Current, best practice */
>  char * qemuBuildChrChardevStr(virDomainChrDefPtr dev);
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index dd5bd24..219a973 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -7567,7 +7567,7 @@ static int qemudDomainAttachHostPciDevice(struct qemud_driver *driver,
>          if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &hostdev->info) < 0)
>              goto error;
>  
> -        if (!(devstr = qemuBuildPCIHostdevDevStr(hostdev)))
> +        if (!(devstr = qemuBuildPCIHostdevDevStr(hostdev, -1)))

Looks like this is dynamically assigning host PCI device to running guest,
we should still be able to pass fd here.  That will complicate the qemu
side to be able to accept the fd.

thanks,
-chris




More information about the libvir-list mailing list