* [PATCH v4 1/5] vfio: Do not allow !ops->dma_unmap in vfio_pin/unpin_pages()
2023-03-08 14:25 [PATCH v4 0/5] Add IO page table replacement support Nicolin Chen
@ 2023-03-08 14:25 ` Nicolin Chen
2023-03-10 20:14 ` Jason Gunthorpe
2023-03-08 14:25 ` [PATCH v4 2/5] iommufd/selftest: Add IOMMU_TEST_OP_ACCESS_SET_IOAS coverage Nicolin Chen
` (3 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Nicolin Chen @ 2023-03-08 14:25 UTC (permalink / raw)
To: jgg, kevin.tian, joro, will, robin.murphy, alex.williamson, shuah
Cc: yi.l.liu, linux-kernel, iommu, kvm, linux-kselftest, mjrosato,
farman
A driver that doesn't implement ops->dma_unmap shouldn't be allowed to do
vfio_pin/unpin_pages(), though it can use vfio_dma_rw() to access an iova
range. Deny !ops->dma_unmap cases in vfio_pin/unpin_pages().
Suggested-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Yi Liu <yi.l.liu@intel.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/vfio/vfio_main.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index e5f4738692ac..32ea7cea1236 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -1522,6 +1522,8 @@ int vfio_pin_pages(struct vfio_device *device, dma_addr_t iova,
/* group->container cannot change while a vfio device is open */
if (!pages || !npage || WARN_ON(!vfio_assert_device_open(device)))
return -EINVAL;
+ if (!device->ops->dma_unmap)
+ return -EINVAL;
if (vfio_device_has_container(device))
return vfio_device_container_pin_pages(device, iova,
npage, prot, pages);
@@ -1559,6 +1561,8 @@ void vfio_unpin_pages(struct vfio_device *device, dma_addr_t iova, int npage)
{
if (WARN_ON(!vfio_assert_device_open(device)))
return;
+ if (WARN_ON(!device->ops->dma_unmap))
+ return;
if (vfio_device_has_container(device)) {
vfio_device_container_unpin_pages(device, iova, npage);
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v4 1/5] vfio: Do not allow !ops->dma_unmap in vfio_pin/unpin_pages()
2023-03-08 14:25 ` [PATCH v4 1/5] vfio: Do not allow !ops->dma_unmap in vfio_pin/unpin_pages() Nicolin Chen
@ 2023-03-10 20:14 ` Jason Gunthorpe
0 siblings, 0 replies; 14+ messages in thread
From: Jason Gunthorpe @ 2023-03-10 20:14 UTC (permalink / raw)
To: Nicolin Chen
Cc: kevin.tian, joro, will, robin.murphy, alex.williamson, shuah,
yi.l.liu, linux-kernel, iommu, kvm, linux-kselftest, mjrosato,
farman
On Wed, Mar 08, 2023 at 06:25:58AM -0800, Nicolin Chen wrote:
> A driver that doesn't implement ops->dma_unmap shouldn't be allowed to do
> vfio_pin/unpin_pages(), though it can use vfio_dma_rw() to access an iova
> range. Deny !ops->dma_unmap cases in vfio_pin/unpin_pages().
>
> Suggested-by: Kevin Tian <kevin.tian@intel.com>
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> Reviewed-by: Yi Liu <yi.l.liu@intel.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
> drivers/vfio/vfio_main.c | 4 ++++
> 1 file changed, 4 insertions(+)
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 2/5] iommufd/selftest: Add IOMMU_TEST_OP_ACCESS_SET_IOAS coverage
2023-03-08 14:25 [PATCH v4 0/5] Add IO page table replacement support Nicolin Chen
2023-03-08 14:25 ` [PATCH v4 1/5] vfio: Do not allow !ops->dma_unmap in vfio_pin/unpin_pages() Nicolin Chen
@ 2023-03-08 14:25 ` Nicolin Chen
2023-03-10 20:15 ` Jason Gunthorpe
2023-03-08 14:26 ` [PATCH v4 3/5] iommufd: Add replace support in iommufd_access_set_ioas() Nicolin Chen
` (2 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Nicolin Chen @ 2023-03-08 14:25 UTC (permalink / raw)
To: jgg, kevin.tian, joro, will, robin.murphy, alex.williamson, shuah
Cc: yi.l.liu, linux-kernel, iommu, kvm, linux-kselftest, mjrosato,
farman
Add a new IOMMU_TEST_OP_ACCESS_SET_IOAS to allow setting access->ioas
individually, corresponding to the iommufd_access_set_ioas() helper.
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/iommufd_test.h | 4 +++
drivers/iommu/iommufd/selftest.c | 26 +++++++++++++++----
tools/testing/selftests/iommu/iommufd_utils.h | 22 ++++++++++++++--
3 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/iommufd_test.h
index dd9168a20ddf..da1898a9128f 100644
--- a/drivers/iommu/iommufd/iommufd_test.h
+++ b/drivers/iommu/iommufd/iommufd_test.h
@@ -18,6 +18,7 @@ enum {
IOMMU_TEST_OP_ACCESS_RW,
IOMMU_TEST_OP_SET_TEMP_MEMORY_LIMIT,
IOMMU_TEST_OP_MOCK_DOMAIN_REPLACE,
+ IOMMU_TEST_OP_ACCESS_SET_IOAS,
};
enum {
@@ -91,6 +92,9 @@ struct iommu_test_cmd {
struct {
__u32 limit;
} memory_limit;
+ struct {
+ __u32 ioas_id;
+ } access_set_ioas;
};
__u32 last;
};
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index 60f21bb3f3d4..d7832ffc3aa6 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -732,7 +732,7 @@ static struct selftest_access *iommufd_test_alloc_access(void)
}
static int iommufd_test_create_access(struct iommufd_ucmd *ucmd,
- unsigned int ioas_id, unsigned int flags)
+ unsigned int flags)
{
struct iommu_test_cmd *cmd = ucmd->cmd;
struct selftest_access *staccess;
@@ -764,9 +764,6 @@ static int iommufd_test_create_access(struct iommufd_ucmd *ucmd,
rc = PTR_ERR(access);
goto out_put_fdno;
}
- rc = iommufd_access_set_ioas(access, ioas_id);
- if (rc)
- goto out_destroy;
cmd->create_access.out_access_fd = fdno;
rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
if (rc)
@@ -785,6 +782,22 @@ static int iommufd_test_create_access(struct iommufd_ucmd *ucmd,
return rc;
}
+static int iommufd_test_access_set_ioas(struct iommufd_ucmd *ucmd,
+ unsigned int access_id,
+ unsigned int ioas_id)
+{
+ struct selftest_access *staccess;
+ int rc;
+
+ staccess = iommufd_access_get(access_id);
+ if (IS_ERR(staccess))
+ return PTR_ERR(staccess);
+
+ rc = iommufd_access_set_ioas(staccess->access, ioas_id);
+ fput(staccess->file);
+ return rc;
+}
+
/* Check that the pages in a page array match the pages in the user VA */
static int iommufd_test_check_pages(void __user *uptr, struct page **pages,
size_t npages)
@@ -998,8 +1011,11 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
ucmd, u64_to_user_ptr(cmd->check_refs.uptr),
cmd->check_refs.length, cmd->check_refs.refs);
case IOMMU_TEST_OP_CREATE_ACCESS:
- return iommufd_test_create_access(ucmd, cmd->id,
+ return iommufd_test_create_access(ucmd,
cmd->create_access.flags);
+ case IOMMU_TEST_OP_ACCESS_SET_IOAS:
+ return iommufd_test_access_set_ioas(
+ ucmd, cmd->id, cmd->access_set_ioas.ioas_id);
case IOMMU_TEST_OP_ACCESS_PAGES:
return iommufd_test_access_pages(
ucmd, cmd->id, cmd->access_pages.iova,
diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h
index 9b6dcb921750..399779acce23 100644
--- a/tools/testing/selftests/iommu/iommufd_utils.h
+++ b/tools/testing/selftests/iommu/iommufd_utils.h
@@ -117,13 +117,31 @@ static int _test_cmd_hwpt_alloc(int fd, __u32 device_id, __u32 pt_id,
#define test_cmd_hwpt_alloc(device_id, pt_id, hwpt_id) \
ASSERT_EQ(0, _test_cmd_hwpt_alloc(self->fd, device_id, pt_id, hwpt_id))
+static int _test_cmd_access_set_ioas(int fd, __u32 access_id,
+ unsigned int ioas_id)
+{
+ struct iommu_test_cmd cmd = {
+ .size = sizeof(cmd),
+ .op = IOMMU_TEST_OP_ACCESS_SET_IOAS,
+ .id = access_id,
+ .access_set_ioas = { .ioas_id = ioas_id },
+ };
+ int ret;
+
+ ret = ioctl(fd, IOMMU_TEST_CMD, &cmd);
+ if (ret)
+ return ret;
+ return 0;
+}
+#define test_cmd_access_set_ioas(access_id, ioas_id) \
+ ASSERT_EQ(0, _test_cmd_access_set_ioas(self->fd, access_id, ioas_id))
+
static int _test_cmd_create_access(int fd, unsigned int ioas_id,
__u32 *access_id, unsigned int flags)
{
struct iommu_test_cmd cmd = {
.size = sizeof(cmd),
.op = IOMMU_TEST_OP_CREATE_ACCESS,
- .id = ioas_id,
.create_access = { .flags = flags },
};
int ret;
@@ -132,7 +150,7 @@ static int _test_cmd_create_access(int fd, unsigned int ioas_id,
if (ret)
return ret;
*access_id = cmd.create_access.out_access_fd;
- return 0;
+ return _test_cmd_access_set_ioas(fd, *access_id, ioas_id);
}
#define test_cmd_create_access(ioas_id, access_id, flags) \
ASSERT_EQ(0, _test_cmd_create_access(self->fd, ioas_id, access_id, \
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v4 2/5] iommufd/selftest: Add IOMMU_TEST_OP_ACCESS_SET_IOAS coverage
2023-03-08 14:25 ` [PATCH v4 2/5] iommufd/selftest: Add IOMMU_TEST_OP_ACCESS_SET_IOAS coverage Nicolin Chen
@ 2023-03-10 20:15 ` Jason Gunthorpe
2023-03-11 0:06 ` Nicolin Chen
0 siblings, 1 reply; 14+ messages in thread
From: Jason Gunthorpe @ 2023-03-10 20:15 UTC (permalink / raw)
To: Nicolin Chen
Cc: kevin.tian, joro, will, robin.murphy, alex.williamson, shuah,
yi.l.liu, linux-kernel, iommu, kvm, linux-kselftest, mjrosato,
farman
On Wed, Mar 08, 2023 at 06:25:59AM -0800, Nicolin Chen wrote:
> Add a new IOMMU_TEST_OP_ACCESS_SET_IOAS to allow setting access->ioas
> individually, corresponding to the iommufd_access_set_ioas() helper.
>
> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
> drivers/iommu/iommufd/iommufd_test.h | 4 +++
> drivers/iommu/iommufd/selftest.c | 26 +++++++++++++++----
> tools/testing/selftests/iommu/iommufd_utils.h | 22 ++++++++++++++--
> 3 files changed, 45 insertions(+), 7 deletions(-)
I'd prefer we keep it so that the IOAS can be setup with an argument,
this will greatly help syzkaller
Lets have it so a 0 ioas will avoid the setup so the second call can
happen
Jason
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 2/5] iommufd/selftest: Add IOMMU_TEST_OP_ACCESS_SET_IOAS coverage
2023-03-10 20:15 ` Jason Gunthorpe
@ 2023-03-11 0:06 ` Nicolin Chen
2023-03-16 5:38 ` Nicolin Chen
0 siblings, 1 reply; 14+ messages in thread
From: Nicolin Chen @ 2023-03-11 0:06 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: kevin.tian, joro, will, robin.murphy, alex.williamson, shuah,
yi.l.liu, linux-kernel, iommu, kvm, linux-kselftest, mjrosato,
farman
On Fri, Mar 10, 2023 at 04:15:33PM -0400, Jason Gunthorpe wrote:
> On Wed, Mar 08, 2023 at 06:25:59AM -0800, Nicolin Chen wrote:
> > Add a new IOMMU_TEST_OP_ACCESS_SET_IOAS to allow setting access->ioas
> > individually, corresponding to the iommufd_access_set_ioas() helper.
> >
> > Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> > Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> > ---
> > drivers/iommu/iommufd/iommufd_test.h | 4 +++
> > drivers/iommu/iommufd/selftest.c | 26 +++++++++++++++----
> > tools/testing/selftests/iommu/iommufd_utils.h | 22 ++++++++++++++--
> > 3 files changed, 45 insertions(+), 7 deletions(-)
>
> I'd prefer we keep it so that the IOAS can be setup with an argument,
> this will greatly help syzkaller
>
> Lets have it so a 0 ioas will avoid the setup so the second call can
> happen
I assume that you mean the iommufd_access_set_ioas() call and
the "unsigned int ioas_id" input of iommufd_test_create_access?
Thanks
Nic
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 2/5] iommufd/selftest: Add IOMMU_TEST_OP_ACCESS_SET_IOAS coverage
2023-03-11 0:06 ` Nicolin Chen
@ 2023-03-16 5:38 ` Nicolin Chen
0 siblings, 0 replies; 14+ messages in thread
From: Nicolin Chen @ 2023-03-16 5:38 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: kevin.tian, joro, will, robin.murphy, alex.williamson, shuah,
yi.l.liu, linux-kernel, iommu, kvm, linux-kselftest, mjrosato,
farman
On Fri, Mar 10, 2023 at 04:06:52PM -0800, Nicolin Chen wrote:
> On Fri, Mar 10, 2023 at 04:15:33PM -0400, Jason Gunthorpe wrote:
> > On Wed, Mar 08, 2023 at 06:25:59AM -0800, Nicolin Chen wrote:
> > > Add a new IOMMU_TEST_OP_ACCESS_SET_IOAS to allow setting access->ioas
> > > individually, corresponding to the iommufd_access_set_ioas() helper.
> > >
> > > Reviewed-by: Kevin Tian <kevin.tian@intel.com>
> > > Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> > > ---
> > > drivers/iommu/iommufd/iommufd_test.h | 4 +++
> > > drivers/iommu/iommufd/selftest.c | 26 +++++++++++++++----
> > > tools/testing/selftests/iommu/iommufd_utils.h | 22 ++++++++++++++--
> > > 3 files changed, 45 insertions(+), 7 deletions(-)
> >
> > I'd prefer we keep it so that the IOAS can be setup with an argument,
> > this will greatly help syzkaller
> >
> > Lets have it so a 0 ioas will avoid the setup so the second call can
> > happen
>
> I assume that you mean the iommufd_access_set_ioas() call and
> the "unsigned int ioas_id" input of iommufd_test_create_access?
I changed it to keep the id in iommufd_test_create_access().
Instead, I renamed the IOMMU_TEST_OP_ACCESS_SET_IOAS ioctl to
IOMMU_TEST_OP_ACCESS_REPLACE_IOAS. So an access can be created
by the original ioctl, and then be replaced using the new one.
Thanks
Nic
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 3/5] iommufd: Add replace support in iommufd_access_set_ioas()
2023-03-08 14:25 [PATCH v4 0/5] Add IO page table replacement support Nicolin Chen
2023-03-08 14:25 ` [PATCH v4 1/5] vfio: Do not allow !ops->dma_unmap in vfio_pin/unpin_pages() Nicolin Chen
2023-03-08 14:25 ` [PATCH v4 2/5] iommufd/selftest: Add IOMMU_TEST_OP_ACCESS_SET_IOAS coverage Nicolin Chen
@ 2023-03-08 14:26 ` Nicolin Chen
2023-03-10 11:50 ` Tian, Kevin
2023-03-08 14:26 ` [PATCH v4 4/5] iommufd/selftest: Add coverage for access->ioas replacement Nicolin Chen
2023-03-08 14:26 ` [PATCH v4 5/5] vfio: Support IO page table replacement Nicolin Chen
4 siblings, 1 reply; 14+ messages in thread
From: Nicolin Chen @ 2023-03-08 14:26 UTC (permalink / raw)
To: jgg, kevin.tian, joro, will, robin.murphy, alex.williamson, shuah
Cc: yi.l.liu, linux-kernel, iommu, kvm, linux-kselftest, mjrosato,
farman
Support an access->ioas replacement in iommufd_access_set_ioas(), which
sets the access->ioas to NULL provisionally so that any further incoming
iommufd_access_pin_pages() callback can be blocked.
Then, call access->ops->unmap() to clean up the entire iopt. To allow an
iommufd_access_unpin_pages() callback to happen via this unmap() call,
add an ioas_unpin pointer so the unpin routine won't be affected by the
"access->ioas = NULL" trick above.
Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/device.c | 17 +++++++++++++++--
drivers/iommu/iommufd/iommufd_private.h | 1 +
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c
index 612a5f424bd7..c10e02f6a0be 100644
--- a/drivers/iommu/iommufd/device.c
+++ b/drivers/iommu/iommufd/device.c
@@ -727,11 +727,24 @@ int iommufd_access_set_ioas(struct iommufd_access *access, u32 ioas_id)
iommufd_ref_to_users(obj);
}
+ /*
+ * Set ioas to NULL to block any further iommufd_access_pin_pages().
+ * iommufd_access_unpin_pages() can continue using access->ioas_unpin.
+ */
+ access->ioas = NULL;
+
+ if (access->ops->unmap) {
+ mutex_unlock(&access->ioas_lock);
+ access->ops->unmap(access->data, 0, ULONG_MAX);
+ mutex_lock(&access->ioas_lock);
+ }
+
if (cur_ioas) {
iopt_remove_access(&cur_ioas->iopt, access);
refcount_dec(&cur_ioas->obj.users);
}
+ access->ioas_unpin = new_ioas;
access->ioas = new_ioas;
mutex_unlock(&access->ioas_lock);
@@ -805,11 +818,11 @@ void iommufd_access_unpin_pages(struct iommufd_access *access,
return;
mutex_lock(&access->ioas_lock);
- if (!access->ioas) {
+ if (!access->ioas_unpin) {
mutex_unlock(&access->ioas_lock);
return;
}
- iopt = &access->ioas->iopt;
+ iopt = &access->ioas_unpin->iopt;
down_read(&iopt->iova_rwsem);
iopt_for_each_contig_area(&iter, area, iopt, iova, last_iova)
diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index db1ead8ff9d0..b18f843ad6a4 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -312,6 +312,7 @@ struct iommufd_access {
struct iommufd_object obj;
struct iommufd_ctx *ictx;
struct iommufd_ioas *ioas;
+ struct iommufd_ioas *ioas_unpin;
struct mutex ioas_lock;
const struct iommufd_access_ops *ops;
void *data;
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* RE: [PATCH v4 3/5] iommufd: Add replace support in iommufd_access_set_ioas()
2023-03-08 14:26 ` [PATCH v4 3/5] iommufd: Add replace support in iommufd_access_set_ioas() Nicolin Chen
@ 2023-03-10 11:50 ` Tian, Kevin
0 siblings, 0 replies; 14+ messages in thread
From: Tian, Kevin @ 2023-03-10 11:50 UTC (permalink / raw)
To: Nicolin Chen, jgg@nvidia.com, joro@8bytes.org, will@kernel.org,
robin.murphy@arm.com, alex.williamson@redhat.com,
shuah@kernel.org
Cc: Liu, Yi L, linux-kernel@vger.kernel.org, iommu@lists.linux.dev,
kvm@vger.kernel.org, linux-kselftest@vger.kernel.org,
mjrosato@linux.ibm.com, farman@linux.ibm.com
> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: Wednesday, March 8, 2023 10:26 PM
>
> Support an access->ioas replacement in iommufd_access_set_ioas(), which
> sets the access->ioas to NULL provisionally so that any further incoming
> iommufd_access_pin_pages() callback can be blocked.
>
> Then, call access->ops->unmap() to clean up the entire iopt. To allow an
> iommufd_access_unpin_pages() callback to happen via this unmap() call,
> add an ioas_unpin pointer so the unpin routine won't be affected by the
> "access->ioas = NULL" trick above.
>
> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 4/5] iommufd/selftest: Add coverage for access->ioas replacement
2023-03-08 14:25 [PATCH v4 0/5] Add IO page table replacement support Nicolin Chen
` (2 preceding siblings ...)
2023-03-08 14:26 ` [PATCH v4 3/5] iommufd: Add replace support in iommufd_access_set_ioas() Nicolin Chen
@ 2023-03-08 14:26 ` Nicolin Chen
2023-03-08 14:26 ` [PATCH v4 5/5] vfio: Support IO page table replacement Nicolin Chen
4 siblings, 0 replies; 14+ messages in thread
From: Nicolin Chen @ 2023-03-08 14:26 UTC (permalink / raw)
To: jgg, kevin.tian, joro, will, robin.murphy, alex.williamson, shuah
Cc: yi.l.liu, linux-kernel, iommu, kvm, linux-kselftest, mjrosato,
farman
Add replace coverage as a part of user_copy test case. It basically
repeats the copy test after replacing the old ioas with a new one.
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
tools/testing/selftests/iommu/iommufd.c | 29 +++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
index c07252dbf62d..5c33b6b52c65 100644
--- a/tools/testing/selftests/iommu/iommufd.c
+++ b/tools/testing/selftests/iommu/iommufd.c
@@ -1252,7 +1252,13 @@ TEST_F(iommufd_mock_domain, user_copy)
.dst_iova = MOCK_APERTURE_START,
.length = BUFFER_SIZE,
};
- unsigned int ioas_id;
+ struct iommu_ioas_unmap unmap_cmd = {
+ .size = sizeof(unmap_cmd),
+ .ioas_id = self->ioas_id,
+ .iova = MOCK_APERTURE_START,
+ .length = BUFFER_SIZE,
+ };
+ unsigned int new_ioas_id, ioas_id;
/* Pin the pages in an IOAS with no domains then copy to an IOAS with domains */
test_ioctl_ioas_alloc(&ioas_id);
@@ -1270,11 +1276,30 @@ TEST_F(iommufd_mock_domain, user_copy)
ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_COPY, ©_cmd));
check_mock_iova(buffer, MOCK_APERTURE_START, BUFFER_SIZE);
+ /* Now replace the ioas with a new one */
+ test_ioctl_ioas_alloc(&new_ioas_id);
+ test_ioctl_ioas_map_id(new_ioas_id, buffer, BUFFER_SIZE,
+ ©_cmd.src_iova);
+ test_cmd_access_set_ioas(access_cmd.id, new_ioas_id);
+
+ /* Destroy the old ioas and cleanup copied mapping */
+ ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_UNMAP, &unmap_cmd));
+ test_ioctl_destroy(ioas_id);
+
+ /* Then run the same test again with the new ioas */
+ access_cmd.access_pages.iova = copy_cmd.src_iova;
+ ASSERT_EQ(0,
+ ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_PAGES),
+ &access_cmd));
+ copy_cmd.src_ioas_id = new_ioas_id;
+ ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_COPY, ©_cmd));
+ check_mock_iova(buffer, MOCK_APERTURE_START, BUFFER_SIZE);
+
test_cmd_destroy_access_pages(
access_cmd.id, access_cmd.access_pages.out_access_pages_id);
test_cmd_destroy_access(access_cmd.id);
- test_ioctl_destroy(ioas_id);
+ test_ioctl_destroy(new_ioas_id);
}
TEST_F(iommufd_mock_domain, replace)
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v4 5/5] vfio: Support IO page table replacement
2023-03-08 14:25 [PATCH v4 0/5] Add IO page table replacement support Nicolin Chen
` (3 preceding siblings ...)
2023-03-08 14:26 ` [PATCH v4 4/5] iommufd/selftest: Add coverage for access->ioas replacement Nicolin Chen
@ 2023-03-08 14:26 ` Nicolin Chen
2023-03-10 11:53 ` Tian, Kevin
4 siblings, 1 reply; 14+ messages in thread
From: Nicolin Chen @ 2023-03-08 14:26 UTC (permalink / raw)
To: jgg, kevin.tian, joro, will, robin.murphy, alex.williamson, shuah
Cc: yi.l.liu, linux-kernel, iommu, kvm, linux-kselftest, mjrosato,
farman
Now both the physical path and the emulated path should support an IO page
table replacement.
Call iommufd_device_replace() when vdev->iommufd_attached is true.
Also update the VFIO_DEVICE_ATTACH_IOMMUFD_PT kdoc in the uAPI header.
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/vfio/iommufd.c | 6 +++---
include/uapi/linux/vfio.h | 6 ++++++
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/vfio/iommufd.c b/drivers/vfio/iommufd.c
index 8a9457d0a33c..a245a8e0c8ab 100644
--- a/drivers/vfio/iommufd.c
+++ b/drivers/vfio/iommufd.c
@@ -145,9 +145,9 @@ int vfio_iommufd_physical_attach_ioas(struct vfio_device *vdev, u32 *pt_id)
return -EINVAL;
if (vdev->iommufd_attached)
- return -EBUSY;
-
- rc = iommufd_device_attach(vdev->iommufd_device, pt_id);
+ rc = iommufd_device_replace(vdev->iommufd_device, pt_id);
+ else
+ rc = iommufd_device_attach(vdev->iommufd_device, pt_id);
if (rc)
return rc;
vdev->iommufd_attached = true;
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 692156a708bb..14375826a25b 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -243,6 +243,12 @@ struct vfio_device_bind_iommufd {
*
* Undo by VFIO_DEVICE_DETACH_IOMMUFD_PT or device fd close.
*
+ * If a vfio device is currently attached to a valid hw_pagetable, without doing
+ * a VFIO_DEVICE_DETACH_IOMMUFD_PT, a second VFIO_DEVICE_ATTACH_IOMMUFD_PT ioctl
+ * passing in another hw_pagetable (hwpt) id is allowed. This action, also known
+ * as a hw_pagetable replacement, will replace the device's currently attached
+ * hw_pagetable with a new hw_pagetable corresponding to the given pt_id.
+ *
* @argsz: user filled size of this data.
* @flags: must be 0.
* @pt_id: Input the target id which can represent an ioas or a hwpt
--
2.39.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* RE: [PATCH v4 5/5] vfio: Support IO page table replacement
2023-03-08 14:26 ` [PATCH v4 5/5] vfio: Support IO page table replacement Nicolin Chen
@ 2023-03-10 11:53 ` Tian, Kevin
2023-03-10 23:38 ` Nicolin Chen
0 siblings, 1 reply; 14+ messages in thread
From: Tian, Kevin @ 2023-03-10 11:53 UTC (permalink / raw)
To: Nicolin Chen, jgg@nvidia.com, joro@8bytes.org, will@kernel.org,
robin.murphy@arm.com, alex.williamson@redhat.com,
shuah@kernel.org
Cc: Liu, Yi L, linux-kernel@vger.kernel.org, iommu@lists.linux.dev,
kvm@vger.kernel.org, linux-kselftest@vger.kernel.org,
mjrosato@linux.ibm.com, farman@linux.ibm.com
> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: Wednesday, March 8, 2023 10:26 PM
>
> Now both the physical path and the emulated path should support an IO
> page
> table replacement.
>
> Call iommufd_device_replace() when vdev->iommufd_attached is true.
>
why is replace enabled only in physical path in this patch?
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 5/5] vfio: Support IO page table replacement
2023-03-10 11:53 ` Tian, Kevin
@ 2023-03-10 23:38 ` Nicolin Chen
2023-03-13 2:04 ` Tian, Kevin
0 siblings, 1 reply; 14+ messages in thread
From: Nicolin Chen @ 2023-03-10 23:38 UTC (permalink / raw)
To: Tian, Kevin
Cc: jgg@nvidia.com, joro@8bytes.org, will@kernel.org,
robin.murphy@arm.com, alex.williamson@redhat.com,
shuah@kernel.org, Liu, Yi L, linux-kernel@vger.kernel.org,
iommu@lists.linux.dev, kvm@vger.kernel.org,
linux-kselftest@vger.kernel.org, mjrosato@linux.ibm.com,
farman@linux.ibm.com
On Fri, Mar 10, 2023 at 11:53:56AM +0000, Tian, Kevin wrote:
> External email: Use caution opening links or attachments
>
>
> > From: Nicolin Chen <nicolinc@nvidia.com>
> > Sent: Wednesday, March 8, 2023 10:26 PM
> >
> > Now both the physical path and the emulated path should support an IO
> > page
> > table replacement.
> >
> > Call iommufd_device_replace() when vdev->iommufd_attached is true.
> >
>
> why is replace enabled only in physical path in this patch?
The emulated pathway does not call iommufd_device_attach() but
iommufd_access_set_ioas() in the other patch, which internally
takes care of the replacement for the access pointer.
Thanks
Nic
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH v4 5/5] vfio: Support IO page table replacement
2023-03-10 23:38 ` Nicolin Chen
@ 2023-03-13 2:04 ` Tian, Kevin
0 siblings, 0 replies; 14+ messages in thread
From: Tian, Kevin @ 2023-03-13 2:04 UTC (permalink / raw)
To: Nicolin Chen
Cc: jgg@nvidia.com, joro@8bytes.org, will@kernel.org,
robin.murphy@arm.com, alex.williamson@redhat.com,
shuah@kernel.org, Liu, Yi L, linux-kernel@vger.kernel.org,
iommu@lists.linux.dev, kvm@vger.kernel.org,
linux-kselftest@vger.kernel.org, mjrosato@linux.ibm.com,
farman@linux.ibm.com
> From: Nicolin Chen <nicolinc@nvidia.com>
> Sent: Saturday, March 11, 2023 7:38 AM
>
> On Fri, Mar 10, 2023 at 11:53:56AM +0000, Tian, Kevin wrote:
> > External email: Use caution opening links or attachments
> >
> >
> > > From: Nicolin Chen <nicolinc@nvidia.com>
> > > Sent: Wednesday, March 8, 2023 10:26 PM
> > >
> > > Now both the physical path and the emulated path should support an IO
> > > page
> > > table replacement.
> > >
> > > Call iommufd_device_replace() when vdev->iommufd_attached is true.
> > >
> >
> > why is replace enabled only in physical path in this patch?
>
> The emulated pathway does not call iommufd_device_attach() but
> iommufd_access_set_ioas() in the other patch, which internally
> takes care of the replacement for the access pointer.
>
I thought there is a similar check as in physical path which should
be removed:
if (vdev->iommufd_attached)
- return -EBUSY;
but looks it's not the case for the emulated path.
^ permalink raw reply [flat|nested] 14+ messages in thread