* [PATCH RFC v1 0/3] Add set_rid_user and unset_rid_user support
@ 2023-04-06 6:25 Nicolin Chen
2023-04-06 6:25 ` [PATCH RFC v1 1/3] iommu: Add set/unset_rid_user ops Nicolin Chen
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Nicolin Chen @ 2023-04-06 6:25 UTC (permalink / raw)
To: jgg, robin.murphy, kevin.tian
Cc: eric.auger, yi.l.liu, baolu.lu, will, joro,
shameerali.kolothum.thodi, jean-philippe, linux-arm-kernel, iommu,
linux-kernel
This is a pair of new uAPI/ops for user space to set a user space virtual
Request ID for a passthrough PCI device, down to the IOMMU driver. This's
primarily used by SMMUv3 driver for now, to link the vSID and the pSID of
a device behind the SMMU. The link (lookup table) will be used to verify
an ATC_INV command from the user space for that device, and then replace
the virtual SID with the corresponding physical SID.
This is a RFC series, since I am not confident at all about the uAPI/ops
namings. Hopefully we can finalize this small series soon and include it
in the next version of SMMUv3 nesting series.
This series is available on Github:
https://github.com/nicolinc/iommufd/commits/set_rid_user-rfc-v1
Thanks!
Nicolin
Nicolin Chen (3):
iommu: Add set/unset_rid_user ops
iommufd: Add IOMMUFD_CMD_DEVICE_SET_RID and
IOMMUFD_CMD_DEVICE_UNSET_RID
iommu/arm-smmu-v3: Implement set_rid_user and unset_rid_user
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 45 +++++++++++++++++++++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 2 +
drivers/iommu/iommufd/device.c | 39 ++++++++++++++++++
drivers/iommu/iommufd/iommufd_private.h | 2 +
drivers/iommu/iommufd/main.c | 4 ++
include/linux/iommu.h | 4 ++
include/uapi/linux/iommufd.h | 31 ++++++++++++++
7 files changed, 127 insertions(+)
--
2.40.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH RFC v1 1/3] iommu: Add set/unset_rid_user ops
2023-04-06 6:25 [PATCH RFC v1 0/3] Add set_rid_user and unset_rid_user support Nicolin Chen
@ 2023-04-06 6:25 ` Nicolin Chen
2023-04-06 6:25 ` [PATCH RFC v1 2/3] iommufd: Add IOMMUFD_CMD_DEVICE_SET_RID and IOMMUFD_CMD_DEVICE_UNSET_RID Nicolin Chen
2023-04-06 6:25 ` [PATCH RFC v1 3/3] iommu/arm-smmu-v3: Implement set_rid_user and unset_rid_user Nicolin Chen
2 siblings, 0 replies; 4+ messages in thread
From: Nicolin Chen @ 2023-04-06 6:25 UTC (permalink / raw)
To: jgg, robin.murphy, kevin.tian
Cc: eric.auger, yi.l.liu, baolu.lu, will, joro,
shameerali.kolothum.thodi, jean-philippe, linux-arm-kernel, iommu,
linux-kernel
Add a pair of new ops to allow user space to set virtual RID of a device.
This can be converted to Stream ID for SMMUv3, so as to create the link
between a physical Stream ID and a virtual Stream ID.
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
include/linux/iommu.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 080278c8154d..f85ce6f01408 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -248,6 +248,7 @@ struct iommu_iotlb_gather {
* driver init to device driver init (default no)
* @dev_enable/disable_feat: per device entries to enable/disable
* iommu specific features.
+ * @set/unset_rid_user: per device entries to set/unset user space Request ID
* @page_response: handle page request response
* @def_domain_type: device default domain type, return value:
* - IOMMU_DOMAIN_IDENTITY: must use an identity domain
@@ -291,6 +292,9 @@ struct iommu_ops {
int (*dev_enable_feat)(struct device *dev, enum iommu_dev_features f);
int (*dev_disable_feat)(struct device *dev, enum iommu_dev_features f);
+ int (*set_rid_user)(struct device *dev, u32 rid, u32 rid_base);
+ int (*unset_rid_user)(struct device *dev);
+
int (*page_response)(struct device *dev,
struct iommu_fault_event *evt,
struct iommu_page_response *msg);
--
2.40.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH RFC v1 2/3] iommufd: Add IOMMUFD_CMD_DEVICE_SET_RID and IOMMUFD_CMD_DEVICE_UNSET_RID
2023-04-06 6:25 [PATCH RFC v1 0/3] Add set_rid_user and unset_rid_user support Nicolin Chen
2023-04-06 6:25 ` [PATCH RFC v1 1/3] iommu: Add set/unset_rid_user ops Nicolin Chen
@ 2023-04-06 6:25 ` Nicolin Chen
2023-04-06 6:25 ` [PATCH RFC v1 3/3] iommu/arm-smmu-v3: Implement set_rid_user and unset_rid_user Nicolin Chen
2 siblings, 0 replies; 4+ messages in thread
From: Nicolin Chen @ 2023-04-06 6:25 UTC (permalink / raw)
To: jgg, robin.murphy, kevin.tian
Cc: eric.auger, yi.l.liu, baolu.lu, will, joro,
shameerali.kolothum.thodi, jean-philippe, linux-arm-kernel, iommu,
linux-kernel
Add a new pair of ioctls to allow user space to set user space Request ID
for a passthrough PCI device. This is to create a link between a physical
RID and a virtual RID in the IOMMU driver that cares.
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/device.c | 39 +++++++++++++++++++++++++
drivers/iommu/iommufd/iommufd_private.h | 2 ++
drivers/iommu/iommufd/main.c | 4 +++
include/uapi/linux/iommufd.h | 31 ++++++++++++++++++++
4 files changed, 76 insertions(+)
diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c
index 207b0e3fd9c8..db756e5cd77b 100644
--- a/drivers/iommu/iommufd/device.c
+++ b/drivers/iommu/iommufd/device.c
@@ -735,6 +735,45 @@ void iommufd_device_detach(struct iommufd_device *idev)
}
EXPORT_SYMBOL_NS_GPL(iommufd_device_detach, IOMMUFD);
+int iommufd_device_set_rid(struct iommufd_ucmd *ucmd)
+{
+ struct iommufd_device_set_rid *cmd = ucmd->cmd;
+ struct iommufd_device *idev;
+ const struct iommu_ops *ops;
+ int rc = 0;
+
+ if (!cmd->rid)
+ return -EINVAL;
+
+ idev = iommufd_get_device(ucmd, cmd->dev_id);
+ if (IS_ERR(idev))
+ return PTR_ERR(idev);
+
+ ops = dev_iommu_ops(idev->dev);
+ if (ops && ops->set_rid_user)
+ rc = ops->set_rid_user(idev->dev, cmd->rid, cmd->rid_base);
+ iommufd_put_object(&idev->obj);
+ return rc;
+}
+
+int iommufd_device_unset_rid(struct iommufd_ucmd *ucmd)
+{
+ struct iommufd_device_unset_rid *cmd = ucmd->cmd;
+ struct iommufd_device *idev;
+ const struct iommu_ops *ops;
+ int rc = 0;
+
+ idev = iommufd_get_device(ucmd, cmd->dev_id);
+ if (IS_ERR(idev))
+ return PTR_ERR(idev);
+
+ ops = dev_iommu_ops(idev->dev);
+ if (ops && ops->unset_rid_user)
+ rc = ops->unset_rid_user(idev->dev);
+ iommufd_put_object(&idev->obj);
+ return rc;
+}
+
void iommufd_access_destroy_object(struct iommufd_object *obj)
{
struct iommufd_access *access =
diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index e52fd9d8c160..d65617727c0c 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -320,6 +320,8 @@ iommufd_get_device(struct iommufd_ucmd *ucmd, u32 id)
void iommufd_device_destroy(struct iommufd_object *obj);
int iommufd_device_get_hw_info(struct iommufd_ucmd *ucmd);
+int iommufd_device_set_rid(struct iommufd_ucmd *ucmd);
+int iommufd_device_unset_rid(struct iommufd_ucmd *ucmd);
extern const u64 iommufd_hwpt_type_bitmaps[];
diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c
index 7ec3ceac01b3..113fac4d4de0 100644
--- a/drivers/iommu/iommufd/main.c
+++ b/drivers/iommu/iommufd/main.c
@@ -317,6 +317,10 @@ static const struct iommufd_ioctl_op iommufd_ioctl_ops[] = {
val64),
IOCTL_OP(IOMMU_VFIO_IOAS, iommufd_vfio_ioas, struct iommu_vfio_ioas,
__reserved),
+ IOCTL_OP(IOMMU_DEVICE_SET_RID, iommufd_device_set_rid,
+ struct iommufd_device_set_rid, rid_base),
+ IOCTL_OP(IOMMU_DEVICE_UNSET_RID, iommufd_device_unset_rid,
+ struct iommufd_device_unset_rid, dev_id),
#ifdef CONFIG_IOMMUFD_TEST
IOCTL_OP(IOMMU_TEST_CMD, iommufd_test, struct iommu_test_cmd, last),
#endif
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index 59a44ceff27d..5188a4318e22 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -48,6 +48,8 @@ enum {
IOMMUFD_CMD_HWPT_ALLOC,
IOMMUFD_CMD_DEVICE_GET_HW_INFO,
IOMMUFD_CMD_HWPT_INVALIDATE,
+ IOMMUFD_CMD_DEVICE_SET_RID,
+ IOMMUFD_CMD_DEVICE_UNSET_RID,
};
/**
@@ -482,4 +484,33 @@ struct iommu_hwpt_invalidate {
__aligned_u64 data_uptr;
};
#define IOMMU_HWPT_INVALIDATE _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_INVALIDATE)
+
+/**
+ * struct iommufd_device_set_rid - ioctl(IOMMU_DEVICE_SET_RID)
+ * @size: sizeof(struct iommufd_device_set_rid)
+ * @dev_id: The device to set a Request ID
+ * @rid: PCI Request ID
+ * Bits [15:8] are the Bus number.
+ * Bits [7:3] are the Device number.
+ * Bits [2:0] are the Function number.
+ * @rid_base: Base ID to map PCI Request ID
+ */
+struct iommufd_device_set_rid {
+ __u32 size;
+ __u32 dev_id;
+ __u32 rid;
+ __u32 rid_base;
+};
+#define IOMMU_DEVICE_SET_RID _IO(IOMMUFD_TYPE, IOMMUFD_CMD_DEVICE_SET_RID)
+
+/**
+ * struct iommufd_device_unset_rid - ioctl(IOMMU_DEVICE_UNSET_RID)
+ * @size: sizeof(struct iommufd_device_unset_rid)
+ * @dev_id: The device to unset a Request ID
+ */
+struct iommufd_device_unset_rid {
+ __u32 size;
+ __u32 dev_id;
+};
+#define IOMMU_DEVICE_UNSET_RID _IO(IOMMUFD_TYPE, IOMMUFD_CMD_DEVICE_UNSET_RID)
#endif
--
2.40.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH RFC v1 3/3] iommu/arm-smmu-v3: Implement set_rid_user and unset_rid_user
2023-04-06 6:25 [PATCH RFC v1 0/3] Add set_rid_user and unset_rid_user support Nicolin Chen
2023-04-06 6:25 ` [PATCH RFC v1 1/3] iommu: Add set/unset_rid_user ops Nicolin Chen
2023-04-06 6:25 ` [PATCH RFC v1 2/3] iommufd: Add IOMMUFD_CMD_DEVICE_SET_RID and IOMMUFD_CMD_DEVICE_UNSET_RID Nicolin Chen
@ 2023-04-06 6:25 ` Nicolin Chen
2 siblings, 0 replies; 4+ messages in thread
From: Nicolin Chen @ 2023-04-06 6:25 UTC (permalink / raw)
To: jgg, robin.murphy, kevin.tian
Cc: eric.auger, yi.l.liu, baolu.lu, will, joro,
shameerali.kolothum.thodi, jean-philippe, linux-arm-kernel, iommu,
linux-kernel
Implement the new set_rid_user and unset_rid_user ops, by using an xarray
to store the stream pointer indexed by a given user space Stream ID. This
will be used by user cache invalidation hypercall, to check the SID field
of an ATC_INV command and replace it with the corresponding physical SID.
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 45 +++++++++++++++++++++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 2 +
2 files changed, 47 insertions(+)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index f2425b0f0cd6..17bb90e78547 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2843,6 +2843,48 @@ static void arm_smmu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
arm_smmu_sva_remove_dev_pasid(domain, dev, pasid);
}
+static int arm_smmu_set_rid_user(struct device *dev, u32 rid, u32 rid_base)
+{
+ struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+ struct arm_smmu_stream *stream = &master->streams[0];
+ struct arm_smmu_device *smmu = master->smmu;
+ u32 sid_user = rid_base | rid;
+ int ret = 0;
+
+ if (!sid_user)
+ return -EINVAL;
+
+ ret = xa_alloc(&smmu->streams_user, &sid_user, stream,
+ XA_LIMIT(sid_user, sid_user), GFP_KERNEL_ACCOUNT);
+ if (ret)
+ return ret;
+ stream->id_user = sid_user;
+ return 0;
+}
+
+static int arm_smmu_unset_rid_user(struct device *dev)
+{
+ struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+ struct arm_smmu_stream *stream = &master->streams[0];
+ struct arm_smmu_device *smmu = master->smmu;
+ u32 sid_user = stream->id_user;
+
+ if (!sid_user)
+ return -ENODEV;
+
+ xa_lock(&smmu->streams_user);
+ stream = __xa_erase(&smmu->streams_user, sid_user);
+ if (stream != master->streams) {
+ WARN_ON(__xa_alloc(&smmu->streams_user, &sid_user, stream,
+ XA_LIMIT(sid_user, sid_user),
+ GFP_KERNEL_ACCOUNT));
+ xa_unlock(&smmu->streams_user);
+ return -EINVAL;
+ }
+ xa_unlock(&smmu->streams_user);
+ return 0;
+}
+
static struct iommu_ops arm_smmu_ops = {
.capable = arm_smmu_capable,
.domain_alloc = arm_smmu_domain_alloc,
@@ -2854,6 +2896,8 @@ static struct iommu_ops arm_smmu_ops = {
.remove_dev_pasid = arm_smmu_remove_dev_pasid,
.dev_enable_feat = arm_smmu_dev_enable_feature,
.dev_disable_feat = arm_smmu_dev_disable_feature,
+ .set_rid_user = arm_smmu_set_rid_user,
+ .unset_rid_user = arm_smmu_unset_rid_user,
.page_response = arm_smmu_page_response,
.def_domain_type = arm_smmu_def_domain_type,
.pgsize_bitmap = -1UL, /* Restricted during device attach */
@@ -3082,6 +3126,7 @@ static int arm_smmu_init_structures(struct arm_smmu_device *smmu)
mutex_init(&smmu->streams_mutex);
smmu->streams = RB_ROOT;
+ xa_init_flags(&smmu->streams_user, XA_FLAGS_ALLOC1 | XA_FLAGS_ACCOUNT);
ret = arm_smmu_init_queues(smmu);
if (ret)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 8d772ea8a583..8ccea2e84bbb 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -674,10 +674,12 @@ struct arm_smmu_device {
struct rb_root streams;
struct mutex streams_mutex;
+ struct xarray streams_user;
};
struct arm_smmu_stream {
u32 id;
+ u32 id_user;
struct arm_smmu_master *master;
struct rb_node node;
};
--
2.40.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-04-06 6:27 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-06 6:25 [PATCH RFC v1 0/3] Add set_rid_user and unset_rid_user support Nicolin Chen
2023-04-06 6:25 ` [PATCH RFC v1 1/3] iommu: Add set/unset_rid_user ops Nicolin Chen
2023-04-06 6:25 ` [PATCH RFC v1 2/3] iommufd: Add IOMMUFD_CMD_DEVICE_SET_RID and IOMMUFD_CMD_DEVICE_UNSET_RID Nicolin Chen
2023-04-06 6:25 ` [PATCH RFC v1 3/3] iommu/arm-smmu-v3: Implement set_rid_user and unset_rid_user Nicolin Chen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).