diff --git a/common/include/villas/kernel/vfio.hpp b/common/include/villas/kernel/vfio.hpp index 6e4e2a828..f73c9136b 100644 --- a/common/include/villas/kernel/vfio.hpp +++ b/common/include/villas/kernel/vfio.hpp @@ -25,22 +25,29 @@ #define VFIO_NOIOMMU_IOMMU 8 #endif -/* Forward declarations */ -struct pci_device; - namespace villas { +namespace kernel { -class VfioContainer; -class VfioGroup; +namespace pci { +/* Forward declarations */ +struct Device; -class VfioDevice { - friend class VfioContainer; +} + +namespace vfio { + +/* Forward declarations */ +class Container; +class Group; + +class Device { + friend class Container; public: - VfioDevice(const std::string& name, VfioGroup& group) : + Device(const std::string &name, Group &group) : name(name), group(group) {} - ~VfioDevice(); + ~Device(); bool reset(); @@ -79,23 +86,23 @@ private: std::vector mappings; /**< libpci handle of the device */ - const struct pci_device *pci_device; + const kernel::pci::Device *pci_device; - VfioGroup& group; /**< The VFIO group this device belongs to */ + Group &group; /**< The VFIO group this device belongs to */ }; -class VfioGroup { - friend class VfioContainer; - friend VfioDevice; +class Group { + friend class Container; + friend Device; private: - VfioGroup(int index) : fd(-1), index(index) {} + Group(int index) : fd(-1), index(index) {} public: - ~VfioGroup(); + ~Group(); - static std::unique_ptr - attach(VfioContainer& container, int groupIndex); + static std::unique_ptr + attach(Container &container, int groupIndex); private: /// VFIO group file descriptor @@ -108,25 +115,25 @@ private: struct vfio_group_status status; /// All devices owned by this group - std::list> devices; + std::list> devices; - VfioContainer* container; /**< The VFIO container to which this group is belonging */ + Container* container; /**< The VFIO container to which this group is belonging */ }; -class VfioContainer { +class Container { private: - VfioContainer(); + Container(); public: - ~VfioContainer(); + ~Container(); - static std::shared_ptr + static std::shared_ptr create(); void dump(); - VfioDevice& attachDevice(const char *name, int groupIndex); - VfioDevice& attachDevice(const struct pci_device *pdev); + Device & attachDevice(const char *name, int groupIndex); + Device & attachDevice(const pci::Device &pdev); /** * @brief Map VM to an IOVA, which is accessible by devices in the container @@ -143,11 +150,11 @@ public: bool isIommuEnabled() const { return this->hasIommu; } - const int& getFd() const + const int &getFd() const { return fd; } private: - VfioGroup& getOrAttachGroup(int index); + Group & getOrAttachGroup(int index); private: int fd; @@ -157,9 +164,11 @@ private: bool hasIommu; /// All groups bound to this container - std::list> groups; + std::list> groups; }; /** @} */ +} /* namespace vfio */ +} /* namespace kernel */ } /* namespace villas */ diff --git a/common/lib/kernel/vfio.cpp b/common/lib/kernel/vfio.cpp index 10392d669..d3a9a0446 100644 --- a/common/lib/kernel/vfio.cpp +++ b/common/lib/kernel/vfio.cpp @@ -44,12 +44,13 @@ #include #include +#include #include #include #include #include -using namespace villas; +using namespace villas::kernel::vfio; static const char *vfio_pci_region_names[] = { "PCI_BAR0", /* VFIO_PCI_BAR0_REGION_INDEX */ @@ -74,7 +75,7 @@ static const char *vfio_pci_irq_names[] = { namespace villas { -VfioContainer::VfioContainer() +Container::Container() : iova_next(0) { @@ -136,7 +137,7 @@ VfioContainer::VfioContainer() } -VfioContainer::~VfioContainer() +Container::~Container() { Logger logger = logging.get("kernel:vfio"); @@ -153,16 +154,16 @@ VfioContainer::~VfioContainer() } -std::shared_ptr -VfioContainer::create() +std::shared_ptr +Container::create() { - std::shared_ptr container { new VfioContainer }; + std::shared_ptr container { new Container }; return container; } void -VfioContainer::dump() +Container::dump() { Logger logger = logging.get("kernel:vfio"); @@ -170,14 +171,14 @@ VfioContainer::dump() logger->info("Version: {}", version); logger->info("Extensions: 0x{:x}", extensions); - for (auto& group : groups) { + for (auto &group : groups) { logger->info("VFIO Group {}, viable={}, container={}", group->index, (group->status.flags & VFIO_GROUP_FLAGS_VIABLE) > 0, (group->status.flags & VFIO_GROUP_FLAGS_CONTAINER_SET) > 0 ); - for (auto& device : group->devices) { + for (auto &device : group->devices) { logger->info("Device {}: regions={}, irqs={}, flags={}", device->name, device->info.num_regions, @@ -216,13 +217,13 @@ VfioContainer::dump() } -VfioDevice& -VfioContainer::attachDevice(const char* name, int index) +Device& +Container::attachDevice(const char* name, int index) { Logger logger = logging.get("kernel:vfio"); - VfioGroup& group = getOrAttachGroup(index); - auto device = std::make_unique(name, group); + Group &group = getOrAttachGroup(index); + auto device = std::make_unique(name, group); /* Open device fd */ device->fd = ioctl(group.fd, VFIO_GROUP_GET_DEVICE_FD, name); @@ -289,8 +290,8 @@ VfioContainer::attachDevice(const char* name, int index) } -VfioDevice& -VfioContainer::attachDevice(const pci_device* pdev) +Device& +Container::attachDevice(const pci::Device &pdev) { int ret; char name[32], iommu_state[4]; @@ -299,10 +300,8 @@ VfioContainer::attachDevice(const pci_device* pdev) Logger logger = logging.get("kernel:vfio"); /* Load PCI bus driver for VFIO */ - if (kernel::module_load("vfio_pci")) { - logger->error("Failed to load kernel driver: vfio_pci"); - throw std::exception(); - } + if (kernel::module_load("vfio_pci")) + throw RuntimeError("Failed to load kernel driver: vfio_pci"); /* Bind PCI card to vfio-pci driver if not already bound */ if (pdev.getDriver() != kernelDriver) { @@ -325,13 +324,13 @@ VfioContainer::attachDevice(const pci_device* pdev) } /* VFIO device name consists of PCI BDF */ - snprintf(name, sizeof(name), "%04x:%02x:%02x.%x", pdev->slot.domain, - pdev->slot.bus, pdev->slot.device, pdev->slot.function); + snprintf(name, sizeof(name), "%04x:%02x:%02x.%x", pdev.slot.domain, + pdev.slot.bus, pdev.slot.device, pdev.slot.function); logger->info("Attach to device {} with index {}", std::string(name), index); - auto& device = attachDevice(name, index); + auto &device = attachDevice(name, index); - device.pci_device = pdev; + device.pci_device = &pdev; /* Check if this is really a vfio-pci device */ if (not device.isVfioPciDevice()) { @@ -344,7 +343,7 @@ VfioContainer::attachDevice(const pci_device* pdev) uintptr_t -VfioContainer::memoryMap(uintptr_t virt, uintptr_t phys, size_t length) +Container::memoryMap(uintptr_t virt, uintptr_t phys, size_t length) { int ret; @@ -396,7 +395,7 @@ VfioContainer::memoryMap(uintptr_t virt, uintptr_t phys, size_t length) bool -VfioContainer::memoryUnmap(uintptr_t phys, size_t length) +Container::memoryUnmap(uintptr_t phys, size_t length) { int ret; @@ -421,20 +420,20 @@ VfioContainer::memoryUnmap(uintptr_t phys, size_t length) } -VfioGroup& -VfioContainer::getOrAttachGroup(int index) +Group& +Container::getOrAttachGroup(int index) { Logger logger = logging.get("kernel:vfio"); /* Search if group with index already exists */ - for (auto& group : groups) { + for (auto &group : groups) { if (group->index == index) { return *group; } } /* Group not yet part of this container, so acquire ownership */ - auto group = VfioGroup::attach(*this, index); + auto group = Group::attach(*this, index); if (not group) { logger->error("Failed to attach to IOMMU group: {}", index); throw std::exception(); @@ -449,13 +448,13 @@ VfioContainer::getOrAttachGroup(int index) } -VfioDevice::~VfioDevice() +Device::~Device() { Logger logger = logging.get("kernel:vfio"); logger->debug("Clean up device {} with fd {}", this->name, this->fd); - for (auto& region : regions) { + for (auto ®ion : regions) { regionUnmap(region.index); } @@ -467,7 +466,7 @@ VfioDevice::~VfioDevice() bool -VfioDevice::reset() +Device::reset() { if (this->info.flags & VFIO_DEVICE_FLAGS_RESET) return ioctl(this->fd, VFIO_DEVICE_RESET) == 0; @@ -477,7 +476,7 @@ VfioDevice::reset() void* -VfioDevice::regionMap(size_t index) +Device::regionMap(size_t index) { struct vfio_region_info *r = ®ions[index]; @@ -499,7 +498,7 @@ VfioDevice::regionMap(size_t index) bool -VfioDevice::regionUnmap(size_t index) +Device::regionUnmap(size_t index) { int ret; struct vfio_region_info *r = ®ions[index]; @@ -522,7 +521,7 @@ VfioDevice::regionUnmap(size_t index) size_t -VfioDevice::regionGetSize(size_t index) +Device::regionGetSize(size_t index) { Logger logger = logging.get("kernel:vfio"); @@ -536,7 +535,7 @@ VfioDevice::regionGetSize(size_t index) bool -VfioDevice::pciEnable() +Device::pciEnable() { int ret; uint32_t reg; @@ -563,7 +562,7 @@ VfioDevice::pciEnable() bool -VfioDevice::pciHotReset() +Device::pciHotReset() { Logger logger = logging.get("kernel:vfio"); @@ -624,7 +623,7 @@ VfioDevice::pciHotReset() int -VfioDevice::pciMsiInit(int efds[]) +Device::pciMsiInit(int efds[]) { /* Check if this is really a vfio-pci device */ if (not isVfioPciDevice()) @@ -668,7 +667,7 @@ VfioDevice::pciMsiInit(int efds[]) int -VfioDevice::pciMsiDeinit(int efds[]) +Device::pciMsiDeinit(int efds[]) { /* Check if this is really a vfio-pci device */ if (not isVfioPciDevice()) @@ -708,7 +707,7 @@ VfioDevice::pciMsiDeinit(int efds[]) bool -VfioDevice::pciMsiFind(int nos[]) +Device::pciMsiFind(int nos[]) { int ret, idx, irq; char *end, *col, *last, line[1024], name[13]; @@ -750,13 +749,13 @@ VfioDevice::pciMsiFind(int nos[]) bool -VfioDevice::isVfioPciDevice() const +Device::isVfioPciDevice() const { return info.flags & VFIO_DEVICE_FLAGS_PCI; } -VfioGroup::~VfioGroup() +Group::~Group() { Logger logger = logging.get("kernel:vfio"); @@ -781,12 +780,12 @@ VfioGroup::~VfioGroup() } -std::unique_ptr -VfioGroup::attach(VfioContainer& container, int groupIndex) +std::unique_ptr +Group::attach(Container &container, int groupIndex) { Logger logger = logging.get("kernel:vfio"); - std::unique_ptr group { new VfioGroup(groupIndex) }; + std::unique_ptr group { new Group(groupIndex) }; group->container = &container;