* [PATCH] arm: fix pmd flushing in map_init_section
@ 2013-06-14 16:22 Mark Rutland
2013-06-14 16:34 ` Christoffer Dall
0 siblings, 1 reply; 8+ messages in thread
From: Mark Rutland @ 2013-06-14 16:22 UTC (permalink / raw)
To: linux-arm-kernel
In e651eab0af: "ARM: 7677/1: LPAE: Fix mapping in alloc_init_section for
unaligned addresses", the pmd flushing was broken when split out to
map_init_section. At the end of the final iteration of the while loop,
pmd will point at the pmd_t immediately after the pmds we updated, and
thus flush_pmd_entry(pmd) won't flush the newly modified pmds. This has
been observed to prevent an 11MPCore system from booting.
This patch fixes this by remembering the address of the first pmd we
update and using this as the argument to flush_pmd_entry.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: R Sricharan <r.sricharan@ti.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christoffer Dall <cdall@cs.columbia.edu>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: stable at vger.kernel.org
---
arch/arm/mm/mmu.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index e0d8565..22bc0ff 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -620,6 +620,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
unsigned long end, phys_addr_t phys,
const struct mem_type *type)
{
+ pmd_t *p = pmd;
#ifndef CONFIG_ARM_LPAE
/*
* In classic MMU format, puds and pmds are folded in to
@@ -638,7 +639,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
phys += SECTION_SIZE;
} while (pmd++, addr += SECTION_SIZE, addr != end);
- flush_pmd_entry(pmd);
+ flush_pmd_entry(p);
}
static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
--
1.8.1.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH] arm: fix pmd flushing in map_init_section
2013-06-14 16:22 [PATCH] arm: fix pmd flushing in map_init_section Mark Rutland
@ 2013-06-14 16:34 ` Christoffer Dall
2013-06-14 16:48 ` Mark Rutland
2013-06-14 17:28 ` [PATCH] " Catalin Marinas
0 siblings, 2 replies; 8+ messages in thread
From: Christoffer Dall @ 2013-06-14 16:34 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jun 14, 2013 at 05:22:22PM +0100, Mark Rutland wrote:
> In e651eab0af: "ARM: 7677/1: LPAE: Fix mapping in alloc_init_section for
> unaligned addresses", the pmd flushing was broken when split out to
> map_init_section. At the end of the final iteration of the while loop,
> pmd will point at the pmd_t immediately after the pmds we updated, and
> thus flush_pmd_entry(pmd) won't flush the newly modified pmds. This has
> been observed to prevent an 11MPCore system from booting.
>
> This patch fixes this by remembering the address of the first pmd we
> update and using this as the argument to flush_pmd_entry.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: R Sricharan <r.sricharan@ti.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Christoffer Dall <cdall@cs.columbia.edu>
> Cc: Russell King <rmk+kernel@arm.linux.org.uk>
> Cc: stable at vger.kernel.org
> ---
> arch/arm/mm/mmu.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index e0d8565..22bc0ff 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -620,6 +620,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
> unsigned long end, phys_addr_t phys,
> const struct mem_type *type)
> {
> + pmd_t *p = pmd;
> #ifndef CONFIG_ARM_LPAE
> /*
> * In classic MMU format, puds and pmds are folded in to
> @@ -638,7 +639,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
> phys += SECTION_SIZE;
> } while (pmd++, addr += SECTION_SIZE, addr != end);
>
> - flush_pmd_entry(pmd);
> + flush_pmd_entry(p);
> }
>
> static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
> --
Refresh my memory here again, why are we not flushing every pmd entry we
update? Is it because we assume the cache lines cover the maximum span
between addr and end?
Theoretically, shouldn't you also increment p in the non-LPAE case?
-Christoffer
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] arm: fix pmd flushing in map_init_section
2013-06-14 16:34 ` Christoffer Dall
@ 2013-06-14 16:48 ` Mark Rutland
2013-06-14 16:54 ` Christoffer Dall
2013-06-14 17:28 ` [PATCH] " Catalin Marinas
1 sibling, 1 reply; 8+ messages in thread
From: Mark Rutland @ 2013-06-14 16:48 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jun 14, 2013 at 05:34:09PM +0100, Christoffer Dall wrote:
> On Fri, Jun 14, 2013 at 05:22:22PM +0100, Mark Rutland wrote:
> > In e651eab0af: "ARM: 7677/1: LPAE: Fix mapping in alloc_init_section for
> > unaligned addresses", the pmd flushing was broken when split out to
> > map_init_section. At the end of the final iteration of the while loop,
> > pmd will point at the pmd_t immediately after the pmds we updated, and
> > thus flush_pmd_entry(pmd) won't flush the newly modified pmds. This has
> > been observed to prevent an 11MPCore system from booting.
> >
> > This patch fixes this by remembering the address of the first pmd we
> > update and using this as the argument to flush_pmd_entry.
> >
> > Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> > Cc: R Sricharan <r.sricharan@ti.com>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: Christoffer Dall <cdall@cs.columbia.edu>
> > Cc: Russell King <rmk+kernel@arm.linux.org.uk>
> > Cc: stable at vger.kernel.org
> > ---
> > arch/arm/mm/mmu.c | 3 ++-
> > 1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> > index e0d8565..22bc0ff 100644
> > --- a/arch/arm/mm/mmu.c
> > +++ b/arch/arm/mm/mmu.c
> > @@ -620,6 +620,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
> > unsigned long end, phys_addr_t phys,
> > const struct mem_type *type)
> > {
> > + pmd_t *p = pmd;
> > #ifndef CONFIG_ARM_LPAE
> > /*
> > * In classic MMU format, puds and pmds are folded in to
> > @@ -638,7 +639,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
> > phys += SECTION_SIZE;
> > } while (pmd++, addr += SECTION_SIZE, addr != end);
> >
> > - flush_pmd_entry(pmd);
> > + flush_pmd_entry(p);
> > }
> >
> > static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
> > --
>
> Refresh my memory here again, why are we not flushing every pmd entry we
> update? Is it because we assume the cache lines cover the maximum span
> between addr and end?
Yup, we assume a minimum cache line size of 8 bytes. I'm not so keen on this,
but I suspect others might not be happy with moving the flush into the loop.
>
> Theoretically, shouldn't you also increment p in the non-LPAE case?
Yes, I should. v2 shortly...
Thanks,
Mark.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] arm: fix pmd flushing in map_init_section
2013-06-14 16:48 ` Mark Rutland
@ 2013-06-14 16:54 ` Christoffer Dall
2013-06-14 16:57 ` [PATCHv2] " Mark Rutland
0 siblings, 1 reply; 8+ messages in thread
From: Christoffer Dall @ 2013-06-14 16:54 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jun 14, 2013 at 05:48:31PM +0100, Mark Rutland wrote:
> On Fri, Jun 14, 2013 at 05:34:09PM +0100, Christoffer Dall wrote:
> > On Fri, Jun 14, 2013 at 05:22:22PM +0100, Mark Rutland wrote:
> > > In e651eab0af: "ARM: 7677/1: LPAE: Fix mapping in alloc_init_section for
> > > unaligned addresses", the pmd flushing was broken when split out to
> > > map_init_section. At the end of the final iteration of the while loop,
> > > pmd will point at the pmd_t immediately after the pmds we updated, and
> > > thus flush_pmd_entry(pmd) won't flush the newly modified pmds. This has
> > > been observed to prevent an 11MPCore system from booting.
> > >
> > > This patch fixes this by remembering the address of the first pmd we
> > > update and using this as the argument to flush_pmd_entry.
> > >
> > > Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> > > Cc: R Sricharan <r.sricharan@ti.com>
> > > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > > Cc: Christoffer Dall <cdall@cs.columbia.edu>
> > > Cc: Russell King <rmk+kernel@arm.linux.org.uk>
> > > Cc: stable at vger.kernel.org
> > > ---
> > > arch/arm/mm/mmu.c | 3 ++-
> > > 1 file changed, 2 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> > > index e0d8565..22bc0ff 100644
> > > --- a/arch/arm/mm/mmu.c
> > > +++ b/arch/arm/mm/mmu.c
> > > @@ -620,6 +620,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
> > > unsigned long end, phys_addr_t phys,
> > > const struct mem_type *type)
> > > {
> > > + pmd_t *p = pmd;
> > > #ifndef CONFIG_ARM_LPAE
> > > /*
> > > * In classic MMU format, puds and pmds are folded in to
> > > @@ -638,7 +639,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
> > > phys += SECTION_SIZE;
> > > } while (pmd++, addr += SECTION_SIZE, addr != end);
> > >
> > > - flush_pmd_entry(pmd);
> > > + flush_pmd_entry(p);
> > > }
> > >
> > > static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
> > > --
> >
> > Refresh my memory here again, why are we not flushing every pmd entry we
> > update? Is it because we assume the cache lines cover the maximum span
> > between addr and end?
>
> Yup, we assume a minimum cache line size of 8 bytes. I'm not so keen on this,
> but I suspect others might not be happy with moving the flush into the loop.
>
A comment on the call to flush_pmd_entry could solve it.
> >
> > Theoretically, shouldn't you also increment p in the non-LPAE case?
>
> Yes, I should. v2 shortly...
>
> Thanks,
> Mark.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCHv2] arm: fix pmd flushing in map_init_section
2013-06-14 16:54 ` Christoffer Dall
@ 2013-06-14 16:57 ` Mark Rutland
2013-06-14 17:04 ` Christoffer Dall
2013-06-14 17:29 ` Catalin Marinas
0 siblings, 2 replies; 8+ messages in thread
From: Mark Rutland @ 2013-06-14 16:57 UTC (permalink / raw)
To: linux-arm-kernel
In e651eab0af: "ARM: 7677/1: LPAE: Fix mapping in alloc_init_section for
unaligned addresses", the pmd flushing was broken when split out to
map_init_section. At the end of the final iteration of the while loop,
pmd will point at the pmd_t immediately after the pmds we updated, and
thus flush_pmd_entry(pmd) won't flush the newly modified pmds. This has
been observed to prevent an 11MPCore system from booting.
This patch fixes this by remembering the address of the first pmd we
update and using this as the argument to flush_pmd_entry.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: R Sricharan <r.sricharan@ti.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christoffer Dall <cdall@cs.columbia.edu>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: stable at vger.kernel.org
---
Since v1:
* Take the incremented value of pmd for !LPAE.
* Comment why only one cache flush is necessary.
arch/arm/mm/mmu.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index e0d8565..1c66f51 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -620,6 +620,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
unsigned long end, phys_addr_t phys,
const struct mem_type *type)
{
+ pmd_t *p;
#ifndef CONFIG_ARM_LPAE
/*
* In classic MMU format, puds and pmds are folded in to
@@ -633,12 +634,18 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
if (addr & SECTION_SIZE)
pmd++;
#endif
+ p = pmd;
+
do {
*pmd = __pmd(phys | type->prot_sect);
phys += SECTION_SIZE;
} while (pmd++, addr += SECTION_SIZE, addr != end);
- flush_pmd_entry(pmd);
+ /*
+ * We expect a minimum cache line of 8 bytes, so this will flush both
+ * pmd entries with classic tables, and will be a nop for LPAE systems.
+ */
+ flush_pmd_entry(p);
}
static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
--
1.8.1.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCHv2] arm: fix pmd flushing in map_init_section
2013-06-14 16:57 ` [PATCHv2] " Mark Rutland
@ 2013-06-14 17:04 ` Christoffer Dall
2013-06-14 17:29 ` Catalin Marinas
1 sibling, 0 replies; 8+ messages in thread
From: Christoffer Dall @ 2013-06-14 17:04 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jun 14, 2013 at 05:57:24PM +0100, Mark Rutland wrote:
> In e651eab0af: "ARM: 7677/1: LPAE: Fix mapping in alloc_init_section for
> unaligned addresses", the pmd flushing was broken when split out to
> map_init_section. At the end of the final iteration of the while loop,
> pmd will point at the pmd_t immediately after the pmds we updated, and
> thus flush_pmd_entry(pmd) won't flush the newly modified pmds. This has
> been observed to prevent an 11MPCore system from booting.
>
> This patch fixes this by remembering the address of the first pmd we
> update and using this as the argument to flush_pmd_entry.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: R Sricharan <r.sricharan@ti.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Christoffer Dall <cdall@cs.columbia.edu>
> Cc: Russell King <rmk+kernel@arm.linux.org.uk>
> Cc: stable at vger.kernel.org
> ---
> Since v1:
> * Take the incremented value of pmd for !LPAE.
> * Comment why only one cache flush is necessary.
>
> arch/arm/mm/mmu.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index e0d8565..1c66f51 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -620,6 +620,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
> unsigned long end, phys_addr_t phys,
> const struct mem_type *type)
> {
> + pmd_t *p;
> #ifndef CONFIG_ARM_LPAE
> /*
> * In classic MMU format, puds and pmds are folded in to
> @@ -633,12 +634,18 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
> if (addr & SECTION_SIZE)
> pmd++;
> #endif
> + p = pmd;
> +
> do {
> *pmd = __pmd(phys | type->prot_sect);
> phys += SECTION_SIZE;
> } while (pmd++, addr += SECTION_SIZE, addr != end);
>
> - flush_pmd_entry(pmd);
> + /*
> + * We expect a minimum cache line of 8 bytes, so this will flush both
> + * pmd entries with classic tables, and will be a nop for LPAE systems.
> + */
> + flush_pmd_entry(p);
> }
>
> static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
> --
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] arm: fix pmd flushing in map_init_section
2013-06-14 16:34 ` Christoffer Dall
2013-06-14 16:48 ` Mark Rutland
@ 2013-06-14 17:28 ` Catalin Marinas
1 sibling, 0 replies; 8+ messages in thread
From: Catalin Marinas @ 2013-06-14 17:28 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jun 14, 2013 at 05:34:09PM +0100, Christoffer Dall wrote:
> On Fri, Jun 14, 2013 at 05:22:22PM +0100, Mark Rutland wrote:
> > In e651eab0af: "ARM: 7677/1: LPAE: Fix mapping in alloc_init_section for
> > unaligned addresses", the pmd flushing was broken when split out to
> > map_init_section. At the end of the final iteration of the while loop,
> > pmd will point at the pmd_t immediately after the pmds we updated, and
> > thus flush_pmd_entry(pmd) won't flush the newly modified pmds. This has
> > been observed to prevent an 11MPCore system from booting.
> >
> > This patch fixes this by remembering the address of the first pmd we
> > update and using this as the argument to flush_pmd_entry.
> >
> > Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> > Cc: R Sricharan <r.sricharan@ti.com>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: Christoffer Dall <cdall@cs.columbia.edu>
> > Cc: Russell King <rmk+kernel@arm.linux.org.uk>
> > Cc: stable at vger.kernel.org
> > ---
> > arch/arm/mm/mmu.c | 3 ++-
> > 1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> > index e0d8565..22bc0ff 100644
> > --- a/arch/arm/mm/mmu.c
> > +++ b/arch/arm/mm/mmu.c
> > @@ -620,6 +620,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
> > unsigned long end, phys_addr_t phys,
> > const struct mem_type *type)
> > {
> > + pmd_t *p = pmd;
> > #ifndef CONFIG_ARM_LPAE
> > /*
> > * In classic MMU format, puds and pmds are folded in to
> > @@ -638,7 +639,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr,
> > phys += SECTION_SIZE;
> > } while (pmd++, addr += SECTION_SIZE, addr != end);
> >
> > - flush_pmd_entry(pmd);
> > + flush_pmd_entry(p);
> > }
> >
> > static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
> > --
>
> Refresh my memory here again, why are we not flushing every pmd entry we
> update? Is it because we assume the cache lines cover the maximum span
> between addr and end?
>
> Theoretically, shouldn't you also increment p in the non-LPAE case?
It wouldn't make any difference. With classic MMU we assume that we
write 2 pmds at the same time (to form a pgd covering 2MB) but the above
increment is a workaround to only allow 1MB section mappings. Either
way, it's harmless.
--
Catalin
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCHv2] arm: fix pmd flushing in map_init_section
2013-06-14 16:57 ` [PATCHv2] " Mark Rutland
2013-06-14 17:04 ` Christoffer Dall
@ 2013-06-14 17:29 ` Catalin Marinas
1 sibling, 0 replies; 8+ messages in thread
From: Catalin Marinas @ 2013-06-14 17:29 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Jun 14, 2013 at 05:57:24PM +0100, Mark Rutland wrote:
> In e651eab0af: "ARM: 7677/1: LPAE: Fix mapping in alloc_init_section for
> unaligned addresses", the pmd flushing was broken when split out to
> map_init_section. At the end of the final iteration of the while loop,
> pmd will point at the pmd_t immediately after the pmds we updated, and
> thus flush_pmd_entry(pmd) won't flush the newly modified pmds. This has
> been observed to prevent an 11MPCore system from booting.
>
> This patch fixes this by remembering the address of the first pmd we
> update and using this as the argument to flush_pmd_entry.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: R Sricharan <r.sricharan@ti.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Christoffer Dall <cdall@cs.columbia.edu>
> Cc: Russell King <rmk+kernel@arm.linux.org.uk>
> Cc: stable at vger.kernel.org
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-06-14 17:29 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-14 16:22 [PATCH] arm: fix pmd flushing in map_init_section Mark Rutland
2013-06-14 16:34 ` Christoffer Dall
2013-06-14 16:48 ` Mark Rutland
2013-06-14 16:54 ` Christoffer Dall
2013-06-14 16:57 ` [PATCHv2] " Mark Rutland
2013-06-14 17:04 ` Christoffer Dall
2013-06-14 17:29 ` Catalin Marinas
2013-06-14 17:28 ` [PATCH] " Catalin Marinas
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).