STRUCT IOMMU_HWPT_ALLOC(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… struct iommu_hwpt_alloc β€” from the Kernel API Manual, section 9 πŸŽ€

okay bestie, sit down, hydrate, and let me tell you about struct iommu_hwpt_alloc, aka the shape you pass into the ioctl(IOMMU_HWPT_ALLOC) call. it's giving "let me make you a hardware page table" and honestly? iconic. ✨


🌸 SYNOPSIS 🌸

like, literally this exact struct, no notes:

struct iommu_hwpt_alloc {
    __u32 size;
    __u32 flags;
    __u32 dev_id;
    __u32 pt_id;
    __u32 out_hwpt_id;
    __u32 __reserved;
    __u32 data_type;
    __u32 data_len;
    __aligned_u64 data_uptr;
    __u32 fault_id;
    __u32 __reserved2;
 };

πŸ¦‹ Members πŸ¦‹

so every field has a job and they ALL ate:

  • size β€” it's sizeof(struct iommu_hwpt_alloc). yes queen, tell the kernel how big you are. πŸ’–
  • flags β€” a combo of enum iommufd_hwpt_alloc_flags. mix and match, slay.
  • dev_id β€” the device you're allocating this HWPT for. like, whose HWPT is it anyway? πŸ”₯
  • pt_id β€” the IOAS or HWPT or vIOMMU you're connecting this HWPT to. the link-up. the situationship.
  • out_hwpt_id β€” the ID of the brand-new HWPT. the output, the main character. πŸ‘‘
  • __reserved β€” must be 0. no cap, just zero. πŸ’€
  • data_type β€” one of enum iommu_hwpt_data_type. pick your flavor.
  • data_len β€” length of the type-specific data. how much data? this much. πŸ“
  • data_uptr β€” user pointer to the type-specific data. point at it, bestie. 🫢
  • fault_id β€” the ID of the IOMMUFD_FAULT object. it's only valid if the flags field has IOMMU_HWPT_FAULT_ID_VALID set, so don't get cute with it. ⭐
  • __reserved2 β€” padding to 64-bit alignment. must be 0. that's it. that's the whole vibe check. πŸ™ˆ

✨ Description ✨

okay so the whole point: this explicitly allocates a hardware page table object. and get this β€” it's the same object type that iommufd_device_attach returns, and it represents the underlying iommu driver's iommu_domain kernel object. same energy, different door. πŸšͺ

Here's the tea on how you actually make one:

A kernel-managed HWPT gets created with the mappings from the given IOAS via the pt_id. For this kind of allocation, data_type must be set to IOMMU_HWPT_DATA_NONE. and if you want it as a parent HWPT for a nesting configuration? just pass IOMMU_HWPT_ALLOC_NEST_PARENT via flags and you're so back. πŸŽ€

A user-managed nested HWPT gets created from a given vIOMMU (which wraps a parent HWPT) or a parent HWPT via pt_id β€” and lowkey important: that parent HWPT must have been allocated previously, via this same ioctl, from a given IOAS (that's your pt_id again). in this case, data_type must be set to a pre-defined type corresponding to an I/O page table type supported by the underlying IOMMU hardware. hardware said "this is what I support," so pick from that list, bestie. πŸ’…

also, the device via dev_id and the vIOMMU via pt_id must be associated to the same IOMMU instance. same instance or it's not happening, fr fr. 😭

⚠️ and here's the rule that will humble you: if data_type is set to IOMMU_HWPT_DATA_NONE, then data_len and data_uptr should be zero. otherwise, both data_len and data_uptr must be given. no half-sending, no ghosting one field. πŸ’€

🌈 SEE ALSO 🌈

  • 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)
  • 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_hw_info(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)

like I said. read. them. all. iykyk πŸ“šπŸ’œ


anyway that's the whole page 🫢 this one lives in ./include/uapi/linux, dated October 2026, and it's filed under struct iommu_hwpt_alloc(9) β€” go forth and allocate responsibly, bestie πŸ’–βœ¨

πŸ“¦ where this page comes from