2017-08-28 15:25:41

by Jan Lübbe

[permalink] [raw]
Subject: [PATCH 0/2] fix 4GB DRAM window support on mvebu

The current MBUS DRAM window calculation fails for 4GB windows because it
overflows. This is fixed in the first patch by using u64 instead of u32 to
store the size. The second excplicitly checks that we don't try to configure a
too large memory window in the pci driver.

As they don't depend on each other, they could also go in separatly.

Jan Luebbe (2):
bus: mbus: fix window size calculation for 4GB windows
PCI: mvebu: Check DRAM window size

drivers/bus/mvebu-mbus.c | 2 +-
drivers/pci/host/pci-mvebu.c | 27 ++++++++++++++++++++++-----
include/linux/mbus.h | 4 ++--
3 files changed, 25 insertions(+), 8 deletions(-)

--
2.11.0


2017-08-28 15:25:39

by Jan Lübbe

[permalink] [raw]
Subject: [PATCH 1/2] bus: mbus: fix window size calculation for 4GB windows

At least the Armada XP SoC supports 4GB on a single DRAM window. Because
the size register values contain the actual size - 1, the MSB is set in
that case. For example, the SDRAM window's control register's value is
0xffffffe1 for 4GB (bits 31 to 24 contain the size).

The MBUS driver reads back each window's size from registers and
calculates the actual size as (control_reg | ~DDR_SIZE_MASK) + 1, which
overflows for 32 bit values, resulting in other miscalculations further
on (a bad RAM window for the CESA crypto engine calculated by
mvebu_mbus_setup_cpu_target_nooverlap() in my case).

This patch changes the type in 'struct mbus_dram_window' from u32 to
u64, which allows us to keep using the same register calculation code in
most MBUS-using drivers (which calculate ->size - 1 again).

Signed-off-by: Jan Luebbe <[email protected]>
---
drivers/bus/mvebu-mbus.c | 2 +-
include/linux/mbus.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c
index c7f396903184..70db4d5638a6 100644
--- a/drivers/bus/mvebu-mbus.c
+++ b/drivers/bus/mvebu-mbus.c
@@ -720,7 +720,7 @@ mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
if (mbus->hw_io_coherency)
w->mbus_attr |= ATTR_HW_COHERENCY;
w->base = base & DDR_BASE_CS_LOW_MASK;
- w->size = (size | ~DDR_SIZE_MASK) + 1;
+ w->size = (u64)(size | ~DDR_SIZE_MASK) + 1;
}
}
mvebu_mbus_dram_info.num_cs = cs;
diff --git a/include/linux/mbus.h b/include/linux/mbus.h
index 0d3f14fd2621..4773145246ed 100644
--- a/include/linux/mbus.h
+++ b/include/linux/mbus.h
@@ -31,8 +31,8 @@ struct mbus_dram_target_info
struct mbus_dram_window {
u8 cs_index;
u8 mbus_attr;
- u32 base;
- u32 size;
+ u64 base;
+ u64 size;
} cs[4];
};

--
2.11.0

2017-08-28 15:25:38

by Jan Lübbe

[permalink] [raw]
Subject: [PATCH 2/2] PCI: mvebu: Check DRAM window size

The sum of the DRAM windows may exceed 4GB (at least on Armada XP).
Return an error in that case.

Signed-off-by: Jan Luebbe <[email protected]>
---
drivers/pci/host/pci-mvebu.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index f353a6eb2f01..5d74af81d104 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -206,10 +206,10 @@ static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr)
* BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
* WIN[0-3] -> DRAM bank[0-3]
*/
-static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
+static int mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
{
const struct mbus_dram_target_info *dram;
- u32 size;
+ u64 size;
int i;

dram = mv_mbus_dram_info();
@@ -252,19 +252,32 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
if ((size & (size - 1)) != 0)
size = 1 << fls(size);

+ if (size > 0x100000000) {
+ dev_err(&port->pcie->pdev->dev,
+ "Could not configure DRAM window (too large): 0x%llx\n",
+ size);
+
+ return -EINVAL;
+ }
+
/* Setup BAR[1] to all DRAM banks. */
mvebu_writel(port, dram->cs[0].base, PCIE_BAR_LO_OFF(1));
mvebu_writel(port, 0, PCIE_BAR_HI_OFF(1));
mvebu_writel(port, ((size - 1) & 0xffff0000) | 1,
PCIE_BAR_CTRL_OFF(1));
+
+ return 0;
}

-static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
+static int mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
{
u32 cmd, mask;
+ int ret;

/* Point PCIe unit MBUS decode windows to DRAM space. */
- mvebu_pcie_setup_wins(port);
+ ret = mvebu_pcie_setup_wins(port);
+ if (ret)
+ return ret;

/* Master + slave enable. */
cmd = mvebu_readl(port, PCIE_CMD_OFF);
@@ -277,6 +290,8 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
mask = mvebu_readl(port, PCIE_MASK_OFF);
mask |= PCIE_MASK_ENABLE_INTS;
mvebu_writel(port, mask, PCIE_MASK_OFF);
+
+ return 0;
}

static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
@@ -882,7 +897,9 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)

if (!port->base)
continue;
- mvebu_pcie_setup_hw(port);
+ err = mvebu_pcie_setup_hw(port);
+ if (err)
+ return 0;
}

return 1;
--
2.11.0

2017-08-28 15:30:51

by Jan Lübbe

[permalink] [raw]
Subject: [RFC] ARM: Orion: Check DRAM window size

This is a corresponding change as "PCI: mvebu: Check DRAM window size" applied
to the Orion PCIe driver. I don't have the relevant hardware myself, but the
patch may still be useful for someone who has. This is completely untested.

Signed-off-by: Jan Luebbe <[email protected]>
---
arch/arm/mach-dove/pcie.c | 3 ++-
arch/arm/mach-mv78xx0/pcie.c | 3 ++-
arch/arm/mach-orion5x/pci.c | 3 ++-
arch/arm/plat-orion/pcie.c | 19 +++++++++++++++----
4 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c
index 91fe97144570..27e4689ee58d 100644
--- a/arch/arm/mach-dove/pcie.c
+++ b/arch/arm/mach-dove/pcie.c
@@ -51,7 +51,8 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
*/
orion_pcie_set_local_bus_nr(pp->base, sys->busnr);

- orion_pcie_setup(pp->base);
+ if (!orion_pcie_setup(pp->base))
+ return 0;

if (pp->index == 0)
pci_ioremap_io(sys->busnr * SZ_64K, DOVE_PCIE0_IO_PHYS_BASE);
diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c
index 81ff4327a962..3d17eeff44bf 100644
--- a/arch/arm/mach-mv78xx0/pcie.c
+++ b/arch/arm/mach-mv78xx0/pcie.c
@@ -113,7 +113,8 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys)
* Generic PCIe unit setup.
*/
orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
- orion_pcie_setup(pp->base);
+ if (!orion_pcie_setup(pp->base))
+ return 0;

pci_ioremap_io(nr * SZ_64K, MV78XX0_PCIE_IO_PHYS_BASE(nr));

diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c
index ecb998e7f8dc..f7f830872cc9 100644
--- a/arch/arm/mach-orion5x/pci.c
+++ b/arch/arm/mach-orion5x/pci.c
@@ -147,7 +147,8 @@ static int __init pcie_setup(struct pci_sys_data *sys)
/*
* Generic PCIe unit setup.
*/
- orion_pcie_setup(PCIE_BASE);
+ if (!orion_pcie_setup(PCIE_BASE))
+ return 0;

/*
* Check whether to apply Orion-1/Orion-NAS PCIe config
diff --git a/arch/arm/plat-orion/pcie.c b/arch/arm/plat-orion/pcie.c
index 8b8c06d2e9c4..07ae382cf48a 100644
--- a/arch/arm/plat-orion/pcie.c
+++ b/arch/arm/plat-orion/pcie.c
@@ -120,10 +120,10 @@ void __init orion_pcie_reset(void __iomem *base)
* BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
* WIN[0-3] -> DRAM bank[0-3]
*/
-static void __init orion_pcie_setup_wins(void __iomem *base)
+static int __init orion_pcie_setup_wins(void __iomem *base)
{
const struct mbus_dram_target_info *dram;
- u32 size;
+ u64 size;
int i;

dram = mv_mbus_dram_info();
@@ -170,15 +170,23 @@ static void __init orion_pcie_setup_wins(void __iomem *base)
if ((size & (size - 1)) != 0)
size = 1 << fls(size);

+ if (size > 0x100000000) {
+ pr_err("Could not configure DRAM window (too large): 0x%llx\n",
+ size);
+ return 0;
+ }
+
/*
* Setup BAR[1] to all DRAM banks.
*/
writel(dram->cs[0].base, base + PCIE_BAR_LO_OFF(1));
writel(0, base + PCIE_BAR_HI_OFF(1));
writel(((size - 1) & 0xffff0000) | 1, base + PCIE_BAR_CTRL_OFF(1));
+
+ return 1;
}

-void __init orion_pcie_setup(void __iomem *base)
+int __init orion_pcie_setup(void __iomem *base)
{
u16 cmd;
u32 mask;
@@ -186,7 +194,8 @@ void __init orion_pcie_setup(void __iomem *base)
/*
* Point PCIe unit MBUS decode windows to DRAM space.
*/
- orion_pcie_setup_wins(base);
+ if (!orion_pcie_setup_wins(base))
+ return 0;

/*
* Master + slave enable.
@@ -203,6 +212,8 @@ void __init orion_pcie_setup(void __iomem *base)
mask = readl(base + PCIE_MASK_OFF);
mask |= 0x0f000000;
writel(mask, base + PCIE_MASK_OFF);
+
+ return 1;
}

int orion_pcie_rd_conf(void __iomem *base, struct pci_bus *bus,
--
2.11.0

2017-08-28 15:51:43

by Andrew Lunn

[permalink] [raw]
Subject: Re: [RFC] ARM: Orion: Check DRAM window size

On Mon, Aug 28, 2017 at 05:30:39PM +0200, Jan Luebbe wrote:
> This is a corresponding change as "PCI: mvebu: Check DRAM window size" applied
> to the Orion PCIe driver. I don't have the relevant hardware myself, but the
> patch may still be useful for someone who has. This is completely untested.

Hi Jan

I've never seen one of these boards have more than 512M bytes of RAM.
So it is probably a non-issue.

Andrew

2017-08-30 20:07:03

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH 0/2] fix 4GB DRAM window support on mvebu

On Mon, Aug 28, 2017 at 05:25:15PM +0200, Jan Luebbe wrote:
> The current MBUS DRAM window calculation fails for 4GB windows because it
> overflows. This is fixed in the first patch by using u64 instead of u32 to
> store the size. The second excplicitly checks that we don't try to configure a
> too large memory window in the pci driver.
>
> As they don't depend on each other, they could also go in separatly.
>
> Jan Luebbe (2):
> bus: mbus: fix window size calculation for 4GB windows
> PCI: mvebu: Check DRAM window size
>
> drivers/bus/mvebu-mbus.c | 2 +-
> drivers/pci/host/pci-mvebu.c | 27 ++++++++++++++++++++++-----
> include/linux/mbus.h | 4 ++--
> 3 files changed, 25 insertions(+), 8 deletions(-)

Since these can be applied separately, I'll let somebody else take care of
the drivers/bus/mvebu-mbus.c part.

I'll look for an ack from Thomas or Jason before applying the second patch,
which touches drivers/pci/host/pci-mvebu.c.

2017-08-31 08:11:48

by Gregory CLEMENT

[permalink] [raw]
Subject: Re: [PATCH 0/2] fix 4GB DRAM window support on mvebu

Hi Bjorn and Jan,

On mer., août 30 2017, Bjorn Helgaas <[email protected]> wrote:

> On Mon, Aug 28, 2017 at 05:25:15PM +0200, Jan Luebbe wrote:
>> The current MBUS DRAM window calculation fails for 4GB windows because it
>> overflows. This is fixed in the first patch by using u64 instead of u32 to
>> store the size. The second excplicitly checks that we don't try to configure a
>> too large memory window in the pci driver.
>>
>> As they don't depend on each other, they could also go in separatly.
>>
>> Jan Luebbe (2):
>> bus: mbus: fix window size calculation for 4GB windows
>> PCI: mvebu: Check DRAM window size
>>
>> drivers/bus/mvebu-mbus.c | 2 +-
>> drivers/pci/host/pci-mvebu.c | 27 ++++++++++++++++++++++-----
>> include/linux/mbus.h | 4 ++--
>> 3 files changed, 25 insertions(+), 8 deletions(-)
>
> Since these can be applied separately, I'll let somebody else take care of
> the drivers/bus/mvebu-mbus.c part.

I think I am the one who should take it. I will apply it when v4.14-rc1
will be released as it is too late for me for 4.14 now.

However I am not against the fact that it is applied through an other
tree because we don't touch this file for the next release so there is
no risk for a conflict, I can give my Acked-by if needed.

Thanks,

Gregory

>
> I'll look for an ack from Thomas or Jason before applying the second patch,
> which touches drivers/pci/host/pci-mvebu.c.

--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

2017-09-19 14:43:22

by Gregory CLEMENT

[permalink] [raw]
Subject: Re: [PATCH 1/2] bus: mbus: fix window size calculation for 4GB windows

Hi Jan,

On lun., août 28 2017, Jan Luebbe <[email protected]> wrote:

> At least the Armada XP SoC supports 4GB on a single DRAM window. Because
> the size register values contain the actual size - 1, the MSB is set in
> that case. For example, the SDRAM window's control register's value is
> 0xffffffe1 for 4GB (bits 31 to 24 contain the size).
>
> The MBUS driver reads back each window's size from registers and
> calculates the actual size as (control_reg | ~DDR_SIZE_MASK) + 1, which
> overflows for 32 bit values, resulting in other miscalculations further
> on (a bad RAM window for the CESA crypto engine calculated by
> mvebu_mbus_setup_cpu_target_nooverlap() in my case).
>
> This patch changes the type in 'struct mbus_dram_window' from u32 to
> u64, which allows us to keep using the same register calculation code in
> most MBUS-using drivers (which calculate ->size - 1 again).
>

Your patch looks good, but as it is a fix we should also apply it on
stable, could you provide the commit to fix?

Thanks,

Gregory

> Signed-off-by: Jan Luebbe <[email protected]>
> ---
> drivers/bus/mvebu-mbus.c | 2 +-
> include/linux/mbus.h | 4 ++--
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c
> index c7f396903184..70db4d5638a6 100644
> --- a/drivers/bus/mvebu-mbus.c
> +++ b/drivers/bus/mvebu-mbus.c
> @@ -720,7 +720,7 @@ mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
> if (mbus->hw_io_coherency)
> w->mbus_attr |= ATTR_HW_COHERENCY;
> w->base = base & DDR_BASE_CS_LOW_MASK;
> - w->size = (size | ~DDR_SIZE_MASK) + 1;
> + w->size = (u64)(size | ~DDR_SIZE_MASK) + 1;
> }
> }
> mvebu_mbus_dram_info.num_cs = cs;
> diff --git a/include/linux/mbus.h b/include/linux/mbus.h
> index 0d3f14fd2621..4773145246ed 100644
> --- a/include/linux/mbus.h
> +++ b/include/linux/mbus.h
> @@ -31,8 +31,8 @@ struct mbus_dram_target_info
> struct mbus_dram_window {
> u8 cs_index;
> u8 mbus_attr;
> - u32 base;
> - u32 size;
> + u64 base;
> + u64 size;
> } cs[4];
> };
>
> --
> 2.11.0
>

--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

2017-09-20 16:37:20

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [PATCH 1/2] bus: mbus: fix window size calculation for 4GB windows

On Tue, Sep 19, 2017 at 04:43:18PM +0200, Gregory CLEMENT wrote:
> Hi Jan,
>
> On lun., ao?t 28 2017, Jan Luebbe <[email protected]> wrote:
>
> > At least the Armada XP SoC supports 4GB on a single DRAM window. Because
> > the size register values contain the actual size - 1, the MSB is set in
> > that case. For example, the SDRAM window's control register's value is
> > 0xffffffe1 for 4GB (bits 31 to 24 contain the size).
> >
> > The MBUS driver reads back each window's size from registers and
> > calculates the actual size as (control_reg | ~DDR_SIZE_MASK) + 1, which
> > overflows for 32 bit values, resulting in other miscalculations further
> > on (a bad RAM window for the CESA crypto engine calculated by
> > mvebu_mbus_setup_cpu_target_nooverlap() in my case).
> >
> > This patch changes the type in 'struct mbus_dram_window' from u32 to
> > u64, which allows us to keep using the same register calculation code in
> > most MBUS-using drivers (which calculate ->size - 1 again).
> >
>
> Your patch looks good, but as it is a fix we should also apply it on
> stable, could you provide the commit to fix?

It was there just from the start: the .c file was introduced in
v3.10-rc1~64^2~1^2~8^2~2 and already did that 32 bit calculus.

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |

2017-09-25 23:57:02

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH 2/2] PCI: mvebu: Check DRAM window size

On Mon, Aug 28, 2017 at 05:25:17PM +0200, Jan Luebbe wrote:
> The sum of the DRAM windows may exceed 4GB (at least on Armada XP).
> Return an error in that case.
>
> Signed-off-by: Jan Luebbe <[email protected]>

Looking for an ack from Thomas or Jason before applying this...

> ---
> drivers/pci/host/pci-mvebu.c | 27 ++++++++++++++++++++++-----
> 1 file changed, 22 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
> index f353a6eb2f01..5d74af81d104 100644
> --- a/drivers/pci/host/pci-mvebu.c
> +++ b/drivers/pci/host/pci-mvebu.c
> @@ -206,10 +206,10 @@ static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr)
> * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
> * WIN[0-3] -> DRAM bank[0-3]
> */
> -static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> +static int mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> {
> const struct mbus_dram_target_info *dram;
> - u32 size;
> + u64 size;
> int i;
>
> dram = mv_mbus_dram_info();
> @@ -252,19 +252,32 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> if ((size & (size - 1)) != 0)
> size = 1 << fls(size);
>
> + if (size > 0x100000000) {
> + dev_err(&port->pcie->pdev->dev,
> + "Could not configure DRAM window (too large): 0x%llx\n",
> + size);
> +
> + return -EINVAL;
> + }
> +
> /* Setup BAR[1] to all DRAM banks. */
> mvebu_writel(port, dram->cs[0].base, PCIE_BAR_LO_OFF(1));
> mvebu_writel(port, 0, PCIE_BAR_HI_OFF(1));
> mvebu_writel(port, ((size - 1) & 0xffff0000) | 1,
> PCIE_BAR_CTRL_OFF(1));
> +
> + return 0;
> }
>
> -static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> +static int mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> {
> u32 cmd, mask;
> + int ret;
>
> /* Point PCIe unit MBUS decode windows to DRAM space. */
> - mvebu_pcie_setup_wins(port);
> + ret = mvebu_pcie_setup_wins(port);
> + if (ret)
> + return ret;
>
> /* Master + slave enable. */
> cmd = mvebu_readl(port, PCIE_CMD_OFF);
> @@ -277,6 +290,8 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> mask = mvebu_readl(port, PCIE_MASK_OFF);
> mask |= PCIE_MASK_ENABLE_INTS;
> mvebu_writel(port, mask, PCIE_MASK_OFF);
> +
> + return 0;
> }
>
> static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
> @@ -882,7 +897,9 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
>
> if (!port->base)
> continue;
> - mvebu_pcie_setup_hw(port);
> + err = mvebu_pcie_setup_hw(port);
> + if (err)
> + return 0;
> }
>
> return 1;
> --
> 2.11.0
>

2017-11-06 20:53:48

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH 2/2] PCI: mvebu: Check DRAM window size

On Thu, Oct 05, 2017 at 04:16:50PM -0500, Bjorn Helgaas wrote:
> On Mon, Sep 25, 2017 at 06:56:58PM -0500, Bjorn Helgaas wrote:
> > On Mon, Aug 28, 2017 at 05:25:17PM +0200, Jan Luebbe wrote:
> > > The sum of the DRAM windows may exceed 4GB (at least on Armada XP).
> > > Return an error in that case.
> > >
> > > Signed-off-by: Jan Luebbe <[email protected]>
> >
> > Looking for an ack from Thomas or Jason before applying this...
>
> Ping, I think I'm stil waiting for an ack for this. Or did I miss it?

I'm dropping this. Please repost it with the appropriate acks if it's
still needed.

> > > ---
> > > drivers/pci/host/pci-mvebu.c | 27 ++++++++++++++++++++++-----
> > > 1 file changed, 22 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
> > > index f353a6eb2f01..5d74af81d104 100644
> > > --- a/drivers/pci/host/pci-mvebu.c
> > > +++ b/drivers/pci/host/pci-mvebu.c
> > > @@ -206,10 +206,10 @@ static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr)
> > > * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
> > > * WIN[0-3] -> DRAM bank[0-3]
> > > */
> > > -static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> > > +static int mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> > > {
> > > const struct mbus_dram_target_info *dram;
> > > - u32 size;
> > > + u64 size;
> > > int i;
> > >
> > > dram = mv_mbus_dram_info();
> > > @@ -252,19 +252,32 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> > > if ((size & (size - 1)) != 0)
> > > size = 1 << fls(size);
> > >
> > > + if (size > 0x100000000) {
> > > + dev_err(&port->pcie->pdev->dev,
> > > + "Could not configure DRAM window (too large): 0x%llx\n",
> > > + size);
> > > +
> > > + return -EINVAL;
> > > + }
> > > +
> > > /* Setup BAR[1] to all DRAM banks. */
> > > mvebu_writel(port, dram->cs[0].base, PCIE_BAR_LO_OFF(1));
> > > mvebu_writel(port, 0, PCIE_BAR_HI_OFF(1));
> > > mvebu_writel(port, ((size - 1) & 0xffff0000) | 1,
> > > PCIE_BAR_CTRL_OFF(1));
> > > +
> > > + return 0;
> > > }
> > >
> > > -static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > > +static int mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > > {
> > > u32 cmd, mask;
> > > + int ret;
> > >
> > > /* Point PCIe unit MBUS decode windows to DRAM space. */
> > > - mvebu_pcie_setup_wins(port);
> > > + ret = mvebu_pcie_setup_wins(port);
> > > + if (ret)
> > > + return ret;
> > >
> > > /* Master + slave enable. */
> > > cmd = mvebu_readl(port, PCIE_CMD_OFF);
> > > @@ -277,6 +290,8 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > > mask = mvebu_readl(port, PCIE_MASK_OFF);
> > > mask |= PCIE_MASK_ENABLE_INTS;
> > > mvebu_writel(port, mask, PCIE_MASK_OFF);
> > > +
> > > + return 0;
> > > }
> > >
> > > static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
> > > @@ -882,7 +897,9 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
> > >
> > > if (!port->base)
> > > continue;
> > > - mvebu_pcie_setup_hw(port);
> > > + err = mvebu_pcie_setup_hw(port);
> > > + if (err)
> > > + return 0;
> > > }
> > >
> > > return 1;
> > > --
> > > 2.11.0
> > >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > [email protected]
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

From 1580453962301255820@xxx Thu Oct 05 21:19:12 +0000 2017
X-GM-THRID: 1576989131249353178
X-Gmail-Labels: Inbox,Category Forums

2017-10-05 21:19:12

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH 2/2] PCI: mvebu: Check DRAM window size

On Mon, Sep 25, 2017 at 06:56:58PM -0500, Bjorn Helgaas wrote:
> On Mon, Aug 28, 2017 at 05:25:17PM +0200, Jan Luebbe wrote:
> > The sum of the DRAM windows may exceed 4GB (at least on Armada XP).
> > Return an error in that case.
> >
> > Signed-off-by: Jan Luebbe <[email protected]>
>
> Looking for an ack from Thomas or Jason before applying this...

Ping, I think I'm stil waiting for an ack for this. Or did I miss it?

> > ---
> > drivers/pci/host/pci-mvebu.c | 27 ++++++++++++++++++++++-----
> > 1 file changed, 22 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
> > index f353a6eb2f01..5d74af81d104 100644
> > --- a/drivers/pci/host/pci-mvebu.c
> > +++ b/drivers/pci/host/pci-mvebu.c
> > @@ -206,10 +206,10 @@ static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr)
> > * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
> > * WIN[0-3] -> DRAM bank[0-3]
> > */
> > -static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> > +static int mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> > {
> > const struct mbus_dram_target_info *dram;
> > - u32 size;
> > + u64 size;
> > int i;
> >
> > dram = mv_mbus_dram_info();
> > @@ -252,19 +252,32 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> > if ((size & (size - 1)) != 0)
> > size = 1 << fls(size);
> >
> > + if (size > 0x100000000) {
> > + dev_err(&port->pcie->pdev->dev,
> > + "Could not configure DRAM window (too large): 0x%llx\n",
> > + size);
> > +
> > + return -EINVAL;
> > + }
> > +
> > /* Setup BAR[1] to all DRAM banks. */
> > mvebu_writel(port, dram->cs[0].base, PCIE_BAR_LO_OFF(1));
> > mvebu_writel(port, 0, PCIE_BAR_HI_OFF(1));
> > mvebu_writel(port, ((size - 1) & 0xffff0000) | 1,
> > PCIE_BAR_CTRL_OFF(1));
> > +
> > + return 0;
> > }
> >
> > -static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > +static int mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > {
> > u32 cmd, mask;
> > + int ret;
> >
> > /* Point PCIe unit MBUS decode windows to DRAM space. */
> > - mvebu_pcie_setup_wins(port);
> > + ret = mvebu_pcie_setup_wins(port);
> > + if (ret)
> > + return ret;
> >
> > /* Master + slave enable. */
> > cmd = mvebu_readl(port, PCIE_CMD_OFF);
> > @@ -277,6 +290,8 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > mask = mvebu_readl(port, PCIE_MASK_OFF);
> > mask |= PCIE_MASK_ENABLE_INTS;
> > mvebu_writel(port, mask, PCIE_MASK_OFF);
> > +
> > + return 0;
> > }
> >
> > static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
> > @@ -882,7 +897,9 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
> >
> > if (!port->base)
> > continue;
> > - mvebu_pcie_setup_hw(port);
> > + err = mvebu_pcie_setup_hw(port);
> > + if (err)
> > + return 0;
> > }
> >
> > return 1;
> > --
> > 2.11.0
> >
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

From 1579574362761759674@xxx Tue Sep 26 04:18:20 +0000 2017
X-GM-THRID: 1576989131249353178
X-Gmail-Labels: Inbox,Category Forums