Skip to content

Commit c2dc4c0

Browse files
committed
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull vhost fixes from Michael Tsirkin: "Fixes all over the place. A new UAPI is borderline: can also be considered a new feature but also seems to be the only way we could come up with to fix addressing for userspace - and it seems important to switch to it now before userspace making assumptions about addressing ability of devices is set in stone" * tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: vdpasim: allow to assign a MAC address vdpasim: fix MAC address configuration vdpa: handle irq bypass register failure case vdpa_sim: Fix DMA mask Revert "vhost-vdpa: fix page pinning leakage in error path" vdpa/mlx5: Fix error return in map_direct_mr() vhost_vdpa: Return -EFAULT if copy_from_user() fails vdpa_sim: implement get_iova_range() vhost: vdpa: report iova range vdpa: introduce config op to get valid iova range
2 parents 53760f9 + 0c86d77 commit c2dc4c0

6 files changed

Lines changed: 157 additions & 82 deletions

File tree

drivers/vdpa/mlx5/core/mr.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,6 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
239239
u64 paend;
240240
struct scatterlist *sg;
241241
struct device *dma = mvdev->mdev->device;
242-
int ret;
243242

244243
for (map = vhost_iotlb_itree_first(iotlb, mr->start, mr->end - 1);
245244
map; map = vhost_iotlb_itree_next(map, start, mr->end - 1)) {
@@ -277,8 +276,8 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
277276
done:
278277
mr->log_size = log_entity_size;
279278
mr->nsg = nsg;
280-
ret = dma_map_sg_attrs(dma, mr->sg_head.sgl, mr->nsg, DMA_BIDIRECTIONAL, 0);
281-
if (!ret)
279+
err = dma_map_sg_attrs(dma, mr->sg_head.sgl, mr->nsg, DMA_BIDIRECTIONAL, 0);
280+
if (!err)
282281
goto err_map;
283282

284283
err = create_direct_mr(mvdev, mr);

drivers/vdpa/vdpa_sim/vdpa_sim.c

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ static int batch_mapping = 1;
3838
module_param(batch_mapping, int, 0444);
3939
MODULE_PARM_DESC(batch_mapping, "Batched mapping 1 -Enable; 0 - Disable");
4040

41+
static char *macaddr;
42+
module_param(macaddr, charp, 0);
43+
MODULE_PARM_DESC(macaddr, "Ethernet MAC address");
44+
4145
struct vdpasim_virtqueue {
4246
struct vringh vring;
4347
struct vringh_kiov iov;
@@ -60,7 +64,8 @@ struct vdpasim_virtqueue {
6064

6165
static u64 vdpasim_features = (1ULL << VIRTIO_F_ANY_LAYOUT) |
6266
(1ULL << VIRTIO_F_VERSION_1) |
63-
(1ULL << VIRTIO_F_ACCESS_PLATFORM);
67+
(1ULL << VIRTIO_F_ACCESS_PLATFORM) |
68+
(1ULL << VIRTIO_NET_F_MAC);
6469

6570
/* State of each vdpasim device */
6671
struct vdpasim {
@@ -361,7 +366,9 @@ static struct vdpasim *vdpasim_create(void)
361366
spin_lock_init(&vdpasim->iommu_lock);
362367

363368
dev = &vdpasim->vdpa.dev;
364-
dev->coherent_dma_mask = DMA_BIT_MASK(64);
369+
dev->dma_mask = &dev->coherent_dma_mask;
370+
if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)))
371+
goto err_iommu;
365372
set_dma_ops(dev, &vdpasim_dma_ops);
366373

367374
vdpasim->iommu = vhost_iotlb_alloc(2048, 0);
@@ -372,7 +379,15 @@ static struct vdpasim *vdpasim_create(void)
372379
if (!vdpasim->buffer)
373380
goto err_iommu;
374381

375-
eth_random_addr(vdpasim->config.mac);
382+
if (macaddr) {
383+
mac_pton(macaddr, vdpasim->config.mac);
384+
if (!is_valid_ether_addr(vdpasim->config.mac)) {
385+
ret = -EADDRNOTAVAIL;
386+
goto err_iommu;
387+
}
388+
} else {
389+
eth_random_addr(vdpasim->config.mac);
390+
}
376391

377392
vringh_set_iotlb(&vdpasim->vqs[0].vring, vdpasim->iommu);
378393
vringh_set_iotlb(&vdpasim->vqs[1].vring, vdpasim->iommu);
@@ -574,6 +589,16 @@ static u32 vdpasim_get_generation(struct vdpa_device *vdpa)
574589
return vdpasim->generation;
575590
}
576591

592+
static struct vdpa_iova_range vdpasim_get_iova_range(struct vdpa_device *vdpa)
593+
{
594+
struct vdpa_iova_range range = {
595+
.first = 0ULL,
596+
.last = ULLONG_MAX,
597+
};
598+
599+
return range;
600+
}
601+
577602
static int vdpasim_set_map(struct vdpa_device *vdpa,
578603
struct vhost_iotlb *iotlb)
579604
{
@@ -657,6 +682,7 @@ static const struct vdpa_config_ops vdpasim_net_config_ops = {
657682
.get_config = vdpasim_get_config,
658683
.set_config = vdpasim_set_config,
659684
.get_generation = vdpasim_get_generation,
685+
.get_iova_range = vdpasim_get_iova_range,
660686
.dma_map = vdpasim_dma_map,
661687
.dma_unmap = vdpasim_dma_unmap,
662688
.free = vdpasim_free,
@@ -683,6 +709,7 @@ static const struct vdpa_config_ops vdpasim_net_batch_config_ops = {
683709
.get_config = vdpasim_get_config,
684710
.set_config = vdpasim_set_config,
685711
.get_generation = vdpasim_get_generation,
712+
.get_iova_range = vdpasim_get_iova_range,
686713
.set_map = vdpasim_set_map,
687714
.free = vdpasim_free,
688715
};

drivers/vhost/vdpa.c

Lines changed: 97 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct vhost_vdpa {
4747
int minor;
4848
struct eventfd_ctx *config_ctx;
4949
int in_batch;
50+
struct vdpa_iova_range range;
5051
};
5152

5253
static DEFINE_IDA(vhost_vdpa_ida);
@@ -103,6 +104,9 @@ static void vhost_vdpa_setup_vq_irq(struct vhost_vdpa *v, u16 qid)
103104
vq->call_ctx.producer.token = vq->call_ctx.ctx;
104105
vq->call_ctx.producer.irq = irq;
105106
ret = irq_bypass_register_producer(&vq->call_ctx.producer);
107+
if (unlikely(ret))
108+
dev_info(&v->dev, "vq %u, irq bypass producer (token %p) registration fails, ret = %d\n",
109+
qid, vq->call_ctx.producer.token, ret);
106110
}
107111

108112
static void vhost_vdpa_unsetup_vq_irq(struct vhost_vdpa *v, u16 qid)
@@ -337,6 +341,16 @@ static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp)
337341
return 0;
338342
}
339343

344+
static long vhost_vdpa_get_iova_range(struct vhost_vdpa *v, u32 __user *argp)
345+
{
346+
struct vhost_vdpa_iova_range range = {
347+
.first = v->range.first,
348+
.last = v->range.last,
349+
};
350+
351+
return copy_to_user(argp, &range, sizeof(range));
352+
}
353+
340354
static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
341355
void __user *argp)
342356
{
@@ -421,12 +435,11 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
421435
void __user *argp = (void __user *)arg;
422436
u64 __user *featurep = argp;
423437
u64 features;
424-
long r;
438+
long r = 0;
425439

426440
if (cmd == VHOST_SET_BACKEND_FEATURES) {
427-
r = copy_from_user(&features, featurep, sizeof(features));
428-
if (r)
429-
return r;
441+
if (copy_from_user(&features, featurep, sizeof(features)))
442+
return -EFAULT;
430443
if (features & ~VHOST_VDPA_BACKEND_FEATURES)
431444
return -EOPNOTSUPP;
432445
vhost_set_backend_features(&v->vdev, features);
@@ -469,7 +482,11 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
469482
break;
470483
case VHOST_GET_BACKEND_FEATURES:
471484
features = VHOST_VDPA_BACKEND_FEATURES;
472-
r = copy_to_user(featurep, &features, sizeof(features));
485+
if (copy_to_user(featurep, &features, sizeof(features)))
486+
r = -EFAULT;
487+
break;
488+
case VHOST_VDPA_GET_IOVA_RANGE:
489+
r = vhost_vdpa_get_iova_range(v, argp);
473490
break;
474491
default:
475492
r = vhost_dev_ioctl(&v->vdev, cmd, argp);
@@ -588,106 +605,87 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
588605
struct vhost_dev *dev = &v->vdev;
589606
struct vhost_iotlb *iotlb = dev->iotlb;
590607
struct page **page_list;
591-
struct vm_area_struct **vmas;
608+
unsigned long list_size = PAGE_SIZE / sizeof(struct page *);
592609
unsigned int gup_flags = FOLL_LONGTERM;
593-
unsigned long map_pfn, last_pfn = 0;
594-
unsigned long npages, lock_limit;
595-
unsigned long i, nmap = 0;
610+
unsigned long npages, cur_base, map_pfn, last_pfn = 0;
611+
unsigned long locked, lock_limit, pinned, i;
596612
u64 iova = msg->iova;
597-
long pinned;
598613
int ret = 0;
599614

615+
if (msg->iova < v->range.first ||
616+
msg->iova + msg->size - 1 > v->range.last)
617+
return -EINVAL;
618+
600619
if (vhost_iotlb_itree_first(iotlb, msg->iova,
601620
msg->iova + msg->size - 1))
602621
return -EEXIST;
603622

623+
page_list = (struct page **) __get_free_page(GFP_KERNEL);
624+
if (!page_list)
625+
return -ENOMEM;
626+
604627
if (msg->perm & VHOST_ACCESS_WO)
605628
gup_flags |= FOLL_WRITE;
606629

607630
npages = PAGE_ALIGN(msg->size + (iova & ~PAGE_MASK)) >> PAGE_SHIFT;
608631
if (!npages)
609632
return -EINVAL;
610633

611-
page_list = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
612-
vmas = kvmalloc_array(npages, sizeof(struct vm_area_struct *),
613-
GFP_KERNEL);
614-
if (!page_list || !vmas) {
615-
ret = -ENOMEM;
616-
goto free;
617-
}
618-
619634
mmap_read_lock(dev->mm);
620635

636+
locked = atomic64_add_return(npages, &dev->mm->pinned_vm);
621637
lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
622-
if (npages + atomic64_read(&dev->mm->pinned_vm) > lock_limit) {
623-
ret = -ENOMEM;
624-
goto unlock;
625-
}
626638

627-
pinned = pin_user_pages(msg->uaddr & PAGE_MASK, npages, gup_flags,
628-
page_list, vmas);
629-
if (npages != pinned) {
630-
if (pinned < 0) {
631-
ret = pinned;
632-
} else {
633-
unpin_user_pages(page_list, pinned);
634-
ret = -ENOMEM;
635-
}
636-
goto unlock;
639+
if (locked > lock_limit) {
640+
ret = -ENOMEM;
641+
goto out;
637642
}
638643

644+
cur_base = msg->uaddr & PAGE_MASK;
639645
iova &= PAGE_MASK;
640-
map_pfn = page_to_pfn(page_list[0]);
641-
642-
/* One more iteration to avoid extra vdpa_map() call out of loop. */
643-
for (i = 0; i <= npages; i++) {
644-
unsigned long this_pfn;
645-
u64 csize;
646-
647-
/* The last chunk may have no valid PFN next to it */
648-
this_pfn = i < npages ? page_to_pfn(page_list[i]) : -1UL;
649-
650-
if (last_pfn && (this_pfn == -1UL ||
651-
this_pfn != last_pfn + 1)) {
652-
/* Pin a contiguous chunk of memory */
653-
csize = last_pfn - map_pfn + 1;
654-
ret = vhost_vdpa_map(v, iova, csize << PAGE_SHIFT,
655-
map_pfn << PAGE_SHIFT,
656-
msg->perm);
657-
if (ret) {
658-
/*
659-
* Unpin the rest chunks of memory on the
660-
* flight with no corresponding vdpa_map()
661-
* calls having been made yet. On the other
662-
* hand, vdpa_unmap() in the failure path
663-
* is in charge of accounting the number of
664-
* pinned pages for its own.
665-
* This asymmetrical pattern of accounting
666-
* is for efficiency to pin all pages at
667-
* once, while there is no other callsite
668-
* of vdpa_map() than here above.
669-
*/
670-
unpin_user_pages(&page_list[nmap],
671-
npages - nmap);
672-
goto out;
646+
647+
while (npages) {
648+
pinned = min_t(unsigned long, npages, list_size);
649+
ret = pin_user_pages(cur_base, pinned,
650+
gup_flags, page_list, NULL);
651+
if (ret != pinned)
652+
goto out;
653+
654+
if (!last_pfn)
655+
map_pfn = page_to_pfn(page_list[0]);
656+
657+
for (i = 0; i < ret; i++) {
658+
unsigned long this_pfn = page_to_pfn(page_list[i]);
659+
u64 csize;
660+
661+
if (last_pfn && (this_pfn != last_pfn + 1)) {
662+
/* Pin a contiguous chunk of memory */
663+
csize = (last_pfn - map_pfn + 1) << PAGE_SHIFT;
664+
if (vhost_vdpa_map(v, iova, csize,
665+
map_pfn << PAGE_SHIFT,
666+
msg->perm))
667+
goto out;
668+
map_pfn = this_pfn;
669+
iova += csize;
673670
}
674-
atomic64_add(csize, &dev->mm->pinned_vm);
675-
nmap += csize;
676-
iova += csize << PAGE_SHIFT;
677-
map_pfn = this_pfn;
671+
672+
last_pfn = this_pfn;
678673
}
679-
last_pfn = this_pfn;
674+
675+
cur_base += ret << PAGE_SHIFT;
676+
npages -= ret;
680677
}
681678

682-
WARN_ON(nmap != npages);
679+
/* Pin the rest chunk */
680+
ret = vhost_vdpa_map(v, iova, (last_pfn - map_pfn + 1) << PAGE_SHIFT,
681+
map_pfn << PAGE_SHIFT, msg->perm);
683682
out:
684-
if (ret)
683+
if (ret) {
685684
vhost_vdpa_unmap(v, msg->iova, msg->size);
686-
unlock:
685+
atomic64_sub(npages, &dev->mm->pinned_vm);
686+
}
687687
mmap_read_unlock(dev->mm);
688-
free:
689-
kvfree(vmas);
690-
kvfree(page_list);
688+
free_page((unsigned long)page_list);
691689
return ret;
692690
}
693691

@@ -783,6 +781,27 @@ static void vhost_vdpa_free_domain(struct vhost_vdpa *v)
783781
v->domain = NULL;
784782
}
785783

784+
static void vhost_vdpa_set_iova_range(struct vhost_vdpa *v)
785+
{
786+
struct vdpa_iova_range *range = &v->range;
787+
struct iommu_domain_geometry geo;
788+
struct vdpa_device *vdpa = v->vdpa;
789+
const struct vdpa_config_ops *ops = vdpa->config;
790+
791+
if (ops->get_iova_range) {
792+
*range = ops->get_iova_range(vdpa);
793+
} else if (v->domain &&
794+
!iommu_domain_get_attr(v->domain,
795+
DOMAIN_ATTR_GEOMETRY, &geo) &&
796+
geo.force_aperture) {
797+
range->first = geo.aperture_start;
798+
range->last = geo.aperture_end;
799+
} else {
800+
range->first = 0;
801+
range->last = ULLONG_MAX;
802+
}
803+
}
804+
786805
static int vhost_vdpa_open(struct inode *inode, struct file *filep)
787806
{
788807
struct vhost_vdpa *v;
@@ -823,6 +842,8 @@ static int vhost_vdpa_open(struct inode *inode, struct file *filep)
823842
if (r)
824843
goto err_init_iotlb;
825844

845+
vhost_vdpa_set_iova_range(v);
846+
826847
filep->private_data = v;
827848

828849
return 0;

include/linux/vdpa.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ struct vdpa_device {
5252
int nvqs;
5353
};
5454

55+
/**
56+
* vDPA IOVA range - the IOVA range support by the device
57+
* @first: start of the IOVA range
58+
* @last: end of the IOVA range
59+
*/
60+
struct vdpa_iova_range {
61+
u64 first;
62+
u64 last;
63+
};
64+
5565
/**
5666
* vDPA_config_ops - operations for configuring a vDPA device.
5767
* Note: vDPA device drivers are required to implement all of the
@@ -151,6 +161,10 @@ struct vdpa_device {
151161
* @get_generation: Get device config generation (optional)
152162
* @vdev: vdpa device
153163
* Returns u32: device generation
164+
* @get_iova_range: Get supported iova range (optional)
165+
* @vdev: vdpa device
166+
* Returns the iova range supported by
167+
* the device.
154168
* @set_map: Set device memory mapping (optional)
155169
* Needed for device that using device
156170
* specific DMA translation (on-chip IOMMU)
@@ -216,6 +230,7 @@ struct vdpa_config_ops {
216230
void (*set_config)(struct vdpa_device *vdev, unsigned int offset,
217231
const void *buf, unsigned int len);
218232
u32 (*get_generation)(struct vdpa_device *vdev);
233+
struct vdpa_iova_range (*get_iova_range)(struct vdpa_device *vdev);
219234

220235
/* DMA ops */
221236
int (*set_map)(struct vdpa_device *vdev, struct vhost_iotlb *iotlb);

0 commit comments

Comments
 (0)