mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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 is risky if ENABLE is set, so clear them both. Reported-by: Jason Andryuk <jandryuk@gmail.com> Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Tested-by: Jason Andryuk <jandryuk@gmail.com>
This commit is contained in:
1 parent
c6c8c0808f
commit
913751d7af
1 file changed
+17
@@ -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),
|
||||
!!(ctrl & PCI_MSIX_FLAGS_ENABLE));
|
||||
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;
|
||||
|
||||