69 lines
2.3 KiB
Diff
69 lines
2.3 KiB
Diff
![]() |
# HG changeset patch
|
||
|
# User Keir Fraser <keir.fraser@citrix.com>
|
||
|
# Date 1281542462 -3600
|
||
|
# Node ID 786b163da49bbf18857b5484cce5e5aed33528b3
|
||
|
# Parent f45026ec8db5a18131acd924a5b99f3b0e480df1
|
||
|
msi: Avoid uninitialized msi descriptors
|
||
|
|
||
|
When __pci_enable_msix() returns early, output parameter (struct
|
||
|
msi_desc **desc) will not be initialized. On my machine, a Broadcom
|
||
|
BCM5709 nic has both MSI and MSIX capability blocks and when guest
|
||
|
tries to enable msix interrupts but __pci_enable_msix() returns early
|
||
|
for encountering a msi block, the whole system will crash for fatal
|
||
|
page fault immediately.
|
||
|
|
||
|
Signed-off-by: Wei Wang <wei.wang2@amd.com>
|
||
|
|
||
|
--- a/xen/arch/x86/msi.c
|
||
|
+++ b/xen/arch/x86/msi.c
|
||
|
@@ -605,21 +605,25 @@ static int msix_capability_init(struct p
|
||
|
* indicates the successful setup of an entry zero with the new MSI
|
||
|
* irq or non-zero for otherwise.
|
||
|
**/
|
||
|
+
|
||
|
static int __pci_enable_msi(struct msi_info *msi, struct msi_desc **desc)
|
||
|
{
|
||
|
int status;
|
||
|
struct pci_dev *pdev;
|
||
|
+ struct msi_desc *old_desc;
|
||
|
|
||
|
ASSERT(spin_is_locked(&pcidevs_lock));
|
||
|
pdev = pci_get_pdev(msi->bus, msi->devfn);
|
||
|
if ( !pdev )
|
||
|
return -ENODEV;
|
||
|
|
||
|
- if ( find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSI) )
|
||
|
+ old_desc = find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSI);
|
||
|
+ if ( old_desc )
|
||
|
{
|
||
|
dprintk(XENLOG_WARNING, "irq %d has already mapped to MSI on "
|
||
|
"device %02x:%02x.%01x.\n", msi->irq, msi->bus,
|
||
|
PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn));
|
||
|
+ *desc = old_desc;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -669,6 +673,7 @@ static int __pci_enable_msix(struct msi_
|
||
|
u16 control;
|
||
|
u8 slot = PCI_SLOT(msi->devfn);
|
||
|
u8 func = PCI_FUNC(msi->devfn);
|
||
|
+ struct msi_desc *old_desc;
|
||
|
|
||
|
ASSERT(spin_is_locked(&pcidevs_lock));
|
||
|
pdev = pci_get_pdev(msi->bus, msi->devfn);
|
||
|
@@ -681,11 +686,13 @@ static int __pci_enable_msix(struct msi_
|
||
|
if (msi->entry_nr >= nr_entries)
|
||
|
return -EINVAL;
|
||
|
|
||
|
- if ( find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSIX) )
|
||
|
+ old_desc = find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSIX);
|
||
|
+ if ( old_desc )
|
||
|
{
|
||
|
dprintk(XENLOG_WARNING, "irq %d has already mapped to MSIX on "
|
||
|
"device %02x:%02x.%01x.\n", msi->irq, msi->bus,
|
||
|
PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn));
|
||
|
+ *desc = old_desc;
|
||
|
return 0;
|
||
|
}
|
||
|
|