diff mbox series

[03/15] PCI: mvebu: Check that PCI bridge specified in DT has function number zero

Message ID 20211125124605.25915-4-pali@kernel.org (mailing list archive)
State Accepted
Delegated to: Lorenzo Pieralisi
Headers show
Series pci: mvebu: Various fixes | expand

Commit Message

Pali Rohár Nov. 25, 2021, 12:45 p.m. UTC
Driver cannot handle PCI bridges at non-zero function address. So add
appropriate check. Currently all in-tree kernel DTS files set PCI bridge
function to zero.

Signed-off-by: Pali Rohár <pali@kernel.org>
Cc: stable@vger.kernel.org
---
 drivers/pci/controller/pci-mvebu.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Bjorn Helgaas Jan. 7, 2022, 6:15 p.m. UTC | #1
On Thu, Nov 25, 2021 at 01:45:53PM +0100, Pali Rohár wrote:
> Driver cannot handle PCI bridges at non-zero function address. So add
> appropriate check. Currently all in-tree kernel DTS files set PCI bridge
> function to zero.

Why can the driver not handle bridges at non-zero function addresses?
The PCI spec allows that, doesn't it?  Is this a hardware limitation?

> Signed-off-by: Pali Rohár <pali@kernel.org>
> Cc: stable@vger.kernel.org
> ---
>  drivers/pci/controller/pci-mvebu.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> index 6197f7e7c317..08274132cdfb 100644
> --- a/drivers/pci/controller/pci-mvebu.c
> +++ b/drivers/pci/controller/pci-mvebu.c
> @@ -864,6 +864,11 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
>  	port->devfn = of_pci_get_devfn(child);
>  	if (port->devfn < 0)
>  		goto skip;
> +	if (PCI_FUNC(port->devfn) != 0) {
> +		dev_err(dev, "%s: invalid function number, must be zero\n",
> +			port->name);
> +		goto skip;
> +	}
>  
>  	ret = mvebu_get_tgt_attr(dev->of_node, port->devfn, IORESOURCE_MEM,
>  				 &port->mem_target, &port->mem_attr);
> -- 
> 2.20.1
>
Pali Rohár Jan. 7, 2022, 6:18 p.m. UTC | #2
On Friday 07 January 2022 12:15:12 Bjorn Helgaas wrote:
> On Thu, Nov 25, 2021 at 01:45:53PM +0100, Pali Rohár wrote:
> > Driver cannot handle PCI bridges at non-zero function address. So add
> > appropriate check. Currently all in-tree kernel DTS files set PCI bridge
> > function to zero.
> 
> Why can the driver not handle bridges at non-zero function addresses?
> The PCI spec allows that, doesn't it?  Is this a hardware limitation?

It is software / kernel limitation.

Because this bridge is virtual, emulated by pci-bridge-emul.c driver and
this driver can emulate only single function PCI-to-PCI bridge device.

> > Signed-off-by: Pali Rohár <pali@kernel.org>
> > Cc: stable@vger.kernel.org
> > ---
> >  drivers/pci/controller/pci-mvebu.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > index 6197f7e7c317..08274132cdfb 100644
> > --- a/drivers/pci/controller/pci-mvebu.c
> > +++ b/drivers/pci/controller/pci-mvebu.c
> > @@ -864,6 +864,11 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
> >  	port->devfn = of_pci_get_devfn(child);
> >  	if (port->devfn < 0)
> >  		goto skip;
> > +	if (PCI_FUNC(port->devfn) != 0) {
> > +		dev_err(dev, "%s: invalid function number, must be zero\n",
> > +			port->name);
> > +		goto skip;
> > +	}
> >  
> >  	ret = mvebu_get_tgt_attr(dev->of_node, port->devfn, IORESOURCE_MEM,
> >  				 &port->mem_target, &port->mem_attr);
> > -- 
> > 2.20.1
> >
Bjorn Helgaas Jan. 7, 2022, 9:09 p.m. UTC | #3
On Fri, Jan 07, 2022 at 07:18:19PM +0100, Pali Rohár wrote:
> On Friday 07 January 2022 12:15:12 Bjorn Helgaas wrote:
> > On Thu, Nov 25, 2021 at 01:45:53PM +0100, Pali Rohár wrote:
> > > Driver cannot handle PCI bridges at non-zero function address. So add
> > > appropriate check. Currently all in-tree kernel DTS files set PCI bridge
> > > function to zero.
> > 
> > Why can the driver not handle bridges at non-zero function addresses?
> > The PCI spec allows that, doesn't it?  Is this a hardware limitation?
> 
> It is software / kernel limitation.
> 
> Because this bridge is virtual, emulated by pci-bridge-emul.c driver and
> this driver can emulate only single function PCI-to-PCI bridge device.

That's weird.  Why does pci-bridge-emul.c care about the function
number?  Or maybe you're saying that pci-mvebu.c isn't smart enough to
build an emulated bridge at a non-zero function?  Or, since this is
emulated, maybe there's just no *reason* to ever use a non-zero
function?

It would really be nice to have the commit log and maybe even a
comment allude to what's going on here .  Otherwise this check sort of
dangles without having an obvious reason for existence.

Does this issue also affect pci-aardvark.c (which looks like the only
other user of pci_bridge_emul_init())?

> > > Signed-off-by: Pali Rohár <pali@kernel.org>
> > > Cc: stable@vger.kernel.org
> > > ---
> > >  drivers/pci/controller/pci-mvebu.c | 5 +++++
> > >  1 file changed, 5 insertions(+)
> > > 
> > > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > > index 6197f7e7c317..08274132cdfb 100644
> > > --- a/drivers/pci/controller/pci-mvebu.c
> > > +++ b/drivers/pci/controller/pci-mvebu.c
> > > @@ -864,6 +864,11 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
> > >  	port->devfn = of_pci_get_devfn(child);
> > >  	if (port->devfn < 0)
> > >  		goto skip;
> > > +	if (PCI_FUNC(port->devfn) != 0) {
> > > +		dev_err(dev, "%s: invalid function number, must be zero\n",
> > > +			port->name);
> > > +		goto skip;
> > > +	}
> > >  
> > >  	ret = mvebu_get_tgt_attr(dev->of_node, port->devfn, IORESOURCE_MEM,
> > >  				 &port->mem_target, &port->mem_attr);
> > > -- 
> > > 2.20.1
> > >
Pali Rohár Jan. 7, 2022, 9:58 p.m. UTC | #4
On Friday 07 January 2022 15:09:02 Bjorn Helgaas wrote:
> On Fri, Jan 07, 2022 at 07:18:19PM +0100, Pali Rohár wrote:
> > On Friday 07 January 2022 12:15:12 Bjorn Helgaas wrote:
> > > On Thu, Nov 25, 2021 at 01:45:53PM +0100, Pali Rohár wrote:
> > > > Driver cannot handle PCI bridges at non-zero function address. So add
> > > > appropriate check. Currently all in-tree kernel DTS files set PCI bridge
> > > > function to zero.
> > > 
> > > Why can the driver not handle bridges at non-zero function addresses?
> > > The PCI spec allows that, doesn't it?  Is this a hardware limitation?
> > 
> > It is software / kernel limitation.
> > 
> > Because this bridge is virtual, emulated by pci-bridge-emul.c driver and
> > this driver can emulate only single function PCI-to-PCI bridge device.
> 
> That's weird.  Why does pci-bridge-emul.c care about the function
> number?

pci-bridge-emul.c emulates whole PCI config space and multifunction PCI
device needs to have Multi-Function Device bit set. Which
pci-bridge-emul.c does not do as it "emulates" only singe-function
device. Also some extended PCIe registers needs to be aligned for
multifunction device. And for simplification nothing from this is
implemented in that pci-bridge-emul.c driver. Basically single function
device is easily to emulate than multi function device. And for
simplicity of driver it is just better to do not implement more stuff
if it is not required.

> Or maybe you're saying that pci-mvebu.c isn't smart enough to
> build an emulated bridge at a non-zero function?  Or, since this is
> emulated, maybe there's just no *reason* to ever use a non-zero
> function?

These PCIe root ports are basically on different PCI domains, every root
port with its subtree has its own configuration, including own access
to config space of subdevices. And I do not think that there is a reason
to try putting root port (as emulated pci-to-pci bridge) on non-zero
function and putting separate root ports into "one" multifunction
device.

Technically it could be possible to implement it and also properly, as
it is just emulation of PCI device. But why? Just big complication
without any benefit. At least I do not see benefit.

> It would really be nice to have the commit log and maybe even a
> comment allude to what's going on here .  Otherwise this check sort of
> dangles without having an obvious reason for existence.
> 
> Does this issue also affect pci-aardvark.c (which looks like the only
> other user of pci_bridge_emul_init())?

Theoretically yes. But pci-aardvark is single-root-port hardware and
therefore it is single-function device. And emulated device is
registered by pci-aardvark driver, not by DT. Because it is
single-root-port HW there is no DT node for root port like for any other
single-root-port PCIe controllers. So practically no.

> > > > Signed-off-by: Pali Rohár <pali@kernel.org>
> > > > Cc: stable@vger.kernel.org
> > > > ---
> > > >  drivers/pci/controller/pci-mvebu.c | 5 +++++
> > > >  1 file changed, 5 insertions(+)
> > > > 
> > > > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > > > index 6197f7e7c317..08274132cdfb 100644
> > > > --- a/drivers/pci/controller/pci-mvebu.c
> > > > +++ b/drivers/pci/controller/pci-mvebu.c
> > > > @@ -864,6 +864,11 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
> > > >  	port->devfn = of_pci_get_devfn(child);
> > > >  	if (port->devfn < 0)
> > > >  		goto skip;
> > > > +	if (PCI_FUNC(port->devfn) != 0) {
> > > > +		dev_err(dev, "%s: invalid function number, must be zero\n",
> > > > +			port->name);
> > > > +		goto skip;
> > > > +	}
> > > >  
> > > >  	ret = mvebu_get_tgt_attr(dev->of_node, port->devfn, IORESOURCE_MEM,
> > > >  				 &port->mem_target, &port->mem_attr);
> > > > -- 
> > > > 2.20.1
> > > >
diff mbox series

Patch

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 6197f7e7c317..08274132cdfb 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -864,6 +864,11 @@  static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
 	port->devfn = of_pci_get_devfn(child);
 	if (port->devfn < 0)
 		goto skip;
+	if (PCI_FUNC(port->devfn) != 0) {
+		dev_err(dev, "%s: invalid function number, must be zero\n",
+			port->name);
+		goto skip;
+	}
 
 	ret = mvebu_get_tgt_attr(dev->of_node, port->devfn, IORESOURCE_MEM,
 				 &port->mem_target, &port->mem_attr);