iommu/sprd: Add support for reattaching an existing domain
This IOMMU driver should allow a domain to be attached more than once. If IOMMU is reattaching to the same domain which is attached, there's nothing to be done. If reattching to a previously-used domain, do not alloc DMA buffer again which stores address mapping table to avoid memory leak. Signed-off-by: Chunyan Zhang <chunyan.zhang@unisoc.com> Link: https://lore.kernel.org/r/20230331033124.864691-3-zhang.lyra@gmail.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
9afea57384
commit
816c698c05
|
@ -62,6 +62,7 @@ enum sprd_iommu_version {
|
||||||
* @eb: gate clock which controls IOMMU access
|
* @eb: gate clock which controls IOMMU access
|
||||||
*/
|
*/
|
||||||
struct sprd_iommu_device {
|
struct sprd_iommu_device {
|
||||||
|
struct sprd_iommu_domain *dom;
|
||||||
enum sprd_iommu_version ver;
|
enum sprd_iommu_version ver;
|
||||||
u32 *prot_page_va;
|
u32 *prot_page_va;
|
||||||
dma_addr_t prot_page_pa;
|
dma_addr_t prot_page_pa;
|
||||||
|
@ -252,15 +253,27 @@ static int sprd_iommu_attach_device(struct iommu_domain *domain,
|
||||||
struct sprd_iommu_domain *dom = to_sprd_domain(domain);
|
struct sprd_iommu_domain *dom = to_sprd_domain(domain);
|
||||||
size_t pgt_size = sprd_iommu_pgt_size(domain);
|
size_t pgt_size = sprd_iommu_pgt_size(domain);
|
||||||
|
|
||||||
if (dom->sdev)
|
/* The device is attached to this domain */
|
||||||
return -EINVAL;
|
if (sdev->dom == dom)
|
||||||
|
return 0;
|
||||||
|
|
||||||
dom->pgt_va = dma_alloc_coherent(sdev->dev, pgt_size, &dom->pgt_pa, GFP_KERNEL);
|
/* The first time that domain is attaching to a device */
|
||||||
if (!dom->pgt_va)
|
if (!dom->pgt_va) {
|
||||||
return -ENOMEM;
|
dom->pgt_va = dma_alloc_coherent(sdev->dev, pgt_size, &dom->pgt_pa, GFP_KERNEL);
|
||||||
|
if (!dom->pgt_va)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
dom->sdev = sdev;
|
dom->sdev = sdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
sdev->dom = dom;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One sprd IOMMU serves one client device only, disabled it before
|
||||||
|
* configure mapping table to avoid access conflict in case other
|
||||||
|
* mapping table is stored in.
|
||||||
|
*/
|
||||||
|
sprd_iommu_hw_en(sdev, false);
|
||||||
sprd_iommu_first_ppn(dom);
|
sprd_iommu_first_ppn(dom);
|
||||||
sprd_iommu_first_vpn(dom);
|
sprd_iommu_first_vpn(dom);
|
||||||
sprd_iommu_vpn_range(dom);
|
sprd_iommu_vpn_range(dom);
|
||||||
|
|
Loading…
Reference in New Issue