* [PATCH 1/2] PCI: dwc: allow to limit registers set length
@ 2018-11-19 9:41 Stefan Agner
2018-11-19 9:41 ` [PATCH 2/2] PCI: imx6: limit DBI register length Stefan Agner
0 siblings, 1 reply; 11+ messages in thread
From: Stefan Agner @ 2018-11-19 9:41 UTC (permalink / raw)
To: jingoohan1, gustavo.pimentel, l.stach, tpiepho
Cc: bhelgaas, linux-pci, linux-kernel, Stefan Agner
Add length to the struct dw_pcie and check that the accessors
dw_pcie_(rd|wr)_own_conf() do not read/write beyond that point.
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
drivers/pci/controller/dwc/pcie-designware-host.c | 4 ++++
drivers/pci/controller/dwc/pcie-designware.h | 1 +
2 files changed, 5 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 29a05759a294..b422538ee0bb 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -29,6 +29,8 @@ static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
return pp->ops->rd_own_conf(pp, where, size, val);
pci = to_dw_pcie_from_pp(pp);
+ if (pci->dbi_length && where + size > pci->dbi_length)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
return dw_pcie_read(pci->dbi_base + where, size, val);
}
@@ -41,6 +43,8 @@ static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
return pp->ops->wr_own_conf(pp, where, size, val);
pci = to_dw_pcie_from_pp(pp);
+ if (pci->dbi_length && where + size > pci->dbi_length)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
return dw_pcie_write(pci->dbi_base + where, size, val);
}
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 9f1a5e399b70..5be5f369abf2 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -215,6 +215,7 @@ struct dw_pcie {
struct device *dev;
void __iomem *dbi_base;
void __iomem *dbi_base2;
+ int dbi_length;
u32 num_viewport;
u8 iatu_unroll_enabled;
struct pcie_port pp;
--
2.19.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/2] PCI: imx6: limit DBI register length
2018-11-19 9:41 [PATCH 1/2] PCI: dwc: allow to limit registers set length Stefan Agner
@ 2018-11-19 9:41 ` Stefan Agner
2018-11-20 1:06 ` Trent Piepho
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Stefan Agner @ 2018-11-19 9:41 UTC (permalink / raw)
To: jingoohan1, gustavo.pimentel, l.stach, tpiepho
Cc: bhelgaas, linux-pci, linux-kernel, Stefan Agner
Define the length of the DBI registers. This makes sure that
the kernel does not access registers beyond that point, avoiding
the following abort on a i.MX 6Quad:
# cat /sys/devices/soc0/soc/1ffc000.pcie/pci0000\:00/0000\:00\:00.0/config
[ 100.021433] Unhandled fault: imprecise external abort (0x1406) at 0xb6ea7000
...
[ 100.056423] PC is at dw_pcie_read+0x50/0x84
[ 100.060790] LR is at dw_pcie_rd_own_conf+0x44/0x48
...
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
drivers/pci/controller/dwc/pci-imx6.c | 51 +++++++++++++++++++--------
1 file changed, 37 insertions(+), 14 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 4a9a673b4777..8c96af414dac 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -39,6 +39,11 @@ enum imx6_pcie_variants {
IMX7D,
};
+struct imx6_pcie_drvdata {
+ enum imx6_pcie_variants variant;
+ int dbi_length;
+};
+
struct imx6_pcie {
struct dw_pcie *pci;
int reset_gpio;
@@ -50,7 +55,6 @@ struct imx6_pcie {
struct regmap *iomuxc_gpr;
struct reset_control *pciephy_reset;
struct reset_control *apps_reset;
- enum imx6_pcie_variants variant;
u32 tx_deemph_gen1;
u32 tx_deemph_gen2_3p5db;
u32 tx_deemph_gen2_6db;
@@ -58,6 +62,7 @@ struct imx6_pcie {
u32 tx_swing_low;
int link_gen;
struct regulator *vpcie;
+ const struct imx6_pcie_drvdata *drvdata;
};
/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
@@ -285,7 +290,7 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
{
struct device *dev = imx6_pcie->pci->dev;
- switch (imx6_pcie->variant) {
+ switch (imx6_pcie->drvdata->variant) {
case IMX7D:
reset_control_assert(imx6_pcie->pciephy_reset);
reset_control_assert(imx6_pcie->apps_reset);
@@ -327,7 +332,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
struct device *dev = pci->dev;
int ret = 0;
- switch (imx6_pcie->variant) {
+ switch (imx6_pcie->drvdata->variant) {
case IMX6SX:
ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi);
if (ret) {
@@ -430,7 +435,7 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
!imx6_pcie->gpio_active_high);
}
- switch (imx6_pcie->variant) {
+ switch (imx6_pcie->drvdata->variant) {
case IMX7D:
reset_control_deassert(imx6_pcie->pciephy_reset);
imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie);
@@ -468,7 +473,7 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
{
- switch (imx6_pcie->variant) {
+ switch (imx6_pcie->drvdata->variant) {
case IMX7D:
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
@@ -560,7 +565,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp);
/* Start LTSSM. */
- if (imx6_pcie->variant == IMX7D)
+ if (imx6_pcie->drvdata->variant == IMX7D)
reset_control_deassert(imx6_pcie->apps_reset);
else
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
@@ -585,7 +590,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
tmp |= PORT_LOGIC_SPEED_CHANGE;
dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp);
- if (imx6_pcie->variant != IMX7D) {
+ if (imx6_pcie->drvdata->variant != IMX7D) {
/*
* On i.MX7, DIRECT_SPEED_CHANGE behaves differently
* from i.MX6 family when no link speed transition
@@ -703,8 +708,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
pci->ops = &dw_pcie_ops;
imx6_pcie->pci = pci;
- imx6_pcie->variant =
- (enum imx6_pcie_variants)of_device_get_match_data(dev);
+ imx6_pcie->drvdata = of_device_get_match_data(dev);
dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pci->dbi_base = devm_ioremap_resource(dev, dbi_base);
@@ -748,7 +752,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
return PTR_ERR(imx6_pcie->pcie);
}
- switch (imx6_pcie->variant) {
+ switch (imx6_pcie->drvdata->variant) {
case IMX6SX:
imx6_pcie->pcie_inbound_axi = devm_clk_get(dev,
"pcie_inbound_axi");
@@ -776,6 +780,8 @@ static int imx6_pcie_probe(struct platform_device *pdev)
break;
}
+ pci->dbi_length = imx6_pcie->drvdata->dbi_length;
+
/* Grab GPR config register range */
imx6_pcie->iomuxc_gpr =
syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
@@ -835,11 +841,28 @@ static void imx6_pcie_shutdown(struct platform_device *pdev)
imx6_pcie_assert_core_reset(imx6_pcie);
}
+static const struct imx6_pcie_drvdata imx6q_pcie_drvdata = {
+ .variant = IMX6Q,
+ .dbi_length = 0x15c,
+};
+
+static const struct imx6_pcie_drvdata imx6sx_pcie_drvdata = {
+ .variant = IMX6SX,
+};
+
+static const struct imx6_pcie_drvdata imx6qp_pcie_drvdata = {
+ .variant = IMX6QP,
+};
+
+static const struct imx6_pcie_drvdata imx7d_pcie_drvdata = {
+ .variant = IMX7D,
+};
+
static const struct of_device_id imx6_pcie_of_match[] = {
- { .compatible = "fsl,imx6q-pcie", .data = (void *)IMX6Q, },
- { .compatible = "fsl,imx6sx-pcie", .data = (void *)IMX6SX, },
- { .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, },
- { .compatible = "fsl,imx7d-pcie", .data = (void *)IMX7D, },
+ { .compatible = "fsl,imx6q-pcie", .data = &imx6q_pcie_drvdata, },
+ { .compatible = "fsl,imx6sx-pcie", .data = &imx6sx_pcie_drvdata, },
+ { .compatible = "fsl,imx6qp-pcie", .data = &imx6qp_pcie_drvdata, },
+ { .compatible = "fsl,imx7d-pcie", .data = &imx7d_pcie_drvdata, },
{},
};
--
2.19.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] PCI: imx6: limit DBI register length
2018-11-19 9:41 ` [PATCH 2/2] PCI: imx6: limit DBI register length Stefan Agner
@ 2018-11-20 1:06 ` Trent Piepho
2018-11-20 1:33 ` Trent Piepho
2018-11-20 10:22 ` Leonard Crestez
2 siblings, 0 replies; 11+ messages in thread
From: Trent Piepho @ 2018-11-20 1:06 UTC (permalink / raw)
To: stefan, jingoohan1, l.stach, gustavo.pimentel
Cc: linux-kernel, linux-pci, bhelgaas
On Mon, 2018-11-19 at 10:41 +0100, Stefan Agner wrote:
> Define the length of the DBI registers. This makes sure that
> the kernel does not access registers beyond that point, avoiding
> the following abort on a i.MX 6Quad:
> # cat
> /sys/devices/soc0/soc/1ffc000.pcie/pci0000\:00/0000\:00\:00.0/config
> [ 100.021433] Unhandled fault: imprecise external abort (0x1406)
> at 0xb6ea7000
> ...
> [ 100.056423] PC is at dw_pcie_read+0x50/0x84
> [ 100.060790] LR is at dw_pcie_rd_own_conf+0x44/0x48
> ...
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
After updating this for v4.20-rc2, tested on IMX 7d, config space
access works as before.
Tested-by: Trent Piepho <tpiepho@impinj.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] PCI: imx6: limit DBI register length
2018-11-19 9:41 ` [PATCH 2/2] PCI: imx6: limit DBI register length Stefan Agner
2018-11-20 1:06 ` Trent Piepho
@ 2018-11-20 1:33 ` Trent Piepho
2018-11-20 10:22 ` Leonard Crestez
2 siblings, 0 replies; 11+ messages in thread
From: Trent Piepho @ 2018-11-20 1:33 UTC (permalink / raw)
To: stefan, jingoohan1, l.stach, gustavo.pimentel
Cc: linux-kernel, linux-pci, bhelgaas
On Mon, 2018-11-19 at 10:41 +0100, Stefan Agner wrote:
>
>
> +static const struct imx6_pcie_drvdata imx6q_pcie_drvdata = {
> + .variant = IMX6Q,
> + .dbi_length = 0x15c,
> +};
> +
> +static const struct imx6_pcie_drvdata imx6sx_pcie_drvdata = {
> + .variant = IMX6SX,
> +};
> +
> +static const struct imx6_pcie_drvdata imx6qp_pcie_drvdata = {
> + .variant = IMX6QP,
> +};
> +
> +static const struct imx6_pcie_drvdata imx7d_pcie_drvdata = {
> + .variant = IMX7D,
> +};
> +
> static const struct of_device_id imx6_pcie_of_match[] = {
> - { .compatible = "fsl,imx6q-pcie", .data = (void *)IMX6Q, },
> - { .compatible = "fsl,imx6sx-pcie", .data = (void *)IMX6SX, },
> - { .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, },
> - { .compatible = "fsl,imx7d-pcie", .data = (void *)IMX7D, },
> + { .compatible = "fsl,imx6q-pcie", .data = &imx6q_pcie_drvdata, },
> + { .compatible = "fsl,imx6sx-pcie", .data = &imx6sx_pcie_drvdata, },
> + { .compatible = "fsl,imx6qp-pcie", .data = &imx6qp_pcie_drvdata, },
> + { .compatible = "fsl,imx7d-pcie", .data = &imx7d_pcie_drvdata, },
> {},
> };
Instead of making a single drvdata struct for each type, this could use
an array:
static const struct imx6_pcie_drvdata drvdata[] = {
[IMX6Q] = { .variant = IMX6Q, .dbi_length = 0x15c },
[IMX6SX] = { .variant = IMX6SX },
[...]
};
static const struct of_device_id imx6_pcie_of_match[] = {
{ .compatible = "fsl,imx6q-pcie", .data = &drvdata[IMX6Q], },
{ .compatible = "fsl,imx6sx-pcie", .data = &drvdata[IMX6SX], },
...
};
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] PCI: imx6: limit DBI register length
2018-11-19 9:41 ` [PATCH 2/2] PCI: imx6: limit DBI register length Stefan Agner
2018-11-20 1:06 ` Trent Piepho
2018-11-20 1:33 ` Trent Piepho
@ 2018-11-20 10:22 ` Leonard Crestez
2018-11-20 10:30 ` Stefan Agner
2 siblings, 1 reply; 11+ messages in thread
From: Leonard Crestez @ 2018-11-20 10:22 UTC (permalink / raw)
To: stefan
Cc: Richard Zhu, linux-kernel, jingoohan1, gustavo.pimentel, tpiepho,
andrew.smirnov, linux-pci, l.stach, bhelgaas
On Mon, 2018-11-19 at 10:41 +0100, Stefan Agner wrote:
> Define the length of the DBI registers. This makes sure that
> the kernel does not access registers beyond that point, avoiding
> the following abort on a i.MX 6Quad:
> # cat /sys/devices/soc0/soc/1ffc000.pcie/pci0000\:00/0000\:00\:00.0/config
> [ 100.021433] Unhandled fault: imprecise external abort (0x1406) at 0xb6ea7000
> ...
> [ 100.056423] PC is at dw_pcie_read+0x50/0x84
> [ 100.060790] LR is at dw_pcie_rd_own_conf+0x44/0x48
> ...
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
>
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c
> +struct imx6_pcie_drvdata {
> + enum imx6_pcie_variants variant;
> + int dbi_length;
> +};
Turning imx6_pcie drvdata into a struct is very nice, maybe in the
future some of the long case statements in this driver could be split
into per-soc functions called via drvdata.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] PCI: imx6: limit DBI register length
2018-11-20 10:22 ` Leonard Crestez
@ 2018-11-20 10:30 ` Stefan Agner
2018-11-20 13:03 ` Leonard Crestez
0 siblings, 1 reply; 11+ messages in thread
From: Stefan Agner @ 2018-11-20 10:30 UTC (permalink / raw)
To: Leonard Crestez
Cc: Richard Zhu, linux-kernel, jingoohan1, gustavo.pimentel, tpiepho,
andrew.smirnov, linux-pci, l.stach, bhelgaas
On 20.11.2018 11:22, Leonard Crestez wrote:
> On Mon, 2018-11-19 at 10:41 +0100, Stefan Agner wrote:
>> Define the length of the DBI registers. This makes sure that
>> the kernel does not access registers beyond that point, avoiding
>> the following abort on a i.MX 6Quad:
>> # cat /sys/devices/soc0/soc/1ffc000.pcie/pci0000\:00/0000\:00\:00.0/config
>> [ 100.021433] Unhandled fault: imprecise external abort (0x1406) at 0xb6ea7000
>> ...
>> [ 100.056423] PC is at dw_pcie_read+0x50/0x84
>> [ 100.060790] LR is at dw_pcie_rd_own_conf+0x44/0x48
>> ...
>>
>> Signed-off-by: Stefan Agner <stefan@agner.ch>
>>
>> diff --git a/drivers/pci/controller/dwc/pci-imx6.c
>
>> +struct imx6_pcie_drvdata {
>> + enum imx6_pcie_variants variant;
>> + int dbi_length;
>> +};
>
> Turning imx6_pcie drvdata into a struct is very nice, maybe in the
> future some of the long case statements in this driver could be split
> into per-soc functions called via drvdata.
Yeah I thought that too. At a quick glance I did not saw an obvious
contender. Should certainly help for similar cases in the future.
--
Stefan
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH 2/2] PCI: imx6: limit DBI register length
2018-11-20 10:30 ` Stefan Agner
@ 2018-11-20 13:03 ` Leonard Crestez
2018-11-20 13:12 ` Stefan Agner
0 siblings, 1 reply; 11+ messages in thread
From: Leonard Crestez @ 2018-11-20 13:03 UTC (permalink / raw)
To: Stefan Agner, Richard Zhu
Cc: linux-kernel, jingoohan1, gustavo.pimentel, tpiepho,
andrew.smirnov, linux-pci, l.stach, bhelgaas
From: Stefan Agner <stefan@agner.ch>
> On 20.11.2018 11:22, Leonard Crestez wrote:
> > On Mon, 2018-11-19 at 10:41 +0100, Stefan Agner wrote:
> >> Define the length of the DBI registers. This makes sure that
> >> the kernel does not access registers beyond that point, avoiding
> >> the following abort on a i.MX 6Quad:
> >> # cat
> /sys/devices/soc0/soc/1ffc000.pcie/pci0000\:00/0000\:00\:00.0/config
> >> [ 100.021433] Unhandled fault: imprecise external abort (0x1406) at
> 0xb6ea7000
> >> ...
> >> [ 100.056423] PC is at dw_pcie_read+0x50/0x84
> >> [ 100.060790] LR is at dw_pcie_rd_own_conf+0x44/0x48
> >> ...
> >>
> >> Signed-off-by: Stefan Agner <stefan@agner.ch>
> >>
> >> diff --git a/drivers/pci/controller/dwc/pci-imx6.c
> >
> >> +struct imx6_pcie_drvdata {
> >> + enum imx6_pcie_variants variant;
> >> + int dbi_length;
> >> +};
> >
> > Turning imx6_pcie drvdata into a struct is very nice, maybe in the
> > future some of the long case statements in this driver could be split
> > into per-soc functions called via drvdata.
>
> Yeah I thought that too. At a quick glance I did not saw an obvious
> contender. Should certainly help for similar cases in the future.
Yes, there are other cases in which it would be useful.
But I think it makes more sense to split introducing drvdata to a separate patch.
It's nice to separate functional and code cleanup changes.
For example maybe dbi_length causes issues and has to be reverted?
--
Regards,
Leonard
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] PCI: imx6: limit DBI register length
2018-11-20 13:03 ` Leonard Crestez
@ 2018-11-20 13:12 ` Stefan Agner
0 siblings, 0 replies; 11+ messages in thread
From: Stefan Agner @ 2018-11-20 13:12 UTC (permalink / raw)
To: Leonard Crestez
Cc: Richard Zhu, linux-kernel, jingoohan1, gustavo.pimentel, tpiepho,
andrew.smirnov, linux-pci, l.stach, bhelgaas
On 20.11.2018 14:03, Leonard Crestez wrote:
> From: Stefan Agner <stefan@agner.ch>
>> On 20.11.2018 11:22, Leonard Crestez wrote:
>> > On Mon, 2018-11-19 at 10:41 +0100, Stefan Agner wrote:
>> >> Define the length of the DBI registers. This makes sure that
>> >> the kernel does not access registers beyond that point, avoiding
>> >> the following abort on a i.MX 6Quad:
>> >> # cat
>> /sys/devices/soc0/soc/1ffc000.pcie/pci0000\:00/0000\:00\:00.0/config
>> >> [ 100.021433] Unhandled fault: imprecise external abort (0x1406) at
>> 0xb6ea7000
>> >> ...
>> >> [ 100.056423] PC is at dw_pcie_read+0x50/0x84
>> >> [ 100.060790] LR is at dw_pcie_rd_own_conf+0x44/0x48
>> >> ...
>> >>
>> >> Signed-off-by: Stefan Agner <stefan@agner.ch>
>> >>
>> >> diff --git a/drivers/pci/controller/dwc/pci-imx6.c
>> >
>> >> +struct imx6_pcie_drvdata {
>> >> + enum imx6_pcie_variants variant;
>> >> + int dbi_length;
>> >> +};
>> >
>> > Turning imx6_pcie drvdata into a struct is very nice, maybe in the
>> > future some of the long case statements in this driver could be split
>> > into per-soc functions called via drvdata.
>>
>> Yeah I thought that too. At a quick glance I did not saw an obvious
>> contender. Should certainly help for similar cases in the future.
>
> Yes, there are other cases in which it would be useful.
>
> But I think it makes more sense to split introducing drvdata to a
> separate patch.
> It's nice to separate functional and code cleanup changes.
>
> For example maybe dbi_length causes issues and has to be reverted?
Ok, makes sense, will split drvdata introduction in its own patch.
--
Stefan
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] PCI: dwc: allow to limit registers set length
2019-02-06 9:57 [PATCH 1/2] PCI: dwc: allow to limit registers set length Stefan Agner
2019-02-06 18:02 ` Lorenzo Pieralisi
@ 2019-02-08 11:10 ` Lorenzo Pieralisi
1 sibling, 0 replies; 11+ messages in thread
From: Lorenzo Pieralisi @ 2019-02-08 11:10 UTC (permalink / raw)
To: Stefan Agner
Cc: jingoohan1, gustavo.pimentel, l.stach, tpiepho, leonard.crestez,
bhelgaas, linux-pci, linux-kernel
On Wed, Feb 06, 2019 at 10:57:31AM +0100, Stefan Agner wrote:
> Add length to the struct dw_pcie and check that the accessors
> dw_pcie_(rd|wr)_conf() do not read/write beyond that point.
>
> Suggested-by: Trent Piepho <tpiepho@impinj.com>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
> Changes in v4:
> - Move length check to dw_pcie_rd_conf
> Changes in v5:
> - Rebased ontop of pci/dwc
>
> .../pci/controller/dwc/pcie-designware-host.c | 16 ++++++++++++++--
> drivers/pci/controller/dwc/pcie-designware.h | 1 +
> 2 files changed, 15 insertions(+), 2 deletions(-)
Applied to pci/dwc for v5.1, thanks.
Lorenzo
PS: Remember adding a version number to the patches next time please,
thanks.
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 45ff5e4f8af6..bad54204fb52 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -612,14 +612,20 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
> int size, u32 *val)
> {
> struct pcie_port *pp = bus->sysdata;
> + struct dw_pcie *pci;
>
> if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn))) {
> *val = 0xffffffff;
> return PCIBIOS_DEVICE_NOT_FOUND;
> }
>
> - if (bus->number == pp->root_bus_nr)
> + if (bus->number == pp->root_bus_nr) {
> + pci = to_dw_pcie_from_pp(pp);
> + if (pci->dbi_length && where + size > pci->dbi_length)
> + return PCIBIOS_BAD_REGISTER_NUMBER;
> +
> return dw_pcie_rd_own_conf(pp, where, size, val);
> + }
>
> return dw_pcie_rd_other_conf(pp, bus, devfn, where, size, val);
> }
> @@ -628,12 +634,18 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
> int where, int size, u32 val)
> {
> struct pcie_port *pp = bus->sysdata;
> + struct dw_pcie *pci;
>
> if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn)))
> return PCIBIOS_DEVICE_NOT_FOUND;
>
> - if (bus->number == pp->root_bus_nr)
> + if (bus->number == pp->root_bus_nr) {
> + pci = to_dw_pcie_from_pp(pp);
> + if (pci->dbi_length && where + size > pci->dbi_length)
> + return PCIBIOS_BAD_REGISTER_NUMBER;
> +
> return dw_pcie_wr_own_conf(pp, where, size, val);
> + }
>
> return dw_pcie_wr_other_conf(pp, bus, devfn, where, size, val);
> }
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index 279000255ad1..d1d95119a422 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -226,6 +226,7 @@ struct dw_pcie_ops {
> struct dw_pcie {
> struct device *dev;
> void __iomem *dbi_base;
> + int dbi_length;
> void __iomem *dbi_base2;
> /* Used when iatu_unroll_enabled is true */
> void __iomem *atu_base;
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] PCI: dwc: allow to limit registers set length
2019-02-06 9:57 [PATCH 1/2] PCI: dwc: allow to limit registers set length Stefan Agner
@ 2019-02-06 18:02 ` Lorenzo Pieralisi
2019-02-08 11:10 ` Lorenzo Pieralisi
1 sibling, 0 replies; 11+ messages in thread
From: Lorenzo Pieralisi @ 2019-02-06 18:02 UTC (permalink / raw)
To: Stefan Agner, gustavo.pimentel
Cc: jingoohan1, l.stach, tpiepho, leonard.crestez, bhelgaas,
linux-pci, linux-kernel
On Wed, Feb 06, 2019 at 10:57:31AM +0100, Stefan Agner wrote:
> Add length to the struct dw_pcie and check that the accessors
> dw_pcie_(rd|wr)_conf() do not read/write beyond that point.
>
> Suggested-by: Trent Piepho <tpiepho@impinj.com>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
> Changes in v4:
> - Move length check to dw_pcie_rd_conf
> Changes in v5:
> - Rebased ontop of pci/dwc
>
> .../pci/controller/dwc/pcie-designware-host.c | 16 ++++++++++++++--
> drivers/pci/controller/dwc/pcie-designware.h | 1 +
> 2 files changed, 15 insertions(+), 2 deletions(-)
Hi Gustavo,
I need your ACK on this patch to proceed, thanks.
Lorenzo
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 45ff5e4f8af6..bad54204fb52 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -612,14 +612,20 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
> int size, u32 *val)
> {
> struct pcie_port *pp = bus->sysdata;
> + struct dw_pcie *pci;
>
> if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn))) {
> *val = 0xffffffff;
> return PCIBIOS_DEVICE_NOT_FOUND;
> }
>
> - if (bus->number == pp->root_bus_nr)
> + if (bus->number == pp->root_bus_nr) {
> + pci = to_dw_pcie_from_pp(pp);
> + if (pci->dbi_length && where + size > pci->dbi_length)
> + return PCIBIOS_BAD_REGISTER_NUMBER;
> +
> return dw_pcie_rd_own_conf(pp, where, size, val);
> + }
>
> return dw_pcie_rd_other_conf(pp, bus, devfn, where, size, val);
> }
> @@ -628,12 +634,18 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
> int where, int size, u32 val)
> {
> struct pcie_port *pp = bus->sysdata;
> + struct dw_pcie *pci;
>
> if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn)))
> return PCIBIOS_DEVICE_NOT_FOUND;
>
> - if (bus->number == pp->root_bus_nr)
> + if (bus->number == pp->root_bus_nr) {
> + pci = to_dw_pcie_from_pp(pp);
> + if (pci->dbi_length && where + size > pci->dbi_length)
> + return PCIBIOS_BAD_REGISTER_NUMBER;
> +
> return dw_pcie_wr_own_conf(pp, where, size, val);
> + }
>
> return dw_pcie_wr_other_conf(pp, bus, devfn, where, size, val);
> }
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index 279000255ad1..d1d95119a422 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -226,6 +226,7 @@ struct dw_pcie_ops {
> struct dw_pcie {
> struct device *dev;
> void __iomem *dbi_base;
> + int dbi_length;
> void __iomem *dbi_base2;
> /* Used when iatu_unroll_enabled is true */
> void __iomem *atu_base;
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/2] PCI: dwc: allow to limit registers set length
@ 2019-02-06 9:57 Stefan Agner
2019-02-06 18:02 ` Lorenzo Pieralisi
2019-02-08 11:10 ` Lorenzo Pieralisi
0 siblings, 2 replies; 11+ messages in thread
From: Stefan Agner @ 2019-02-06 9:57 UTC (permalink / raw)
To: lorenzo.pieralisi, jingoohan1, gustavo.pimentel, l.stach, tpiepho
Cc: leonard.crestez, bhelgaas, linux-pci, linux-kernel, stefan
Add length to the struct dw_pcie and check that the accessors
dw_pcie_(rd|wr)_conf() do not read/write beyond that point.
Suggested-by: Trent Piepho <tpiepho@impinj.com>
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
Changes in v4:
- Move length check to dw_pcie_rd_conf
Changes in v5:
- Rebased ontop of pci/dwc
.../pci/controller/dwc/pcie-designware-host.c | 16 ++++++++++++++--
drivers/pci/controller/dwc/pcie-designware.h | 1 +
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 45ff5e4f8af6..bad54204fb52 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -612,14 +612,20 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
int size, u32 *val)
{
struct pcie_port *pp = bus->sysdata;
+ struct dw_pcie *pci;
if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn))) {
*val = 0xffffffff;
return PCIBIOS_DEVICE_NOT_FOUND;
}
- if (bus->number == pp->root_bus_nr)
+ if (bus->number == pp->root_bus_nr) {
+ pci = to_dw_pcie_from_pp(pp);
+ if (pci->dbi_length && where + size > pci->dbi_length)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
return dw_pcie_rd_own_conf(pp, where, size, val);
+ }
return dw_pcie_rd_other_conf(pp, bus, devfn, where, size, val);
}
@@ -628,12 +634,18 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
int where, int size, u32 val)
{
struct pcie_port *pp = bus->sysdata;
+ struct dw_pcie *pci;
if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn)))
return PCIBIOS_DEVICE_NOT_FOUND;
- if (bus->number == pp->root_bus_nr)
+ if (bus->number == pp->root_bus_nr) {
+ pci = to_dw_pcie_from_pp(pp);
+ if (pci->dbi_length && where + size > pci->dbi_length)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
return dw_pcie_wr_own_conf(pp, where, size, val);
+ }
return dw_pcie_wr_other_conf(pp, bus, devfn, where, size, val);
}
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 279000255ad1..d1d95119a422 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -226,6 +226,7 @@ struct dw_pcie_ops {
struct dw_pcie {
struct device *dev;
void __iomem *dbi_base;
+ int dbi_length;
void __iomem *dbi_base2;
/* Used when iatu_unroll_enabled is true */
void __iomem *atu_base;
--
2.20.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2019-02-08 11:11 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-19 9:41 [PATCH 1/2] PCI: dwc: allow to limit registers set length Stefan Agner
2018-11-19 9:41 ` [PATCH 2/2] PCI: imx6: limit DBI register length Stefan Agner
2018-11-20 1:06 ` Trent Piepho
2018-11-20 1:33 ` Trent Piepho
2018-11-20 10:22 ` Leonard Crestez
2018-11-20 10:30 ` Stefan Agner
2018-11-20 13:03 ` Leonard Crestez
2018-11-20 13:12 ` Stefan Agner
2019-02-06 9:57 [PATCH 1/2] PCI: dwc: allow to limit registers set length Stefan Agner
2019-02-06 18:02 ` Lorenzo Pieralisi
2019-02-08 11:10 ` Lorenzo Pieralisi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).