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

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
...@@ -531,12 +531,12 @@ static int vop_virtio_copy_to_user(struct vop_vdev *vdev, void __user *ubuf, ...@@ -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); void __iomem *dbuf = vpdev->hw_ops->ioremap(vpdev, daddr, len);
struct vop_vringh *vvr = &vdev->vvr[vr_idx]; struct vop_vringh *vvr = &vdev->vvr[vr_idx];
struct vop_info *vi = dev_get_drvdata(&vpdev->dev); struct vop_info *vi = dev_get_drvdata(&vpdev->dev);
size_t dma_alignment = 1 << vi->dma_ch->device->copy_align; size_t dma_alignment;
bool x200 = is_dma_copy_aligned(vi->dma_ch->device, 1, 1, 1); bool x200;
size_t dma_offset, partlen; size_t dma_offset, partlen;
int err; int err;
if (!VOP_USE_DMA) { if (!VOP_USE_DMA || !vi->dma_ch) {
if (copy_to_user(ubuf, (void __force *)dbuf, len)) { if (copy_to_user(ubuf, (void __force *)dbuf, len)) {
err = -EFAULT; err = -EFAULT;
dev_err(vop_dev(vdev), "%s %d err %d\n", 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, ...@@ -548,6 +548,9 @@ static int vop_virtio_copy_to_user(struct vop_vdev *vdev, void __user *ubuf,
goto err; 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); dma_offset = daddr - round_down(daddr, dma_alignment);
daddr -= dma_offset; daddr -= dma_offset;
len += dma_offset; len += dma_offset;
...@@ -606,12 +609,16 @@ static int vop_virtio_copy_from_user(struct vop_vdev *vdev, void __user *ubuf, ...@@ -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); void __iomem *dbuf = vpdev->hw_ops->ioremap(vpdev, daddr, len);
struct vop_vringh *vvr = &vdev->vvr[vr_idx]; struct vop_vringh *vvr = &vdev->vvr[vr_idx];
struct vop_info *vi = dev_get_drvdata(&vdev->vpdev->dev); struct vop_info *vi = dev_get_drvdata(&vdev->vpdev->dev);
size_t dma_alignment = 1 << vi->dma_ch->device->copy_align; size_t dma_alignment;
bool x200 = is_dma_copy_aligned(vi->dma_ch->device, 1, 1, 1); bool x200;
size_t partlen; size_t partlen;
bool dma = VOP_USE_DMA; bool dma = VOP_USE_DMA && vi->dma_ch;
int err = 0; 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)) { if (daddr & (dma_alignment - 1)) {
vdev->tx_dst_unaligned += len; vdev->tx_dst_unaligned += len;
dma = false; dma = false;
...@@ -619,6 +626,7 @@ static int vop_virtio_copy_from_user(struct vop_vdev *vdev, void __user *ubuf, ...@@ -619,6 +626,7 @@ static int vop_virtio_copy_from_user(struct vop_vdev *vdev, void __user *ubuf,
vdev->tx_len_unaligned += len; vdev->tx_len_unaligned += len;
dma = false; dma = false;
} }
}
if (!dma) if (!dma)
goto memcpy; goto memcpy;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment