STRUCT IOMMU_OPS(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’– struct iommu_ops πŸ’–

okay bestie, welcome to the Kernel API Manual β€” this is the page for struct iommu_ops(9), aka "iommu ops and capabilities", and honestly it's giving main-character energy in the IOMMU world πŸ‘‘


✨ NAME ✨

struct iommu_ops β€” iommu ops and capabilities. that's it, that's the whole vibe check πŸ¦‹


🌸 SYNOPSIS 🌸

here's the whole struct, laid out for you, no cap:

struct iommu_ops {
    bool (*capable)(struct device *dev, enum iommu_cap);
    void *(*hw_info)(struct device *dev, u32 *length, enum iommu_hw_info_type *type);
  #if IS_ENABLED(CONFIG_FSL_PAMU);
    struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
  #endif;
    struct iommu_domain *(*domain_alloc_identity)(struct device *dev);
    struct iommu_domain *(*domain_alloc_paging_flags)( struct device *dev, u32 flags, const struct iommu_user_data *user_data);
    struct iommu_domain *(*domain_alloc_paging)(struct device *dev);
    struct iommu_domain *(*domain_alloc_sva)(struct device *dev, struct mm_struct *mm);
    struct iommu_domain *(*domain_alloc_nested)( struct device *dev, struct iommu_domain *parent, u32 flags, const struct iommu_user_data *user_data);
    struct iommu_device *(*probe_device)(struct device *dev);
    void (*release_device)(struct device *dev);
    void (*probe_finalize)(struct device *dev);
    struct iommu_group *(*device_group)(struct device *dev);
    void (*get_resv_regions)(struct device *dev, struct list_head *list);
    int (*of_xlate)(struct device *dev, const struct of_phandle_args *args);
    bool (*is_attach_deferred)(struct device *dev);
    void (*page_response)(struct device *dev, struct iopf_fault *evt, struct iommu_page_response *msg);
    int (*def_domain_type)(struct device *dev);
    size_t (*get_viommu_size)(struct device *dev, enum iommu_viommu_type viommu_type);
    int (*viommu_init)(struct iommufd_viommu *viommu, struct iommu_domain *parent_domain, const struct iommu_user_data *user_data);
    const struct iommu_domain_ops *default_domain_ops;
    struct module *owner;
    struct iommu_domain *identity_domain;
    struct iommu_domain *blocked_domain;
    struct iommu_domain *release_domain;
    struct iommu_domain *default_domain;
    u8 user_pasid_table:1;
 };

πŸ’… MEMBERS πŸ’…

okay so now we go through every single field, one by one, because we do not skip πŸ’€

  • capable β€” check capability πŸ”
  • hw_info β€” report iommu hardware information. The data buffer returned by this op is allocated in the iommu driver and freed by the caller after use. type can input a requested type and output a supported type. Driver should reject an unsupported data type input πŸ™…β€β™€οΈ
  • domain_alloc β€” Do not use in new drivers ⚠️ like, seriously, don't
  • domain_alloc_identity β€” allocate an IDENTITY domain. Drivers should prefer to use identity_domain instead. This should only be used if dynamic logic is necessary πŸŒ€
  • domain_alloc_paging_flags β€” Allocate an iommu domain corresponding to the input parameters as defined in include/uapi/linux/iommufd.h. The user_data can be optionally provided, the new domain must support __IOMMU_DOMAIN_PAGING. Upon failure, ERR_PTR must be returned 🫢
  • domain_alloc_paging β€” Allocate an iommu_domain that can be used for UNMANAGED, DMA, and DMA_FQ domain types. This is the same as invoking domain_alloc_paging_flags with flags=0, user_data=NULL. A driver should implement only one of the two ops πŸ‘―β€β™€οΈ (pick one, bestie, not both)
  • domain_alloc_sva β€” Allocate an iommu_domain for Shared Virtual Addressing 🌈
  • domain_alloc_nested β€” Allocate an iommu_domain for nested translation πŸͺ†
  • probe_device β€” Add device to iommu driver handling βž•
  • release_device β€” Remove device from iommu driver handling βž–
  • probe_finalize β€” Do final setup work after the device is added to an IOMMU group and attached to the groups domain πŸŽ€
  • device_group β€” find iommu group for a particular device πŸ”Ž
  • get_resv_regions β€” Request list of reserved regions for a device πŸ“‹
  • of_xlate β€” add OF master IDs to iommu grouping 🌳
  • is_attach_deferred β€” Check if domain attach should be deferred from iommu driver init to device driver init (default no) ⏳
  • page_response β€” handle page request response πŸ“¨
  • def_domain_type β€” device default domain type, return value:
    • IOMMU_DOMAIN_IDENTITY: must use an identity domain
    • IOMMU_DOMAIN_DMA: must use a dma domain
    • 0: use the default setting
  • get_viommu_size β€” Get the size of a driver-level vIOMMU structure for a given dev corresponding to viommu_type. Driver should return 0 if vIOMMU isn't supported accordingly. It is required for driver to use the VIOMMU_STRUCT_SIZE macro to sanitize the driver-level vIOMMU structure related to the core one πŸ“
  • viommu_init β€” Init the driver-level struct of an iommufd_viommu on a physical IOMMU instance viommu->iommu_dev, as the set of virtualization resources shared/passed to user space IOMMU instance. Associate it with a nesting parent_domain. It is required for driver to set viommu->ops pointing to its own viommu_ops 🧚
  • default_domain_ops β€” the default ops for domains 🧬
  • owner β€” Driver module providing these ops πŸ“¦
  • identity_domain β€” An always available, always attachable identity translation ✨
  • blocked_domain β€” An always available, always attachable blocking translation 🚫
  • default_domain β€” If not NULL this will always be set as the default domain. This should be an IDENTITY/BLOCKED/PLATFORM domain. Do not use in new drivers. ⚠️ (yes, another one of those)
  • user_pasid_table β€” IOMMU driver supports user-managed PASID table. There is no user domain for each PASID and the I/O page faults are forwarded through the user domain attached to the device RID πŸ—‚οΈ
fr fr, if you're writing a new driver and you reach for domain_alloc or default_domain, read the line above again. it's literally telling you not to πŸ™ˆ

πŸ‘‘ SEE ALSO πŸ‘‘

go read these next, bestie, they're all in the Kernel file ./include/linux/iommu.h:

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_domain_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)


aaaaand that's the page, you ate that πŸ’… this whole thing lives over in ./include/linux, dated October 2026, and it's filed under struct iommu_ops(9) in the Kernel API Manual β€” mwah, slay, go write a driver now πŸ«ΆπŸ’–β­

πŸ“¦ where this page comes from