Skip to contentSkip to conversation

spufs: change ppc_rtas declaration to weak

PATCH In review Geoff Levand 2 participants 3 messages Oct 5, 2006 – Oct 7, 2006

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 spufs: change ppc_rtas declaration to weak

The symbol ppc_rtas is defined as weak, but the declaration is missing the weak attribute specifier. The improper declaration causes problems when linking the ppc_rtas reference in spu_syscall_table[] (spu_callbacks.c) when RTAS support is not enabled.

Fixes this powerpc build error with CONFIG_SPU_FS=y, CONFIG_PPC_RTAS=n:

arch/powerpc/platforms/built-in.o: undefined reference to `ppc_rtas'

---

I did a test build with pseries_defconfig and verified the proper routine is linked in. No run time test done.

include/asm-powerpc/syscalls.h +1 -1
Index: cell--common--5/include/asm-powerpc/syscalls.h
===================================================================
@@ -37,7 +37,7 @@
 asmlinkage int sys_ipc(uint call, int first, unsigned long second,
 		long third, void __user *ptr, long fifth);
 asmlinkage long ppc64_personality(unsigned long personality);
-asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
+asmlinkage int ppc_rtas(struct rtas_args __user *uargs) __attribute__((weak));
 asmlinkage time_t sys64_time(time_t __user * tloc);
 asmlinkage long ppc_newuname(struct new_utsname __user * name);
 
#1 lore raw
Quoted 2 lines · Geoff Levand

Index: cell--common--5/include/asm-powerpc/syscalls.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

Quoted 5 lines
include/asm-powerpc/syscalls.h +0 -0
@@ -37,7 +37,7 @@
 =A0asmlinkage int sys_ipc(uint call, int first, unsigned long second,

=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0long third, void __user *=

ptr, long fifth);

include/asm-powerpc/syscalls.h

Quoted 3 lines

=A0asmlinkage long ppc64_personality(unsigned long personality);

include/asm-powerpc/syscalls.h +1 -1
-asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
+asmlinkage int ppc_rtas(struct rtas_args __user *uargs) __attribute__((w=

eak));

Quoted 3 lines

=A0asmlinkage time_t sys64_time(time_t __user * tloc); =A0asmlinkage long ppc_newuname(struct new_utsname __user * name); =A0

Hmm, I can't see why this does the right thing. __attribute__((weak)) should normally be put only into the definition of a function, not into the common declaration. This looks like it makes _both_ definitions (kernel/sys.c and arch/powerpc/kernel/rtas.c) weak, so on pseries it becomes unspecific which one is actually used.

The problem that this is trying to work around is probably caused by the
dot-symbols: cond_syscall defines a ".ppc_rtas", but not a "ppc_rtas" symbo= l,
which spufs tries to resolve.

	Arnd <><=20
#2 lore raw
Quoted 3 lines · Arnd Bergmann
Quoted 2 lines · Geoff Levand

Index: cell--common--5/include/asm-powerpc/syscalls.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

Quoted 4 lines
Quoted 4 lines
include/asm-powerpc/syscalls.h +0 -0
@@ -37,7 +37,7 @@

=EF=BF=BDasmlinkage int sys_ipc(uint call, int first, unsigned long se=

cond,

Quoted 1 line
Quoted 1 line

=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD=

=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BDl= ong third, void __user *ptr, long fifth);

Quoted 3 lines

include/asm-powerpc/syscalls.h

Quoted 3 lines

=EF=BF=BDasmlinkage long ppc64_personality(unsigned long personality);

include/asm-powerpc/syscalls.h +1 -1
-asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
+asmlinkage int ppc_rtas(struct rtas_args __user *uargs) __attribute__=

((weak));

Quoted 2 lines
Quoted 2 lines

=EF=BF=BDasmlinkage time_t sys64_time(time_t __user * tloc); =EF=BF=BDasmlinkage long ppc_newuname(struct new_utsname __user * name=

);

Quoted 3 lines
Quoted 1 line

=EF=BF=BD

=20
Hmm, I can't see why this does the right thing. __attribute__((weak)) s=

hould

Quoted 1 line

normally be put only into the definition of a function, not into the co=

mmon

Quoted 1 line

declaration. This looks like it makes _both_ definitions (kernel/sys.c =

and

Quoted 1 line

arch/powerpc/kernel/rtas.c) weak, so on pseries it becomes unspecific w=

hich

Quoted 1 line

one is actually used.

You're right, I see now that that fix just worked by pure chance.

Quoted 1 line

The problem that this is trying to work around is probably caused by th=

e

Quoted 1 line

dot-symbols: cond_syscall defines a ".ppc_rtas", but not a "ppc_rtas" s=

ymbol,

Quoted 1 line

which spufs tries to resolve.

Yes, on studying the code produced I found that the problem was that cond_syscall() didn't create a non-dot symbol that the C linkage of spu_syscall_table[] expected, as seen here:

./arch/powerpc/platforms/cell/spu_callbacks.o
U ppc_rtas
./kernel/sys_ni.o
0000000000000000 W .ppc_rtas

As you suggested to try, the method used by ia64 works properly, creating=
both
a dot and a non-dot weak symbol:

./kernel/sys_ni.o
0000000000000000 W .ppc_rtas
0000000000000000 W ppc_rtas

Updated patch follows.

-Geoff

Change the definition of powerpc's cond_syscall() to use the standard gcc weak attribute specifier which provides proper support for C linkage as needed by spu_syscall_table[].

Fixes this powerpc build error with CONFIG_SPU_FS=3Dy, CONFIG_PPC_RTAS=3D= n:

arch/powerpc/platforms/built-in.o: undefined reference to `ppc_rtas'

---

Build tests done with pseries_defconfig, cell_defconfig and ebony_defconf= ig.

Quoted 1 line

From what I could determine, the toolchain troubles are no longer relevan=

t
with the recent change to a minimum version of gcc 3.2 for kernel builds. Confirmation of this point would be appreciated.

=20
Index: cell--common--5/include/asm-powerpc/unistd.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

include/asm-powerpc/unistd.h +0 -1
@@ -445,7 +445,6 @@
 #include <linux/types.h>
 #include <linux/compiler.h>
 #include <linux/linkage.h>
-#include <asm/syscalls.h>

=20
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
@@ -487,16 +486,9 @@
=20
/*
* "Conditional" syscalls
- *
- * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
- * but it doesn't work on all toolchains, so we just do it by hand */
-#ifdef CONFIG_PPC32
-#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscal= l")
-#else
-#define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_sys= call")
-#endif
-
+#define cond_syscall(x) \
+ asmlinkage long x (void) __attribute__((weak,alias("sys_ni_syscall")))
=20
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */