[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC][PATCH 39/45] pci-assign: Use generic MSI support
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [RFC][PATCH 39/45] pci-assign: Use generic MSI support |
Date: |
Mon, 17 Oct 2011 11:28:13 +0200 |
Implement MSI support of a assigned devices via the generic MSI layer of
QEMU. Use config notifiers to update the vector route or switch back to
INTx when MSI gets disabled again.
Using the generic layer not only saves a bit code, it also fixes reset
while legacy MSI is in use and adds 64 bit support.
Signed-off-by: Jan Kiszka <address@hidden>
---
hw/device-assignment.c | 77 +++++++++++++++++++----------------------------
1 files changed, 31 insertions(+), 46 deletions(-)
diff --git a/hw/device-assignment.c b/hw/device-assignment.c
index 2484afd..10b30a3 100644
--- a/hw/device-assignment.c
+++ b/hw/device-assignment.c
@@ -699,10 +699,6 @@ static void free_assigned_device(AssignedDevice *dev)
close(dev->real_device.config_fd);
}
- if (dev->dev.msi_cache) {
- kvm_msi_cache_invalidate(&dev->dev.msi_cache[0]);
- g_free(dev->dev.msi_cache);
- }
invalidate_msix_vectors(dev);
g_free(dev->dev.msix_cache);
}
@@ -847,7 +843,7 @@ static int assign_intx(AssignedDevice *dev)
irq_type = KVM_DEV_IRQ_GUEST_INTX;
if (dev->features & ASSIGNED_DEVICE_PREFER_MSI_MASK &&
- dev->cap.available & ASSIGNED_DEVICE_CAP_MSI) {
+ msi_present(&dev->dev)) {
irq_type |= KVM_DEV_IRQ_HOST_MSI;
} else {
irq_type |= KVM_DEV_IRQ_HOST_INTX;
@@ -920,31 +916,33 @@ void assigned_dev_update_irqs(void)
}
}
-static void assigned_dev_update_msi(PCIDevice *pci_dev)
+static void assigned_dev_update_msi(PCIDevice *pci_dev, bool enabled)
{
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);
-
- if (ctrl_byte & PCI_MSI_FLAGS_ENABLE) {
- uint8_t *pos = pci_dev->config + pci_dev->msi_cap;
- MSIMessage msg;
- deassign_irq(dev);
+ if (!enabled) {
+ assign_intx(dev);
+ }
+}
- msg.address = pci_get_long(pos + PCI_MSI_ADDRESS_LO);
- msg.data = pci_get_word(pos + PCI_MSI_DATA_32);
+static int assigned_dev_update_msi_vector(PCIDevice *pci_dev,
+ unsigned int vector,
+ MSIMessage *msg, bool masked)
+{
+ AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev);
+ int ret;
- 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;
+ if (!masked) {
+ deassign_irq(dev);
+ ret = kvm_device_msi_assign(kvm_state, calc_assigned_dev_id(dev), msg,
+ &dev->dev.msi_cache[0]);
+ if (ret < 0) {
+ perror("assigned_dev_update_msi_vector: assign msi");
+ return ret;
}
dev->irq_requested_type = KVM_DEV_IRQ_HOST_MSI | KVM_DEV_IRQ_GUEST_MSI;
- } else {
- kvm_msi_cache_invalidate(&dev->dev.msi_cache[0]);
- assign_intx(dev);
}
+ return 0;
}
static int assigned_dev_set_msix_vectors(PCIDevice *pci_dev)
@@ -1085,12 +1083,6 @@ static void assigned_dev_pci_write_config(PCIDevice
*pci_dev, uint32_t address,
pci_default_write_config(pci_dev, address, val, len);
- if (assigned_dev->cap.available & ASSIGNED_DEVICE_CAP_MSI) {
- if (range_covers_byte(address, len,
- pci_dev->msi_cap + PCI_MSI_FLAGS)) {
- assigned_dev_update_msi(pci_dev);
- }
- }
if (assigned_dev->cap.available & ASSIGNED_DEVICE_CAP_MSIX) {
if (range_covers_byte(address, len,
pci_dev->msix_cap + PCI_MSIX_FLAGS + 1)) {
@@ -1136,26 +1128,19 @@ static int assigned_device_pci_cap_init(PCIDevice
*pci_dev)
* MSI capability is the 1st capability in capability config */
pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSI, 0);
if (pos != 0 && kvm_check_extension(kvm_state, KVM_CAP_ASSIGN_DEV_IRQ)) {
- dev->cap.available |= ASSIGNED_DEVICE_CAP_MSI;
- /* Only 32-bit/no-mask currently supported */
- if ((ret = pci_add_capability(pci_dev, PCI_CAP_ID_MSI, pos, 10)) < 0) {
+ uint16_t flags = pci_get_word(pci_dev->config + pos + PCI_MSI_FLAGS);
+
+ /* Note: KVM does not support multiple messages */
+ ret = msi_init(pci_dev, pos, 1, flags & PCI_MSI_FLAGS_64BIT,
+ flags & PCI_MSI_FLAGS_MASKBIT);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = msi_set_config_notifiers(pci_dev, assigned_dev_update_msi,
+ assigned_dev_update_msi_vector);
+ if (ret < 0) {
return ret;
}
- pci_dev->msi_cap = pos;
-
- pci_set_word(pci_dev->config + pos + PCI_MSI_FLAGS,
- pci_get_word(pci_dev->config + pos + PCI_MSI_FLAGS) &
- PCI_MSI_FLAGS_QMASK);
- pci_set_long(pci_dev->config + pos + PCI_MSI_ADDRESS_LO, 0);
- pci_set_word(pci_dev->config + pos + PCI_MSI_DATA_32, 0);
-
- /* Set writable fields */
- pci_set_word(pci_dev->wmask + pos + PCI_MSI_FLAGS,
- 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);
--
1.7.3.4
- Re: [Qemu-devel] [RFC][PATCH 23/45] qemu-kvm: Rework MSI-X mask notifier to generic MSI config notifiers, (continued)
- [Qemu-devel] [RFC][PATCH 41/45] msix: Drop unused msix_bar_size, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 33/45] qemu-kvm: Factor out kvm_device_intx_assign, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 05/45] msi: Invoke msi/msix_write_config from PCI core, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 27/45] qemu-kvm: Lazily update MSI caches, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 35/45] pci-assign: Polish assigned_dev_update_msix_mmio, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 40/45] qemu-kvm: msix: Drop check for preexisting cap from msix_add_config, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 18/45] qemu-kvm: Hook into MSI delivery at APIC level, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 32/45] pci-assign: Factor out deassign_irq, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 37/45] qemu-kvm: Clean up irqrouting API, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 39/45] pci-assign: Use generic MSI support,
Jan Kiszka <=
- [Qemu-devel] [RFC][PATCH 28/45] qemu-kvm: msix: Drop tracking of used vectors, Jan Kiszka, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 28/45] qemu-kvm: msix: Drop tracking of used vectors, Michael S. Tsirkin, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 28/45] qemu-kvm: msix: Drop tracking of used vectors, Jan Kiszka, 2011/10/18
- Re: [Qemu-devel] [RFC][PATCH 28/45] qemu-kvm: msix: Drop tracking of used vectors, Michael S. Tsirkin, 2011/10/18
- Re: [Qemu-devel] [RFC][PATCH 28/45] qemu-kvm: msix: Drop tracking of used vectors, Jan Kiszka, 2011/10/18
- Re: [Qemu-devel] [RFC][PATCH 28/45] qemu-kvm: msix: Drop tracking of used vectors, Michael S. Tsirkin, 2011/10/18
- Re: [Qemu-devel] [RFC][PATCH 28/45] qemu-kvm: msix: Drop tracking of used vectors, Jan Kiszka, 2011/10/18
- Re: [Qemu-devel] [RFC][PATCH 28/45] qemu-kvm: msix: Drop tracking of used vectors, Michael S. Tsirkin, 2011/10/18
- Re: [Qemu-devel] [RFC][PATCH 28/45] qemu-kvm: msix: Drop tracking of used vectors, Jan Kiszka, 2011/10/18
- Re: [Qemu-devel] [RFC][PATCH 28/45] qemu-kvm: msix: Drop tracking of used vectors, Michael S. Tsirkin, 2011/10/18