Commit 7e62edd7 authored by Tina Zhang's avatar Tina Zhang Committed by Joerg Roedel

iommu/virtio: Add map/unmap_pages() callbacks implementation

Map/unmap_pags() allows map and unmap multiple pages of the same size
in one call, which can improve performance by reducing the numbers of
vmexits. With map/unmap_pages() implemented, the prior map/unmap()
callbacks are deprecated.
Signed-off-by: default avatarTina Zhang <tina.zhang@intel.com>
Reviewed-by: default avatarJean-Philippe Brucker <jean-philippe@linaro.org>
Link: https://lore.kernel.org/r/20220605161152.3171-1-tina.zhang@intel.comSigned-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent a111daf0
...@@ -788,11 +788,13 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev) ...@@ -788,11 +788,13 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
return 0; return 0;
} }
static int viommu_map(struct iommu_domain *domain, unsigned long iova, static int viommu_map_pages(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot, gfp_t gfp) phys_addr_t paddr, size_t pgsize, size_t pgcount,
int prot, gfp_t gfp, size_t *mapped)
{ {
int ret; int ret;
u32 flags; u32 flags;
size_t size = pgsize * pgcount;
u64 end = iova + size - 1; u64 end = iova + size - 1;
struct virtio_iommu_req_map map; struct virtio_iommu_req_map map;
struct viommu_domain *vdomain = to_viommu_domain(domain); struct viommu_domain *vdomain = to_viommu_domain(domain);
...@@ -823,17 +825,21 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova, ...@@ -823,17 +825,21 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova,
ret = viommu_send_req_sync(vdomain->viommu, &map, sizeof(map)); ret = viommu_send_req_sync(vdomain->viommu, &map, sizeof(map));
if (ret) if (ret)
viommu_del_mappings(vdomain, iova, end); viommu_del_mappings(vdomain, iova, end);
else if (mapped)
*mapped = size;
return ret; return ret;
} }
static size_t viommu_unmap(struct iommu_domain *domain, unsigned long iova, static size_t viommu_unmap_pages(struct iommu_domain *domain, unsigned long iova,
size_t size, struct iommu_iotlb_gather *gather) size_t pgsize, size_t pgcount,
struct iommu_iotlb_gather *gather)
{ {
int ret = 0; int ret = 0;
size_t unmapped; size_t unmapped;
struct virtio_iommu_req_unmap unmap; struct virtio_iommu_req_unmap unmap;
struct viommu_domain *vdomain = to_viommu_domain(domain); struct viommu_domain *vdomain = to_viommu_domain(domain);
size_t size = pgsize * pgcount;
unmapped = viommu_del_mappings(vdomain, iova, iova + size - 1); unmapped = viommu_del_mappings(vdomain, iova, iova + size - 1);
if (unmapped < size) if (unmapped < size)
...@@ -1018,8 +1024,8 @@ static struct iommu_ops viommu_ops = { ...@@ -1018,8 +1024,8 @@ static struct iommu_ops viommu_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.default_domain_ops = &(const struct iommu_domain_ops) { .default_domain_ops = &(const struct iommu_domain_ops) {
.attach_dev = viommu_attach_dev, .attach_dev = viommu_attach_dev,
.map = viommu_map, .map_pages = viommu_map_pages,
.unmap = viommu_unmap, .unmap_pages = viommu_unmap_pages,
.iova_to_phys = viommu_iova_to_phys, .iova_to_phys = viommu_iova_to_phys,
.iotlb_sync = viommu_iotlb_sync, .iotlb_sync = viommu_iotlb_sync,
.free = viommu_domain_free, .free = viommu_domain_free,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment