Re: [PATCH 4/5] powerpc: Make the 64-bit kernel as a position-independent executable

2008-10-09 Thread Grant Likely
On Fri, Sep 26, 2008 at 6:10 PM, Remi Machet <[EMAIL PROTECTED]> wrote:
> Hi Paul,
>
> This patch breaks my build with the following error:
>
> /u1/rmachet/projects/c2k/linux-powerpc-git $ make cuImage.c2k modules 
> ARCH=powerpc V=1
> ...
>  powerpc-linux-gnu-ld -m elf32ppc  -Bstatic  -o .tmp_vmlinux1 -T 
> arch/powerpc/kernel/vmlinux.lds arch/powerpc/kernel/head_32.o 
> arch/powerpc/kernel/fpu.o  init/built-in.o --start-group  usr/built-in.o  
> arch/powerpc/kernel/built-in.o  arch/powerpc/mm/built-in.o  
> arch/powerpc/lib/built-in.o  arch/powerpc/sysdev/built-in.o  
> arch/powerpc/platforms/built-in.o  kernel/built-in.o  mm/built-in.o  
> fs/built-in.o  ipc/built-in.o  security/built-in.o  crypto/built-in.o  
> block/built-in.o  lib/lib.a  lib/built-in.o  drivers/built-in.o  
> sound/built-in.o  firmware/built-in.o  net/built-in.o --end-group
> powerpc-linux-gnu-ld: BFD 2.16.1 internal error, aborting at 
> /u1/rmachet/project/crosstool/crosstool-0.43/build/powerpc-linux-gnu/gcc-4.1.1-glibc-2.3.6/binutils-2.16.1/bfd/elflink.c
>  line 6419 in elf_link_output_extsym
>
> powerpc-linux-gnu-ld: Please report this bug.

I can confirm this problem.  This patch breaks builds using binutils
2.16.1.  It definitely looks like a binutils bug.  It builds fine with
2.17.

>
> I isolated the problem to line 202 in arch/powerpc/kernel/vmlinux.lds.S: If I 
> remove that
> line then the kernel builds and run fine on my board (a PowerPC 32bits c2k).
> For reference the line is:
>
>.rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET)
>{
> 202->   __rela_dyn_start = .;
>*(.rela*)
>}

There are still a lot of embedded developers using 2.16.1 binutils in
their toolchains so I think that this needs to be worked around.
Otherwise we'll see lots of complaints when this gets merged into
mainline.  However, I haven't figured out a workaround yet.  Looking
at the binutils sourcecode doesn't reveal anything obvious, but it's
too late for my brain to work properly.  Anyone else have any ideas?

g.


-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH 4/5] powerpc: Make the 64-bit kernel as a position-independent executable

2008-09-26 Thread Remi Machet
Hi Paul,

This patch breaks my build with the following error:

/u1/rmachet/projects/c2k/linux-powerpc-git $ make cuImage.c2k modules 
ARCH=powerpc V=1
...
  powerpc-linux-gnu-ld -m elf32ppc  -Bstatic  -o .tmp_vmlinux1 -T 
arch/powerpc/kernel/vmlinux.lds arch/powerpc/kernel/head_32.o 
arch/powerpc/kernel/fpu.o  init/built-in.o --start-group  usr/built-in.o  
arch/powerpc/kernel/built-in.o  arch/powerpc/mm/built-in.o  
arch/powerpc/lib/built-in.o  arch/powerpc/sysdev/built-in.o  
arch/powerpc/platforms/built-in.o  kernel/built-in.o  mm/built-in.o  
fs/built-in.o  ipc/built-in.o  security/built-in.o  crypto/built-in.o  
block/built-in.o  lib/lib.a  lib/built-in.o  drivers/built-in.o  
sound/built-in.o  firmware/built-in.o  net/built-in.o --end-group
powerpc-linux-gnu-ld: BFD 2.16.1 internal error, aborting at 
/u1/rmachet/project/crosstool/crosstool-0.43/build/powerpc-linux-gnu/gcc-4.1.1-glibc-2.3.6/binutils-2.16.1/bfd/elflink.c
 line 6419 in elf_link_output_extsym

powerpc-linux-gnu-ld: Please report this bug.


I isolated the problem to line 202 in arch/powerpc/kernel/vmlinux.lds.S: If I 
remove that
line then the kernel builds and run fine on my board (a PowerPC 32bits c2k).
For reference the line is:

.rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET)
{
202->   __rela_dyn_start = .;
*(.rela*)
}

Any idea of what cause this crash? I strongly suspect this is a binutils 2.16.1 
bug 
that was fixed later but since it may affect other people I just wanted to let 
you and 
the list know.

Remi


On Sat, 2008-08-30 at 11:43 +1000, Paul Mackerras wrote:
> This implements CONFIG_RELOCATABLE for 64-bit by making the kernel as
> a position-independent executable (PIE) when it is set.  This involves
> processing the dynamic relocations in the image in the early stages of
> booting, even if the kernel is being run at the address it is linked at,
> since the linker does not necessarily fill in words in the image for
> which there are dynamic relocations.  (In fact the linker does fill in
> such words for 64-bit executables, though not for 32-bit executables,
> so in principle we could avoid calling relocate() entirely when we're
> running a 64-bit kernel at the linked address.)
> 
> The dynamic relocations are processed by a new function relocate(addr),
> where the addr parameter is the virtual address where the image will be
> run.  In fact we call it twice; once before calling prom_init, and again
> when starting the main kernel.  This means that reloc_offset() returns
> 0 in prom_init (since it has been relocated to the address it is running
> at), which necessitated a few adjustments.
> 
> This also changes __va and __pa to use an equivalent definition that is
> simpler.  With the relocatable kernel, PAGE_OFFSET and MEMORY_START are
> constants (for 64-bit) whereas PHYSICAL_START is a variable (and
> KERNELBASE ideally should be too, but isn't yet).
> 
> With this, relocatable kernels still copy themselves down to physical
> address 0 and run there.
> 
> Signed-off-by: Paul Mackerras <[EMAIL PROTECTED]>
> ---
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 587da5e..17c988b 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -806,6 +806,19 @@ config PIN_TLB
>  endmenu
>  
>  if PPC64
> +config RELOCATABLE
> + bool "Build a relocatable kernel"
> + help
> +   This builds a kernel image that is capable of running anywhere
> +   in the RMA (real memory area) at any 16k-aligned base address.
> +   The kernel is linked as a position-independent executable (PIE)
> +   and contains dynamic relocations which are processed early
> +   in the bootup process.
> +
> +   One use is for the kexec on panic case where the recovery kernel
> +   must live at a different physical address than the primary
> +   kernel.
> +
>  config PAGE_OFFSET
>   hex
>   default "0xc000"
> diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
> index 9155c93..14c86fe 100644
> --- a/arch/powerpc/Makefile
> +++ b/arch/powerpc/Makefile
> @@ -63,7 +63,9 @@ override CC += -m$(CONFIG_WORD_SIZE)
>  override AR  := GNUTARGET=elf$(CONFIG_WORD_SIZE)-powerpc $(AR)
>  endif
>  
> -LDFLAGS_vmlinux  := -Bstatic
> +LDFLAGS_vmlinux-yy := -Bstatic
> +LDFLAGS_vmlinux-$(CONFIG_PPC64)$(CONFIG_RELOCATABLE) := -pie
> +LDFLAGS_vmlinux  := $(LDFLAGS_vmlinux-yy)
>  
>  CFLAGS-$(CONFIG_PPC64)   := -mminimal-toc -mtraceback=none  
> -mcall-aixdesc
>  CFLAGS-$(CONFIG_PPC32)   := -ffixed-r2 -mmultiple
> diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
> index 14174aa..9109e1f 100644
> --- a/arch/powerpc/boot/Makefile
> +++ b/arch/powerpc/boot/Makefile
> @@ -310,8 +310,11 @@ $(obj)/dtbImage.%: vmlinux $(wrapperbits) $(obj)/%.dtb
>  $(obj)/vmlinux.strip: vmlinux
>   $(STRIP) -s -R .comment $< -o $@
>  
> +# The iseries hypervisor won't take an ET_DYN executable, so this
> +# changes the type (byte 1

[PATCH 4/5] powerpc: Make the 64-bit kernel as a position-independent executable

2008-08-29 Thread Paul Mackerras
This implements CONFIG_RELOCATABLE for 64-bit by making the kernel as
a position-independent executable (PIE) when it is set.  This involves
processing the dynamic relocations in the image in the early stages of
booting, even if the kernel is being run at the address it is linked at,
since the linker does not necessarily fill in words in the image for
which there are dynamic relocations.  (In fact the linker does fill in
such words for 64-bit executables, though not for 32-bit executables,
so in principle we could avoid calling relocate() entirely when we're
running a 64-bit kernel at the linked address.)

The dynamic relocations are processed by a new function relocate(addr),
where the addr parameter is the virtual address where the image will be
run.  In fact we call it twice; once before calling prom_init, and again
when starting the main kernel.  This means that reloc_offset() returns
0 in prom_init (since it has been relocated to the address it is running
at), which necessitated a few adjustments.

This also changes __va and __pa to use an equivalent definition that is
simpler.  With the relocatable kernel, PAGE_OFFSET and MEMORY_START are
constants (for 64-bit) whereas PHYSICAL_START is a variable (and
KERNELBASE ideally should be too, but isn't yet).

With this, relocatable kernels still copy themselves down to physical
address 0 and run there.

Signed-off-by: Paul Mackerras <[EMAIL PROTECTED]>
---
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 587da5e..17c988b 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -806,6 +806,19 @@ config PIN_TLB
 endmenu
 
 if PPC64
+config RELOCATABLE
+   bool "Build a relocatable kernel"
+   help
+ This builds a kernel image that is capable of running anywhere
+ in the RMA (real memory area) at any 16k-aligned base address.
+ The kernel is linked as a position-independent executable (PIE)
+ and contains dynamic relocations which are processed early
+ in the bootup process.
+
+ One use is for the kexec on panic case where the recovery kernel
+ must live at a different physical address than the primary
+ kernel.
+
 config PAGE_OFFSET
hex
default "0xc000"
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 9155c93..14c86fe 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -63,7 +63,9 @@ override CC   += -m$(CONFIG_WORD_SIZE)
 override AR:= GNUTARGET=elf$(CONFIG_WORD_SIZE)-powerpc $(AR)
 endif
 
-LDFLAGS_vmlinux:= -Bstatic
+LDFLAGS_vmlinux-yy := -Bstatic
+LDFLAGS_vmlinux-$(CONFIG_PPC64)$(CONFIG_RELOCATABLE) := -pie
+LDFLAGS_vmlinux:= $(LDFLAGS_vmlinux-yy)
 
 CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=none  -mcall-aixdesc
 CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 14174aa..9109e1f 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -310,8 +310,11 @@ $(obj)/dtbImage.%: vmlinux $(wrapperbits) $(obj)/%.dtb
 $(obj)/vmlinux.strip: vmlinux
$(STRIP) -s -R .comment $< -o $@
 
+# The iseries hypervisor won't take an ET_DYN executable, so this
+# changes the type (byte 17) in the file to ET_EXEC (2).
 $(obj)/zImage.iseries: vmlinux
$(STRIP) -s -R .comment $< -o $@
+   printf "\x02" | dd of=$@ conv=notrunc bs=1 seek=17
 
 $(obj)/uImage: vmlinux $(wrapperbits)
$(call if_changed,wrap,uboot)
diff --git a/arch/powerpc/boot/elf_util.c b/arch/powerpc/boot/elf_util.c
index 7454aa4..1567a0c 100644
--- a/arch/powerpc/boot/elf_util.c
+++ b/arch/powerpc/boot/elf_util.c
@@ -27,7 +27,8 @@ int parse_elf64(void *hdr, struct elf_info *info)
  elf64->e_ident[EI_MAG3]  == ELFMAG3   &&
  elf64->e_ident[EI_CLASS] == ELFCLASS64&&
  elf64->e_ident[EI_DATA]  == ELFDATA2MSB   &&
- elf64->e_type== ET_EXEC   &&
+ (elf64->e_type== ET_EXEC ||
+  elf64->e_type== ET_DYN)  &&
  elf64->e_machine == EM_PPC64))
return 0;
 
@@ -58,7 +59,8 @@ int parse_elf32(void *hdr, struct elf_info *info)
  elf32->e_ident[EI_MAG3]  == ELFMAG3   &&
  elf32->e_ident[EI_CLASS] == ELFCLASS32&&
  elf32->e_ident[EI_DATA]  == ELFDATA2MSB   &&
- elf32->e_type== ET_EXEC   &&
+ (elf32->e_type== ET_EXEC ||
+  elf32->e_type== ET_DYN)  &&
  elf32->e_machine == EM_PPC))
return 0;
 
diff --git a/arch/powerpc/include/asm/mmu-hash64.h 
b/arch/powerpc/include/asm/mmu-hash64.h
index c2df53c..5a44174 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -437,7 +437,7 @@ typedef struct {
})
 #endif /* 1 */
 
-/* This is only valid for addresses >= KERNELBASE */
+/* This is

Re: [PATCH 4/5] powerpc: Make the 64-bit kernel as a position-independent executable

2008-08-19 Thread Paul Mackerras
Geert Uytterhoeven writes:

> This part broke ppc32:
> 
> | arch/powerpc/kernel/prom.c: In function 'early_init_devtree':
> | arch/powerpc/kernel/prom.c:1166: error: '__end_interrupts' undeclared 
> (first use in this function)
> | arch/powerpc/kernel/prom.c:1166: error: (Each undeclared identifier is 
> reported only once
> | arch/powerpc/kernel/prom.c:1166: error: for each function it appears in.)

I'm not totally surprised I broke ppc32 somewhere along the line
there. :)  I think we will end up with having to have a #ifdef
CONFIG_RELOCATABLE in there or maybe a test on PHYSICAL_START.  It
will depend a bit on whether we want to make relocatable 32-bit
kernels as PIEs as well.

Paul.
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH 4/5] powerpc: Make the 64-bit kernel as a position-independent executable

2008-08-19 Thread Geert Uytterhoeven
On Wed, 13 Aug 2008, Paul Mackerras wrote:
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -1163,7 +1163,9 @@ void __init early_init_devtree(void *params)
>   parse_early_param();
>  
>   /* Reserve LMB regions used by kernel, initrd, dt, etc... */
> - lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
> + lmb_reserve(0, __end_interrupts - _stext);
> + lmb_reserve(__pa(__end_interrupts),
> + klimit - (unsigned long)__end_interrupts);
>   reserve_kdump_trampoline();
>   reserve_crashkernel();
>   early_reserve_mem();

This part broke ppc32:

| arch/powerpc/kernel/prom.c: In function 'early_init_devtree':
| arch/powerpc/kernel/prom.c:1166: error: '__end_interrupts' undeclared (first 
use in this function)
| arch/powerpc/kernel/prom.c:1166: error: (Each undeclared identifier is 
reported only once
| arch/powerpc/kernel/prom.c:1166: error: for each function it appears in.)

After applying the patch below, I was able to build and boot a kernel for the
Sequoia.

Signed-off-by: Geert Uytterhoeven <[EMAIL PROTECTED]>
---
 arch/powerpc/kernel/prom.c |4 
 1 file changed, 4 insertions(+)

--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1163,9 +1163,13 @@ void __init early_init_devtree(void *par
parse_early_param();
 
/* Reserve LMB regions used by kernel, initrd, dt, etc... */
+#ifdef CONFIG_PPC64
lmb_reserve(0, __end_interrupts - _stext);
lmb_reserve(__pa(__end_interrupts),
klimit - (unsigned long)__end_interrupts);
+#else
+   lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
+#endif
reserve_kdump_trampoline();
reserve_crashkernel();
early_reserve_mem();

With kind regards,

Geert Uytterhoeven
Software Architect

Sony Techsoft Centre Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium

Phone:+32 (0)2 700 8453
Fax:  +32 (0)2 700 8622
E-mail:   [EMAIL PROTECTED]
Internet: http://www.sony-europe.com/

A division of Sony Europe (Belgium) N.V.
VAT BE 0413.825.160 · RPR Brussels
Fortis · BIC GEBABEBB · IBAN BE41293037680010___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

[PATCH 4/5] powerpc: Make the 64-bit kernel as a position-independent executable

2008-08-12 Thread Paul Mackerras
This implements CONFIG_RELOCATABLE for 64-bit by making the kernel as
a position-independent executable (PIE).  This involves processing the
dynamic relocations in the image in the early stages of booting, even
if the kernel is being run at the address it is linked at, since the
linker does not necessarily fill in words in the image for which there
are dynamic relocations.

The dynamic relocations are processed by a new function relocate(addr),
where the addr parameter is the virtual address where the image will be
run.  In fact we call it twice; once before calling prom_init, and again
when starting the main kernel.  This means that reloc_offset() returns
0 in prom_init (since it has been relocated to the address it is running
at), which necessitated a few adjustments.

The relocate() function currently only handles R_PPC64_RELATIVE
relocs, which are very simple to process (and the linker puts them all
first in the dynamic relocation section, and tells us how many of them
there are).  Currently we only get R_PPC64_RELATIVE relocs, plus one
R_PPC64_NONE reloc which we can ignore, plus some relocs against weak
undefined symbols (e.g. mach_iseries, mach_powermac) which we can also
ignore.  Ideally we would have a little program to check that we
hadn't inadvertently ended up with any other relocs.

This also changes __va and __pa to use an equivalent definition that is
simpler.  With the relocatable kernel, PAGE_OFFSET and MEMORY_START are
constants (for 64-bit) whereas PHYSICAL_START is a variable (and
KERNELBASE ideally should be too, but isn't yet).

With this, relocatable kernels still copy themselves down to physical
address 0 and run there.

Signed-off-by: Paul Mackerras <[EMAIL PROTECTED]>
---
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 63c9caf..5a5cf3f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -809,6 +809,19 @@ config PIN_TLB
 endmenu
 
 if PPC64
+config RELOCATABLE
+   bool "Build a relocatable kernel"
+   help
+ This builds a kernel image that is capable of running anywhere
+ in the RMA (real memory area) at any 16k-aligned base address.
+ The kernel is linked as a position-independent executable (PIE)
+ and contains dynamic relocations which are processed early
+ in the bootup process.
+
+ One use is for the kexec on panic case where the recovery kernel
+ must live at a different physical address than the primary
+ kernel.
+
 config PAGE_OFFSET
hex
default "0xc000"
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 9155c93..9e5a53f 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -63,7 +63,8 @@ override CC   += -m$(CONFIG_WORD_SIZE)
 override AR:= GNUTARGET=elf$(CONFIG_WORD_SIZE)-powerpc $(AR)
 endif
 
-LDFLAGS_vmlinux:= -Bstatic
+LDFLAGS_vmlinux-$(CONFIG_PPC64)$(CONFIG_RELOCATABLE) := -pie
+LDFLAGS_vmlinux:= -Bstatic $(LDFLAGS_vmlinux-yy)
 
 CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=none  -mcall-aixdesc
 CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 14174aa..9109e1f 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -310,8 +310,11 @@ $(obj)/dtbImage.%: vmlinux $(wrapperbits) $(obj)/%.dtb
 $(obj)/vmlinux.strip: vmlinux
$(STRIP) -s -R .comment $< -o $@
 
+# The iseries hypervisor won't take an ET_DYN executable, so this
+# changes the type (byte 17) in the file to ET_EXEC (2).
 $(obj)/zImage.iseries: vmlinux
$(STRIP) -s -R .comment $< -o $@
+   printf "\x02" | dd of=$@ conv=notrunc bs=1 seek=17
 
 $(obj)/uImage: vmlinux $(wrapperbits)
$(call if_changed,wrap,uboot)
diff --git a/arch/powerpc/boot/elf_util.c b/arch/powerpc/boot/elf_util.c
index 7454aa4..1567a0c 100644
--- a/arch/powerpc/boot/elf_util.c
+++ b/arch/powerpc/boot/elf_util.c
@@ -27,7 +27,8 @@ int parse_elf64(void *hdr, struct elf_info *info)
  elf64->e_ident[EI_MAG3]  == ELFMAG3   &&
  elf64->e_ident[EI_CLASS] == ELFCLASS64&&
  elf64->e_ident[EI_DATA]  == ELFDATA2MSB   &&
- elf64->e_type== ET_EXEC   &&
+ (elf64->e_type== ET_EXEC ||
+  elf64->e_type== ET_DYN)  &&
  elf64->e_machine == EM_PPC64))
return 0;
 
@@ -58,7 +59,8 @@ int parse_elf32(void *hdr, struct elf_info *info)
  elf32->e_ident[EI_MAG3]  == ELFMAG3   &&
  elf32->e_ident[EI_CLASS] == ELFCLASS32&&
  elf32->e_ident[EI_DATA]  == ELFDATA2MSB   &&
- elf32->e_type== ET_EXEC   &&
+ (elf32->e_type== ET_EXEC ||
+  elf32->e_type== ET_DYN)  &&
  elf32->e_machine == EM_PPC))
return 0;
 
diff --git a/arch/powerpc/include/asm/mmu-hash64.h 
b/arch/powerpc