PowerPC: Rename __kernel_vdso_get_tbfreq to __kernel_get_tbfreq.

In order for the __kernel_get_tbfreq vDSO call to work the
INTERNAL_VSYSCALL_NCS macro needed to be updated to prevent it from
assuming an integer return type (since the timebase frequency is a 64-bit
value) by specifying the type of the return type as a macro parameter.  The
macro then specifically declares the return value as a 'register' (or
implied pair) of the denoted type.  The compiler is then informed that this
register (or implied pair) is to be used for the return value.
This commit is contained in:
Anton Blanchard 2013-01-15 12:50:46 -06:00 committed by Ryan S. Arnold
parent f7bff1ed96
commit 471a1672d4
5 changed files with 55 additions and 29 deletions

View File

@ -1,3 +1,25 @@
2013-01-15 Anton Blanchard <anton@samba.org>
Ryan S. Arnold <rsa@linux.vnet.ibm.com>
* sysdeps/unix/sysv/linux/powerpc/init-first.c: Rename
__kernel_vdso_get_tbfreq to __kernel_get_tbfreq.
* sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c: Add parameter to
INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK to specify return type.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
(INTERNAL_VSYSCALL_NCS): Change "=&r" in inline asm output regs list to
"+r" and remove output regs list as redundant. Add explicit inline
asm to specify register of return val to work around compiler codegen
bug. Remove (int) cast on return value. Add return type parameter to
use in macro so that this macro does not truncate return value for
64-bit values.
(INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK): Add return type parameter and
pass to INTERNAL_VSYSCALL_NCS.
(INLINE_VSYSCALL): Add 'long int' as return type to
INTERNAL_VSYSCALL_NCS macro invocation.
(INTERNAL_VSYSCALL): Add 'long int' as return type to
INTERNAL_VSYSCALL_NCS macro invocation.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h: Likewise.
2013-01-18 Siddhesh Poyarekar <siddhesh@redhat.com>
[BZ #14496]

View File

@ -41,7 +41,8 @@ __get_clockfreq (void)
/* If we can use the vDSO to obtain the timebase even better. */
#ifdef SHARED
INTERNAL_SYSCALL_DECL (err);
timebase_freq = INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, 0);
timebase_freq =
INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, hp_timing_t, 0);
if (INTERNAL_SYSCALL_ERROR_P (timebase_freq, err)
&& INTERNAL_SYSCALL_ERRNO (timebase_freq, err) == ENOSYS)
#endif

View File

@ -41,7 +41,7 @@ _libc_vdso_platform_setup (void)
__vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres", &linux2615);
__vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_vdso_get_tbfreq", &linux2615);
__vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_get_tbfreq", &linux2615);
__vdso_getcpu = _dl_vdso_vsym ("__kernel_getcpu", &linux2615);
}

View File

@ -60,7 +60,8 @@
\
if (__vdso_##name != NULL) \
{ \
sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, nr, ##args); \
sc_ret = \
INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, long int, nr, ##args);\
if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
goto out; \
if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS) \
@ -90,7 +91,8 @@
\
if (__vdso_##name != NULL) \
{ \
v_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \
v_ret = \
INTERNAL_VSYSCALL_NCS (__vdso_##name, err, long int, nr, ##args); \
if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err) \
|| INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS) \
goto out; \
@ -104,12 +106,12 @@
INTERNAL_SYSCALL (name, err, nr, ##args)
# endif
# define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \
# define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, type, nr, args...) \
({ \
long int sc_ret = ENOSYS; \
type sc_ret = ENOSYS; \
\
if (__vdso_##name != NULL) \
sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \
sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, type, nr, ##args); \
else \
err = 1 << 28; \
sc_ret; \
@ -126,7 +128,7 @@
function call, with the exception of LR (which is needed for the
"sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
an error return status). */
# define INTERNAL_VSYSCALL_NCS(funcptr, err, nr, args...) \
# define INTERNAL_VSYSCALL_NCS(funcptr, err, type, nr, args...) \
({ \
register void *r0 __asm__ ("r0"); \
register long int r3 __asm__ ("r3"); \
@ -139,18 +141,18 @@
register long int r10 __asm__ ("r10"); \
register long int r11 __asm__ ("r11"); \
register long int r12 __asm__ ("r12"); \
register type rval __asm__ ("r3"); \
LOADARGS_##nr (funcptr, args); \
__asm__ __volatile__ \
("mtctr %0\n\t" \
"bctrl\n\t" \
"mfcr %0" \
: "=&r" (r0), \
"=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \
"=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \
: ASM_INPUT_##nr \
: "cr0", "ctr", "lr", "memory"); \
: "+r" (r0), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), \
"+r" (r8), "+r" (r9), "+r" (r10), "+r" (r11), "+r" (r12) \
: : "cr0", "ctr", "lr", "memory"); \
err = (long int) r0; \
(int) r3; \
__asm__ __volatile__ ("" : "=r" (rval) : "r" (r3), "r" (r4)); \
rval; \
})
# undef INLINE_SYSCALL
@ -191,7 +193,7 @@
register long int r10 __asm__ ("r10"); \
register long int r11 __asm__ ("r11"); \
register long int r12 __asm__ ("r12"); \
LOADARGS_##nr(name, args); \
LOADARGS_##nr(name, args); \
__asm__ __volatile__ \
("sc \n\t" \
"mfcr %0" \

View File

@ -75,7 +75,8 @@
\
if (__vdso_##name != NULL) \
{ \
sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, nr, ##args); \
sc_ret = \
INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, long int, nr, ##args);\
if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
goto out; \
if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS) \
@ -105,7 +106,8 @@
\
if (__vdso_##name != NULL) \
{ \
v_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \
v_ret = \
INTERNAL_VSYSCALL_NCS (__vdso_##name, err, long int, nr, ##args); \
if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err) \
|| INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS) \
goto out; \
@ -121,12 +123,12 @@
/* This version is for internal uses when there is no desire
to set errno */
#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \
#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, type, nr, args...) \
({ \
long int sc_ret = ENOSYS; \
type sc_ret = ENOSYS; \
\
if (__vdso_##name != NULL) \
sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \
sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, type, nr, ##args); \
else \
err = 1 << 28; \
sc_ret; \
@ -142,7 +144,7 @@
gave back in the non-error (CR0.SO cleared) case, otherwise (CR0.SO set)
the negation of the return value in the kernel gets reverted. */
#define INTERNAL_VSYSCALL_NCS(funcptr, err, nr, args...) \
#define INTERNAL_VSYSCALL_NCS(funcptr, err, type, nr, args...) \
({ \
register void *r0 __asm__ ("r0"); \
register long int r3 __asm__ ("r3"); \
@ -151,20 +153,19 @@
register long int r6 __asm__ ("r6"); \
register long int r7 __asm__ ("r7"); \
register long int r8 __asm__ ("r8"); \
register type rval __asm__ ("r3"); \
LOADARGS_##nr (funcptr, args); \
__asm__ __volatile__ \
("mtctr %0\n\t" \
"bctrl\n\t" \
"mfcr %0\n\t" \
"0:" \
: "=&r" (r0), \
"=&r" (r3), "=&r" (r4), "=&r" (r5), \
"=&r" (r6), "=&r" (r7), "=&r" (r8) \
: ASM_INPUT_##nr \
: "r9", "r10", "r11", "r12", \
"cr0", "ctr", "lr", "memory"); \
err = (long int) r0; \
r3; \
: "+r" (r0), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), \
"+r" (r7), "+r" (r8) \
: : "r9", "r10", "r11", "r12", "cr0", "ctr", "lr", "memory"); \
err = (long int) r0; \
__asm__ __volatile__ ("" : "=r" (rval) : "r" (r3)); \
rval; \
})
#undef INLINE_SYSCALL