Robin Murphy
2019-Jul-22 15:36 UTC
[PATCH 2/2] virtio/virtio_ring: Fix the dma_max_mapping_size call
On 22/07/2019 15:55, Eric Auger wrote:> Do not call dma_max_mapping_size for devices that have no DMA > mask set, otherwise we can hit a NULL pointer dereference. > > This occurs when a virtio-blk-pci device is protected with > a virtual IOMMU. > > Fixes: e6d6dd6c875e ("virtio: Introduce virtio_max_dma_size()") > Signed-off-by: Eric Auger <eric.auger at redhat.com> > Suggested-by: Christoph Hellwig <hch at lst.de> > --- > drivers/virtio/virtio_ring.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c > index c8be1c4f5b55..37c143971211 100644 > --- a/drivers/virtio/virtio_ring.c > +++ b/drivers/virtio/virtio_ring.c > @@ -262,7 +262,7 @@ size_t virtio_max_dma_size(struct virtio_device *vdev) > { > size_t max_segment_size = SIZE_MAX; > > - if (vring_use_dma_api(vdev)) > + if (vring_use_dma_api(vdev) && vdev->dev.dma_mask)Hmm, might it make sense to roll that check up into vring_use_dma_api() itself? After all, if the device has no mask then it's likely that other DMA API ops wouldn't really work as expected either. Robin.> max_segment_size = dma_max_mapping_size(&vdev->dev); > > return max_segment_size; >
Michael S. Tsirkin
2019-Jul-22 15:45 UTC
[PATCH 2/2] virtio/virtio_ring: Fix the dma_max_mapping_size call
On Mon, Jul 22, 2019 at 04:36:09PM +0100, Robin Murphy wrote:> On 22/07/2019 15:55, Eric Auger wrote: > > Do not call dma_max_mapping_size for devices that have no DMA > > mask set, otherwise we can hit a NULL pointer dereference. > > > > This occurs when a virtio-blk-pci device is protected with > > a virtual IOMMU. > > > > Fixes: e6d6dd6c875e ("virtio: Introduce virtio_max_dma_size()") > > Signed-off-by: Eric Auger <eric.auger at redhat.com> > > Suggested-by: Christoph Hellwig <hch at lst.de> > > --- > > drivers/virtio/virtio_ring.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c > > index c8be1c4f5b55..37c143971211 100644 > > --- a/drivers/virtio/virtio_ring.c > > +++ b/drivers/virtio/virtio_ring.c > > @@ -262,7 +262,7 @@ size_t virtio_max_dma_size(struct virtio_device *vdev) > > { > > size_t max_segment_size = SIZE_MAX; > > - if (vring_use_dma_api(vdev)) > > + if (vring_use_dma_api(vdev) && vdev->dev.dma_mask) > > Hmm, might it make sense to roll that check up into vring_use_dma_api() > itself? After all, if the device has no mask then it's likely that other DMA > API ops wouldn't really work as expected either. > > Robin.Nope, Eric pointed out it's just dma_addressing_limited that is broken. Other APIs call dma_get_mask which handles the NULL mask case fine.> > max_segment_size = dma_max_mapping_size(&vdev->dev); > > return max_segment_size; > >
Christoph Hellwig
2019-Jul-23 15:38 UTC
[PATCH 2/2] virtio/virtio_ring: Fix the dma_max_mapping_size call
On Mon, Jul 22, 2019 at 04:36:09PM +0100, Robin Murphy wrote:>> diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c >> index c8be1c4f5b55..37c143971211 100644 >> --- a/drivers/virtio/virtio_ring.c >> +++ b/drivers/virtio/virtio_ring.c >> @@ -262,7 +262,7 @@ size_t virtio_max_dma_size(struct virtio_device *vdev) >> { >> size_t max_segment_size = SIZE_MAX; >> - if (vring_use_dma_api(vdev)) >> + if (vring_use_dma_api(vdev) && vdev->dev.dma_mask) > > Hmm, might it make sense to roll that check up into vring_use_dma_api() > itself? After all, if the device has no mask then it's likely that other > DMA API ops wouldn't really work as expected either.Makes sense to me.
Michael S. Tsirkin
2019-Jul-24 22:10 UTC
[PATCH 2/2] virtio/virtio_ring: Fix the dma_max_mapping_size call
On Tue, Jul 23, 2019 at 05:38:51PM +0200, Christoph Hellwig wrote:> On Mon, Jul 22, 2019 at 04:36:09PM +0100, Robin Murphy wrote: > >> diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c > >> index c8be1c4f5b55..37c143971211 100644 > >> --- a/drivers/virtio/virtio_ring.c > >> +++ b/drivers/virtio/virtio_ring.c > >> @@ -262,7 +262,7 @@ size_t virtio_max_dma_size(struct virtio_device *vdev) > >> { > >> size_t max_segment_size = SIZE_MAX; > >> - if (vring_use_dma_api(vdev)) > >> + if (vring_use_dma_api(vdev) && vdev->dev.dma_mask) > > > > Hmm, might it make sense to roll that check up into vring_use_dma_api() > > itself? After all, if the device has no mask then it's likely that other > > DMA API ops wouldn't really work as expected either. > > Makes sense to me.Christoph - would a documented API wrapping dma_mask make sense? With the documentation explaining how users must desist from using DMA APIs if that returns false ... -- MST
Auger Eric
2019-Jul-25 11:53 UTC
[PATCH 2/2] virtio/virtio_ring: Fix the dma_max_mapping_size call
Hi, On 7/23/19 5:38 PM, Christoph Hellwig wrote:> On Mon, Jul 22, 2019 at 04:36:09PM +0100, Robin Murphy wrote: >>> diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c >>> index c8be1c4f5b55..37c143971211 100644 >>> --- a/drivers/virtio/virtio_ring.c >>> +++ b/drivers/virtio/virtio_ring.c >>> @@ -262,7 +262,7 @@ size_t virtio_max_dma_size(struct virtio_device *vdev) >>> { >>> size_t max_segment_size = SIZE_MAX; >>> - if (vring_use_dma_api(vdev)) >>> + if (vring_use_dma_api(vdev) && vdev->dev.dma_mask) >> >> Hmm, might it make sense to roll that check up into vring_use_dma_api() >> itself? After all, if the device has no mask then it's likely that other >> DMA API ops wouldn't really work as expected either. > > Makes sense to me. >I am confused: if vring_use_dma_api() returns false if the dma_mask is unset (ie. vring_use_dma_api() returns false), the virtio-blk-pci device will not be able to get translated addresses and won't work properly. The patch above allows the dma api to be used and only influences the max_segment_size and it works properly. So is it normal the dma_mask is unset in my case? Thanks Eric