Recently a check for maximum supported MSIX vectors number has been
added. However the check always assumed that MSIX is the only case
and failed on devices which have MSI but do not have MSIX such as
QEMU's PCI Bridge. This results in assert in xics_alloc_block() as
req_num is zero.

This adds a check for MSI vectors number too.

Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru>
---

I posted recently a memory corruption fix, patch
"spapr_pci: Fix number of returned vectors in ibm, change-msi".

However it breaks QEMU's PCI bridge so here is a patch.

I would prepare a patch to replace the one in agrag/ppc-next ad01ba7
but it has Cc: qemu-sta...@nongnu.org in it so I am afraid it could make
it to some other tree already (did not it?).

Sorry for missing that. This is embarassing :(


---
 hw/ppc/spapr_pci.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 305f459..c052917 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -343,8 +343,20 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, 
sPAPREnvironment *spapr,
 
     /* There is no cached config, allocate MSIs */
     if (!phb->msi_table[ndev].nvec) {
-        if (req_num > pdev->msix_entries_nr) {
-            req_num = pdev->msix_entries_nr;
+        int max_irqs = 0;
+        if (ret_intr_type == RTAS_TYPE_MSI) {
+            max_irqs = msi_nr_vectors_allocated(pdev);
+        } else if (ret_intr_type == RTAS_TYPE_MSIX) {
+            max_irqs = pdev->msix_entries_nr;
+        }
+        if (!max_irqs) {
+            error_report("Requested interrupt type %d is not enabled for 
device#%d",
+                         ret_intr_type, ndev);
+            rtas_st(rets, 0, -1); /* Hardware error */
+            return;
+        }
+        if (req_num > max_irqs) {
+            req_num = max_irqs;
         }
         irq = spapr_allocate_irq_block(req_num, false,
                                        ret_intr_type == RTAS_TYPE_MSI);
-- 
1.8.4.rc4


Reply via email to