On Mon, 4 Nov 2024 at 17:19, Jason Gunthorpe <jgg@xxxxxxxxxx> wrote: > > On Thu, Oct 31, 2024 at 02:21:11PM +0800, Zhangfei Gao wrote: > > > > +static struct iommu_domain * > > > +arm_vsmmu_alloc_domain_nested(struct iommufd_viommu *viommu, u32 flags, > > > + const struct iommu_user_data *user_data) > > > +{ > > > + struct arm_vsmmu *vsmmu = container_of(viommu, struct arm_vsmmu, core); > > > + struct arm_smmu_nested_domain *nested_domain; > > > + struct iommu_hwpt_arm_smmuv3 arg; > > > + int ret; > > > + > > > + if (flags) > > > + return ERR_PTR(-EOPNOTSUPP); > > > > This check fails when using user page fault, with flags = > > IOMMU_HWPT_FAULT_ID_VALID (4) > > Strange, the check is not exist in last version? > > > > iommufd_viommu_alloc_hwpt_nested -> > > viommu->ops->alloc_domain_nested(viommu, flags, user_data) -> > > arm_vsmmu_alloc_domain_nested > > It should permit IOMMU_HWPT_FAULT_ID_VALID, I'll add this hunk: > > --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c > +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c > @@ -178,12 +178,18 @@ arm_vsmmu_alloc_domain_nested(struct iommufd_viommu *viommu, u32 flags, > const struct iommu_user_data *user_data) > { > struct arm_vsmmu *vsmmu = container_of(viommu, struct arm_vsmmu, core); > + const u32 SUPPORTED_FLAGS = IOMMU_HWPT_FAULT_ID_VALID; > struct arm_smmu_nested_domain *nested_domain; > struct iommu_hwpt_arm_smmuv3 arg; > bool enable_ats = false; > int ret; > > - if (flags) > + /* > + * Faults delivered to the nested domain are faults that originated by > + * the S1 in the domain. The core code will match all PASIDs when > + * delivering the fault due to user_pasid_table > + */ > + if (flags & ~SUPPORTED_FLAGS) > return ERR_PTR(-EOPNOTSUPP); Thanks Jason, this works