All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ARM: mm: reduce maximum number of CPUs if DEBUG_KMAP_LOCAL is enabled
@ 2021-02-16 18:14 Ard Biesheuvel
  2021-02-16 23:06 ` Peter Robinson
  0 siblings, 1 reply; 4+ messages in thread
From: Ard Biesheuvel @ 2021-02-16 18:14 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Ard Biesheuvel, linus.walleij, linux, pbrobinson

The debugging code for kmap_local() doubles the number of fixmap slots
allocated for kmap_local(), in order to use half of them as guard
regions. This causes the fixmap region to grow downwards and collide
with the newly added virtual DT mapping, which is obviously not good.

One manifestation of this is EFI boot on a kernel built with NR_CPUS=32,
which may pass the FDT in highmem, resulting in block entries that the
fixmap code misidentifies as table entries, and subsequently tries to
dereference using a phys-to-virt translation that is only valid for
lowmem. This results in a cryptic splat such as the one below.

  ftrace: allocating 45548 entries in 89 pages
  8<--- cut here ---
  Unable to handle kernel paging request at virtual address fc6006f0
  pgd = (ptrval)
  [fc6006f0] *pgd=80000040207003, *pmd=00000000
  Internal error: Oops: a06 [#1] SMP ARM
  Modules linked in:
  CPU: 0 PID: 0 Comm: swapper Not tainted 5.11.0+ #382
  Hardware name: Generic DT based system
  PC is at cpu_ca15_set_pte_ext+0x24/0x30
  LR is at __set_fixmap+0xe4/0x118
  pc : [<c041ac9c>]    lr : [<c04189d8>]    psr: 400000d3
  sp : c1601ed8  ip : 00400000  fp : 00800000
  r10: 0000071f  r9 : 00421000  r8 : 00c00000
  r7 : 00c00000  r6 : 0000071f  r5 : ffade000  r4 : 4040171f
  r3 : 00c00000  r2 : 4040171f  r1 : c041ac78  r0 : fc6006f0
  Flags: nZcv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment none
  Control: 30c5387d  Table: 40203000  DAC: 00000001
  Process swapper (pid: 0, stack limit = 0x(ptrval))

So let's limit the supported number of CPUs to 16 when
CONFIG_DEBUG_KMAP_LOCAL is in effect.

Reported-by: Peter Robinson <pbrobinson@gmail.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm/Kconfig | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 138248999df7..3d2c684eab77 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1310,9 +1310,15 @@ config KASAN_SHADOW_OFFSET
 
 config NR_CPUS
 	int "Maximum number of CPUs (2-32)"
-	range 2 32
+	range 2 16 if DEBUG_KMAP_LOCAL
+	range 2 32 if !DEBUG_KMAP_LOCAL
 	depends on SMP
 	default "4"
+	help
+	  The maximum number of CPUs that the kernel can support.
+	  Up to 32 CPUs can be supported, or up to 16 if kmap_local()
+	  debugging is enabled, which uses half of the per-CPU fixmap
+	  slots as guard regions.
 
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs"
-- 
2.30.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] ARM: mm: reduce maximum number of CPUs if DEBUG_KMAP_LOCAL is enabled
  2021-02-16 18:14 [PATCH] ARM: mm: reduce maximum number of CPUs if DEBUG_KMAP_LOCAL is enabled Ard Biesheuvel
@ 2021-02-16 23:06 ` Peter Robinson
  2021-02-17  7:08   ` Ard Biesheuvel
  0 siblings, 1 reply; 4+ messages in thread
From: Peter Robinson @ 2021-02-16 23:06 UTC (permalink / raw)
  To: Ard Biesheuvel; +Cc: linus.walleij, linux, linux-arm-kernel

On Tue, Feb 16, 2021 at 6:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> The debugging code for kmap_local() doubles the number of fixmap slots
> allocated for kmap_local(), in order to use half of them as guard
> regions. This causes the fixmap region to grow downwards and collide
> with the newly added virtual DT mapping, which is obviously not good.
>
> One manifestation of this is EFI boot on a kernel built with NR_CPUS=32,
> which may pass the FDT in highmem, resulting in block entries that the
> fixmap code misidentifies as table entries, and subsequently tries to
> dereference using a phys-to-virt translation that is only valid for
> lowmem. This results in a cryptic splat such as the one below.
>
>   ftrace: allocating 45548 entries in 89 pages
>   8<--- cut here ---
>   Unable to handle kernel paging request at virtual address fc6006f0
>   pgd = (ptrval)
>   [fc6006f0] *pgd=80000040207003, *pmd=00000000
>   Internal error: Oops: a06 [#1] SMP ARM
>   Modules linked in:
>   CPU: 0 PID: 0 Comm: swapper Not tainted 5.11.0+ #382
>   Hardware name: Generic DT based system
>   PC is at cpu_ca15_set_pte_ext+0x24/0x30
>   LR is at __set_fixmap+0xe4/0x118
>   pc : [<c041ac9c>]    lr : [<c04189d8>]    psr: 400000d3
>   sp : c1601ed8  ip : 00400000  fp : 00800000
>   r10: 0000071f  r9 : 00421000  r8 : 00c00000
>   r7 : 00c00000  r6 : 0000071f  r5 : ffade000  r4 : 4040171f
>   r3 : 00c00000  r2 : 4040171f  r1 : c041ac78  r0 : fc6006f0
>   Flags: nZcv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment none
>   Control: 30c5387d  Table: 40203000  DAC: 00000001
>   Process swapper (pid: 0, stack limit = 0x(ptrval))
>
> So let's limit the supported number of CPUs to 16 when
> CONFIG_DEBUG_KMAP_LOCAL is in effect.
>
> Reported-by: Peter Robinson <pbrobinson@gmail.com>
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Tested-by: Peter Robinson <pbrobinson@gmail.com>

Tested with both a LPAE and non LPAE kernel.

> ---
>  arch/arm/Kconfig | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 138248999df7..3d2c684eab77 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1310,9 +1310,15 @@ config KASAN_SHADOW_OFFSET
>
>  config NR_CPUS
>         int "Maximum number of CPUs (2-32)"
> -       range 2 32
> +       range 2 16 if DEBUG_KMAP_LOCAL
> +       range 2 32 if !DEBUG_KMAP_LOCAL
>         depends on SMP
>         default "4"
> +       help
> +         The maximum number of CPUs that the kernel can support.
> +         Up to 32 CPUs can be supported, or up to 16 if kmap_local()
> +         debugging is enabled, which uses half of the per-CPU fixmap
> +         slots as guard regions.
>
>  config HOTPLUG_CPU
>         bool "Support for hot-pluggable CPUs"
> --
> 2.30.0
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] ARM: mm: reduce maximum number of CPUs if DEBUG_KMAP_LOCAL is enabled
  2021-02-16 23:06 ` Peter Robinson
@ 2021-02-17  7:08   ` Ard Biesheuvel
  2021-02-18 14:06     ` Thomas Gleixner
  0 siblings, 1 reply; 4+ messages in thread
From: Ard Biesheuvel @ 2021-02-17  7:08 UTC (permalink / raw)
  To: Peter Robinson, Thomas Gleixner; +Cc: Linus Walleij, Russell King, Linux ARM

(+ Thomas)

On Wed, 17 Feb 2021 at 00:06, Peter Robinson <pbrobinson@gmail.com> wrote:
>
> On Tue, Feb 16, 2021 at 6:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > The debugging code for kmap_local() doubles the number of fixmap slots
> > allocated for kmap_local(), in order to use half of them as guard
> > regions. This causes the fixmap region to grow downwards and collide
> > with the newly added virtual DT mapping, which is obviously not good.
> >
> > One manifestation of this is EFI boot on a kernel built with NR_CPUS=32,
> > which may pass the FDT in highmem, resulting in block entries that the
> > fixmap code misidentifies as table entries, and subsequently tries to
> > dereference using a phys-to-virt translation that is only valid for
> > lowmem. This results in a cryptic splat such as the one below.
> >
> >   ftrace: allocating 45548 entries in 89 pages
> >   8<--- cut here ---
> >   Unable to handle kernel paging request at virtual address fc6006f0
> >   pgd = (ptrval)
> >   [fc6006f0] *pgd=80000040207003, *pmd=00000000
> >   Internal error: Oops: a06 [#1] SMP ARM
> >   Modules linked in:
> >   CPU: 0 PID: 0 Comm: swapper Not tainted 5.11.0+ #382
> >   Hardware name: Generic DT based system
> >   PC is at cpu_ca15_set_pte_ext+0x24/0x30
> >   LR is at __set_fixmap+0xe4/0x118
> >   pc : [<c041ac9c>]    lr : [<c04189d8>]    psr: 400000d3
> >   sp : c1601ed8  ip : 00400000  fp : 00800000
> >   r10: 0000071f  r9 : 00421000  r8 : 00c00000
> >   r7 : 00c00000  r6 : 0000071f  r5 : ffade000  r4 : 4040171f
> >   r3 : 00c00000  r2 : 4040171f  r1 : c041ac78  r0 : fc6006f0
> >   Flags: nZcv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment none
> >   Control: 30c5387d  Table: 40203000  DAC: 00000001
> >   Process swapper (pid: 0, stack limit = 0x(ptrval))
> >
> > So let's limit the supported number of CPUs to 16 when
> > CONFIG_DEBUG_KMAP_LOCAL is in effect.
> >
> > Reported-by: Peter Robinson <pbrobinson@gmail.com>
> > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> Tested-by: Peter Robinson <pbrobinson@gmail.com>
>
> Tested with both a LPAE and non LPAE kernel.
>

Thanks Peter.

Note that this patch should probably carry

Fixes: 2a15ba82fa6ca3f3 ("ARM: highmem: Switch to generic kmap atomic")

given that the ARM specific kmap implementation did not suffer from
this issue, and the DT remapping change (7a1be318f579) does not make
any difference here.



> > ---
> >  arch/arm/Kconfig | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > index 138248999df7..3d2c684eab77 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -1310,9 +1310,15 @@ config KASAN_SHADOW_OFFSET
> >
> >  config NR_CPUS
> >         int "Maximum number of CPUs (2-32)"
> > -       range 2 32
> > +       range 2 16 if DEBUG_KMAP_LOCAL
> > +       range 2 32 if !DEBUG_KMAP_LOCAL
> >         depends on SMP
> >         default "4"
> > +       help
> > +         The maximum number of CPUs that the kernel can support.
> > +         Up to 32 CPUs can be supported, or up to 16 if kmap_local()
> > +         debugging is enabled, which uses half of the per-CPU fixmap
> > +         slots as guard regions.
> >
> >  config HOTPLUG_CPU
> >         bool "Support for hot-pluggable CPUs"
> > --
> > 2.30.0
> >

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] ARM: mm: reduce maximum number of CPUs if DEBUG_KMAP_LOCAL is enabled
  2021-02-17  7:08   ` Ard Biesheuvel
@ 2021-02-18 14:06     ` Thomas Gleixner
  0 siblings, 0 replies; 4+ messages in thread
From: Thomas Gleixner @ 2021-02-18 14:06 UTC (permalink / raw)
  To: Ard Biesheuvel, Peter Robinson; +Cc: Linus Walleij, Russell King, Linux ARM

On Wed, Feb 17 2021 at 08:08, Ard Biesheuvel wrote:
> On Wed, 17 Feb 2021 at 00:06, Peter Robinson <pbrobinson@gmail.com> wrote:
>> > So let's limit the supported number of CPUs to 16 when
>> > CONFIG_DEBUG_KMAP_LOCAL is in effect.
>> >
>> > Reported-by: Peter Robinson <pbrobinson@gmail.com>
>> > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
>> Tested-by: Peter Robinson <pbrobinson@gmail.com>
>>
>> Tested with both a LPAE and non LPAE kernel.
>>
>
> Thanks Peter.
>
> Note that this patch should probably carry
>
> Fixes: 2a15ba82fa6ca3f3 ("ARM: highmem: Switch to generic kmap atomic")
>
> given that the ARM specific kmap implementation did not suffer from
> this issue, and the DT remapping change (7a1be318f579) does not make
> any difference here.

Makes sense.

Thanks,

        tglx

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-02-18 14:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-16 18:14 [PATCH] ARM: mm: reduce maximum number of CPUs if DEBUG_KMAP_LOCAL is enabled Ard Biesheuvel
2021-02-16 23:06 ` Peter Robinson
2021-02-17  7:08   ` Ard Biesheuvel
2021-02-18 14:06     ` Thomas Gleixner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.