aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Brucker <jean-philippe.brucker@arm.com>2022-07-01 15:24:25 +0100
committerWill Deacon <will@kernel.org>2022-07-01 16:09:00 +0100
commit21c9bc7440878fd341c26a32a068e045ff188e5c (patch)
tree65f2fb4351c7a3c9e9f0a62f1e84e55fc91d00c9
parentd0607293c937ec3f3fd1b69ef535a3a282754f9c (diff)
downloadkvmtool-21c9bc7440878fd341c26a32a068e045ff188e5c.tar.gz
virtio/pci: Make doorbell offset dynamic
The doorbell offset depends on the transport - virtio-legacy uses a fixed offset, but modern virtio can have per-vq offsets. Add an offset field to the virtio_pci structure. Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> Link: https://lore.kernel.org/r/20220701142434.75170-4-jean-philippe.brucker@arm.com Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r--include/kvm/virtio-pci.h1
-rw-r--r--virtio/pci.c14
2 files changed, 10 insertions, 5 deletions
diff --git a/include/kvm/virtio-pci.h b/include/kvm/virtio-pci.h
index 959b4b81..d64e5c99 100644
--- a/include/kvm/virtio-pci.h
+++ b/include/kvm/virtio-pci.h
@@ -24,6 +24,7 @@ struct virtio_pci {
void *dev;
struct kvm *kvm;
+ u32 doorbell_offset;
u8 status;
u8 isr;
u32 features;
diff --git a/virtio/pci.c b/virtio/pci.c
index f0459925..c02534a6 100644
--- a/virtio/pci.c
+++ b/virtio/pci.c
@@ -81,6 +81,7 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_device *vde
struct virtio_pci *vpci = vdev->virtio;
u32 mmio_addr = virtio_pci__mmio_addr(vpci);
u16 port_addr = virtio_pci__port_addr(vpci);
+ off_t offset = vpci->doorbell_offset;
int r, flags = 0;
int fd;
@@ -104,7 +105,7 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_device *vde
flags |= IOEVENTFD_FLAG_USER_POLL;
/* ioport */
- ioevent.io_addr = port_addr + VIRTIO_PCI_QUEUE_NOTIFY;
+ ioevent.io_addr = port_addr + offset;
ioevent.io_len = sizeof(u16);
ioevent.fd = fd = eventfd(0, 0);
r = ioeventfd__add_event(&ioevent, flags | IOEVENTFD_FLAG_PIO);
@@ -112,7 +113,7 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_device *vde
return r;
/* mmio */
- ioevent.io_addr = mmio_addr + VIRTIO_PCI_QUEUE_NOTIFY;
+ ioevent.io_addr = mmio_addr + offset;
ioevent.io_len = sizeof(u16);
ioevent.fd = eventfd(0, 0);
r = ioeventfd__add_event(&ioevent, flags);
@@ -124,7 +125,7 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_device *vde
return 0;
free_ioport_evt:
- ioeventfd__del_event(port_addr + VIRTIO_PCI_QUEUE_NOTIFY, vq);
+ ioeventfd__del_event(port_addr + offset, vq);
return r;
}
@@ -148,12 +149,13 @@ static void virtio_pci_exit_vq(struct kvm *kvm, struct virtio_device *vdev,
struct virtio_pci *vpci = vdev->virtio;
u32 mmio_addr = virtio_pci__mmio_addr(vpci);
u16 port_addr = virtio_pci__port_addr(vpci);
+ off_t offset = vpci->doorbell_offset;
virtio_pci__del_msix_route(vpci, vpci->gsis[vq]);
vpci->gsis[vq] = 0;
vpci->vq_vector[vq] = VIRTIO_MSI_NO_VECTOR;
- ioeventfd__del_event(mmio_addr + VIRTIO_PCI_QUEUE_NOTIFY, vq);
- ioeventfd__del_event(port_addr + VIRTIO_PCI_QUEUE_NOTIFY, vq);
+ ioeventfd__del_event(mmio_addr + offset, vq);
+ ioeventfd__del_event(port_addr + offset, vq);
virtio_exit_vq(kvm, vdev, vpci->dev, vq);
}
@@ -571,6 +573,8 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
mmio_addr = pci_get_mmio_block(PCI_IO_SIZE);
msix_io_block = pci_get_mmio_block(VIRTIO_MSIX_BAR_SIZE);
+ vpci->doorbell_offset = VIRTIO_PCI_QUEUE_NOTIFY;
+
vpci->pci_hdr = (struct pci_device_header) {
.vendor_id = cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
.device_id = cpu_to_le16(device_id),