aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vhost/net.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vhost/net.c')
-rw-r--r--drivers/vhost/net.c67
1 files changed, 57 insertions, 10 deletions
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index e032ca397371..5dc128a8da83 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -61,7 +61,8 @@ MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;"
61enum { 61enum {
62 VHOST_NET_FEATURES = VHOST_FEATURES | 62 VHOST_NET_FEATURES = VHOST_FEATURES |
63 (1ULL << VHOST_NET_F_VIRTIO_NET_HDR) | 63 (1ULL << VHOST_NET_F_VIRTIO_NET_HDR) |
64 (1ULL << VIRTIO_NET_F_MRG_RXBUF) 64 (1ULL << VIRTIO_NET_F_MRG_RXBUF) |
65 (1ULL << VIRTIO_F_IOMMU_PLATFORM)
65}; 66};
66 67
67enum { 68enum {
@@ -334,7 +335,7 @@ static int vhost_net_tx_get_vq_desc(struct vhost_net *net,
334{ 335{
335 unsigned long uninitialized_var(endtime); 336 unsigned long uninitialized_var(endtime);
336 int r = vhost_get_vq_desc(vq, vq->iov, ARRAY_SIZE(vq->iov), 337 int r = vhost_get_vq_desc(vq, vq->iov, ARRAY_SIZE(vq->iov),
337 out_num, in_num, NULL, NULL); 338 out_num, in_num, NULL, NULL);
338 339
339 if (r == vq->num && vq->busyloop_timeout) { 340 if (r == vq->num && vq->busyloop_timeout) {
340 preempt_disable(); 341 preempt_disable();
@@ -344,7 +345,7 @@ static int vhost_net_tx_get_vq_desc(struct vhost_net *net,
344 cpu_relax_lowlatency(); 345 cpu_relax_lowlatency();
345 preempt_enable(); 346 preempt_enable();
346 r = vhost_get_vq_desc(vq, vq->iov, ARRAY_SIZE(vq->iov), 347 r = vhost_get_vq_desc(vq, vq->iov, ARRAY_SIZE(vq->iov),
347 out_num, in_num, NULL, NULL); 348 out_num, in_num, NULL, NULL);
348 } 349 }
349 350
350 return r; 351 return r;
@@ -377,6 +378,9 @@ static void handle_tx(struct vhost_net *net)
377 if (!sock) 378 if (!sock)
378 goto out; 379 goto out;
379 380
381 if (!vq_iotlb_prefetch(vq))
382 goto out;
383
380 vhost_disable_notify(&net->dev, vq); 384 vhost_disable_notify(&net->dev, vq);
381 385
382 hdr_size = nvq->vhost_hlen; 386 hdr_size = nvq->vhost_hlen;
@@ -652,6 +656,10 @@ static void handle_rx(struct vhost_net *net)
652 sock = vq->private_data; 656 sock = vq->private_data;
653 if (!sock) 657 if (!sock)
654 goto out; 658 goto out;
659
660 if (!vq_iotlb_prefetch(vq))
661 goto out;
662
655 vhost_disable_notify(&net->dev, vq); 663 vhost_disable_notify(&net->dev, vq);
656 vhost_net_disable_vq(net, vq); 664 vhost_net_disable_vq(net, vq);
657 665
@@ -1052,20 +1060,20 @@ static long vhost_net_reset_owner(struct vhost_net *n)
1052 struct socket *tx_sock = NULL; 1060 struct socket *tx_sock = NULL;
1053 struct socket *rx_sock = NULL; 1061 struct socket *rx_sock = NULL;
1054 long err; 1062 long err;
1055 struct vhost_memory *memory; 1063 struct vhost_umem *umem;
1056 1064
1057 mutex_lock(&n->dev.mutex); 1065 mutex_lock(&n->dev.mutex);
1058 err = vhost_dev_check_owner(&n->dev); 1066 err = vhost_dev_check_owner(&n->dev);
1059 if (err) 1067 if (err)
1060 goto done; 1068 goto done;
1061 memory = vhost_dev_reset_owner_prepare(); 1069 umem = vhost_dev_reset_owner_prepare();
1062 if (!memory) { 1070 if (!umem) {
1063 err = -ENOMEM; 1071 err = -ENOMEM;
1064 goto done; 1072 goto done;
1065 } 1073 }
1066 vhost_net_stop(n, &tx_sock, &rx_sock); 1074 vhost_net_stop(n, &tx_sock, &rx_sock);
1067 vhost_net_flush(n); 1075 vhost_net_flush(n);
1068 vhost_dev_reset_owner(&n->dev, memory); 1076 vhost_dev_reset_owner(&n->dev, umem);
1069 vhost_net_vq_reset(n); 1077 vhost_net_vq_reset(n);
1070done: 1078done:
1071 mutex_unlock(&n->dev.mutex); 1079 mutex_unlock(&n->dev.mutex);
@@ -1096,10 +1104,14 @@ static int vhost_net_set_features(struct vhost_net *n, u64 features)
1096 } 1104 }
1097 mutex_lock(&n->dev.mutex); 1105 mutex_lock(&n->dev.mutex);
1098 if ((features & (1 << VHOST_F_LOG_ALL)) && 1106 if ((features & (1 << VHOST_F_LOG_ALL)) &&
1099 !vhost_log_access_ok(&n->dev)) { 1107 !vhost_log_access_ok(&n->dev))
1100 mutex_unlock(&n->dev.mutex); 1108 goto out_unlock;
1101 return -EFAULT; 1109
1110 if ((features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))) {
1111 if (vhost_init_device_iotlb(&n->dev, true))
1112 goto out_unlock;
1102 } 1113 }
1114
1103 for (i = 0; i < VHOST_NET_VQ_MAX; ++i) { 1115 for (i = 0; i < VHOST_NET_VQ_MAX; ++i) {
1104 mutex_lock(&n->vqs[i].vq.mutex); 1116 mutex_lock(&n->vqs[i].vq.mutex);
1105 n->vqs[i].vq.acked_features = features; 1117 n->vqs[i].vq.acked_features = features;
@@ -1109,6 +1121,10 @@ static int vhost_net_set_features(struct vhost_net *n, u64 features)
1109 } 1121 }
1110 mutex_unlock(&n->dev.mutex); 1122 mutex_unlock(&n->dev.mutex);
1111 return 0; 1123 return 0;
1124
1125out_unlock:
1126 mutex_unlock(&n->dev.mutex);
1127 return -EFAULT;
1112} 1128}
1113 1129
1114static long vhost_net_set_owner(struct vhost_net *n) 1130static long vhost_net_set_owner(struct vhost_net *n)
@@ -1182,9 +1198,40 @@ static long vhost_net_compat_ioctl(struct file *f, unsigned int ioctl,
1182} 1198}
1183#endif 1199#endif
1184 1200
1201static ssize_t vhost_net_chr_read_iter(struct kiocb *iocb, struct iov_iter *to)
1202{
1203 struct file *file = iocb->ki_filp;
1204 struct vhost_net *n = file->private_data;
1205 struct vhost_dev *dev = &n->dev;
1206 int noblock = file->f_flags & O_NONBLOCK;
1207
1208 return vhost_chr_read_iter(dev, to, noblock);
1209}
1210
1211static ssize_t vhost_net_chr_write_iter(struct kiocb *iocb,
1212 struct iov_iter *from)
1213{
1214 struct file *file = iocb->ki_filp;
1215 struct vhost_net *n = file->private_data;
1216 struct vhost_dev *dev = &n->dev;
1217
1218 return vhost_chr_write_iter(dev, from);
1219}
1220
1221static unsigned int vhost_net_chr_poll(struct file *file, poll_table *wait)
1222{
1223 struct vhost_net *n = file->private_data;
1224 struct vhost_dev *dev = &n->dev;
1225
1226 return vhost_chr_poll(file, dev, wait);
1227}
1228
1185static const struct file_operations vhost_net_fops = { 1229static const struct file_operations vhost_net_fops = {
1186 .owner = THIS_MODULE, 1230 .owner = THIS_MODULE,
1187 .release = vhost_net_release, 1231 .release = vhost_net_release,
1232 .read_iter = vhost_net_chr_read_iter,
1233 .write_iter = vhost_net_chr_write_iter,
1234 .poll = vhost_net_chr_poll,
1188 .unlocked_ioctl = vhost_net_ioctl, 1235 .unlocked_ioctl = vhost_net_ioctl,
1189#ifdef CONFIG_COMPAT 1236#ifdef CONFIG_COMPAT
1190 .compat_ioctl = vhost_net_compat_ioctl, 1237 .compat_ioctl = vhost_net_compat_ioctl,