[PATCH] hw/pci/pcie.c: Fix invalid PCI_EXP_LNKCAP setting

Wenliang Wang posted 1 patch 1 year, 11 months ago
hw/pci/pcie.c | 5 +++++
1 file changed, 5 insertions(+)
[PATCH] hw/pci/pcie.c: Fix invalid PCI_EXP_LNKCAP setting
Posted by Wenliang Wang 1 year, 11 months ago
pcie_cap_fill_slot_lnk() wrongly set PCI_EXP_LNKCAP when slot speed
and width is not set, causing strange downstream port link cap
(Speed unknown, Width x0) and pcie devices native hotplug error on Linux:

[    3.545654] pcieport 0000:02:00.0: pciehp: link training error: status 0x2000
[    3.547143] pcieport 0000:02:00.0: pciehp: Failed to check link status

We do not touch PCI_EXP_LNKCAP when speed=0 or width=0, as pcie_cap_v1_fill()
already do the default setting for us.

Signed-off-by: Wenliang Wang <wangwenliang.1995@bytedance.com>
---
 hw/pci/pcie.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 68a62da..c82e7fc 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -92,6 +92,11 @@ static void pcie_cap_fill_slot_lnk(PCIDevice *dev)
         return;
     }
 
+    /* Use default LNKCAP setting */
+    if (s->speed == 0 || s->width == 0) {
+        return;
+    }
+
     /* Clear and fill LNKCAP from what was configured above */
     pci_long_test_and_clear_mask(exp_cap + PCI_EXP_LNKCAP,
                                  PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS);
-- 
2.7.4
Re: [PATCH] hw/pci/pcie.c: Fix invalid PCI_EXP_LNKCAP setting
Posted by Michael S. Tsirkin 1 year, 11 months ago
On Thu, May 19, 2022 at 10:45:59PM +0800, Wenliang Wang wrote:
> pcie_cap_fill_slot_lnk() wrongly set PCI_EXP_LNKCAP when slot speed
> and width is not set, causing strange downstream port link cap
> (Speed unknown, Width x0) and pcie devices native hotplug error on Linux:
> 
> [    3.545654] pcieport 0000:02:00.0: pciehp: link training error: status 0x2000
> [    3.547143] pcieport 0000:02:00.0: pciehp: Failed to check link status
> 
> We do not touch PCI_EXP_LNKCAP when speed=0 or width=0, as pcie_cap_v1_fill()
> already do the default setting for us.
> 
> Signed-off-by: Wenliang Wang <wangwenliang.1995@bytedance.com>


do we need machine type compat dance with this?
can you check whether this affects cross version
migration please?

> ---
>  hw/pci/pcie.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
> index 68a62da..c82e7fc 100644
> --- a/hw/pci/pcie.c
> +++ b/hw/pci/pcie.c
> @@ -92,6 +92,11 @@ static void pcie_cap_fill_slot_lnk(PCIDevice *dev)
>          return;
>      }
>  
> +    /* Use default LNKCAP setting */
> +    if (s->speed == 0 || s->width == 0) {
> +        return;
> +    }
> +
>      /* Clear and fill LNKCAP from what was configured above */
>      pci_long_test_and_clear_mask(exp_cap + PCI_EXP_LNKCAP,
>                                   PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS);
> -- 
> 2.7.4
Re: [External] Re: [PATCH] hw/pci/pcie.c: Fix invalid PCI_EXP_LNKCAP setting
Posted by Wenliang Wang 1 year, 11 months ago
As PCI_EXP_LNKCAP is never masked when loading, this patch does affect 
cross version migration. It seems we need machine type compat to deal 
with that. What do you suggest, Michael?

On 5/20/22 12:49 AM, Michael S. Tsirkin wrote:
> On Thu, May 19, 2022 at 10:45:59PM +0800, Wenliang Wang wrote:
>> pcie_cap_fill_slot_lnk() wrongly set PCI_EXP_LNKCAP when slot speed
>> and width is not set, causing strange downstream port link cap
>> (Speed unknown, Width x0) and pcie devices native hotplug error on Linux:
>>
>> [    3.545654] pcieport 0000:02:00.0: pciehp: link training error: status 0x2000
>> [    3.547143] pcieport 0000:02:00.0: pciehp: Failed to check link status
>>
>> We do not touch PCI_EXP_LNKCAP when speed=0 or width=0, as pcie_cap_v1_fill()
>> already do the default setting for us.
>>
>> Signed-off-by: Wenliang Wang <wangwenliang.1995@bytedance.com>
> 
> 
> do we need machine type compat dance with this?
> can you check whether this affects cross version
> migration please?
> 
>> ---
>>   hw/pci/pcie.c | 5 +++++
>>   1 file changed, 5 insertions(+)
>>
>> diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
>> index 68a62da..c82e7fc 100644
>> --- a/hw/pci/pcie.c
>> +++ b/hw/pci/pcie.c
>> @@ -92,6 +92,11 @@ static void pcie_cap_fill_slot_lnk(PCIDevice *dev)
>>           return;
>>       }
>>   
>> +    /* Use default LNKCAP setting */
>> +    if (s->speed == 0 || s->width == 0) {
>> +        return;
>> +    }
>> +
>>       /* Clear and fill LNKCAP from what was configured above */
>>       pci_long_test_and_clear_mask(exp_cap + PCI_EXP_LNKCAP,
>>                                    PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS);
>> -- 
>> 2.7.4
>