sparc64/73413: [patch] pthread(libkse) library is broken on sparc64
Andrew Belashov
bel at orel.ru
Tue Nov 2 05:20:20 PST 2004
>Number: 73413
>Category: sparc64
>Synopsis: [patch] pthread(libkse) library is broken on sparc64
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: freebsd-sparc64
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Tue Nov 02 13:20:19 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: Andrew Belashov
>Release: FreeBSD 5.3-STABLE sparc64
>Organization:
JSC CenterTelecom
>Environment:
System: FreeBSD bel.localdomain 5.3-STABLE FreeBSD 5.3-STABLE #13: Tue Nov 2
14:04:34 MSK 2004 bel at bel.localdomain:/usr/obj/usr/src/sys/SUNC3D sparc64
Hardware: Ultra 60 (2 x UltraSparc IIi @ 450 MHz)
>Description:
Programs compiled with libkse does not work at all.
>How-To-Repeat:
Use this test code:
--- ss2.c begins here ---
#include <stdio.h>
#include <string.h>
#include <pthread.h>
static void *
entry1(void *argp)
{
long x = 0, y = 1;
while (1) {
if ((y - x) != 1) {
fprintf(stderr, "FATAL ERROR: (y - x) != 1, "
"x = %ld, y = %ld\n", x, y);
}
x++; y++;
}
return NULL;
}
void *
entry2(void *argp)
{
long x = 0, y = -1;
while (1) {
if ((y - x) != -1) {
fprintf(stderr, "FATAL ERROR: (y - x) != -1, "
"x = %ld, y = %ld\n", x, y);
}
x--; y--;
}
return NULL;
}
static void *
entry3(void *argp)
{
long x = 0, y = 2;
while (1) {
if ((y - x) != 2) {
fprintf(stderr, "FATAL ERROR: (y - x) != 2, "
"x = %ld, y = %ld\n", x, y);
}
x += 2; y += 2;
}
return NULL;
}
static void *
entry4(void *argp)
{
long x = 0, y = -2;
while (1) {
if ((y - x) != -2) {
fprintf(stderr, "FATAL ERROR: (y - x) != -2, "
"x = %ld, y = %ld\n", x, y);
}
x -= 2; y -= 2;
}
return NULL;
}
struct thr_table {
void * (*entry)(void *);
pthread_t thread;
};
static struct thr_table threads[] = {
{entry1, NULL},
{entry2, NULL},
{entry3, NULL},
{entry4, NULL},
{NULL, NULL}
};
int
main()
{
int error;
struct thr_table *pthr;
for (pthr = threads; pthr->entry != NULL; pthr++) {
error = pthread_create(&pthr->thread, NULL, pthr->entry, NULL);
if (error)
fprintf(stderr, "Error in pthread_create(): %s\n",
strerror(error));
}
sleep(20);
return 0;
}
--- ss2.c ends here ---
bel at bel$ cc -g -o ss2 ss2.c -lkse
bel at bel$ ./ss2
Segmentation fault (core dumped)
bel at bel$ gdb ss2 ss2.core
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
[...]
This GDB was configured as "sparc64-marcel-freebsd"...
Core was generated by `ss2'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/lib/libkse.so.1...done.
Loaded symbols for /usr/lib/libkse.so.1
Reading symbols from /lib/libc.so.5...done.
Loaded symbols for /lib/libc.so.5
Reading symbols from /libexec/ld-elf.so.1...done.
Loaded symbols for /libexec/ld-elf.so.1
#0 0x0000000040507bb0 in __utrap_panic () from /lib/libc.so.5
(gdb) bt
#0 0x0000000040507bb0 in __utrap_panic () from /lib/libc.so.5
#1 0x00000000405079d4 in __sparc_utrap () from /lib/libc.so.5
#2 0x000000004049ab6c in __sparc_utrap_gen () from /lib/libc.so.5
#3 0x000000004049ab6c in __sparc_utrap_gen () from /lib/libc.so.5
Previous frame identical to this frame (corrupt stack?)
(gdb) quit
>Fix:
I have preliminary patch. Also needed kernel patch from
PR sparc64/72998 <http://www.freebsd.org/cgi/query-pr.cgi?pr=sparc64/72998>
--- libkse.patch begins here ---
--- lib/libpthread/arch/sparc64/include/pthread_md.h.orig Thu Aug 5 09:29:06 2004
+++ lib/libpthread/arch/sparc64/include/pthread_md.h Thu Sep 30 14:16:50 2004
@@ -232,6 +232,9 @@ _thread_switch(struct kcb *kcb, struct t
_tcb_set(kcb, tcb);
mc = &tcb->tcb_tmbx.tm_context.uc_mcontext;
+
+ /* XXX Setup new tcb_tp pointer in machine context */
+ mc->mc_global[6] = (uint64_t)_tp;
if (_libkse_debug == 0) {
tcb->tcb_tmbx.tm_lwp = kcb->kcb_kmbx.km_lwp;
if (setmbox)
--- lib/libpthread/arch/sparc64/sparc64/thr_getcontext.S.orig Mon Aug 9 12:20:25 2004
+++ lib/libpthread/arch/sparc64/sparc64/thr_getcontext.S Thu Sep 30 14:18:53 2004
@@ -27,24 +27,66 @@
#include <machine/asm.h>
__FBSDID("$FreeBSD: src/lib/libpthread/arch/sparc64/sparc64/thr_getcontext.S,v 1.3 2003/10/09 20:52:17 deischen Exp $");
+#include <machine/fsr.h>
+#include <machine/tstate.h>
+
#include "assym.s"
+/*
+ * int thr_getcontext(mcontext_t *mcp);
+ *
+ * Returns -1 if there is an error, 0 no errors; 1 upon return
+ * from a setcontext().
+ */
.weak CNAME(_thr_getcontext)
.set CNAME(_thr_getcontext),CNAME(__thr_getcontext)
ENTRY(__thr_getcontext)
add %o7, 8, %o1
add %o1, 4, %o2
+ stx %g6, [%o0 + MC_GLOBAL + (6 * 8)] /* Current tcb_tp pointer */
+ stx %g7, [%o0 + MC_GLOBAL + (7 * 8)] /* XXX %g7 not used? */
stx %sp, [%o0 + MC_OUT + (6 * 8)]
stx %o1, [%o0 + MC_TPC]
stx %o2, [%o0 + MC_TNPC]
- mov MC_VALID_FLAGS, %l0 /* Validate the context. */
- stx %l0, [%o0 + MC_FLAGS]
- mov 1, %l0
- stx %l0, [%o0 + MC_OUT + (0 * 8)] /* return 1 when resumed */
- retl
- mov 0, %o0 /* return 0 */
+ rd %y, %g1 /* XXX %y deprecated */
+ stx %g1, [%o0 + MC_Y]
+ rd %fprs, %g1
+ stx %g1, [%o0 + MC_FPRS]
+ wr %g0, FPRS_FEF, %fprs /* Enable FPU */
+ stx %fsr, [%o0 + MC_FSR] /* Store FPU Status Register */
+ rd %gsr, %g2
+ stx %g2, [%o0 + MC_GSR] /* Store %gsr */
+ wr %g1, 0, %fprs /* Restore %fprs */
+ andcc %g1, FPRS_FEF, %g0 /* FPU enabled? */
+ bz,a,pt %xcc, 1f
+ nop
+ std %f0, [%o0 + MC_FP + (0 * 64)] /* Store FPU registers */
+ std %f16, [%o0 + MC_FP + (1 * 64)]
+ std %f32, [%o0 + MC_FP + (2 * 64)]
+ std %f48, [%o0 + MC_FP + (3 * 64)]
+
+1:
+ set (TSTATE_IE | TSTATE_PEF), %g1
+ stx %g1, [%o0 + MC_TSTATE] /* XXX Emulated %tstate */
+ mov T_RESERVED, %g1
+ stx %g1, [%o0 + MC_TYPE] /* XXX Emulated trap type */
+ clr [%o0 + MC_WSTATE] /* XXX Emulated %wstate */
+
+ mov MC_VALID_FLAGS, %o3 /* Validate the context. */
+ stx %o3, [%o0 + MC_FLAGS]
+ mov 1, %o3
+ stx %o3, [%o0 + MC_OUT + (0 * 8)] /* return 1 when resumed */
+ jmpl %o7 + 8, %g0
+ clr %o0 /* return 0 */
END(__thr_getcontext)
+/*
+ * int thr_setcontext(mcontext_t *mcp, intptr_t val, intptr_t *loc)
+ *
+ * Restores the context in mcp.
+ *
+ * Returns 0 if there are no errors; -1 otherwise
+ */
.weak CNAME(_thr_setcontext)
.set CNAME(_thr_setcontext),CNAME(__thr_setcontext)
ENTRY(__thr_setcontext)
@@ -53,28 +95,59 @@ ENTRY(__thr_setcontext)
mov %i0, %l0
mov %i1, %l1
mov %i2, %l2
+ ldx [%l0 + MC_FLAGS], %l5
+ cmp %l5, MC_VALID_FLAGS
+ be,pt %icc, 2f /* XXX Checking lower 32bit */
+ nop
+ return %i7 + 8
+ mov -1, %i0 /* Return -1 */
+2:
ldx [%l0 + MC_GLOBAL + (1 * 8)], %g1
ldx [%l0 + MC_GLOBAL + (2 * 8)], %g2
ldx [%l0 + MC_GLOBAL + (3 * 8)], %g3
ldx [%l0 + MC_GLOBAL + (4 * 8)], %g4
ldx [%l0 + MC_GLOBAL + (5 * 8)], %g5
- ldx [%l0 + MC_GLOBAL + (6 * 8)], %g6
- ldx [%l0 + MC_GLOBAL + (7 * 8)], %g7
- ldx [%l0 + MC_OUT + (0 * 8)], %i0
+ ldx [%l0 + MC_GLOBAL + (6 * 8)], %g6 /* Current tcb_tp pointer */
+ ldx [%l0 + MC_GLOBAL + (7 * 8)], %g7 /* XXX %g7 not used? */
+ ldx [%l0 + MC_OUT + (0 * 8)], %i0 /* Return value */
ldx [%l0 + MC_OUT + (1 * 8)], %i1
ldx [%l0 + MC_OUT + (2 * 8)], %i2
ldx [%l0 + MC_OUT + (3 * 8)], %i3
ldx [%l0 + MC_OUT + (4 * 8)], %i4
ldx [%l0 + MC_OUT + (5 * 8)], %i5
- ldx [%l0 + MC_OUT + (6 * 8)], %i6
+ ldx [%l0 + MC_OUT + (6 * 8)], %fp /* %fp */
ldx [%l0 + MC_OUT + (7 * 8)], %i7
+ ldx [%l0 + MC_FPRS], %l5
+ ldx [%l0 + MC_GSR], %l4
+ ldx [%l0 + MC_Y], %l3
+ wr %g0, FPRS_FEF, %fprs /* Enable FPU */
+ andcc %l5, FPRS_FEF, %g0 /* FPU has been enabled? */
+ bz,a,pt %xcc, 3f
+ nop
+ ldd [%l0 + MC_FP + (0 * 64)], %f0 /* Restore FPU registers */
+ ldd [%l0 + MC_FP + (1 * 64)], %f16
+ ldd [%l0 + MC_FP + (2 * 64)], %f32
+ ldd [%l0 + MC_FP + (3 * 64)], %f48
+3:
+ ldx [%l0 + MC_FSR], %fsr /* Restore %fsr */
+ wr %l4, 0, %gsr /* Restore %gsr */
+ wr %g0, 0, %fprs /* Disable FPU */
+ wr %l3, 0, %y /* XXX %y deprecated */
+ wr %l5, 0, %fprs /* Restore %fprs */
ldx [%l0 + MC_TPC], %l4
ldx [%l0 + MC_TNPC], %l3
- brz %l2, 1f
- nop
- stx %l1, [%l2]
-1: jmpl %l3, %g0
- return %l4
+ ldx [%l0 + MC_TSTATE], %l5
+ brnz,a,pn %l2, 1f
+ stx %l1, [%l2] /* Set mbox */
+1:
+ srlx %l5, TSTATE_CCR_SHIFT, %l1
+ and %l1, CCR_MASK, %l1
+ srlx %l5, TSTATE_ASI_SHIFT, %l2
+ and %l2, ASI_MASK, %l2
+ wr %l2, 0, %asi
+ wr %l1, 0, %ccr
+ jmpl %l4, %g0
+ return %l3
END(__thr_setcontext)
ENTRY(_sparc64_enter_uts)
@@ -83,5 +156,5 @@ ENTRY(_sparc64_enter_uts)
add %i2, %i3, %i2
sub %i2, SPOFF + CCFSZ, %sp
jmpl %i0, %g0
- mov %i1, %o0
+ mov %i1, %o0
END(_sparc64_enter_uts)
--- lib/libpthread/arch/sparc64/sparc64/assym.s.orig Thu Oct 9 18:48:09 2003
+++ lib/libpthread/arch/sparc64/sparc64/assym.s Thu Sep 30 13:26:09 2004
@@ -11,5 +11,22 @@
#define MC_VALID_FLAGS 0x1
#define MC_GLOBAL 0x0
#define MC_OUT 0x40
-#define MC_TPC 0xc8
+#define MC_LOCAL 0x80
+#define MC_IN 0xc0
+#define MC_FP 0x100
+#define MC_SIZEOF 512
+
+#define MC_FPRS 0x80
+#define MC_FSR 0x88
+#define MC_GSR 0x90
#define MC_TNPC 0xc0
+#define MC_TPC 0xc8
+#define MC_TSTATE 0xd0
+#define MC_TYPE 0xd8
+#define MC_Y 0xe0
+#define MC_WSTATE 0xe8
+
+#define CCR_MASK 0xff
+#define ASI_MASK 0xff
+#define T_SYSCALL 48
+#define T_RESERVED 0
--- libkse.patch ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-sparc64
mailing list