[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC][PATCH 34/45] qemu-kvm: Factor out kvm_device_msi_assi
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [RFC][PATCH 34/45] qemu-kvm: Factor out kvm_device_msi_assign |
Date: |
Mon, 17 Oct 2011 11:28:08 +0200 |
This reuses the MSI routing infrastructure of the KVM core by folding
both the routing setup and the IRQ assignment into a new function called
kvm_device_msi_assign. It's also a good chance to clean up the IRQ
deassignment before updates.
Signed-off-by: Jan Kiszka <address@hidden>
---
hw/device-assignment.c | 70 +++++++++++++----------------------------------
qemu-kvm.c | 16 +++++++++++
qemu-kvm.h | 2 +
3 files changed, 38 insertions(+), 50 deletions(-)
diff --git a/hw/device-assignment.c b/hw/device-assignment.c
index f145a84..7a8f702 100644
--- a/hw/device-assignment.c
+++ b/hw/device-assignment.c
@@ -40,6 +40,7 @@
#include "monitor.h"
#include "range.h"
#include "sysemu.h"
+#include "msi.h"
#define MSIX_PAGE_SIZE 0x1000
@@ -701,6 +702,11 @@ static void free_assigned_device(AssignedDevice *dev)
}
free_dev_irq_entries(dev);
+
+ if (dev->dev.msi_cache) {
+ kvm_msi_cache_invalidate(&dev->dev.msi_cache[0]);
+ g_free(dev->dev.msi_cache);
+ }
}
static uint32_t calc_assigned_dev_id(AssignedDevice *dev)
@@ -918,66 +924,28 @@ void assigned_dev_update_irqs(void)
static void assigned_dev_update_msi(PCIDevice *pci_dev)
{
- struct kvm_assigned_irq assigned_irq_data;
- AssignedDevice *assigned_dev = DO_UPCAST(AssignedDevice, dev, pci_dev);
+ AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev);
uint8_t ctrl_byte = pci_get_byte(pci_dev->config + pci_dev->msi_cap +
PCI_MSI_FLAGS);
- uint32_t dev_id;
- int r;
-
- dev_id = calc_assigned_dev_id(assigned_dev);
-
- /* Some guests gratuitously disable MSI even if they're not using it,
- * try to catch this by only deassigning irqs if the guest is using
- * MSI or intends to start. */
- if ((assigned_dev->irq_requested_type & KVM_DEV_IRQ_GUEST_MSI) ||
- (ctrl_byte & PCI_MSI_FLAGS_ENABLE)) {
- free_dev_irq_entries(assigned_dev);
- r = kvm_device_irq_deassign(kvm_state, dev_id,
- assigned_dev->irq_requested_type);
- /* -ENXIO means no assigned irq */
- if (r && r != -ENXIO)
- perror("assigned_dev_update_msi: deassign irq");
-
- assigned_dev->irq_requested_type = 0;
- }
if (ctrl_byte & PCI_MSI_FLAGS_ENABLE) {
uint8_t *pos = pci_dev->config + pci_dev->msi_cap;
+ MSIMessage msg;
- assigned_dev->entry = g_malloc0(sizeof(*(assigned_dev->entry)));
- assigned_dev->entry->u.msi.address_lo =
- pci_get_long(pos + PCI_MSI_ADDRESS_LO);
- assigned_dev->entry->u.msi.address_hi = 0;
- assigned_dev->entry->u.msi.data = pci_get_word(pos + PCI_MSI_DATA_32);
- assigned_dev->entry->type = KVM_IRQ_ROUTING_MSI;
- r = kvm_get_irq_route_gsi();
- if (r < 0) {
- perror("assigned_dev_update_msi: kvm_get_irq_route_gsi");
- return;
- }
- assigned_dev->entry->gsi = r;
+ deassign_irq(dev);
- kvm_add_routing_entry(assigned_dev->entry, NULL);
- if (kvm_commit_irq_routes() < 0) {
- perror("assigned_dev_update_msi: kvm_commit_irq_routes");
- assigned_dev->cap.state &= ~ASSIGNED_DEVICE_MSI_ENABLED;
- return;
- }
- assigned_dev->irq_entries_nr = 1;
+ msg.address = pci_get_long(pos + PCI_MSI_ADDRESS_LO);
+ msg.data = pci_get_word(pos + PCI_MSI_DATA_32);
- memset(&assigned_irq_data, 0, sizeof assigned_irq_data);
- assigned_irq_data.assigned_dev_id = dev_id;
- assigned_irq_data.guest_irq = assigned_dev->entry->gsi;
- assigned_irq_data.flags = KVM_DEV_IRQ_HOST_MSI | KVM_DEV_IRQ_GUEST_MSI;
- if (kvm_assign_irq(kvm_state, &assigned_irq_data) < 0) {
- perror("assigned_dev_enable_msi: assign irq");
+ if (kvm_device_msi_assign(kvm_state, calc_assigned_dev_id(dev), &msg,
+ &dev->dev.msi_cache[0]) < 0) {
+ perror("assigned_dev_update_msi: assign msi");
+ return;
}
-
- assigned_dev->girq = -1;
- assigned_dev->irq_requested_type = assigned_irq_data.flags;
+ dev->irq_requested_type = KVM_DEV_IRQ_HOST_MSI | KVM_DEV_IRQ_GUEST_MSI;
} else {
- assign_intx(assigned_dev);
+ kvm_msi_cache_invalidate(&dev->dev.msi_cache[0]);
+ assign_intx(dev);
}
}
@@ -1215,6 +1183,8 @@ static int assigned_device_pci_cap_init(PCIDevice
*pci_dev)
PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);
pci_set_long(pci_dev->wmask + pos + PCI_MSI_ADDRESS_LO, 0xfffffffc);
pci_set_word(pci_dev->wmask + pos + PCI_MSI_DATA_32, 0xffff);
+
+ dev->dev.msi_cache = g_malloc0(sizeof(MSIRoutingCache));
}
/* Expose MSI-X capability */
pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSIX, 0);
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 0086514..27723a6 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -600,6 +600,22 @@ int kvm_msi_irqfd_set(MSIMessage *msg, MSIRoutingCache
*cache, int fd,
return kvm_set_irqfd(cache->kvm_gsi, fd, assigned);
}
+int kvm_device_msi_assign(KVMState *s, uint32_t dev_id, MSIMessage *msg,
+ MSIRoutingCache *cache)
+{
+ struct kvm_assigned_irq assigned_irq;
+ int ret;
+
+ ret = kvm_msi_message_update(msg, cache, MSI_ROUTE_STATIC);
+ if (ret < 0) {
+ return ret;
+ }
+ assigned_irq.assigned_dev_id = dev_id;
+ assigned_irq.guest_irq = cache->kvm_gsi;
+ assigned_irq.flags = KVM_DEV_IRQ_HOST_MSI | KVM_DEV_IRQ_GUEST_MSI;
+ return kvm_vm_ioctl(s, KVM_ASSIGN_DEV_IRQ, &assigned_irq);
+}
+
#ifdef KVM_CAP_DEVICE_MSIX
int kvm_assign_set_msix_nr(KVMState *s, struct kvm_assigned_msix_nr *msix_nr)
{
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 783df7f..d987d41 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -152,6 +152,8 @@ int kvm_assign_irq(KVMState *s, struct kvm_assigned_irq
*assigned_irq);
int kvm_device_intx_assign(KVMState *s, uint32_t dev_id,
uint32_t host_irq_type, uint32_t guest_irq);
+int kvm_device_msi_assign(KVMState *s, uint32_t dev_id, MSIMessage *msg,
+ MSIRoutingCache *cache);
int kvm_device_irq_deassign(KVMState *s, uint32_t dev_id, uint32_t type);
/*!
--
1.7.3.4
- [Qemu-devel] [RFC][PATCH 09/45] msi: Factor out msi_message_from_vector, (continued)
- [Qemu-devel] [RFC][PATCH 04/45] msi: Invoke msi/msix_reset from PCI core, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 25/45] qemu-kvm: Update MSI cache on kvm_msi_irqfd_set, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 20/45] qemu-kvm: msix: Only invoke msix_handle_mask_update on changes, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 14/45] qemu-kvm: Drop useless kvm_clear_gsi_routes, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 34/45] qemu-kvm: Factor out kvm_device_msi_assign,
Jan Kiszka <=
- [Qemu-devel] [RFC][PATCH 08/45] Introduce MSIMessage structure, Jan Kiszka, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 08/45] Introduce MSIMessage structure, Michael S. Tsirkin, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 08/45] Introduce MSIMessage structure, Jan Kiszka, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 08/45] Introduce MSIMessage structure, Michael S. Tsirkin, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 08/45] Introduce MSIMessage structure, Jan Kiszka, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 08/45] Introduce MSIMessage structure, Michael S. Tsirkin, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 08/45] Introduce MSIMessage structure, Jan Kiszka, 2011/10/18
[Qemu-devel] [RFC][PATCH 16/45] qemu-kvm: Use MSIMessage and MSIRoutingCache, Jan Kiszka, 2011/10/17
[Qemu-devel] [RFC][PATCH 12/45] msi: Introduce MSIRoutingCache, Jan Kiszka, 2011/10/17