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

Kernel module loading system and bug fixes of vfio (#110)

- feature: Header to specify which kernel modules (vfio support) to load
- Bug fixes: wrong errror messages, bugged region cap
- Quality of use improvements e.g. getter and str()

---------

Signed-off-by: IgnoreWarnings <pascal.bauer@rwth-aachen.de>
Signed-off-by: IgnoreWarnings <119685519+IgnoreWarnings@users.noreply.github.com>
Co-authored-by: Steffen Vogel <steffen.vogel@opal-rt.com>
This commit is contained in:
IgnoreWarnings 2023-09-08 10:12:12 +02:00 committed by Steffen Vogel
parent 5bfade1d66
commit d73663bb01
5 changed files with 54 additions and 13 deletions

View file

@ -0,0 +1,34 @@
/** VFIO Kernel module loader
*
* Author: Pascal Bauer <pascal.bauer@rwth-aachen.de>
* SPDX-FileCopyrightText: 2017 Institute for Automation of Complex Power Systems, RWTH Aachen University
* SPDX-License-Identifier: Apache-2.0
*********************************************************************************/
//TODO: Move to cmake args
//#define FPGA_PLATFORM
#define FPGA_PCI
#if defined(FPGA_PLATFORM)
#define KERNEL_MODULE_VFIO
#endif
#if defined(FPGA_PCI)
#define KERNEL_MODULE_VFIO
#define KERNEL_MODULE_VFIO_PCI
#define KERNEL_MODULE_VFIO_IOMMU_TYPE1
#endif
static constexpr const char* const requiredKernelModules[] = {
#if defined(KERNEL_MODULE_VFIO)
"vfio",
#endif // KERNEL_MODULE_VFIO_PCI
#if defined(KERNEL_MODULE_VFIO_PCI)
"vfio_pci",
#endif // KERNEL_MODULE_VFIO_PCI
#if defined(KERNEL_MODULE_VFIO_IOMMU_TYPE1)
"vfio_iommu_type1"
#endif // KERNEL_MODULE_VFIO_IOMMU_TYPE1
};

View file

@ -37,6 +37,8 @@ public:
bool reset();
std::string getName() { return name; };
// Map a device memory region to the application address space (e.g. PCI BARs)
void* regionMap(size_t index);

View file

@ -120,6 +120,13 @@ private:
<< ", size=0x" << mapping.size
<< ")";
}
std::string toString()
{
std::stringstream s;
s << *this;
return s.str();
}
};
// Custom vertex in memory graph representing an address space

View file

@ -32,6 +32,7 @@
#include <villas/exceptions.hpp>
#include <villas/log.hpp>
#include <villas/kernel/vfio.hpp>
#include <villas/kernel/vfio_container.hpp>
#include <villas/kernel/kernel.hpp>
@ -74,15 +75,10 @@ Container::Container() :
groups(),
log(logging.get("kernel:vfio::Container"))
{
static constexpr
const char* requiredKernelModules[] = {
"vfio", "vfio_pci", "vfio_iommu_type1"
};
for (const char* module : requiredKernelModules) {
if (kernel::loadModule(module) != 0) {
throw RuntimeError("Kernel module '{}' required but could not be loaded. "
"Please load manually!", module);
throw RuntimeError("Kernel module '{}' required but could not be loaded. "
"Please load manually!", module);
}
}

View file

@ -84,10 +84,12 @@ Device::Device(const std::string &name, int groupFileDescriptor, const kernel::p
log->debug("device info: flags: 0x{:x}, num_regions: {}, num_irqs: {}",
info.flags, info.num_regions, info.num_irqs);
// device_info.num_region reports always 9 and includes a VGA region, which is only supported on
// certain device IDs. So for non-VGA devices VFIO_PCI_CONFIG_REGION_INDEX will be the highest
// region index. This is the config space.
info.num_regions = VFIO_PCI_CONFIG_REGION_INDEX + 1;
if (pci_device != 0) {
// device_info.num_region reports always 9 and includes a VGA region, which is only supported on
// certain device IDs. So for non-VGA devices VFIO_PCI_CONFIG_REGION_INDEX will be the highest
// region index. This is the config space.
info.num_regions = VFIO_PCI_CONFIG_REGION_INDEX + 1;
} else { info.num_regions = 1; }
// Reserve slots already so that we can use the []-operator for access
irqs.resize(info.num_irqs);
@ -95,7 +97,7 @@ Device::Device(const std::string &name, int groupFileDescriptor, const kernel::p
mappings.resize(info.num_regions);
// Get device regions
for (size_t i = 0; i < info.num_regions && i < 8; i++) {
for (size_t i = 0; i < info.num_regions; i++) {
struct vfio_region_info region;
memset(&region, 0, sizeof (region));
@ -106,7 +108,7 @@ Device::Device(const std::string &name, int groupFileDescriptor, const kernel::p
if (ret < 0)
throw RuntimeError("Failed to get region {} of VFIO device: {}", i, name);
log->debug("region {} info: flags: 0x{:x}, cap_offset: 0x{:x}, size: 0x{:x}, offset: 0x{:x}",
log->debug("region {} info: flags: 0x{:x}, cap_offset: 0x{:x}, size: 0x{:x}, offset: 0x{:x}",
region.index, region.flags, region.cap_offset, region.size, region.offset);
regions[i] = region;