[PATCH] powerpc: Make the vDSO functions set error code (#2)

Benjamin Herrenschmidt benh at kernel.crashing.org
Wed Nov 16 13:54:32 EST 2005


The vDSO functions should have the same calling convention as a syscall.
Unfortunately, they currently don't set the cr0.so bit which is used to
indicate an error. This patch makes them clear this bit unconditionally
since all functions currently succeed. The syscall fallback done by some
of them will eventually override this if the syscall fails.

This also changes the symbol version of all vdso exports to make sure
glibc can differenciate between old and fixed calls for existing ones
like __kernel_gettimeofday.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---

Tom, Steve: You'll have to write a wrapper macro to call the vdso
similar to the syscall one, that does something like:

   mtctr   %0 <--- function address
   bctrl
   mfcr    %1 <--- error indication in cr0.so 

With appropriate clobbers, similar to the syscall macro (the vDSO
clobbers all volatile register (r0, r3 ... r12, cr0, cr1 and XER)

The advantage of doing so is that you don't have to create fake
descriptors for ppc64 and thus avoid useless TOC reloads, you can even
have a single macro that works on both 32 and 64 bits.

Index: linux-work/arch/powerpc/kernel/vdso32/cacheflush.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso32/cacheflush.S	2005-11-16 13:39:00.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vdso32/cacheflush.S	2005-11-16 13:52:05.000000000 +1100
@@ -35,6 +35,7 @@
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5		/* ensure we get enough */
 	srwi.	r8,r8,7			/* compute line count */
+	crclr	cr0*4+so
 	beqlr				/* nothing to do? */
 	mtctr	r8
 	mr	r3,r6
@@ -58,6 +59,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_sync_dicache_p5)
   .cfi_startproc
+	crclr	cr0*4+so
 	sync
 	isync
 	li	r3,0
Index: linux-work/arch/powerpc/kernel/vdso32/datapage.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso32/datapage.S	2005-11-16 13:39:00.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vdso32/datapage.S	2005-11-16 13:51:35.000000000 +1100
@@ -54,7 +54,6 @@
   .cfi_startproc
 	mflr	r12
   .cfi_register lr,r12
-
 	mr	r4,r3
 	bl	__get_datapage at local
 	mtlr	r12
@@ -63,6 +62,7 @@
 	beqlr
 	li	r0,__NR_syscalls
 	stw	r0,0(r4)
+	crclr	cr0*4+so
 	blr
   .cfi_endproc
 V_FUNCTION_END(__kernel_get_syscall_map)
@@ -80,6 +80,7 @@
 	lwz	r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
 	lwz	r3,CFG_TB_TICKS_PER_SEC(r3)
 	mtlr	r12
+	crclr	cr0*4+so
 	blr
   .cfi_endproc
 V_FUNCTION_END(__kernel_get_tbfreq)
Index: linux-work/arch/powerpc/kernel/vdso32/gettimeofday.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso32/gettimeofday.S	2005-11-16 13:39:00.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vdso32/gettimeofday.S	2005-11-16 13:50:35.000000000 +1100
@@ -59,6 +59,7 @@
 	stw	r5,TZONE_TZ_DSTTIME(r11)
 
 1:	mtlr	r12
+	crclr	cr0*4+so
 	li	r3,0
 	blr
 
@@ -117,6 +118,7 @@
 	mulli	r5,r5,1000
 	stw	r5,TSPC32_TV_NSEC(r11)
 	mtlr	r12
+	crclr	cr0*4+so
 	li	r3,0
 	blr
 
@@ -185,6 +187,7 @@
 	stw	r4,TSPC32_TV_NSEC(r11)
 
 	mtlr	r12
+	crclr	cr0*4+so
 	li	r3,0
 	blr
 
@@ -219,6 +222,7 @@
 
 	li	r3,0
 	cmpli	cr0,r4,0
+	crclr	cr0*4+so
 	beqlr
 	lis	r5,CLOCK_REALTIME_RES at h
 	ori	r5,r5,CLOCK_REALTIME_RES at l
Index: linux-work/arch/powerpc/kernel/vdso64/cacheflush.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso64/cacheflush.S	2005-11-16 13:39:00.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vdso64/cacheflush.S	2005-11-16 13:53:48.000000000 +1100
@@ -35,6 +35,7 @@
 	subf	r8,r6,r4		/* compute length */
 	add	r8,r8,r5		/* ensure we get enough */
 	srwi.	r8,r8,7			/* compute line count */
+	crclr	cr0*4+so
 	beqlr				/* nothing to do? */
 	mtctr	r8
 	mr	r3,r6
@@ -58,6 +59,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_sync_dicache_p5)
   .cfi_startproc
+	crclr	cr0*4+so
 	sync
 	isync
 	li	r3,0
Index: linux-work/arch/powerpc/kernel/vdso64/datapage.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso64/datapage.S	2005-11-16 13:39:00.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vdso64/datapage.S	2005-11-16 13:53:36.000000000 +1100
@@ -54,12 +54,12 @@
   .cfi_startproc
 	mflr	r12
   .cfi_register lr,r12
-
 	mr	r4,r3
 	bl	V_LOCAL_FUNC(__get_datapage)
 	mtlr	r12
 	addi	r3,r3,CFG_SYSCALL_MAP64
 	cmpli	cr0,r4,0
+	crclr	cr0*4+so
 	beqlr
 	li	r0,__NR_syscalls
 	stw	r0,0(r4)
@@ -80,6 +80,7 @@
 	bl	V_LOCAL_FUNC(__get_datapage)
 	ld	r3,CFG_TB_TICKS_PER_SEC(r3)
 	mtlr	r12
+	crclr	cr0*4+so
 	blr
   .cfi_endproc
 V_FUNCTION_END(__kernel_get_tbfreq)
Index: linux-work/arch/powerpc/kernel/vdso64/gettimeofday.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso64/gettimeofday.S	2005-11-16 13:39:00.000000000 +1100
+++ linux-work/arch/powerpc/kernel/vdso64/gettimeofday.S	2005-11-16 13:53:12.000000000 +1100
@@ -52,6 +52,7 @@
 	stw	r4,TZONE_TZ_MINWEST(r10)
 	stw	r5,TZONE_TZ_DSTTIME(r10)
 1:	mtlr	r12
+	crclr	cr0*4+so
 	li	r3,0			/* always success */
 	blr
   .cfi_endproc
@@ -99,6 +100,7 @@
 	std	r0,TSPC64_TV_NSEC(r11)	/* store nsec in tp */
 
 	mtlr	r12
+	crclr	cr0*4+so
 	li	r3,0
 	blr
 
@@ -159,6 +161,7 @@
 	std	r7,TSPC64_TV_NSEC(r11)
 
 	mtlr	r12
+	crclr	cr0*4+so
 	li	r3,0
 	blr
 
@@ -193,6 +196,7 @@
 
 	li	r3,0
 	cmpli	cr0,r4,0
+	crclr	cr0*4+so
 	beqlr
 	lis	r5,CLOCK_REALTIME_RES at h
 	ori	r5,r5,CLOCK_REALTIME_RES at l
Index: linux-work/include/asm-powerpc/vdso.h
===================================================================
--- linux-work.orig/include/asm-powerpc/vdso.h	2005-11-16 13:39:00.000000000 +1100
+++ linux-work/include/asm-powerpc/vdso.h	2005-11-16 13:42:22.000000000 +1100
@@ -11,7 +11,7 @@
 #define VDSO32_MBASE	VDSO32_LBASE
 #define VDSO64_MBASE	VDSO64_LBASE
 
-#define VDSO_VERSION_STRING	LINUX_2.6.12
+#define VDSO_VERSION_STRING	LINUX_2.6.15
 
 /* Define if 64 bits VDSO has procedure descriptors */
 #undef VDS64_HAS_DESCRIPTORS





More information about the Linuxppc64-dev mailing list