mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +00:00
iommufd 6.13 merge window pull #2
Change the driver callback op domain_alloc_user() into two ops domain_alloc_paging_flags() and domain_alloc_nesting() that better describe what the ops are expected to do. There will be per-driver cleanup based on this going into the next cycle via the driver trees. -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRRRCHOFoQz/8F5bUaFwuHvBreFYQUCZ0c+GQAKCRCFwuHvBreF YVJXAP97zriu5x9AVNzG6mLOOYYROuhCTXGieKPqNg/apGOyogD/cMuMql3w86h+ oBIMai6GaTBUU+Ie8S07PM0849TpLgA= =yyYk -----END PGP SIGNATURE----- Merge tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd Pull more iommufd updates from Jason Gunthorpe: "Change the driver callback op domain_alloc_user() into two ops: domain_alloc_paging_flags() and domain_alloc_nesting() that better describe what the ops are expected to do. There will be per-driver cleanup based on this going into the next cycle via the driver trees" * tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd: iommu: Rename ops->domain_alloc_user() to domain_alloc_paging_flags() iommu: Add ops->domain_alloc_nested()
This commit is contained in:
commit
64e6fc27d6
@ -2407,9 +2407,8 @@ static struct iommu_domain *amd_iommu_domain_alloc(unsigned int type)
|
||||
}
|
||||
|
||||
static struct iommu_domain *
|
||||
amd_iommu_domain_alloc_user(struct device *dev, u32 flags,
|
||||
struct iommu_domain *parent,
|
||||
const struct iommu_user_data *user_data)
|
||||
amd_iommu_domain_alloc_paging_flags(struct device *dev, u32 flags,
|
||||
const struct iommu_user_data *user_data)
|
||||
|
||||
{
|
||||
unsigned int type = IOMMU_DOMAIN_UNMANAGED;
|
||||
@ -2420,7 +2419,7 @@ amd_iommu_domain_alloc_user(struct device *dev, u32 flags,
|
||||
if (dev)
|
||||
iommu = get_amd_iommu_from_dev(dev);
|
||||
|
||||
if ((flags & ~supported_flags) || parent || user_data)
|
||||
if ((flags & ~supported_flags) || user_data)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
/* Allocate domain with v2 page table if IOMMU supports PASID. */
|
||||
@ -2884,7 +2883,7 @@ const struct iommu_ops amd_iommu_ops = {
|
||||
.release_domain = &release_domain,
|
||||
.identity_domain = &identity_domain.domain,
|
||||
.domain_alloc = amd_iommu_domain_alloc,
|
||||
.domain_alloc_user = amd_iommu_domain_alloc_user,
|
||||
.domain_alloc_paging_flags = amd_iommu_domain_alloc_paging_flags,
|
||||
.domain_alloc_sva = amd_iommu_domain_alloc_sva,
|
||||
.probe_device = amd_iommu_probe_device,
|
||||
.release_device = amd_iommu_release_device,
|
||||
|
@ -3132,9 +3132,8 @@ static struct iommu_domain arm_smmu_blocked_domain = {
|
||||
};
|
||||
|
||||
static struct iommu_domain *
|
||||
arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
|
||||
struct iommu_domain *parent,
|
||||
const struct iommu_user_data *user_data)
|
||||
arm_smmu_domain_alloc_paging_flags(struct device *dev, u32 flags,
|
||||
const struct iommu_user_data *user_data)
|
||||
{
|
||||
struct arm_smmu_master *master = dev_iommu_priv_get(dev);
|
||||
const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_DIRTY_TRACKING |
|
||||
@ -3145,7 +3144,7 @@ arm_smmu_domain_alloc_user(struct device *dev, u32 flags,
|
||||
|
||||
if (flags & ~PAGING_FLAGS)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
if (parent || user_data)
|
||||
if (user_data)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
if (flags & IOMMU_HWPT_ALLOC_PASID)
|
||||
@ -3546,7 +3545,7 @@ static struct iommu_ops arm_smmu_ops = {
|
||||
.hw_info = arm_smmu_hw_info,
|
||||
.domain_alloc_paging = arm_smmu_domain_alloc_paging,
|
||||
.domain_alloc_sva = arm_smmu_sva_domain_alloc,
|
||||
.domain_alloc_user = arm_smmu_domain_alloc_user,
|
||||
.domain_alloc_paging_flags = arm_smmu_domain_alloc_paging_flags,
|
||||
.probe_device = arm_smmu_probe_device,
|
||||
.release_device = arm_smmu_release_device,
|
||||
.device_group = arm_smmu_device_group,
|
||||
|
@ -3328,9 +3328,8 @@ static struct dmar_domain *paging_domain_alloc(struct device *dev, bool first_st
|
||||
}
|
||||
|
||||
static struct iommu_domain *
|
||||
intel_iommu_domain_alloc_user(struct device *dev, u32 flags,
|
||||
struct iommu_domain *parent,
|
||||
const struct iommu_user_data *user_data)
|
||||
intel_iommu_domain_alloc_paging_flags(struct device *dev, u32 flags,
|
||||
const struct iommu_user_data *user_data)
|
||||
{
|
||||
struct device_domain_info *info = dev_iommu_priv_get(dev);
|
||||
bool dirty_tracking = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
|
||||
@ -3340,13 +3339,6 @@ intel_iommu_domain_alloc_user(struct device *dev, u32 flags,
|
||||
struct iommu_domain *domain;
|
||||
bool first_stage;
|
||||
|
||||
/* Must be NESTING domain */
|
||||
if (parent) {
|
||||
if (!nested_supported(iommu) || flags)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
return intel_nested_domain_alloc(parent, user_data);
|
||||
}
|
||||
|
||||
if (flags &
|
||||
(~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING
|
||||
| IOMMU_HWPT_FAULT_ID_VALID)))
|
||||
@ -4472,9 +4464,10 @@ const struct iommu_ops intel_iommu_ops = {
|
||||
.identity_domain = &identity_domain,
|
||||
.capable = intel_iommu_capable,
|
||||
.hw_info = intel_iommu_hw_info,
|
||||
.domain_alloc_user = intel_iommu_domain_alloc_user,
|
||||
.domain_alloc_paging_flags = intel_iommu_domain_alloc_paging_flags,
|
||||
.domain_alloc_sva = intel_svm_domain_alloc,
|
||||
.domain_alloc_paging = intel_iommu_domain_alloc_paging,
|
||||
.domain_alloc_nested = intel_iommu_domain_alloc_nested,
|
||||
.probe_device = intel_iommu_probe_device,
|
||||
.release_device = intel_iommu_release_device,
|
||||
.get_resv_regions = intel_iommu_get_resv_regions,
|
||||
|
@ -1265,8 +1265,10 @@ int __domain_setup_first_level(struct intel_iommu *iommu,
|
||||
int dmar_ir_support(void);
|
||||
|
||||
void iommu_flush_write_buffer(struct intel_iommu *iommu);
|
||||
struct iommu_domain *intel_nested_domain_alloc(struct iommu_domain *parent,
|
||||
const struct iommu_user_data *user_data);
|
||||
struct iommu_domain *
|
||||
intel_iommu_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,
|
||||
u32 flags,
|
||||
const struct iommu_user_data *user_data);
|
||||
struct device *device_rbtree_find(struct intel_iommu *iommu, u16 rid);
|
||||
|
||||
enum cache_tag_type {
|
||||
|
@ -186,14 +186,21 @@ static const struct iommu_domain_ops intel_nested_domain_ops = {
|
||||
.cache_invalidate_user = intel_nested_cache_invalidate_user,
|
||||
};
|
||||
|
||||
struct iommu_domain *intel_nested_domain_alloc(struct iommu_domain *parent,
|
||||
const struct iommu_user_data *user_data)
|
||||
struct iommu_domain *
|
||||
intel_iommu_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,
|
||||
u32 flags,
|
||||
const struct iommu_user_data *user_data)
|
||||
{
|
||||
struct device_domain_info *info = dev_iommu_priv_get(dev);
|
||||
struct dmar_domain *s2_domain = to_dmar_domain(parent);
|
||||
struct intel_iommu *iommu = info->iommu;
|
||||
struct iommu_hwpt_vtd_s1 vtd;
|
||||
struct dmar_domain *domain;
|
||||
int ret;
|
||||
|
||||
if (!nested_supported(iommu) || flags)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
/* Must be nested domain */
|
||||
if (user_data->type != IOMMU_HWPT_DATA_VTD_S1)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
@ -1987,8 +1987,8 @@ __iommu_paging_domain_alloc_flags(struct device *dev, unsigned int type,
|
||||
|
||||
if (ops->domain_alloc_paging && !flags)
|
||||
domain = ops->domain_alloc_paging(dev);
|
||||
else if (ops->domain_alloc_user)
|
||||
domain = ops->domain_alloc_user(dev, flags, NULL, NULL);
|
||||
else if (ops->domain_alloc_paging_flags)
|
||||
domain = ops->domain_alloc_paging_flags(dev, flags, NULL);
|
||||
else if (ops->domain_alloc && !flags)
|
||||
domain = ops->domain_alloc(IOMMU_DOMAIN_UNMANAGED);
|
||||
else
|
||||
|
@ -119,7 +119,7 @@ iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
|
||||
|
||||
lockdep_assert_held(&ioas->mutex);
|
||||
|
||||
if ((flags || user_data) && !ops->domain_alloc_user)
|
||||
if ((flags || user_data) && !ops->domain_alloc_paging_flags)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
if (flags & ~valid_flags)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
@ -139,9 +139,9 @@ iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
|
||||
hwpt_paging->ioas = ioas;
|
||||
hwpt_paging->nest_parent = flags & IOMMU_HWPT_ALLOC_NEST_PARENT;
|
||||
|
||||
if (ops->domain_alloc_user) {
|
||||
hwpt->domain = ops->domain_alloc_user(idev->dev, flags, NULL,
|
||||
user_data);
|
||||
if (ops->domain_alloc_paging_flags) {
|
||||
hwpt->domain = ops->domain_alloc_paging_flags(idev->dev, flags,
|
||||
user_data);
|
||||
if (IS_ERR(hwpt->domain)) {
|
||||
rc = PTR_ERR(hwpt->domain);
|
||||
hwpt->domain = NULL;
|
||||
@ -227,7 +227,7 @@ iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx,
|
||||
int rc;
|
||||
|
||||
if ((flags & ~IOMMU_HWPT_FAULT_ID_VALID) ||
|
||||
!user_data->len || !ops->domain_alloc_user)
|
||||
!user_data->len || !ops->domain_alloc_nested)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
if (parent->auto_domain || !parent->nest_parent ||
|
||||
parent->common.domain->owner != ops)
|
||||
@ -242,9 +242,9 @@ iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx,
|
||||
refcount_inc(&parent->common.obj.users);
|
||||
hwpt_nested->parent = parent;
|
||||
|
||||
hwpt->domain = ops->domain_alloc_user(idev->dev,
|
||||
flags & ~IOMMU_HWPT_FAULT_ID_VALID,
|
||||
parent->common.domain, user_data);
|
||||
hwpt->domain = ops->domain_alloc_nested(
|
||||
idev->dev, parent->common.domain,
|
||||
flags & ~IOMMU_HWPT_FAULT_ID_VALID, user_data);
|
||||
if (IS_ERR(hwpt->domain)) {
|
||||
rc = PTR_ERR(hwpt->domain);
|
||||
hwpt->domain = NULL;
|
||||
|
@ -356,8 +356,8 @@ __mock_domain_alloc_nested(const struct iommu_user_data *user_data)
|
||||
}
|
||||
|
||||
static struct iommu_domain *
|
||||
mock_domain_alloc_nested(struct iommu_domain *parent, u32 flags,
|
||||
const struct iommu_user_data *user_data)
|
||||
mock_domain_alloc_nested(struct device *dev, struct iommu_domain *parent,
|
||||
u32 flags, const struct iommu_user_data *user_data)
|
||||
{
|
||||
struct mock_iommu_domain_nested *mock_nested;
|
||||
struct mock_iommu_domain *mock_parent;
|
||||
@ -379,9 +379,8 @@ mock_domain_alloc_nested(struct iommu_domain *parent, u32 flags,
|
||||
}
|
||||
|
||||
static struct iommu_domain *
|
||||
mock_domain_alloc_user(struct device *dev, u32 flags,
|
||||
struct iommu_domain *parent,
|
||||
const struct iommu_user_data *user_data)
|
||||
mock_domain_alloc_paging_flags(struct device *dev, u32 flags,
|
||||
const struct iommu_user_data *user_data)
|
||||
{
|
||||
bool has_dirty_flag = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
|
||||
const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_DIRTY_TRACKING |
|
||||
@ -390,9 +389,6 @@ mock_domain_alloc_user(struct device *dev, u32 flags,
|
||||
MOCK_FLAGS_DEVICE_NO_DIRTY;
|
||||
struct iommu_domain *domain;
|
||||
|
||||
if (parent)
|
||||
return mock_domain_alloc_nested(parent, flags, user_data);
|
||||
|
||||
if (user_data)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
if ((flags & ~PAGING_FLAGS) || (has_dirty_flag && no_dirty_ops))
|
||||
@ -718,7 +714,8 @@ static const struct iommu_ops mock_ops = {
|
||||
.pgsize_bitmap = MOCK_IO_PAGE_SIZE,
|
||||
.hw_info = mock_domain_hw_info,
|
||||
.domain_alloc_paging = mock_domain_alloc_paging,
|
||||
.domain_alloc_user = mock_domain_alloc_user,
|
||||
.domain_alloc_paging_flags = mock_domain_alloc_paging_flags,
|
||||
.domain_alloc_nested = mock_domain_alloc_nested,
|
||||
.capable = mock_domain_capable,
|
||||
.device_group = generic_device_group,
|
||||
.probe_device = mock_probe_device,
|
||||
|
@ -557,17 +557,19 @@ iommu_copy_struct_from_full_user_array(void *kdst, size_t kdst_entry_size,
|
||||
* @domain_alloc: allocate and return an iommu domain if success. Otherwise
|
||||
* NULL is returned. The domain is not fully initialized until
|
||||
* the caller iommu_domain_alloc() returns.
|
||||
* @domain_alloc_user: Allocate an iommu domain corresponding to the input
|
||||
* parameters as defined in include/uapi/linux/iommufd.h.
|
||||
* Upon success, if the @user_data is valid and the @parent
|
||||
* points to a kernel-managed domain, the new domain must be
|
||||
* IOMMU_DOMAIN_NESTED type; otherwise, the @parent must be
|
||||
* NULL while the @user_data can be optionally provided, the
|
||||
* new domain must support __IOMMU_DOMAIN_PAGING.
|
||||
* Upon failure, ERR_PTR must be returned.
|
||||
* @domain_alloc_paging_flags: Allocate an iommu domain corresponding to the
|
||||
* input parameters as defined in
|
||||
* include/uapi/linux/iommufd.h. The @user_data can be
|
||||
* optionally provided, the new domain must support
|
||||
* __IOMMU_DOMAIN_PAGING. Upon failure, ERR_PTR must be
|
||||
* returned.
|
||||
* @domain_alloc_paging: Allocate an iommu_domain that can be used for
|
||||
* UNMANAGED, DMA, and DMA_FQ domain types.
|
||||
* UNMANAGED, DMA, and DMA_FQ domain types. This is the
|
||||
* same as invoking domain_alloc_paging_flags() with
|
||||
* @flags=0, @user_data=NULL. A driver should implement
|
||||
* only one of the two ops.
|
||||
* @domain_alloc_sva: Allocate an iommu_domain for Shared Virtual Addressing.
|
||||
* @domain_alloc_nested: Allocate an iommu_domain for nested translation.
|
||||
* @probe_device: Add device to iommu driver handling
|
||||
* @release_device: Remove device from iommu driver handling
|
||||
* @probe_finalize: Do final setup work after the device is added to an IOMMU
|
||||
@ -616,12 +618,15 @@ struct iommu_ops {
|
||||
|
||||
/* Domain allocation and freeing by the iommu driver */
|
||||
struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type);
|
||||
struct iommu_domain *(*domain_alloc_user)(
|
||||
struct device *dev, u32 flags, struct iommu_domain *parent,
|
||||
struct iommu_domain *(*domain_alloc_paging_flags)(
|
||||
struct device *dev, u32 flags,
|
||||
const struct iommu_user_data *user_data);
|
||||
struct iommu_domain *(*domain_alloc_paging)(struct device *dev);
|
||||
struct iommu_domain *(*domain_alloc_sva)(struct device *dev,
|
||||
struct mm_struct *mm);
|
||||
struct iommu_domain *(*domain_alloc_nested)(
|
||||
struct device *dev, struct iommu_domain *parent, u32 flags,
|
||||
const struct iommu_user_data *user_data);
|
||||
|
||||
struct iommu_device *(*probe_device)(struct device *dev);
|
||||
void (*release_device)(struct device *dev);
|
||||
|
Loading…
Reference in New Issue
Block a user