mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 03:53:37 +02:00
iommu/arm-smmu-v3: Replace arm_vsmmu_alloc with arm_vsmmu_init
To ease the for-driver iommufd APIs, get_viommu_size and viommu_init ops are introduced. Sanitize the inputs and report the size of struct arm_vsmmu on success, in arm_smmu_get_viommu_size(). Place the type sanity at the last, becase there will be soon an impl level get_viommu_size op, which will require the same sanity tests prior. It can simply insert a piece of code in front of the IOMMU_VIOMMU_TYPE_ARM_SMMUV3 sanity. The core will ensure the viommu_type is set to the core vIOMMU object, and pass in the same dev pointer, so arm_vsmmu_init() won't need to repeat the same sanity tests but to simply init the arm_vsmmu struct. Remove the arm_vsmmu_alloc, completing the replacement. Link: https://patch.msgid.link/r/64e4b4c33acd26e1bd676e077be80e00fb63f17c.1749882255.git.nicolinc@nvidia.com Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Pranjal Shrivastava <praan@google.com> Acked-by: Will Deacon <will@kernel.org> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
683cff7c3b
commit
3961f2f5da
|
|
@ -382,25 +382,14 @@ static const struct iommufd_viommu_ops arm_vsmmu_ops = {
|
|||
.cache_invalidate = arm_vsmmu_cache_invalidate,
|
||||
};
|
||||
|
||||
struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
|
||||
struct iommu_domain *parent,
|
||||
struct iommufd_ctx *ictx,
|
||||
unsigned int viommu_type)
|
||||
size_t arm_smmu_get_viommu_size(struct device *dev,
|
||||
enum iommu_viommu_type viommu_type)
|
||||
{
|
||||
struct arm_smmu_device *smmu =
|
||||
iommu_get_iommu_dev(dev, struct arm_smmu_device, iommu);
|
||||
struct arm_smmu_master *master = dev_iommu_priv_get(dev);
|
||||
struct arm_smmu_domain *s2_parent = to_smmu_domain(parent);
|
||||
struct arm_vsmmu *vsmmu;
|
||||
|
||||
if (viommu_type != IOMMU_VIOMMU_TYPE_ARM_SMMUV3)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
struct arm_smmu_device *smmu = master->smmu;
|
||||
|
||||
if (!(smmu->features & ARM_SMMU_FEAT_NESTING))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
if (s2_parent->smmu != master->smmu)
|
||||
return ERR_PTR(-EINVAL);
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* FORCE_SYNC is not set with FEAT_NESTING. Some study of the exact HW
|
||||
|
|
@ -408,7 +397,7 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
|
|||
* any change to remove this.
|
||||
*/
|
||||
if (WARN_ON(smmu->options & ARM_SMMU_OPT_CMDQ_FORCE_SYNC))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Must support some way to prevent the VM from bypassing the cache
|
||||
|
|
@ -420,19 +409,32 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
|
|||
*/
|
||||
if (!arm_smmu_master_canwbs(master) &&
|
||||
!(smmu->features & ARM_SMMU_FEAT_S2FWB))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
return 0;
|
||||
|
||||
vsmmu = iommufd_viommu_alloc(ictx, struct arm_vsmmu, core,
|
||||
&arm_vsmmu_ops);
|
||||
if (IS_ERR(vsmmu))
|
||||
return ERR_CAST(vsmmu);
|
||||
if (viommu_type != IOMMU_VIOMMU_TYPE_ARM_SMMUV3)
|
||||
return 0;
|
||||
|
||||
return VIOMMU_STRUCT_SIZE(struct arm_vsmmu, core);
|
||||
}
|
||||
|
||||
int arm_vsmmu_init(struct iommufd_viommu *viommu,
|
||||
struct iommu_domain *parent_domain)
|
||||
{
|
||||
struct arm_vsmmu *vsmmu = container_of(viommu, struct arm_vsmmu, core);
|
||||
struct arm_smmu_device *smmu =
|
||||
container_of(viommu->iommu_dev, struct arm_smmu_device, iommu);
|
||||
struct arm_smmu_domain *s2_parent = to_smmu_domain(parent_domain);
|
||||
|
||||
if (s2_parent->smmu != smmu)
|
||||
return -EINVAL;
|
||||
|
||||
vsmmu->smmu = smmu;
|
||||
vsmmu->s2_parent = s2_parent;
|
||||
/* FIXME Move VMID allocation from the S2 domain allocation to here */
|
||||
vsmmu->vmid = s2_parent->s2_cfg.vmid;
|
||||
|
||||
return &vsmmu->core;
|
||||
viommu->ops = &arm_vsmmu_ops;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster, u64 *evt)
|
||||
|
|
|
|||
|
|
@ -3688,7 +3688,8 @@ static struct iommu_ops arm_smmu_ops = {
|
|||
.get_resv_regions = arm_smmu_get_resv_regions,
|
||||
.page_response = arm_smmu_page_response,
|
||||
.def_domain_type = arm_smmu_def_domain_type,
|
||||
.viommu_alloc = arm_vsmmu_alloc,
|
||||
.get_viommu_size = arm_smmu_get_viommu_size,
|
||||
.viommu_init = arm_vsmmu_init,
|
||||
.user_pasid_table = 1,
|
||||
.pgsize_bitmap = -1UL, /* Restricted during device attach */
|
||||
.owner = THIS_MODULE,
|
||||
|
|
|
|||
|
|
@ -1034,18 +1034,19 @@ struct arm_vsmmu {
|
|||
|
||||
#if IS_ENABLED(CONFIG_ARM_SMMU_V3_IOMMUFD)
|
||||
void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type);
|
||||
struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
|
||||
struct iommu_domain *parent,
|
||||
struct iommufd_ctx *ictx,
|
||||
unsigned int viommu_type);
|
||||
size_t arm_smmu_get_viommu_size(struct device *dev,
|
||||
enum iommu_viommu_type viommu_type);
|
||||
int arm_vsmmu_init(struct iommufd_viommu *viommu,
|
||||
struct iommu_domain *parent_domain);
|
||||
int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
|
||||
struct arm_smmu_nested_domain *nested_domain);
|
||||
void arm_smmu_attach_commit_vmaster(struct arm_smmu_attach_state *state);
|
||||
void arm_smmu_master_clear_vmaster(struct arm_smmu_master *master);
|
||||
int arm_vmaster_report_event(struct arm_smmu_vmaster *vmaster, u64 *evt);
|
||||
#else
|
||||
#define arm_smmu_get_viommu_size NULL
|
||||
#define arm_smmu_hw_info NULL
|
||||
#define arm_vsmmu_alloc NULL
|
||||
#define arm_vsmmu_init NULL
|
||||
|
||||
static inline int
|
||||
arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user