2
2
/*
3
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
8
#define pr_fmt (fmt ) KBUILD_MODNAME ": " fmt
@@ -47,7 +47,10 @@ struct viommu_dev {
47
47
/* Device configuration */
48
48
struct iommu_domain_geometry geometry ;
49
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
54
u32 probe_size ;
52
55
};
53
56
@@ -62,6 +65,7 @@ struct viommu_domain {
62
65
struct viommu_dev * viommu ;
63
66
struct mutex mutex ; /* protects viommu pointer */
64
67
unsigned int id ;
68
+ u32 map_flags ;
65
69
66
70
spinlock_t mappings_lock ;
67
71
struct rb_root_cached mappings ;
@@ -113,6 +117,8 @@ static int viommu_get_req_errno(void *buf, size_t len)
113
117
return - ENOENT ;
114
118
case VIRTIO_IOMMU_S_FAULT :
115
119
return - EFAULT ;
120
+ case VIRTIO_IOMMU_S_NOMEM :
121
+ return - ENOMEM ;
116
122
case VIRTIO_IOMMU_S_IOERR :
117
123
case VIRTIO_IOMMU_S_DEVERR :
118
124
default :
@@ -607,15 +613,15 @@ static int viommu_domain_finalise(struct viommu_dev *viommu,
607
613
{
608
614
int ret ;
609
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
617
vdomain -> viommu = viommu ;
618
+ vdomain -> map_flags = viommu -> map_flags ;
614
619
615
620
domain -> pgsize_bitmap = viommu -> pgsize_bitmap ;
616
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
625
if (ret >= 0 )
620
626
vdomain -> id = (unsigned int )ret ;
621
627
@@ -710,14 +716,17 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova,
710
716
phys_addr_t paddr , size_t size , int prot )
711
717
{
712
718
int ret ;
713
- int flags ;
719
+ u32 flags ;
714
720
struct virtio_iommu_req_map map ;
715
721
struct viommu_domain * vdomain = to_viommu_domain (domain );
716
722
717
723
flags = (prot & IOMMU_READ ? VIRTIO_IOMMU_MAP_F_READ : 0 ) |
718
724
(prot & IOMMU_WRITE ? VIRTIO_IOMMU_MAP_F_WRITE : 0 ) |
719
725
(prot & IOMMU_MMIO ? VIRTIO_IOMMU_MAP_F_MMIO : 0 );
720
726
727
+ if (flags & ~vdomain -> map_flags )
728
+ return - EINVAL ;
729
+
721
730
ret = viommu_add_mapping (vdomain , iova , paddr , size , flags );
722
731
if (ret )
723
732
return ret ;
@@ -1027,7 +1036,8 @@ static int viommu_probe(struct virtio_device *vdev)
1027
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
1042
/* Optional features */
1033
1043
virtio_cread_feature (vdev , VIRTIO_IOMMU_F_INPUT_RANGE ,
@@ -1038,9 +1048,13 @@ static int viommu_probe(struct virtio_device *vdev)
1038
1048
struct virtio_iommu_config , input_range .end ,
1039
1049
& input_end );
1040
1050
1041
- virtio_cread_feature (vdev , VIRTIO_IOMMU_F_DOMAIN_BITS ,
1042
- struct virtio_iommu_config , domain_bits ,
1043
- & viommu -> domain_bits );
1051
+ virtio_cread_feature (vdev , VIRTIO_IOMMU_F_DOMAIN_RANGE ,
1052
+ struct virtio_iommu_config , domain_range .start ,
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
1059
virtio_cread_feature (vdev , VIRTIO_IOMMU_F_PROBE ,
1046
1060
struct virtio_iommu_config , probe_size ,
@@ -1052,6 +1066,9 @@ static int viommu_probe(struct virtio_device *vdev)
1052
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
1072
viommu_ops .pgsize_bitmap = viommu -> pgsize_bitmap ;
1056
1073
1057
1074
virtio_device_ready (vdev );
@@ -1130,9 +1147,10 @@ static void viommu_config_changed(struct virtio_device *vdev)
1130
1147
1131
1148
static unsigned int features [] = {
1132
1149
VIRTIO_IOMMU_F_MAP_UNMAP ,
1133
- VIRTIO_IOMMU_F_DOMAIN_BITS ,
1134
1150
VIRTIO_IOMMU_F_INPUT_RANGE ,
1151
+ VIRTIO_IOMMU_F_DOMAIN_RANGE ,
1135
1152
VIRTIO_IOMMU_F_PROBE ,
1153
+ VIRTIO_IOMMU_F_MMIO ,
1136
1154
};
1137
1155
1138
1156
static struct virtio_device_id id_table [] = {
0 commit comments