|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 4/4] x86/msi: clear initial MSI-X state on boot
Some firmware/devices are found to not reset MSI-X properly, leaving
MASKALL set. Jason reports on his machine MASKALL persists through a
warm reboot, but is cleared on cold boot. Xen relies on initial state
being MASKALL clear. Especially, pci_reset_msix_state() assumes if
MASKALL is set, it was Xen setting it due to msix->host_maskall or
msix->guest_maskall. Clearing just MASKALL might be unsafe if ENABLE is
set, so clear them both.
Reported-by: Jason Andryuk <jandryuk@xxxxxxxxx>
Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---
v3:
- update comment
- clear bits only when they were set
---
xen/drivers/passthrough/msi.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/xen/drivers/passthrough/msi.c b/xen/drivers/passthrough/msi.c
index ce1a450f6f4a..c9f7eac29ebf 100644
--- a/xen/drivers/passthrough/msi.c
+++ b/xen/drivers/passthrough/msi.c
@@ -46,6 +46,23 @@ int pdev_msi_init(struct pci_dev *pdev)
spin_lock_init(&msix->table_lock);
ctrl = pci_conf_read16(pdev->sbdf, msix_control_reg(pos));
+
+ if ( ctrl & (PCI_MSIX_FLAGS_MASKALL|PCI_MSIX_FLAGS_ENABLE) )
+ {
+ /*
+ * pci_reset_msix_state() relies on MASKALL not being set
+ * initially, clear it (and ENABLE too - for safety), to meet that
+ * expectation.
+ */
+ printk(XENLOG_WARNING
+ "%pp: unexpected initial MSI-X state (MASKALL=%d,
ENABLE=%d), fixing\n",
+ &pdev->sbdf,
+ (ctrl & PCI_MSIX_FLAGS_MASKALL) ? 1 : 0,
+ (ctrl & PCI_MSIX_FLAGS_ENABLE) ? 1 : 0);
+ ctrl &= ~(PCI_MSIX_FLAGS_ENABLE|PCI_MSIX_FLAGS_MASKALL);
+ pci_conf_write16(pdev->sbdf, msix_control_reg(pos), ctrl);
+ }
+
msix->nr_entries = msix_table_size(ctrl);
pdev->msix = msix;
--
git-series 0.9.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |