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:
parent
da3b38be2e
commit
ecfb9a7897
5 changed files with 54 additions and 13 deletions
34
common/include/villas/kernel/vfio.hpp
Normal file
34
common/include/villas/kernel/vfio.hpp
Normal 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
|
||||
};
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(®ion, 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;
|
||||
|
|
Loading…
Add table
Reference in a new issue