#include #include #include #include #include #include #include #include #include #include #define err(x) do { perror(x); exit(1); } while (0) #define die(...) do { fprintf(stderr, __VA_ARGS__); fputc('\n', stderr); exit(1); } while (0) int main() { // Open vfio container int ret; int container = open("/dev/vfio/vfio", O_RDWR); if (container < 0) err("open vfio container"); if (ioctl(container, VFIO_GET_API_VERSION) != VFIO_API_VERSION) die("Unknown VFIO API version! Recompile?"); // Check IOMMU mode support if (!ioctl(container, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_v2_IOMMU)) die("SPAPR iommu mode is not supported"); // Open vfio group 0 int group = open("/dev/vfio/0", O_RDWR); if (group < 0) err("open vfio group"); // Check if group is viable struct vfio_group_status group_status = { .argsz = sizeof(group_status) }; ioctl(group, VFIO_GROUP_GET_STATUS, &group_status); if (!(group_status.flags & VFIO_GROUP_FLAGS_VIABLE)) die("VFIO Group 0 is not viable!"); // Add the group to the container ret = ioctl(group, VFIO_GROUP_SET_CONTAINER, &container); if (ret < 0) err("VFIO_GROUP_SET_CONTAINER"); // Set IOMMU mode ret = ioctl(container, VFIO_SET_IOMMU, VFIO_SPAPR_TCE_v2_IOMMU); if (ret < 0) err("VFIO_SET_IOMMU"); // Get device handle int device = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "0000:00:00.0" /* ivshmem device */); if (device < 0) err("VFIO_GROUP_GET_DEVICE_FD"); // Get device info struct vfio_device_info device_info = { .argsz = sizeof(device_info) }; ret = ioctl(device, VFIO_DEVICE_GET_INFO, &device_info); if (ret < 0) err("VFIO_DEVICE_GET_INFO"); }