diff --git a/include/vfn/iommu/context.h b/include/vfn/iommu/context.h index 8656252c..5a396b2b 100644 --- a/include/vfn/iommu/context.h +++ b/include/vfn/iommu/context.h @@ -23,4 +23,12 @@ */ struct iommu_ctx *iommu_get_context(const char *name); +/** + * iommu_ctx_is_iommufd - Check whether the given @ctx is binded to iommufd + * @ctx: &struct iommu_ctx + * + * Return: ``true`` if @ctx is binded to iommufd, otherwise ``false``. + */ +bool iommu_ctx_is_iommufd(struct iommu_ctx *ctx); + #endif /* LIBVFN_IOMMU_CONTEXT_H */ diff --git a/src/iommu/context.c b/src/iommu/context.c index da852f8a..5eb68a55 100644 --- a/src/iommu/context.c +++ b/src/iommu/context.c @@ -26,24 +26,21 @@ #define IOVA_MIN 0x10000 #define IOVA_MAX_39BITS (1ULL << 39) -#ifdef HAVE_VFIO_DEVICE_BIND_IOMMUFD -static inline bool __iommufd_is_broken(void) +static inline bool __iommufd_is_available(void) { struct stat sb; - if (stat("/dev/vfio/devices", &sb) || !S_ISDIR(sb.st_mode)) { - log_info("iommufd broken; probably missing CONFIG_VFIO_DEVICE_CDEV=y\n"); + if (stat("/dev/vfio/devices", &sb) || !S_ISDIR(sb.st_mode)) + return false; + if (stat("/dev/iommu", &sb)) + return false; - return true; - } - return false; + return true; } -#endif struct iommu_ctx *iommu_get_default_context(void) { -#ifdef HAVE_VFIO_DEVICE_BIND_IOMMUFD - if (__iommufd_is_broken()) + if (!__iommufd_is_available()) goto fallback; if (getenv("VFN_IOMMU_FORCE_VFIO")) @@ -52,20 +49,20 @@ struct iommu_ctx *iommu_get_default_context(void) return iommufd_get_default_iommu_context(); fallback: -#endif return vfio_get_default_iommu_context(); } struct iommu_ctx *iommu_get_context(const char *name) { -#ifdef HAVE_VFIO_DEVICE_BIND_IOMMUFD - if (__iommufd_is_broken()) + if (!__iommufd_is_available()) + goto fallback; + + if (getenv("VFN_IOMMU_FORCE_VFIO")) goto fallback; return iommufd_get_iommu_context(name); fallback: -#endif return vfio_get_iommu_context(name); } @@ -84,3 +81,8 @@ void iommu_ctx_init(struct iommu_ctx *ctx) skiplist_init(&ctx->map.list); pthread_rwlock_init(&ctx->map.lock, NULL); } + +bool iommu_ctx_is_iommufd(struct iommu_ctx *ctx) +{ + return ctx->iommufd; +} diff --git a/src/iommu/context.h b/src/iommu/context.h index a3b56c71..0b2f9d90 100644 --- a/src/iommu/context.h +++ b/src/iommu/context.h @@ -50,6 +50,8 @@ struct iommu_ctx { int nranges; struct iommu_iova_range *iova_ranges; + + bool iommufd; }; struct iommu_ctx *iommu_get_default_context(void); @@ -57,10 +59,8 @@ struct iommu_ctx *iommu_get_default_context(void); struct iommu_ctx *vfio_get_default_iommu_context(void); struct iommu_ctx *vfio_get_iommu_context(const char *name); -#ifdef HAVE_VFIO_DEVICE_BIND_IOMMUFD struct iommu_ctx *iommufd_get_default_iommu_context(void); struct iommu_ctx *iommufd_get_iommu_context(const char *name); -#endif void iommu_ctx_init(struct iommu_ctx *ctx); int iommu_iova_range_to_string(struct iommu_iova_range *range, char **str); diff --git a/src/iommu/iommufd.c b/src/iommu/iommufd.c index 37fda2ee..836aa2ac 100644 --- a/src/iommu/iommufd.c +++ b/src/iommu/iommufd.c @@ -28,19 +28,26 @@ #include #include -#include #include +#ifdef HAVE_VFIO_DEVICE_BIND_IOMMUFD +#include +#endif + #include "vfn/trace.h" #include "vfn/support.h" #include "vfn/pci.h" #include "vfn/iommu.h" + +#include "context.h" + +#ifdef HAVE_VFIO_DEVICE_BIND_IOMMUFD + #include "vfn/iommu/iommufd.h" #include "ccan/list/list.h" #include "ccan/compiler/compiler.h" -#include "context.h" #include "trace.h" static int __iommufd = -1; @@ -65,6 +72,7 @@ struct iommu_ioas { }; static struct iommu_ioas iommufd_default_ioas = { + .ctx.iommufd = true, .name = "default", }; @@ -419,3 +427,22 @@ struct iommu_ctx *iommufd_get_default_iommu_context(void) return &iommufd_default_ioas.ctx; } + +#else /* !HAVE_VFIO_DEVICE_BIND_IOMMUFD */ + +struct iommu_ctx *iommufd_get_iommu_context(const char *name) +{ + (void)name; + log_debug("iommufd support not compiled in (missing kernel headers)\n"); + errno = ENOTSUP; + return NULL; +} + +struct iommu_ctx *iommufd_get_default_iommu_context(void) +{ + log_debug("iommufd support not compiled in (missing kernel headers)\n"); + errno = ENOTSUP; + return NULL; +} + +#endif /* HAVE_VFIO_DEVICE_BIND_IOMMUFD */ diff --git a/src/iommu/meson.build b/src/iommu/meson.build index b79965e6..0c4e62f4 100644 --- a/src/iommu/meson.build +++ b/src/iommu/meson.build @@ -3,10 +3,7 @@ iommu_sources = files( 'dma.c', 'dmabuf.c', 'vfio.c', + 'iommufd.c', ) -if config_host.get('HAVE_VFIO_DEVICE_BIND_IOMMUFD', false) - iommu_sources += files('iommufd.c',) -endif - vfn_sources += iommu_sources diff --git a/src/iommu/vfio.c b/src/iommu/vfio.c index 212fcd3f..9c99ce44 100644 --- a/src/iommu/vfio.c +++ b/src/iommu/vfio.c @@ -78,6 +78,7 @@ struct vfio_container { }; static struct vfio_container vfio_default_container = { + .ctx.iommufd = false, .fd = -1, .name = "default", .nr_groups = 0,