Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/vfn/iommu/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
30 changes: 16 additions & 14 deletions src/iommu/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand All @@ -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);
}

Expand All @@ -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;
}
4 changes: 2 additions & 2 deletions src/iommu/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ struct iommu_ctx {

int nranges;
struct iommu_iova_range *iova_ranges;

bool iommufd;
};

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);
31 changes: 29 additions & 2 deletions src/iommu/iommufd.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,26 @@
#include <sys/mman.h>

#include <linux/types.h>
#include <linux/iommufd.h>
#include <linux/vfio.h>

#ifdef HAVE_VFIO_DEVICE_BIND_IOMMUFD
#include <linux/iommufd.h>
#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;
Expand All @@ -65,6 +72,7 @@ struct iommu_ioas {
};

static struct iommu_ioas iommufd_default_ioas = {
.ctx.iommufd = true,
.name = "default",
};

Expand Down Expand Up @@ -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 */
5 changes: 1 addition & 4 deletions src/iommu/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions src/iommu/vfio.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ struct vfio_container {
};

static struct vfio_container vfio_default_container = {
.ctx.iommufd = false,
.fd = -1,
.name = "default",
.nr_groups = 0,
Expand Down
Loading