From: Alexey Kardashevskiy <a...@ozlabs.ru>

[ Upstream commit 1282ba7fc28dbc66c3f0e4aaafaaa228361d1ae5 ]

The existing SPAPR TCE driver advertises both VFIO_SPAPR_TCE_IOMMU and
VFIO_SPAPR_TCE_v2_IOMMU types to the userspace and the userspace usually
picks the v2.

Normally the userspace would create a container, attach an IOMMU group
to it and only then set the IOMMU type (which would normally be v2).

However a specific IOMMU group may not support v2, in other words
it may not implement set_window/unset_window/take_ownership/
release_ownership and such a group should not be attached to
a v2 container.

This adds extra checks that a new group can do what the selected IOMMU
type suggests. The userspace can then test the return value from
ioctl(VFIO_SET_IOMMU, VFIO_SPAPR_TCE_v2_IOMMU) and try
VFIO_SPAPR_TCE_IOMMU.

Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru>
Signed-off-by: Alex Williamson <alex.william...@redhat.com>
Signed-off-by: Sasha Levin <alexander.le...@microsoft.com>
---
 drivers/vfio/vfio_iommu_spapr_tce.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c 
b/drivers/vfio/vfio_iommu_spapr_tce.c
index 59b3f62a2d64..87ad0d72d8a9 100644
--- a/drivers/vfio/vfio_iommu_spapr_tce.c
+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
@@ -1332,8 +1332,16 @@ static int tce_iommu_attach_group(void *iommu_data,
 
        if (!table_group->ops || !table_group->ops->take_ownership ||
                        !table_group->ops->release_ownership) {
+               if (container->v2) {
+                       ret = -EPERM;
+                       goto unlock_exit;
+               }
                ret = tce_iommu_take_ownership(container, table_group);
        } else {
+               if (!container->v2) {
+                       ret = -EPERM;
+                       goto unlock_exit;
+               }
                ret = tce_iommu_take_ownership_ddw(container, table_group);
                if (!tce_groups_attached(container) && !container->tables[0])
                        container->def_window_pending = true;
-- 
2.14.1

Reply via email to