/* Vfio connection to a device. * * Author: Pascal Bauer * * SPDX-FileCopyrightText: 2024-25 Pascal Bauer * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include namespace villas { namespace kernel { namespace devices { DeviceConnection::DeviceConnection( std::shared_ptr vfio_device) : logger(villas::Log::get("DeviceConnection")), vfio_device(vfio_device) {}; DeviceConnection DeviceConnection::from( const villas::kernel::devices::Device &device, std::shared_ptr vfio_container) { auto logger = villas::Log::get("Builder: DeviceConnection"); // Bind the devicetree device to vfio driver LinuxDriver driver( std::filesystem::path("/sys/bus/platform/drivers/vfio-platform")); driver.attach(device); // Attach vfio container to the iommu group const int iommu_group = device.iommu_group().value(); auto vfio_group = vfio_container->getOrAttachGroup(iommu_group); logger->debug("Device: {}, Iommu: {}", device.name(), iommu_group); // Open Vfio Device auto vfio_device = std::make_shared( device.name(), vfio_group->getFileDescriptor()); // Attach device to group vfio_group->attachDevice(vfio_device); return DeviceConnection(vfio_device); } void DeviceConnection::addToMemorygraph() const { // Map vfio device memory to process const void *mapping = this->vfio_device->regionMap(0); if (mapping == MAP_FAILED) { logger->error("Failed to mmap() device"); } logger->debug("memory mapped: {}", this->vfio_device->getName()); // Create memorygraph edge from process to vfio device auto &mm = MemoryManager::get(); size_t srcVertexId = mm.getProcessAddressSpace(); const size_t mem_size = this->vfio_device->regionGetSize(0); size_t targetVertexId = mm.getOrCreateAddressSpace(this->vfio_device->getName()); mm.createMapping(reinterpret_cast(mapping), 0, mem_size, "process to vfio", srcVertexId, targetVertexId); logger->debug("create edge from process to {}", this->vfio_device->getName()); } } // namespace devices } // namespace kernel } // namespace villas