Commit 9e311bca authored by Jason Wang's avatar Jason Wang Committed by Michael S. Tsirkin
Browse files

virtio-pci library: report resource address



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: default avatarJason Wang <jasowang@redhat.com>
Link: https://lore.kernel.org/r/20210415073147.19331-7-jasowang@redhat.com


Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent fd466b36
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -415,7 +415,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;
+1 −1
Original line number Diff line number Diff line
@@ -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;
+17 −7
Original line number Diff line number Diff line
@@ -13,13 +13,14 @@
 * @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
 */
static void __iomem *
vp_modern_map_capability(struct virtio_pci_modern_device *mdev, int off,
			 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;
@@ -87,6 +88,9 @@ vp_modern_map_capability(struct virtio_pci_modern_device *mdev, int off,
		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;
}

@@ -273,12 +277,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;

@@ -306,7 +310,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 {
@@ -319,7 +324,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;
	}
@@ -595,11 +601,12 @@ static u16 vp_modern_get_queue_notify_off(struct virtio_pci_modern_device *mdev,
 * 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);

@@ -614,13 +621,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);
+3 −1
Original line number Diff line number Diff line
@@ -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;

@@ -100,7 +102,7 @@ u16 vp_modern_get_queue_size(struct virtio_pci_modern_device *mdev,
			     u16 idx);
u16 vp_modern_get_num_queues(struct virtio_pci_modern_device *mdev);
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