|
@@ -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);
|
|
|
}
|