STRUCT IOMMU_HW_INFO(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… struct iommu_hw_info β€” NAME

okay so bestie, this is the manual page for struct iommu_hw_info, and it's literally the struct behind ioctl(IOMMU_GET_HW_INFO). yes THAT ioctl. she's the one who goes and asks the iommu "hey queen, what are your hardware vibes?" πŸŽ€

(also hi, this is from the Kernel API Manual, more on that at the very bottom 🫢)


✨ SYNOPSIS ✨

here's the struct in all her glory, copy it exactly bestie, don't freehand this:

struct iommu_hw_info {
    __u32 size;
    __u32 flags;
    __u32 dev_id;
    __u32 data_len;
    __aligned_u64 data_uptr;
    union {
      __u32 in_data_type;
      __u32 out_data_type;
    };
    __u8 out_max_pasid_log2;
    __u8 __reserved[3];
    __aligned_u64 out_capabilities;
 };

🌸 Members 🌸

every field, one by one, no skipping, we don't do that here πŸ’–

  • size β€” this is sizeof(struct iommu_hw_info). that's it. that's the field. iconic honestly.
  • flags β€” must be 0. not 1, not "eh close enough". zero. 🚨
  • dev_id β€” the device that's bound to the iommufd. the main character device, if you will πŸ‘‘
  • data_len β€” bidirectional bestie πŸ’«. as input, it's the length in bytes of your user buffer. as output, it's the length of data that the kernel actually supports.
  • data_uptr β€” a user pointer to a user-space buffer, and the kernel uses it to fill in the iommu type specific hardware information data. it's giving "you bring the cup, kernel brings the tea" πŸ“
  • {unnamed_union} β€” anonymous. she has no name. she simply exists. πŸ¦‹
    • in_data_type β€” plot twist: this shares the same field with out_data_type, so it's a bidirectional field πŸ”. when IOMMU_HW_INFO_FLAG_INPUT_TYPE is set, an input type carried via this in_data_type field is valid, and it's requesting the info data for that given type. if IOMMU_HW_INFO_FLAG_INPUT_TYPE is unset, then any input value gets treated as IOMMU_HW_INFO_TYPE_DEFAULT. so like, no pressure on the input value in that case πŸ’€
    • out_data_type β€” outputs the iommu hardware info type, as defined in the enum iommu_hw_info_type. this is the "which flavor is this" field 🍦
  • out_max_pasid_log2 β€” outputs the width of PASIDs. 0 means no PASID support, periodt. ⚠️ and heads up: PCI devices should turn to out_capabilities to check whether a specific capability is supported or not.
  • __reserved β€” must be 0. again. zero. do not get creative with the reserved bytes, bestie, that's how you end up in the group chat at 3am 😭
  • out_capabilities β€” outputs the generic iommu capability info type, as defined in the enum iommu_hw_capabilities. the receipts of what she can do ✨

πŸ¦‹ Description πŸ¦‹

so what does this thing actually do. okay so: it queries iommu type specific hardware information data from an iommu that sits behind a given device which has been bound to iommufd. that hardware info data gets used to sync capabilities between the virtual iommu and the physical iommu β€” like, for example, a nested translation setup needs to check the hardware info so that a guest stage-1 page table can be compatible with the physical iommu. it's literally matchmaking between virtual and physical, and honestly? they slay together πŸ’…

to actually capture that iommu type specific hardware information data, data_uptr and its length data_len must be provided. no buffer, no data, no cap 🧒

here's the deets on sizes, and this part matters so read it properly:

  • if your user buffer is larger than the data the kernel has, the trailing bytes will be zeroed. thoughtful queen.
  • otherwise, the kernel only fills the buffer using the given length in data_len.

if the ioctl succeeds, then:

  1. data_len gets updated to the length that the kernel actually supports, and
  2. out_data_type gets filled in, so you can decode the data that got filled into the buffer pointed to by data_uptr.

also, input data_len == zero is allowed. yes really. zero is a valid input. she said "I'll allow it" πŸŽ€


πŸ”₯ SEE ALSO πŸ”₯

the whole extended friend group, in order, all of them, we're not leaving anyone out of the group chat πŸ’œ

  • Kernel file ./include/uapi/linux/iommufd.h
  • General ioctl format(9)
  • struct iommu_destroy(9)
  • struct iommu_ioas_alloc(9)
  • struct iommu_iova_range(9)
  • struct iommu_ioas_iova_ranges(9)
  • struct iommu_ioas_allow_iovas(9)
  • enum iommufd_ioas_map_flags(9)
  • struct iommu_ioas_map(9)
  • struct iommu_ioas_noiommu_get_pa(9)
  • struct iommu_ioas_map_file(9)
  • struct iommu_ioas_copy(9)
  • struct iommu_ioas_unmap(9)
  • enum iommufd_option(9)
  • enum iommufd_option_ops(9)
  • struct iommu_option(9)
  • enum iommufd_vfio_ioas_op(9)
  • struct iommu_vfio_ioas(9)
  • enum iommufd_hwpt_alloc_flags(9)
  • enum iommu_hwpt_vtd_s1_flags(9)
  • struct iommu_hwpt_vtd_s1(9)
  • struct iommu_hwpt_arm_smmuv3(9)
  • struct iommu_hwpt_amd_guest(9)
  • enum iommu_hwpt_data_type(9)
  • struct iommu_hwpt_alloc(9)
  • enum iommu_hw_info_vtd_flags(9)
  • struct iommu_hw_info_vtd(9)
  • enum iommu_hw_info_arm_smmuv3_flags(9)
  • struct iommu_hw_info_arm_smmuv3(9)
  • struct iommu_hw_info_tegra241_cmdqv(9)
  • struct iommu_hw_info_amd(9)
  • enum iommu_hw_info_type(9)
  • enum iommufd_hw_capabilities(9)
  • enum iommufd_hw_info_flags(9)
  • struct iommu_hwpt_set_dirty_tracking(9)
  • enum iommufd_hwpt_get_dirty_bitmap_flags(9)
  • struct iommu_hwpt_get_dirty_bitmap(9)
  • enum iommu_hwpt_invalidate_data_type(9)
  • enum iommu_hwpt_vtd_s1_invalidate_flags(9)
  • struct iommu_hwpt_vtd_s1_invalidate(9)
  • struct iommu_viommu_arm_smmuv3_invalidate(9)
  • struct iommu_hwpt_invalidate(9)
  • enum iommu_hwpt_pgfault_flags(9)
  • enum iommu_hwpt_pgfault_perm(9)
  • struct iommu_hwpt_pgfault(9)
  • enum iommufd_page_response_code(9)
  • struct iommu_hwpt_page_response(9)
  • struct iommu_fault_alloc(9)
  • enum iommu_viommu_type(9)
  • struct iommu_viommu_tegra241_cmdqv(9)
  • struct iommu_viommu_alloc(9)
  • struct iommu_vdevice_alloc(9)
  • struct iommu_ioas_change_process(9)
  • enum iommu_veventq_flag(9)
  • struct iommufd_vevent_header(9)
  • enum iommu_veventq_type(9)
  • struct iommu_vevent_arm_smmuv3(9)
  • struct iommu_vevent_tegra241_cmdqv(9)
  • struct iommu_veventq_alloc(9)
  • enum iommu_hw_queue_type(9)
  • struct iommu_hw_queue_alloc(9)

and that's the whole page bestie, you ate that 🫢✨

source things for the record: this one lives under ./include/uapi/linux, and the version/date situation is October 2026. go forth and query your hardware info, you got this πŸ’–πŸŽ€

πŸ“¦ where this page comes from