STRUCT IOMMU_DOMAIN_OPS(9)
π struct iommu_domain_ops(9) β the kernel API manual, but make it make sense π
okay bestie, so this is a page from the Kernel API Manual, and honestly? it's giving "the plugin interface for your IOMMU domain." it's the struct that says what your domain can actually do β domain specific operations, periodt. β¨
πΈ NAME πΈ
struct iommu_domain_ops β domain specific operations π
β SYNOPSIS β
struct iommu_domain_ops {
int (*attach_dev)(struct iommu_domain *domain, struct device *dev,
struct iommu_domain *old);
int (*set_dev_pasid)(struct iommu_domain *domain, struct device
*dev, ioasid_t pasid, struct iommu_domain *old);
int (*map_pages)(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t pgsize, size_t pgcount, int prot, gfp_t gfp,
size_t *mapped);
size_t (*unmap_pages)(struct iommu_domain *domain, unsigned long
iova, size_t pgsize, size_t pgcount, struct iommu_iotlb_gather
*iotlb_gather);
void (*flush_iotlb_all)(struct iommu_domain *domain);
int (*iotlb_sync_map)(struct iommu_domain *domain, unsigned long
iova, size_t size);
void (*iotlb_sync)(struct iommu_domain *domain, struct
iommu_iotlb_gather *iotlb_gather);
int (*cache_invalidate_user)(struct iommu_domain *domain, struct
iommu_user_data_array *array);
phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t
iova);
bool (*enforce_cache_coherency)(struct iommu_domain *domain);
int (*set_pgtable_quirks)(struct iommu_domain *domain, unsigned long
quirks);
void (*free)(struct iommu_domain *domain);
};
like, twelve function pointers, all vibing in one struct. it's a whole squad π«Ά
π¦ Members π¦
attach_devβ attaches an iommu domain to a device. matching-making, but for hardware πset_dev_pasidβ sets or replaces an iommu domain on a pasid of a device. one (1) important rule, no cap: if it errors out, the pasid of the device should be left in the old config. don't leave it in a half-changed limbo state, that's not the vibe πmap_pagesβ maps a physically contiguous set of pages, all the same size, onto an iommu domain. iconic.unmap_pagesβ unmaps a number (could be many!) of pages of the same size from an iommu domain. the reverse slay.flush_iotlb_allβ Synchronously flushes all the hardware TLBs for this domain. capital-S Synchronously, bestie, it waits.iotlb_sync_mapβ syncs mappings you created recently using map over to the hardware. π§iotlb_syncβ flushes all the queued ranges from the hardware TLBs and empties the flush queue. clearing the group chat energy.cache_invalidate_userβ flushes the hardware cache for the user space IO page table. ok so the deets:- the domain must be
IOMMU_DOMAIN_NESTED(this is not optional, it's a requirement π) - the array passes in the cache invalidation requests, in the form of a driver data structure
- the driver must update
array->entry_numto report the number of handled invalidation requests - the driver data structure must be defined in
include/uapi/linux/iommufd.h
- the domain must be
iova_to_physβ translatesiovato a physical address. glow-up but for addresses β¨enforce_cache_coherencyβ prevents any kind of DMA from bypassingIOMMU_CACHE. that includes no-snoop TLPs on PCIe, or any other platform specific mechanisms. it's a strict bouncer at the door πset_pgtable_quirksβ sets io page table quirks (IO_PGTABLE_QUIRK_*). quirky on purpose.freeβ releases the domain after use. clean up your room after the party π
π Return π
these are the return vibes, bestie β memorize them iykyk:
0β success πEINVALβ can indicate that the device and domain are incompatible because of some previous configuration of the domain. and in that case the driver shouldn't log an error, because it's totally legitimate for a caller to test reuse of existing domains (testing the waters is valid π ). otherwise, it may still represent some other fundamental problemENOMEMβ out of memory πENOSPCβ non-ENOMEMtype of resource allocation failuresEBUSYβ the device is attached to a domain and cannot be changed. locked in, literally.ENODEVβ device specific errors, not able to be attached π<others>β treated asENODEVby the caller. Use is discouraged. like, don't. fr fr.
π real talk: if you're returning something random and hoping the caller figures it out β it won't. it just becomes ENODEV. use the documented codes.
π₯ SEE ALSO π₯
Kernel file ./include/linux/iommu.h, plus the whole extended friend group:
struct iommu_fault_page_request(9), struct iommu_fault(9), enum iommu_page_response_code(9), struct iommu_page_response(9), struct iopf_queue(9), struct iommu_resv_region(9), struct iommu_iotlb_gather(9), struct iommu_dirty_bitmap(9), struct iommu_dirty_ops(9), struct iommu_user_data(9), struct iommu_user_data_array(9), __iommu_copy_struct_from_user(9), iommu_copy_struct_from_user(9), __iommu_copy_struct_from_user_array(9), iommu_copy_struct_from_user_array(9), iommu_copy_struct_from_full_user_array(9), __iommu_copy_struct_to_user(9), iommu_copy_struct_to_user(9), struct iommu_ops(9), struct iommu_device(9), struct iommu_fault_param(9), struct dev_iommu(9), iommu_iotlb_gather_is_disjoint(9), iommu_iotlb_gather_add_range(9), iommu_iotlb_gather_add_page(9), struct iommu_fwspec(9), struct iommu_sva(9), iommu_map_sgtable(9)
okay that's the whole page, you ate that π mwah π β this one lives in ./include/linux, dated October 2026, from the Kernel API Manual. go forth and attach your devices correctly, bestie. π¦π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms