From 46728d732b3a634c6c57beb0065b1bcd27d24ee4 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Thu, 15 Apr 2021 03:31:46 -0400 Subject: [PATCH] virtio-pci library: report resource address stable inclusion from stable-v5.13 commit 9e311bcad73dc14bd0a736db6ad3d382227e11fe category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I5WXCZ CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=9e311bcad73dc14bd0a736db6ad3d382227e11fe ---------------------------------------------------------------------- Sometimes it might be useful to report the capability physical address. One example is to report the physical address of the doorbell in order to be mapped by userspace. Signed-off-by: Jason Wang Link: https://lore.kernel.org/r/20210415073147.19331-7-jasowang@redhat.com Signed-off-by: Michael S. Tsirkin Signed-off-by: Pengyuan Zhao --- drivers/vdpa/virtio_pci/vp_vdpa.c | 3 ++- drivers/virtio/virtio_pci_modern.c | 2 +- drivers/virtio/virtio_pci_modern_dev.c | 25 ++++++++++++++++++------- include/linux/virtio_pci_modern.h | 6 ++++-- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c b/drivers/vdpa/virtio_pci/vp_vdpa.c index a9ba4d6a27a2..1923e93f4429 100644 --- a/drivers/vdpa/virtio_pci/vp_vdpa.c +++ b/drivers/vdpa/virtio_pci/vp_vdpa.c @@ -423,7 +423,8 @@ static int vp_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id) for (i = 0; i < vp_vdpa->queues; i++) { vp_vdpa->vring[i].irq = VIRTIO_MSI_NO_VECTOR; - vp_vdpa->vring[i].notify = vp_modern_map_vq_notify(mdev, i); + vp_vdpa->vring[i].notify = + vp_modern_map_vq_notify(mdev, i, NULL); if (!vp_vdpa->vring[i].notify) { dev_warn(&pdev->dev, "Fail to map vq notify %d\n", i); goto err; diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c index 29607d9bd95c..722ea44e7579 100644 --- a/drivers/virtio/virtio_pci_modern.c +++ b/drivers/virtio/virtio_pci_modern.c @@ -224,7 +224,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev, virtqueue_get_avail_addr(vq), virtqueue_get_used_addr(vq)); - vq->priv = vp_modern_map_vq_notify(mdev, index); + vq->priv = vp_modern_map_vq_notify(mdev, index, NULL); if (!vq->priv) { err = -ENOMEM; goto err_map_notify; diff --git a/drivers/virtio/virtio_pci_modern_dev.c b/drivers/virtio/virtio_pci_modern_dev.c index 28cb5847fafa..60931fec2fb1 100644 --- a/drivers/virtio/virtio_pci_modern_dev.c +++ b/drivers/virtio/virtio_pci_modern_dev.c @@ -13,6 +13,7 @@ * @start: start from the capability * @size: map size * @len: the length that is actually mapped + * @pa: physical address of the capability * * Returns the io address of for the part of the capability */ @@ -20,7 +21,7 @@ void __iomem *vp_modern_map_capability(struct virtio_pci_modern_device *mdev, in size_t minlen, u32 align, u32 start, u32 size, - size_t *len) + size_t *len, resource_size_t *pa) { struct pci_dev *dev = mdev->pci_dev; u8 bar; @@ -88,6 +89,10 @@ void __iomem *vp_modern_map_capability(struct virtio_pci_modern_device *mdev, in dev_err(&dev->dev, "virtio_pci: unable to map virtio %u@%u on bar %i\n", length, offset, bar); + + else if (pa) + *pa = pci_resource_start(dev, bar) + offset; + return p; } EXPORT_SYMBOL_GPL(vp_modern_map_capability); @@ -275,12 +280,12 @@ int vp_modern_probe(struct virtio_pci_modern_device *mdev) mdev->common = vp_modern_map_capability(mdev, common, sizeof(struct virtio_pci_common_cfg), 4, 0, sizeof(struct virtio_pci_common_cfg), - NULL); + NULL, NULL); if (!mdev->common) goto err_map_common; mdev->isr = vp_modern_map_capability(mdev, isr, sizeof(u8), 1, 0, 1, - NULL); + NULL, NULL); if (!mdev->isr) goto err_map_isr; @@ -308,7 +313,8 @@ int vp_modern_probe(struct virtio_pci_modern_device *mdev) mdev->notify_base = vp_modern_map_capability(mdev, notify, 2, 2, 0, notify_length, - &mdev->notify_len); + &mdev->notify_len, + &mdev->notify_pa); if (!mdev->notify_base) goto err_map_notify; } else { @@ -321,7 +327,8 @@ int vp_modern_probe(struct virtio_pci_modern_device *mdev) if (device) { mdev->device = vp_modern_map_capability(mdev, device, 0, 4, 0, PAGE_SIZE, - &mdev->device_len); + &mdev->device_len, + NULL); if (!mdev->device) goto err_map_device; } @@ -598,11 +605,12 @@ EXPORT_SYMBOL_GPL(vp_modern_get_queue_notify_off); * specific virtqueue * @mdev: the modern virtio-pci device * @index: the queue index + * @pa: the pointer to the physical address of the nofity area * * Returns the address of the notification area */ void *vp_modern_map_vq_notify(struct virtio_pci_modern_device *mdev, - u16 index) + u16 index, resource_size_t *pa) { u16 off = vp_modern_get_queue_notify_off(mdev, index); @@ -617,13 +625,16 @@ void *vp_modern_map_vq_notify(struct virtio_pci_modern_device *mdev, index, mdev->notify_len); return NULL; } + if (pa) + *pa = mdev->notify_pa + + off * mdev->notify_offset_multiplier; return (void __force *)mdev->notify_base + off * mdev->notify_offset_multiplier; } else { return (void __force *)vp_modern_map_capability(mdev, mdev->notify_map_cap, 2, 2, off * mdev->notify_offset_multiplier, 2, - NULL); + NULL, pa); } } EXPORT_SYMBOL_GPL(vp_modern_map_vq_notify); diff --git a/include/linux/virtio_pci_modern.h b/include/linux/virtio_pci_modern.h index 1b95d39b00fc..541ee88348c3 100644 --- a/include/linux/virtio_pci_modern.h +++ b/include/linux/virtio_pci_modern.h @@ -13,6 +13,8 @@ struct virtio_pci_modern_device { void __iomem *device; /* Base of vq notifications (non-legacy mode). */ void __iomem *notify_base; + /* Physical base of vq notifications */ + resource_size_t notify_pa; /* Where to read and clear interrupt */ u8 __iomem *isr; @@ -105,9 +107,9 @@ void __iomem *vp_modern_map_capability(struct virtio_pci_modern_device *mdev, in size_t minlen, u32 align, u32 start, u32 size, - size_t *len); + size_t *len, resource_size_t *pa); void *vp_modern_map_vq_notify(struct virtio_pci_modern_device *mdev, - u16 index); + u16 index, resource_size_t *pa); int vp_modern_probe(struct virtio_pci_modern_device *mdev); void vp_modern_remove(struct virtio_pci_modern_device *mdev); #endif -- GitLab