diff --git a/common/include/villas/kernel/devices/device_connection.hpp b/common/include/villas/kernel/devices/device_connection.hpp new file mode 100644 index 000000000..3fea94fd8 --- /dev/null +++ b/common/include/villas/kernel/devices/device_connection.hpp @@ -0,0 +1,79 @@ +/* Vfio connection to a device. + * + * Author: Pascal Bauer + * + * SPDX-FileCopyrightText: 2024-25 Pascal Bauer + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#include +#include + +namespace villas { +namespace kernel { +namespace devices { + +class DeviceConnection { +public: + Logger logger; + const std::shared_ptr vfio_device; + +private: + DeviceConnection(std::shared_ptr vfio_device) + : logger(villas::Log::get("DeviceConnection")), + vfio_device(vfio_device){}; + +public: + static DeviceConnection + from(const villas::kernel::devices::Device& device, + std::shared_ptr vfio_container) { + auto logger = villas::Log::get("Builder: DeviceConnection"); + + // Bind to driver + LinuxDriver driver( + std::filesystem::path("/sys/bus/platform/drivers/vfio-platform")); + driver.attach(device); + + // Attach group to container + 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 add_to_memorygraph() 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 \ No newline at end of file