mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 10:45:49 +00:00
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 <jgg@ziepe.ca> Co-developed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Link: https://lore.kernel.org/r/20241028093810.5901-4-vasant.hegde@amd.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
20858d4ebb
commit
b7a0855eb9
@ -32,6 +32,7 @@
|
|||||||
#include <trace/events/iommu.h>
|
#include <trace/events/iommu.h>
|
||||||
#include <linux/sched/mm.h>
|
#include <linux/sched/mm.h>
|
||||||
#include <linux/msi.h>
|
#include <linux/msi.h>
|
||||||
|
#include <uapi/linux/iommufd.h>
|
||||||
|
|
||||||
#include "dma-iommu.h"
|
#include "dma-iommu.h"
|
||||||
#include "iommu-priv.h"
|
#include "iommu-priv.h"
|
||||||
@ -99,6 +100,9 @@ static int __iommu_attach_device(struct iommu_domain *domain,
|
|||||||
struct device *dev);
|
struct device *dev);
|
||||||
static int __iommu_attach_group(struct iommu_domain *domain,
|
static int __iommu_attach_group(struct iommu_domain *domain,
|
||||||
struct iommu_group *group);
|
struct iommu_group *group);
|
||||||
|
static struct iommu_domain *__iommu_paging_domain_alloc_flags(struct device *dev,
|
||||||
|
unsigned int type,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
IOMMU_SET_DOMAIN_MUST_SUCCEED = 1 << 0,
|
IOMMU_SET_DOMAIN_MUST_SUCCEED = 1 << 0,
|
||||||
@ -1585,8 +1589,30 @@ EXPORT_SYMBOL_GPL(fsl_mc_device_group);
|
|||||||
static struct iommu_domain *
|
static struct iommu_domain *
|
||||||
__iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
|
__iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
|
||||||
{
|
{
|
||||||
|
struct device *dev = iommu_group_first_dev(group);
|
||||||
|
struct iommu_domain *dom;
|
||||||
|
|
||||||
if (group->default_domain && group->default_domain->type == req_type)
|
if (group->default_domain && group->default_domain->type == req_type)
|
||||||
return group->default_domain;
|
return group->default_domain;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When allocating the DMA API domain assume that the driver is going to
|
||||||
|
* use PASID and make sure the RID's domain is PASID compatible.
|
||||||
|
*/
|
||||||
|
if (req_type & __IOMMU_DOMAIN_PAGING) {
|
||||||
|
dom = __iommu_paging_domain_alloc_flags(dev, req_type,
|
||||||
|
dev->iommu->max_pasids ? IOMMU_HWPT_ALLOC_PASID : 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If driver does not support PASID feature then
|
||||||
|
* try to allocate non-PASID domain
|
||||||
|
*/
|
||||||
|
if (PTR_ERR(dom) == -EOPNOTSUPP)
|
||||||
|
dom = __iommu_paging_domain_alloc_flags(dev, req_type, 0);
|
||||||
|
|
||||||
|
return dom;
|
||||||
|
}
|
||||||
|
|
||||||
return __iommu_group_domain_alloc(group, req_type);
|
return __iommu_group_domain_alloc(group, req_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1961,16 +1987,9 @@ __iommu_group_domain_alloc(struct iommu_group *group, unsigned int type)
|
|||||||
return __iommu_domain_alloc(dev_iommu_ops(dev), dev, type);
|
return __iommu_domain_alloc(dev_iommu_ops(dev), dev, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static struct iommu_domain *
|
||||||
* iommu_paging_domain_alloc_flags() - Allocate a paging domain
|
__iommu_paging_domain_alloc_flags(struct device *dev, unsigned int type,
|
||||||
* @dev: device for which the domain is allocated
|
unsigned int flags)
|
||||||
* @flags: Enum of iommufd_hwpt_alloc_flags
|
|
||||||
*
|
|
||||||
* Allocate a paging domain which will be managed by a kernel driver. Return
|
|
||||||
* allocated domain if successful, or an ERR pointer for failure.
|
|
||||||
*/
|
|
||||||
struct iommu_domain *iommu_paging_domain_alloc_flags(struct device *dev,
|
|
||||||
unsigned int flags)
|
|
||||||
{
|
{
|
||||||
const struct iommu_ops *ops;
|
const struct iommu_ops *ops;
|
||||||
struct iommu_domain *domain;
|
struct iommu_domain *domain;
|
||||||
@ -1994,9 +2013,24 @@ struct iommu_domain *iommu_paging_domain_alloc_flags(struct device *dev,
|
|||||||
if (!domain)
|
if (!domain)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
iommu_domain_init(domain, IOMMU_DOMAIN_UNMANAGED, ops);
|
iommu_domain_init(domain, type, ops);
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* iommu_paging_domain_alloc_flags() - Allocate a paging domain
|
||||||
|
* @dev: device for which the domain is allocated
|
||||||
|
* @flags: Bitmap of iommufd_hwpt_alloc_flags
|
||||||
|
*
|
||||||
|
* Allocate a paging domain which will be managed by a kernel driver. Return
|
||||||
|
* allocated domain if successful, or an ERR pointer for failure.
|
||||||
|
*/
|
||||||
|
struct iommu_domain *iommu_paging_domain_alloc_flags(struct device *dev,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
return __iommu_paging_domain_alloc_flags(dev,
|
||||||
|
IOMMU_DOMAIN_UNMANAGED, flags);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL_GPL(iommu_paging_domain_alloc_flags);
|
EXPORT_SYMBOL_GPL(iommu_paging_domain_alloc_flags);
|
||||||
|
|
||||||
void iommu_domain_free(struct iommu_domain *domain)
|
void iommu_domain_free(struct iommu_domain *domain)
|
||||||
|
@ -359,11 +359,19 @@ struct iommu_vfio_ioas {
|
|||||||
* enforced on device attachment
|
* enforced on device attachment
|
||||||
* @IOMMU_HWPT_FAULT_ID_VALID: The fault_id field of hwpt allocation data is
|
* @IOMMU_HWPT_FAULT_ID_VALID: The fault_id field of hwpt allocation data is
|
||||||
* valid.
|
* valid.
|
||||||
|
* @IOMMU_HWPT_ALLOC_PASID: Requests a domain that can be used with PASID. The
|
||||||
|
* domain can be attached to any PASID on the device.
|
||||||
|
* Any domain attached to the non-PASID part of the
|
||||||
|
* device must also be flaged, otherwise attaching a
|
||||||
|
* PASID will blocked.
|
||||||
|
* If IOMMU does not support PASID it will return
|
||||||
|
* error (-EOPNOTSUPP).
|
||||||
*/
|
*/
|
||||||
enum iommufd_hwpt_alloc_flags {
|
enum iommufd_hwpt_alloc_flags {
|
||||||
IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0,
|
IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0,
|
||||||
IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1,
|
IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1,
|
||||||
IOMMU_HWPT_FAULT_ID_VALID = 1 << 2,
|
IOMMU_HWPT_FAULT_ID_VALID = 1 << 2,
|
||||||
|
IOMMU_HWPT_ALLOC_PASID = 1 << 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user