mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
iommu/arm-smmu-v3-iommufd: Require exactly one Stream ID for a vDEVICE
arm_vsmmu_vsid_to_sid() maps a guest's vSID to a single physical Stream ID
taken from master->streams[0], assuming a device has exactly one stream. A
device with several streams gets only its first one mapped, so a guest vSID
invalidation cannot reach the others' ATC and IOTLB entries; a device with
none makes master->streams a ZERO_SIZE_PTR, read out of bounds.
Add an arm_vsmmu_vdevice_init() op to reject the vDEVICE with -EOPNOTSUPP
when master->num_streams is not one, rather than mapping it silently.
Fixes: d68beb276b ("iommu/arm-smmu-v3: Support IOMMU_HWPT_INVALIDATE using a VIOMMU object")
Link: https://patch.msgid.link/r/b15f2b73520f389f3f57881da2f040e7bdc18876.1783311134.git.nicolinc@nvidia.com
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Assisted-by: Claude:claude-opus-4-8
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
9be311cfbe
commit
c3b8ee84a9
|
|
@ -297,6 +297,20 @@ static int arm_vsmmu_vsid_to_sid(struct arm_vsmmu *vsmmu, u32 vsid, u32 *sid)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int arm_vsmmu_vdevice_init(struct iommufd_vdevice *vdev)
|
||||
{
|
||||
struct device *dev = iommufd_vdevice_to_device(vdev);
|
||||
struct arm_smmu_master *master = dev_iommu_priv_get(dev);
|
||||
|
||||
/*
|
||||
* arm_vsmmu_vsid_to_sid() maps a vSID to master->streams[0] alone, so
|
||||
* more streams would leave the rest stale and none reads out of bounds.
|
||||
*/
|
||||
if (master->num_streams != 1)
|
||||
return -EOPNOTSUPP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is basically iommu_viommu_arm_smmuv3_invalidate in u64 for conversion */
|
||||
struct arm_vsmmu_invalidation_cmd {
|
||||
union {
|
||||
|
|
@ -403,6 +417,7 @@ int arm_vsmmu_cache_invalidate(struct iommufd_viommu *viommu,
|
|||
static const struct iommufd_viommu_ops arm_vsmmu_ops = {
|
||||
.alloc_domain_nested = arm_vsmmu_alloc_domain_nested,
|
||||
.cache_invalidate = arm_vsmmu_cache_invalidate,
|
||||
.vdevice_init = arm_vsmmu_vdevice_init,
|
||||
};
|
||||
|
||||
size_t arm_smmu_get_viommu_size(struct device *dev,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user