[PATCH] hw/pci-host: PowerNV PCIe Device On Small PHB Seg Faults

Glenn Miles posted 1 patch 4 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20250716165017.2770845-1-milesg@linux.ibm.com
Maintainers: Nicholas Piggin <npiggin@gmail.com>, Aditya Gupta <adityag@linux.ibm.com>
hw/pci-host/pnv_phb4.c | 2 ++
1 file changed, 2 insertions(+)
[PATCH] hw/pci-host: PowerNV PCIe Device On Small PHB Seg Faults
Posted by Glenn Miles 4 months ago
The PowerNV PCI Host Bridge (PHB) supports a large and small
configuration where the small configuration supports only
half the number of interrupts supported by the large configuration.

Since the PCIe LSIs are allocated at the end of the PHB IRQ list,
when calculating the LSI IRQ number, the code must take into
consideration the number of IRQ's supported by the PHB.  This
was not happening and was resulting in a QEMU segmentation fault
when a PCI device was added to a PHB with the small configuration.

Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
---
 hw/pci-host/pnv_phb4.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 18992054e8..aeb2a45b4b 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -1167,6 +1167,7 @@ static int pnv_phb4_map_irq(PCIDevice *pci_dev, int irq_num)
 static void pnv_phb4_set_irq(void *opaque, int irq_num, int level)
 {
     PnvPHB4 *phb = PNV_PHB4(opaque);
+    XiveSource *xsrc = &phb->xsrc;
     uint32_t lsi_base;
 
     /* LSI only ... */
@@ -1175,6 +1176,7 @@ static void pnv_phb4_set_irq(void *opaque, int irq_num, int level)
     }
     lsi_base = GETFIELD(PHB_LSI_SRC_ID, phb->regs[PHB_LSI_SOURCE_ID >> 3]);
     lsi_base <<= 3;
+    lsi_base &= xsrc->nr_irqs - 1;
     qemu_set_irq(phb->qirqs[lsi_base + irq_num], level);
 }
 
-- 
2.43.5
Re: [PATCH] hw/pci-host: PowerNV PCIe Device On Small PHB Seg Faults
Posted by Aditya Gupta 3 months, 1 week ago
On 25/07/16 11:50AM, Glenn Miles wrote:
> The PowerNV PCI Host Bridge (PHB) supports a large and small
> configuration where the small configuration supports only
> half the number of interrupts supported by the large configuration.
> 
> Since the PCIe LSIs are allocated at the end of the PHB IRQ list,
> when calculating the LSI IRQ number, the code must take into
> consideration the number of IRQ's supported by the PHB.  This
> was not happening and was resulting in a QEMU segmentation fault
> when a PCI device was added to a PHB with the small configuration.
> 
> Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
> ---
>  hw/pci-host/pnv_phb4.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
> index 18992054e8..aeb2a45b4b 100644
> --- a/hw/pci-host/pnv_phb4.c
> +++ b/hw/pci-host/pnv_phb4.c
> @@ -1167,6 +1167,7 @@ static int pnv_phb4_map_irq(PCIDevice *pci_dev, int irq_num)
>  static void pnv_phb4_set_irq(void *opaque, int irq_num, int level)
>  {
>      PnvPHB4 *phb = PNV_PHB4(opaque);
> +    XiveSource *xsrc = &phb->xsrc;
>      uint32_t lsi_base;
>  
>      /* LSI only ... */
> @@ -1175,6 +1176,7 @@ static void pnv_phb4_set_irq(void *opaque, int irq_num, int level)
>      }
>      lsi_base = GETFIELD(PHB_LSI_SRC_ID, phb->regs[PHB_LSI_SOURCE_ID >> 3]);
>      lsi_base <<= 3;
> +    lsi_base &= xsrc->nr_irqs - 1;
>      qemu_set_irq(phb->qirqs[lsi_base + irq_num], level);
>  }

Looks good to me. And passes all powernv functional tests, hence:

Reviewed-by: Aditya Gupta <adityag@linux.ibm.com>

Thanks,
- Aditya G
Re: [PATCH] hw/pci-host: PowerNV PCIe Device On Small PHB Seg Faults
Posted by Miles Glenn 4 months ago
+qemu-ppc@nongnu.org

On Wed, 2025-07-16 at 11:50 -0500, Glenn Miles wrote:
> The PowerNV PCI Host Bridge (PHB) supports a large and small
> configuration where the small configuration supports only
> half the number of interrupts supported by the large configuration.
> 
> Since the PCIe LSIs are allocated at the end of the PHB IRQ list,
> when calculating the LSI IRQ number, the code must take into
> consideration the number of IRQ's supported by the PHB.  This
> was not happening and was resulting in a QEMU segmentation fault
> when a PCI device was added to a PHB with the small configuration.
> 
> Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
> ---
>  hw/pci-host/pnv_phb4.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
> index 18992054e8..aeb2a45b4b 100644
> --- a/hw/pci-host/pnv_phb4.c
> +++ b/hw/pci-host/pnv_phb4.c
> @@ -1167,6 +1167,7 @@ static int pnv_phb4_map_irq(PCIDevice *pci_dev, int irq_num)
>  static void pnv_phb4_set_irq(void *opaque, int irq_num, int level)
>  {
>      PnvPHB4 *phb = PNV_PHB4(opaque);
> +    XiveSource *xsrc = &phb->xsrc;
>      uint32_t lsi_base;
>  
>      /* LSI only ... */
> @@ -1175,6 +1176,7 @@ static void pnv_phb4_set_irq(void *opaque, int irq_num, int level)
>      }
>      lsi_base = GETFIELD(PHB_LSI_SRC_ID, phb->regs[PHB_LSI_SOURCE_ID >> 3]);
>      lsi_base <<= 3;
> +    lsi_base &= xsrc->nr_irqs - 1;
>      qemu_set_irq(phb->qirqs[lsi_base + irq_num], level);
>  }
>
Re: [PATCH] hw/pci-host: PowerNV PCIe Device On Small PHB Seg Faults
Posted by Miles Glenn 3 months, 1 week ago
+harsh

On Wed, 2025-07-16 at 12:24 -0500, Miles Glenn wrote:
> +qemu-ppc@nongnu.org
> 
> On Wed, 2025-07-16 at 11:50 -0500, Glenn Miles wrote:
> > The PowerNV PCI Host Bridge (PHB) supports a large and small
> > configuration where the small configuration supports only
> > half the number of interrupts supported by the large configuration.
> > 
> > Since the PCIe LSIs are allocated at the end of the PHB IRQ list,
> > when calculating the LSI IRQ number, the code must take into
> > consideration the number of IRQ's supported by the PHB.  This
> > was not happening and was resulting in a QEMU segmentation fault
> > when a PCI device was added to a PHB with the small configuration.
> > 
> > Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
> > ---
> >  hw/pci-host/pnv_phb4.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
> > index 18992054e8..aeb2a45b4b 100644
> > --- a/hw/pci-host/pnv_phb4.c
> > +++ b/hw/pci-host/pnv_phb4.c
> > @@ -1167,6 +1167,7 @@ static int pnv_phb4_map_irq(PCIDevice *pci_dev, int irq_num)
> >  static void pnv_phb4_set_irq(void *opaque, int irq_num, int level)
> >  {
> >      PnvPHB4 *phb = PNV_PHB4(opaque);
> > +    XiveSource *xsrc = &phb->xsrc;
> >      uint32_t lsi_base;
> >  
> >      /* LSI only ... */
> > @@ -1175,6 +1176,7 @@ static void pnv_phb4_set_irq(void *opaque, int irq_num, int level)
> >      }
> >      lsi_base = GETFIELD(PHB_LSI_SRC_ID, phb->regs[PHB_LSI_SOURCE_ID >> 3]);
> >      lsi_base <<= 3;
> > +    lsi_base &= xsrc->nr_irqs - 1;
> >      qemu_set_irq(phb->qirqs[lsi_base + irq_num], level);
> >  }
> >
Re: [PATCH] hw/pci-host: PowerNV PCIe Device On Small PHB Seg Faults
Posted by Harsh Prateek Bora 3 months, 1 week ago
+ adding folks working in this area to help with review.

On 8/7/25 02:31, Miles Glenn wrote:
> +harsh
> 
> On Wed, 2025-07-16 at 12:24 -0500, Miles Glenn wrote:
>> +qemu-ppc@nongnu.org
>>
>> On Wed, 2025-07-16 at 11:50 -0500, Glenn Miles wrote:
>>> The PowerNV PCI Host Bridge (PHB) supports a large and small
>>> configuration where the small configuration supports only
>>> half the number of interrupts supported by the large configuration.
>>>
>>> Since the PCIe LSIs are allocated at the end of the PHB IRQ list,
>>> when calculating the LSI IRQ number, the code must take into
>>> consideration the number of IRQ's supported by the PHB.  This
>>> was not happening and was resulting in a QEMU segmentation fault
>>> when a PCI device was added to a PHB with the small configuration.
>>>
>>> Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
>>> ---
>>>   hw/pci-host/pnv_phb4.c | 2 ++
>>>   1 file changed, 2 insertions(+)
>>>
>>> diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
>>> index 18992054e8..aeb2a45b4b 100644
>>> --- a/hw/pci-host/pnv_phb4.c
>>> +++ b/hw/pci-host/pnv_phb4.c
>>> @@ -1167,6 +1167,7 @@ static int pnv_phb4_map_irq(PCIDevice *pci_dev, int irq_num)
>>>   static void pnv_phb4_set_irq(void *opaque, int irq_num, int level)
>>>   {
>>>       PnvPHB4 *phb = PNV_PHB4(opaque);
>>> +    XiveSource *xsrc = &phb->xsrc;
>>>       uint32_t lsi_base;
>>>   
>>>       /* LSI only ... */
>>> @@ -1175,6 +1176,7 @@ static void pnv_phb4_set_irq(void *opaque, int irq_num, int level)
>>>       }
>>>       lsi_base = GETFIELD(PHB_LSI_SRC_ID, phb->regs[PHB_LSI_SOURCE_ID >> 3]);
>>>       lsi_base <<= 3;
>>> +    lsi_base &= xsrc->nr_irqs - 1;
>>>       qemu_set_irq(phb->qirqs[lsi_base + irq_num], level);
>>>   }
>>>   
>