1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

vfio: move to new namespace

This commit is contained in:
Steffen Vogel 2020-06-14 21:52:49 +02:00
parent 14013ac3e4
commit 138dabb899
2 changed files with 82 additions and 74 deletions

View file

@ -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<void*> 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<VfioGroup>
attach(VfioContainer& container, int groupIndex);
static std::unique_ptr<Group>
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<std::unique_ptr<VfioDevice>> devices;
std::list<std::unique_ptr<Device>> 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<VfioContainer>
static std::shared_ptr<Container>
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<std::unique_ptr<VfioGroup>> groups;
std::list<std::unique_ptr<Group>> groups;
};
/** @} */
} /* namespace vfio */
} /* namespace kernel */
} /* namespace villas */

View file

@ -44,12 +44,13 @@
#include <sys/eventfd.h>
#include <linux/pci_regs.h>
#include <villas/exceptions.hpp>
#include <villas/log.hpp>
#include <villas/kernel/pci.hpp>
#include <villas/kernel/kernel.hpp>
#include <villas/kernel/vfio.hpp>
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>
VfioContainer::create()
std::shared_ptr<Container>
Container::create()
{
std::shared_ptr<VfioContainer> container { new VfioContainer };
std::shared_ptr<Container> 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<VfioDevice>(name, group);
Group &group = getOrAttachGroup(index);
auto device = std::make_unique<Device>(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 &region : 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 = &regions[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 = &regions[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>
VfioGroup::attach(VfioContainer& container, int groupIndex)
std::unique_ptr<Group>
Group::attach(Container &container, int groupIndex)
{
Logger logger = logging.get("kernel:vfio");
std::unique_ptr<VfioGroup> group { new VfioGroup(groupIndex) };
std::unique_ptr<Group> group { new Group(groupIndex) };
group->container = &container;