[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC][PATCH 11/45] msi: Factor out delivery hook
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [RFC][PATCH 11/45] msi: Factor out delivery hook |
Date: |
Mon, 17 Oct 2011 11:27:45 +0200 |
So far we deliver MSI messages by writing them into the target MMIO
area. This reflects what happens on hardware, but imposes some
limitations on the emulation when introducing KVM in-kernel irqchip
models. For those we will need to track the message origin. Moreover,
different architecture or accelerators may want to overload the delivery
handler.
Therefore, this commit introduces a delivery hook that is called by the
MSI/MSI-X layer when devices send normal messages, but also on spurious
deliveries that ended up on the APIC MMIO handler. Our default delivery
handler for APIC-based PCs then dispatches between real MSIs and other
DMA requests that happened to take the MSI patch.
Signed-off-by: Jan Kiszka <address@hidden>
---
hw/apic.c | 19 ++++++++++++-------
hw/apic.h | 1 +
hw/msi.c | 10 +++++++++-
hw/msi.h | 2 ++
hw/msix.c | 2 +-
hw/pc.c | 11 +++++++++++
6 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/hw/apic.c b/hw/apic.c
index e43219f..c1d557d 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -19,6 +19,7 @@
#include "hw.h"
#include "apic.h"
#include "ioapic.h"
+#include "msi.h"
#include "qemu-timer.h"
#include "host-utils.h"
#include "sysbus.h"
@@ -803,13 +804,15 @@ static uint32_t apic_mem_readl(void *opaque,
target_phys_addr_t addr)
return val;
}
-static void apic_send_msi(target_phys_addr_t addr, uint32_t data)
+void apic_deliver_msi(MSIMessage *msg)
{
- uint8_t dest = (addr & MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT;
- uint8_t vector = (data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT;
- uint8_t dest_mode = (addr >> MSI_ADDR_DEST_MODE_SHIFT) & 0x1;
- uint8_t trigger_mode = (data >> MSI_DATA_TRIGGER_SHIFT) & 0x1;
- uint8_t delivery = (data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
+ uint8_t dest =
+ (msg->address & MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT;
+ uint8_t vector =
+ (msg->data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT;
+ uint8_t dest_mode = (msg->address >> MSI_ADDR_DEST_MODE_SHIFT) & 0x1;
+ uint8_t trigger_mode = (msg->data >> MSI_DATA_TRIGGER_SHIFT) & 0x1;
+ uint8_t delivery = (msg->data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
/* XXX: Ignore redirection hint. */
apic_deliver_irq(dest, dest_mode, delivery, vector, trigger_mode);
}
@@ -825,7 +828,9 @@ static void apic_mem_writel(void *opaque,
target_phys_addr_t addr, uint32_t val)
* APIC is connected directly to the CPU.
* Mapping them on the global bus happens to work because
* MSI registers are reserved in APIC MMIO and vice versa. */
- apic_send_msi(addr, val);
+ MSIMessage msg = { .address = addr, .data = val };
+
+ msi_deliver(&msg);
return;
}
diff --git a/hw/apic.h b/hw/apic.h
index c398c83..fa848fd 100644
--- a/hw/apic.h
+++ b/hw/apic.h
@@ -18,6 +18,7 @@ void cpu_set_apic_tpr(DeviceState *s, uint8_t val);
uint8_t cpu_get_apic_tpr(DeviceState *s);
void apic_init_reset(DeviceState *s);
void apic_sipi(DeviceState *s);
+void apic_deliver_msi(MSIMessage *msg);
/* pc.c */
int cpu_is_bsp(CPUState *env);
diff --git a/hw/msi.c b/hw/msi.c
index 3c7ebc3..9055155 100644
--- a/hw/msi.c
+++ b/hw/msi.c
@@ -40,6 +40,14 @@
/* Flag for interrupt controller to declare MSI/MSI-X support */
bool msi_supported;
+static void msi_unsupported(MSIMessage *msg)
+{
+ /* If we get here, the board failed to register a delivery handler. */
+ abort();
+}
+
+void (*msi_deliver)(MSIMessage *msg) = msi_unsupported;
+
/* If we get rid of cap allocator, we won't need this. */
static inline uint8_t msi_cap_sizeof(uint16_t flags)
{
@@ -381,7 +389,7 @@ void msi_notify(PCIDevice *dev, unsigned int vector)
"notify vector 0x%x"
" address: 0x%"PRIx64" data: 0x%"PRIx32"\n",
vector, msg.address, msg.data);
- stl_le_phys(msg.address, msg.data);
+ msi_deliver(&msg);
}
/* Normally called by pci_default_write_config(). */
diff --git a/hw/msi.h b/hw/msi.h
index 22e3932..f3152f3 100644
--- a/hw/msi.h
+++ b/hw/msi.h
@@ -46,4 +46,6 @@ static inline bool msi_present(const PCIDevice *dev)
return dev->cap_present & QEMU_PCI_CAP_MSI;
}
+extern void (*msi_deliver)(MSIMessage *msg);
+
#endif /* QEMU_MSI_H */
diff --git a/hw/msix.c b/hw/msix.c
index 50fa504..08cc526 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -478,7 +478,7 @@ void msix_notify(PCIDevice *dev, unsigned vector)
msix_message_from_vector(dev, vector, &msg);
- stl_le_phys(msg.address, msg.data);
+ msi_deliver(&msg);
}
void msix_reset(PCIDevice *dev)
diff --git a/hw/pc.c b/hw/pc.c
index 768a20c..7d29a4a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -24,6 +24,7 @@
#include "hw.h"
#include "pc.h"
#include "apic.h"
+#include "msi.h"
#include "fdc.h"
#include "ide.h"
#include "pci.h"
@@ -102,6 +103,15 @@ void isa_irq_handler(void *opaque, int n, int level)
qemu_set_irq(isa->ioapic[n], level);
};
+static void pc_msi_deliver(MSIMessage *msg)
+{
+ if ((msg->address & 0xfff00000) == MSI_ADDR_BASE) {
+ apic_deliver_msi(msg);
+ } else {
+ stl_phys(msg->address, msg->data);
+ }
+}
+
static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
{
}
@@ -889,6 +899,7 @@ static DeviceState *apic_init(void *env, uint8_t apic_id)
on the global memory bus. */
/* XXX: what if the base changes? */
sysbus_mmio_map(d, 0, MSI_ADDR_BASE);
+ msi_deliver = pc_msi_deliver;
apic_mapped = 1;
}
--
1.7.3.4
- [Qemu-devel] [RFC][PATCH 00/45] qemu-kvm: MSI layer rework for in-kernel irqchip support, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 07/45] msi: Generalize msix_supported to msi_supported, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 01/45] msi: Guard msi/msix_write_config with msi_present, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 15/45] qemu-kvm: Drop unused kvm_del_irq_route, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 10/45] msix: Factor out msix_message_from_vector, Jan Kiszka, 2011/10/17
- [Qemu-devel] [RFC][PATCH 11/45] msi: Factor out delivery hook,
Jan Kiszka <=
- Re: [Qemu-devel] [RFC][PATCH 11/45] msi: Factor out delivery hook, Avi Kivity, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 11/45] msi: Factor out delivery hook, Jan Kiszka, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 11/45] msi: Factor out delivery hook, Avi Kivity, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 11/45] msi: Factor out delivery hook, Jan Kiszka, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 11/45] msi: Factor out delivery hook, Avi Kivity, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 11/45] msi: Factor out delivery hook, Jan Kiszka, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 11/45] msi: Factor out delivery hook, Michael S. Tsirkin, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 11/45] msi: Factor out delivery hook, Avi Kivity, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 11/45] msi: Factor out delivery hook, Michael S. Tsirkin, 2011/10/17
- Re: [Qemu-devel] [RFC][PATCH 11/45] msi: Factor out delivery hook, Jan Kiszka, 2011/10/18