mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
code-style fixes
Signed-off-by: Steffen Vogel <post@steffenvogel.de>
This commit is contained in:
parent
e9e638d6a4
commit
1844d4fbfc
7 changed files with 142 additions and 199 deletions
|
@ -15,25 +15,24 @@
|
|||
namespace villas {
|
||||
namespace kernel {
|
||||
|
||||
/** Get the version of the kernel. */
|
||||
// Get the version of the kernel.
|
||||
utils::Version getVersion();
|
||||
|
||||
/** Get number of reserved hugepages. */
|
||||
// Get number of reserved hugepages.
|
||||
int getNrHugepages();
|
||||
|
||||
/** Set number of reserved hugepages. */
|
||||
// Set number of reserved hugepages.
|
||||
int setNrHugepages(int nr);
|
||||
|
||||
/** Get kernel cmdline parameter
|
||||
*
|
||||
* See https://www.kernel.org/doc/Documentation/kernel-parameters.txt
|
||||
*
|
||||
* @param param The cmdline parameter to look for.
|
||||
* @param buf The string buffer to which the parameter value will be copied to.
|
||||
* @param len The length of the buffer \p value
|
||||
* @retval 0 Parameter \p key was found and value was copied to \p value
|
||||
* @reval <>0 Kernel was not booted with parameter \p key
|
||||
*/
|
||||
// Get kernel cmdline parameter
|
||||
//
|
||||
// See https://www.kernel.org/doc/Documentation/kernel-parameters.txt
|
||||
//
|
||||
// @param param The cmdline parameter to look for.
|
||||
// @param buf The string buffer to which the parameter value will be copied to.
|
||||
// @param len The length of the buffer \p value
|
||||
// @retval 0 Parameter \p key was found and value was copied to \p value
|
||||
// @reval <>0 Kernel was not booted with parameter \p key
|
||||
int getCmdlineParam(const char *param, char *buf, size_t len);
|
||||
|
||||
/** Checks if a kernel module is loaded
|
||||
|
@ -44,25 +43,25 @@ int getCmdlineParam(const char *param, char *buf, size_t len);
|
|||
*/
|
||||
int isModuleLoaded(const char *module);
|
||||
|
||||
/** Load kernel module via modprobe */
|
||||
// Load kernel module via modprobe
|
||||
int loadModule(const char *module);
|
||||
|
||||
/** Set parameter of loaded kernel module */
|
||||
// Set parameter of loaded kernel module
|
||||
int setModuleParam(const char *module, const char *param, const char *value);
|
||||
|
||||
/** Get cacheline size in bytes */
|
||||
// Get cacheline size in bytes
|
||||
int getCachelineSize();
|
||||
|
||||
/** Get the size of a standard page in bytes. */
|
||||
// Get the size of a standard page in bytes.
|
||||
int getPageSize();
|
||||
|
||||
/** Get the size of a huge page in bytes. */
|
||||
// Get the size of a huge page in bytes.
|
||||
int getHugePageSize();
|
||||
|
||||
/** Get CPU base frequency */
|
||||
// Get CPU base frequency
|
||||
int get_cpu_frequency(uint64_t *freq);
|
||||
|
||||
/** Set SMP affinity of IRQ */
|
||||
// Set SMP affinity of IRQ
|
||||
int setIRQAffinity(unsigned irq, uintmax_t aff , uintmax_t *old);
|
||||
|
||||
} // namespace villas
|
||||
|
|
|
@ -31,8 +31,7 @@ public:
|
|||
class_code(cc)
|
||||
{ }
|
||||
|
||||
bool
|
||||
operator==(const Id &i);
|
||||
bool operator==(const Id &i);
|
||||
|
||||
unsigned int vendor;
|
||||
unsigned int device;
|
||||
|
@ -50,8 +49,7 @@ public:
|
|||
function(fcn)
|
||||
{ }
|
||||
|
||||
bool
|
||||
operator==(const Slot &s);
|
||||
bool operator==(const Slot &s);
|
||||
|
||||
unsigned int domain;
|
||||
unsigned int bus;
|
||||
|
@ -87,35 +85,29 @@ public:
|
|||
bool
|
||||
operator==(const Device &other);
|
||||
|
||||
/** Get currently loaded driver for device */
|
||||
std::string
|
||||
getDriver() const;
|
||||
// Get currently loaded driver for device.
|
||||
std::string getDriver() const;
|
||||
|
||||
/** Bind a new LKM to the PCI device */
|
||||
bool
|
||||
attachDriver(const std::string &driver) const;
|
||||
// Bind a new LKM to the PCI device.
|
||||
bool attachDriver(const std::string &driver) const;
|
||||
|
||||
/** Return the IOMMU group of this PCI device or -1 if the device is not in a group. */
|
||||
int
|
||||
getIOMMUGroup() const;
|
||||
// Return the IOMMU group of this PCI device or -1 if the device is not in a group.
|
||||
int getIommuGroup() const;
|
||||
|
||||
std::list<Region>
|
||||
getRegions() const;
|
||||
std::list<Region> getRegions() const;
|
||||
|
||||
/** Write 32-bit BAR value from to the PCI configuration space */
|
||||
// Write 32-bit BAR value from to the PCI configuration space
|
||||
bool writeBar(uint32_t new_bar);
|
||||
|
||||
/** If BAR values in config space and in the kernel do not match, rewrite
|
||||
* the BAR value of the kernel to PCIe config space.
|
||||
*/
|
||||
// If BAR values in config space and in the kernel do not match, rewrite
|
||||
// the BAR value of the kernel to PCIe config space.
|
||||
bool rewriteBar();
|
||||
|
||||
/** Read 32-bit BAR value from the PCI configuration space */
|
||||
// Read 32-bit BAR value from the PCI configuration space.
|
||||
bool readBar(uint32_t &bar) const;
|
||||
|
||||
/** Read 32-bit BAR value from the devices resource file. This is what the kernel
|
||||
* thinks the BAR should be.
|
||||
*/
|
||||
// Read 32-bit BAR value from the devices resource file. This is what the kernel
|
||||
// thinks the BAR should be.
|
||||
bool readHostBar(uint32_t &bar) const;
|
||||
|
||||
Id id;
|
||||
|
@ -126,20 +118,16 @@ private:
|
|||
|
||||
class DeviceList : public std::list<std::shared_ptr<Device>> {
|
||||
public:
|
||||
/** Initialize Linux PCI handle.
|
||||
*
|
||||
* This search for all available PCI devices under /sys/bus/pci
|
||||
*/
|
||||
// Initialize Linux PCI handle.
|
||||
//
|
||||
// This search for all available PCI devices under /sys/bus/pci
|
||||
DeviceList();
|
||||
|
||||
DeviceList::value_type
|
||||
lookupDevice(const Slot &s);
|
||||
DeviceList::value_type lookupDevice(const Slot &s);
|
||||
|
||||
DeviceList::value_type
|
||||
lookupDevice(const Id &i);
|
||||
DeviceList::value_type lookupDevice(const Id &i);
|
||||
|
||||
DeviceList::value_type
|
||||
lookupDevice(const Device &f);
|
||||
DeviceList::value_type lookupDevice(const Device &f);
|
||||
};
|
||||
|
||||
} // namespace pci
|
||||
|
|
|
@ -22,13 +22,12 @@ void setThreadAffinity(pthread_t thread, int affinity);
|
|||
|
||||
void setPriority(int priority);
|
||||
|
||||
/** Checks for realtime (PREEMPT_RT) patched kernel.
|
||||
*
|
||||
* See https://rt.wiki.kernel.org
|
||||
*
|
||||
* @retval true Kernel is patched.
|
||||
* @retval false Kernel is not patched.
|
||||
*/
|
||||
// Checks for realtime (PREEMPT_RT) patched kernel.
|
||||
//
|
||||
// See https://rt.wiki.kernel.org
|
||||
//
|
||||
// @retval true Kernel is patched.
|
||||
// @retval false Kernel is not patched.
|
||||
bool isPreemptible();
|
||||
|
||||
} // namespace villas
|
||||
|
|
|
@ -51,13 +51,12 @@ public:
|
|||
std::shared_ptr<Device> attachDevice(const std::string& name, int groupIndex);
|
||||
std::shared_ptr<Device> attachDevice(pci::Device &pdev);
|
||||
|
||||
/**
|
||||
* @brief Map VM to an IOVA, which is accessible by devices in the container
|
||||
* @param virt virtual address of memory
|
||||
* @param phys IOVA where to map @p virt, -1 to use VFIO internal allocator
|
||||
* @param length size of memory region in bytes
|
||||
* @return IOVA address, UINTPTR_MAX on failure
|
||||
*/
|
||||
// Map VM to an IOVA, which is accessible by devices in the container
|
||||
//
|
||||
// @param virt virtual address of memory
|
||||
// @param phys IOVA where to map @p virt, -1 to use VFIO internal allocator
|
||||
// @param length size of memory region in bytes
|
||||
// @return IOVA address, UINTPTR_MAX on failure
|
||||
uintptr_t memoryMap(uintptr_t virt, uintptr_t phys, size_t length);
|
||||
|
||||
/** munmap() a region which has been mapped by vfio_map_region() */
|
||||
|
@ -75,7 +74,7 @@ private:
|
|||
int version;
|
||||
|
||||
std::array<bool, EXTENSION_SIZE> extensions;
|
||||
uint64_t iova_next; /**< Next free IOVA address */
|
||||
uint64_t iova_next; // Next free IOVA address
|
||||
bool hasIommu;
|
||||
|
||||
// All groups bound to this container
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <villas/kernel/pci.hpp>
|
||||
#include <villas/log.hpp>
|
||||
|
||||
|
||||
namespace villas {
|
||||
namespace kernel {
|
||||
namespace vfio {
|
||||
|
|
|
@ -35,8 +35,7 @@ DeviceList::DeviceList()
|
|||
if (!dp)
|
||||
throw SystemError("Failed to detect PCI devices");
|
||||
|
||||
while ((e = readdir(dp)))
|
||||
{
|
||||
while ((e = readdir(dp))) {
|
||||
// Ignore special entries
|
||||
if ((strcmp(e->d_name, ".") == 0) ||
|
||||
(strcmp(e->d_name, "..") == 0))
|
||||
|
@ -45,8 +44,7 @@ DeviceList::DeviceList()
|
|||
Id id;
|
||||
Slot slot;
|
||||
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
const char *s;
|
||||
unsigned int *p;
|
||||
} map[] = {
|
||||
|
@ -54,8 +52,7 @@ DeviceList::DeviceList()
|
|||
{"device", &id.device}};
|
||||
|
||||
// Read vendor & device id
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (int i = 0; i < 2; i++) {
|
||||
snprintf(path, sizeof(path), "%s/bus/pci/devices/%s/%s", SYSFS_PATH, e->d_name, map[i].s);
|
||||
|
||||
f = fopen(path, "r");
|
||||
|
@ -80,22 +77,19 @@ DeviceList::DeviceList()
|
|||
closedir(dp);
|
||||
}
|
||||
|
||||
DeviceList::value_type
|
||||
DeviceList::lookupDevice(const Slot &s)
|
||||
DeviceList::value_type DeviceList::lookupDevice(const Slot &s)
|
||||
{
|
||||
return *std::find_if(begin(), end(), [s](const DeviceList::value_type &d)
|
||||
{ return d->slot == s; });
|
||||
}
|
||||
|
||||
DeviceList::value_type
|
||||
DeviceList::lookupDevice(const Id &i)
|
||||
DeviceList::value_type DeviceList::lookupDevice(const Id &i)
|
||||
{
|
||||
return *std::find_if(begin(), end(), [i](const DeviceList::value_type &d)
|
||||
{ return d->id == i; });
|
||||
}
|
||||
|
||||
DeviceList::value_type
|
||||
DeviceList::lookupDevice(const Device &d)
|
||||
DeviceList::value_type DeviceList::lookupDevice(const Device &d)
|
||||
{
|
||||
auto dev = std::find_if(begin(), end(), [d](const DeviceList::value_type &e)
|
||||
{ return *e == d; });
|
||||
|
@ -103,9 +97,10 @@ DeviceList::lookupDevice(const Device &d)
|
|||
return dev == end() ? value_type() : *dev;
|
||||
}
|
||||
|
||||
Id::Id(const std::string &str) : vendor(0),
|
||||
device(0),
|
||||
class_code(0)
|
||||
Id::Id(const std::string &str) :
|
||||
vendor(0),
|
||||
device(0),
|
||||
class_code(0)
|
||||
{
|
||||
char *s, *c, *e;
|
||||
char *tmp = strdup(str.c_str());
|
||||
|
@ -114,19 +109,16 @@ Id::Id(const std::string &str) : vendor(0),
|
|||
return;
|
||||
|
||||
s = strchr(tmp, ':');
|
||||
if (!s)
|
||||
{
|
||||
if (!s) {
|
||||
free(tmp);
|
||||
throw RuntimeError("Failed to parse PCI id: ':' expected", str);
|
||||
}
|
||||
|
||||
*s++ = 0;
|
||||
if (tmp[0] && strcmp(tmp, "*"))
|
||||
{
|
||||
if (tmp[0] && strcmp(tmp, "*")) {
|
||||
long int x = strtol(tmp, &e, 16);
|
||||
|
||||
if ((e && *e) || (x < 0 || x > 0xffff))
|
||||
{
|
||||
if ((e && *e) || (x < 0 || x > 0xffff)) {
|
||||
free(tmp);
|
||||
throw RuntimeError("Failed to parse PCI id: {}: Invalid vendor id", str);
|
||||
}
|
||||
|
@ -138,11 +130,9 @@ Id::Id(const std::string &str) : vendor(0),
|
|||
if (c)
|
||||
*c++ = 0;
|
||||
|
||||
if (s[0] && strcmp(s, "*"))
|
||||
{
|
||||
if (s[0] && strcmp(s, "*")) {
|
||||
long int x = strtol(s, &e, 16);
|
||||
if ((e && *e) || (x < 0 || x > 0xffff))
|
||||
{
|
||||
if ((e && *e) || (x < 0 || x > 0xffff)) {
|
||||
free(tmp);
|
||||
throw RuntimeError("Failed to parse PCI id: {}: Invalid device id", str);
|
||||
}
|
||||
|
@ -150,12 +140,10 @@ Id::Id(const std::string &str) : vendor(0),
|
|||
device = x;
|
||||
}
|
||||
|
||||
if (c && c[0] && strcmp(s, "*"))
|
||||
{
|
||||
if (c && c[0] && strcmp(s, "*")) {
|
||||
long int x = strtol(c, &e, 16);
|
||||
|
||||
if ((e && *e) || (x < 0 || x > 0xffff))
|
||||
{
|
||||
if ((e && *e) || (x < 0 || x > 0xffff)) {
|
||||
free(tmp);
|
||||
throw RuntimeError("Failed to parse PCI id: {}: Invalid class code", str);
|
||||
}
|
||||
|
@ -176,10 +164,11 @@ bool Id::operator==(const Id &i)
|
|||
return true;
|
||||
}
|
||||
|
||||
Slot::Slot(const std::string &str) : domain(0),
|
||||
bus(0),
|
||||
device(0),
|
||||
function(0)
|
||||
Slot::Slot(const std::string &str) :
|
||||
domain(0),
|
||||
bus(0),
|
||||
device(0),
|
||||
function(0)
|
||||
{
|
||||
char *tmp = strdup(str.c_str());
|
||||
char *colon = strrchr(tmp, ':');
|
||||
|
@ -187,22 +176,18 @@ Slot::Slot(const std::string &str) : domain(0),
|
|||
char *mid = tmp;
|
||||
char *e, *buss, *colon2;
|
||||
|
||||
if (colon)
|
||||
{
|
||||
if (colon) {
|
||||
*colon++ = 0;
|
||||
mid = colon;
|
||||
|
||||
colon2 = strchr(tmp, ':');
|
||||
if (colon2)
|
||||
{
|
||||
if (colon2) {
|
||||
*colon2++ = 0;
|
||||
buss = colon2;
|
||||
|
||||
if (tmp[0] && strcmp(tmp, "*"))
|
||||
{
|
||||
if (tmp[0] && strcmp(tmp, "*")) {
|
||||
long int x = strtol(tmp, &e, 16);
|
||||
if ((e && *e) || (x < 0 || x > 0x7fffffff))
|
||||
{
|
||||
if ((e && *e) || (x < 0 || x > 0x7fffffff)) {
|
||||
free(tmp);
|
||||
throw RuntimeError("Failed to parse PCI slot: {}: invalid domain", str);
|
||||
}
|
||||
|
@ -213,11 +198,9 @@ Slot::Slot(const std::string &str) : domain(0),
|
|||
else
|
||||
buss = tmp;
|
||||
|
||||
if (buss[0] && strcmp(buss, "*"))
|
||||
{
|
||||
if (buss[0] && strcmp(buss, "*")) {
|
||||
long int x = strtol(buss, &e, 16);
|
||||
if ((e && *e) || (x < 0 || x > 0xff))
|
||||
{
|
||||
if ((e && *e) || (x < 0 || x > 0xff)) {
|
||||
free(tmp);
|
||||
throw RuntimeError("Failed to parse PCI slot: {}: invalid bus", str);
|
||||
}
|
||||
|
@ -229,12 +212,10 @@ Slot::Slot(const std::string &str) : domain(0),
|
|||
if (dot)
|
||||
*dot++ = 0;
|
||||
|
||||
if (mid[0] && strcmp(mid, "*"))
|
||||
{
|
||||
if (mid[0] && strcmp(mid, "*")) {
|
||||
long int x = strtol(mid, &e, 16);
|
||||
|
||||
if ((e && *e) || (x < 0 || x > 0x1f))
|
||||
{
|
||||
if ((e && *e) || (x < 0 || x > 0x1f)) {
|
||||
free(tmp);
|
||||
throw RuntimeError("Failed to parse PCI slot: {}: invalid slot", str);
|
||||
}
|
||||
|
@ -242,12 +223,10 @@ Slot::Slot(const std::string &str) : domain(0),
|
|||
device = x;
|
||||
}
|
||||
|
||||
if (dot && dot[0] && strcmp(dot, "*"))
|
||||
{
|
||||
if (dot && dot[0] && strcmp(dot, "*")) {
|
||||
long int x = strtol(dot, &e, 16);
|
||||
|
||||
if ((e && *e) || (x < 0 || x > 7))
|
||||
{
|
||||
if ((e && *e) || (x < 0 || x > 7)) {
|
||||
free(tmp);
|
||||
throw RuntimeError("Failed to parse PCI slot: {}: invalid function", str);
|
||||
}
|
||||
|
@ -274,8 +253,7 @@ bool Device::operator==(const Device &f)
|
|||
return id == f.id && slot == f.slot;
|
||||
}
|
||||
|
||||
std::list<Region>
|
||||
Device::getRegions() const
|
||||
std::list<Region> Device::getRegions() const
|
||||
{
|
||||
FILE *f;
|
||||
char sysfs[1024];
|
||||
|
@ -296,16 +274,13 @@ Device::getRegions() const
|
|||
int reg_num = 0;
|
||||
|
||||
// Cap to 8 regions, just because we don't know how many may exist.
|
||||
while (reg_num < 8 && (bytesRead = getline(&line, &len, f)) != -1)
|
||||
{
|
||||
while (reg_num < 8 && (bytesRead = getline(&line, &len, f)) != -1) {
|
||||
unsigned long long tokens[3];
|
||||
char *s = line;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int i = 0; i < 3; i++) {
|
||||
char *end;
|
||||
tokens[i] = strtoull(s, &end, 16);
|
||||
if (s == end)
|
||||
{
|
||||
if (s == end) {
|
||||
log->debug("Error parsing line {} of {}", reg_num + 1, sysfs);
|
||||
tokens[0] = tokens[1] = 0; // Mark invalid
|
||||
break;
|
||||
|
@ -319,8 +294,7 @@ Device::getRegions() const
|
|||
line = nullptr;
|
||||
len = 0;
|
||||
|
||||
if (tokens[0] != tokens[1])
|
||||
{ // This is a valid region
|
||||
if (tokens[0] != tokens[1]) { // This is a valid region
|
||||
Region region;
|
||||
|
||||
region.num = reg_num;
|
||||
|
@ -339,8 +313,7 @@ Device::getRegions() const
|
|||
return regions;
|
||||
}
|
||||
|
||||
std::string
|
||||
Device::getDriver() const
|
||||
std::string Device::getDriver() const
|
||||
{
|
||||
int ret;
|
||||
char sysfs[1024], syml[1024];
|
||||
|
@ -393,62 +366,61 @@ bool Device::attachDriver(const std::string &driver) const
|
|||
bool Device::readHostBar(uint32_t &bar) const
|
||||
{
|
||||
unsigned long long start, end, size, flags;
|
||||
|
||||
char *path = NULL;
|
||||
if (asprintf(&path, "%s/bus/pci/devices/%04x:%02x:%02x.%x/resource", SYSFS_PATH,
|
||||
slot.domain, slot.bus, slot.device, slot.function) == -1)
|
||||
{
|
||||
slot.domain, slot.bus, slot.device, slot.function) == -1) {
|
||||
log->error("could not allocate memory for path");
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *file = fopen(path, "r");
|
||||
if (!file)
|
||||
{
|
||||
if (!file) {
|
||||
log->error("error opening resource file");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fscanf(file, "%llx %llx %llx", &start, &end, &flags) != 3)
|
||||
{
|
||||
if (fscanf(file, "%llx %llx %llx", &start, &end, &flags) != 3) {
|
||||
log->error("error reading resource file");
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (end > start)
|
||||
{
|
||||
size = end - start + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
log->error("error reading bar size");
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
log->debug("start: {:#x}, end: {:#x}, size: {:#x}, flags: {:#x}", start, end, size, flags);
|
||||
|
||||
log->debug("Start: {:#x}, end: {:#x}, size: {:#x}, flags: {:#x}", start, end, size, flags);
|
||||
|
||||
fclose(file);
|
||||
bar = start;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Device::rewriteBar()
|
||||
{
|
||||
uint32_t hostbar, configbar;
|
||||
if (!readHostBar(hostbar))
|
||||
{
|
||||
log->error("error reading host bar");
|
||||
if (!readHostBar(hostbar)) {
|
||||
log->error("Error reading host bar");
|
||||
return false;
|
||||
}
|
||||
if (!readBar(configbar))
|
||||
{
|
||||
log->error("error reading config bar");
|
||||
|
||||
if (!readBar(configbar)) {
|
||||
log->error("Error reading config bar");
|
||||
return false;
|
||||
}
|
||||
log->debug("hostbar: {:#x}, configbar: {:#x}", hostbar, configbar);
|
||||
if (hostbar == configbar)
|
||||
{
|
||||
log->debug("bar is already correct");
|
||||
log->debug("Host BAR: {:#x}, configbar: {:#x}", hostbar, configbar);
|
||||
|
||||
if (hostbar == configbar) {
|
||||
log->debug("BAR is already correct");
|
||||
return true;
|
||||
} else {
|
||||
log->debug("bar is incorrect, rewriting");
|
||||
log->debug("BAR is incorrect, rewriting");
|
||||
return writeBar(hostbar);
|
||||
}
|
||||
}
|
||||
|
@ -459,26 +431,26 @@ bool Device::readBar(uint32_t &bar) const
|
|||
uint32_t read_buf;
|
||||
char *path = NULL;
|
||||
if (asprintf(&path, "%s/bus/pci/devices/%04x:%02x:%02x.%x/config", SYSFS_PATH,
|
||||
slot.domain, slot.bus, slot.device, slot.function) == -1)
|
||||
{
|
||||
slot.domain, slot.bus, slot.device, slot.function) == -1) {
|
||||
log->error("could not allocate memory for path");
|
||||
return false;
|
||||
}
|
||||
|
||||
int fd = open(path, O_RDWR);
|
||||
if (fd < 0)
|
||||
{
|
||||
if (fd < 0) {
|
||||
log->error("could not open config space");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pread(fd, &read_buf, sizeof(read_buf), pos) != sizeof(read_buf))
|
||||
{
|
||||
if (pread(fd, &read_buf, sizeof(read_buf), pos) != sizeof(read_buf)) {
|
||||
log->error("error reading from {:#x}", pos);
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
bar = read_buf;
|
||||
close(fd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -487,33 +459,34 @@ bool Device::writeBar(uint32_t new_bar)
|
|||
uint32_t write_buf = new_bar;
|
||||
off_t pos = PCI_BASE_ADDRESS_0;
|
||||
char *path = NULL;
|
||||
|
||||
if (asprintf(&path, "%s/bus/pci/devices/%04x:%02x:%02x.%x/config", SYSFS_PATH,
|
||||
slot.domain, slot.bus, slot.device, slot.function) == -1)
|
||||
{
|
||||
slot.domain, slot.bus, slot.device, slot.function) == -1) {
|
||||
log->error("could not allocate memory for path");
|
||||
return false;
|
||||
}
|
||||
|
||||
int fd = open(path, O_RDWR);
|
||||
if (fd < 0)
|
||||
{
|
||||
if (fd < 0) {
|
||||
log->error("could not open config space");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pwrite(fd, &write_buf, sizeof(write_buf), pos) != sizeof(write_buf))
|
||||
{
|
||||
if (pwrite(fd, &write_buf, sizeof(write_buf), pos) != sizeof(write_buf)) {
|
||||
log->error("error writing to {:#x}", pos);
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
int Device::getIOMMUGroup() const
|
||||
int Device::getIommuGroup() const
|
||||
{
|
||||
int ret;
|
||||
char *group;
|
||||
|
||||
// readlink() does not add a null terminator!
|
||||
char link[1024] = {0};
|
||||
char sysfs[1024];
|
||||
|
|
|
@ -98,11 +98,9 @@ Container::Container() :
|
|||
// Check available VFIO extensions (IOMMU types)
|
||||
for (unsigned int i = VFIO_TYPE1_IOMMU; i < EXTENSION_SIZE; i++) {
|
||||
int ret = ioctl(fd, VFIO_CHECK_EXTENSION, i);
|
||||
if (ret == 0)
|
||||
extensions[i] = false;
|
||||
else {
|
||||
extensions[i] = true;
|
||||
}
|
||||
|
||||
extensions[i] = ret != 0;
|
||||
|
||||
log->debug("VFIO extension {} is {} ({})", i, extensions[i] ? "available" : "not available", VFIO_EXTENSION_STR[i]);
|
||||
}
|
||||
|
||||
|
@ -112,9 +110,8 @@ Container::Container() :
|
|||
} else if (extensions[VFIO_NOIOMMU_IOMMU]) {
|
||||
log->debug("Using VFIO type {} ({})", VFIO_NOIOMMU_IOMMU, VFIO_EXTENSION_STR[VFIO_NOIOMMU_IOMMU]);
|
||||
hasIommu = false;
|
||||
} else {
|
||||
} else
|
||||
throw RuntimeError("No supported IOMMU type available");
|
||||
}
|
||||
|
||||
log->debug("Version: {:#x}", version);
|
||||
log->debug("IOMMU: {}", hasIommu ? "yes" : "no");
|
||||
|
@ -140,20 +137,16 @@ void Container::attachGroup(std::shared_ptr<Group> group)
|
|||
|
||||
// Claim group ownership
|
||||
int ret = ioctl(group->getFileDescriptor(), VFIO_GROUP_SET_CONTAINER, &fd);
|
||||
if (ret < 0) {
|
||||
log->error("Failed to attach VFIO group {} to container fd {} (error {})",
|
||||
group->getIndex(), fd, ret);
|
||||
throw RuntimeError("Failed to attach VFIO group to container");
|
||||
}
|
||||
if (ret < 0)
|
||||
throw SystemError("Failed to attach VFIO group {} to container fd {}",
|
||||
group->getIndex(), fd);
|
||||
|
||||
// Set IOMMU type
|
||||
int iommu_type = isIommuEnabled() ? VFIO_TYPE1_IOMMU : VFIO_NOIOMMU_IOMMU;
|
||||
|
||||
ret = ioctl(fd, VFIO_SET_IOMMU, iommu_type);
|
||||
if (ret < 0) {
|
||||
log->error("Failed to set IOMMU type of container: {}", ret);
|
||||
throw RuntimeError("Failed to set IOMMU type of container");
|
||||
}
|
||||
if (ret < 0)
|
||||
throw SystemError("Failed to set IOMMU type of container");
|
||||
|
||||
group->setAttachedToContainer();
|
||||
|
||||
|
@ -167,16 +160,14 @@ std::shared_ptr<Group> Container::getOrAttachGroup(int index)
|
|||
{
|
||||
// Search if group with index already exists
|
||||
for (auto &group : groups) {
|
||||
if (group->getIndex() == index) {
|
||||
if (group->getIndex() == index)
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
||||
// Group not yet part of this container, so acquire ownership
|
||||
auto group = std::make_shared<Group>(index, isIommuEnabled());
|
||||
attachGroup(group);
|
||||
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
|
@ -186,13 +177,11 @@ void Container::dump()
|
|||
log->info("Version: {}", version);
|
||||
|
||||
// Check available VFIO extensions (IOMMU types)
|
||||
for (size_t i = 0; i < extensions.size(); i++) {
|
||||
for (size_t i = 0; i < extensions.size(); i++)
|
||||
log->debug("VFIO extension {} ({}) is {}", extensions[i], VFIO_EXTENSION_STR[i], extensions[i] ? "available" : "not available");
|
||||
}
|
||||
|
||||
for (auto &group : groups) {
|
||||
for (auto &group : groups)
|
||||
group->dump();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Device> Container::attachDevice(const std::string& name, int index)
|
||||
|
@ -225,14 +214,14 @@ std::shared_ptr<Device> Container::attachDevice(pci::Device &pdev)
|
|||
}
|
||||
|
||||
// Get IOMMU group of device
|
||||
int index = isIommuEnabled() ? pdev.getIOMMUGroup() : 0;
|
||||
int index = isIommuEnabled() ? pdev.getIommuGroup() : 0;
|
||||
if (index < 0) {
|
||||
ret = kernel::getCmdlineParam("intel_iommu", iommu_state, sizeof(iommu_state));
|
||||
if (ret != 0 || strcmp("on", iommu_state) != 0)
|
||||
log->warn("Kernel booted without command line parameter "
|
||||
"'intel_iommu' set to 'on'. Please check documentation "
|
||||
"(https://villas.fein-aachen.org/doc/fpga-setup.html) "
|
||||
"for help with troubleshooting.");
|
||||
"'intel_iommu' set to 'on'. Please check documentation "
|
||||
"(https://villas.fein-aachen.org/doc/fpga-setup.html) "
|
||||
"for help with troubleshooting.");
|
||||
|
||||
throw RuntimeError("Failed to get IOMMU group of device");
|
||||
}
|
||||
|
@ -245,7 +234,6 @@ std::shared_ptr<Device> Container::attachDevice(pci::Device &pdev)
|
|||
auto group = getOrAttachGroup(index);
|
||||
auto device = group->attachDevice(name, &pdev);
|
||||
|
||||
|
||||
// Check if this is really a vfio-pci device
|
||||
if (!device->isVfioPciDevice())
|
||||
throw RuntimeError("Device is not a vfio-pci device");
|
||||
|
@ -253,7 +241,6 @@ std::shared_ptr<Device> Container::attachDevice(pci::Device &pdev)
|
|||
return device;
|
||||
}
|
||||
|
||||
|
||||
uintptr_t Container::memoryMap(uintptr_t virt, uintptr_t phys, size_t length)
|
||||
{
|
||||
int ret;
|
||||
|
@ -323,4 +310,3 @@ bool Container::memoryUnmap(uintptr_t phys, size_t length)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue