mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
virtio: pci-legacy: Validate queue pfn
Legacy PCI over virtio uses a 32bit PFN for the queue. If the queue pfn is too large to fit in 32bits, which we could hit on arm64 systems with 52bit physical addresses (even with 64K page size), we simply miss out a proper link to the other side of the queue. Add a check to validate the PFN, rather than silently breaking the devices. Cc: "Michael S. Tsirkin" <mst@redhat.com> Cc: Jason Wang <jasowang@redhat.com> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: Christoffer Dall <cdall@kernel.org> Cc: Peter Maydel <peter.maydell@linaro.org> Cc: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
3fc92a96c2
commit
69599206ea
@ -122,6 +122,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
|
||||
struct virtqueue *vq;
|
||||
u16 num;
|
||||
int err;
|
||||
u64 q_pfn;
|
||||
|
||||
/* Select the queue we're interested in */
|
||||
iowrite16(index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL);
|
||||
@ -141,9 +142,17 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
|
||||
if (!vq)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
q_pfn = virtqueue_get_desc_addr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
|
||||
if (q_pfn >> 32) {
|
||||
dev_err(&vp_dev->pci_dev->dev,
|
||||
"platform bug: legacy virtio-mmio must not be used with RAM above 0x%llxGB\n",
|
||||
0x1ULL << (32 + PAGE_SHIFT - 30));
|
||||
err = -E2BIG;
|
||||
goto out_del_vq;
|
||||
}
|
||||
|
||||
/* activate the queue */
|
||||
iowrite32(virtqueue_get_desc_addr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT,
|
||||
vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
|
||||
iowrite32(q_pfn, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
|
||||
|
||||
vq->priv = (void __force *)vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY;
|
||||
|
||||
@ -160,6 +169,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
|
||||
|
||||
out_deactivate:
|
||||
iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
|
||||
out_del_vq:
|
||||
vring_del_virtqueue(vq);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user