iommufd: Extend attach/detach_hwpt callbacks to support pasid
Same for the two wrappers and their call sites. Suggested-by: Shameer Kolothum Thodi <skolothumtho@nvidia.com> Suggested-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Reviewed-by: Yi Liu <yi.l.liu@intel.com> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com> Tested-by: Xudong Hao <xudong.hao@intel.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20260527054658.1021096-3-zhenzhong.duan@intel.com>
Zhenzhong Duan committed
May 27, 2026 at 01:46 UTC
20fb2f6961f847392bdbc26f85017a73570af0b5
5 files changed
+40
-28
backends/iommufd.c
+5
-4
@@ -539,23 +539,24 @@ bool iommufd_backend_alloc_veventq(IOMMUFDBackend *be, uint32_t viommu_id,
539
}
540
541
bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
542
- uint32_t hwpt_id, Error **errp)
542
+ uint32_t pasid, uint32_t hwpt_id,
543
+ Error **errp)
544
{
545
HostIOMMUDeviceIOMMUFDClass *hiodic =
546
HOST_IOMMU_DEVICE_IOMMUFD_GET_CLASS(hiodi);
547
548
g_assert(hiodic->attach_hwpt);
548
- return hiodic->attach_hwpt(hiodi, hwpt_id, errp);
549
+ return hiodic->attach_hwpt(hiodi, pasid, hwpt_id, errp);
550
}
551
552
bool host_iommu_device_iommufd_detach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
552
- Error **errp)
553
+ uint32_t pasid, Error **errp)
554
{
555
HostIOMMUDeviceIOMMUFDClass *hiodic =
556
HOST_IOMMU_DEVICE_IOMMUFD_GET_CLASS(hiodi);
557
558
g_assert(hiodic->detach_hwpt);
558
- return hiodic->detach_hwpt(hiodi, errp);
559
+ return hiodic->detach_hwpt(hiodi, pasid, errp);
560
}
561
562
static int hiod_iommufd_get_cap(HostIOMMUDevice *hiod, int cap, Error **errp)
hw/arm/smmuv3-accel.c
+8
-4
@@ -300,7 +300,8 @@ bool smmuv3_accel_install_ste(SMMUv3State *s, SMMUDevice *sdev, int sid,
300
return false;
301
}
302
303
- if (!host_iommu_device_iommufd_attach_hwpt(hiodi, hwpt_id, errp)) {
303
+ if (!host_iommu_device_iommufd_attach_hwpt(hiodi, IOMMU_NO_PASID, hwpt_id,
304
+ errp)) {
305
if (s1_hwpt) {
306
iommufd_backend_free_id(hiodi->iommufd, s1_hwpt->hwpt_id);
307
g_free(s1_hwpt);
@@ -575,7 +576,8 @@ smmuv3_accel_alloc_viommu(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *hiodi,
576
577
/* Attach a HWPT based on SMMUv3 GBPA.ABORT value */
578
hwpt_id = smmuv3_accel_gbpa_hwpt(s, accel);
578
- if (!host_iommu_device_iommufd_attach_hwpt(hiodi, hwpt_id, errp)) {
579
+ if (!host_iommu_device_iommufd_attach_hwpt(hiodi, IOMMU_NO_PASID, hwpt_id,
580
+ errp)) {
581
goto free_veventq;
582
}
583
return true;
@@ -665,7 +667,8 @@ static void smmuv3_accel_unset_iommu_device(PCIBus *bus, void *opaque,
667
hiodi = accel_dev->hiodi;
668
accel = accel_dev->s_accel;
669
/* Re-attach the default s2 hwpt id */
668
- if (!host_iommu_device_iommufd_attach_hwpt(hiodi, hiodi->hwpt_id, NULL)) {
670
+ if (!host_iommu_device_iommufd_attach_hwpt(hiodi, IOMMU_NO_PASID,
671
+ hiodi->hwpt_id, NULL)) {
672
error_report("Unable to attach the default HW pagetable: hiodi devid "
673
"0x%x", hiodi->devid);
674
}
@@ -879,7 +882,8 @@ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, Error **errp)
882
883
hwpt_id = smmuv3_accel_gbpa_hwpt(s, accel);
884
QLIST_FOREACH(accel_dev, &accel->device_list, next) {
882
- if (!host_iommu_device_iommufd_attach_hwpt(accel_dev->hiodi, hwpt_id,
885
+ if (!host_iommu_device_iommufd_attach_hwpt(accel_dev->hiodi,
886
+ IOMMU_NO_PASID, hwpt_id,
887
&local_err)) {
888
error_append_hint(&local_err, "Failed to attach GBPA hwpt %u for "
889
"hiodi devid %u", hwpt_id,
hw/i386/intel_iommu_accel.c
+10
-9
@@ -121,8 +121,9 @@ static bool vtd_device_attach_iommufd(VTDHostIOMMUDevice *vtd_hiod,
121
}
122
}
123
124
- ret = host_iommu_device_iommufd_attach_hwpt(hiodi, hwpt_id, errp);
125
- trace_vtd_device_attach_hwpt(hiodi->devid, vtd_as->pasid, hwpt_id, ret);
124
+ ret = host_iommu_device_iommufd_attach_hwpt(hiodi, IOMMU_NO_PASID, hwpt_id,
125
+ errp);
126
+ trace_vtd_device_attach_hwpt(hiodi->devid, IOMMU_NO_PASID, hwpt_id, ret);
127
if (ret) {
128
/* Destroy old fs_hwpt if it's a replacement */
129
vtd_destroy_old_fs_hwpt(hiodi, vtd_as);
@@ -141,22 +142,22 @@ static bool vtd_device_detach_iommufd(VTDHostIOMMUDevice *vtd_hiod,
142
{
143
HostIOMMUDeviceIOMMUFD *hiodi = HOST_IOMMU_DEVICE_IOMMUFD(vtd_hiod->hiod);
144
IntelIOMMUState *s = vtd_as->iommu_state;
144
- uint32_t pasid = vtd_as->pasid;
145
bool ret;
146
147
if (s->dmar_enabled && s->root_scalable) {
148
- ret = host_iommu_device_iommufd_detach_hwpt(hiodi, errp);
149
- trace_vtd_device_detach_hwpt(hiodi->devid, pasid, ret);
148
+ ret = host_iommu_device_iommufd_detach_hwpt(hiodi, IOMMU_NO_PASID,
149
+ errp);
150
+ trace_vtd_device_detach_hwpt(hiodi->devid, IOMMU_NO_PASID, ret);
151
} else {
152
/*
153
* If DMAR remapping is disabled or guest switches to legacy mode,
154
* we fallback to the default HWPT which contains shadow page table.
155
* So guest DMA could still work.
156
*/
156
- ret = host_iommu_device_iommufd_attach_hwpt(hiodi, hiodi->hwpt_id,
157
- errp);
158
- trace_vtd_device_reattach_def_hwpt(hiodi->devid, pasid, hiodi->hwpt_id,
159
- ret);
157
+ ret = host_iommu_device_iommufd_attach_hwpt(hiodi, IOMMU_NO_PASID,
158
+ hiodi->hwpt_id, errp);
159
+ trace_vtd_device_reattach_def_hwpt(hiodi->devid, IOMMU_NO_PASID,
160
+ hiodi->hwpt_id, ret);
161
}
162
163
if (ret) {
hw/vfio/iommufd.c
+5
-5
@@ -934,21 +934,21 @@ static void vfio_iommu_iommufd_class_init(ObjectClass *klass, const void *data)
934
935
static bool
936
host_iommu_device_iommufd_vfio_attach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
937
- uint32_t hwpt_id, Error **errp)
937
+ uint32_t pasid, uint32_t hwpt_id,
938
+ Error **errp)
939
{
940
VFIODevice *vbasedev = HOST_IOMMU_DEVICE(hiodi)->agent;
941
941
- return !iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
942
- hwpt_id, errp);
942
+ return !iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, pasid, hwpt_id, errp);
943
}
944
945
static bool
946
host_iommu_device_iommufd_vfio_detach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
947
- Error **errp)
947
+ uint32_t pasid, Error **errp)
948
{
949
VFIODevice *vbasedev = HOST_IOMMU_DEVICE(hiodi)->agent;
950
951
- return iommufd_cdev_pasid_detach_ioas_hwpt(vbasedev, IOMMU_NO_PASID, errp);
951
+ return iommufd_cdev_pasid_detach_ioas_hwpt(vbasedev, pasid, errp);
952
}
953
954
static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,
include/system/iommufd.h
+12
-6
@@ -138,14 +138,16 @@ struct HostIOMMUDeviceIOMMUFDClass {
138
*
139
* @hiodi: host IOMMU device backed by IOMMUFD backend.
140
*
141
+ * @pasid: target pasid of the device to be attached.
142
+ *
143
* @hwpt_id: ID of IOMMUFD hardware page table.
144
*
145
* @errp: pass an Error out when attachment fails.
146
*
147
* Returns: true on success, false on failure.
148
*/
147
- bool (*attach_hwpt)(HostIOMMUDeviceIOMMUFD *hiodi, uint32_t hwpt_id,
148
- Error **errp);
149
+ bool (*attach_hwpt)(HostIOMMUDeviceIOMMUFD *hiodi, uint32_t pasid,
150
+ uint32_t hwpt_id, Error **errp);
151
/**
152
* @detach_hwpt: detach host IOMMU device from IOMMUFD hardware page table.
153
* VFIO and VDPA device can have different implementation.
@@ -154,15 +156,19 @@ struct HostIOMMUDeviceIOMMUFDClass {
156
*
157
* @hiodi: host IOMMU device backed by IOMMUFD backend.
158
*
157
- * @errp: pass an Error out when attachment fails.
159
+ * @pasid: target pasid of the device to be detached.
160
+ *
161
+ * @errp: pass an Error out when detachment fails.
162
*
163
* Returns: true on success, false on failure.
164
*/
161
- bool (*detach_hwpt)(HostIOMMUDeviceIOMMUFD *hiodi, Error **errp);
165
+ bool (*detach_hwpt)(HostIOMMUDeviceIOMMUFD *hiodi, uint32_t pasid,
166
+ Error **errp);
167
};
168
169
bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
165
- uint32_t hwpt_id, Error **errp);
166
-bool host_iommu_device_iommufd_detach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
170
+ uint32_t pasid, uint32_t hwpt_id,
171
Error **errp);
172
+bool host_iommu_device_iommufd_detach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
173
+ uint32_t pasid, Error **errp);
174
#endif