aboutsummaryrefslogtreecommitdiff
path: root/hw/virtio-pci.c
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2013-03-26 16:16:43 -0500
committerAnthony Liguori <aliguori@us.ibm.com>2013-03-26 16:16:43 -0500
commit404e7a4f4af753bd2aef649adf79e7434fb6dc31 (patch)
tree43a43089f2e5cab27bd5d514ba2e9753d9c760af /hw/virtio-pci.c
parent18501ae6e825d8da72369fd091018ef71071bd87 (diff)
parent6214e73cc5b75a4f8d89a70d71727edfa47a81b3 (diff)
downloadqemu-404e7a4f4af753bd2aef649adf79e7434fb6dc31.zip
qemu-404e7a4f4af753bd2aef649adf79e7434fb6dc31.tar.gz
qemu-404e7a4f4af753bd2aef649adf79e7434fb6dc31.tar.bz2
Merge remote-tracking branch 'mst/tags/for_anthony' into staging
virtio,pci,qom Work by Alex to support VGA assignment, pci and virtio fixes by Stefan, Jason and myself, and a new qmp event for hotplug support by myself. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Tue 26 Mar 2013 02:02:24 PM CDT using RSA key ID D28D5469 # gpg: Can't check signature: public key not found # By Alex Williamson (13) and others # Via Michael S. Tsirkin * mst/tags/for_anthony: (23 commits) pcie: Add endpoint capability initialization wrapper roms: switch oldnoconfig to olddefconfig pcie: Mangle types to match topology pci: Create and use API to determine root buses pci: Create pci_bus_is_express helper pci: Q35, Root Ports, and Switches create PCI Express buses pci: Allow PCI bus creation interfaces to specify the type of bus pci: Move PCI and PCIE type defines pci: Create and register a new PCI Express TypeInfo exec: assert that RAMBlock size is non-zero pci: refuse empty ROM files pci_bridge: Remove duplicate IRQ swizzle function pci_bridge: Use a default map_irq function pci: Fix INTx routing notifier recursion pci_bridge: drop formatting from source pci_bridge: factor out common code pci: Teach PCI Bridges about VGA routing pci: Add PCI VGA helpers virtio-pci: guest notifier mask without non-irqfd virtio-net: remove layout assumptions for mq ctrl ...
Diffstat (limited to 'hw/virtio-pci.c')
-rw-r--r--hw/virtio-pci.c79
1 files changed, 44 insertions, 35 deletions
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 668060d..736a9bf 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -609,20 +609,23 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
}
}
-static int kvm_virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
- unsigned int queue_no,
- unsigned int vector,
- MSIMessage msg)
+static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
+ unsigned int queue_no,
+ unsigned int vector,
+ MSIMessage msg)
{
VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
EventNotifier *n = virtio_queue_get_guest_notifier(vq);
- VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
+ VirtIOIRQFD *irqfd;
int ret = 0;
- if (irqfd->msg.data != msg.data || irqfd->msg.address != msg.address) {
- ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg);
- if (ret < 0) {
- return ret;
+ if (proxy->vector_irqfd) {
+ irqfd = &proxy->vector_irqfd[vector];
+ if (irqfd->msg.data != msg.data || irqfd->msg.address != msg.address) {
+ ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg);
+ if (ret < 0) {
+ return ret;
+ }
}
}
@@ -642,7 +645,7 @@ static int kvm_virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
return ret;
}
-static void kvm_virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
+static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
unsigned int queue_no,
unsigned int vector)
{
@@ -656,8 +659,8 @@ static void kvm_virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
}
}
-static int kvm_virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
- MSIMessage msg)
+static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
+ MSIMessage msg)
{
VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
VirtIODevice *vdev = proxy->vdev;
@@ -670,7 +673,7 @@ static int kvm_virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
if (virtio_queue_vector(vdev, queue_no) != vector) {
continue;
}
- ret = kvm_virtio_pci_vq_vector_unmask(proxy, queue_no, vector, msg);
+ ret = virtio_pci_vq_vector_unmask(proxy, queue_no, vector, msg);
if (ret < 0) {
goto undo;
}
@@ -682,12 +685,12 @@ undo:
if (virtio_queue_vector(vdev, queue_no) != vector) {
continue;
}
- kvm_virtio_pci_vq_vector_mask(proxy, queue_no, vector);
+ virtio_pci_vq_vector_mask(proxy, queue_no, vector);
}
return ret;
}
-static void kvm_virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
+static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
{
VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
VirtIODevice *vdev = proxy->vdev;
@@ -700,13 +703,13 @@ static void kvm_virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
if (virtio_queue_vector(vdev, queue_no) != vector) {
continue;
}
- kvm_virtio_pci_vq_vector_mask(proxy, queue_no, vector);
+ virtio_pci_vq_vector_mask(proxy, queue_no, vector);
}
}
-static void kvm_virtio_pci_vector_poll(PCIDevice *dev,
- unsigned int vector_start,
- unsigned int vector_end)
+static void virtio_pci_vector_poll(PCIDevice *dev,
+ unsigned int vector_start,
+ unsigned int vector_end)
{
VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
VirtIODevice *vdev = proxy->vdev;
@@ -781,11 +784,13 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
proxy->nvqs_with_notifiers = nvqs;
/* Must unset vector notifier while guest notifier is still assigned */
- if (proxy->vector_irqfd && !assign) {
+ if ((proxy->vector_irqfd || vdev->guest_notifier_mask) && !assign) {
msix_unset_vector_notifiers(&proxy->pci_dev);
- kvm_virtio_pci_vector_release(proxy, nvqs);
- g_free(proxy->vector_irqfd);
- proxy->vector_irqfd = NULL;
+ if (proxy->vector_irqfd) {
+ kvm_virtio_pci_vector_release(proxy, nvqs);
+ g_free(proxy->vector_irqfd);
+ proxy->vector_irqfd = NULL;
+ }
}
for (n = 0; n < nvqs; n++) {
@@ -801,18 +806,20 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
}
/* Must set vector notifier after guest notifier has been assigned */
- if (with_irqfd && assign) {
- proxy->vector_irqfd =
- g_malloc0(sizeof(*proxy->vector_irqfd) *
- msix_nr_vectors_allocated(&proxy->pci_dev));
- r = kvm_virtio_pci_vector_use(proxy, nvqs);
- if (r < 0) {
- goto assign_error;
+ if ((with_irqfd || vdev->guest_notifier_mask) && assign) {
+ if (with_irqfd) {
+ proxy->vector_irqfd =
+ g_malloc0(sizeof(*proxy->vector_irqfd) *
+ msix_nr_vectors_allocated(&proxy->pci_dev));
+ r = kvm_virtio_pci_vector_use(proxy, nvqs);
+ if (r < 0) {
+ goto assign_error;
+ }
}
r = msix_set_vector_notifiers(&proxy->pci_dev,
- kvm_virtio_pci_vector_unmask,
- kvm_virtio_pci_vector_mask,
- kvm_virtio_pci_vector_poll);
+ virtio_pci_vector_unmask,
+ virtio_pci_vector_mask,
+ virtio_pci_vector_poll);
if (r < 0) {
goto notifiers_error;
}
@@ -821,8 +828,10 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
return 0;
notifiers_error:
- assert(assign);
- kvm_virtio_pci_vector_release(proxy, nvqs);
+ if (with_irqfd) {
+ assert(assign);
+ kvm_virtio_pci_vector_release(proxy, nvqs);
+ }
assign_error:
/* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */