Skip to content

Commit c0c7635

Browse files
jpbruckerjoergroedel
authored andcommitted
iommu/virtio: Pass end address to viommu_add_mapping()
To support identity mappings, the virtio-iommu driver must be able to represent full 64-bit ranges internally. Pass (start, end) instead of (start, size) to viommu_add/del_mapping(). Clean comments. The one about the returned size was never true: when sweeping the whole address space the returned size will most certainly be smaller than 2^64. Reviewed-by: Eric Auger <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Signed-off-by: Jean-Philippe Brucker <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 5610979 commit c0c7635

File tree

1 file changed

+15
-16
lines changed

1 file changed

+15
-16
lines changed

drivers/iommu/virtio-iommu.c

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,8 @@ static int viommu_send_req_sync(struct viommu_dev *viommu, void *buf,
311311
*
312312
* On success, return the new mapping. Otherwise return NULL.
313313
*/
314-
static int viommu_add_mapping(struct viommu_domain *vdomain, unsigned long iova,
315-
phys_addr_t paddr, size_t size, u32 flags)
314+
static int viommu_add_mapping(struct viommu_domain *vdomain, u64 iova, u64 end,
315+
phys_addr_t paddr, u32 flags)
316316
{
317317
unsigned long irqflags;
318318
struct viommu_mapping *mapping;
@@ -323,7 +323,7 @@ static int viommu_add_mapping(struct viommu_domain *vdomain, unsigned long iova,
323323

324324
mapping->paddr = paddr;
325325
mapping->iova.start = iova;
326-
mapping->iova.last = iova + size - 1;
326+
mapping->iova.last = end;
327327
mapping->flags = flags;
328328

329329
spin_lock_irqsave(&vdomain->mappings_lock, irqflags);
@@ -338,26 +338,24 @@ static int viommu_add_mapping(struct viommu_domain *vdomain, unsigned long iova,
338338
*
339339
* @vdomain: the domain
340340
* @iova: start of the range
341-
* @size: size of the range. A size of 0 corresponds to the entire address
342-
* space.
341+
* @end: end of the range
343342
*
344-
* On success, returns the number of unmapped bytes (>= size)
343+
* On success, returns the number of unmapped bytes
345344
*/
346345
static size_t viommu_del_mappings(struct viommu_domain *vdomain,
347-
unsigned long iova, size_t size)
346+
u64 iova, u64 end)
348347
{
349348
size_t unmapped = 0;
350349
unsigned long flags;
351-
unsigned long last = iova + size - 1;
352350
struct viommu_mapping *mapping = NULL;
353351
struct interval_tree_node *node, *next;
354352

355353
spin_lock_irqsave(&vdomain->mappings_lock, flags);
356-
next = interval_tree_iter_first(&vdomain->mappings, iova, last);
354+
next = interval_tree_iter_first(&vdomain->mappings, iova, end);
357355
while (next) {
358356
node = next;
359357
mapping = container_of(node, struct viommu_mapping, iova);
360-
next = interval_tree_iter_next(node, iova, last);
358+
next = interval_tree_iter_next(node, iova, end);
361359

362360
/* Trying to split a mapping? */
363361
if (mapping->iova.start < iova)
@@ -656,8 +654,8 @@ static void viommu_domain_free(struct iommu_domain *domain)
656654
{
657655
struct viommu_domain *vdomain = to_viommu_domain(domain);
658656

659-
/* Free all remaining mappings (size 2^64) */
660-
viommu_del_mappings(vdomain, 0, 0);
657+
/* Free all remaining mappings */
658+
viommu_del_mappings(vdomain, 0, ULLONG_MAX);
661659

662660
if (vdomain->viommu)
663661
ida_free(&vdomain->viommu->domain_ids, vdomain->id);
@@ -742,6 +740,7 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova,
742740
{
743741
int ret;
744742
u32 flags;
743+
u64 end = iova + size - 1;
745744
struct virtio_iommu_req_map map;
746745
struct viommu_domain *vdomain = to_viommu_domain(domain);
747746

@@ -752,7 +751,7 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova,
752751
if (flags & ~vdomain->map_flags)
753752
return -EINVAL;
754753

755-
ret = viommu_add_mapping(vdomain, iova, paddr, size, flags);
754+
ret = viommu_add_mapping(vdomain, iova, end, paddr, flags);
756755
if (ret)
757756
return ret;
758757

@@ -761,7 +760,7 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova,
761760
.domain = cpu_to_le32(vdomain->id),
762761
.virt_start = cpu_to_le64(iova),
763762
.phys_start = cpu_to_le64(paddr),
764-
.virt_end = cpu_to_le64(iova + size - 1),
763+
.virt_end = cpu_to_le64(end),
765764
.flags = cpu_to_le32(flags),
766765
};
767766

@@ -770,7 +769,7 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova,
770769

771770
ret = viommu_send_req_sync(vdomain->viommu, &map, sizeof(map));
772771
if (ret)
773-
viommu_del_mappings(vdomain, iova, size);
772+
viommu_del_mappings(vdomain, iova, end);
774773

775774
return ret;
776775
}
@@ -783,7 +782,7 @@ static size_t viommu_unmap(struct iommu_domain *domain, unsigned long iova,
783782
struct virtio_iommu_req_unmap unmap;
784783
struct viommu_domain *vdomain = to_viommu_domain(domain);
785784

786-
unmapped = viommu_del_mappings(vdomain, iova, size);
785+
unmapped = viommu_del_mappings(vdomain, iova, iova + size - 1);
787786
if (unmapped < size)
788787
return 0;
789788

0 commit comments

Comments
 (0)