linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] powerpc: Fix -mcmodel=medium breakage in prom_init.c
@ 2013-03-12 11:51 Anton Blanchard
  2013-03-12 22:11 ` Aaro Koskinen
  2013-03-14 16:26 ` Alexander Graf
  0 siblings, 2 replies; 3+ messages in thread
From: Anton Blanchard @ 2013-03-12 11:51 UTC (permalink / raw)
  To: agraf, benh, aaro.koskinen, amodra; +Cc: linuxppc-dev


Commit 5ac47f7a6efb (powerpc: Relocate prom_init.c on 64bit) made
prom_init.c position independent by manually relocating its entries
in the TOC.

We get the address of the TOC entries with the __prom_init_toc_start
linker symbol. If __prom_init_toc_start ends up as an entry in the
TOC then we need to add an offset to get the current address. This is
the case for older toolchains.

On the other hand, if we have a newer toolchain that supports
-mcmodel=medium then __prom_init_toc_start will be created by a
relative offset from r2 (the TOC pointer). Since r2 has already been
relocated, nothing more needs to be done.  Adding an offset in this
case is wrong and Aaro Koskinen and Alexander Graf have noticed noticed
G5 and OpenBIOS breakage.

Alan Modra suggested we just use r2 to get at the TOC which is simpler
and works with both old and new toolchains.

Reported-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Anton Blanchard <anton@samba.org>
---

Thanks Aaro for reporting this, and Alexander for an initial
fix. This tested ok for me with both a new and an old toolchain,
but would appreciate if you could double check it fixes your issues
too.

diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 7f7fb7f..13f8d16 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -2832,11 +2832,13 @@ static void unreloc_toc(void)
 {
 }
 #else
-static void __reloc_toc(void *tocstart, unsigned long offset,
-			unsigned long nr_entries)
+static void __reloc_toc(unsigned long offset, unsigned long nr_entries)
 {
 	unsigned long i;
-	unsigned long *toc_entry = (unsigned long *)tocstart;
+	unsigned long *toc_entry;
+
+	/* Get the start of the TOC by using r2 directly. */
+	asm volatile("addi %0,2,-0x8000" : "=b" (toc_entry));
 
 	for (i = 0; i < nr_entries; i++) {
 		*toc_entry = *toc_entry + offset;
@@ -2850,8 +2852,7 @@ static void reloc_toc(void)
 	unsigned long nr_entries =
 		(__prom_init_toc_end - __prom_init_toc_start) / sizeof(long);
 
-	/* Need to add offset to get at __prom_init_toc_start */
-	__reloc_toc(__prom_init_toc_start + offset, offset, nr_entries);
+	__reloc_toc(offset, nr_entries);
 
 	mb();
 }
@@ -2864,8 +2865,7 @@ static void unreloc_toc(void)
 
 	mb();
 
-	/* __prom_init_toc_start has been relocated, no need to add offset */
-	__reloc_toc(__prom_init_toc_start, -offset, nr_entries);
+	__reloc_toc(-offset, nr_entries);
 }
 #endif
 #endif

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

* Re: [PATCH] powerpc: Fix -mcmodel=medium breakage in prom_init.c
  2013-03-12 11:51 [PATCH] powerpc: Fix -mcmodel=medium breakage in prom_init.c Anton Blanchard
@ 2013-03-12 22:11 ` Aaro Koskinen
  2013-03-14 16:26 ` Alexander Graf
  1 sibling, 0 replies; 3+ messages in thread
From: Aaro Koskinen @ 2013-03-12 22:11 UTC (permalink / raw)
  To: Anton Blanchard; +Cc: linuxppc-dev, agraf, amodra

Hi,

On Tue, Mar 12, 2013 at 10:51:51PM +1100, Anton Blanchard wrote:
> Commit 5ac47f7a6efb (powerpc: Relocate prom_init.c on 64bit) made
> prom_init.c position independent by manually relocating its entries
> in the TOC.
> 
> We get the address of the TOC entries with the __prom_init_toc_start
> linker symbol. If __prom_init_toc_start ends up as an entry in the
> TOC then we need to add an offset to get the current address. This is
> the case for older toolchains.
> 
> On the other hand, if we have a newer toolchain that supports
> -mcmodel=medium then __prom_init_toc_start will be created by a
> relative offset from r2 (the TOC pointer). Since r2 has already been
> relocated, nothing more needs to be done.  Adding an offset in this
> case is wrong and Aaro Koskinen and Alexander Graf have noticed noticed
> G5 and OpenBIOS breakage.
> 
> Alan Modra suggested we just use r2 to get at the TOC which is simpler
> and works with both old and new toolchains.
> 
> Reported-by: Alexander Graf <agraf@suse.de>
> Signed-off-by: Anton Blanchard <anton@samba.org>
> ---
> 
> Thanks Aaro for reporting this, and Alexander for an initial
> fix. This tested ok for me with both a new and an old toolchain,
> but would appreciate if you could double check it fixes your issues
> too.

This seems to fix the issue also for me, so:

Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>

Thanks,

A.

> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index 7f7fb7f..13f8d16 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -2832,11 +2832,13 @@ static void unreloc_toc(void)
>  {
>  }
>  #else
> -static void __reloc_toc(void *tocstart, unsigned long offset,
> -			unsigned long nr_entries)
> +static void __reloc_toc(unsigned long offset, unsigned long nr_entries)
>  {
>  	unsigned long i;
> -	unsigned long *toc_entry = (unsigned long *)tocstart;
> +	unsigned long *toc_entry;
> +
> +	/* Get the start of the TOC by using r2 directly. */
> +	asm volatile("addi %0,2,-0x8000" : "=b" (toc_entry));
>  
>  	for (i = 0; i < nr_entries; i++) {
>  		*toc_entry = *toc_entry + offset;
> @@ -2850,8 +2852,7 @@ static void reloc_toc(void)
>  	unsigned long nr_entries =
>  		(__prom_init_toc_end - __prom_init_toc_start) / sizeof(long);
>  
> -	/* Need to add offset to get at __prom_init_toc_start */
> -	__reloc_toc(__prom_init_toc_start + offset, offset, nr_entries);
> +	__reloc_toc(offset, nr_entries);
>  
>  	mb();
>  }
> @@ -2864,8 +2865,7 @@ static void unreloc_toc(void)
>  
>  	mb();
>  
> -	/* __prom_init_toc_start has been relocated, no need to add offset */
> -	__reloc_toc(__prom_init_toc_start, -offset, nr_entries);
> +	__reloc_toc(-offset, nr_entries);
>  }
>  #endif
>  #endif
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

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

* Re: [PATCH] powerpc: Fix -mcmodel=medium breakage in prom_init.c
  2013-03-12 11:51 [PATCH] powerpc: Fix -mcmodel=medium breakage in prom_init.c Anton Blanchard
  2013-03-12 22:11 ` Aaro Koskinen
@ 2013-03-14 16:26 ` Alexander Graf
  1 sibling, 0 replies; 3+ messages in thread
From: Alexander Graf @ 2013-03-14 16:26 UTC (permalink / raw)
  To: Anton Blanchard; +Cc: amodra, linuxppc-dev, aaro.koskinen


On 12.03.2013, at 12:51, Anton Blanchard wrote:

>=20
> Commit 5ac47f7a6efb (powerpc: Relocate prom_init.c on 64bit) made
> prom_init.c position independent by manually relocating its entries
> in the TOC.
>=20
> We get the address of the TOC entries with the __prom_init_toc_start
> linker symbol. If __prom_init_toc_start ends up as an entry in the
> TOC then we need to add an offset to get the current address. This is
> the case for older toolchains.
>=20
> On the other hand, if we have a newer toolchain that supports
> -mcmodel=3Dmedium then __prom_init_toc_start will be created by a
> relative offset from r2 (the TOC pointer). Since r2 has already been
> relocated, nothing more needs to be done.  Adding an offset in this
> case is wrong and Aaro Koskinen and Alexander Graf have noticed =
noticed
> G5 and OpenBIOS breakage.
>=20
> Alan Modra suggested we just use r2 to get at the TOC which is simpler
> and works with both old and new toolchains.
>=20
> Reported-by: Alexander Graf <agraf@suse.de>
> Signed-off-by: Anton Blanchard <anton@samba.org>

This fixes my G5 again as well.

Acked-by: Alexander Graf <agraf@suse.de>

Please make sure this patch goes into 3.9.


Alex


> ---
>=20
> Thanks Aaro for reporting this, and Alexander for an initial
> fix. This tested ok for me with both a new and an old toolchain,
> but would appreciate if you could double check it fixes your issues
> too.
>=20
> diff --git a/arch/powerpc/kernel/prom_init.c =
b/arch/powerpc/kernel/prom_init.c
> index 7f7fb7f..13f8d16 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -2832,11 +2832,13 @@ static void unreloc_toc(void)
> {
> }
> #else
> -static void __reloc_toc(void *tocstart, unsigned long offset,
> -			unsigned long nr_entries)
> +static void __reloc_toc(unsigned long offset, unsigned long =
nr_entries)
> {
> 	unsigned long i;
> -	unsigned long *toc_entry =3D (unsigned long *)tocstart;
> +	unsigned long *toc_entry;
> +
> +	/* Get the start of the TOC by using r2 directly. */
> +	asm volatile("addi %0,2,-0x8000" : "=3Db" (toc_entry));
>=20
> 	for (i =3D 0; i < nr_entries; i++) {
> 		*toc_entry =3D *toc_entry + offset;
> @@ -2850,8 +2852,7 @@ static void reloc_toc(void)
> 	unsigned long nr_entries =3D
> 		(__prom_init_toc_end - __prom_init_toc_start) / =
sizeof(long);
>=20
> -	/* Need to add offset to get at __prom_init_toc_start */
> -	__reloc_toc(__prom_init_toc_start + offset, offset, nr_entries);
> +	__reloc_toc(offset, nr_entries);
>=20
> 	mb();
> }
> @@ -2864,8 +2865,7 @@ static void unreloc_toc(void)
>=20
> 	mb();
>=20
> -	/* __prom_init_toc_start has been relocated, no need to add =
offset */
> -	__reloc_toc(__prom_init_toc_start, -offset, nr_entries);
> +	__reloc_toc(-offset, nr_entries);
> }
> #endif
> #endif

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

end of thread, other threads:[~2013-03-14 16:26 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-12 11:51 [PATCH] powerpc: Fix -mcmodel=medium breakage in prom_init.c Anton Blanchard
2013-03-12 22:11 ` Aaro Koskinen
2013-03-14 16:26 ` Alexander Graf

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).