Libraries¶
Every header is bundled by the umbrella upcie.h, or can be included on its own.
The descriptions below follow the bottom-up layering.
Primitives¶
bitfield.hMacros and helpers for working with bitfields: extraction, masking, shifting, and printing of fields packed within integers or registers.
barriers.hCompiler and memory barriers for ordering loads and stores. Used by the MMIO and DMA paths to keep device-visible accesses in the intended order.
debug.hConditional debug logging behind a single
UPCIE_DEBUGmacro. Enabled for debug builds and compiled out otherwise.mmio.hVolatile 32-bit and 64-bit load and store helpers for MMIO access, suited to PCI BARs and device registers.
PCI and VFIO¶
pci.hPCI device discovery, BDF parsing and formatting, and BAR mapping.
vfioctl.hWraps the Linux VFIO ioctls with helpers and structs for managing containers, IOMMU groups, and devices, including DMA mapping into the IOMMU.
Host memory¶
hostmem.hTop-level entry point for host memory management, delegating to the components below.
hostmem_config.hShared sizing and granularity configuration, such as hugepage size and allocation granularity.
hostmem_hugepage.hPhysically contiguous memory via Linux hugepages, with allocation and physical address resolution. Ideal for direct hardware access or P2P DMA.
hostmem_heap.hA simple heap allocator over a hugepage-backed region, with virtual-to-physical resolution per block.
hostmem_dma.hA malloc-like interface for allocating and freeing DMA-capable buffers.
dma-buf¶
dmabuf.hRepresents a dma-buf and the physical pages behind it, segments those pages into a LUT for raw-physical DMA, and pretty-prints the layout. The dma-buf may originate from host memory (memfd via udmabuf) or device memory such as CUDA. This header needs nothing beyond libc.
experimental/dmabuf_import.hExperimental. Resolves the DMA addresses behind a dma-buf (
dmabuf_import_attach/dmabuf_import_detach), which is what populates the structure above. It imports the dma-buf through the out-of-treedmabuf_importmodule, shipped as thedmabuf-importDKMS package (seeexperimental/dmabuf_import). When its UAPI header<linux/dmabuf_import.h>is absent these helpers compile as stubs returningENOTSUPandUPCIE_HAVE_DMABUF_IMPORTis 0, so uPCIe still builds without it; the module must also be loaded at runtime for the import to succeed.The GPU memory helpers (
cudamem_heap.h,cudamem_mapping.h,hipmem_heap.h,hipmem_mapping.h) all reach their physical addresses through this path, so they carry the same dependency.
DMA memory¶
dmamem.hA region a device can read and write, plus the translation from a pointer into it to the address the device puts on the bus. One translator serves every flavour: arithmetic from a base where a mapping was installed, or a registry lookup where the addresses were not ours to choose.
dmamem_registry.hResolves arbitrarily many registered regions through a granule-indexed table, so a lookup stays a single load however many are registered. What the device can address is the allocation a registration falls inside, held as a refcounted backing. Registration and removal are not thread-safe and the consumer serialises them; translation is lock-free.
dmamem_heap.h, dmamem_hostmem.h, dmamem_cuda.h, dmamem_hip.h,
dmamem_memfd.h, dmamem_dmabuf.h
- A suballocating heap over a dmamem, and the constructors for the flavours:
hugepages, CUDA and HIP allocations, a memfd, and an existing dma-buf.
Experimental¶
experimental/iommu_map_pa.hExperimental. Maps an array of physical addresses into the IOMMU domain a VFIO-controlled device already uses (
iommu_map_pa_add/_del), returning an IOVA base to address that memory through, e.g. from NVMe PRPs. Needs the out-of-treeiommu-map-paDKMS package (seeexperimental/iommu_map_pa). When its UAPI header<linux/iommu_map_pa.h>is absent these helpers compile as stubs returningENOTSUPandUPCIE_HAVE_IOMMU_MAP_PAis 0, so uPCIe still builds without it; the module must also be loaded at runtime for the ioctls to succeed.
Umbrella¶
upcie.hIncludes all non-NVMe, non-CUDA components for convenient, all-in-one access.
NVMe driver components¶
Enabled by defining _UPCIE_WITH_NVME before including the umbrella header.
These form a minimal user-space NVMe driver and are intentionally limited to
basic NVMe over PCIe.
nvme_mmio.hAccessors and structured views for the NVMe controller registers (CAP, VS, CC, CSTS, AQA, DB).
nvme_controller.hA
struct nvme_controllerwrapping BAR access, admin queue setup, and reset logic. The high-level entry point for interacting with a controller.nvme_controller_vfio.hA VFIO-backed variant of the controller setup. Acquires the device through a VFIO container and group and maps its DMA buffers into the IOMMU, instead of the raw-physical sysfs path. A CUDA variant exists for GPU-direct DMA.
nvme_qpair.hA
struct nvme_qpairfor submission and completion queues, with allocation, doorbell management, and teardown.nvme_command.hThe NVMe command format and helpers for initializing common admin and I/O commands.
nvme_request.hA
struct nvme_requesttracking the lifecycle of a single command: metadata, payload, and completion.nvme_qid.hAn abstraction for queue identifiers, tracking queue type, index, and role.