Commit 417406f2 authored by Vincent Whitchurch's avatar Vincent Whitchurch Committed by Greg Kroah-Hartman
Browse files

vop: vringh: Do not crash if no DMA channel



Fallback gracefully if no DMA channel is provided instead of
dereferencing NULL pointers.

Signed-off-by: default avatarVincent Whitchurch <vincent.whitchurch@axis.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 96c12ef9
Loading
Loading
Loading
Loading
+20 −12
Original line number Diff line number Diff line
@@ -531,12 +531,12 @@ static int vop_virtio_copy_to_user(struct vop_vdev *vdev, void __user *ubuf,
	void __iomem *dbuf = vpdev->hw_ops->ioremap(vpdev, daddr, len);
	struct vop_vringh *vvr = &vdev->vvr[vr_idx];
	struct vop_info *vi = dev_get_drvdata(&vpdev->dev);
	size_t dma_alignment = 1 << vi->dma_ch->device->copy_align;
	bool x200 = is_dma_copy_aligned(vi->dma_ch->device, 1, 1, 1);
	size_t dma_alignment;
	bool x200;
	size_t dma_offset, partlen;
	int err;

	if (!VOP_USE_DMA) {
	if (!VOP_USE_DMA || !vi->dma_ch) {
		if (copy_to_user(ubuf, (void __force *)dbuf, len)) {
			err = -EFAULT;
			dev_err(vop_dev(vdev), "%s %d err %d\n",
@@ -548,6 +548,9 @@ static int vop_virtio_copy_to_user(struct vop_vdev *vdev, void __user *ubuf,
		goto err;
	}

	dma_alignment = 1 << vi->dma_ch->device->copy_align;
	x200 = is_dma_copy_aligned(vi->dma_ch->device, 1, 1, 1);

	dma_offset = daddr - round_down(daddr, dma_alignment);
	daddr -= dma_offset;
	len += dma_offset;
@@ -606,12 +609,16 @@ static int vop_virtio_copy_from_user(struct vop_vdev *vdev, void __user *ubuf,
	void __iomem *dbuf = vpdev->hw_ops->ioremap(vpdev, daddr, len);
	struct vop_vringh *vvr = &vdev->vvr[vr_idx];
	struct vop_info *vi = dev_get_drvdata(&vdev->vpdev->dev);
	size_t dma_alignment = 1 << vi->dma_ch->device->copy_align;
	bool x200 = is_dma_copy_aligned(vi->dma_ch->device, 1, 1, 1);
	size_t dma_alignment;
	bool x200;
	size_t partlen;
	bool dma = VOP_USE_DMA;
	bool dma = VOP_USE_DMA && vi->dma_ch;
	int err = 0;

	if (dma) {
		dma_alignment = 1 << vi->dma_ch->device->copy_align;
		x200 = is_dma_copy_aligned(vi->dma_ch->device, 1, 1, 1);

		if (daddr & (dma_alignment - 1)) {
			vdev->tx_dst_unaligned += len;
			dma = false;
@@ -619,6 +626,7 @@ static int vop_virtio_copy_from_user(struct vop_vdev *vdev, void __user *ubuf,
			vdev->tx_len_unaligned += len;
			dma = false;
		}
	}

	if (!dma)
		goto memcpy;