Re: [libvirt] [PATCHv4 2/3] qemu: hostdev: Add checks if PCI passthrough is availabe in the host
On 10/09/13 15:02, Christophe Fergeau wrote: > If it's not pushed already, there's a typo in the subject: 'availabe' Thanks for noticing. Pushed with fixed subject. > > Christophe > > On Tue, Oct 08, 2013 at 05:46:57PM +0200, Peter Krempa wrote: >> Add code to check availability of PCI passhthrough using VFIO and the >> legacy KVM passthrough and use it when starting VMs and hotplugging >> devices to live machine. >> --- >> >> Notes: >> Version 4: >> - moved this function so that it can be called from >> qemuPrepareHostdevPCIDevices() >> - now caching the support for passthrough types right away >> >> src/qemu/qemu_hostdev.c | 125 >> >> 1 file changed, 125 insertions(+) >> Peter signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv4 2/3] qemu: hostdev: Add checks if PCI passthrough is availabe in the host
If it's not pushed already, there's a typo in the subject: 'availabe' Christophe On Tue, Oct 08, 2013 at 05:46:57PM +0200, Peter Krempa wrote: > Add code to check availability of PCI passhthrough using VFIO and the > legacy KVM passthrough and use it when starting VMs and hotplugging > devices to live machine. > --- > > Notes: > Version 4: > - moved this function so that it can be called from > qemuPrepareHostdevPCIDevices() > - now caching the support for passthrough types right away > > src/qemu/qemu_hostdev.c | 125 > > 1 file changed, 125 insertions(+) > > diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c > index 4127abd..7f3170d 100644 > --- a/src/qemu/qemu_hostdev.c > +++ b/src/qemu/qemu_hostdev.c > @@ -23,6 +23,11 @@ > > #include > > +#include > +#include > +#include > +#include > + > #include "qemu_hostdev.h" > #include "virlog.h" > #include "virerror.h" > @@ -31,6 +36,7 @@ > #include "virusb.h" > #include "virscsi.h" > #include "virnetdev.h" > +#include "virfile.h" > > #define VIR_FROM_THIS VIR_FROM_QEMU > > @@ -486,6 +492,122 @@ > qemuDomainHostdevNetConfigRestore(virDomainHostdevDefPtr hostdev, > } > > > +static bool > +qemuHostdevHostSupportsPassthroughVFIO(void) > +{ > +DIR *iommuDir = NULL; > +struct dirent *iommuGroup = NULL; > +bool ret = false; > + > +/* condition 1 - /sys/kernel/iommu_groups/ contains entries */ > +if (!(iommuDir = opendir("/sys/kernel/iommu_groups/"))) > +goto cleanup; > + > +while ((iommuGroup = readdir(iommuDir))) { > +/* skip ./ ../ */ > +if (STRPREFIX(iommuGroup->d_name, ".")) > +continue; > + > +/* assume we found a group */ > +break; > +} > + > +if (!iommuGroup) > +goto cleanup; > +/* okay, iommu is on and recognizes groups */ > + > +/* condition 2 - /dev/vfio/vfio exists */ > +if (!virFileExists("/dev/vfio/vfio")) > +goto cleanup; > + > +ret = true; > + > +cleanup: > +if (iommuDir) > +closedir(iommuDir); > + > +return ret; > +} > + > + > +#if HAVE_LINUX_KVM_H > +# include > +static bool > +qemuHostdevHostSupportsPassthroughLegacy(void) > +{ > +int kvmfd = -1; > +bool ret = false; > + > +if ((kvmfd = open("/dev/kvm", O_RDONLY)) < 0) > +goto cleanup; > + > +# ifdef KVM_CAP_IOMMU > +if ((ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_IOMMU)) <= 0) > +goto cleanup; > + > +ret = true; > +# endif > + > +cleanup: > +VIR_FORCE_CLOSE(kvmfd); > + > +return ret; > +} > +#else > +static bool > +qemuHostdevHostSupportsPassthroughLegacy(void) > +{ > +return false; > +} > +#endif > + > + > +static bool > +qemuPrepareHostdevPCICheckSupport(virDomainHostdevDefPtr *hostdevs, > + size_t nhostdevs) > +{ > +bool supportsPassthroughKVM = qemuHostdevHostSupportsPassthroughLegacy(); > +bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO(); > +size_t i; > + > +/* assign defaults for hostdev passthrough */ > +for (i = 0; i < nhostdevs; i++) { > +virDomainHostdevDefPtr hostdev = hostdevs[i]; > +int *backend = &hostdev->source.subsys.u.pci.backend; > + > +if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) > +continue; > +if (hostdev->source.subsys.type != > VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) > +continue; > + > +switch ((virDomainHostdevSubsysPciBackendType) *backend) { > +case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO: > +if (!supportsPassthroughVFIO) { > +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("host doesn't support VFIO PCI > passthrough")); > +return false; > +} > +break; > + > +case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT: > +case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM: > +if (!supportsPassthroughKVM) { > +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("host doesn't support legacy PCI > passthrough")); > +return false; > +} > + > +break; > + > +case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST: > +break; > +} > +} > + > +return true; > +} > + > + > int > qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver, > const char *name, > @@ -499,6 +621,9 @@ qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver, > int ret = -1; > virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); > > +if (!qemuPrepareHostdevPCICheckSupport(hostdevs, nhostdevs)) > +goto cleanup; > + > virObjectLock(driver->activePciHostdevs); > virObjectLock(driver->inactivePciHostdevs); > > -- > 1.8.3.2 > > -- > libvir-list mailing list > libvir-list@redhat.com > https://www.redhat.co
Re: [libvirt] [PATCHv4 2/3] qemu: hostdev: Add checks if PCI passthrough is availabe in the host
On 10/08/2013 06:46 PM, Peter Krempa wrote: > Add code to check availability of PCI passhthrough using VFIO and the > legacy KVM passthrough and use it when starting VMs and hotplugging > devices to live machine. > --- > > Notes: > Version 4: > - moved this function so that it can be called from > qemuPrepareHostdevPCIDevices() > - now caching the support for passthrough types right away > > src/qemu/qemu_hostdev.c | 125 > > 1 file changed, 125 insertions(+) > > diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c > index 4127abd..7f3170d 100644 > --- a/src/qemu/qemu_hostdev.c > +++ b/src/qemu/qemu_hostdev.c > @@ -23,6 +23,11 @@ > > #include > > +#include > +#include > +#include > +#include > + > #include "qemu_hostdev.h" > #include "virlog.h" > #include "virerror.h" > @@ -31,6 +36,7 @@ > #include "virusb.h" > #include "virscsi.h" > #include "virnetdev.h" > +#include "virfile.h" > > #define VIR_FROM_THIS VIR_FROM_QEMU > > @@ -486,6 +492,122 @@ > qemuDomainHostdevNetConfigRestore(virDomainHostdevDefPtr hostdev, > } > > > +static bool > +qemuHostdevHostSupportsPassthroughVFIO(void) > +{ > +DIR *iommuDir = NULL; > +struct dirent *iommuGroup = NULL; > +bool ret = false; > + > +/* condition 1 - /sys/kernel/iommu_groups/ contains entries */ > +if (!(iommuDir = opendir("/sys/kernel/iommu_groups/"))) > +goto cleanup; > + > +while ((iommuGroup = readdir(iommuDir))) { > +/* skip ./ ../ */ > +if (STRPREFIX(iommuGroup->d_name, ".")) > +continue; > + > +/* assume we found a group */ > +break; > +} > + > +if (!iommuGroup) > +goto cleanup; > +/* okay, iommu is on and recognizes groups */ > + > +/* condition 2 - /dev/vfio/vfio exists */ > +if (!virFileExists("/dev/vfio/vfio")) > +goto cleanup; > + > +ret = true; > + > +cleanup: > +if (iommuDir) > +closedir(iommuDir); > + > +return ret; > +} > + > + > +#if HAVE_LINUX_KVM_H > +# include > +static bool > +qemuHostdevHostSupportsPassthroughLegacy(void) > +{ > +int kvmfd = -1; > +bool ret = false; > + > +if ((kvmfd = open("/dev/kvm", O_RDONLY)) < 0) > +goto cleanup; > + > +# ifdef KVM_CAP_IOMMU > +if ((ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_IOMMU)) <= 0) > +goto cleanup; > + > +ret = true; > +# endif > + > +cleanup: > +VIR_FORCE_CLOSE(kvmfd); > + > +return ret; > +} > +#else > +static bool > +qemuHostdevHostSupportsPassthroughLegacy(void) > +{ > +return false; > +} > +#endif > + > + > +static bool > +qemuPrepareHostdevPCICheckSupport(virDomainHostdevDefPtr *hostdevs, > + size_t nhostdevs) > +{ > +bool supportsPassthroughKVM = qemuHostdevHostSupportsPassthroughLegacy(); > +bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO(); I just double checked, and these two calls won't ever be done unnecessarily, because qemuPrepareHostdevPCIDevices() is never called unless there will be at least one hostdev added. > +size_t i; > + > +/* assign defaults for hostdev passthrough */ > +for (i = 0; i < nhostdevs; i++) { > +virDomainHostdevDefPtr hostdev = hostdevs[i]; > +int *backend = &hostdev->source.subsys.u.pci.backend; > + > +if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) > +continue; > +if (hostdev->source.subsys.type != > VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) > +continue; > + > +switch ((virDomainHostdevSubsysPciBackendType) *backend) { > +case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO: > +if (!supportsPassthroughVFIO) { > +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("host doesn't support VFIO PCI > passthrough")); > +return false; > +} > +break; > + > +case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT: > +case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM: > +if (!supportsPassthroughKVM) { > +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("host doesn't support legacy PCI > passthrough")); > +return false; > +} > + > +break; > + > +case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST: > +break; > +} > +} > + > +return true; > +} > + > + > int > qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver, > const char *name, > @@ -499,6 +621,9 @@ qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver, > int ret = -1; > virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); > > +if (!qemuPrepareHostdevPCICheckSupport(hostdevs, nhostdevs)) > +goto cleanup; > + > virObjectLock(driver->activePciHostdevs); > virObjectLock(driver->inactivePciHostdevs); > ACK. -- libvir-list mail
[libvirt] [PATCHv4 2/3] qemu: hostdev: Add checks if PCI passthrough is availabe in the host
Add code to check availability of PCI passhthrough using VFIO and the legacy KVM passthrough and use it when starting VMs and hotplugging devices to live machine. --- Notes: Version 4: - moved this function so that it can be called from qemuPrepareHostdevPCIDevices() - now caching the support for passthrough types right away src/qemu/qemu_hostdev.c | 125 1 file changed, 125 insertions(+) diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c index 4127abd..7f3170d 100644 --- a/src/qemu/qemu_hostdev.c +++ b/src/qemu/qemu_hostdev.c @@ -23,6 +23,11 @@ #include +#include +#include +#include +#include + #include "qemu_hostdev.h" #include "virlog.h" #include "virerror.h" @@ -31,6 +36,7 @@ #include "virusb.h" #include "virscsi.h" #include "virnetdev.h" +#include "virfile.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -486,6 +492,122 @@ qemuDomainHostdevNetConfigRestore(virDomainHostdevDefPtr hostdev, } +static bool +qemuHostdevHostSupportsPassthroughVFIO(void) +{ +DIR *iommuDir = NULL; +struct dirent *iommuGroup = NULL; +bool ret = false; + +/* condition 1 - /sys/kernel/iommu_groups/ contains entries */ +if (!(iommuDir = opendir("/sys/kernel/iommu_groups/"))) +goto cleanup; + +while ((iommuGroup = readdir(iommuDir))) { +/* skip ./ ../ */ +if (STRPREFIX(iommuGroup->d_name, ".")) +continue; + +/* assume we found a group */ +break; +} + +if (!iommuGroup) +goto cleanup; +/* okay, iommu is on and recognizes groups */ + +/* condition 2 - /dev/vfio/vfio exists */ +if (!virFileExists("/dev/vfio/vfio")) +goto cleanup; + +ret = true; + +cleanup: +if (iommuDir) +closedir(iommuDir); + +return ret; +} + + +#if HAVE_LINUX_KVM_H +# include +static bool +qemuHostdevHostSupportsPassthroughLegacy(void) +{ +int kvmfd = -1; +bool ret = false; + +if ((kvmfd = open("/dev/kvm", O_RDONLY)) < 0) +goto cleanup; + +# ifdef KVM_CAP_IOMMU +if ((ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_IOMMU)) <= 0) +goto cleanup; + +ret = true; +# endif + +cleanup: +VIR_FORCE_CLOSE(kvmfd); + +return ret; +} +#else +static bool +qemuHostdevHostSupportsPassthroughLegacy(void) +{ +return false; +} +#endif + + +static bool +qemuPrepareHostdevPCICheckSupport(virDomainHostdevDefPtr *hostdevs, + size_t nhostdevs) +{ +bool supportsPassthroughKVM = qemuHostdevHostSupportsPassthroughLegacy(); +bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO(); +size_t i; + +/* assign defaults for hostdev passthrough */ +for (i = 0; i < nhostdevs; i++) { +virDomainHostdevDefPtr hostdev = hostdevs[i]; +int *backend = &hostdev->source.subsys.u.pci.backend; + +if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) +continue; +if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) +continue; + +switch ((virDomainHostdevSubsysPciBackendType) *backend) { +case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO: +if (!supportsPassthroughVFIO) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("host doesn't support VFIO PCI passthrough")); +return false; +} +break; + +case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT: +case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM: +if (!supportsPassthroughKVM) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("host doesn't support legacy PCI passthrough")); +return false; +} + +break; + +case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST: +break; +} +} + +return true; +} + + int qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver, const char *name, @@ -499,6 +621,9 @@ qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver, int ret = -1; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); +if (!qemuPrepareHostdevPCICheckSupport(hostdevs, nhostdevs)) +goto cleanup; + virObjectLock(driver->activePciHostdevs); virObjectLock(driver->inactivePciHostdevs); -- 1.8.3.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list