[Intel-wired-lan] [PATCH v2] PCI: Fix Intel i210 by avoiding overlapping of BARs

Michael Walle michael at walle.cc
Sun Jan 17 19:27:18 UTC 2021


Hi Bjorn,

Am 2021-01-16 00:57, schrieb Bjorn Helgaas:
> On Wed, Jan 13, 2021 at 12:32:32AM +0100, Michael Walle wrote:
>> Am 2021-01-12 23:58, schrieb Bjorn Helgaas:
>> > On Sat, Jan 09, 2021 at 07:31:46PM +0100, Michael Walle wrote:
>> > > Am 2021-01-08 22:20, schrieb Bjorn Helgaas:
> 
>> > > > 3) If the Intel i210 is defective in how it handles an Expansion ROM
>> > > > that overlaps another BAR, a quirk might be the right fix. But my
>> > > > guess is the device is working correctly per spec and there's
>> > > > something wrong in how firmware/Linux is assigning things.  That would
>> > > > mean we need a more generic fix that's not a quirk and not tied to the
>> > > > Intel i210.
>> > >
>> > > Agreed, but as you already stated (and I've also found that in
>> > > the PCI spec) the Expansion ROM address decoder can be shared by
>> > > the other BARs and it shouldn't matter as long as the ExpROM BAR
>> > > is disabled, which is the case here.
>> >
>> > My point is just that if this could theoretically affect devices
>> > other than the i210, the fix should not be an i210-specific quirk.
>> > I'll assume this is a general problem and wait for a generic PCI
>> > core solution unless it's i210-specific.
>> 
>> I guess the culprit here is that linux skips the programming of the
>> BAR because of some broken Matrox card. That should have been a
>> quirk instead, right? But I don't know if we want to change that, do
>> we? How many other cards depend on that?
> 
> Oh, right.  There's definitely some complicated history there that
> makes me a little scared to change things.  But it's also unfortunate
> if we have to pile quirks on top of quirks.
> 
>> And still, how do we find out that the i210 is behaving correctly?
>> In my opinion it is clearly not. You can change the ExpROM BAR value
>> during runtime and it will start working (while keeping it
>> disabled).  Am I missing something here?
> 
> I agree; if the ROM BAR is disabled, I don't think it should matter at
> all what it contains, so this does look like an i210 defect.
> 
> Would you mind trying the patch below?  It should update the ROM BAR
> value even when it is disabled.  With the current pci_enable_rom()
> code that doesn't rely on the value read from the BAR, I *think* this
> should be safe even on the Matrox and similar devices.

Your patch will fix my issue:

Tested-by: Michael Walle <michael at walle.cc>

> 
> commit 0ca2233eb71f ("PCI: Update ROM BAR even if disabled")
> Author: Bjorn Helgaas <bhelgaas at google.com>
> Date:   Fri Jan 15 17:17:44 2021 -0600
> 
>     PCI: Update ROM BAR even if disabled
> 
>     Test patch for i210 issue reported by Michael Walle:
>     https://lore.kernel.org/r/20201230185317.30915-1-michael@walle.cc
> 
> diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
> index 8fc9a4e911e3..fc638034628c 100644
> --- a/drivers/pci/rom.c
> +++ b/drivers/pci/rom.c
> @@ -35,9 +35,8 @@ int pci_enable_rom(struct pci_dev *pdev)
>  		return 0;
> 
>  	/*
> -	 * Ideally pci_update_resource() would update the ROM BAR address,
> -	 * and we would only set the enable bit here.  But apparently some
> -	 * devices have buggy ROM BARs that read as zero when disabled.
> +	 * Some ROM BARs read as zero when disabled, so we can't simply
> +	 * read the BAR, set the enable bit, and write it back.
>  	 */
>  	pcibios_resource_to_bus(pdev->bus, &region, res);
>  	pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
> diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
> index 7f1acb3918d0..f69b7d179617 100644
> --- a/drivers/pci/setup-res.c
> +++ b/drivers/pci/setup-res.c
> @@ -69,18 +69,10 @@ static void pci_std_update_resource(struct pci_dev
> *dev, int resno)
>  	if (resno < PCI_ROM_RESOURCE) {
>  		reg = PCI_BASE_ADDRESS_0 + 4 * resno;
>  	} else if (resno == PCI_ROM_RESOURCE) {
> -
> -		/*
> -		 * Apparently some Matrox devices have ROM BARs that read
> -		 * as zero when disabled, so don't update ROM BARs unless
> -		 * they're enabled.  See
> -		 * https://lore.kernel.org/r/43147B3D.1030309@vc.cvut.cz/
> -		 */
> -		if (!(res->flags & IORESOURCE_ROM_ENABLE))
> -			return;
> +		if (res->flags & IORESOURCE_ROM_ENABLE)
> +			new |= PCI_ROM_ADDRESS_ENABLE;
> 
>  		reg = dev->rom_base_reg;
> -		new |= PCI_ROM_ADDRESS_ENABLE;
>  	} else
>  		return;
> 
> @@ -99,7 +91,8 @@ static void pci_std_update_resource(struct pci_dev
> *dev, int resno)
>  	pci_write_config_dword(dev, reg, new);
>  	pci_read_config_dword(dev, reg, &check);
> 
> -	if ((new ^ check) & mask) {
> +	/* Some ROM BARs read as zero when disabled */
> +	if (resno != PCI_ROM_RESOURCE && (new ^ check) & mask) {
>  		pci_err(dev, "BAR %d: error updating (%#08x != %#08x)\n",
>  			resno, new, check);
>  	}

-- 
-michael


More information about the Intel-wired-lan mailing list