[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 4/6] pci/aer: fix error injection
From: |
Michael S. Tsirkin |
Subject: |
[Qemu-devel] [PATCH 4/6] pci/aer: fix error injection |
Date: |
Fri, 3 Dec 2010 00:54:40 +0200 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
Fix the injection logic upon aer message to follow 6.2.4.1.2 more
closely: specifically only send an msi interrupt when the logical or of
the enabled bits changed, not when a bit which was previously clear
becomes set.
Signed-off-by: Michael S. Tsirkin <address@hidden>
---
hw/pcie_aer.c | 45 ++++++++++++++++++++++++++++++++++-----------
1 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/hw/pcie_aer.c b/hw/pcie_aer.c
index 204155b..0fc191f 100644
--- a/hw/pcie_aer.c
+++ b/hw/pcie_aer.c
@@ -257,6 +257,22 @@ static unsigned int pcie_aer_root_get_vector(PCIDevice
*dev)
return (root_status & PCI_ERR_ROOT_IRQ) >> PCI_ERR_ROOT_IRQ_SHIFT;
}
+/* Given a status register, get corresponding bits in the command register */
+static uint32_t pcie_aer_status_to_cmd(uint32_t status)
+{
+ uint32_t cmd = 0;
+ if (status & PCI_ERR_ROOT_COR_RCV) {
+ cmd |= PCI_ERR_ROOT_CMD_COR_EN;
+ }
+ if (status & PCI_ERR_ROOT_NONFATAL_RCV) {
+ cmd |= PCI_ERR_ROOT_CMD_NONFATAL_EN;
+ }
+ if (status & PCI_ERR_ROOT_FATAL_RCV) {
+ cmd |= PCI_ERR_ROOT_CMD_FATAL_EN;
+ }
+ return cmd;
+}
+
/*
* 6.2.6 Error Message Control
* Figure 6-3
@@ -267,12 +283,12 @@ static void pcie_aer_msg_root_port(PCIDevice *dev, const
PCIEAERMsg *msg)
uint16_t cmd;
uint8_t *aer_cap;
uint32_t root_cmd;
- uint32_t root_status;
+ uint32_t root_status, prev_status;
cmd = pci_get_word(dev->config + PCI_COMMAND);
aer_cap = dev->config + dev->exp.aer_cap;
root_cmd = pci_get_long(aer_cap + PCI_ERR_ROOT_COMMAND);
- root_status = pci_get_long(aer_cap + PCI_ERR_ROOT_STATUS);
+ prev_status = root_status = pci_get_long(aer_cap + PCI_ERR_ROOT_STATUS);
if (cmd & PCI_COMMAND_SERR) {
/* System Error.
@@ -326,15 +342,22 @@ static void pcie_aer_msg_root_port(PCIDevice *dev, const
PCIEAERMsg *msg)
}
pci_set_long(aer_cap + PCI_ERR_ROOT_STATUS, root_status);
- if (root_cmd & msg->severity) {
- /* 6.2.4.1.2 Interrupt Generation */
- if (msix_enabled(dev)) {
- msix_notify(dev, pcie_aer_root_get_vector(dev));
- } else if (msi_enabled(dev)) {
- msi_notify(dev, pcie_aer_root_get_vector(dev));
- } else {
- qemu_set_irq(dev->irq[dev->exp.aer_intx], 1);
- }
+ /* 6.2.4.1.2 Interrupt Generation */
+ /* All the above did was set some bits in the status register.
+ * Specifically these that match message severity.
+ * The below code relies on this fact. */
+ if (!(root_cmd & msg->severity) ||
+ (pcie_aer_status_to_cmd(prev_status) & root_cmd)) {
+ /* Condition is not being set or was already true so nothing to do. */
+ return;
+ }
+
+ if (msix_enabled(dev)) {
+ msix_notify(dev, pcie_aer_root_get_vector(dev));
+ } else if (msi_enabled(dev)) {
+ msi_notify(dev, pcie_aer_root_get_vector(dev));
+ } else {
+ qemu_set_irq(dev->irq[dev->exp.aer_intx], 1);
}
}
--
1.7.3.2.91.g446ac
- [Qemu-devel] [PATCH 0/6] pcie aer fixes, Michael S. Tsirkin, 2010/12/02
- [Qemu-devel] [PATCH 1/6] pci: untangle pci/msi dependency, Michael S. Tsirkin, 2010/12/02
- [Qemu-devel] [PATCH 3/6] pci/aer: remove dead code, Michael S. Tsirkin, 2010/12/02
- [Qemu-devel] [PATCH 4/6] pci/aer: fix error injection,
Michael S. Tsirkin <=
- [Qemu-devel] [PATCH 5/6] pci/aer: fix interrupt on config write, Michael S. Tsirkin, 2010/12/02
- [Qemu-devel] [PATCH 6/6] pci/aer: factor out common code, Michael S. Tsirkin, 2010/12/02
- [Qemu-devel] [PATCH 2/6] Makefile: make msix/msi depend on CONFIG_PCI, Michael S. Tsirkin, 2010/12/02