IOMMU Driver Development for FreeBSD
Bringing Modern Security to ARM and RISC-V Systems
A PCI device plugged into a PC typically gets full R/W access to entire DRAM, which is probably the most serious trust-boundary violations in modern PCs.
How IOMMU helps?
- Protect the operating system from malicious or bad DMA memory accesses from errant devices
- Support 32-bit devices in 64-bit environment
- Support mapping of contiguous virtual addresses to an underlying fragmented physical addresses (avoidance of scatter/gather lists)
- Support shared virtual addressing
- In a hypervisor (Bhyve) case IOMMU makes it possible for a guest operating system to be given direct control of an I/O device with only minimal hypervisor intervention.
How IOMMU works in FreeBSD?
On initialisation, a PCI-bus device requests a busdma tag. If IOMMU is active, the default busdma backend provided by architecture is replaced with a generic IOMMU busdma backend for this PCI device. The IOMMU busdma backend manages the virtual address space per domain and allows to establish and tear down arbitrary mappings by invoking methods on an underlying IOMMU driver (ARM System MMU, RISC-V IOMMU, x86 DMAR).
Implementation details
Parts that are implemented
- Page table management code (pmap for IOMMU)
- A 1/2/3-level radix tree to associate PCI devices with translation contexts
- Management of IO queues for: TLB invalidation, reporting faults and receiving paging requests from IOMMU controller.
Source code for ARM64
Initial commit to FreeBSD/arm64
Review for FreeBSD/RISC-V
Copyright © Machine-Dependent Ltd