20
#include "trace.h"
21
#include "qapi/error.h"
22
#include "system/iommufd.h"
23
+#include "hw/core/iommu.h"
24
#include "hw/core/qdev.h"
25
#include "hw/vfio/vfio-cpr.h"
26
#include "system/reset.h"
306
return ret;
307
}
308
308
-static int iommufd_cdev_attach_ioas_hwpt(VFIODevice *vbasedev, uint32_t id,
309
- Error **errp)
309
+static int iommufd_cdev_pasid_attach_ioas_hwpt(VFIODevice *vbasedev,
310
+ uint32_t pasid, uint32_t id,
311
+ Error **errp)
312
{
313
int iommufd = vbasedev->iommufd->fd;
314
struct vfio_device_attach_iommufd_pt attach_data = {
315
.argsz = sizeof(attach_data),
314
- .flags = 0,
316
+ .flags = pasid == IOMMU_NO_PASID ? 0 : VFIO_DEVICE_ATTACH_PASID,
317
+ .pasid = pasid,
318
.pt_id = id,
319
};
320
321
/* Attach device to an IOAS or hwpt within iommufd */
322
if (ioctl(vbasedev->fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT, &attach_data)) {
323
error_setg_errno(errp, errno,
321
- "[iommufd=%d] error attach %s (%d) to id=%d",
322
- iommufd, vbasedev->name, vbasedev->fd, id);
324
+ "[iommufd=%d] error attach %s (%d) pasid %d to id=%d",
325
+ iommufd, vbasedev->name, vbasedev->fd, pasid, id);
326
return -errno;
327
}
328
326
- trace_iommufd_cdev_attach_ioas_hwpt(iommufd, vbasedev->name,
327
- vbasedev->fd, id);
329
+ trace_iommufd_cdev_pasid_attach_ioas_hwpt(iommufd, vbasedev->name,
330
+ vbasedev->fd, pasid, id);
331
return 0;
332
}
333
331
-static bool iommufd_cdev_detach_ioas_hwpt(VFIODevice *vbasedev, Error **errp)
334
+static bool iommufd_cdev_pasid_detach_ioas_hwpt(VFIODevice *vbasedev,
335
+ uint32_t pasid, Error **errp)
336
{
337
int iommufd = vbasedev->iommufd->fd;
338
struct vfio_device_detach_iommufd_pt detach_data = {
339
.argsz = sizeof(detach_data),
336
- .flags = 0,
340
+ .flags = pasid == IOMMU_NO_PASID ? 0 : VFIO_DEVICE_DETACH_PASID,
341
+ .pasid = pasid,
342
};
343
344
if (ioctl(vbasedev->fd, VFIO_DEVICE_DETACH_IOMMUFD_PT, &detach_data)) {
340
- error_setg_errno(errp, errno, "detach %s failed", vbasedev->name);
345
+ error_setg_errno(errp, errno, "detach %s pasid %d failed",
346
+ vbasedev->name, pasid);
347
return false;
348
}
349
344
- trace_iommufd_cdev_detach_ioas_hwpt(iommufd, vbasedev->name);
350
+ trace_iommufd_cdev_pasid_detach_ioas_hwpt(iommufd, vbasedev->name, pasid);
351
return true;
352
}
353
369
/* Try to find a domain */
370
QLIST_FOREACH(hwpt, &container->hwpt_list, next) {
371
if (!cpr_is_incoming()) {
366
- ret = iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt->hwpt_id, errp);
372
+ ret = iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
373
+ hwpt->hwpt_id, errp);
374
} else if (vbasedev->cpr.hwpt_id == hwpt->hwpt_id) {
375
ret = 0;
376
} else {
449
return false;
450
}
451
445
- ret = iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt_id, errp);
452
+ ret = iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID, hwpt_id,
453
+ errp);
454
if (ret) {
455
iommufd_backend_free_id(container->be, hwpt_id);
456
return false;
503
504
/* If CPR, we are already attached to ioas_id. */
505
return cpr_is_incoming() ||
498
- !iommufd_cdev_attach_ioas_hwpt(vbasedev, container->ioas_id, errp);
506
+ !iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
507
+ container->ioas_id, errp);
508
}
509
510
static void iommufd_cdev_detach_container(VFIODevice *vbasedev,
512
{
513
Error *err = NULL;
514
506
- if (!iommufd_cdev_detach_ioas_hwpt(vbasedev, &err)) {
515
+ if (!iommufd_cdev_pasid_detach_ioas_hwpt(vbasedev, IOMMU_NO_PASID, &err)) {
516
error_report_err(err);
517
}
518
938
{
939
VFIODevice *vbasedev = HOST_IOMMU_DEVICE(hiodi)->agent;
940
932
- return !iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt_id, errp);
941
+ return !iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
942
+ hwpt_id, errp);
943
}
944
945
static bool
948
{
949
VFIODevice *vbasedev = HOST_IOMMU_DEVICE(hiodi)->agent;
950
941
- return iommufd_cdev_detach_ioas_hwpt(vbasedev, errp);
951
+ return iommufd_cdev_pasid_detach_ioas_hwpt(vbasedev, IOMMU_NO_PASID, errp);
952
}
953
954
static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,