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: track if IOMMU is enabled to prepare for non-IOMMU mode

This commit is contained in:
Daniel Krebs 2018-05-15 11:22:29 +02:00
parent 1f42f5bb63
commit 94ba899b21
2 changed files with 38 additions and 3 deletions

View file

@ -135,6 +135,9 @@ public:
/** munmap() a region which has been mapped by vfio_map_region() */
bool memoryUnmap(uintptr_t phys, size_t length);
bool isIommuEnabled() const
{ return this->hasIommu; }
private:
VfioGroup& getOrAttachGroup(int index);
@ -143,6 +146,7 @@ private:
int version;
int extensions;
uint64_t iova_next; /**< Next free IOVA address */
bool hasIommu;
/// All groups bound to this container
std::list<std::unique_ptr<VfioGroup>> groups;

View file

@ -108,12 +108,25 @@ VfioContainer::VfioContainer()
logger->error("Failed to get VFIO extensions");
throw std::exception();
}
else if (ret > 0)
else if (ret > 0) {
extensions |= (1 << i);
}
}
logger->debug("Version: {:#x}", version);
hasIommu = false;
if(not (extensions & (1 << VFIO_NOIOMMU_IOMMU))) {
if(not (extensions & (1 << VFIO_TYPE1_IOMMU))) {
logger->error("No supported IOMMU extension found");
throw std::exception();
} else {
hasIommu = true;
}
}
logger->debug("Version: {:#x}", version);
logger->debug("Extensions: {:#x}", extensions);
logger->debug("IOMMU: {}", hasIommu ? "yes" : "no");
}
@ -319,6 +332,11 @@ VfioContainer::memoryMap(uintptr_t virt, uintptr_t phys, size_t length)
{
int ret;
if(not hasIommu) {
logger->error("DMA mapping not supported without IOMMU");
return UINTPTR_MAX;
}
if (length & 0xFFF) {
length += 0x1000;
length &= ~0xFFF;
@ -363,6 +381,10 @@ VfioContainer::memoryUnmap(uintptr_t phys, size_t length)
{
int ret;
if(not hasIommu) {
return true;
}
struct vfio_iommu_type1_dma_unmap dmaUnmap;
dmaUnmap.argsz = sizeof(struct vfio_iommu_type1_dma_unmap);
dmaUnmap.flags = 0;
@ -554,6 +576,11 @@ VfioDevice::pciHotReset()
free(reset);
free(reset_info);
if(not success and not group.container->isIommuEnabled()) {
logger->info("PCI hot reset failed, but this is expected without IOMMU");
return true;
}
return success;
}
@ -740,7 +767,11 @@ VfioGroup::attach(int containerFd, int groupIndex)
}
/* Set IOMMU type */
ret = ioctl(containerFd, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
int iommu_type = container.isIommuEnabled() ?
VFIO_TYPE1_IOMMU :
VFIO_NOIOMMU_IOMMU;
ret = ioctl(containerFd, VFIO_SET_IOMMU, iommu_type);
if (ret < 0) {
logger->error("Failed to set IOMMU type of container: {}", ret);
return nullptr;