mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 01:22:07 +00:00
iommu/vt-d: Implement map/unmap_pages() iommu_ops callback
Implement the map_pages() and unmap_pages() callback for the Intel IOMMU driver to allow calls from iommu core to map and unmap multiple pages of the same size in one call. With map/unmap_pages() implemented, the prior map/unmap callbacks are deprecated. Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Link: https://lore.kernel.org/r/20210720020615.4144323-3-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
a886d5a7e6
commit
3f34f12597
@ -5065,6 +5065,28 @@ static int intel_iommu_map(struct iommu_domain *domain,
|
|||||||
hpa >> VTD_PAGE_SHIFT, size, prot);
|
hpa >> VTD_PAGE_SHIFT, size, prot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int intel_iommu_map_pages(struct iommu_domain *domain,
|
||||||
|
unsigned long iova, phys_addr_t paddr,
|
||||||
|
size_t pgsize, size_t pgcount,
|
||||||
|
int prot, gfp_t gfp, size_t *mapped)
|
||||||
|
{
|
||||||
|
unsigned long pgshift = __ffs(pgsize);
|
||||||
|
size_t size = pgcount << pgshift;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (pgsize != SZ_4K && pgsize != SZ_2M && pgsize != SZ_1G)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!IS_ALIGNED(iova | paddr, pgsize))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = intel_iommu_map(domain, iova, paddr, size, prot, gfp);
|
||||||
|
if (!ret && mapped)
|
||||||
|
*mapped = size;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static size_t intel_iommu_unmap(struct iommu_domain *domain,
|
static size_t intel_iommu_unmap(struct iommu_domain *domain,
|
||||||
unsigned long iova, size_t size,
|
unsigned long iova, size_t size,
|
||||||
struct iommu_iotlb_gather *gather)
|
struct iommu_iotlb_gather *gather)
|
||||||
@ -5094,6 +5116,17 @@ static size_t intel_iommu_unmap(struct iommu_domain *domain,
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t intel_iommu_unmap_pages(struct iommu_domain *domain,
|
||||||
|
unsigned long iova,
|
||||||
|
size_t pgsize, size_t pgcount,
|
||||||
|
struct iommu_iotlb_gather *gather)
|
||||||
|
{
|
||||||
|
unsigned long pgshift = __ffs(pgsize);
|
||||||
|
size_t size = pgcount << pgshift;
|
||||||
|
|
||||||
|
return intel_iommu_unmap(domain, iova, size, gather);
|
||||||
|
}
|
||||||
|
|
||||||
static void intel_iommu_tlb_sync(struct iommu_domain *domain,
|
static void intel_iommu_tlb_sync(struct iommu_domain *domain,
|
||||||
struct iommu_iotlb_gather *gather)
|
struct iommu_iotlb_gather *gather)
|
||||||
{
|
{
|
||||||
@ -5591,9 +5624,9 @@ const struct iommu_ops intel_iommu_ops = {
|
|||||||
.aux_attach_dev = intel_iommu_aux_attach_device,
|
.aux_attach_dev = intel_iommu_aux_attach_device,
|
||||||
.aux_detach_dev = intel_iommu_aux_detach_device,
|
.aux_detach_dev = intel_iommu_aux_detach_device,
|
||||||
.aux_get_pasid = intel_iommu_aux_get_pasid,
|
.aux_get_pasid = intel_iommu_aux_get_pasid,
|
||||||
.map = intel_iommu_map,
|
.map_pages = intel_iommu_map_pages,
|
||||||
|
.unmap_pages = intel_iommu_unmap_pages,
|
||||||
.iotlb_sync_map = intel_iommu_iotlb_sync_map,
|
.iotlb_sync_map = intel_iommu_iotlb_sync_map,
|
||||||
.unmap = intel_iommu_unmap,
|
|
||||||
.flush_iotlb_all = intel_flush_iotlb_all,
|
.flush_iotlb_all = intel_flush_iotlb_all,
|
||||||
.iotlb_sync = intel_iommu_tlb_sync,
|
.iotlb_sync = intel_iommu_tlb_sync,
|
||||||
.iova_to_phys = intel_iommu_iova_to_phys,
|
.iova_to_phys = intel_iommu_iova_to_phys,
|
||||||
|
Loading…
Reference in New Issue
Block a user