Re: [libvirt] [PATCHv4 2/3] qemu: hostdev: Add checks if PCI passthrough is availabe in the host

2013-10-10 Thread Peter Krempa
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

2013-10-09 Thread Christophe Fergeau
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

2013-10-09 Thread Laine Stump
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

2013-10-08 Thread Peter Krempa
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