Skip to content

Commit 7423e01

Browse files
LuBaolujoergroedel
authored andcommitted
iommu: Add API to request DMA domain for device
Normally during iommu probing a device, a default doamin will be allocated and attached to the device. The domain type of the default domain is statically defined, which results in a situation where the allocated default domain isn't suitable for the device due to some limitations. We already have API iommu_request_dm_for_dev() to replace a DMA domain with an identity one. This adds iommu_request_dma_domain_for_dev() to request a dma domain if an allocated identity domain isn't suitable for the device in question. Signed-off-by: Lu Baolu <[email protected]> Signed-off-by: Joerg Roedel <[email protected]>
1 parent dd5142c commit 7423e01

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

drivers/iommu/iommu.c

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1907,10 +1907,10 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
19071907
return region;
19081908
}
19091909

1910-
/* Request that a device is direct mapped by the IOMMU */
1911-
int iommu_request_dm_for_dev(struct device *dev)
1910+
static int
1911+
request_default_domain_for_dev(struct device *dev, unsigned long type)
19121912
{
1913-
struct iommu_domain *dm_domain;
1913+
struct iommu_domain *domain;
19141914
struct iommu_group *group;
19151915
int ret;
19161916

@@ -1923,8 +1923,7 @@ int iommu_request_dm_for_dev(struct device *dev)
19231923

19241924
/* Check if the default domain is already direct mapped */
19251925
ret = 0;
1926-
if (group->default_domain &&
1927-
group->default_domain->type == IOMMU_DOMAIN_IDENTITY)
1926+
if (group->default_domain && group->default_domain->type == type)
19281927
goto out;
19291928

19301929
/* Don't change mappings of existing devices */
@@ -1934,23 +1933,26 @@ int iommu_request_dm_for_dev(struct device *dev)
19341933

19351934
/* Allocate a direct mapped domain */
19361935
ret = -ENOMEM;
1937-
dm_domain = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_IDENTITY);
1938-
if (!dm_domain)
1936+
domain = __iommu_domain_alloc(dev->bus, type);
1937+
if (!domain)
19391938
goto out;
19401939

19411940
/* Attach the device to the domain */
1942-
ret = __iommu_attach_group(dm_domain, group);
1941+
ret = __iommu_attach_group(domain, group);
19431942
if (ret) {
1944-
iommu_domain_free(dm_domain);
1943+
iommu_domain_free(domain);
19451944
goto out;
19461945
}
19471946

1947+
iommu_group_create_direct_mappings(group, dev);
1948+
19481949
/* Make the direct mapped domain the default for this group */
19491950
if (group->default_domain)
19501951
iommu_domain_free(group->default_domain);
1951-
group->default_domain = dm_domain;
1952+
group->default_domain = domain;
19521953

1953-
dev_info(dev, "Using iommu direct mapping\n");
1954+
dev_info(dev, "Using iommu %s mapping\n",
1955+
type == IOMMU_DOMAIN_DMA ? "dma" : "direct");
19541956

19551957
ret = 0;
19561958
out:
@@ -1960,6 +1962,18 @@ int iommu_request_dm_for_dev(struct device *dev)
19601962
return ret;
19611963
}
19621964

1965+
/* Request that a device is direct mapped by the IOMMU */
1966+
int iommu_request_dm_for_dev(struct device *dev)
1967+
{
1968+
return request_default_domain_for_dev(dev, IOMMU_DOMAIN_IDENTITY);
1969+
}
1970+
1971+
/* Request that a device can't be direct mapped by the IOMMU */
1972+
int iommu_request_dma_domain_for_dev(struct device *dev)
1973+
{
1974+
return request_default_domain_for_dev(dev, IOMMU_DOMAIN_DMA);
1975+
}
1976+
19631977
const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
19641978
{
19651979
const struct iommu_ops *ops = NULL;

include/linux/iommu.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ extern void iommu_set_fault_handler(struct iommu_domain *domain,
362362
extern void iommu_get_resv_regions(struct device *dev, struct list_head *list);
363363
extern void iommu_put_resv_regions(struct device *dev, struct list_head *list);
364364
extern int iommu_request_dm_for_dev(struct device *dev);
365+
extern int iommu_request_dma_domain_for_dev(struct device *dev);
365366
extern struct iommu_resv_region *
366367
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
367368
enum iommu_resv_type type);
@@ -626,6 +627,11 @@ static inline int iommu_request_dm_for_dev(struct device *dev)
626627
return -ENODEV;
627628
}
628629

630+
static inline int iommu_request_dma_domain_for_dev(struct device *dev)
631+
{
632+
return -ENODEV;
633+
}
634+
629635
static inline int iommu_attach_group(struct iommu_domain *domain,
630636
struct iommu_group *group)
631637
{

0 commit comments

Comments
 (0)