summaryrefslogtreecommitdiffstats
path: root/drivers/iommu/virtio-iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iommu/virtio-iommu.c')
-rw-r--r--drivers/iommu/virtio-iommu.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 433f4d2ee956..80a740df0737 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -2,7 +2,7 @@
2/* 2/*
3 * Virtio driver for the paravirtualized IOMMU 3 * Virtio driver for the paravirtualized IOMMU
4 * 4 *
5 * Copyright (C) 2018 Arm Limited 5 * Copyright (C) 2019 Arm Limited
6 */ 6 */
7 7
8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -47,7 +47,10 @@ struct viommu_dev {
47 /* Device configuration */ 47 /* Device configuration */
48 struct iommu_domain_geometry geometry; 48 struct iommu_domain_geometry geometry;
49 u64 pgsize_bitmap; 49 u64 pgsize_bitmap;
50 u8 domain_bits; 50 u32 first_domain;
51 u32 last_domain;
52 /* Supported MAP flags */
53 u32 map_flags;
51 u32 probe_size; 54 u32 probe_size;
52}; 55};
53 56
@@ -62,6 +65,7 @@ struct viommu_domain {
62 struct viommu_dev *viommu; 65 struct viommu_dev *viommu;
63 struct mutex mutex; /* protects viommu pointer */ 66 struct mutex mutex; /* protects viommu pointer */
64 unsigned int id; 67 unsigned int id;
68 u32 map_flags;
65 69
66 spinlock_t mappings_lock; 70 spinlock_t mappings_lock;
67 struct rb_root_cached mappings; 71 struct rb_root_cached mappings;
@@ -113,6 +117,8 @@ static int viommu_get_req_errno(void *buf, size_t len)
113 return -ENOENT; 117 return -ENOENT;
114 case VIRTIO_IOMMU_S_FAULT: 118 case VIRTIO_IOMMU_S_FAULT:
115 return -EFAULT; 119 return -EFAULT;
120 case VIRTIO_IOMMU_S_NOMEM:
121 return -ENOMEM;
116 case VIRTIO_IOMMU_S_IOERR: 122 case VIRTIO_IOMMU_S_IOERR:
117 case VIRTIO_IOMMU_S_DEVERR: 123 case VIRTIO_IOMMU_S_DEVERR:
118 default: 124 default:
@@ -607,15 +613,15 @@ static int viommu_domain_finalise(struct viommu_dev *viommu,
607{ 613{
608 int ret; 614 int ret;
609 struct viommu_domain *vdomain = to_viommu_domain(domain); 615 struct viommu_domain *vdomain = to_viommu_domain(domain);
610 unsigned int max_domain = viommu->domain_bits > 31 ? ~0 :
611 (1U << viommu->domain_bits) - 1;
612 616
613 vdomain->viommu = viommu; 617 vdomain->viommu = viommu;
618 vdomain->map_flags = viommu->map_flags;
614 619
615 domain->pgsize_bitmap = viommu->pgsize_bitmap; 620 domain->pgsize_bitmap = viommu->pgsize_bitmap;
616 domain->geometry = viommu->geometry; 621 domain->geometry = viommu->geometry;
617 622
618 ret = ida_alloc_max(&viommu->domain_ids, max_domain, GFP_KERNEL); 623 ret = ida_alloc_range(&viommu->domain_ids, viommu->first_domain,
624 viommu->last_domain, GFP_KERNEL);
619 if (ret >= 0) 625 if (ret >= 0)
620 vdomain->id = (unsigned int)ret; 626 vdomain->id = (unsigned int)ret;
621 627
@@ -710,7 +716,7 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova,
710 phys_addr_t paddr, size_t size, int prot) 716 phys_addr_t paddr, size_t size, int prot)
711{ 717{
712 int ret; 718 int ret;
713 int flags; 719 u32 flags;
714 struct virtio_iommu_req_map map; 720 struct virtio_iommu_req_map map;
715 struct viommu_domain *vdomain = to_viommu_domain(domain); 721 struct viommu_domain *vdomain = to_viommu_domain(domain);
716 722
@@ -718,6 +724,9 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova,
718 (prot & IOMMU_WRITE ? VIRTIO_IOMMU_MAP_F_WRITE : 0) | 724 (prot & IOMMU_WRITE ? VIRTIO_IOMMU_MAP_F_WRITE : 0) |
719 (prot & IOMMU_MMIO ? VIRTIO_IOMMU_MAP_F_MMIO : 0); 725 (prot & IOMMU_MMIO ? VIRTIO_IOMMU_MAP_F_MMIO : 0);
720 726
727 if (flags & ~vdomain->map_flags)
728 return -EINVAL;
729
721 ret = viommu_add_mapping(vdomain, iova, paddr, size, flags); 730 ret = viommu_add_mapping(vdomain, iova, paddr, size, flags);
722 if (ret) 731 if (ret)
723 return ret; 732 return ret;
@@ -1027,7 +1036,8 @@ static int viommu_probe(struct virtio_device *vdev)
1027 goto err_free_vqs; 1036 goto err_free_vqs;
1028 } 1037 }
1029 1038
1030 viommu->domain_bits = 32; 1039 viommu->map_flags = VIRTIO_IOMMU_MAP_F_READ | VIRTIO_IOMMU_MAP_F_WRITE;
1040 viommu->last_domain = ~0U;
1031 1041
1032 /* Optional features */ 1042 /* Optional features */
1033 virtio_cread_feature(vdev, VIRTIO_IOMMU_F_INPUT_RANGE, 1043 virtio_cread_feature(vdev, VIRTIO_IOMMU_F_INPUT_RANGE,
@@ -1038,9 +1048,13 @@ static int viommu_probe(struct virtio_device *vdev)
1038 struct virtio_iommu_config, input_range.end, 1048 struct virtio_iommu_config, input_range.end,
1039 &input_end); 1049 &input_end);
1040 1050
1041 virtio_cread_feature(vdev, VIRTIO_IOMMU_F_DOMAIN_BITS, 1051 virtio_cread_feature(vdev, VIRTIO_IOMMU_F_DOMAIN_RANGE,
1042 struct virtio_iommu_config, domain_bits, 1052 struct virtio_iommu_config, domain_range.start,
1043 &viommu->domain_bits); 1053 &viommu->first_domain);
1054
1055 virtio_cread_feature(vdev, VIRTIO_IOMMU_F_DOMAIN_RANGE,
1056 struct virtio_iommu_config, domain_range.end,
1057 &viommu->last_domain);
1044 1058
1045 virtio_cread_feature(vdev, VIRTIO_IOMMU_F_PROBE, 1059 virtio_cread_feature(vdev, VIRTIO_IOMMU_F_PROBE,
1046 struct virtio_iommu_config, probe_size, 1060 struct virtio_iommu_config, probe_size,
@@ -1052,6 +1066,9 @@ static int viommu_probe(struct virtio_device *vdev)
1052 .force_aperture = true, 1066 .force_aperture = true,
1053 }; 1067 };
1054 1068
1069 if (virtio_has_feature(vdev, VIRTIO_IOMMU_F_MMIO))
1070 viommu->map_flags |= VIRTIO_IOMMU_MAP_F_MMIO;
1071
1055 viommu_ops.pgsize_bitmap = viommu->pgsize_bitmap; 1072 viommu_ops.pgsize_bitmap = viommu->pgsize_bitmap;
1056 1073
1057 virtio_device_ready(vdev); 1074 virtio_device_ready(vdev);
@@ -1130,9 +1147,10 @@ static void viommu_config_changed(struct virtio_device *vdev)
1130 1147
1131static unsigned int features[] = { 1148static unsigned int features[] = {
1132 VIRTIO_IOMMU_F_MAP_UNMAP, 1149 VIRTIO_IOMMU_F_MAP_UNMAP,
1133 VIRTIO_IOMMU_F_DOMAIN_BITS,
1134 VIRTIO_IOMMU_F_INPUT_RANGE, 1150 VIRTIO_IOMMU_F_INPUT_RANGE,
1151 VIRTIO_IOMMU_F_DOMAIN_RANGE,
1135 VIRTIO_IOMMU_F_PROBE, 1152 VIRTIO_IOMMU_F_PROBE,
1153 VIRTIO_IOMMU_F_MMIO,
1136}; 1154};
1137 1155
1138static struct virtio_device_id id_table[] = { 1156static struct virtio_device_id id_table[] = {