diff options
author | Anton Blanchard <anton@samba.org> | 2013-01-15 12:50:46 -0600 |
---|---|---|
committer | Ryan S. Arnold <rsa@linux.vnet.ibm.com> | 2013-07-25 11:56:14 -0500 |
commit | dafbd378a285b44acd8015025227326497cd99d9 (patch) | |
tree | bcabf262e8d026d6f037877668d676a48341f3fa | |
parent | d8f90bcfad22ae63108ab3b3446fc6b6a4ea6fee (diff) | |
download | glibc-dafbd378a285b44acd8015025227326497cd99d9.tar.gz |
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.
(cherry picked from commit 471a1672d4d55124de4db8273829f96cc14d424a)
-rw-r--r-- | ChangeLog | 22 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c | 3 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/init-first.c | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h | 28 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h | 29 |
5 files changed, 55 insertions, 29 deletions
@@ -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-09 Anton Blanchard <anton@samba.org> * sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c: New file. diff --git a/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c b/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c index a863a27b32..021594c056 100644 --- a/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c +++ b/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c @@ -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 diff --git a/sysdeps/unix/sysv/linux/powerpc/init-first.c b/sysdeps/unix/sysv/linux/powerpc/init-first.c index 6bcb7d5657..5587e2acc6 100644 --- a/sysdeps/unix/sysv/linux/powerpc/init-first.c +++ b/sysdeps/unix/sysv/linux/powerpc/init-first.c @@ -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); } diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h index da25c01504..fa4116ef5f 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h @@ -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" \ diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h index 059cf70755..b4cdbbb522 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h @@ -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 |