Skip to content

Commit b7a0855

Browse files
jgunthorpejoergroedel
authored andcommitted
iommu: Add new flag to explictly request PASID capable domain
Introduce new flag (IOMMU_HWPT_ALLOC_PASID) to domain_alloc_users() ops. If IOMMU supports PASID it will allocate domain. Otherwise return error. In error path check for -EOPNOTSUPP and try to allocate non-PASID domain so that DMA-API mode work fine for drivers which does not support PASID as well. Also modify __iommu_group_alloc_default_domain() to call iommu_paging_domain_alloc_flags() with appropriate flag when allocating paging domain. Signed-off-by: Jason Gunthorpe <[email protected]> Co-developed-by: Vasant Hegde <[email protected]> Signed-off-by: Vasant Hegde <[email protected]> Reviewed-by: Lu Baolu <[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 20858d4 commit b7a0855

File tree

2 files changed

+53
-11
lines changed

2 files changed

+53
-11
lines changed

drivers/iommu/iommu.c

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <trace/events/iommu.h>
3333
#include <linux/sched/mm.h>
3434
#include <linux/msi.h>
35+
#include <uapi/linux/iommufd.h>
3536

3637
#include "dma-iommu.h"
3738
#include "iommu-priv.h"
@@ -99,6 +100,9 @@ static int __iommu_attach_device(struct iommu_domain *domain,
99100
struct device *dev);
100101
static int __iommu_attach_group(struct iommu_domain *domain,
101102
struct iommu_group *group);
103+
static struct iommu_domain *__iommu_paging_domain_alloc_flags(struct device *dev,
104+
unsigned int type,
105+
unsigned int flags);
102106

103107
enum {
104108
IOMMU_SET_DOMAIN_MUST_SUCCEED = 1 << 0,
@@ -1585,8 +1589,30 @@ EXPORT_SYMBOL_GPL(fsl_mc_device_group);
15851589
static struct iommu_domain *
15861590
__iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
15871591
{
1592+
struct device *dev = iommu_group_first_dev(group);
1593+
struct iommu_domain *dom;
1594+
15881595
if (group->default_domain && group->default_domain->type == req_type)
15891596
return group->default_domain;
1597+
1598+
/*
1599+
* When allocating the DMA API domain assume that the driver is going to
1600+
* use PASID and make sure the RID's domain is PASID compatible.
1601+
*/
1602+
if (req_type & __IOMMU_DOMAIN_PAGING) {
1603+
dom = __iommu_paging_domain_alloc_flags(dev, req_type,
1604+
dev->iommu->max_pasids ? IOMMU_HWPT_ALLOC_PASID : 0);
1605+
1606+
/*
1607+
* If driver does not support PASID feature then
1608+
* try to allocate non-PASID domain
1609+
*/
1610+
if (PTR_ERR(dom) == -EOPNOTSUPP)
1611+
dom = __iommu_paging_domain_alloc_flags(dev, req_type, 0);
1612+
1613+
return dom;
1614+
}
1615+
15901616
return __iommu_group_domain_alloc(group, req_type);
15911617
}
15921618

@@ -1961,16 +1987,9 @@ __iommu_group_domain_alloc(struct iommu_group *group, unsigned int type)
19611987
return __iommu_domain_alloc(dev_iommu_ops(dev), dev, type);
19621988
}
19631989

1964-
/**
1965-
* iommu_paging_domain_alloc_flags() - Allocate a paging domain
1966-
* @dev: device for which the domain is allocated
1967-
* @flags: Enum of iommufd_hwpt_alloc_flags
1968-
*
1969-
* Allocate a paging domain which will be managed by a kernel driver. Return
1970-
* allocated domain if successful, or an ERR pointer for failure.
1971-
*/
1972-
struct iommu_domain *iommu_paging_domain_alloc_flags(struct device *dev,
1973-
unsigned int flags)
1990+
static struct iommu_domain *
1991+
__iommu_paging_domain_alloc_flags(struct device *dev, unsigned int type,
1992+
unsigned int flags)
19741993
{
19751994
const struct iommu_ops *ops;
19761995
struct iommu_domain *domain;
@@ -1994,9 +2013,24 @@ struct iommu_domain *iommu_paging_domain_alloc_flags(struct device *dev,
19942013
if (!domain)
19952014
return ERR_PTR(-ENOMEM);
19962015

1997-
iommu_domain_init(domain, IOMMU_DOMAIN_UNMANAGED, ops);
2016+
iommu_domain_init(domain, type, ops);
19982017
return domain;
19992018
}
2019+
2020+
/**
2021+
* iommu_paging_domain_alloc_flags() - Allocate a paging domain
2022+
* @dev: device for which the domain is allocated
2023+
* @flags: Bitmap of iommufd_hwpt_alloc_flags
2024+
*
2025+
* Allocate a paging domain which will be managed by a kernel driver. Return
2026+
* allocated domain if successful, or an ERR pointer for failure.
2027+
*/
2028+
struct iommu_domain *iommu_paging_domain_alloc_flags(struct device *dev,
2029+
unsigned int flags)
2030+
{
2031+
return __iommu_paging_domain_alloc_flags(dev,
2032+
IOMMU_DOMAIN_UNMANAGED, flags);
2033+
}
20002034
EXPORT_SYMBOL_GPL(iommu_paging_domain_alloc_flags);
20012035

20022036
void iommu_domain_free(struct iommu_domain *domain)

include/uapi/linux/iommufd.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,11 +359,19 @@ struct iommu_vfio_ioas {
359359
* enforced on device attachment
360360
* @IOMMU_HWPT_FAULT_ID_VALID: The fault_id field of hwpt allocation data is
361361
* valid.
362+
* @IOMMU_HWPT_ALLOC_PASID: Requests a domain that can be used with PASID. The
363+
* domain can be attached to any PASID on the device.
364+
* Any domain attached to the non-PASID part of the
365+
* device must also be flaged, otherwise attaching a
366+
* PASID will blocked.
367+
* If IOMMU does not support PASID it will return
368+
* error (-EOPNOTSUPP).
362369
*/
363370
enum iommufd_hwpt_alloc_flags {
364371
IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0,
365372
IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1,
366373
IOMMU_HWPT_FAULT_ID_VALID = 1 << 2,
374+
IOMMU_HWPT_ALLOC_PASID = 1 << 3,
367375
};
368376

369377
/**

0 commit comments

Comments
 (0)