Skip to content

Commit 4bf13fd

Browse files
vwaxgregkh
authored andcommitted
mic: vop: Fix crash on remove
The remove path contains a hack which depends on internal structures in other source files, similar to the one which was recently removed from the registration path. Since commit 1ce9e60 ("virtio_ring: introduce packed ring support"), this leads to a crash when vop devices are removed. The structure in question is only examined to get the virtual address of the allocated used page. Store that pointer locally instead to fix the crash. Fixes: 1ce9e60 ("virtio_ring: introduce packed ring support") Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 70ed714 commit 4bf13fd

File tree

1 file changed

+6
-3
lines changed

1 file changed

+6
-3
lines changed

drivers/misc/mic/vop/vop_main.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@
4747
* @dc: Virtio device control
4848
* @vpdev: VOP device which is the parent for this virtio device
4949
* @vr: Buffer for accessing the VRING
50-
* @used: Buffer for used
50+
* @used_virt: Virtual address of used ring
51+
* @used: DMA address of used ring
5152
* @used_size: Size of the used buffer
5253
* @reset_done: Track whether VOP reset is complete
5354
* @virtio_cookie: Cookie returned upon requesting a interrupt
@@ -61,6 +62,7 @@ struct _vop_vdev {
6162
struct mic_device_ctrl __iomem *dc;
6263
struct vop_device *vpdev;
6364
void __iomem *vr[VOP_MAX_VRINGS];
65+
void *used_virt[VOP_MAX_VRINGS];
6466
dma_addr_t used[VOP_MAX_VRINGS];
6567
int used_size[VOP_MAX_VRINGS];
6668
struct completion reset_done;
@@ -260,12 +262,12 @@ static bool vop_notify(struct virtqueue *vq)
260262
static void vop_del_vq(struct virtqueue *vq, int n)
261263
{
262264
struct _vop_vdev *vdev = to_vopvdev(vq->vdev);
263-
struct vring *vr = (struct vring *)(vq + 1);
264265
struct vop_device *vpdev = vdev->vpdev;
265266

266267
dma_unmap_single(&vpdev->dev, vdev->used[n],
267268
vdev->used_size[n], DMA_BIDIRECTIONAL);
268-
free_pages((unsigned long)vr->used, get_order(vdev->used_size[n]));
269+
free_pages((unsigned long)vdev->used_virt[n],
270+
get_order(vdev->used_size[n]));
269271
vring_del_virtqueue(vq);
270272
vpdev->hw_ops->iounmap(vpdev, vdev->vr[n]);
271273
vdev->vr[n] = NULL;
@@ -355,6 +357,7 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev,
355357
le16_to_cpu(config.num));
356358
used = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
357359
get_order(vdev->used_size[index]));
360+
vdev->used_virt[index] = used;
358361
if (!used) {
359362
err = -ENOMEM;
360363
dev_err(_vop_dev(vdev), "%s %d err %d\n",

0 commit comments

Comments
 (0)