diff --git a/common/include/villas/kernel/vfio.hpp b/common/include/villas/kernel/vfio.hpp index dbd96f71b..89a2d7d15 100644 --- a/common/include/villas/kernel/vfio.hpp +++ b/common/include/villas/kernel/vfio.hpp @@ -27,20 +27,9 @@ namespace villas { namespace kernel { namespace pci { - -/* Forward declarations */ -struct Device; - -} - namespace vfio { -/* Forward declarations */ -class Container; -class Group; - class Device { - friend class Container; public: Device(const std::string &name, Group &group) : name(name), @@ -110,6 +99,12 @@ public: static std::unique_ptr attach(Container &container, int groupIndex); + std::list>& getDevices() + { return devices; } + + int getFd() + { return fd; } + private: /// VFIO group file descriptor int fd; @@ -159,10 +154,12 @@ public: const int &getFd() const { return fd; } + std::list> &getGroups() + { return groups; } + private: Group & getOrAttachGroup(int index); -private: int fd; int version; int extensions; diff --git a/common/lib/kernel/vfio.cpp b/common/lib/kernel/vfio.cpp index b71995f55..d8b546880 100644 --- a/common/lib/kernel/vfio.cpp +++ b/common/lib/kernel/vfio.cpp @@ -59,11 +59,27 @@ static const char *vfio_pci_irq_names[] = { namespace villas { +void panicResetEverything() +{ + int ret = 0; + for (auto& group : container->getGroups()) { + for (auto& device : group->getDevices()) { + ret += device->reset(); + + } + if (group->getFd() > 0) { + ret += ioctl(group->getFd(), VFIO_GROUP_UNSET_CONTAINER); + } + } + if (ret > 0) + logging.get("kernel:vfio")->error("panic reset return errors."); +} Container::Container() : iova_next(0) { Logger logger = logging.get("kernel:vfio"); + spdlog::set_level(spdlog::level::debug); static constexpr const char* requiredKernelModules[] = { "vfio", "vfio_pci", "vfio_iommu_type1" @@ -107,6 +123,11 @@ Container::Container() logger->debug("Version: {:#x}", version); logger->debug("Extensions: {:#x}", extensions); logger->debug("IOMMU: {}", hasIommu ? "yes" : "no"); + + container = this; + std::atexit([](){ + panicResetEverything(); + }); } @@ -417,6 +438,7 @@ Device::~Device() for (auto ®ion : regions) { regionUnmap(region.index); } + reset(); int ret = close(fd); if (ret != 0) { @@ -428,6 +450,7 @@ Device::~Device() bool Device::reset() { + logging.get("kernel:vfio")->debug("Resetting device."); if (this->info.flags & VFIO_DEVICE_FLAGS_RESET) return ioctl(this->fd, VFIO_DEVICE_RESET) == 0; else @@ -735,6 +758,7 @@ Group::~Group() if (fd < 0) logger->debug("Destructing group that has not been attached"); else { + logger->debug("unsetting group container"); int ret = ioctl(fd, VFIO_GROUP_UNSET_CONTAINER); if (ret != 0) logger->error("Cannot unset container for group fd {}", fd);