@@ -1243,6 +1243,51 @@ static void vduse_vq_update_effective_cpu(struct vduse_virtqueue *vq)
12431243 vq -> irq_effective_cpu = curr_cpu ;
12441244}
12451245
1246+ static int vduse_dev_iotlb_entry (struct vduse_dev * dev ,
1247+ struct vduse_iotlb_entry * entry ,
1248+ struct file * * f , uint64_t * capability )
1249+ {
1250+ int r = - EINVAL ;
1251+ struct vhost_iotlb_map * map ;
1252+
1253+ if (entry -> start > entry -> last )
1254+ return - EINVAL ;
1255+
1256+ mutex_lock (& dev -> domain_lock );
1257+ if (!dev -> domain )
1258+ goto out ;
1259+
1260+ spin_lock (& dev -> domain -> iotlb_lock );
1261+ map = vhost_iotlb_itree_first (dev -> domain -> iotlb , entry -> start ,
1262+ entry -> last );
1263+ if (map ) {
1264+ if (f ) {
1265+ const struct vdpa_map_file * map_file ;
1266+
1267+ map_file = (struct vdpa_map_file * )map -> opaque ;
1268+ entry -> offset = map_file -> offset ;
1269+ * f = get_file (map_file -> file );
1270+ }
1271+ entry -> start = map -> start ;
1272+ entry -> last = map -> last ;
1273+ entry -> perm = map -> perm ;
1274+ if (capability ) {
1275+ * capability = 0 ;
1276+
1277+ if (dev -> domain -> bounce_map && map -> start == 0 &&
1278+ map -> last == dev -> domain -> bounce_size - 1 )
1279+ * capability |= VDUSE_IOVA_CAP_UMEM ;
1280+ }
1281+
1282+ r = 0 ;
1283+ }
1284+ spin_unlock (& dev -> domain -> iotlb_lock );
1285+
1286+ out :
1287+ mutex_unlock (& dev -> domain_lock );
1288+ return r ;
1289+ }
1290+
12461291static long vduse_dev_ioctl (struct file * file , unsigned int cmd ,
12471292 unsigned long arg )
12481293{
@@ -1256,36 +1301,16 @@ static long vduse_dev_ioctl(struct file *file, unsigned int cmd,
12561301 switch (cmd ) {
12571302 case VDUSE_IOTLB_GET_FD : {
12581303 struct vduse_iotlb_entry entry ;
1259- struct vhost_iotlb_map * map ;
1260- struct vdpa_map_file * map_file ;
12611304 struct file * f = NULL ;
12621305
12631306 ret = - EFAULT ;
12641307 if (copy_from_user (& entry , argp , sizeof (entry )))
12651308 break ;
12661309
1267- ret = - EINVAL ;
1268- if (entry . start > entry . last )
1310+ ret = vduse_dev_iotlb_entry ( dev , & entry , & f , NULL ) ;
1311+ if (ret )
12691312 break ;
12701313
1271- mutex_lock (& dev -> domain_lock );
1272- if (!dev -> domain ) {
1273- mutex_unlock (& dev -> domain_lock );
1274- break ;
1275- }
1276- spin_lock (& dev -> domain -> iotlb_lock );
1277- map = vhost_iotlb_itree_first (dev -> domain -> iotlb ,
1278- entry .start , entry .last );
1279- if (map ) {
1280- map_file = (struct vdpa_map_file * )map -> opaque ;
1281- f = get_file (map_file -> file );
1282- entry .offset = map_file -> offset ;
1283- entry .start = map -> start ;
1284- entry .last = map -> last ;
1285- entry .perm = map -> perm ;
1286- }
1287- spin_unlock (& dev -> domain -> iotlb_lock );
1288- mutex_unlock (& dev -> domain_lock );
12891314 ret = - EINVAL ;
12901315 if (!f )
12911316 break ;
@@ -1475,41 +1500,26 @@ static long vduse_dev_ioctl(struct file *file, unsigned int cmd,
14751500 }
14761501 case VDUSE_IOTLB_GET_INFO : {
14771502 struct vduse_iova_info info ;
1478- struct vhost_iotlb_map * map ;
1503+ struct vduse_iotlb_entry entry ;
14791504
14801505 ret = - EFAULT ;
14811506 if (copy_from_user (& info , argp , sizeof (info )))
14821507 break ;
14831508
1484- ret = - EINVAL ;
1485- if (info .start > info .last )
1486- break ;
1487-
14881509 if (!is_mem_zero ((const char * )info .reserved ,
14891510 sizeof (info .reserved )))
14901511 break ;
14911512
1492- mutex_lock (& dev -> domain_lock );
1493- if (!dev -> domain ) {
1494- mutex_unlock (& dev -> domain_lock );
1495- break ;
1496- }
1497- spin_lock (& dev -> domain -> iotlb_lock );
1498- map = vhost_iotlb_itree_first (dev -> domain -> iotlb ,
1499- info .start , info .last );
1500- if (map ) {
1501- info .start = map -> start ;
1502- info .last = map -> last ;
1503- info .capability = 0 ;
1504- if (dev -> domain -> bounce_map && map -> start == 0 &&
1505- map -> last == dev -> domain -> bounce_size - 1 )
1506- info .capability |= VDUSE_IOVA_CAP_UMEM ;
1507- }
1508- spin_unlock (& dev -> domain -> iotlb_lock );
1509- mutex_unlock (& dev -> domain_lock );
1510- if (!map )
1513+ entry .start = info .start ;
1514+ entry .last = info .last ;
1515+ ret = vduse_dev_iotlb_entry (dev , & entry , NULL ,
1516+ & info .capability );
1517+ if (ret < 0 )
15111518 break ;
15121519
1520+ info .start = entry .start ;
1521+ info .last = entry .last ;
1522+
15131523 ret = - EFAULT ;
15141524 if (copy_to_user (argp , & info , sizeof (info )))
15151525 break ;
0 commit comments