All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ARM: decompressor: fix BSS size calculation for LLVM ld.lld
@ 2021-02-05  8:52 Ard Biesheuvel
  2021-02-05 18:00 ` Nick Desaulniers
  0 siblings, 1 reply; 7+ messages in thread
From: Ard Biesheuvel @ 2021-02-05  8:52 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Nathan Chancellor, Guillaume Tucker, Nick Desaulniers, linux,
	Ard Biesheuvel

The LLVM ld.lld linker uses a different symbol type for __bss_start,
resulting in the calculation of KBSS_SZ to be thrown off. Up until now,
this has gone unnoticed as it only affects the appended DTB case, but
pending changes for ARM in the way the decompressed kernel is cleaned
from the caches has uncovered this problem.

On a ld.lld build:

  $ nm vmlinux |grep bss_
  c1c22034 D __bss_start
  c1c86e98 B __bss_stop

resulting in

  433: c1c86e98     0 NOTYPE  GLOBAL DEFAULT  ABS _kernel_bss_size

which is obviously incorrect, and may cause the cache clean to access
unmapped memory, or cause the size calculation to wrap, resulting in no
cache clean to be performed at all.

Fix this by updating the sed regex to take D type symbols into account.

Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Guillaume Tucker <guillaume.tucker@collabora.com>
Link: https://lore.kernel.org/linux-arm-kernel/6c65bcef-d4e7-25fa-43cf-2c435bb61bb9@collabora.com/
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm/boot/compressed/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index fb521efcc6c2..54307db7854d 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -115,8 +115,8 @@ asflags-y := -DZIMAGE
 
 # Supply kernel BSS size to the decompressor via a linker symbol.
 KBSS_SZ = $(shell echo $$(($$($(NM) $(obj)/../../../../vmlinux | \
-		sed -n -e 's/^\([^ ]*\) [AB] __bss_start$$/-0x\1/p' \
-		       -e 's/^\([^ ]*\) [AB] __bss_stop$$/+0x\1/p') )) )
+		sed -n -e 's/^\([^ ]*\) [ABD] __bss_start$$/-0x\1/p' \
+		       -e 's/^\([^ ]*\) [ABD] __bss_stop$$/+0x\1/p') )) )
 LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
 # Supply ZRELADDR to the decompressor via a linker symbol.
 ifneq ($(CONFIG_AUTO_ZRELADDR),y)
-- 
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] 7+ messages in thread

* Re: [PATCH] ARM: decompressor: fix BSS size calculation for LLVM ld.lld
  2021-02-05  8:52 [PATCH] ARM: decompressor: fix BSS size calculation for LLVM ld.lld Ard Biesheuvel
@ 2021-02-05 18:00 ` Nick Desaulniers
  2021-02-05 18:11   ` Ard Biesheuvel
  0 siblings, 1 reply; 7+ messages in thread
From: Nick Desaulniers @ 2021-02-05 18:00 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Fangrui Song, Guillaume Tucker, Russell King, Nathan Chancellor,
	clang-built-linux, Linux ARM

On Fri, Feb 5, 2021 at 12:52 AM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> The LLVM ld.lld linker uses a different symbol type for __bss_start,
> resulting in the calculation of KBSS_SZ to be thrown off. Up until now,
> this has gone unnoticed as it only affects the appended DTB case, but
> pending changes for ARM in the way the decompressed kernel is cleaned
> from the caches has uncovered this problem.
>
> On a ld.lld build:
>
>   $ nm vmlinux |grep bss_
>   c1c22034 D __bss_start
>   c1c86e98 B __bss_stop
>
> resulting in
>

$ readelf -s arch/arm/boot/compressed/vmlinux | grep bss_size

>   433: c1c86e98     0 NOTYPE  GLOBAL DEFAULT  ABS _kernel_bss_size
>
> which is obviously incorrect, and may cause the cache clean to access
> unmapped memory, or cause the size calculation to wrap, resulting in no
> cache clean to be performed at all.
>
> Fix this by updating the sed regex to take D type symbols into account.
>
> Cc: Nick Desaulniers <ndesaulniers@google.com>
> Cc: Nathan Chancellor <nathan@kernel.org>
> Cc: Guillaume Tucker <guillaume.tucker@collabora.com>
> Link: https://lore.kernel.org/linux-arm-kernel/6c65bcef-d4e7-25fa-43cf-2c435bb61bb9@collabora.com/
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>


Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>

Thanks for debugging+fixing this, and Guillaume for the report.  It's
nice to see a fix so early; thinking back to last year before KernelCI
integration, we probably would have only noticed when CrOS went to
upgrade their rk3288 platform devices.

Some other tags that might be nice to apply:

Cc: stable@kernel.org
Fixes: 429f7a062e3b ("ARM: decompressor: fix BSS size calculation")
Reported-by: Guillaume Tucker <guillaume.tucker@collabora.com>
Reported-by: "kernelci.org bot" <bot@kernelci.org>

Tests run:

Before (LLD):
$ llvm-nm vmlinux | grep bss_
c1c1a3fc D __bss_start
c1c7e998 B __bss_stop
$ llvm-readelf -s arch/arm/boot/compressed/vmlinux | grep bss_size
   440: c1c7e998     0 NOTYPE  GLOBAL DEFAULT   ABS _kernel_bss_size

After (LLD):
$ llvm-nm vmlinux | grep bss_
c1c1a3fc D __bss_start
c1c7e998 B __bss_stop
$ llvm-readelf -s arch/arm/boot/compressed/vmlinux | grep bss_size
   440: 0006459c     0 NOTYPE  GLOBAL DEFAULT   ABS _kernel_bss_size

Before (BFD):
$ llvm-nm vmlinux | grep bss_
c1c1a3fc B __bss_start
c1c7e998 B __bss_stop
$ llvm-readelf -s arch/arm/boot/compressed/vmlinux | grep bss_size
   463: 0006459c     0 NOTYPE  GLOBAL DEFAULT   ABS _kernel_bss_size

After (BFD):
$ llvm-nm vmlinux | grep bss_
c1c1a3fc B __bss_start
c1c7e998 B __bss_stop
$ llvm-readelf -s arch/arm/boot/compressed/vmlinux | grep bss_size
   463: 0006459c     0 NOTYPE  GLOBAL DEFAULT   ABS _kernel_bss_size

+ Fangrui,
Fangrui, __bss_start looks like it's linker script defined by the
BSS_SECTION macro from include/asm-generic/vmlinux.lds.h:1160 being
used in arch/arm/kernel/vmlinux.lds.S:149.  Should these symbols be
placed in .bss? Might save a few bytes in the image, unless there's an
initial value that's encoded with them?

> ---
>  arch/arm/boot/compressed/Makefile | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
> index fb521efcc6c2..54307db7854d 100644
> --- a/arch/arm/boot/compressed/Makefile
> +++ b/arch/arm/boot/compressed/Makefile
> @@ -115,8 +115,8 @@ asflags-y := -DZIMAGE
>
>  # Supply kernel BSS size to the decompressor via a linker symbol.
>  KBSS_SZ = $(shell echo $$(($$($(NM) $(obj)/../../../../vmlinux | \
> -               sed -n -e 's/^\([^ ]*\) [AB] __bss_start$$/-0x\1/p' \
> -                      -e 's/^\([^ ]*\) [AB] __bss_stop$$/+0x\1/p') )) )
> +               sed -n -e 's/^\([^ ]*\) [ABD] __bss_start$$/-0x\1/p' \
> +                      -e 's/^\([^ ]*\) [ABD] __bss_stop$$/+0x\1/p') )) )

I wasn't sure whether we still needed `A`, but
commit 6cea14f55474 ("ARM: replace unnecessary perl with sed and the
shell $(( )) operator")
references that depending on the version of binutils you might observe
that.  There's no more info on which version or under what conditions.
Lest we reintroduce this same problem for that version, it's fine to
leave it.

>  LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
>  # Supply ZRELADDR to the decompressor via a linker symbol.
>  ifneq ($(CONFIG_AUTO_ZRELADDR),y)
> --
> 2.30.0
>


-- 
Thanks,
~Nick Desaulniers

_______________________________________________
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] 7+ messages in thread

* Re: [PATCH] ARM: decompressor: fix BSS size calculation for LLVM ld.lld
  2021-02-05 18:00 ` Nick Desaulniers
@ 2021-02-05 18:11   ` Ard Biesheuvel
  2021-02-05 18:33     ` Fangrui Song
                       ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Ard Biesheuvel @ 2021-02-05 18:11 UTC (permalink / raw)
  To: Nick Desaulniers
  Cc: Fangrui Song, Guillaume Tucker, Russell King, Nathan Chancellor,
	clang-built-linux, Linux ARM

On Fri, 5 Feb 2021 at 19:00, Nick Desaulniers <ndesaulniers@google.com> wrote:
>
> On Fri, Feb 5, 2021 at 12:52 AM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > The LLVM ld.lld linker uses a different symbol type for __bss_start,
> > resulting in the calculation of KBSS_SZ to be thrown off. Up until now,
> > this has gone unnoticed as it only affects the appended DTB case, but
> > pending changes for ARM in the way the decompressed kernel is cleaned
> > from the caches has uncovered this problem.
> >
> > On a ld.lld build:
> >
> >   $ nm vmlinux |grep bss_
> >   c1c22034 D __bss_start
> >   c1c86e98 B __bss_stop
> >
> > resulting in
> >
>
> $ readelf -s arch/arm/boot/compressed/vmlinux | grep bss_size
>
> >   433: c1c86e98     0 NOTYPE  GLOBAL DEFAULT  ABS _kernel_bss_size
> >
> > which is obviously incorrect, and may cause the cache clean to access
> > unmapped memory, or cause the size calculation to wrap, resulting in no
> > cache clean to be performed at all.
> >
> > Fix this by updating the sed regex to take D type symbols into account.
> >
> > Cc: Nick Desaulniers <ndesaulniers@google.com>
> > Cc: Nathan Chancellor <nathan@kernel.org>
> > Cc: Guillaume Tucker <guillaume.tucker@collabora.com>
> > Link: https://lore.kernel.org/linux-arm-kernel/6c65bcef-d4e7-25fa-43cf-2c435bb61bb9@collabora.com/
> > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
>
>
> Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
> Tested-by: Nick Desaulniers <ndesaulniers@google.com>
>
> Thanks for debugging+fixing this, and Guillaume for the report.  It's
> nice to see a fix so early; thinking back to last year before KernelCI
> integration, we probably would have only noticed when CrOS went to
> upgrade their rk3288 platform devices.
>
> Some other tags that might be nice to apply:
>
> Cc: stable@kernel.org
> Fixes: 429f7a062e3b ("ARM: decompressor: fix BSS size calculation")
> Reported-by: Guillaume Tucker <guillaume.tucker@collabora.com>
> Reported-by: "kernelci.org bot" <bot@kernelci.org>
>

Thanks. I'll add these tags and drop this patch into the patch system

> Tests run:
>
...
>
> + Fangrui,
> Fangrui, __bss_start looks like it's linker script defined by the
> BSS_SECTION macro from include/asm-generic/vmlinux.lds.h:1160 being
> used in arch/arm/kernel/vmlinux.lds.S:149.  Should these symbols be
> placed in .bss? Might save a few bytes in the image, unless there's an
> initial value that's encoded with them?
>

Not sure what you are asking here. These symbols just delineate .bss,
they don't take up any space themselves.

What seems to be happening is that the placement of __bss_start
outside of the .sbss/.bss section declarations causes it to be
annotated as residing in .data.


> > ---
> >  arch/arm/boot/compressed/Makefile | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
> > index fb521efcc6c2..54307db7854d 100644
> > --- a/arch/arm/boot/compressed/Makefile
> > +++ b/arch/arm/boot/compressed/Makefile
> > @@ -115,8 +115,8 @@ asflags-y := -DZIMAGE
> >
> >  # Supply kernel BSS size to the decompressor via a linker symbol.
> >  KBSS_SZ = $(shell echo $$(($$($(NM) $(obj)/../../../../vmlinux | \
> > -               sed -n -e 's/^\([^ ]*\) [AB] __bss_start$$/-0x\1/p' \
> > -                      -e 's/^\([^ ]*\) [AB] __bss_stop$$/+0x\1/p') )) )
> > +               sed -n -e 's/^\([^ ]*\) [ABD] __bss_start$$/-0x\1/p' \
> > +                      -e 's/^\([^ ]*\) [ABD] __bss_stop$$/+0x\1/p') )) )
>
> I wasn't sure whether we still needed `A`, but
> commit 6cea14f55474 ("ARM: replace unnecessary perl with sed and the
> shell $(( )) operator")
> references that depending on the version of binutils you might observe
> that.  There's no more info on which version or under what conditions.
> Lest we reintroduce this same problem for that version, it's fine to
> leave it.
>

Agreed.

> >  LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
> >  # Supply ZRELADDR to the decompressor via a linker symbol.
> >  ifneq ($(CONFIG_AUTO_ZRELADDR),y)
> > --
> > 2.30.0
> >
>
>
> --
> Thanks,
> ~Nick Desaulniers

_______________________________________________
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] 7+ messages in thread

* Re: [PATCH] ARM: decompressor: fix BSS size calculation for LLVM ld.lld
  2021-02-05 18:11   ` Ard Biesheuvel
@ 2021-02-05 18:33     ` Fangrui Song
  2021-02-05 18:55     ` Nick Desaulniers
  2021-02-06 13:16     ` Guillaume Tucker
  2 siblings, 0 replies; 7+ messages in thread
From: Fangrui Song @ 2021-02-05 18:33 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Guillaume Tucker, Nick Desaulniers, Russell King,
	Nathan Chancellor, clang-built-linux, Linux ARM

On 2021-02-05, Ard Biesheuvel wrote:
>On Fri, 5 Feb 2021 at 19:00, Nick Desaulniers <ndesaulniers@google.com> wrote:
>>
>> On Fri, Feb 5, 2021 at 12:52 AM Ard Biesheuvel <ardb@kernel.org> wrote:
>> >
>> > The LLVM ld.lld linker uses a different symbol type for __bss_start,
>> > resulting in the calculation of KBSS_SZ to be thrown off. Up until now,
>> > this has gone unnoticed as it only affects the appended DTB case, but
>> > pending changes for ARM in the way the decompressed kernel is cleaned
>> > from the caches has uncovered this problem.
>> >
>> > On a ld.lld build:
>> >
>> >   $ nm vmlinux |grep bss_
>> >   c1c22034 D __bss_start
>> >   c1c86e98 B __bss_stop
>> >
>> > resulting in
>> >
>>
>> $ readelf -s arch/arm/boot/compressed/vmlinux | grep bss_size
>>
>> >   433: c1c86e98     0 NOTYPE  GLOBAL DEFAULT  ABS _kernel_bss_size
>> >
>> > which is obviously incorrect, and may cause the cache clean to access
>> > unmapped memory, or cause the size calculation to wrap, resulting in no
>> > cache clean to be performed at all.
>> >
>> > Fix this by updating the sed regex to take D type symbols into account.
>> >
>> > Cc: Nick Desaulniers <ndesaulniers@google.com>
>> > Cc: Nathan Chancellor <nathan@kernel.org>
>> > Cc: Guillaume Tucker <guillaume.tucker@collabora.com>
>> > Link: https://lore.kernel.org/linux-arm-kernel/6c65bcef-d4e7-25fa-43cf-2c435bb61bb9@collabora.com/
>> > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
>>
>>
>> Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
>> Tested-by: Nick Desaulniers <ndesaulniers@google.com>
>>
>> Thanks for debugging+fixing this, and Guillaume for the report.  It's
>> nice to see a fix so early; thinking back to last year before KernelCI
>> integration, we probably would have only noticed when CrOS went to
>> upgrade their rk3288 platform devices.
>>
>> Some other tags that might be nice to apply:
>>
>> Cc: stable@kernel.org
>> Fixes: 429f7a062e3b ("ARM: decompressor: fix BSS size calculation")
>> Reported-by: Guillaume Tucker <guillaume.tucker@collabora.com>
>> Reported-by: "kernelci.org bot" <bot@kernelci.org>
>>
>
>Thanks. I'll add these tags and drop this patch into the patch system
>
>> Tests run:
>>
>...
>>
>> + Fangrui,
>> Fangrui, __bss_start looks like it's linker script defined by the
>> BSS_SECTION macro from include/asm-generic/vmlinux.lds.h:1160 being
>> used in arch/arm/kernel/vmlinux.lds.S:149.  Should these symbols be
>> placed in .bss? Might save a few bytes in the image, unless there's an
>> initial value that's encoded with them?
>>
>
>Not sure what you are asking here. These symbols just delineate .bss,
>they don't take up any space themselves.
>
>What seems to be happening is that the placement of __bss_start
>outside of the .sbss/.bss section declarations causes it to be
>annotated as residing in .data.

In my build (make -sk -j 50 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- LLVM=1 O=/tmp/out/arm -j 50 defconfig vmlinux), vmlinux has:

   [34] .data..percpu     PROGBITS        c195f000 151f000 00c20c 00  WA  0   0 64
   [35] .data             PROGBITS        c1a00000 1530000 217914 00  WA  0   0 4096
   [36] __bug_table       PROGBITS        c1c17918 1747918 00a5cc 00  WA  0   0  4
   [37] .sbss             PROGBITS        c1c21ee4 1751ee4 000000 00  WA  0   0  1
   [38] .bss              NOBITS          c1c21f00 1751f00 063f98 00  WA  0   0 64

__bss_start is defined relative to __bug_table.
The issue is that __bss_start is defined outside of the output section description of .bss,
so its st_shndx (section) is not guaranteed.

I noticed that many linker script fragments used by the kernel have similar problems.
The delineating symbols are defined outside of output sections. With ld --orphan-handling=,
we can somewhat guarantee there are no undesired interleaving sections, but it is hard to
ensure their st_shndx values.

>
>> > ---
>> >  arch/arm/boot/compressed/Makefile | 4 ++--
>> >  1 file changed, 2 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
>> > index fb521efcc6c2..54307db7854d 100644
>> > --- a/arch/arm/boot/compressed/Makefile
>> > +++ b/arch/arm/boot/compressed/Makefile
>> > @@ -115,8 +115,8 @@ asflags-y := -DZIMAGE
>> >
>> >  # Supply kernel BSS size to the decompressor via a linker symbol.
>> >  KBSS_SZ = $(shell echo $$(($$($(NM) $(obj)/../../../../vmlinux | \
>> > -               sed -n -e 's/^\([^ ]*\) [AB] __bss_start$$/-0x\1/p' \
>> > -                      -e 's/^\([^ ]*\) [AB] __bss_stop$$/+0x\1/p') )) )
>> > +               sed -n -e 's/^\([^ ]*\) [ABD] __bss_start$$/-0x\1/p' \
>> > +                      -e 's/^\([^ ]*\) [ABD] __bss_stop$$/+0x\1/p') )) )
>>
>> I wasn't sure whether we still needed `A`, but
>> commit 6cea14f55474 ("ARM: replace unnecessary perl with sed and the
>> shell $(( )) operator")
>> references that depending on the version of binutils you might observe
>> that.  There's no more info on which version or under what conditions.
>> Lest we reintroduce this same problem for that version, it's fine to
>> leave it.
>>

In my observation a symbol may be SHN_ABS (nm key 'A') if it is

* defined by --defsym
* a symbol assignment outside of output sections in -no-pie link mode

>Agreed.
>
>> >  LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
>> >  # Supply ZRELADDR to the decompressor via a linker symbol.
>> >  ifneq ($(CONFIG_AUTO_ZRELADDR),y)
>> > --
>> > 2.30.0
>> >
>>
>>
>> --
>> Thanks,
>> ~Nick Desaulniers

_______________________________________________
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] 7+ messages in thread

* Re: [PATCH] ARM: decompressor: fix BSS size calculation for LLVM ld.lld
  2021-02-05 18:11   ` Ard Biesheuvel
  2021-02-05 18:33     ` Fangrui Song
@ 2021-02-05 18:55     ` Nick Desaulniers
  2021-02-06 13:31       ` Ard Biesheuvel
  2021-02-06 13:16     ` Guillaume Tucker
  2 siblings, 1 reply; 7+ messages in thread
From: Nick Desaulniers @ 2021-02-05 18:55 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Fangrui Song, Guillaume Tucker, Russell King, Nathan Chancellor,
	clang-built-linux, Linux ARM

On Fri, Feb 5, 2021 at 10:11 AM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Fri, 5 Feb 2021 at 19:00, Nick Desaulniers <ndesaulniers@google.com> wrote:
> >
> > On Fri, Feb 5, 2021 at 12:52 AM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > The LLVM ld.lld linker uses a different symbol type for __bss_start,
> > > resulting in the calculation of KBSS_SZ to be thrown off. Up until now,
> > > this has gone unnoticed as it only affects the appended DTB case, but
> > > pending changes for ARM in the way the decompressed kernel is cleaned
> > > from the caches has uncovered this problem.
> > >
> > > On a ld.lld build:
> > >
> > >   $ nm vmlinux |grep bss_
> > >   c1c22034 D __bss_start
> > >   c1c86e98 B __bss_stop
> > >
> > + Fangrui,
> > Fangrui, __bss_start looks like it's linker script defined by the
> > BSS_SECTION macro from include/asm-generic/vmlinux.lds.h:1160 being
> > used in arch/arm/kernel/vmlinux.lds.S:149.  Should these symbols be
> > placed in .bss? Might save a few bytes in the image, unless there's an
> > initial value that's encoded with them?
> >
>
> Not sure what you are asking here. These symbols just delineate .bss,
> they don't take up any space themselves.
>
> What seems to be happening is that the placement of __bss_start
> outside of the .sbss/.bss section declarations causes it to be
> annotated as residing in .data.

Perhaps a misunderstanding on my part on how symbols are represented
in ELF, but my understanding is:

$ cat foo.c
int foo;
int bar = 0;
int baz = 42;
$ cc -c foo.c
$ nm foo.o
0000000000000004 B bar
0000000000000000 D baz
0000000000000000 B foo
$ ls -l foo.o
-rw-r----- 1 ndesaulniers primarygroup 1016 Feb  5 10:47 foo.o

$ cat bar.c
int foo;
int bar = 0;
int baz = 0; // changed from foo.c
$ cc -c bar.o
$ nm bar.o
0000000000000004 B bar
0000000000000008 B baz
0000000000000000 B foo
$ ls -l bar.o
-rw-r----- 1 ndesaulniers primarygroup 1008 Feb  5 10:48 bar.o
# ^ smaller object file

That if a symbol's value was an address within .bss, then there was no
additional space reserved in an ELF object since the initial value for
all such symbols in the section can memset to 0 by the loader.  But if
a symbol's value was an address in .data, that initial value must
occupy space in the object file.  Perhaps that's not the case though
for linker defined symbols, since I'm not sure what data/initial value
they would correspond to besides the Elf{32|64}_Sym's value in the
symbol table?  (I should go reread the relevant section from Expert C
Programming: Deep C Secrets, or finish reading Linkers and Loaders).
-- 
Thanks,
~Nick Desaulniers

_______________________________________________
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] 7+ messages in thread

* Re: [PATCH] ARM: decompressor: fix BSS size calculation for LLVM ld.lld
  2021-02-05 18:11   ` Ard Biesheuvel
  2021-02-05 18:33     ` Fangrui Song
  2021-02-05 18:55     ` Nick Desaulniers
@ 2021-02-06 13:16     ` Guillaume Tucker
  2 siblings, 0 replies; 7+ messages in thread
From: Guillaume Tucker @ 2021-02-06 13:16 UTC (permalink / raw)
  To: Ard Biesheuvel, Nick Desaulniers
  Cc: Nathan Chancellor, clang-built-linux, Russell King, Linux ARM,
	Fangrui Song

On 05/02/2021 18:11, Ard Biesheuvel wrote:
> On Fri, 5 Feb 2021 at 19:00, Nick Desaulniers <ndesaulniers@google.com> wrote:
>>
>> On Fri, Feb 5, 2021 at 12:52 AM Ard Biesheuvel <ardb@kernel.org> wrote:
>>>
>>> The LLVM ld.lld linker uses a different symbol type for __bss_start,
>>> resulting in the calculation of KBSS_SZ to be thrown off. Up until now,
>>> this has gone unnoticed as it only affects the appended DTB case, but
>>> pending changes for ARM in the way the decompressed kernel is cleaned
>>> from the caches has uncovered this problem.
>>>
>>> On a ld.lld build:
>>>
>>>   $ nm vmlinux |grep bss_
>>>   c1c22034 D __bss_start
>>>   c1c86e98 B __bss_stop
>>>
>>> resulting in
>>>
>>
>> $ readelf -s arch/arm/boot/compressed/vmlinux | grep bss_size
>>
>>>   433: c1c86e98     0 NOTYPE  GLOBAL DEFAULT  ABS _kernel_bss_size
>>>
>>> which is obviously incorrect, and may cause the cache clean to access
>>> unmapped memory, or cause the size calculation to wrap, resulting in no
>>> cache clean to be performed at all.
>>>
>>> Fix this by updating the sed regex to take D type symbols into account.
>>>
>>> Cc: Nick Desaulniers <ndesaulniers@google.com>
>>> Cc: Nathan Chancellor <nathan@kernel.org>
>>> Cc: Guillaume Tucker <guillaume.tucker@collabora.com>
>>> Link: https://lore.kernel.org/linux-arm-kernel/6c65bcef-d4e7-25fa-43cf-2c435bb61bb9@collabora.com/
>>> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
>>
>>
>> Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
>> Tested-by: Nick Desaulniers <ndesaulniers@google.com>
>>
>> Thanks for debugging+fixing this, and Guillaume for the report.  It's
>> nice to see a fix so early; thinking back to last year before KernelCI
>> integration, we probably would have only noticed when CrOS went to
>> upgrade their rk3288 platform devices.
>>
>> Some other tags that might be nice to apply:
>>
>> Cc: stable@kernel.org
>> Fixes: 429f7a062e3b ("ARM: decompressor: fix BSS size calculation")
>> Reported-by: Guillaume Tucker <guillaume.tucker@collabora.com>
>> Reported-by: "kernelci.org bot" <bot@kernelci.org>
>>
> 
> Thanks. I'll add these tags and drop this patch into the patch system

Thanks!  You may even add:

  Tested-by: "kernelci.org bot" <bot@kernelci.org>

See some results here, showing it's all booting fine:

  https://staging.kernelci.org/test/job/ardb/branch/for-kernelci/kernel/v5.11-rc6-146-g923ca344043a/plan/baseline/

with this revision from your for-kernelci branch:

  https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/commit/?id=923ca344043a19067c21f46bd8649f35f61ce920

Best wishes,
Guillaume

_______________________________________________
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] 7+ messages in thread

* Re: [PATCH] ARM: decompressor: fix BSS size calculation for LLVM ld.lld
  2021-02-05 18:55     ` Nick Desaulniers
@ 2021-02-06 13:31       ` Ard Biesheuvel
  0 siblings, 0 replies; 7+ messages in thread
From: Ard Biesheuvel @ 2021-02-06 13:31 UTC (permalink / raw)
  To: Nick Desaulniers
  Cc: Fangrui Song, Guillaume Tucker, Russell King, Nathan Chancellor,
	clang-built-linux, Linux ARM

On Fri, 5 Feb 2021 at 19:56, Nick Desaulniers <ndesaulniers@google.com> wrote:
>
> On Fri, Feb 5, 2021 at 10:11 AM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Fri, 5 Feb 2021 at 19:00, Nick Desaulniers <ndesaulniers@google.com> wrote:
> > >
> > > On Fri, Feb 5, 2021 at 12:52 AM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > >
> > > > The LLVM ld.lld linker uses a different symbol type for __bss_start,
> > > > resulting in the calculation of KBSS_SZ to be thrown off. Up until now,
> > > > this has gone unnoticed as it only affects the appended DTB case, but
> > > > pending changes for ARM in the way the decompressed kernel is cleaned
> > > > from the caches has uncovered this problem.
> > > >
> > > > On a ld.lld build:
> > > >
> > > >   $ nm vmlinux |grep bss_
> > > >   c1c22034 D __bss_start
> > > >   c1c86e98 B __bss_stop
> > > >
> > > + Fangrui,
> > > Fangrui, __bss_start looks like it's linker script defined by the
> > > BSS_SECTION macro from include/asm-generic/vmlinux.lds.h:1160 being
> > > used in arch/arm/kernel/vmlinux.lds.S:149.  Should these symbols be
> > > placed in .bss? Might save a few bytes in the image, unless there's an
> > > initial value that's encoded with them?
> > >
> >
> > Not sure what you are asking here. These symbols just delineate .bss,
> > they don't take up any space themselves.
> >
> > What seems to be happening is that the placement of __bss_start
> > outside of the .sbss/.bss section declarations causes it to be
> > annotated as residing in .data.
>
> Perhaps a misunderstanding on my part on how symbols are represented
> in ELF, but my understanding is:
>
> $ cat foo.c
> int foo;
> int bar = 0;
> int baz = 42;
> $ cc -c foo.c
> $ nm foo.o
> 0000000000000004 B bar
> 0000000000000000 D baz
> 0000000000000000 B foo
> $ ls -l foo.o
> -rw-r----- 1 ndesaulniers primarygroup 1016 Feb  5 10:47 foo.o
>
> $ cat bar.c
> int foo;
> int bar = 0;
> int baz = 0; // changed from foo.c
> $ cc -c bar.o
> $ nm bar.o
> 0000000000000004 B bar
> 0000000000000008 B baz
> 0000000000000000 B foo
> $ ls -l bar.o
> -rw-r----- 1 ndesaulniers primarygroup 1008 Feb  5 10:48 bar.o
> # ^ smaller object file
>
> That if a symbol's value was an address within .bss, then there was no
> additional space reserved in an ELF object since the initial value for
> all such symbols in the section can memset to 0 by the loader.  But if
> a symbol's value was an address in .data, that initial value must
> occupy space in the object file.  Perhaps that's not the case though
> for linker defined symbols, since I'm not sure what data/initial value
> they would correspond to besides the Elf{32|64}_Sym's value in the
> symbol table?  (I should go reread the relevant section from Expert C
> Programming: Deep C Secrets, or finish reading Linkers and Loaders).

A symbol defined in C allocates space in the binary (either in .data
or in .bss), along with a symbol to refer to it.

A linker defined symbol such as __bss_start is just a pointer into the
binary. It will alias with whichever C variable ended up at offset 0x0
in the section. Remember that clearing [__bss_start, __bss_end] in the
startup code is what initializes those variables to zero.

_______________________________________________
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] 7+ messages in thread

end of thread, other threads:[~2021-02-06 13:33 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-05  8:52 [PATCH] ARM: decompressor: fix BSS size calculation for LLVM ld.lld Ard Biesheuvel
2021-02-05 18:00 ` Nick Desaulniers
2021-02-05 18:11   ` Ard Biesheuvel
2021-02-05 18:33     ` Fangrui Song
2021-02-05 18:55     ` Nick Desaulniers
2021-02-06 13:31       ` Ard Biesheuvel
2021-02-06 13:16     ` Guillaume Tucker

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.