Skip to content

Commit 20858d4

Browse files
jgunthorpejoergroedel
authored andcommitted
iommu: Introduce iommu_paging_domain_alloc_flags()
Currently drivers calls iommu_paging_domain_alloc(dev) to get an UNMANAGED domain. This is not sufficient to support PASID with UNMANAGED domain as some HW like AMD requires certain page table type to support PASIDs. Also the domain_alloc_paging op only passes device as param for domain allocation. This is not sufficient for AMD driver to decide the right page table. Instead of extending ops->domain_alloc_paging() it was decided to enhance ops->domain_alloc_user() so that caller can pass various additional flags. Hence add iommu_paging_domain_alloc_flags() API which takes flags as parameter. Caller can pass additional parameter to indicate type of domain required, etc. iommu_paging_domain_alloc_flags() internally calls appropriate callback function to allocate a domain. Signed-off-by: Jason Gunthorpe <[email protected]> [Added description - Vasant] Signed-off-by: Vasant Hegde <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Reviewed-by: Lu Baolu <[email protected]> Reviewed-by: Yi Liu <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 541b967 commit 20858d4

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

drivers/iommu/iommu.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,20 +1962,42 @@ __iommu_group_domain_alloc(struct iommu_group *group, unsigned int type)
19621962
}
19631963

19641964
/**
1965-
* iommu_paging_domain_alloc() - Allocate a paging domain
1965+
* iommu_paging_domain_alloc_flags() - Allocate a paging domain
19661966
* @dev: device for which the domain is allocated
1967+
* @flags: Enum of iommufd_hwpt_alloc_flags
19671968
*
19681969
* Allocate a paging domain which will be managed by a kernel driver. Return
1969-
* allocated domain if successful, or a ERR pointer for failure.
1970+
* allocated domain if successful, or an ERR pointer for failure.
19701971
*/
1971-
struct iommu_domain *iommu_paging_domain_alloc(struct device *dev)
1972+
struct iommu_domain *iommu_paging_domain_alloc_flags(struct device *dev,
1973+
unsigned int flags)
19721974
{
1975+
const struct iommu_ops *ops;
1976+
struct iommu_domain *domain;
1977+
19731978
if (!dev_has_iommu(dev))
19741979
return ERR_PTR(-ENODEV);
19751980

1976-
return __iommu_domain_alloc(dev_iommu_ops(dev), dev, IOMMU_DOMAIN_UNMANAGED);
1981+
ops = dev_iommu_ops(dev);
1982+
1983+
if (ops->domain_alloc_paging && !flags)
1984+
domain = ops->domain_alloc_paging(dev);
1985+
else if (ops->domain_alloc_user)
1986+
domain = ops->domain_alloc_user(dev, flags, NULL, NULL);
1987+
else if (ops->domain_alloc && !flags)
1988+
domain = ops->domain_alloc(IOMMU_DOMAIN_UNMANAGED);
1989+
else
1990+
return ERR_PTR(-EOPNOTSUPP);
1991+
1992+
if (IS_ERR(domain))
1993+
return domain;
1994+
if (!domain)
1995+
return ERR_PTR(-ENOMEM);
1996+
1997+
iommu_domain_init(domain, IOMMU_DOMAIN_UNMANAGED, ops);
1998+
return domain;
19771999
}
1978-
EXPORT_SYMBOL_GPL(iommu_paging_domain_alloc);
2000+
EXPORT_SYMBOL_GPL(iommu_paging_domain_alloc_flags);
19792001

19802002
void iommu_domain_free(struct iommu_domain *domain)
19812003
{

include/linux/iommu.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -511,8 +511,6 @@ static inline int __iommu_copy_struct_from_user_array(
511511
* the caller iommu_domain_alloc() returns.
512512
* @domain_alloc_user: Allocate an iommu domain corresponding to the input
513513
* parameters as defined in include/uapi/linux/iommufd.h.
514-
* Unlike @domain_alloc, it is called only by IOMMUFD and
515-
* must fully initialize the new domain before return.
516514
* Upon success, if the @user_data is valid and the @parent
517515
* points to a kernel-managed domain, the new domain must be
518516
* IOMMU_DOMAIN_NESTED type; otherwise, the @parent must be
@@ -787,7 +785,11 @@ static inline void iommu_iotlb_gather_init(struct iommu_iotlb_gather *gather)
787785
extern int bus_iommu_probe(const struct bus_type *bus);
788786
extern bool device_iommu_capable(struct device *dev, enum iommu_cap cap);
789787
extern bool iommu_group_has_isolated_msi(struct iommu_group *group);
790-
struct iommu_domain *iommu_paging_domain_alloc(struct device *dev);
788+
struct iommu_domain *iommu_paging_domain_alloc_flags(struct device *dev, unsigned int flags);
789+
static inline struct iommu_domain *iommu_paging_domain_alloc(struct device *dev)
790+
{
791+
return iommu_paging_domain_alloc_flags(dev, 0);
792+
}
791793
extern void iommu_domain_free(struct iommu_domain *domain);
792794
extern int iommu_attach_device(struct iommu_domain *domain,
793795
struct device *dev);
@@ -1078,6 +1080,12 @@ static inline bool device_iommu_capable(struct device *dev, enum iommu_cap cap)
10781080
return false;
10791081
}
10801082

1083+
struct iommu_domain *iommu_paging_domain_alloc_flags(struct device *dev,
1084+
unsigned int flags)
1085+
{
1086+
return ERR_PTR(-ENODEV);
1087+
}
1088+
10811089
static inline struct iommu_domain *iommu_paging_domain_alloc(struct device *dev)
10821090
{
10831091
return ERR_PTR(-ENODEV);

0 commit comments

Comments
 (0)