aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Whitchurch <vincent.whitchurch@axis.com>2019-02-01 03:45:09 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-02-01 09:53:54 -0500
commit4bf13fdbc3567e571c20b415e4df70f564d54067 (patch)
tree8a624c8605796425923137747e9f1c1d9356fd48
parent70ed7148dadb812f2f7c9927e98ef3cf4869dfa9 (diff)
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 1ce9e6055fa0 ("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: 1ce9e6055fa0 ("virtio_ring: introduce packed ring support") Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/misc/mic/vop/vop_main.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/misc/mic/vop/vop_main.c b/drivers/misc/mic/vop/vop_main.c
index 9ee3fff3446a..744757f541be 100644
--- a/drivers/misc/mic/vop/vop_main.c
+++ b/drivers/misc/mic/vop/vop_main.c
@@ -47,7 +47,8 @@
47 * @dc: Virtio device control 47 * @dc: Virtio device control
48 * @vpdev: VOP device which is the parent for this virtio device 48 * @vpdev: VOP device which is the parent for this virtio device
49 * @vr: Buffer for accessing the VRING 49 * @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
51 * @used_size: Size of the used buffer 52 * @used_size: Size of the used buffer
52 * @reset_done: Track whether VOP reset is complete 53 * @reset_done: Track whether VOP reset is complete
53 * @virtio_cookie: Cookie returned upon requesting a interrupt 54 * @virtio_cookie: Cookie returned upon requesting a interrupt
@@ -61,6 +62,7 @@ struct _vop_vdev {
61 struct mic_device_ctrl __iomem *dc; 62 struct mic_device_ctrl __iomem *dc;
62 struct vop_device *vpdev; 63 struct vop_device *vpdev;
63 void __iomem *vr[VOP_MAX_VRINGS]; 64 void __iomem *vr[VOP_MAX_VRINGS];
65 void *used_virt[VOP_MAX_VRINGS];
64 dma_addr_t used[VOP_MAX_VRINGS]; 66 dma_addr_t used[VOP_MAX_VRINGS];
65 int used_size[VOP_MAX_VRINGS]; 67 int used_size[VOP_MAX_VRINGS];
66 struct completion reset_done; 68 struct completion reset_done;
@@ -260,12 +262,12 @@ static bool vop_notify(struct virtqueue *vq)
260static void vop_del_vq(struct virtqueue *vq, int n) 262static void vop_del_vq(struct virtqueue *vq, int n)
261{ 263{
262 struct _vop_vdev *vdev = to_vopvdev(vq->vdev); 264 struct _vop_vdev *vdev = to_vopvdev(vq->vdev);
263 struct vring *vr = (struct vring *)(vq + 1);
264 struct vop_device *vpdev = vdev->vpdev; 265 struct vop_device *vpdev = vdev->vpdev;
265 266
266 dma_unmap_single(&vpdev->dev, vdev->used[n], 267 dma_unmap_single(&vpdev->dev, vdev->used[n],
267 vdev->used_size[n], DMA_BIDIRECTIONAL); 268 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]));
269 vring_del_virtqueue(vq); 271 vring_del_virtqueue(vq);
270 vpdev->hw_ops->iounmap(vpdev, vdev->vr[n]); 272 vpdev->hw_ops->iounmap(vpdev, vdev->vr[n]);
271 vdev->vr[n] = NULL; 273 vdev->vr[n] = NULL;
@@ -355,6 +357,7 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev,
355 le16_to_cpu(config.num)); 357 le16_to_cpu(config.num));
356 used = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 358 used = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
357 get_order(vdev->used_size[index])); 359 get_order(vdev->used_size[index]));
360 vdev->used_virt[index] = used;
358 if (!used) { 361 if (!used) {
359 err = -ENOMEM; 362 err = -ENOMEM;
360 dev_err(_vop_dev(vdev), "%s %d err %d\n", 363 dev_err(_vop_dev(vdev), "%s %d err %d\n",