Skip to content

Commit 1364679

Browse files
LuBaolujoergroedel
authored andcommitted
iommu: Add IOMMU SVA domain support
The SVA iommu_domain represents a hardware pagetable that the IOMMU hardware could use for SVA translation. This adds some infrastructures to support SVA domain in the iommu core. It includes: - Extend the iommu_domain to support a new IOMMU_DOMAIN_SVA domain type. The IOMMU drivers that support allocation of the SVA domain should provide its own SVA domain specific iommu_domain_ops. - Add a helper to allocate an SVA domain. The iommu_domain_free() is still used to free an SVA domain. The report_iommu_fault() should be replaced by the new iommu_report_device_fault(). Leave the existing fault handler with the existing users and the newly added SVA members excludes it. Suggested-by: Jean-Philippe Brucker <[email protected]> Suggested-by: Jason Gunthorpe <[email protected]> Signed-off-by: Lu Baolu <[email protected]> Reviewed-by: Jean-Philippe Brucker <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Reviewed-by: Yi Liu <[email protected]> Tested-by: Zhangfei Gao <[email protected]> Tested-by: Tony Zhu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 1660370 commit 1364679

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

drivers/iommu/iommu.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <linux/module.h>
3030
#include <linux/cc_platform.h>
3131
#include <trace/events/iommu.h>
32+
#include <linux/sched/mm.h>
3233

3334
#include "dma-iommu.h"
3435

@@ -1934,6 +1935,8 @@ EXPORT_SYMBOL_GPL(iommu_domain_alloc);
19341935

19351936
void iommu_domain_free(struct iommu_domain *domain)
19361937
{
1938+
if (domain->type == IOMMU_DOMAIN_SVA)
1939+
mmdrop(domain->mm);
19371940
iommu_put_dma_cookie(domain);
19381941
domain->ops->free(domain);
19391942
}
@@ -3383,3 +3386,20 @@ struct iommu_domain *iommu_get_domain_for_dev_pasid(struct device *dev,
33833386
return domain;
33843387
}
33853388
EXPORT_SYMBOL_GPL(iommu_get_domain_for_dev_pasid);
3389+
3390+
struct iommu_domain *iommu_sva_domain_alloc(struct device *dev,
3391+
struct mm_struct *mm)
3392+
{
3393+
const struct iommu_ops *ops = dev_iommu_ops(dev);
3394+
struct iommu_domain *domain;
3395+
3396+
domain = ops->domain_alloc(IOMMU_DOMAIN_SVA);
3397+
if (!domain)
3398+
return NULL;
3399+
3400+
domain->type = IOMMU_DOMAIN_SVA;
3401+
mmgrab(mm);
3402+
domain->mm = mm;
3403+
3404+
return domain;
3405+
}

include/linux/iommu.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ struct iommu_domain_geometry {
6464
#define __IOMMU_DOMAIN_PT (1U << 2) /* Domain is identity mapped */
6565
#define __IOMMU_DOMAIN_DMA_FQ (1U << 3) /* DMA-API uses flush queue */
6666

67+
#define __IOMMU_DOMAIN_SVA (1U << 4) /* Shared process address space */
68+
6769
/*
6870
* This are the possible domain-types
6971
*
@@ -77,6 +79,8 @@ struct iommu_domain_geometry {
7779
* certain optimizations for these domains
7880
* IOMMU_DOMAIN_DMA_FQ - As above, but definitely using batched TLB
7981
* invalidation.
82+
* IOMMU_DOMAIN_SVA - DMA addresses are shared process addresses
83+
* represented by mm_struct's.
8084
*/
8185
#define IOMMU_DOMAIN_BLOCKED (0U)
8286
#define IOMMU_DOMAIN_IDENTITY (__IOMMU_DOMAIN_PT)
@@ -86,15 +90,24 @@ struct iommu_domain_geometry {
8690
#define IOMMU_DOMAIN_DMA_FQ (__IOMMU_DOMAIN_PAGING | \
8791
__IOMMU_DOMAIN_DMA_API | \
8892
__IOMMU_DOMAIN_DMA_FQ)
93+
#define IOMMU_DOMAIN_SVA (__IOMMU_DOMAIN_SVA)
8994

9095
struct iommu_domain {
9196
unsigned type;
9297
const struct iommu_domain_ops *ops;
9398
unsigned long pgsize_bitmap; /* Bitmap of page sizes in use */
94-
iommu_fault_handler_t handler;
95-
void *handler_token;
9699
struct iommu_domain_geometry geometry;
97100
struct iommu_dma_cookie *iova_cookie;
101+
union {
102+
struct {
103+
iommu_fault_handler_t handler;
104+
void *handler_token;
105+
};
106+
struct { /* IOMMU_DOMAIN_SVA */
107+
struct mm_struct *mm;
108+
int users;
109+
};
110+
};
98111
};
99112

100113
static inline bool iommu_is_dma_domain(struct iommu_domain *domain)
@@ -685,6 +698,8 @@ int iommu_group_claim_dma_owner(struct iommu_group *group, void *owner);
685698
void iommu_group_release_dma_owner(struct iommu_group *group);
686699
bool iommu_group_dma_owner_claimed(struct iommu_group *group);
687700

701+
struct iommu_domain *iommu_sva_domain_alloc(struct device *dev,
702+
struct mm_struct *mm);
688703
int iommu_attach_device_pasid(struct iommu_domain *domain,
689704
struct device *dev, ioasid_t pasid);
690705
void iommu_detach_device_pasid(struct iommu_domain *domain,
@@ -1055,6 +1070,12 @@ static inline bool iommu_group_dma_owner_claimed(struct iommu_group *group)
10551070
return false;
10561071
}
10571072

1073+
static inline struct iommu_domain *
1074+
iommu_sva_domain_alloc(struct device *dev, struct mm_struct *mm)
1075+
{
1076+
return NULL;
1077+
}
1078+
10581079
static inline int iommu_attach_device_pasid(struct iommu_domain *domain,
10591080
struct device *dev, ioasid_t pasid)
10601081
{

0 commit comments

Comments
 (0)