Merge master.kernel.org:/home/davem/BK/davem-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index e5bab88..7373c87 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -1,4 +1,4 @@
-/*  $Id: signal.c,v 1.109 2001/12/21 01:22:31 davem Exp $
+/*  $Id: signal.c,v 1.110 2002/02/08 03:57:14 davem Exp $
  *  linux/arch/sparc/kernel/signal.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
index 5ea80c3..f33c94a 100644
--- a/arch/sparc/kernel/sys_sunos.c
+++ b/arch/sparc/kernel/sys_sunos.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos.c,v 1.136 2002/01/08 16:00:14 davem Exp $
+/* $Id: sys_sunos.c,v 1.137 2002/02/08 03:57:14 davem Exp $
  * sys_sunos.c: SunOS specific syscall compatibility support.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index 85dd7cf..72eb437 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.102 2002/01/31 03:30:05 davem Exp $
+/* $Id: systbls.S,v 1.103 2002/02/08 03:57:14 davem Exp $
  * systbls.S: System call entry point tables for OS compatibility.
  *            The native Linux system call table lives here also.
  *
@@ -55,7 +55,7 @@
 /*170*/	.long sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
 /*175*/	.long sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
 /*180*/	.long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_query_module
-/*185*/	.long sys_setpgid, sys_fremovexattr, sys_nis_syscall, sys_nis_syscall, sys_newuname
+/*185*/	.long sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sys_newuname
 /*190*/	.long sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 /*195*/	.long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask
 /*200*/	.long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir
@@ -70,7 +70,7 @@
 /*240*/	.long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
 /*245*/	.long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
 /*250*/	.long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
-/*255*/	.long sys_nis_syscall, sys_nis_syscall, sys_tkill
+/*255*/	.long sys_nis_syscall, sys_nis_syscall
 
 #ifdef CONFIG_SUNOS_EMUL
 	/* Now the SunOS syscall table. */
diff --git a/arch/sparc64/Config.help b/arch/sparc64/Config.help
index 907510a..237c8af 100644
--- a/arch/sparc64/Config.help
+++ b/arch/sparc64/Config.help
@@ -25,6 +25,16 @@
 
   If you don't know what to do here, say N.
 
+CONFIG_PREEMPT
+  This option reduces the latency of the kernel when reacting to
+  real-time or interactive events by allowing a low priority process to
+  be preempted even if it is in kernel mode executing a system call.
+  This allows applications to run more reliably even when the system is
+  under load.
+
+  Say Y here if you are building a kernel for a desktop, embedded
+  or real-time system.  Say N if you are unsure.
+
 CONFIG_SPARC64
   SPARC is a family of RISC microprocessors designed and marketed by
   Sun Microsystems, incorporated.  This port covers the newer 64-bit
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
index 75ce131..fb2c66d 100644
--- a/arch/sparc64/Makefile
+++ b/arch/sparc64/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.51 2001/11/17 00:15:27 davem Exp $
+# $Id: Makefile,v 1.52 2002/02/09 19:49:31 davem Exp $
 # sparc64/Makefile
 #
 # Makefile for the architecture dependent flags and dependencies on the
@@ -79,12 +79,8 @@
 	rm -f $(TOPDIR)/vmlinux.aout
 
 archmrproper:
-	rm -f $(TOPDIR)/include/asm-sparc64/asm_offsets.h
 
-archdep: check_asm
-
-check_asm: include/linux/version.h
-	$(MAKE) -C arch/sparc64/kernel check_asm
+archdep:
 
 tftpboot.img:
 	$(MAKE) -C arch/sparc64/boot tftpboot.img
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
index bcc1e62..4410723 100644
--- a/arch/sparc64/config.in
+++ b/arch/sparc64/config.in
@@ -15,6 +15,7 @@
 define_bool CONFIG_VT_CONSOLE y
 
 bool 'Symmetric multi-processing support' CONFIG_SMP
+bool 'Preemptible kernel' CONFIG_PREEMPT
 
 # Identify this as a Sparc64 build
 define_bool CONFIG_SPARC64 y
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 42d377c..3100e0f 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -3,6 +3,11 @@
 #
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
 # General setup
 #
 CONFIG_NET=y
@@ -11,11 +16,6 @@
 CONFIG_SYSCTL=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-
-#
 # Loadable module support
 #
 CONFIG_MODULES=y
@@ -456,7 +456,6 @@
 CONFIG_HAPPYMEAL=y
 CONFIG_SUNBMAC=m
 CONFIG_SUNQE=m
-CONFIG_SUNLANCE=y
 CONFIG_SUNGEM=y
 CONFIG_NET_VENDOR_3COM=y
 # CONFIG_EL1 is not set
@@ -487,6 +486,7 @@
 # CONFIG_LNE390 is not set
 CONFIG_FEALNX=m
 CONFIG_NATSEMI=m
+# CONFIG_NATSEMI_CABLE_MAGIC is not set
 CONFIG_NE2K_PCI=m
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
@@ -495,6 +495,7 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 CONFIG_SIS900=m
 CONFIG_EPIC100=m
 CONFIG_SUNDANCE=m
@@ -575,7 +576,7 @@
 # CONFIG_DRM_R128 is not set
 
 #
-# Input core support
+# Input device support
 #
 CONFIG_INPUT=y
 CONFIG_INPUT_KEYBDEV=y
@@ -584,6 +585,36 @@
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
 CONFIG_INPUT_EVDEV=y
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_GAMEPORT_PCIGAME is not set
+# CONFIG_GAMEPORT_FM801 is not set
+# CONFIG_GAMEPORT_CS461x is not set
+# CONFIG_SERIO is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
+# CONFIG_JOYSTICK_IFORCE_USB is not set
+# CONFIG_JOYSTICK_IFORCE_232 is not set
+# CONFIG_JOYSTICK_WARRIOR is not set
+# CONFIG_JOYSTICK_MAGELLAN is not set
+# CONFIG_JOYSTICK_SPACEORB is not set
+# CONFIG_JOYSTICK_SPACEBALL is not set
+# CONFIG_JOYSTICK_STINGER is not set
+# CONFIG_JOYSTICK_DB9 is not set
+# CONFIG_JOYSTICK_GAMECON is not set
+# CONFIG_JOYSTICK_TURBOGRAFX is not set
 
 #
 # File systems
@@ -639,7 +670,7 @@
 # Network File Systems
 #
 CONFIG_CODA_FS=m
-CONFIG_INTERMEZZO_FS=m
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_ROOT_NFS is not set
@@ -659,7 +690,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -887,3 +917,5 @@
 # Library routines
 #
 CONFIG_CRC32=y
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index b4b2515..51dd9f3 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.69 2001/11/19 04:09:53 davem Exp $
+# $Id: Makefile,v 1.70 2002/02/09 19:49:30 davem Exp $
 # Makefile for the linux kernel.
 #
 # Note! Dependencies are done automagically by 'make dep', which also
@@ -56,118 +56,4 @@
   CMODEL_CFLAG := -m64 -mcmodel=medlow
 endif
 
-check_asm: dummy
-	@if [ ! -r $(HPATH)/asm/asm_offsets.h ] ; then \
-	  touch $(HPATH)/asm/asm_offsets.h ; \
-	fi
-	@echo "/* Automatically generated. Do not edit. */" > asm_offsets.h
-	@echo "#ifndef __ASM_OFFSETS_H__" >> asm_offsets.h
-	@echo -e "#define __ASM_OFFSETS_H__\n" >> asm_offsets.h
-	@echo -e "#include <linux/config.h>\n" >> asm_offsets.h
-	@echo -e "#ifndef CONFIG_SMP\n" >> asm_offsets.h
-	@echo "#include <linux/config.h>" > tmp.c
-	@echo "#undef CONFIG_SMP" >> tmp.c
-	@echo "#include <linux/sched.h>" >> tmp.c
-	$(CPP) $(CPPFLAGS) -P tmp.c -o tmp.i
-	@echo "/* Automatically generated. Do not edit. */" > check_asm_data.c
-	@echo "#include <linux/config.h>" >> check_asm_data.c
-	@echo "#undef CONFIG_SMP" >> check_asm_data.c
-	@echo "#include <linux/sched.h>" >> check_asm_data.c
-	@echo 'unsigned int check_asm_data[] = {' >> check_asm_data.c
-	$(SH) ./check_asm.sh -data task tmp.i check_asm_data.c
-	$(SH) ./check_asm.sh -data mm tmp.i check_asm_data.c
-	$(SH) ./check_asm.sh -data thread tmp.i check_asm_data.c
-	@echo '};' >> check_asm_data.c
-	$(CC) $(CPPFLAGS) $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm_data.s check_asm_data.c
-	@echo "/* Automatically generated. Do not edit. */" > check_asm.c
-	@echo 'extern int printf(const char *fmt, ...);' >>check_asm.c
-	@echo 'unsigned int check_asm_data[] = {' >> check_asm.c
-	$(SH) ./check_asm.sh -ints check_asm_data.s check_asm.c
-	@echo '};' >> check_asm.c
-	@echo 'int main(void) {' >> check_asm.c
-	@echo 'int i = 0;' >> check_asm.c
-	$(SH) ./check_asm.sh -printf task tmp.i check_asm.c
-	$(SH) ./check_asm.sh -printf mm tmp.i check_asm.c
-	$(SH) ./check_asm.sh -printf thread tmp.i check_asm.c
-	@echo 'return 0; }' >> check_asm.c
-	@rm -f tmp.[ci] check_asm_data.[cs]
-	$(HOSTCC) -o check_asm check_asm.c
-	./check_asm >> asm_offsets.h
-	@rm -f check_asm check_asm.c
-	@echo -e "\n#else /* CONFIG_SMP */\n" >> asm_offsets.h
-	@echo -e "#ifndef CONFIG_DEBUG_SPINLOCK\n" >>asm_offsets.h
-	@echo "#include <linux/config.h>" > tmp.c
-	@echo "#undef CONFIG_SMP" >> tmp.c
-	@echo "#define CONFIG_SMP 1" >> tmp.c
-	@echo "#include <linux/sched.h>" >> tmp.c
-	$(CPP) $(CPPFLAGS) -P tmp.c -o tmp.i
-	@echo "/* Automatically generated. Do not edit. */" > check_asm_data.c
-	@echo "#include <linux/config.h>" >> check_asm_data.c
-	@echo "#undef CONFIG_SMP" >> check_asm_data.c
-	@echo "#define CONFIG_SMP 1" >> check_asm_data.c
-	@echo "#include <linux/sched.h>" >> check_asm_data.c
-	@echo 'unsigned int check_asm_data[] = {' >> check_asm_data.c
-	$(SH) ./check_asm.sh -data task tmp.i check_asm_data.c
-	$(SH) ./check_asm.sh -data mm tmp.i check_asm_data.c
-	$(SH) ./check_asm.sh -data thread tmp.i check_asm_data.c
-	@echo '};' >> check_asm_data.c
-	$(CC) $(CPPFLAGS) $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm_data.s check_asm_data.c
-	@echo "/* Automatically generated. Do not edit. */" > check_asm.c
-	@echo 'extern int printf(const char *fmt, ...);' >>check_asm.c
-	@echo 'unsigned int check_asm_data[] = {' >> check_asm.c
-	$(SH) ./check_asm.sh -ints check_asm_data.s check_asm.c
-	@echo '};' >> check_asm.c
-	@echo 'int main(void) {' >> check_asm.c
-	@echo 'int i = 0;' >> check_asm.c
-	$(SH) ./check_asm.sh -printf task tmp.i check_asm.c
-	$(SH) ./check_asm.sh -printf mm tmp.i check_asm.c
-	$(SH) ./check_asm.sh -printf thread tmp.i check_asm.c
-	@echo 'return 0; }' >> check_asm.c
-	@rm -f tmp.[ci] check_asm_data.[cs]
-	$(HOSTCC) -o check_asm check_asm.c
-	./check_asm >> asm_offsets.h
-	@rm -f check_asm check_asm.c
-	@echo -e "\n#else /* CONFIG_DEBUG_SPINLOCK */\n" >> asm_offsets.h
-	@echo "#include <linux/sched.h>" > tmp.c
-	$(CPP) $(CPPFLAGS) -P -DCONFIG_DEBUG_SPINLOCK tmp.c -o tmp.i
-	@echo "/* Automatically generated. Do not edit. */" > check_asm_data.c
-	@echo "#include <linux/config.h>" >> check_asm_data.c
-	@echo "#undef CONFIG_SMP" >> check_asm_data.c
-	@echo "#define CONFIG_SMP 1" >> check_asm_data.c
-	@echo "#include <linux/sched.h>" >> check_asm_data.c
-	@echo 'unsigned int check_asm_data[] = {' >> check_asm_data.c
-	$(SH) ./check_asm.sh -data task tmp.i check_asm_data.c
-	$(SH) ./check_asm.sh -data mm tmp.i check_asm_data.c
-	$(SH) ./check_asm.sh -data thread tmp.i check_asm_data.c
-	@echo '};' >> check_asm_data.c
-	$(CC) $(CPPFLAGS) -DCONFIG_DEBUG_SPINLOCK $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm_data.s check_asm_data.c
-	@echo "/* Automatically generated. Do not edit. */" > check_asm.c
-	@echo 'extern int printf(const char *fmt, ...);' >>check_asm.c
-	@echo 'unsigned int check_asm_data[] = {' >> check_asm.c
-	$(SH) ./check_asm.sh -ints check_asm_data.s check_asm.c
-	@echo '};' >> check_asm.c
-	@echo 'int main(void) {' >> check_asm.c
-	@echo 'int i = 0;' >> check_asm.c
-	$(SH) ./check_asm.sh -printf task tmp.i check_asm.c
-	$(SH) ./check_asm.sh -printf mm tmp.i check_asm.c
-	$(SH) ./check_asm.sh -printf thread tmp.i check_asm.c
-	@echo 'return 0; }' >> check_asm.c
-	@rm -f tmp.[ci] check_asm_data.[cs]
-	$(HOSTCC) -o check_asm check_asm.c
-	./check_asm >> asm_offsets.h
-	@rm -f check_asm check_asm.c
-	@echo -e "#endif /* CONFIG_DEBUG_SPINLOCK */\n" >> asm_offsets.h
-	@echo -e "#endif /* CONFIG_SMP */\n" >> asm_offsets.h
-	@echo "#endif /* __ASM_OFFSETS_H__ */" >> asm_offsets.h
-	@if test -r $(HPATH)/asm/asm_offsets.h; then \
-	  if cmp -s asm_offsets.h $(HPATH)/asm/asm_offsets.h; then \
-	    echo $(HPATH)/asm/asm_offsets.h is unchanged; \
-	    rm -f asm_offsets.h; \
-	  else \
-	    mv -f asm_offsets.h $(HPATH)/asm/asm_offsets.h; \
-	  fi; \
-	else \
-	  mv -f asm_offsets.h $(HPATH)/asm/asm_offsets.h; \
-	fi
-
 include $(TOPDIR)/Rules.make
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
index f05e57c..1feb6bd 100644
--- a/arch/sparc64/kernel/binfmt_aout32.c
+++ b/arch/sparc64/kernel/binfmt_aout32.c
@@ -314,7 +314,7 @@
 
 	current->mm->start_stack =
 		(unsigned long) create_aout32_tables((char *)bprm->p, bprm);
-	if (!(current->thread.flags & SPARC_FLAG_32BIT)) {
+	if (!(test_thread_flag(TIF_32BIT))) {
 		unsigned long pgd_cache;
 
 		pgd_cache = ((unsigned long)current->mm->pgd[0])<<11UL;
@@ -323,7 +323,7 @@
 				     : /* no outputs */
 				     : "r" (pgd_cache),
 				       "r" (TSB_REG), "i" (ASI_DMMU));
-		current->thread.flags |= SPARC_FLAG_32BIT;
+		set_thread_flag(TIF_32BIT);
 	}
 	start_thread32(regs, ex.a_entry, current->mm->start_stack);
 	if (current->ptrace & PT_PTRACED)
diff --git a/arch/sparc64/kernel/binfmt_elf32.c b/arch/sparc64/kernel/binfmt_elf32.c
index 6d9e291..5b742bc 100644
--- a/arch/sparc64/kernel/binfmt_elf32.c
+++ b/arch/sparc64/kernel/binfmt_elf32.c
@@ -149,7 +149,7 @@
 #ifdef CONFIG_BINFMT_ELF32_MODULE
 #define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE
 #endif
-#define ELF_FLAGS_INIT	current->thread.flags |= SPARC_FLAG_32BIT
+#define ELF_FLAGS_INIT	set_thread_flag(TIF_32BIT)
 
 MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit SparcLinux binaries on the Ultra");
 MODULE_AUTHOR("Eric Youngdale, David S. Miller, Jakub Jelinek");
diff --git a/arch/sparc64/kernel/check_asm.sh b/arch/sparc64/kernel/check_asm.sh
deleted file mode 100755
index 65259c2..0000000
--- a/arch/sparc64/kernel/check_asm.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-case $1 in
-  -printf)
-    sed -n -e '/^#/d;/struct[ 	]*'$2'_struct[ 	]*{/,/};/p' < $3 | sed '/struct[ 	]*'$2'_struct[ 	]*{/d;/:[0-9]*[ 	]*;/d;/^[ 	]*$/d;/};/d;s/^[ 	]*//;s/volatile[ 	]*//;s/\(unsigned\|signed\|struct\)[ 	]*//;s/\(\[\|__attribute__\).*;[ 	]*$//;s/(\*//;s/)(.*)//;s/;[ 	]*$//;s/^[^ 	]*[ 	]*//;s/,/\
-/g' | sed 's/^[ 	*]*//;s/[ 	]*$//;s/^.*$/printf ("#define AOFF_'$2'_\0	0x%08x\\n", check_asm_data[i++]); printf("#define ASIZ_'$2'_\0	0x%08x\\n", check_asm_data[i++]);/' >> $4
-    echo "printf (\"#define ASIZ_$2\\t0x%08x\\n\", check_asm_data[i++]);" >> $4
-  ;;
-  -data)
-    sed -n -e '/^#/d;/struct[ 	]*'$2'_struct[ 	]*{/,/};/p' < $3 | sed '/struct[ 	]*'$2'_struct[ 	]*{/d;/:[0-9]*[ 	]*;/d;/^[ 	]*$/d;/};/d;s/^[ 	]*//;s/volatile[ 	]*//;s/\(unsigned\|signed\|struct\)[ 	]*//;s/\(\[\|__attribute__\).*;[ 	]*$//;s/(\*//;s/)(.*)//;s/;[ 	]*$//;s/^[^ 	]*[ 	]*//;s/,/\
-/g' | sed 's/^[ 	*]*//;s/[ 	]*$//;s/^.*$/	((char *)\&((struct '$2'_struct *)0)->\0) - ((char *)((struct '$2'_struct *)0)),	sizeof(((struct '$2'_struct *)0)->\0),/' >> $4
-    echo "	sizeof(struct $2_struct)," >> $4
-  ;;
-  -ints)
-    sed -n -e '/check_asm_data:/,/\.size/p' <$2 | sed -e 's/check_asm_data://' -e 's/\.size.*//' -e 's/\.long[		]\([0-9]*\)/\1,/' | grep -v '\.ident' >>$3
-  ;;
-  *)
-    exit 1
-  ;;
-esac
-exit 0
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index e1e76b0..d687ae2 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.142 2002/01/31 03:30:06 davem Exp $
+/* $Id: entry.S,v 1.144 2002/02/09 19:49:30 davem Exp $
  * arch/sparc64/kernel/entry.S:  Sparc64 trap low-level entry points.
  *
  * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -151,12 +151,12 @@
 	add		%g0, %g0, %g0
 	ba,a,pt		%xcc, rtrap_clr_l6
 
-1:	ldub		[%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g5	! Load	Group
+1:	ldub		[%g6 + TI_FPSAVED], %g5					! Load	Group
 	wr		%g0, FPRS_FEF, %fprs					! LSU	Group+4bubbles
 	andcc		%g5, FPRS_FEF, %g0					! IEU1	Group
 	be,a,pt		%icc, 1f						! CTI
 	 clr		%g7							! IEU0
-	ldx		[%g6 + AOFF_task_thread + AOFF_thread_gsr], %g7		! Load	Group
+	ldx		[%g6 + TI_GSR], %g7					! Load	Group
 1:	andcc		%g5, FPRS_DL, %g0					! IEU1
 	bne,pn		%icc, 2f						! CTI
 	 fzero		%f0							! FPA
@@ -194,11 +194,11 @@
 	b,pt		%xcc, fpdis_exit2
 	 faddd		%f0, %f2, %f60
 1:	mov		SECONDARY_CONTEXT, %g3
-	add		%g6, AOFF_task_fpregs + 0x80, %g1
+	add		%g6, TI_FPREGS + 0x80, %g1
 	faddd		%f0, %f2, %f4
 	fmuld		%f0, %f2, %f6
 	ldxa		[%g3] ASI_DMMU, %g5
-	add		%g6, AOFF_task_fpregs + 0xc0, %g2
+	add		%g6, TI_FPREGS + 0xc0, %g2
 	stxa		%g0, [%g3] ASI_DMMU
 	membar		#Sync
 	faddd		%f0, %f2, %f8
@@ -223,10 +223,10 @@
 	mov		SECONDARY_CONTEXT, %g3
 	fzero		%f34
 	ldxa		[%g3] ASI_DMMU, %g5
-	add		%g6, AOFF_task_fpregs, %g1
+	add		%g6, TI_FPREGS, %g1
 	stxa		%g0, [%g3] ASI_DMMU
 	membar		#Sync
-	add		%g6, AOFF_task_fpregs + 0x40, %g2
+	add		%g6, TI_FPREGS + 0x40, %g2
 	faddd		%f32, %f34, %f36
 	fmuld		%f32, %f34, %f38
 	ldda		[%g1] ASI_BLK_S, %f0	! grrr, where is ASI_BLK_NUCLEUS 8-(
@@ -246,7 +246,7 @@
 	ba,pt		%xcc, fpdis_exit
 	 membar		#Sync
 3:	mov		SECONDARY_CONTEXT, %g3
-	add		%g6, AOFF_task_fpregs, %g1
+	add		%g6, TI_FPREGS, %g1
 	ldxa		[%g3] ASI_DMMU, %g5
 	mov		0x40, %g2
 	stxa		%g0, [%g3] ASI_DMMU
@@ -262,7 +262,7 @@
 	membar		#Sync
 fpdis_exit2:
 	wr		%g7, 0, %gsr
-	ldx		[%g6 + AOFF_task_thread + AOFF_thread_xfsr], %fsr
+	ldx		[%g6 + TI_XFSR], %fsr
 	rdpr		%tstate, %g3
 	or		%g3, %g4, %g3		! anal...
 	wrpr		%g3, %tstate
@@ -285,12 +285,12 @@
 	/* NOTE: Need to preserve %g7 until we fully commit
 	 *       to the fitos fixup.
 	 */
-	stx		%fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr]
+	stx		%fsr, [%g6 + TI_XFSR]
 	rdpr		%tstate, %g3
 	andcc		%g3, TSTATE_PRIV, %g0
 	bne,pn		%xcc, do_fptrap_after_fsr
 	 nop
-	ldx		[%g6 + AOFF_task_thread + AOFF_thread_xfsr], %g3
+	ldx		[%g6 + TI_XFSR], %g3
 	srlx		%g3, 14, %g1
 	and		%g1, 7, %g1
 	cmp		%g1, 2			! Unfinished FP-OP
@@ -310,7 +310,7 @@
 	cmp		%g1, %g2
 	bne,pn		%xcc, do_fptrap_after_fsr
 	 nop
-	std		%f62, [%g6 + AOFF_task_fpregs + (62 * 4)]
+	std		%f62, [%g6 + TI_FPREGS + (62 * 4)]
 	sethi		%hi(fitos_table_1), %g1
 	and		%g3, 0x1f, %g2
 	or		%g1, %lo(fitos_table_1),  %g1
@@ -396,22 +396,22 @@
 	fdtos		%f62, %f31
 
 fitos_emul_fini:
-	ldd		[%g6 + AOFF_task_fpregs + (62 * 4)], %f62
+	ldd		[%g6 + TI_FPREGS + (62 * 4)], %f62
 	done
 
 	.globl		do_fptrap
 	.align		32
 do_fptrap:
-	stx		%fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr]
+	stx		%fsr, [%g6 + TI_XFSR]
 do_fptrap_after_fsr:
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g3
+	ldub		[%g6 + TI_FPSAVED], %g3
 	rd		%fprs, %g1
 	or		%g3, %g1, %g3
-	stb		%g3, [%g6 + AOFF_task_thread + AOFF_thread_fpsaved]
+	stb		%g3, [%g6 + TI_FPSAVED]
 	rd		%gsr, %g3
-	stx		%g3, [%g6 + AOFF_task_thread + AOFF_thread_gsr]
+	stx		%g3, [%g6 + TI_GSR]
 	mov		SECONDARY_CONTEXT, %g3
-	add		%g6, AOFF_task_fpregs, %g2
+	add		%g6, TI_FPREGS, %g2
 	ldxa		[%g3] ASI_DMMU, %g5
 	stxa		%g0, [%g3] ASI_DMMU
 	membar		#Sync
@@ -713,8 +713,8 @@
 	call		sparc_floppy_irq
 	 add		%sp, STACK_BIAS + REGWIN_SZ, %o2
 
-	b,pt		%xcc, rtrap
-	 clr		%l6
+	b,pt		%xcc, rtrap_irq
+	 nop
 
 #endif /* CONFIG_BLK_DEV_FD */
 
@@ -883,7 +883,7 @@
 	mov	%l5, %o1
 	call	cee_log
 	 add	%sp, STACK_BIAS + REGWIN_SZ, %o2
-	ba,a,pt	%xcc, rtrap_clr_l6
+	ba,a,pt	%xcc, rtrap_irq
 
 	/* Capture I/D/E-cache state into per-cpu error scoreboard.
 	 *
@@ -1109,7 +1109,7 @@
 	mov		%l5, %o2
 	call		cheetah_fecc_handler
 	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
-	ba,a,pt		%xcc, rtrap_clr_l6
+	ba,a,pt		%xcc, rtrap_irq
 
 	/* Our caller has disabled I-cache and performed membar Sync. */
 	.globl		cheetah_cee
@@ -1135,7 +1135,7 @@
 	mov		%l5, %o2
 	call		cheetah_cee_handler
 	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
-	ba,a,pt		%xcc, rtrap_clr_l6
+	ba,a,pt		%xcc, rtrap_irq
 
 	/* Our caller has disabled I-cache+D-cache and performed membar Sync. */
 	.globl		cheetah_deferred_trap
@@ -1161,7 +1161,7 @@
 	mov		%l5, %o2
 	call		cheetah_deferred_handler
 	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
-	ba,a,pt		%xcc, rtrap_clr_l6
+	ba,a,pt		%xcc, rtrap_irq
 
 	.globl		__do_privact
 __do_privact:
@@ -1384,8 +1384,8 @@
 		 add		%o7, 1f-.-4, %o7
 		nop
 		.align		32
-1:		ldub		[%curptr + AOFF_task_work + 1], %l5
-		andcc		%l5, 0xff, %g0
+1:		ldx		[%curptr + TI_FLAGS], %l5
+		andcc		%l5, _TIF_SYSCALL_TRACE, %g0
 		be,pt		%icc, rtrap
 		 clr		%l6
 		call		syscall_trace
@@ -1435,14 +1435,14 @@
 		/* Clear SPARC_FLAG_NEWCHILD, switch_to leaves thread.flags in
 		 * %o7 for us.  Check performance counter stuff too.
 		 */
-		andn		%o7, SPARC_FLAG_NEWCHILD, %l0
+		andn		%o7, _TIF_NEWCHILD, %l0
 		mov		%g5, %o0	/* 'prev' */
 		call		schedule_tail
-		 stb		%l0, [%g6 + AOFF_task_thread + AOFF_thread_flags]
-		andcc		%l0, SPARC_FLAG_PERFCTR, %g0
+		 stx		%l0, [%g6 + TI_FLAGS]
+		andcc		%l0, _TIF_PERFCTR, %g0
 		be,pt		%icc, 1f
 		 nop
-		ldx		[%g6 + AOFF_task_thread + AOFF_thread_pcr_reg], %o7
+		ldx		[%g6 + TI_PCR], %o7
 		wr		%g0, %o7, %pcr
 
 		/* Blackbird errata workaround.  See commentary in
@@ -1465,7 +1465,7 @@
 		wrpr		%g0, 0x0, %otherwin
 		wrpr		%g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV | PSTATE_IE), %pstate
 		ba,pt		%xcc, sys_exit
-		 stb		%g0, [%g6 + AOFF_task_thread + AOFF_thread_w_saved]
+		 stb		%g0, [%g6 + TI_WSAVED]
 
 linux_sparc_ni_syscall:
 	sethi		%hi(sys_ni_syscall), %l7
@@ -1510,11 +1510,11 @@
 	mov		%i4, %o4				! IEU1
 	lduw		[%l7 + %l4], %l7			! Load
 	srl		%i1, 0, %o1				! IEU0	Group
-	ldub		[%curptr + AOFF_task_work + 1], %l0	! Load
+	ldx		[%curptr + TI_FLAGS], %l0		! Load
 
 	mov		%i5, %o5				! IEU1
 	srl		%i2, 0, %o2				! IEU0	Group
-	andcc		%l0, 0xff, %g0				! IEU0	Group
+	andcc		%l0, _TIF_SYSCALL_TRACE, %g0		! IEU0	Group
 	bne,pn		%icc, linux_syscall_trace32		! CTI
 	 mov		%i0, %l5				! IEU1
 	call		%l7					! CTI	Group brk forced
@@ -1538,11 +1538,11 @@
 	mov		%i1, %o1				! IEU1
 	lduw		[%l7 + %l4], %l7			! Load
 4:	mov		%i2, %o2				! IEU0	Group
-	ldub		[%curptr + AOFF_task_work + 1], %l0	! Load
+	ldx		[%curptr + TI_FLAGS], %l0		! Load
 
 	mov		%i3, %o3				! IEU1
 	mov		%i4, %o4				! IEU0	Group
-	andcc		%l0, 0xff, %g0				! IEU1	Group+1 bubble
+	andcc		%l0, _TIF_SYSCALL_TRACE, %g0		! IEU1	Group+1 bubble
 	bne,pn		%icc, linux_syscall_trace		! CTI	Group
 	 mov		%i0, %l5				! IEU0
 2:	call		%l7					! CTI	Group brk forced
@@ -1565,7 +1565,7 @@
 	sllx		%g2, 32, %g2
 	bgeu,pn		%xcc, 1f
 
-	 andcc		%l0, 0x02, %l6	
+	 andcc		%l0, _TIF_SYSCALL_TRACE, %l6	
 	andn		%g3, %g2, %g3		/* System call success, clear Carry condition code. */
 	stx		%g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE]	
 	bne,pn		%icc, linux_syscall_trace2
diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S
index a051180..60a94bd 100644
--- a/arch/sparc64/kernel/etrap.S
+++ b/arch/sparc64/kernel/etrap.S
@@ -1,10 +1,12 @@
-/* $Id: etrap.S,v 1.45 2001/09/07 21:04:40 kanoj Exp $
+/* $Id: etrap.S,v 1.46 2002/02/09 19:49:30 davem Exp $
  * etrap.S: Preparing for entry into the kernel on Sparc V9.
  *
  * Copyright (C) 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
  * Copyright (C) 1997, 1998, 1999 Jakub Jelinek (jj@ultra.linux.cz)
  */
 
+#include <linux/config.h>
+
 #include <asm/asi.h>
 #include <asm/pstate.h>
 #include <asm/ptrace.h>
@@ -25,9 +27,17 @@
 		.text		
 		.align	64
 		.globl	etrap, etrap_irq, etraptl1
-
+#ifdef CONFIG_PREEMPT
+etrap_irq:	ldsw	[%g6 + TI_PRE_COUNT], %g1
+		add	%g1, 1, %g1
+		ba,pt	%xcc, etrap_irq2
+		 stw	%g1, [%g6 + TI_PRE_COUNT]
+#endif
 etrap:		rdpr	%pil, %g2						! Single 	Group
-etrap_irq:	rdpr	%tstate, %g1						! Single 	Group
+#ifndef CONFIG_PREEMPT
+etrap_irq:
+#endif
+etrap_irq2:	rdpr	%tstate, %g1						! Single 	Group
 		sllx	%g2, 20, %g3						! IEU0		Group
 		andcc	%g1, TSTATE_PRIV, %g0					! IEU1
 		or	%g1, %g3, %g1						! IEU0		Group
@@ -60,7 +70,7 @@
 		wrpr	%g0, 0, %canrestore					! Single	Group+4bubbles
 		sll	%g2, 3, %g2						! IEU0		Group
 		mov	1, %l5							! IEU1
-		stb	%l5, [%l6 + AOFF_task_thread + AOFF_thread_fpdepth]	! Store
+		stb	%l5, [%l6 + TI_FPDEPTH]					! Store
 
 		wrpr	%g3, 0, %otherwin					! Single	Group+4bubbles
 		wrpr	%g2, 0, %wstate						! Single	Group+4bubbles
@@ -98,11 +108,11 @@
 		nop
 		nop
 
-3:		ldub	[%l6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5	! Load		Group
-		add	%l6, AOFF_task_thread + AOFF_thread_fpsaved + 1, %l4	! IEU0
+3:		ldub	[%l6 + TI_FPDEPTH], %l5					! Load		Group
+		add	%l6, TI_FPSAVED + 1, %l4				! IEU0
 		srl	%l5, 1, %l3						! IEU0		Group
 		add	%l5, 2, %l5						! IEU1
-		stb	%l5, [%l6 + AOFF_task_thread + AOFF_thread_fpdepth]	! Store
+		stb	%l5, [%l6 + TI_FPDEPTH]					! Store
 		ba,pt	%xcc, 2b						! CTI
 		 stb	%g0, [%l4 + %l3]					! Store		Group
 		nop
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index c8f7525..73c180b 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.86 2001/12/05 01:02:16 davem Exp $
+/* $Id: head.S,v 1.87 2002/02/09 19:49:31 davem Exp $
  * head.S: Initial boot code for the Sparc64 port of Linux.
  *
  * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -10,7 +10,7 @@
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/errno.h>
-#include <asm/asm_offsets.h>
+#include <asm/thread_info.h>
 #include <asm/asi.h>
 #include <asm/pstate.h>
 #include <asm/ptrace.h>
@@ -491,8 +491,8 @@
 	stw	%g2, [%g5 + %lo(tlb_type)]
 
 tlb_fixup_done:
-	sethi	%hi(init_task_union), %g6
-	or	%g6, %lo(init_task_union), %g6
+	sethi	%hi(init_thread_union), %g6
+	or	%g6, %lo(init_thread_union), %g6
 	mov	%sp, %l6
 	mov	%o4, %l7
 
diff --git a/arch/sparc64/kernel/init_task.c b/arch/sparc64/kernel/init_task.c
index ae8150a..1def381 100644
--- a/arch/sparc64/kernel/init_task.c
+++ b/arch/sparc64/kernel/init_task.c
@@ -12,17 +12,25 @@
 struct mm_struct init_mm = INIT_MM(init_mm);
 
 /* .text section in head.S is aligned at 2 page boundry and this gets linked
- * right after that so that the init_task_union is aligned properly as well.
+ * right after that so that the init_thread_union is aligned properly as well.
  * We really don't need this special alignment like the Intel does, but
  * I do it anyways for completeness.
  */
 __asm__ (".text");
-union task_union init_task_union = { INIT_TASK(init_task_union.task) };
+union thread_union init_thread_union = { INIT_THREAD_INFO(init_task) };
 
 /*
- * This is to make the init_task+stack of the right size for >8k pagesize.
- * The definition of task_union in sched.h makes it 16k wide.
+ * This is to make the init_thread+stack be the right size for >8k pagesize.
+ * The definition of thread_union in sched.h makes it 16k wide.
  */
 #if PAGE_SHIFT != 13
-char init_task_stack[THREAD_SIZE - INIT_TASK_SIZE] = { 0 };
+char init_task_stack[THREAD_SIZE - INIT_THREAD_SIZE] = { 0 };
 #endif
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+__asm__(".data");
+struct task_struct init_task = INIT_TASK(init_task);
diff --git a/arch/sparc64/kernel/itlb_base.S b/arch/sparc64/kernel/itlb_base.S
index e98502c..577274e 100644
--- a/arch/sparc64/kernel/itlb_base.S
+++ b/arch/sparc64/kernel/itlb_base.S
@@ -1,4 +1,4 @@
-/* $Id: itlb_base.S,v 1.11 2001/08/17 04:55:09 kanoj Exp $
+/* $Id: itlb_base.S,v 1.12 2002/02/09 19:49:30 davem Exp $
  * itlb_base.S:	Front end to ITLB miss replacement strategy.
  *              This is included directly into the trap table.
  *
@@ -51,8 +51,8 @@
 	rdpr		%tpc, %g5			! And load faulting VA
 	mov		FAULT_CODE_ITLB, %g4		! It was read from ITLB
 sparc64_realfault_common:				! Called by TL0 dtlb_miss too
-	stb		%g4, [%g6 + AOFF_task_thread + AOFF_thread_fault_code]
-	stx		%g5, [%g6 + AOFF_task_thread + AOFF_thread_fault_address]
+	stb		%g4, [%g6 + TI_FAULT_CODE]
+	stx		%g5, [%g6 + TI_FAULT_ADDR]
 	ba,pt		%xcc, etrap			! Save state
 1:	 rd		%pc, %g7			! ...
 	nop
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c
index 3a1a02a..414fe7b 100644
--- a/arch/sparc64/kernel/pci_common.c
+++ b/arch/sparc64/kernel/pci_common.c
@@ -1,4 +1,4 @@
-/* $Id: pci_common.c,v 1.28 2002/01/14 05:47:02 davem Exp $
+/* $Id: pci_common.c,v 1.29 2002/02/01 00:56:03 davem Exp $
  * pci_common.c: PCI controller common support.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -670,6 +670,20 @@
 	int prom_node = pcp->prom_node;
 	int err;
 
+	/* If this is an empty EBUS device, sometimes OBP fails to
+	 * give it a valid fully specified interrupts property.
+	 * The EBUS hooked up to SunHME on PCI I/O boards of
+	 * Ex000 systems is one such case.
+	 *
+	 * The interrupt is not important so just ignore it.
+	 */
+	if (pdev->vendor == PCI_VENDOR_ID_SUN &&
+	    pdev->device == PCI_DEVICE_ID_SUN_EBUS &&
+	    !prom_getchild(prom_node)) {
+		pdev->irq = 0;
+		return;
+	}
+
 	err = prom_getproperty(prom_node, "interrupts",
 			       (char *)&prom_irq, sizeof(prom_irq));
 	if (err == 0 || err == -1) {
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 5adac65..a30493e 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -1,4 +1,4 @@
-/* $Id: pci_psycho.c,v 1.32 2002/01/23 11:27:32 davem Exp $
+/* $Id: pci_psycho.c,v 1.33 2002/02/01 00:58:33 davem Exp $
  * pci_psycho.c: PSYCHO/U2P specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -13,7 +13,6 @@
 #include <linux/slab.h>
 
 #include <asm/pbm.h>
-#include <asm/fhc.h>
 #include <asm/iommu.h>
 #include <asm/irq.h>
 #include <asm/starfire.h>
@@ -1495,8 +1494,6 @@
 	} else {
 		pbm = &p->pbm_B;
 		pbm->pci_first_slot = 2;
-		if (central_bus != NULL)
-			pbm->pci_first_slot = 1;
 		pbm->io_space.start = p->controller_regs + PSYCHO_IOSPACE_B;
 		pbm->mem_space.start = p->controller_regs + PSYCHO_MEMSPACE_B;
 	}
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index a4a190d..143bbcf 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -1,4 +1,4 @@
-/*  $Id: process.c,v 1.130 2002/01/31 03:30:06 davem Exp $
+/*  $Id: process.c,v 1.131 2002/02/09 19:49:30 davem Exp $
  *  arch/sparc64/kernel/process.c
  *
  *  Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -79,10 +79,13 @@
 #define unidle_me()		(cpu_data[smp_processor_id()].idle_volume = 0)
 int cpu_idle(void)
 {
+	set_thread_flag(TIF_POLLING_NRFLAG);
 	while(1) {
 		if (need_resched()) {
 			unidle_me();
+			clear_thread_flag(TIF_POLLING_NRFLAG);
 			schedule();
+			set_thread_flag(TIF_POLLING_NRFLAG);
 			check_pgt_cache();
 		}
 		idle_me_harder();
@@ -97,6 +100,18 @@
 
 #endif
 
+#ifdef CONFIG_PREEMPT
+void kpreempt_maybe(void)
+{
+	int cpu = smp_processor_id();
+
+	if (local_irq_count(cpu) == 0 &&
+	    local_bh_count(cpu) == 0)
+		preempt_schedule();
+	current_thread_info()->preempt_count--;
+}
+#endif
+
 extern char reboot_command [];
 
 #ifdef CONFIG_SUN_CONSOLE
@@ -176,7 +191,7 @@
 	struct reg_window r_w;
 	mm_segment_t old_fs;
 
-	if ((regs->tstate & TSTATE_PRIV) || !(current->thread.flags & SPARC_FLAG_32BIT)) {
+	if ((regs->tstate & TSTATE_PRIV) || !(test_thread_flag(TIF_32BIT))) {
 		__asm__ __volatile__ ("flushw");
 		rw = (struct reg_window *)(regs->u_regs[14] + STACK_BIAS);
 		if (!(regs->tstate & TSTATE_PRIV)) {
@@ -364,34 +379,29 @@
 	       regs->u_regs[15]);
 }
 
-void show_thread(struct thread_struct *thread)
+unsigned long thread_saved_pc(struct task_struct *tsk)
 {
-	int i;
-
-#if 0
-	printk("kregs:             0x%016lx\n", (unsigned long)thread->kregs);
-	show_regs(thread->kregs);
-#endif	
-	printk("ksp:               0x%016lx\n", thread->ksp);
-
-	if (thread->w_saved) {
-		for (i = 0; i < NSWINS; i++) {
-			if (!thread->rwbuf_stkptrs[i])
-				continue;
-			printk("reg_window[%d]:\n", i);
-			printk("stack ptr:         0x%016lx\n", thread->rwbuf_stkptrs[i]);
+	struct thread_info *ti = tsk->thread_info;
+	unsigned long ret = 0xdeadbeefUL;
+	
+	if (ti && ti->ksp) {
+		unsigned long *sp;
+		sp = (unsigned long *)(ti->ksp + STACK_BIAS);
+		if (((unsigned long)sp & (sizeof(long) - 1)) == 0UL &&
+		    sp[14]) {
+			unsigned long *fp;
+			fp = (unsigned long *)(sp[14] + STACK_BIAS);
+			if (((unsigned long)fp & (sizeof(long) - 1)) == 0UL)
+				ret = fp[15];
 		}
-		printk("w_saved:           0x%04x\n", thread->w_saved);
 	}
-
-	printk("flags:             0x%08x\n", thread->flags);
-	printk("current_ds:        0x%x\n", thread->current_ds.seg);
+	return ret;
 }
 
 /* Free current thread data structures etc.. */
 void exit_thread(void)
 {
-	struct thread_struct *t = &current->thread;
+	struct thread_info *t = current_thread_info();
 
 	if (t->utraps) {
 		if (t->utraps[0] < 2)
@@ -400,22 +410,20 @@
 			t->utraps[0]--;
 	}
 
-	/* Turn off performance counters if on. */
-	if (t->flags & SPARC_FLAG_PERFCTR) {
+	if (test_and_clear_thread_flag(TIF_PERFCTR)) {
 		t->user_cntd0 = t->user_cntd1 = NULL;
 		t->pcr_reg = 0;
-		t->flags &= ~(SPARC_FLAG_PERFCTR);
 		write_pcr(0);
 	}
 }
 
 void flush_thread(void)
 {
-	struct thread_struct *t = &current->thread;
+	struct thread_info *t = current_thread_info();
 
-	if (current->mm) {
-		if (t->flags & SPARC_FLAG_32BIT) {
-			struct mm_struct *mm = current->mm;
+	if (t->task->mm) {
+		if (test_thread_flag(TIF_32BIT)) {
+			struct mm_struct *mm = t->task->mm;
 			pgd_t *pgd0 = &mm->pgd[0];
 			unsigned long pgd_cache;
 
@@ -434,24 +442,23 @@
 					       "i" (ASI_DMMU));
 		}
 	}
-	t->w_saved = 0;
+	set_thread_wsaved(0);
 
 	/* Turn off performance counters if on. */
-	if (t->flags & SPARC_FLAG_PERFCTR) {
+	if (test_and_clear_thread_flag(TIF_PERFCTR)) {
 		t->user_cntd0 = t->user_cntd1 = NULL;
 		t->pcr_reg = 0;
-		t->flags &= ~(SPARC_FLAG_PERFCTR);
 		write_pcr(0);
 	}
 
 	/* Clear FPU register state. */
 	t->fpsaved[0] = 0;
 	
-	if (t->current_ds.seg != ASI_AIUS)
+	if (get_thread_current_ds() != ASI_AIUS)
 		set_fs(USER_DS);
 
 	/* Init new signal delivery disposition. */
-	t->flags &= ~SPARC_FLAG_NEWSIGNALS;
+	clear_thread_flag(TIF_NEWSIGNALS);
 }
 
 /* It's a bit more tricky when 64-bit tasks are involved... */
@@ -459,7 +466,7 @@
 {
 	unsigned long fp, distance, rval;
 
-	if (!(current->thread.flags & SPARC_FLAG_32BIT)) {
+	if (!(test_thread_flag(TIF_32BIT))) {
 		csp += STACK_BIAS;
 		psp += STACK_BIAS;
 		__get_user(fp, &(((struct reg_window *)psp)->ins[6]));
@@ -477,7 +484,7 @@
 	rval = (csp - distance);
 	if (copy_in_user(rval, psp, distance))
 		rval = 0;
-	else if (current->thread.flags & SPARC_FLAG_32BIT) {
+	else if (test_thread_flag(TIF_32BIT)) {
 		if (put_user(((u32)csp), &(((struct reg_window32 *)rval)->ins[6])))
 			rval = 0;
 	} else {
@@ -493,7 +500,7 @@
 
 /* Standard stuff. */
 static inline void shift_window_buffer(int first_win, int last_win,
-				       struct thread_struct *t)
+				       struct thread_info *t)
 {
 	int i;
 
@@ -506,15 +513,15 @@
 
 void synchronize_user_stack(void)
 {
-	struct thread_struct *t = &current->thread;
+	struct thread_info *t = current_thread_info();
 	unsigned long window;
 
 	flush_user_windows();
-	if ((window = t->w_saved) != 0) {
+	if ((window = get_thread_wsaved()) != 0) {
 		int winsize = REGWIN_SZ;
 		int bias = 0;
 
-		if (t->flags & SPARC_FLAG_32BIT)
+		if (test_thread_flag(TIF_32BIT))
 			winsize = REGWIN32_SZ;
 		else
 			bias = STACK_BIAS;
@@ -525,8 +532,8 @@
 			struct reg_window *rwin = &t->reg_window[window];
 
 			if (!copy_to_user((char *)sp, rwin, winsize)) {
-				shift_window_buffer(window, t->w_saved - 1, t);
-				t->w_saved--;
+				shift_window_buffer(window, get_thread_wsaved() - 1, t);
+				set_thread_wsaved(get_thread_wsaved() - 1);
 			}
 		} while (window--);
 	}
@@ -534,18 +541,18 @@
 
 void fault_in_user_windows(void)
 {
-	struct thread_struct *t = &current->thread;
+	struct thread_info *t = current_thread_info();
 	unsigned long window;
 	int winsize = REGWIN_SZ;
 	int bias = 0;
 
-	if (t->flags & SPARC_FLAG_32BIT)
+	if (test_thread_flag(TIF_32BIT))
 		winsize = REGWIN32_SZ;
 	else
 		bias = STACK_BIAS;
 
 	flush_user_windows();
-	window = t->w_saved;
+	window = get_thread_wsaved();
 
 	if (window != 0) {
 		window -= 1;
@@ -557,11 +564,11 @@
 				goto barf;
 		} while (window--);
 	}
-	t->w_saved = 0;
+	set_thread_wsaved(0);
 	return;
 
 barf:
-	t->w_saved = window + 1;
+	set_thread_wsaved(window + 1);
 	do_exit(SIGILL);
 }
 
@@ -581,21 +588,23 @@
 		unsigned long unused,
 		struct task_struct *p, struct pt_regs *regs)
 {
-	struct thread_struct *t = &p->thread;
+	struct thread_info *t = p->thread_info;
 	char *child_trap_frame;
 
 #ifdef CONFIG_DEBUG_SPINLOCK
-	t->smp_lock_count = 0;
-	t->smp_lock_pc = 0;
+	p->thread.smp_lock_count = 0;
+	p->thread.smp_lock_pc = 0;
 #endif
 
 	/* Calculate offset to stack_frame & pt_regs */
-	child_trap_frame = ((char *)p) + (THREAD_SIZE - (TRACEREG_SZ+REGWIN_SZ));
+	child_trap_frame = ((char *)t) + (THREAD_SIZE - (TRACEREG_SZ+REGWIN_SZ));
 	memcpy(child_trap_frame, (((struct reg_window *)regs)-1), (TRACEREG_SZ+REGWIN_SZ));
+
+	t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) |
+		_TIF_NEWCHILD |
+		(((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT);
 	t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS;
-	t->flags |= SPARC_FLAG_NEWCHILD;
 	t->kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct reg_window));
-	t->cwp = (regs->tstate + 1) & TSTATE_CWP;
 	t->fpsaved[0] = 0;
 
 	if (regs->tstate & TSTATE_PRIV) {
@@ -604,25 +613,25 @@
 		 * disable performance counters in the child because the
 		 * address space and protection realm are changing.
 		 */
-		if (t->flags & SPARC_FLAG_PERFCTR) {
+		if (t->flags & _TIF_PERFCTR) {
 			t->user_cntd0 = t->user_cntd1 = NULL;
 			t->pcr_reg = 0;
-			t->flags &= ~(SPARC_FLAG_PERFCTR);
+			t->flags &= ~_TIF_PERFCTR;
 		}
-		t->kregs->u_regs[UREG_FP] = p->thread.ksp;
-		t->current_ds = KERNEL_DS;
+		t->kregs->u_regs[UREG_FP] = t->ksp;
+		t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT);
 		flush_register_windows();
 		memcpy((void *)(t->ksp + STACK_BIAS),
 		       (void *)(regs->u_regs[UREG_FP] + STACK_BIAS),
 		       sizeof(struct reg_window));
-		t->kregs->u_regs[UREG_G6] = (unsigned long) p;
+		t->kregs->u_regs[UREG_G6] = (unsigned long) t;
 	} else {
-		if (t->flags & SPARC_FLAG_32BIT) {
+		if (t->flags & _TIF_32BIT) {
 			sp &= 0x00000000ffffffffUL;
 			regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
 		}
 		t->kregs->u_regs[UREG_FP] = sp;
-		t->current_ds = USER_DS;
+		t->flags |= ((long)ASI_AIUS << TI_FLAG_CURRENT_DS_SHIFT);
 		if (sp != regs->u_regs[UREG_FP]) {
 			unsigned long csp;
 
@@ -688,33 +697,10 @@
  */
 void dump_thread(struct pt_regs * regs, struct user * dump)
 {
-#if 1
 	/* Only should be used for SunOS and ancient a.out
-	 * SparcLinux binaries...  Fixme some day when bored.
-	 * But for now at least plug the security hole :-)
+	 * SparcLinux binaries...  Not worth implementing.
 	 */
 	memset(dump, 0, sizeof(struct user));
-#else
-	unsigned long first_stack_page;
-	dump->magic = SUNOS_CORE_MAGIC;
-	dump->len = sizeof(struct user);
-	dump->regs.psr = regs->psr;
-	dump->regs.pc = regs->pc;
-	dump->regs.npc = regs->npc;
-	dump->regs.y = regs->y;
-	/* fuck me plenty */
-	memcpy(&dump->regs.regs[0], &regs->u_regs[1], (sizeof(unsigned long) * 15));
-	dump->u_tsize = (((unsigned long) current->mm->end_code) -
-		((unsigned long) current->mm->start_code)) & ~(PAGE_SIZE - 1);
-	dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1)));
-	dump->u_dsize -= dump->u_tsize;
-	dump->u_dsize &= ~(PAGE_SIZE - 1);
-	first_stack_page = (regs->u_regs[UREG_FP] & ~(PAGE_SIZE - 1));
-	dump->u_ssize = (TASK_SIZE - first_stack_page) & ~(PAGE_SIZE - 1);
-	memcpy(&dump->fpu.fpstatus.fregs.regs[0], &current->thread.float_regs[0], (sizeof(unsigned long) * 32));
-	dump->fpu.fpstatus.fsr = current->thread.fsr;
-	dump->fpu.fpstatus.flags = dump->fpu.fpstatus.extra = 0;
-#endif	
 }
 
 typedef struct {
@@ -735,10 +721,10 @@
  */
 int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs)
 {
-	unsigned long *kfpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs);
-	unsigned long fprs = current->thread.fpsaved[0];
+	unsigned long *kfpregs = current_thread_info()->fpregs;
+	unsigned long fprs = current_thread_info()->fpsaved[0];
 
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		elf_fpregset_t32 *fpregs32 = (elf_fpregset_t32 *)fpregs;
 
 		if (fprs & FPRS_DL)
@@ -752,7 +738,7 @@
 		memset(&fpregs32->pr_q[0], 0,
 		       (sizeof(unsigned int) * 64));
 		if (fprs & FPRS_FEF) {
-			fpregs32->pr_fsr = (unsigned int) current->thread.xfsr[0];
+			fpregs32->pr_fsr = (unsigned int) current_thread_info()->xfsr[0];
 			fpregs32->pr_en = 1;
 		} else {
 			fpregs32->pr_fsr = 0;
@@ -772,8 +758,8 @@
 			memset(&fpregs->pr_regs[16], 0,
 			       sizeof(unsigned int) * 32);
 		if(fprs & FPRS_FEF) {
-			fpregs->pr_fsr = current->thread.xfsr[0];
-			fpregs->pr_gsr = current->thread.gsr[0];
+			fpregs->pr_fsr = current_thread_info()->xfsr[0];
+			fpregs->pr_gsr = current_thread_info()->gsr[0];
 		} else {
 			fpregs->pr_fsr = fpregs->pr_gsr = 0;
 		}
@@ -806,8 +792,8 @@
 	putname(filename);
 	if (!error) {
 		fprs_write(0);
-		current->thread.xfsr[0] = 0;
-		current->thread.fpsaved[0] = 0;
+		current_thread_info()->xfsr[0] = 0;
+		current_thread_info()->fpsaved[0] = 0;
 		regs->tstate &= ~TSTATE_PEF;
 	}
 out:
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index 6ccc596..08937d3 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -27,8 +27,6 @@
 #include <asm/visasm.h>
 #include <asm/spitfire.h>
 
-#define MAGIC_CONSTANT 0x80000000
-
 /* Returning from ptrace is a bit tricky because the syscall return
  * low level code assumes any value returned which is negative and
  * is a valid errno will mean setting the condition codes to indicate
@@ -53,7 +51,7 @@
 static inline void
 pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long *addr)
 {
-	if (current->thread.flags & SPARC_FLAG_32BIT) {
+	if (test_thread_flag(TIF_32BIT)) {
 		if (put_user(value, (unsigned int *)addr))
 			return pt_error_return(regs, EFAULT);
 	} else {
@@ -125,7 +123,7 @@
 	unsigned long addr2 = regs->u_regs[UREG_I4];
 	struct task_struct *child;
 
-	if (current->thread.flags & SPARC_FLAG_32BIT) {
+	if (test_thread_flag(TIF_32BIT)) {
 		addr &= 0xffffffffUL;
 		data &= 0xffffffffUL;
 		addr2 &= 0xffffffffUL;
@@ -201,7 +199,7 @@
 		goto out_tsk;
 	}
 
-	if (!(child->thread.flags & SPARC_FLAG_32BIT)	&&
+	if (!(test_thread_flag(TIF_32BIT))	&&
 	    ((request == PTRACE_READDATA64)		||
 	     (request == PTRACE_WRITEDATA64)		||
 	     (request == PTRACE_READTEXT64)		||
@@ -223,7 +221,7 @@
 		int res, copied;
 
 		res = -EIO;
-		if (current->thread.flags & SPARC_FLAG_32BIT) {
+		if (test_thread_flag(TIF_32BIT)) {
 			copied = access_process_vm(child, addr,
 						   &tmp32, sizeof(tmp32), 0);
 			tmp64 = (unsigned long) tmp32;
@@ -248,7 +246,7 @@
 		unsigned int tmp32;
 		int copied, res = -EIO;
 
-		if (current->thread.flags & SPARC_FLAG_32BIT) {
+		if (test_thread_flag(TIF_32BIT)) {
 			tmp32 = data;
 			copied = access_process_vm(child, addr,
 						   &tmp32, sizeof(tmp32), 1);
@@ -270,7 +268,7 @@
 
 	case PTRACE_GETREGS: {
 		struct pt_regs32 *pregs = (struct pt_regs32 *) addr;
-		struct pt_regs *cregs = child->thread.kregs;
+		struct pt_regs *cregs = child->thread_info->kregs;
 		int rval;
 
 		if (__put_user(tstate_to_psr(cregs->tstate), (&pregs->psr)) ||
@@ -294,11 +292,11 @@
 
 	case PTRACE_GETREGS64: {
 		struct pt_regs *pregs = (struct pt_regs *) addr;
-		struct pt_regs *cregs = child->thread.kregs;
+		struct pt_regs *cregs = child->thread_info->kregs;
 		unsigned long tpc = cregs->tpc;
 		int rval;
 
-		if ((child->thread.flags & SPARC_FLAG_32BIT) != 0)
+		if ((child->thread_info->flags & _TIF_32BIT) != 0)
 			tpc &= 0xffffffff;
 		if (__put_user(cregs->tstate, (&pregs->tstate)) ||
 		    __put_user(tpc, (&pregs->tpc)) ||
@@ -321,7 +319,7 @@
 
 	case PTRACE_SETREGS: {
 		struct pt_regs32 *pregs = (struct pt_regs32 *) addr;
-		struct pt_regs *cregs = child->thread.kregs;
+		struct pt_regs *cregs = child->thread_info->kregs;
 		unsigned int psr, pc, npc, y;
 		int i;
 
@@ -354,7 +352,7 @@
 
 	case PTRACE_SETREGS64: {
 		struct pt_regs *pregs = (struct pt_regs *) addr;
-		struct pt_regs *cregs = child->thread.kregs;
+		struct pt_regs *cregs = child->thread_info->kregs;
 		unsigned long tstate, tpc, tnpc, y;
 		int i;
 
@@ -368,7 +366,7 @@
 			pt_error_return(regs, EFAULT);
 			goto out_tsk;
 		}
-		if ((child->thread.flags & SPARC_FLAG_32BIT) != 0) {
+		if ((child->thread_info->flags & _TIF_32BIT) != 0) {
 			tpc &= 0xffffffff;
 			tnpc &= 0xffffffff;
 		}
@@ -402,11 +400,11 @@
 				unsigned int insn;
 			} fpq[16];
 		} *fps = (struct fps *) addr;
-		unsigned long *fpregs = (unsigned long *)(((char *)child) + AOFF_task_fpregs);
+		unsigned long *fpregs = child->thread_info->fpregs;
 
 		if (copy_to_user(&fps->regs[0], fpregs,
 				 (32 * sizeof(unsigned int))) ||
-		    __put_user(child->thread.xfsr[0], (&fps->fsr)) ||
+		    __put_user(child->thread_info->xfsr[0], (&fps->fsr)) ||
 		    __put_user(0, (&fps->fpqd)) ||
 		    __put_user(0, (&fps->flags)) ||
 		    __put_user(0, (&fps->extra)) ||
@@ -423,11 +421,11 @@
 			unsigned int regs[64];
 			unsigned long fsr;
 		} *fps = (struct fps *) addr;
-		unsigned long *fpregs = (unsigned long *)(((char *)child) + AOFF_task_fpregs);
+		unsigned long *fpregs = child->thread_info->fpregs;
 
 		if (copy_to_user(&fps->regs[0], fpregs,
 				 (64 * sizeof(unsigned int))) ||
-		    __put_user(child->thread.xfsr[0], (&fps->fsr))) {
+		    __put_user(child->thread_info->xfsr[0], (&fps->fsr))) {
 			pt_error_return(regs, EFAULT);
 			goto out_tsk;
 		}
@@ -447,7 +445,7 @@
 				unsigned int insn;
 			} fpq[16];
 		} *fps = (struct fps *) addr;
-		unsigned long *fpregs = (unsigned long *)(((char *)child) + AOFF_task_fpregs);
+		unsigned long *fpregs = child->thread_info->fpregs;
 		unsigned fsr;
 
 		if (copy_from_user(fpregs, &fps->regs[0],
@@ -456,11 +454,11 @@
 			pt_error_return(regs, EFAULT);
 			goto out_tsk;
 		}
-		child->thread.xfsr[0] &= 0xffffffff00000000UL;
-		child->thread.xfsr[0] |= fsr;
-		if (!(child->thread.fpsaved[0] & FPRS_FEF))
-			child->thread.gsr[0] = 0;
-		child->thread.fpsaved[0] |= (FPRS_FEF | FPRS_DL);
+		child->thread_info->xfsr[0] &= 0xffffffff00000000UL;
+		child->thread_info->xfsr[0] |= fsr;
+		if (!(child->thread_info->fpsaved[0] & FPRS_FEF))
+			child->thread_info->gsr[0] = 0;
+		child->thread_info->fpsaved[0] |= (FPRS_FEF | FPRS_DL);
 		pt_succ_return(regs, 0);
 		goto out_tsk;
 	}
@@ -470,17 +468,17 @@
 			unsigned int regs[64];
 			unsigned long fsr;
 		} *fps = (struct fps *) addr;
-		unsigned long *fpregs = (unsigned long *)(((char *)child) + AOFF_task_fpregs);
+		unsigned long *fpregs = child->thread_info->fpregs;
 
 		if (copy_from_user(fpregs, &fps->regs[0],
 				   (64 * sizeof(unsigned int))) ||
-		    __get_user(child->thread.xfsr[0], (&fps->fsr))) {
+		    __get_user(child->thread_info->xfsr[0], (&fps->fsr))) {
 			pt_error_return(regs, EFAULT);
 			goto out_tsk;
 		}
-		if (!(child->thread.fpsaved[0] & FPRS_FEF))
-			child->thread.gsr[0] = 0;
-		child->thread.fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU);
+		if (!(child->thread_info->fpsaved[0] & FPRS_FEF))
+			child->thread_info->gsr[0] = 0;
+		child->thread_info->fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU);
 		pt_succ_return(regs, 0);
 		goto out_tsk;
 	}
@@ -523,7 +521,7 @@
 		if (addr != 1) {
 			unsigned long pc_mask = ~0UL;
 
-			if ((child->thread.flags & SPARC_FLAG_32BIT) != 0)
+			if ((child->thread_info->flags & _TIF_32BIT) != 0)
 				pc_mask = 0xffffffff;
 
 			if (addr & 3) {
@@ -531,27 +529,27 @@
 				goto out_tsk;
 			}
 #ifdef DEBUG_PTRACE
-			printk ("Original: %016lx %016lx\n", child->thread.kregs->tpc, child->thread.kregs->tnpc);
+			printk ("Original: %016lx %016lx\n",
+				child->thread_info->kregs->tpc,
+				child->thread_info->kregs->tnpc);
 			printk ("Continuing with %016lx %016lx\n", addr, addr+4);
 #endif
-			child->thread.kregs->tpc = (addr & pc_mask);
-			child->thread.kregs->tnpc = ((addr + 4) & pc_mask);
+			child->thread_info->kregs->tpc = (addr & pc_mask);
+			child->thread_info->kregs->tnpc = ((addr + 4) & pc_mask);
 		}
 
 		if (request == PTRACE_SYSCALL) {
-			child->ptrace |= PT_SYSCALLTRACE;
-			child->work.syscall_trace++;
+			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		} else {
-			child->ptrace &= ~PT_SYSCALLTRACE;
-			child->work.syscall_trace--;
+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		}
 
 		child->exit_code = data;
 #ifdef DEBUG_PTRACE
 		printk("CONT: %s [%d]: set exit_code = %x %lx %lx\n", child->comm,
 			child->pid, child->exit_code,
-			child->thread.kregs->tpc,
-			child->thread.kregs->tnpc);
+			child->thread_info->kregs->tpc,
+			child->thread_info->kregs->tnpc);
 		       
 #endif
 		wake_up_process(child);
@@ -614,7 +612,7 @@
 	}
 out_tsk:
 	if (child)
-		free_task_struct(child);
+		put_task_struct(child);
 out:
 	unlock_kernel();
 }
@@ -624,12 +622,12 @@
 #ifdef DEBUG_PTRACE
 	printk("%s [%d]: syscall_trace\n", current->comm, current->pid);
 #endif
-	if ((current->ptrace & (PT_PTRACED|PT_SYSCALLTRACE))
-	    != (PT_PTRACED|PT_SYSCALLTRACE))
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		return;
+	if (!(current->ptrace & PT_PTRACED))
 		return;
 	current->exit_code = SIGTRAP;
 	current->state = TASK_STOPPED;
-	current->thread.flags ^= MAGIC_CONSTANT;
 	notify_parent(current, SIGCHLD);
 	schedule();
 	/*
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index 8c400d8..8a68dd0 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -1,10 +1,12 @@
-/* $Id: rtrap.S,v 1.60 2002/01/31 03:30:06 davem Exp $
+/* $Id: rtrap.S,v 1.61 2002/02/09 19:49:31 davem Exp $
  * rtrap.S: Preparing for return from trap on Sparc V9.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
  */
 
+#include <linux/config.h>
+
 #include <asm/asi.h>
 #include <asm/pstate.h>
 #include <asm/ptrace.h>
@@ -42,18 +44,18 @@
 		 wrpr			%g0, RTRAP_PSTATE, %pstate
 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
 		/* Redo sched+sig checks */
-		lduw			[%g6 + AOFF_task_work], %l0
-		srlx			%l0, 24, %o0
+		ldx			[%g6 + TI_FLAGS], %l0
+		andcc			%l0, _TIF_NEED_RESCHED, %g0
 
-		brz,pt			%o0, 1f
+		be,pt			%xcc, 1f
 		 nop
 		call			schedule
 		 wrpr			%g0, RTRAP_PSTATE, %pstate
 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
-		lduw			[%g6 + AOFF_task_work], %l0
+		ldx			[%g6 + TI_FLAGS], %l0
 
-1:		sllx			%l0, 48, %o0
-		brz,pt			%o0, __handle_user_windows_continue
+1:		andcc			%l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0
+		be,pt			%xcc, __handle_user_windows_continue
 		 nop
 		clr			%o0
 		mov			%l5, %o2
@@ -78,7 +80,7 @@
 		call			update_perfctrs
 		 wrpr			%g0, RTRAP_PSTATE, %pstate
 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
-		ldub			[%g6 + AOFF_task_thread + AOFF_thread_w_saved], %o2
+		ldub			[%g6 + TI_WSAVED], %o2
 		brz,pt			%o2, 1f
 		 nop
 		/* Redo userwin+sched+sig checks */
@@ -86,18 +88,18 @@
 
 		 wrpr			%g0, RTRAP_PSTATE, %pstate
 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
-		lduw			[%g6 + AOFF_task_work], %l0
-		srlx			%l0, 24, %o0
-		brz,pt			%o0, 1f
+		ldx			[%g6 + TI_FLAGS], %l0
+		andcc			%l0, _TIF_NEED_RESCHED, %g0
+		be,pt			%xcc, 1f
 
 		 nop
 		call			schedule
 		 wrpr			%g0, RTRAP_PSTATE, %pstate
 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
-		lduw			[%g6 + AOFF_task_work], %l0
-1:		sllx			%l0, 48, %o0
+		ldx			[%g6 + TI_FLAGS], %l0
+1:		andcc			%l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0
 
-		brz,pt			%o0, __handle_perfctrs_continue
+		be,pt			%xcc, __handle_perfctrs_continue
 		 sethi			%hi(TSTATE_PEF), %o0
 		clr			%o0
 		mov			%l5, %o2
@@ -148,9 +150,15 @@
 		 andn			%l1, %l4, %l1
 
 		.align			64
-		.globl			rtrap_clr_l6, rtrap, irqsz_patchme
+		.globl			rtrap_irq, rtrap_clr_l6, rtrap, irqsz_patchme
+rtrap_irq:
+#ifdef CONFIG_PREEMPT
+		ldsw			[%g6 + TI_PRE_COUNT], %l0
+		sub			%l0, 1, %l0
+		stw			%l0, [%g6 + TI_PRE_COUNT]
+#endif
 rtrap_clr_l6:	clr			%l6
-rtrap:		lduw			[%g6 + AOFF_task_cpu], %l0
+rtrap:		ldub			[%g6 + TI_CPU], %l0
 		sethi			%hi(irq_stat), %l2	! &softirq_active
 		or			%l2, %lo(irq_stat), %l2	! &softirq_active
 irqsz_patchme:	sllx			%l0, 0, %l0
@@ -182,26 +190,33 @@
 		 */
 to_user:	wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
 __handle_preemption_continue:
-		lduw			[%g6 + AOFF_task_work], %l0
-		srlx			%l0, 24, %o0
-		brnz,pn			%o0, __handle_preemption
-		 sllx			%l0, 48, %o0
-		brnz,pn			%o0, __handle_signal
+		ldx			[%g6 + TI_FLAGS], %l0
+		sethi			%hi(_TIF_USER_WORK_MASK), %o0
+		or			%o0, %lo(_TIF_USER_WORK_MASK), %o0
+		andcc			%l0, %o0, %g0
+		sethi			%hi(TSTATE_PEF), %o0
+		be,pt			%xcc, user_nowork
+		 andcc			%l1, %o0, %g0
+		andcc			%l0, _TIF_NEED_RESCHED, %g0
+		bne,pn			%xcc, __handle_preemption
+		 andcc			%l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0
+		bne,pn			%xcc, __handle_signal
 __handle_signal_continue:
-		 ldub			[%g6 + AOFF_task_thread + AOFF_thread_w_saved], %o2
+		 ldub			[%g6 + TI_WSAVED], %o2
 		brnz,pn			%o2, __handle_user_windows
 		 nop
 __handle_user_windows_continue:
-		ldub			[%g6 + AOFF_task_thread + AOFF_thread_flags], %l5
-		andcc			%l5, SPARC_FLAG_PERFCTR, %g0
+		ldx			[%g6 + TI_FLAGS], %l5
+		andcc			%l5, _TIF_PERFCTR, %g0
 		sethi			%hi(TSTATE_PEF), %o0
 		bne,pn			%xcc, __handle_perfctrs
 __handle_perfctrs_continue:
 		 andcc			%l1, %o0, %g0
 
 		/* This fpdepth clear is neccessary for non-syscall rtraps only */
+user_nowork:
 		bne,pn			%xcc, __handle_userfpu
-		 stb			%g0, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth]
+		 stb			%g0, [%g6 + TI_FPDEPTH]
 __handle_userfpu_continue:
 
 rt_continue:	ldx			[%sp + PTREGS_OFF + PT_V9_G1], %g1
@@ -254,14 +269,25 @@
 
 kern_rtt:	restore
 		retry
-to_kernel:	ldub			[%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5
+to_kernel:
+#ifdef CONFIG_PREEMPT
+		ldsw			[%g6 + TI_PRE_COUNT], %l5
+		brnz			%l5, kern_fpucheck
+		 add			%l5, 1, %l6
+		stw			%l6, [%g6 + TI_PRE_COUNT]
+		call			kpreempt_maybe
+		 wrpr			%g0, RTRAP_PSTATE, %pstate
+		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate		
+		stw			%l5, [%g6 + TI_PRE_COUNT]
+#endif
+kern_fpucheck:	ldub			[%g6 + TI_FPDEPTH], %l5
 		brz,pt			%l5, rt_continue
 		 srl			%l5, 1, %o0
-		add			%g6, AOFF_task_thread + AOFF_thread_fpsaved, %l6
+		add			%g6, TI_FPSAVED, %l6
 		ldub			[%l6 + %o0], %l2
 		sub			%l5, 2, %l5
 
-		add			%g6, AOFF_task_thread + AOFF_thread_gsr, %o1
+		add			%g6, TI_GSR, %o1
 		andcc			%l2, (FPRS_FEF|FPRS_DU), %g0
 		be,pt			%icc, 2f
 		 and			%l2, FPRS_DL, %l6
@@ -272,12 +298,12 @@
 
 		wr			%g5, FPRS_FEF, %fprs
 		ldx			[%o1 + %o5], %g5
-		add			%g6, AOFF_task_thread + AOFF_thread_xfsr, %o1
+		add			%g6, TI_XFSR, %o1
 		membar			#StoreLoad | #LoadLoad
 		sll			%o0, 8, %o2
-		add			%g6, AOFF_task_fpregs, %o3
+		add			%g6, TI_FPREGS, %o3
 		brz,pn			%l6, 1f
-		 add			%g6, AOFF_task_fpregs+0x40, %o4
+		 add			%g6, TI_FPREGS+0x40, %o4
 
 		ldda			[%o3 + %o2] ASI_BLK_P, %f0
 		ldda			[%o4 + %o2] ASI_BLK_P, %f16
@@ -290,20 +316,20 @@
 
 1:		membar			#Sync
 		ldx			[%o1 + %o5], %fsr
-2:		stb			%l5, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth]
+2:		stb			%l5, [%g6 + TI_FPDEPTH]
 		ba,pt			%xcc, rt_continue
 		 nop
 5:		wr			%g0, FPRS_FEF, %fprs
 		membar			#StoreLoad | #LoadLoad
 		sll			%o0, 8, %o2
 
-		add			%g6, AOFF_task_fpregs+0x80, %o3
-		add			%g6, AOFF_task_fpregs+0xc0, %o4
+		add			%g6, TI_FPREGS+0x80, %o3
+		add			%g6, TI_FPREGS+0xc0, %o4
 		ldda			[%o3 + %o2] ASI_BLK_P, %f32
 		ldda			[%o4 + %o2] ASI_BLK_P, %f48
 		membar			#Sync
 		wr			%g0, FPRS_DU, %fprs
 		ba,pt			%xcc, rt_continue
-		 stb			%l5, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth]
+		 stb			%l5, [%g6 + TI_FPDEPTH]
 
 #undef PTREGS_OFF
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 765f559..cfd1420 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.71 2001/11/13 00:49:28 davem Exp $
+/*  $Id: setup.c,v 1.72 2002/02/09 19:49:30 davem Exp $
  *  linux/arch/sparc64/kernel/setup.c
  *
  *  Copyright (C) 1995,1996  David S. Miller (davem@caip.rutgers.edu)
@@ -536,7 +536,7 @@
 	rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0);	
 #endif
 
-	init_task.thread.kregs = &fake_swapper_regs;
+	init_task.thread_info->kregs = &fake_swapper_regs;
 
 #ifdef CONFIG_IP_PNP
 	if (!ic_set_manually) {
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 8745f7e..5d45b53 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -1,4 +1,4 @@
-/*  $Id: signal.c,v 1.58 2002/01/31 03:30:06 davem Exp $
+/*  $Id: signal.c,v 1.60 2002/02/09 19:49:31 davem Exp $
  *  arch/sparc64/kernel/signal.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
@@ -76,7 +76,6 @@
 asmlinkage void sparc64_set_context(struct pt_regs *regs)
 {
 	struct ucontext *ucp = (struct ucontext *) regs->u_regs[UREG_I0];
-	struct thread_struct *tp = &current->thread;
 	mc_gregset_t *grp;
 	unsigned long pc, npc, tstate;
 	unsigned long fp, i7;
@@ -84,16 +83,16 @@
 	int err;
 
 	flush_user_windows();
-	if(tp->w_saved						||
-	   (((unsigned long)ucp) & (sizeof(unsigned long)-1))	||
-	   (!__access_ok((unsigned long)ucp, sizeof(*ucp))))
+	if (get_thread_wsaved()					||
+	    (((unsigned long)ucp) & (sizeof(unsigned long)-1))	||
+	    (!__access_ok((unsigned long)ucp, sizeof(*ucp))))
 		goto do_sigsegv;
 	grp  = &ucp->uc_mcontext.mc_gregs;
 	err  = __get_user(pc, &((*grp)[MC_PC]));
 	err |= __get_user(npc, &((*grp)[MC_NPC]));
-	if(err || ((pc | npc) & 3))
+	if (err || ((pc | npc) & 3))
 		goto do_sigsegv;
-	if(regs->u_regs[UREG_I1]) {
+	if (regs->u_regs[UREG_I1]) {
 		sigset_t set;
 
 		if (_NSIG_WORDS == 1) {
@@ -109,7 +108,7 @@
 		recalc_sigpending(current);
 		spin_unlock_irq(&current->sigmask_lock);
 	}
-	if ((tp->flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		pc &= 0xffffffff;
 		npc &= 0xffffffff;
 	}
@@ -143,8 +142,8 @@
 	      (&(((struct reg_window *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
 
 	err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
-	if(fenab) {
-		unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs);
+	if (fenab) {
+		unsigned long *fpregs = current_thread_info()->fpregs;
 		unsigned long fprs;
 		
 		fprs_write(0);
@@ -157,9 +156,9 @@
 			err |= copy_from_user(fpregs+16,
 			 ((unsigned long *)&(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs))+16,
 			 (sizeof(unsigned int) * 32));
-		err |= __get_user(current->thread.xfsr[0],
+		err |= __get_user(current_thread_info()->xfsr[0],
 				  &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
-		err |= __get_user(current->thread.gsr[0],
+		err |= __get_user(current_thread_info()->gsr[0],
 				  &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
 		regs->tstate &= ~TSTATE_PEF;
 	}
@@ -174,7 +173,6 @@
 asmlinkage void sparc64_get_context(struct pt_regs *regs)
 {
 	struct ucontext *ucp = (struct ucontext *) regs->u_regs[UREG_I0];
-	struct thread_struct *tp = &current->thread;
 	mc_gregset_t *grp;
 	mcontext_t *mcp;
 	unsigned long fp, i7;
@@ -182,20 +180,20 @@
 	int err;
 
 	synchronize_user_stack();
-	if(tp->w_saved || clear_user(ucp, sizeof(*ucp)))
+	if (get_thread_wsaved() || clear_user(ucp, sizeof(*ucp)))
 		goto do_sigsegv;
 
 #if 1
 	fenab = 0; /* IMO get_context is like any other system call, thus modifies FPU state -jj */
 #else
-	fenab = (current->thread.fpsaved[0] & FPRS_FEF);
+	fenab = (current_thread_info()->fpsaved[0] & FPRS_FEF);
 #endif
 		
 	mcp = &ucp->uc_mcontext;
 	grp = &mcp->mc_gregs;
 
 	/* Skip over the trap instruction, first. */
-	if ((tp->flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc   = (regs->tnpc & 0xffffffff);
 		regs->tnpc  = (regs->tnpc + 4) & 0xffffffff;
 	} else {
@@ -238,11 +236,11 @@
 	err |= __put_user(i7, &(mcp->mc_i7));
 
 	err |= __put_user(fenab, &(mcp->mc_fpregs.mcfpu_enab));
-	if(fenab) {
-		unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs);
+	if (fenab) {
+		unsigned long *fpregs = current_thread_info()->fpregs;
 		unsigned long fprs;
 		
-		fprs = current->thread.fpsaved[0];
+		fprs = current_thread_info()->fpsaved[0];
 		if (fprs & FPRS_DL)
 			err |= copy_to_user(&(mcp->mc_fpregs.mcfpu_fregs), fpregs,
 					    (sizeof(unsigned int) * 32));
@@ -250,8 +248,8 @@
 			err |= copy_to_user(
                           ((unsigned long *)&(mcp->mc_fpregs.mcfpu_fregs))+16, fpregs+16,
 			  (sizeof(unsigned int) * 32));
-		err |= __put_user(current->thread.xfsr[0], &(mcp->mc_fpregs.mcfpu_fsr));
-		err |= __put_user(current->thread.gsr[0], &(mcp->mc_fpregs.mcfpu_gsr));
+		err |= __put_user(current_thread_info()->xfsr[0], &(mcp->mc_fpregs.mcfpu_fsr));
+		err |= __put_user(current_thread_info()->gsr[0], &(mcp->mc_fpregs.mcfpu_gsr));
 		err |= __put_user(fprs, &(mcp->mc_fpregs.mcfpu_fprs));
 	}
 	if (err)
@@ -284,7 +282,7 @@
 	sigset_t saveset;
 
 #ifdef CONFIG_SPARC32_COMPAT
-	if (current->thread.flags & SPARC_FLAG_32BIT) {
+	if (test_thread_flag(TIF_32BIT)) {
 		extern asmlinkage void _sigpause32_common(old_sigset_t32,
 							  struct pt_regs *);
 		_sigpause32_common(set, regs);
@@ -298,7 +296,7 @@
 	recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
 	
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc = (regs->tnpc & 0xffffffff);
 		regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
 	} else {
@@ -358,7 +356,7 @@
 	recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
 	
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc = (regs->tnpc & 0xffffffff);
 		regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
 	} else {
@@ -388,7 +386,7 @@
 static inline int
 restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
 {
-	unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs);
+	unsigned long *fpregs = current_thread_info()->fpregs;
 	unsigned long fprs;
 	int err;
 
@@ -401,9 +399,9 @@
 	if (fprs & FPRS_DU)
 		err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32],
 		       	       (sizeof(unsigned int) * 32));
-	err |= __get_user(current->thread.xfsr[0], &fpu->si_fsr);
-	err |= __get_user(current->thread.gsr[0], &fpu->si_gsr);
-	current->thread.fpsaved[0] |= fprs;
+	err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
+	err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
+	current_thread_info()->fpsaved[0] |= fprs;
 	return err;
 }
 
@@ -426,7 +424,7 @@
 
 	err = get_user(tpc, &sf->regs.tpc);
 	err |= __get_user(tnpc, &sf->regs.tnpc);
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		tpc &= 0xffffffff;
 		tnpc &= 0xffffffff;
 	}
@@ -483,15 +481,15 @@
 	unsigned long fprs;
 	int err = 0;
 	
-	fprs = current->thread.fpsaved[0];
+	fprs = current_thread_info()->fpsaved[0];
 	if (fprs & FPRS_DL)
 		err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
 				    (sizeof(unsigned int) * 32));
 	if (fprs & FPRS_DU)
 		err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
 				    (sizeof(unsigned int) * 32));
-	err |= __put_user(current->thread.xfsr[0], &fpu->si_fsr);
-	err |= __put_user(current->thread.gsr[0], &fpu->si_gsr);
+	err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
+	err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
 	err |= __put_user(fprs, &fpu->si_fprs);
 
 	return err;
@@ -524,7 +522,7 @@
 	save_and_clear_fpu();
 	
 	sigframe_size = RT_ALIGNEDSZ;
-	if (!(current->thread.fpsaved[0] & FPRS_FEF))
+	if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
 		sigframe_size -= sizeof(__siginfo_fpu_t);
 
 	sf = (struct rt_signal_frame *)get_sigframe(ka, regs, sigframe_size);
@@ -532,7 +530,7 @@
 	if (invalid_frame_pointer (sf, sigframe_size))
 		goto sigill;
 
-	if (current->thread.w_saved != 0) {
+	if (get_thread_wsaved() != 0) {
 #ifdef DEBUG_SIGNALS
 		printk ("%s[%d]: Invalid user stack frame for "
 			"signal delivery.\n", current->comm, current->pid);
@@ -543,7 +541,7 @@
 	/* 2. Save the current process state */
 	err = copy_to_user(&sf->regs, regs, sizeof (*regs));
 
-	if (current->thread.fpsaved[0] & FPRS_FEF) {
+	if (current_thread_info()->fpsaved[0] & FPRS_FEF) {
 		err |= save_fpu_state(regs, &sf->fpu_state);
 		err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
 	} else {
@@ -578,7 +576,7 @@
 	/* 5. signal handler */
 	regs->tpc = (unsigned long) ka->sa.sa_handler;
 	regs->tnpc = (regs->tpc + 4);
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -597,9 +595,9 @@
 				 sigset_t *oldset, struct pt_regs *regs)
 {
 	setup_rt_frame(ka, regs, signr, oldset, (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
-	if(ka->sa.sa_flags & SA_ONESHOT)
+	if (ka->sa.sa_flags & SA_ONESHOT)
 		ka->sa.sa_handler = SIG_DFL;
-	if(!(ka->sa.sa_flags & SA_NOMASK)) {
+	if (!(ka->sa.sa_flags & SA_NOMASK)) {
 		spin_lock_irq(&current->sigmask_lock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,signr);
@@ -611,14 +609,14 @@
 static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
 				     struct sigaction *sa)
 {
-	switch(regs->u_regs[UREG_I0]) {
+	switch (regs->u_regs[UREG_I0]) {
 		case ERESTARTNOHAND:
 		no_system_call_restart:
 			regs->u_regs[UREG_I0] = EINTR;
 			regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
 			break;
 		case ERESTARTSYS:
-			if(!(sa->sa_flags & SA_RESTART))
+			if (!(sa->sa_flags & SA_RESTART))
 				goto no_system_call_restart;
 		/* fallthrough */
 		case ERESTARTNOINTR:
@@ -699,7 +697,7 @@
 		oldset = &current->blocked;
 
 #ifdef CONFIG_SPARC32_COMPAT
-	if (current->thread.flags & SPARC_FLAG_32BIT) {
+	if (test_thread_flag(TIF_32BIT)) {
 		extern int do_signal32(sigset_t *, struct pt_regs *,
 				       unsigned long, int);
 		return do_signal32(oldset, regs, orig_i0, restart_syscall);
@@ -741,8 +739,8 @@
 		
 		ka = &current->sig->action[signr-1];
 		
-		if(ka->sa.sa_handler == SIG_IGN) {
-			if(signr != SIGCHLD)
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
 				continue;
 
                         /* sys_wait4() grabs the master kernel lock, so
@@ -750,16 +748,16 @@
                          * threaded and would not be that difficult to
                          * do anyways.
                          */
-                        while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+                        while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
                                 ;
 			continue;
 		}
-		if(ka->sa.sa_handler == SIG_DFL) {
+		if (ka->sa.sa_handler == SIG_DFL) {
 			unsigned long exit_code = signr;
 			
-			if(current->pid == 1)
+			if (current->pid == 1)
 				continue;
-			switch(signr) {
+			switch (signr) {
 			case SIGCONT: case SIGCHLD: case SIGWINCH:
 				continue;
 
@@ -772,8 +770,8 @@
 					continue;
 				current->state = TASK_STOPPED;
 				current->exit_code = signr;
-				if(!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
-				     SA_NOCLDSTOP))
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
+				      SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
 				continue;
@@ -792,8 +790,8 @@
 					struct reg_window *rw = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
 					unsigned long ins[8];
                                                 
-					while(rw &&
-					      !(((unsigned long) rw) & 0x3)) {
+					while (rw &&
+					       !(((unsigned long) rw) & 0x3)) {
 					        copy_from_user(ins, &rw->ins[0], sizeof(ins));
 						printk("Caller[%016lx](%016lx,%016lx,%016lx,%016lx,%016lx,%016lx)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
 						rw = (struct reg_window *)(unsigned long)(ins[6] + STACK_BIAS);
@@ -811,15 +809,15 @@
 				/* NOT REACHED */
 			}
 		}
-		if(restart_syscall)
+		if (restart_syscall)
 			syscall_restart(orig_i0, regs, &ka->sa);
 		handle_signal(signr, ka, &info, oldset, regs);
 		return 1;
 	}
-	if(restart_syscall &&
-	   (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-	    regs->u_regs[UREG_I0] == ERESTARTSYS ||
-	    regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+	if (restart_syscall &&
+	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->tpc -= 4;
@@ -830,12 +828,8 @@
 
 void do_notify_resume(sigset_t *oldset, struct pt_regs *regs,
 		      unsigned long orig_i0, int restart_syscall,
-		      unsigned int work_pending)
+		      unsigned long thread_info_flags)
 {
-	/* We don't pass in the task_work struct as a struct because
-	 * GCC always bounces that onto the stack due to the
-	 * ABI calling conventions.
-	 */
-	if (work_pending & 0x0000ff00)
+	if (thread_info_flags & _TIF_SIGPENDING)
 		do_signal(oldset, regs, orig_i0, restart_syscall);
 }
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 7dc93cc..def7154 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -1,4 +1,4 @@
-/*  $Id: signal32.c,v 1.72 2002/01/31 03:30:06 davem Exp $
+/*  $Id: signal32.c,v 1.74 2002/02/09 19:49:30 davem Exp $
  *  arch/sparc64/kernel/signal32.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
@@ -156,7 +156,7 @@
 	
 	regs->tpc = regs->tnpc;
 	regs->tnpc += 4;
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -211,7 +211,7 @@
 	
 	regs->tpc = regs->tnpc;
 	regs->tnpc += 4;
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -237,7 +237,7 @@
 
 static inline int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu)
 {
-	unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs);
+	unsigned long *fpregs = current_thread_info()->fpregs;
 	unsigned long fprs;
 	int err;
 	
@@ -248,9 +248,9 @@
 		err |= copy_from_user(fpregs, &fpu->si_float_regs[0], (sizeof(unsigned int) * 32));
 	if (fprs & FPRS_DU)
 		err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], (sizeof(unsigned int) * 32));
-	err |= __get_user(current->thread.xfsr[0], &fpu->si_fsr);
-	err |= __get_user(current->thread.gsr[0], &fpu->si_gsr);
-	current->thread.fpsaved[0] |= fprs;
+	err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
+	err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
+	current_thread_info()->fpsaved[0] |= fprs;
 	return err;
 }
 
@@ -277,7 +277,7 @@
 	if ((pc | npc) & 3)
 		goto segv;
 
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		pc &= 0xffffffff;
 		npc &= 0xffffffff;
 	}
@@ -335,20 +335,20 @@
 	int err;
 
 	synchronize_user_stack();
-	if (current->thread.flags & SPARC_FLAG_NEWSIGNALS)
+	if (test_thread_flag(TIF_NEWSIGNALS))
 		return do_new_sigreturn32(regs);
 
 	scptr = (struct sigcontext32 *)
 		(regs->u_regs[UREG_I0] & 0x00000000ffffffffUL);
 	/* Check sanity of the user arg. */
-	if(verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext32)) ||
-	   (((unsigned long) scptr) & 3))
+	if (verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext32)) ||
+	    (((unsigned long) scptr) & 3))
 		goto segv;
 
 	err = __get_user(pc, &scptr->sigc_pc);
 	err |= __get_user(npc, &scptr->sigc_npc);
 
-	if((pc | npc) & 3)
+	if ((pc | npc) & 3)
 		goto segv; /* Nice try. */
 
 	err |= __get_user(seta[0], &scptr->sigc_mask);
@@ -368,7 +368,7 @@
 	recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
 	
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		pc &= 0xffffffff;
 		npc &= 0xffffffff;
 	}
@@ -415,7 +415,7 @@
 	if ((pc | npc) & 3)
 		goto segv;
 
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		pc &= 0xffffffff;
 		npc &= 0xffffffff;
 	}
@@ -510,7 +510,7 @@
 #endif	
 	unsigned psr;
 
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		pc &= 0xffffffff;
 		npc &= 0xffffffff;
 	}
@@ -555,20 +555,20 @@
 	err |= __put_user(pc, &sc->sigc_pc);
 	err |= __put_user(npc, &sc->sigc_npc);
 	psr = tstate_to_psr (regs->tstate);
-	if(current->thread.fpsaved[0] & FPRS_FEF)
+	if (current_thread_info()->fpsaved[0] & FPRS_FEF)
 		psr |= PSR_EF;
 	err |= __put_user(psr, &sc->sigc_psr);
 	err |= __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
 	err |= __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
-	err |= __put_user(current->thread.w_saved, &sc->sigc_oswins);
+	err |= __put_user(get_thread_wsaved(), &sc->sigc_oswins);
 #if 0
 /* w_saved is not currently used... */
-	if(current->thread.w_saved)
-		for(window = 0; window < current->thread.w_saved; window++) {
+	if (get_thread_wsaved())
+		for (window = 0; window < get_thread_wsaved(); window++) {
 			sc->sigc_spbuf[window] =
-				(char *)current->thread.rwbuf_stkptrs[window];
+				(char *) current_thread_info()->rwbuf_stkptrs[window];
 			err |= copy_to_user(&sc->sigc_wbuf[window],
-					    &current->thread.reg_window[window],
+					    &current_thread_info()->reg_window[window],
 					    sizeof(struct reg_window));
 		}
 	else
@@ -577,7 +577,7 @@
 				    (u32 *)(regs->u_regs[UREG_FP]),
 				    sizeof(struct reg_window32));
 		       
-	current->thread.w_saved = 0; /* So process is allowed to execute. */
+	set_thread_wsaved(0); /* So process is allowed to execute. */
 	err |= __put_user(signr, &sframep->sig_num);
 	sig_address = NULL;
 	sig_code = 0;
@@ -641,7 +641,7 @@
 	regs->u_regs[UREG_FP] = (unsigned long) sframep;
 	regs->tpc = (unsigned long) sa->sa_handler;
 	regs->tnpc = (regs->tpc + 4);
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -654,19 +654,19 @@
 
 static inline int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu)
 {
-	unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs);
+	unsigned long *fpregs = current_thread_info()->fpregs;
 	unsigned long fprs;
 	int err = 0;
 	
-	fprs = current->thread.fpsaved[0];
+	fprs = current_thread_info()->fpsaved[0];
 	if (fprs & FPRS_DL)
 		err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
 				    (sizeof(unsigned int) * 32));
 	if (fprs & FPRS_DU)
 		err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
 				    (sizeof(unsigned int) * 32));
-	err |= __put_user(current->thread.xfsr[0], &fpu->si_fsr);
-	err |= __put_user(current->thread.gsr[0], &fpu->si_gsr);
+	err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
+	err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
 	err |= __put_user(fprs, &fpu->si_fprs);
 
 	return err;
@@ -686,7 +686,7 @@
 	save_and_clear_fpu();
 	
 	sigframe_size = NF_ALIGNEDSZ;
-	if (!(current->thread.fpsaved[0] & FPRS_FEF))
+	if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
 		sigframe_size -= sizeof(__siginfo_fpu_t);
 
 	sf = (struct new_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size);
@@ -699,7 +699,7 @@
 		goto sigill;
 	}
 
-	if (current->thread.w_saved != 0) {
+	if (get_thread_wsaved() != 0) {
 #ifdef DEBUG_SIGNALS
 		printk ("%s[%d]: Invalid user stack frame for "
 			"signal delivery.\n", current->comm, current->pid);
@@ -708,7 +708,7 @@
 	}
 
 	/* 2. Save the current process state */
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -716,7 +716,7 @@
 	err |= __put_user(regs->tnpc, &sf->info.si_regs.npc);
 	err |= __put_user(regs->y, &sf->info.si_regs.y);
 	psr = tstate_to_psr (regs->tstate);
-	if(current->thread.fpsaved[0] & FPRS_FEF)
+	if (current_thread_info()->fpsaved[0] & FPRS_FEF)
 		psr |= PSR_EF;
 	err |= __put_user(psr, &sf->info.si_regs.psr);
 	for (i = 0; i < 16; i++)
@@ -762,7 +762,7 @@
 	/* 4. signal handler */
 	regs->tpc = (unsigned long) ka->sa.sa_handler;
 	regs->tnpc = (regs->tpc + 4);
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -781,10 +781,10 @@
 	
 		err  = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/
 		err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
-		if(err)
+		if (err)
 			goto sigsegv;
 
-		if(pte_present(*ptep)) {
+		if (pte_present(*ptep)) {
 			unsigned long page = (unsigned long) page_address(pte_page(*ptep));
 
 			__asm__ __volatile__(
@@ -857,14 +857,14 @@
 		err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
 	
 	/* Store registers */
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
 	err |= __put_user(regs->tpc, &((*gr) [SVR4_PC]));
 	err |= __put_user(regs->tnpc, &((*gr) [SVR4_NPC]));
 	psr = tstate_to_psr (regs->tstate);
-	if(current->thread.fpsaved[0] & FPRS_FEF)
+	if (current_thread_info()->fpsaved[0] & FPRS_FEF)
 		psr |= PSR_EF;
 	err |= __put_user(psr, &((*gr) [SVR4_PSR]));
 	err |= __put_user(regs->y, &((*gr) [SVR4_Y]));
@@ -886,7 +886,7 @@
 	err |= __put_user((u32)(long)gw, &mc->gwin);
 	    
 	/* 2. Number of windows to restore at setcontext (): */
-	err |= __put_user(current->thread.w_saved, &gw->count);
+	err |= __put_user(get_thread_wsaved(), &gw->count);
 
 	/* 3. Save each valid window
 	 *    Currently, it makes a copy of the windows from the kernel copy.
@@ -900,18 +900,18 @@
 	 *    to flush the user windows.
 	 */
 #if 0	 
-	for(window = 0; window < current->thread.w_saved; window++) {
-		err |= __put_user((int *) &(gw->win [window]),
-				  (int **)gw->winptr +window );
-		err |= copy_to_user(&gw->win [window],
-				    &current->thread.reg_window [window],
+	for (window = 0; window < get_thread_wsaved(); window++) {
+		err |= __put_user((int *) &(gw->win[window]),
+				  (int **) gw->winptr + window);
+		err |= copy_to_user(&gw->win[window],
+				    &current_thread_info()->reg_window[window],
 				    sizeof (svr4_rwindow_t));
-		err |= __put_user(0, (int *)gw->winptr + window);
+		err |= __put_user(0, (int *) gw->winptr + window);
 	}
 #endif	
 
 	/* 4. We just pay attention to the gw->count field on setcontext */
-	current->thread.w_saved = 0; /* So process is allowed to execute. */
+	set_thread_wsaved(0); /* So process is allowed to execute. */
 
 	/* Setup the signal information.  Solaris expects a bunch of
 	 * information to be passed to the signal handler, we don't provide
@@ -925,7 +925,7 @@
 	regs->u_regs[UREG_FP] = (unsigned long) sfp;
 	regs->tpc = (unsigned long) sa->sa_handler;
 	regs->tnpc = (regs->tpc + 4);
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -966,8 +966,10 @@
 	synchronize_user_stack();
 	save_and_clear_fpu();
 	
-	if (current->thread.w_saved){
-		printk ("Uh oh, w_saved is not zero (%d)\n", (int) current->thread.w_saved);
+	if (get_thread_wsaved()) {
+#ifdef DEBUG_SIGNALS
+		printk ("Uh oh, w_saved is not zero (%d)\n", (int) get_thread_wsaved());
+#endif
 		do_exit (SIGSEGV);
 	}
 	err = clear_user(uc, sizeof (*uc));
@@ -986,7 +988,7 @@
 		err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
 
 	/* Store registers */
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -996,7 +998,7 @@
 	err |= __put_user(0, &uc->mcontext.greg [SVR4_PSR]);
 #else
 	i = tstate_to_psr(regs->tstate) & ~PSR_EF;		   
-	if (current->thread.fpsaved[0] & FPRS_FEF)
+	if (current_thread_info()->fpsaved[0] & FPRS_FEF)
 		i |= PSR_EF;
 	err |= __put_user(i, &uc->mcontext.greg [SVR4_PSR]);
 #endif
@@ -1023,7 +1025,6 @@
 /* Set the context for a svr4 application, this is Solaris way to sigreturn */
 asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
 {
-	struct thread_struct *tp = &current->thread;
 	svr4_gregset_t  *gr;
 	u32 pc, npc, psr;
 	sigset_t set;
@@ -1036,8 +1037,10 @@
 	 */
 	flush_user_windows();
 	
-	if (tp->w_saved){
-		printk ("Uh oh, w_saved is: 0x%x\n", tp->w_saved);
+	if (get_thread_wsaved()) {
+#ifdef DEBUG_SIGNALS	
+		printk ("Uh oh, w_saved is: 0x%x\n", get_thread_wsaved());
+#endif
 		goto sigsegv;
 	}
 	if (((unsigned long) c) & 3){
@@ -1045,7 +1048,7 @@
 		goto sigsegv;
 	}
 
-	if(!__access_ok((unsigned long)c, sizeof(*c))) {
+	if (!__access_ok((unsigned long)c, sizeof(*c))) {
 		/* Miguel, add nice debugging msg _here_. ;-) */
 		goto sigsegv;
 	}
@@ -1054,7 +1057,7 @@
 	gr = &c->mcontext.greg;
 	err = __get_user(pc, &((*gr)[SVR4_PC]));
 	err |= __get_user(npc, &((*gr)[SVR4_NPC]));
-	if((pc | npc) & 3) {
+	if ((pc | npc) & 3) {
 #ifdef DEBUG_SIGNALS	
 	        printk ("setcontext, PC or nPC were bogus\n");
 #endif
@@ -1087,7 +1090,7 @@
 	spin_unlock_irq(&current->sigmask_lock);
 	regs->tpc = pc;
 	regs->tnpc = npc | 1;
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -1096,7 +1099,7 @@
 	regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
 	regs->tstate |= psr_to_tstate_icc(psr);
 #if 0	
-	if(psr & PSR_EF)
+	if (psr & PSR_EF)
 		regs->tstate |= TSTATE_PEF;
 #endif
 	/* Restore g[1..7] and o[0..7] registers */
@@ -1104,7 +1107,7 @@
 		err |= __get_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
 	for (i = 0; i < 8; i++)
 		err |= __get_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
-	if(err)
+	if (err)
 		goto sigsegv;
 
 	return -EINTR;
@@ -1127,7 +1130,7 @@
 	save_and_clear_fpu();
 	
 	sigframe_size = RT_ALIGNEDSZ;
-	if (!(current->thread.fpsaved[0] & FPRS_FEF))
+	if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
 		sigframe_size -= sizeof(__siginfo_fpu_t);
 
 	sf = (struct rt_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size);
@@ -1140,7 +1143,7 @@
 		goto sigill;
 	}
 
-	if (current->thread.w_saved != 0) {
+	if (get_thread_wsaved() != 0) {
 #ifdef DEBUG_SIGNALS
 		printk ("%s[%d]: Invalid user stack frame for "
 			"signal delivery.\n", current->comm, current->pid);
@@ -1149,7 +1152,7 @@
 	}
 
 	/* 2. Save the current process state */
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -1157,7 +1160,7 @@
 	err |= __put_user(regs->tnpc, &sf->regs.npc);
 	err |= __put_user(regs->y, &sf->regs.y);
 	psr = tstate_to_psr (regs->tstate);
-	if(current->thread.fpsaved[0] & FPRS_FEF)
+	if (current_thread_info()->fpsaved[0] & FPRS_FEF)
 		psr |= PSR_EF;
 	err |= __put_user(psr, &sf->regs.psr);
 	for (i = 0; i < 16; i++)
@@ -1208,7 +1211,7 @@
 	/* 4. signal handler */
 	regs->tpc = (unsigned long) ka->sa.sa_handler;
 	regs->tnpc = (regs->tpc + 4);
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -1233,7 +1236,7 @@
 		if (err)
 			goto sigsegv;
 
-		if(pte_present(*ptep)) {
+		if (pte_present(*ptep)) {
 			unsigned long page = (unsigned long) page_address(pte_page(*ptep));
 
 			__asm__ __volatile__(
@@ -1256,19 +1259,19 @@
 				   sigset_t *oldset, struct pt_regs *regs,
 				   int svr4_signal)
 {
-	if(svr4_signal)
+	if (svr4_signal)
 		setup_svr4_frame32(&ka->sa, regs->tpc, regs->tnpc, regs, signr, oldset);
 	else {
 		if (ka->sa.sa_flags & SA_SIGINFO)
 			setup_rt_frame32(ka, regs, signr, oldset, info);
-		else if (current->thread.flags & SPARC_FLAG_NEWSIGNALS)
+		else if (test_thread_flag(TIF_NEWSIGNALS))
 			new_setup_frame32(ka, regs, signr, oldset);
 		else
 			setup_frame32(&ka->sa, regs, signr, oldset, info);
 	}
-	if(ka->sa.sa_flags & SA_ONESHOT)
+	if (ka->sa.sa_flags & SA_ONESHOT)
 		ka->sa.sa_handler = SIG_DFL;
-	if(!(ka->sa.sa_flags & SA_NOMASK)) {
+	if (!(ka->sa.sa_flags & SA_NOMASK)) {
 		spin_lock_irq(&current->sigmask_lock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,signr);
@@ -1280,14 +1283,14 @@
 static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
 				     struct sigaction *sa)
 {
-	switch(regs->u_regs[UREG_I0]) {
+	switch (regs->u_regs[UREG_I0]) {
 		case ERESTARTNOHAND:
 		no_system_call_restart:
 			regs->u_regs[UREG_I0] = EINTR;
 			regs->tstate |= TSTATE_ICARRY;
 			break;
 		case ERESTARTSYS:
-			if(!(sa->sa_flags & SA_RESTART))
+			if (!(sa->sa_flags & SA_RESTART))
 				goto no_system_call_restart;
 		/* fallthrough */
 		case ERESTARTNOINTR:
@@ -1402,8 +1405,8 @@
 		
 		ka = &current->sig->action[signr-1];
 		
-		if(ka->sa.sa_handler == SIG_IGN) {
-			if(signr != SIGCHLD)
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
 				continue;
 
 			/* sys_wait4() grabs the master kernel lock, so
@@ -1411,16 +1414,16 @@
 			 * threaded and would not be that difficult to
 			 * do anyways.
 			 */
-			while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
 				;
 			continue;
 		}
-		if(ka->sa.sa_handler == SIG_DFL) {
+		if (ka->sa.sa_handler == SIG_DFL) {
 			unsigned long exit_code = signr;
 			
-			if(current->pid == 1)
+			if (current->pid == 1)
 				continue;
-			switch(signr) {
+			switch (signr) {
 			case SIGCONT: case SIGCHLD: case SIGWINCH:
 				continue;
 
@@ -1433,8 +1436,8 @@
 					continue;
 				current->state = TASK_STOPPED;
 				current->exit_code = signr;
-				if(!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
-				     SA_NOCLDSTOP))
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
+				      SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
 				continue;
@@ -1457,15 +1460,15 @@
 					extern void sparc_ultra_dump_dtlb(void);
 					sparc_ultra_dump_dtlb();
 					sparc_ultra_dump_itlb();
-				} while(0);
+				} while (0);
 #endif
 #ifdef DEBUG_SIGNALS_TRACE
 				{
 					struct reg_window32 *rw = (struct reg_window32 *)(regs->u_regs[UREG_FP] & 0xffffffff);
 					unsigned int ins[8];
 
-					while(rw &&
-					      !(((unsigned long) rw) & 0x3)) {
+					while (rw &&
+					       !(((unsigned long) rw) & 0x3)) {
 						copy_from_user(ins, &rw->ins[0], sizeof(ins));
 						printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
 						rw = (struct reg_window32 *)(unsigned long)ins[6];
@@ -1483,15 +1486,15 @@
 				/* NOT REACHED */
 			}
 		}
-		if(restart_syscall)
+		if (restart_syscall)
 			syscall_restart32(orig_i0, regs, &ka->sa);
 		handle_signal32(signr, ka, &info, oldset, regs, svr4_signal);
 		return 1;
 	}
-	if(restart_syscall &&
-	   (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-	    regs->u_regs[UREG_I0] == ERESTARTSYS ||
-	    regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+	if (restart_syscall &&
+	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->tpc -= 4;
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 988b6a9..e0b6632 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -212,7 +212,7 @@
 	/* Clear this or we will die instantly when we
 	 * schedule back to this idler...
 	 */
-	current->thread.flags &= ~(SPARC_FLAG_NEWCHILD);
+	clear_thread_flag(TIF_NEWCHILD);
 
 	/* Attach to the address space of init_task. */
 	atomic_inc(&init_mm.mm_count);
@@ -236,7 +236,7 @@
  * 32-bits (I think) so to be safe we have it read the pointer
  * contained here so we work on >4GB machines. -DaveM
  */
-static struct task_struct *cpu_new_task = NULL;
+static struct thread_info *cpu_new_thread = NULL;
 
 static void smp_tune_scheduling(void);
 
@@ -261,7 +261,7 @@
 			goto ignorecpu;
 		if (cpu_present_map & (1UL << i)) {
 			unsigned long entry = (unsigned long)(&sparc64_cpu_startup);
-			unsigned long cookie = (unsigned long)(&cpu_new_task);
+			unsigned long cookie = (unsigned long)(&cpu_new_thread);
 			struct task_struct *p;
 			int timeout;
 			int no;
@@ -280,7 +280,7 @@
 			for (no = 0; no < linux_num_cpus; no++)
 				if (linux_cpus[no].mid == i)
 					break;
-			cpu_new_task = p;
+			cpu_new_thread = p->thread_info;
 			prom_startcpu(linux_cpus[no].prom_node,
 				      entry, cookie);
 			for (timeout = 0; timeout < 5000000; timeout++) {
@@ -305,7 +305,7 @@
 			__cpu_number_map[i] = -1;
 		}
 	}
-	cpu_new_task = NULL;
+	cpu_new_thread = NULL;
 	if (cpucount == 0) {
 		if (max_cpus != 1)
 			printk("Error: only one processor found.\n");
@@ -902,7 +902,7 @@
 	if (smp_processors_ready && (cpu_present_map & mask) != 0) {
 		u64 data0 = (((u64)&xcall_migrate_task) & 0xffffffff);
 
-		spin_lock(&migration_lock);
+		_raw_spin_lock(&migration_lock);
 		new_task = p;
 
 		if (tlb_type == spitfire)
@@ -923,7 +923,7 @@
 	clear_softint(1 << irq);
 
 	p = new_task;
-	spin_unlock(&migration_lock);
+	_raw_spin_unlock(&migration_lock);
 	sched_task_migrated(p);
 }
 
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 0e066d7..f06d0b2 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.120 2001/12/21 04:56:15 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.121 2002/02/09 19:49:31 davem Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -80,6 +80,11 @@
 extern void tl0_solaris(void);
 extern void sys_sigsuspend(void);
 extern int sys_getppid(void);
+extern int sys_getpid(void);
+extern int sys_geteuid(void);
+extern int sys_getuid(void);
+extern int sys_getegid(void);
+extern int sys_getgid(void);
 extern int svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs);
 extern int svr4_setcontext(svr4_ucontext_t *uc, struct pt_regs *regs);
 extern int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
@@ -307,6 +312,11 @@
 EXPORT_SYMBOL(tl0_solaris);
 EXPORT_SYMBOL(sys_sigsuspend);
 EXPORT_SYMBOL(sys_getppid);
+EXPORT_SYMBOL(sys_getpid);
+EXPORT_SYMBOL(sys_geteuid);
+EXPORT_SYMBOL(sys_getuid);
+EXPORT_SYMBOL(sys_getegid);
+EXPORT_SYMBOL(sys_getgid);
 EXPORT_SYMBOL(svr4_getcontext);
 EXPORT_SYMBOL(svr4_setcontext);
 EXPORT_SYMBOL(prom_cpu_nodes);
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index 353ddf6..9fb202a 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.56 2001/12/21 04:56:15 davem Exp $
+/* $Id: sys_sparc.c,v 1.57 2002/02/09 19:49:30 davem Exp $
  * linux/arch/sparc64/kernel/sys_sparc.c
  *
  * This file contains various random system calls that
@@ -59,7 +59,7 @@
 		return addr;
 	}
 
-	if (current->thread.flags & SPARC_FLAG_32BIT)
+	if (test_thread_flag(TIF_32BIT))
 		task_size = 0xf0000000UL;
 	if (len > task_size || len > -PAGE_OFFSET)
 		return -ENOMEM;
@@ -140,7 +140,7 @@
 asmlinkage unsigned long sparc_brk(unsigned long brk)
 {
 	/* People could try to be nasty and use ta 0x6d in 32bit programs */
-	if ((current->thread.flags & SPARC_FLAG_32BIT) &&
+	if (test_thread_flag(TIF_32BIT) &&
 	    brk >= 0xf0000000UL)
 		return current->mm->brk;
 
@@ -289,7 +289,7 @@
 	len = PAGE_ALIGN(len);
 	retval = -EINVAL;
 
-	if (current->thread.flags & SPARC_FLAG_32BIT) {
+	if (test_thread_flag(TIF_32BIT)) {
 		if (len > 0xf0000000UL ||
 		    ((flags & MAP_FIXED) && addr > 0xf0000000UL - len))
 			goto out_putf;
@@ -334,7 +334,7 @@
 {
 	struct vm_area_struct *vma;
 	unsigned long ret = -EINVAL;
-	if (current->thread.flags & SPARC_FLAG_32BIT)
+	if (test_thread_flag(TIF_32BIT))
 		goto out;
 	if (old_len > -PAGE_OFFSET || new_len > -PAGE_OFFSET)
 		goto out;
@@ -401,7 +401,7 @@
 {
 	siginfo_t info;
 
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -454,7 +454,7 @@
 
 	regs->tpc = regs->tnpc;
 	regs->tnpc += 4;
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -474,7 +474,7 @@
 
 	regs->tpc = regs->tnpc;
 	regs->tnpc += 4;
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -494,11 +494,11 @@
 		return -EINVAL;
 	if (new_p == (utrap_handler_t)(long)UTH_NOCHANGE) {
 		if (old_p) {
-			if (!current->thread.utraps) {
+			if (!current_thread_info()->utraps) {
 				if (put_user(NULL, old_p))
 					return -EFAULT;
 			} else {
-				if (put_user((utrap_handler_t)(current->thread.utraps[type]), old_p))
+				if (put_user((utrap_handler_t)(current_thread_info()->utraps[type]), old_p))
 					return -EFAULT;
 			}
 		}
@@ -508,39 +508,39 @@
 		}
 		return 0;
 	}
-	if (!current->thread.utraps) {
-		current->thread.utraps =
+	if (!current_thread_info()->utraps) {
+		current_thread_info()->utraps =
 			kmalloc((UT_TRAP_INSTRUCTION_31+1)*sizeof(long), GFP_KERNEL);
-		if (!current->thread.utraps) return -ENOMEM;
-		current->thread.utraps[0] = 1;
-		memset(current->thread.utraps+1, 0, UT_TRAP_INSTRUCTION_31*sizeof(long));
+		if (!current_thread_info()->utraps) return -ENOMEM;
+		current_thread_info()->utraps[0] = 1;
+		memset(current_thread_info()->utraps+1, 0, UT_TRAP_INSTRUCTION_31*sizeof(long));
 	} else {
-		if ((utrap_handler_t)current->thread.utraps[type] != new_p &&
-		    current->thread.utraps[0] > 1) {
-			long *p = current->thread.utraps;
+		if ((utrap_handler_t)current_thread_info()->utraps[type] != new_p &&
+		    current_thread_info()->utraps[0] > 1) {
+			long *p = current_thread_info()->utraps;
 
-			current->thread.utraps =
+			current_thread_info()->utraps =
 				kmalloc((UT_TRAP_INSTRUCTION_31+1)*sizeof(long),
 					GFP_KERNEL);
-			if (!current->thread.utraps) {
-				current->thread.utraps = p;
+			if (!current_thread_info()->utraps) {
+				current_thread_info()->utraps = p;
 				return -ENOMEM;
 			}
 			p[0]--;
-			current->thread.utraps[0] = 1;
-			memcpy(current->thread.utraps+1, p+1,
+			current_thread_info()->utraps[0] = 1;
+			memcpy(current_thread_info()->utraps+1, p+1,
 			       UT_TRAP_INSTRUCTION_31*sizeof(long));
 		}
 	}
 	if (old_p) {
-		if (put_user((utrap_handler_t)(current->thread.utraps[type]), old_p))
+		if (put_user((utrap_handler_t)(current_thread_info()->utraps[type]), old_p))
 			return -EFAULT;
 	}
 	if (old_d) {
 		if (put_user(NULL, old_d))
 			return -EFAULT;
 	}
-	current->thread.utraps[type] = (long)new_p;
+	current_thread_info()->utraps[type] = (long)new_p;
 
 	return 0;
 }
@@ -589,10 +589,10 @@
 	unsigned long pic, tmp;
 
 	read_pic(pic);
-	tmp = (current->thread.kernel_cntd0 += (unsigned int)pic);
-	__put_user(tmp, current->thread.user_cntd0);
-	tmp = (current->thread.kernel_cntd1 += (pic >> 32));
-	__put_user(tmp, current->thread.user_cntd1);
+	tmp = (current_thread_info()->kernel_cntd0 += (unsigned int)pic);
+	__put_user(tmp, current_thread_info()->user_cntd0);
+	tmp = (current_thread_info()->kernel_cntd1 += (pic >> 32));
+	__put_user(tmp, current_thread_info()->user_cntd1);
 	reset_pic();
 }
 
@@ -603,24 +603,24 @@
 
 	switch(opcode) {
 	case PERFCTR_ON:
-		current->thread.pcr_reg = arg2;
-		current->thread.user_cntd0 = (u64 *) arg0;
-		current->thread.user_cntd1 = (u64 *) arg1;
-		current->thread.kernel_cntd0 =
-			current->thread.kernel_cntd1 = 0;
+		current_thread_info()->pcr_reg = arg2;
+		current_thread_info()->user_cntd0 = (u64 *) arg0;
+		current_thread_info()->user_cntd1 = (u64 *) arg1;
+		current_thread_info()->kernel_cntd0 =
+			current_thread_info()->kernel_cntd1 = 0;
 		write_pcr(arg2);
 		reset_pic();
-		current->thread.flags |= SPARC_FLAG_PERFCTR;
+		set_thread_flag(TIF_PERFCTR);
 		break;
 
 	case PERFCTR_OFF:
 		err = -EINVAL;
-		if ((current->thread.flags & SPARC_FLAG_PERFCTR) != 0) {
-			current->thread.user_cntd0 =
-				current->thread.user_cntd1 = NULL;
-			current->thread.pcr_reg = 0;
+		if (test_thread_flag(TIF_PERFCTR)) {
+			current_thread_info()->user_cntd0 =
+				current_thread_info()->user_cntd1 = NULL;
+			current_thread_info()->pcr_reg = 0;
 			write_pcr(0);
-			current->thread.flags &= ~(SPARC_FLAG_PERFCTR);
+			clear_thread_flag(TIF_PERFCTR);
 			err = 0;
 		}
 		break;
@@ -628,50 +628,50 @@
 	case PERFCTR_READ: {
 		unsigned long pic, tmp;
 
-		if (!(current->thread.flags & SPARC_FLAG_PERFCTR)) {
+		if (!test_thread_flag(TIF_PERFCTR)) {
 			err = -EINVAL;
 			break;
 		}
 		read_pic(pic);
-		tmp = (current->thread.kernel_cntd0 += (unsigned int)pic);
-		err |= __put_user(tmp, current->thread.user_cntd0);
-		tmp = (current->thread.kernel_cntd1 += (pic >> 32));
-		err |= __put_user(tmp, current->thread.user_cntd1);
+		tmp = (current_thread_info()->kernel_cntd0 += (unsigned int)pic);
+		err |= __put_user(tmp, current_thread_info()->user_cntd0);
+		tmp = (current_thread_info()->kernel_cntd1 += (pic >> 32));
+		err |= __put_user(tmp, current_thread_info()->user_cntd1);
 		reset_pic();
 		break;
 	}
 
 	case PERFCTR_CLRPIC:
-		if (!(current->thread.flags & SPARC_FLAG_PERFCTR)) {
+		if (!test_thread_flag(TIF_PERFCTR)) {
 			err = -EINVAL;
 			break;
 		}
-		current->thread.kernel_cntd0 =
-			current->thread.kernel_cntd1 = 0;
+		current_thread_info()->kernel_cntd0 =
+			current_thread_info()->kernel_cntd1 = 0;
 		reset_pic();
 		break;
 
 	case PERFCTR_SETPCR: {
 		u64 *user_pcr = (u64 *)arg0;
-		if (!(current->thread.flags & SPARC_FLAG_PERFCTR)) {
+		if (!test_thread_flag(TIF_PERFCTR)) {
 			err = -EINVAL;
 			break;
 		}
-		err |= __get_user(current->thread.pcr_reg, user_pcr);
-		write_pcr(current->thread.pcr_reg);
-		current->thread.kernel_cntd0 =
-			current->thread.kernel_cntd1 = 0;
+		err |= __get_user(current_thread_info()->pcr_reg, user_pcr);
+		write_pcr(current_thread_info()->pcr_reg);
+		current_thread_info()->kernel_cntd0 =
+			current_thread_info()->kernel_cntd1 = 0;
 		reset_pic();
 		break;
 	}
 
 	case PERFCTR_GETPCR: {
 		u64 *user_pcr = (u64 *)arg0;
-		if (!(current->thread.flags & SPARC_FLAG_PERFCTR)) {
+		if (!test_thread_flag(TIF_PERFCTR)) {
 			err = -EINVAL;
 			break;
 		}
-		err |= __put_user(current->thread.pcr_reg, user_pcr);
+		err |= __put_user(current_thread_info()->pcr_reg, user_pcr);
 		break;
 	}
 
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 53987ff..d472d4d 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.182 2001/10/18 09:06:36 davem Exp $
+/* $Id: sys_sparc32.c,v 1.184 2002/02/09 19:49:31 davem Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -49,6 +49,7 @@
 #include <linux/in.h>
 #include <linux/icmpv6.h>
 #include <linux/sysctl.h>
+#include <linux/binfmts.h>
 
 #include <asm/types.h>
 #include <asm/ipc.h>
@@ -1461,6 +1462,8 @@
 
 static int cp_new_stat32(struct kstat *stat, struct stat32 *statbuf)
 {
+	int err;
+
 	err  = put_user(stat->dev, &statbuf->st_dev);
 	err |= put_user(stat->ino, &statbuf->st_ino);
 	err |= put_user(stat->mode, &statbuf->st_mode);
@@ -1479,6 +1482,7 @@
 	err |= put_user(stat->blocks, &statbuf->st_blocks);
 	err |= put_user(0, &statbuf->__unused4[0]);
 	err |= put_user(0, &statbuf->__unused4[1]);
+
 	return err;
 }
 
@@ -2723,8 +2727,8 @@
         struct k_sigaction new_ka, old_ka;
         int ret;
 
-	if(sig < 0) {
-		current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
+	if (sig < 0) {
+		set_thread_flag(TIF_NEWSIGNALS);
 		sig = -sig;
 	}
 
@@ -2768,7 +2772,7 @@
 	/* All tasks which use RT signals (effectively) use
 	 * new style signals.
 	 */
-	current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
+	set_thread_flag(TIF_NEWSIGNALS);
 
         if (act) {
 		new_ka.ka_restorer = restorer;
@@ -2991,8 +2995,8 @@
 
 	if(!error) {
 		fprs_write(0);
-		current->thread.xfsr[0] = 0;
-		current->thread.fpsaved[0] = 0;
+		current_thread_info()->xfsr[0] = 0;
+		current_thread_info()->fpsaved[0] = 0;
 		regs->tstate &= ~TSTATE_PEF;
 	}
 out:
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 526a11a..c21d66b 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos32.c,v 1.62 2002/01/08 16:00:14 davem Exp $
+/* $Id: sys_sunos32.c,v 1.64 2002/02/09 19:49:31 davem Exp $
  * sys_sunos32.c: SunOS binary compatability layer on sparc64.
  *
  * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -455,8 +455,8 @@
 	siginfo_t info;
 	static int cnt;
 
-	regs = current->thread.kregs;
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	regs = current_thread_info()->kregs;
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -1046,7 +1046,7 @@
 		if(!kmbuf)
 			break;
 		sp = (struct sparc_stackf32 *)
-			(current->thread.kregs->u_regs[UREG_FP] & 0xffffffffUL);
+			(current_thread_info()->kregs->u_regs[UREG_FP] & 0xffffffffUL);
 		if(get_user(arg5, &sp->xxargs[0])) {
 			rval = -EFAULT;
 			kfree(kmbuf);
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index d27d7a9..f89361a 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.80 2002/01/31 03:30:06 davem Exp $
+/* $Id: systbls.S,v 1.81 2002/02/08 03:57:14 davem Exp $
  * systbls.S: System call entry point tables for OS compatibility.
  *            The native Linux system call table lives here also.
  *
@@ -56,7 +56,7 @@
 /*170*/	.word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents
 	.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
 /*180*/	.word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys32_query_module
-	.word sys_setpgid, sys_fremovexattr, sys_nis_syscall, sys_nis_syscall, sparc64_newuname
+	.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
 /*190*/	.word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 	.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
 /*200*/	.word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
@@ -70,7 +70,7 @@
 /*240*/	.word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
 	.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, sys32_nanosleep
 /*250*/	.word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl
-	.word sys_aplib, sys_tkill
+	.word sys_aplib
 
 	/* Now the 64-bit native Linux syscall table. */
 
@@ -115,7 +115,7 @@
 /*170*/	.word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
 	.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
 /*180*/	.word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_query_module
-	.word sys_setpgid, sys_fremovexattr, sys_nis_syscall, sys_nis_syscall, sparc64_newuname
+	.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
 /*190*/	.word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 	.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
 /*200*/	.word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
@@ -129,7 +129,7 @@
 /*240*/	.word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
 	.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
 /*250*/	.word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
-	.word sys_aplib, sys_tkill
+	.word sys_aplib
 
 #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
     defined(CONFIG_SOLARIS_EMUL_MODULE)
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
index eda8ed5..2c48784 100644
--- a/arch/sparc64/kernel/trampoline.S
+++ b/arch/sparc64/kernel/trampoline.S
@@ -1,4 +1,4 @@
-/* $Id: trampoline.S,v 1.25 2002/01/11 08:45:38 davem Exp $
+/* $Id: trampoline.S,v 1.26 2002/02/09 19:49:30 davem Exp $
  * trampoline.S: Jump start slave processors on sparc64.
  *
  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -14,7 +14,7 @@
 #include <asm/pgtable.h>
 #include <asm/spitfire.h>
 #include <asm/processor.h>
-#include <asm/asm_offsets.h>
+#include <asm/thread_info.h>
 
 	.data
 	.align	8
@@ -262,7 +262,7 @@
 	wrpr		%o1, PSTATE_IG, %pstate
 
 	/* Get our UPA MID. */
-	lduw		[%o2 + AOFF_task_cpu], %g1
+	ldub		[%o2 + TI_CPU], %g1
 	sethi		%hi(cpu_data), %g5
 	or		%g5, %lo(cpu_data), %g5
 
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index b2bdafb..2268e15 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.84 2002/01/30 01:39:56 davem Exp $
+/* $Id: traps.c,v 1.85 2002/02/09 19:49:31 davem Exp $
  * arch/sparc64/kernel/traps.c
  *
  * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -51,7 +51,7 @@
 		sprintf(buffer, "Kernel bad sw trap %lx", lvl);
 		die_if_kernel (buffer, regs);
 	}
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -89,7 +89,7 @@
 		       sfsr, sfar);
 		die_if_kernel("Iax", regs);
 	}
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -1311,14 +1311,14 @@
 
 void do_fpe_common(struct pt_regs *regs)
 {
-	if(regs->tstate & TSTATE_PRIV) {
+	if (regs->tstate & TSTATE_PRIV) {
 		regs->tpc = regs->tnpc;
 		regs->tnpc += 4;
 	} else {
-		unsigned long fsr = current->thread.xfsr[0];
+		unsigned long fsr = current_thread_info()->xfsr[0];
 		siginfo_t info;
 
-		if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+		if (test_thread_flag(TIF_32BIT)) {
 			regs->tpc &= 0xffffffff;
 			regs->tnpc &= 0xffffffff;
 		}
@@ -1355,7 +1355,7 @@
 	struct fpustate *f = FPUSTATE;
 	int ret = 0;
 
-	switch ((current->thread.xfsr[0] & 0x1c000)) {
+	switch ((current_thread_info()->xfsr[0] & 0x1c000)) {
 	case (2 << 14): /* unfinished_FPop */
 	case (3 << 14): /* unimplemented_FPop */
 		ret = do_mathemu(regs, f);
@@ -1370,9 +1370,9 @@
 {
 	siginfo_t info;
 
-	if(regs->tstate & TSTATE_PRIV)
+	if (regs->tstate & TSTATE_PRIV)
 		die_if_kernel("Penguin overflow trap from kernel mode", regs);
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -1388,7 +1388,7 @@
 {
 	siginfo_t info;
 
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -1404,11 +1404,11 @@
 {
 	int i;
 
-	if((((unsigned long) pc) & 3))
+	if ((((unsigned long) pc) & 3))
 		return;
 
 	printk("Instruction DUMP:");
-	for(i = -3; i < 6; i++)
+	for (i = -3; i < 6; i++)
 		printk("%c%08x%c",i?' ':'<',pc[i],i?' ':'>');
 	printk("\n");
 }
@@ -1418,14 +1418,14 @@
 	int i;
 	unsigned int buf[9];
 	
-	if((((unsigned long) pc) & 3))
+	if ((((unsigned long) pc) & 3))
 		return;
 		
-	if(copy_from_user(buf, pc - 3, sizeof(buf)))
+	if (copy_from_user(buf, pc - 3, sizeof(buf)))
 		return;
 
 	printk("Instruction DUMP:");
-	for(i = 0; i < 9; i++)
+	for (i = 0; i < 9; i++)
 		printk("%c%08x%c",i==3?' ':'<',buf[i],i==3?' ':'>');
 	printk("\n");
 }
@@ -1433,18 +1433,18 @@
 void show_trace_task(struct task_struct *tsk)
 {
 	unsigned long pc, fp;
-	unsigned long task_base = (unsigned long)tsk;
+	unsigned long thread_base = (unsigned long) tsk->thread_info;
 	struct reg_window *rw;
 	int count = 0;
 
 	if (!tsk)
 		return;
 
-	fp = tsk->thread.ksp + STACK_BIAS;
+	fp = tsk->thread_info->ksp + STACK_BIAS;
 	do {
 		/* Bogus frame pointer? */
-		if (fp < (task_base + sizeof(struct task_struct)) ||
-		    fp >= (task_base + THREAD_SIZE))
+		if (fp < (thread_base + sizeof(struct thread_info)) ||
+		    fp >= (thread_base + THREAD_SIZE))
 			break;
 		rw = (struct reg_window *)fp;
 		pc = rw->ins[7];
@@ -1471,7 +1471,7 @@
 	printk("%s(%d): %s\n", current->comm, current->pid, str);
 	__asm__ __volatile__("flushw");
 	__show_regs(regs);
-	if(regs->tstate & TSTATE_PRIV) {
+	if (regs->tstate & TSTATE_PRIV) {
 		struct reg_window *rw = (struct reg_window *)
 			(regs->u_regs[UREG_FP] + STACK_BIAS);
 
@@ -1479,12 +1479,12 @@
 		 * find some badly aligned kernel stack.
 		 */
 		lastrw = (struct reg_window *)current;
-		while(rw					&&
-		      count++ < 30				&&
-		      rw >= lastrw				&&
-		      (char *) rw < ((char *) current)
-		        + sizeof (union task_union) 		&&
-		      !(((unsigned long) rw) & 0x7)) {
+		while (rw					&&
+		       count++ < 30				&&
+		       rw >= lastrw				&&
+		       (char *) rw < ((char *) current)
+		       + sizeof (union thread_union) 		&&
+		       !(((unsigned long) rw) & 0x7)) {
 			printk("Caller[%016lx]\n", rw->ins[7]);
 			lastrw = rw;
 			rw = (struct reg_window *)
@@ -1492,7 +1492,7 @@
 		}
 		instruction_dump ((unsigned int *) regs->tpc);
 	} else {
-		if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+		if (test_thread_flag(TIF_32BIT)) {
 			regs->tpc &= 0xffffffff;
 			regs->tnpc &= 0xffffffff;
 		}
@@ -1502,7 +1502,7 @@
 	smp_report_regs();
 #endif
                                                 	
-	if(regs->tstate & TSTATE_PRIV)
+	if (regs->tstate & TSTATE_PRIV)
 		do_exit(SIGKILL);
 	do_exit(SIGSEGV);
 }
@@ -1517,9 +1517,9 @@
 	u32 insn;
 	siginfo_t info;
 
-	if(tstate & TSTATE_PRIV)
+	if (tstate & TSTATE_PRIV)
 		die_if_kernel("Kernel illegal instruction", regs);
-	if(current->thread.flags & SPARC_FLAG_32BIT)
+	if (test_thread_flag(TIF_32BIT))
 		pc = (u32)pc;
 	if (get_user(insn, (u32 *)pc) != -EFAULT) {
 		if ((insn & 0xc1ffc000) == 0x81700000) /* POPC */ {
@@ -1542,7 +1542,7 @@
 {
 	siginfo_t info;
 
-	if(regs->tstate & TSTATE_PRIV) {
+	if (regs->tstate & TSTATE_PRIV) {
 		extern void kernel_unaligned_trap(struct pt_regs *regs,
 						  unsigned int insn, 
 						  unsigned long sfar, unsigned long sfsr);
@@ -1561,7 +1561,7 @@
 {
 	siginfo_t info;
 
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -1669,15 +1669,42 @@
 	regs->u_regs[UREG_I0] = tstate_to_psr(regs->tstate);
 	regs->tpc   = regs->tnpc;
 	regs->tnpc += 4;
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
 }
 
+extern void thread_info_offsets_are_bolixed_dave(void);
+
 /* Only invoked on boot processor. */
 void trap_init(void)
 {
+	/* Compile time sanity check. */
+	if (TI_TASK != offsetof(struct thread_info, task) ||
+	    TI_FLAGS != offsetof(struct thread_info, flags) ||
+	    TI_CPU != offsetof(struct thread_info, cpu) ||
+	    TI_FPSAVED != offsetof(struct thread_info, fpsaved) ||
+	    TI_KSP != offsetof(struct thread_info, ksp) ||
+	    TI_FAULT_ADDR != offsetof(struct thread_info, fault_address) ||
+	    TI_KREGS != offsetof(struct thread_info, kregs) ||
+	    TI_UTRAPS != offsetof(struct thread_info, utraps) ||
+	    TI_EXEC_DOMAIN != offsetof(struct thread_info, exec_domain) ||
+	    TI_REG_WINDOW != offsetof(struct thread_info, reg_window) ||
+	    TI_RWIN_SPTRS != offsetof(struct thread_info, rwbuf_stkptrs) ||
+	    TI_GSR != offsetof(struct thread_info, gsr) ||
+	    TI_XFSR != offsetof(struct thread_info, xfsr) ||
+	    TI_USER_CNTD0 != offsetof(struct thread_info, user_cntd0) ||
+	    TI_USER_CNTD1 != offsetof(struct thread_info, user_cntd1) ||
+	    TI_KERN_CNTD0 != offsetof(struct thread_info, kernel_cntd0) ||
+	    TI_KERN_CNTD1 != offsetof(struct thread_info, kernel_cntd1) ||
+	    TI_PCR != offsetof(struct thread_info, pcr_reg) ||
+	    TI_CEE_STUFF != offsetof(struct thread_info, cee_stuff) ||
+	    TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) ||
+	    TI_FPREGS != offsetof(struct thread_info, fpregs) ||
+	    (TI_FPREGS & (64 - 1)))
+		thread_info_offsets_are_bolixed_dave();
+
 	/* Attach to the address space of init_task.  On SMP we
 	 * do this in smp.c:smp_callin for other cpus.
 	 */
@@ -1685,6 +1712,6 @@
 	current->active_mm = &init_mm;
 
 #ifdef CONFIG_SMP
-	current->cpu = hard_smp_processor_id();
+	current_thread_info()->cpu = hard_smp_processor_id();
 #endif
 }
diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S
index 576127b..2473abf 100644
--- a/arch/sparc64/kernel/ttable.S
+++ b/arch/sparc64/kernel/ttable.S
@@ -1,4 +1,4 @@
-/* $Id: ttable.S,v 1.37 2002/01/23 11:27:32 davem Exp $
+/* $Id: ttable.S,v 1.38 2002/02/09 19:49:30 davem Exp $
  * ttable.S: Sparc V9 Trap Table(s) with SpitFire/Cheetah extensions.
  *
  * Copyright (C) 1996, 2001 David S. Miller (davem@caip.rutgers.edu)
@@ -211,20 +211,20 @@
 tl1_paw:	TRAPTL1(do_paw_tl1)
 tl1_vaw:	TRAPTL1(do_vaw_tl1)
 
-		/* The grotty trick to save %g1 into current->thread.kernel_cntd0
+		/* The grotty trick to save %g1 into current->thread.cee_stuff
 		 * is because when we take this trap we could be interrupting trap
-		 * code already using the trap alternate global registers.  It is
-		 * better to corrupt a performance counter than corrupt trap register
-		 * state.  We cross our fingers and pray that this store/load does
+		 * code already using the trap alternate global registers.
+		 *
+		 * We cross our fingers and pray that this store/load does
 		 * not cause yet another CEE trap.
 		 */
 tl1_cee:	membar	#Sync
-		stx	%g1, [%g6 + AOFF_task_thread + AOFF_thread_kernel_cntd0]
+		stx	%g1, [%g6 + TI_CEE_STUFF]
 		ldxa	[%g0] ASI_AFSR, %g1
 		membar	#Sync
 		stxa	%g1, [%g0] ASI_AFSR
 		membar	#Sync
-		ldx	[%g6 + AOFF_task_thread + AOFF_thread_kernel_cntd0], %g1
+		ldx	[%g6 + TI_CEE_STUFF], %g1
 		retry
 
 tl1_iamiss:	BTRAPTL1(0x64) BTRAPTL1(0x65) BTRAPTL1(0x66) BTRAPTL1(0x67)
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
index 07c95ec..9a1334e 100644
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -1,4 +1,4 @@
-/* $Id: unaligned.c,v 1.23 2001/04/09 04:29:03 davem Exp $
+/* $Id: unaligned.c,v 1.24 2002/02/09 19:49:31 davem Exp $
  * unaligned.c: Unaligned load/store trap handling with special
  *              cases for the kernel to do them more quickly.
  *
@@ -42,7 +42,7 @@
 {
 	unsigned long tmp = (insn >> 21) & 1;
 
-	if(!tmp)
+	if (!tmp)
 		return load;
 	else {
 		switch ((insn>>19)&0xf) {
@@ -63,15 +63,15 @@
 	if (tmp == 11 || tmp == 14) /* ldx/stx */
 		return 8;
 	tmp &= 3;
-	if(!tmp)
+	if (!tmp)
 		return 4;
-	else if(tmp == 3)
+	else if (tmp == 3)
 		return 16;	/* ldd/std - Although it is actually 8 */
-	else if(tmp == 2)
+	else if (tmp == 2)
 		return 2;
 	else {
 		printk("Impossible unaligned trap. insn=%08x\n", insn);
-		die_if_kernel("Byte sized unaligned access?!?!", current->thread.kregs);
+		die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs);
 	}
 }
 
@@ -95,8 +95,8 @@
 static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2,
 				       unsigned int rd, int from_kernel)
 {
-	if(rs2 >= 16 || rs1 >= 16 || rd >= 16) {
-		if(from_kernel != 0)
+	if (rs2 >= 16 || rs1 >= 16 || rd >= 16) {
+		if (from_kernel != 0)
 			__asm__ __volatile__("flushw");
 		else
 			flushw_user();
@@ -112,13 +112,13 @@
 {
 	unsigned long value;
 	
-	if(reg < 16)
+	if (reg < 16)
 		return (!reg ? 0 : regs->u_regs[reg]);
 	if (regs->tstate & TSTATE_PRIV) {
 		struct reg_window *win;
 		win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
 		value = win->locals[reg - 16];
-	} else if (current->thread.flags & SPARC_FLAG_32BIT) {
+	} else if (test_thread_flag(TIF_32BIT)) {
 		struct reg_window32 *win32;
 		win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
 		get_user(value, &win32->locals[reg - 16]);
@@ -132,13 +132,13 @@
 
 static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs)
 {
-	if(reg < 16)
+	if (reg < 16)
 		return &regs->u_regs[reg];
 	if (regs->tstate & TSTATE_PRIV) {
 		struct reg_window *win;
 		win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
 		return &win->locals[reg - 16];
-	} else if (current->thread.flags & SPARC_FLAG_32BIT) {
+	} else if (test_thread_flag(TIF_32BIT)) {
 		struct reg_window32 *win32;
 		win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
 		return (unsigned long *)&win32->locals[reg - 16];
@@ -156,7 +156,7 @@
 	unsigned int rs2 = insn & 0x1f;
 	int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
 
-	if(insn & 0x2000) {
+	if (insn & 0x2000) {
 		maybe_flush_windows(rs1, 0, rd, from_kernel);
 		return (fetch_reg(rs1, regs) + sign_extend_imm13(insn));
 	} else {
@@ -335,7 +335,7 @@
 {
 	regs->tpc   = regs->tnpc;
 	regs->tnpc += 4;
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
@@ -360,7 +360,7 @@
 
 	if (!fixup) {
 		unsigned long address = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f));
-        	if(address < PAGE_SIZE) {
+        	if (address < PAGE_SIZE) {
                 	printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference in mna handler");
         	} else
                 	printk(KERN_ALERT "Unable to handle kernel paging request in mna handler");
@@ -387,7 +387,7 @@
 	enum direction dir = decode_direction(insn);
 	int size = decode_access_size(insn);
 
-	if(!ok_for_kernel(insn) || dir == both) {
+	if (!ok_for_kernel(insn) || dir == both) {
 		printk("Unsupported unaligned load/store trap for kernel at <%016lx>.\n",
 		       regs->tpc);
 		unaligned_panic("Kernel does fpu/atomic unaligned load/store.", regs);
@@ -408,7 +408,7 @@
 		printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] retpc[%016lx]\n",
 		       regs->tpc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]);
 #endif
-		switch(dir) {
+		switch (dir) {
 		case load:
 			do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
 					size, (unsigned long *) addr,
@@ -459,11 +459,11 @@
 		ret += popc_helper[value & 0xf];
 		value >>= 4;
 	}
-	if(rd < 16) {
+	if (rd < 16) {
 		if (rd)
 			regs->u_regs[rd] = ret;
 	} else {
-		if (current->thread.flags & SPARC_FLAG_32BIT) {
+		if (test_thread_flag(TIF_32BIT)) {
 			struct reg_window32 *win32;
 			win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
 			put_user(ret, &win32->locals[rd - 16]);
@@ -490,9 +490,9 @@
 	int flag = (freg < 32) ? FPRS_DL : FPRS_DU;
 
 	save_and_clear_fpu();
-	current->thread.xfsr[0] &= ~0x1c000;
+	current_thread_info()->xfsr[0] &= ~0x1c000;
 	if (freg & 3) {
-		current->thread.xfsr[0] |= (6 << 14) /* invalid_fp_register */;
+		current_thread_info()->xfsr[0] |= (6 << 14) /* invalid_fp_register */;
 		do_fpother(regs);
 		return 0;
 	}
@@ -500,7 +500,7 @@
 		/* STQ */
 		u64 first = 0, second = 0;
 		
-		if (current->thread.fpsaved[0] & flag) {
+		if (current_thread_info()->fpsaved[0] & flag) {
 			first = *(u64 *)&f->regs[freg];
 			second = *(u64 *)&f->regs[freg+2];
 		}
@@ -575,18 +575,18 @@
 				break;
 			}
 		}
-		if (!(current->thread.fpsaved[0] & FPRS_FEF)) {
-			current->thread.fpsaved[0] = FPRS_FEF;
-			current->thread.gsr[0] = 0;
+		if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) {
+			current_thread_info()->fpsaved[0] = FPRS_FEF;
+			current_thread_info()->gsr[0] = 0;
 		}
-		if (!(current->thread.fpsaved[0] & flag)) {
+		if (!(current_thread_info()->fpsaved[0] & flag)) {
 			if (freg < 32)
 				memset(f->regs, 0, 32*sizeof(u32));
 			else
 				memset(f->regs+32, 0, 32*sizeof(u32));
 		}
 		memcpy(f->regs + freg, data, size * 4);
-		current->thread.fpsaved[0] |= flag;
+		current_thread_info()->fpsaved[0] |= flag;
 	}
 	advance(regs);
 	return 1;
@@ -604,7 +604,7 @@
 		reg[0] = 0;
 		if ((insn & 0x780000) == 0x180000)
 			reg[1] = 0;
-	} else if (current->thread.flags & SPARC_FLAG_32BIT) {
+	} else if (test_thread_flag(TIF_32BIT)) {
 		put_user(0, (int *)reg);
 		if ((insn & 0x780000) == 0x180000)
 			put_user(0, ((int *)reg) + 1);
@@ -627,9 +627,9 @@
 	int flag;
 	struct fpustate *f = FPUSTATE;
 
-	if(tstate & TSTATE_PRIV)
+	if (tstate & TSTATE_PRIV)
 		die_if_kernel("lddfmna from kernel", regs);
-	if(current->thread.flags & SPARC_FLAG_32BIT)
+	if (test_thread_flag(TIF_32BIT))
 		pc = (u32)pc;
 	if (get_user(insn, (u32 *)pc) != -EFAULT) {
 		asi = sfsr >> 16;
@@ -649,18 +649,18 @@
 		if (asi & 0x8) /* Little */
 			value = __swab64p(&value);
 		flag = (freg < 32) ? FPRS_DL : FPRS_DU;
-		if (!(current->thread.fpsaved[0] & FPRS_FEF)) {
-			current->thread.fpsaved[0] = FPRS_FEF;
-			current->thread.gsr[0] = 0;
+		if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) {
+			current_thread_info()->fpsaved[0] = FPRS_FEF;
+			current_thread_info()->gsr[0] = 0;
 		}
-		if (!(current->thread.fpsaved[0] & flag)) {
+		if (!(current_thread_info()->fpsaved[0] & flag)) {
 			if (freg < 32)
 				memset(f->regs, 0, 32*sizeof(u32));
 			else
 				memset(f->regs+32, 0, 32*sizeof(u32));
 		}
 		*(u64 *)(f->regs + freg) = value;
-		current->thread.fpsaved[0] |= flag;
+		current_thread_info()->fpsaved[0] |= flag;
 	} else {
 daex:		data_access_exception(regs);
 		return;
@@ -679,9 +679,9 @@
 	int flag;
 	struct fpustate *f = FPUSTATE;
 
-	if(tstate & TSTATE_PRIV)
+	if (tstate & TSTATE_PRIV)
 		die_if_kernel("stdfmna from kernel", regs);
-	if(current->thread.flags & SPARC_FLAG_32BIT)
+	if (test_thread_flag(TIF_32BIT))
 		pc = (u32)pc;
 	if (get_user(insn, (u32 *)pc) != -EFAULT) {
 		freg = ((insn >> 25) & 0x1e) | ((insn >> 20) & 0x20);
@@ -692,7 +692,7 @@
 		    (asi < ASI_P))
 			goto daex;
 		save_and_clear_fpu();
-		if (current->thread.fpsaved[0] & flag)
+		if (current_thread_info()->fpsaved[0] & flag)
 			value = *(u64 *)&f->regs[freg];
 		switch (asi) {
 		case ASI_P:
diff --git a/arch/sparc64/kernel/winfixup.S b/arch/sparc64/kernel/winfixup.S
index d733de2..9b9ad32 100644
--- a/arch/sparc64/kernel/winfixup.S
+++ b/arch/sparc64/kernel/winfixup.S
@@ -1,4 +1,4 @@
-/* $Id: winfixup.S,v 1.29 2000/03/26 09:13:48 davem Exp $
+/* $Id: winfixup.S,v 1.30 2002/02/09 19:49:30 davem Exp $
  *
  * winfixup.S: Handle cases where user stack pointer is found to be bogus.
  *
@@ -11,7 +11,7 @@
 #include <asm/ptrace.h>
 #include <asm/processor.h>
 #include <asm/spitfire.h>
-#include <asm/asm_offsets.h>
+#include <asm/thread_info.h>
 
 	.text
 	.align	32
@@ -69,8 +69,8 @@
 	mov		%g6, %o7			! Get current.
 
 	andn		%l1, PSTATE_MM, %l1		! We want to be in RMO
-	stb		%g4, [%g6 + AOFF_task_thread + AOFF_thread_fault_code]
-	stx		%g5, [%g6 + AOFF_task_thread + AOFF_thread_fault_address]
+	stb		%g4, [%g6 + TI_FAULT_CODE]
+	stx		%g5, [%g6 + TI_FAULT_ADDR]
 	wrpr		%g0, 0x0, %tl			! Out of trap levels.
 	wrpr		%l1, (PSTATE_IE | PSTATE_AG | PSTATE_RMO), %pstate
 	sethi		%uhi(PAGE_OFFSET), %g4		! Prepare page_offset global reg
@@ -94,56 +94,56 @@
 	 * do not touch %g7 or %g2 so we handle the two cases fine.
 	 */
 spill_fixup:
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_flags], %g1
-	andcc		%g1, SPARC_FLAG_32BIT, %g0
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_w_saved], %g1
+	ldx		[%g6 + TI_FLAGS], %g1
+	andcc		%g1, _TIF_32BIT, %g0
+	ldub		[%g6 + TI_WSAVED], %g1
 
 	sll		%g1, 3, %g3
 	add		%g6, %g3, %g3
-	stx		%sp, [%g3 + AOFF_task_thread + AOFF_thread_rwbuf_stkptrs]
+	stx		%sp, [%g3 + TI_RWIN_SPTRS]
 	sll		%g1, 7, %g3
 	bne,pt		%xcc, 1f
 	 add		%g6, %g3, %g3
-	stx		%l0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x00]
-	stx		%l1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x08]
+	stx		%l0, [%g3 + TI_REG_WINDOW + 0x00]
+	stx		%l1, [%g3 + TI_REG_WINDOW + 0x08]
 
-	stx		%l2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x10]
-	stx		%l3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x18]
-	stx		%l4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x20]
-	stx		%l5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x28]
-	stx		%l6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x30]
-	stx		%l7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x38]
-	stx		%i0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x40]
-	stx		%i1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x48]
+	stx		%l2, [%g3 + TI_REG_WINDOW + 0x10]
+	stx		%l3, [%g3 + TI_REG_WINDOW + 0x18]
+	stx		%l4, [%g3 + TI_REG_WINDOW + 0x20]
+	stx		%l5, [%g3 + TI_REG_WINDOW + 0x28]
+	stx		%l6, [%g3 + TI_REG_WINDOW + 0x30]
+	stx		%l7, [%g3 + TI_REG_WINDOW + 0x38]
+	stx		%i0, [%g3 + TI_REG_WINDOW + 0x40]
+	stx		%i1, [%g3 + TI_REG_WINDOW + 0x48]
 
-	stx		%i2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x50]
-	stx		%i3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x58]
-	stx		%i4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x60]
-	stx		%i5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x68]
-	stx		%i6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x70]
+	stx		%i2, [%g3 + TI_REG_WINDOW + 0x50]
+	stx		%i3, [%g3 + TI_REG_WINDOW + 0x58]
+	stx		%i4, [%g3 + TI_REG_WINDOW + 0x60]
+	stx		%i5, [%g3 + TI_REG_WINDOW + 0x68]
+	stx		%i6, [%g3 + TI_REG_WINDOW + 0x70]
 	b,pt		%xcc, 2f
-	 stx		%i7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x78]
-1:	stw		%l0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x00]
+	 stx		%i7, [%g3 + TI_REG_WINDOW + 0x78]
+1:	stw		%l0, [%g3 + TI_REG_WINDOW + 0x00]
 
-	stw		%l1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x04]
-	stw		%l2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x08]
-	stw		%l3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x0c]
-	stw		%l4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x10]
-	stw		%l5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x14]
-	stw		%l6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x18]
-	stw		%l7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x1c]
-	stw		%i0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x20]
+	stw		%l1, [%g3 + TI_REG_WINDOW + 0x04]
+	stw		%l2, [%g3 + TI_REG_WINDOW + 0x08]
+	stw		%l3, [%g3 + TI_REG_WINDOW + 0x0c]
+	stw		%l4, [%g3 + TI_REG_WINDOW + 0x10]
+	stw		%l5, [%g3 + TI_REG_WINDOW + 0x14]
+	stw		%l6, [%g3 + TI_REG_WINDOW + 0x18]
+	stw		%l7, [%g3 + TI_REG_WINDOW + 0x1c]
+	stw		%i0, [%g3 + TI_REG_WINDOW + 0x20]
 
-	stw		%i1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x24]
-	stw		%i2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x28]
-	stw		%i3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x2c]
-	stw		%i4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x30]
-	stw		%i5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x34]
-	stw		%i6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x38]
-	stw		%i7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x3c]
+	stw		%i1, [%g3 + TI_REG_WINDOW + 0x24]
+	stw		%i2, [%g3 + TI_REG_WINDOW + 0x28]
+	stw		%i3, [%g3 + TI_REG_WINDOW + 0x2c]
+	stw		%i4, [%g3 + TI_REG_WINDOW + 0x30]
+	stw		%i5, [%g3 + TI_REG_WINDOW + 0x34]
+	stw		%i6, [%g3 + TI_REG_WINDOW + 0x38]
+	stw		%i7, [%g3 + TI_REG_WINDOW + 0x3c]
 2:	add		%g1, 1, %g1
 
-	stb		%g1, [%g6 + AOFF_task_thread + AOFF_thread_w_saved]
+	stb		%g1, [%g6 + TI_WSAVED]
 	rdpr		%tstate, %g1
 	andcc		%g1, TSTATE_PRIV, %g0
 	saved
@@ -153,8 +153,8 @@
 	retry
 
 window_scheisse_from_user_common:
-	stb		%g4, [%g6 + AOFF_task_thread + AOFF_thread_fault_code]
-	stx		%g5, [%g6 + AOFF_task_thread + AOFF_thread_fault_address]
+	stb		%g4, [%g6 + TI_FAULT_CODE]
+	stx		%g5, [%g6 + TI_FAULT_ADDR]
 	wrpr		%g1, %cwp
 	ba,pt		%xcc, etrap
 	 rd		%pc, %g7
@@ -204,47 +204,47 @@
 	b,pt		%xcc, rtrap
 	 nop						! yes, the nop is correct
 spill_fixup_mna:
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_flags], %g1
-	andcc		%g1, SPARC_FLAG_32BIT, %g0
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_w_saved], %g1
+	ldx		[%g6 + TI_FLAGS], %g1
+	andcc		%g1, _TIF_32BIT, %g0
+	ldub		[%g6 + TI_WSAVED], %g1
 	sll		%g1, 3, %g3
 	add		%g6, %g3, %g3
-	stx		%sp, [%g3 + AOFF_task_thread + AOFF_thread_rwbuf_stkptrs]
+	stx		%sp, [%g3 + TI_RWIN_SPTRS]
 
 	sll		%g1, 7, %g3
 	bne,pt		%xcc, 1f
 	 add		%g6, %g3, %g3
-	stx		%l0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x00]
-	stx		%l1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x08]
-	stx		%l2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x10]
-	stx		%l3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x18]
-	stx		%l4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x20]
+	stx		%l0, [%g3 + TI_REG_WINDOW + 0x00]
+	stx		%l1, [%g3 + TI_REG_WINDOW + 0x08]
+	stx		%l2, [%g3 + TI_REG_WINDOW + 0x10]
+	stx		%l3, [%g3 + TI_REG_WINDOW + 0x18]
+	stx		%l4, [%g3 + TI_REG_WINDOW + 0x20]
 
-	stx		%l5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x28]
-	stx		%l6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x30]
-	stx		%l7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x38]
-	stx		%i0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x40]
-	stx		%i1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x48]
-	stx		%i2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x50]
-	stx		%i3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x58]
-	stx		%i4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x60]
+	stx		%l5, [%g3 + TI_REG_WINDOW + 0x28]
+	stx		%l6, [%g3 + TI_REG_WINDOW + 0x30]
+	stx		%l7, [%g3 + TI_REG_WINDOW + 0x38]
+	stx		%i0, [%g3 + TI_REG_WINDOW + 0x40]
+	stx		%i1, [%g3 + TI_REG_WINDOW + 0x48]
+	stx		%i2, [%g3 + TI_REG_WINDOW + 0x50]
+	stx		%i3, [%g3 + TI_REG_WINDOW + 0x58]
+	stx		%i4, [%g3 + TI_REG_WINDOW + 0x60]
 
-	stx		%i5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x68]
-	stx		%i6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x70]
-	stx		%i7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x78]
+	stx		%i5, [%g3 + TI_REG_WINDOW + 0x68]
+	stx		%i6, [%g3 + TI_REG_WINDOW + 0x70]
+	stx		%i7, [%g3 + TI_REG_WINDOW + 0x78]
 	b,pt		%xcc, 2f
 	 add		%g1, 1, %g1
-1:	std		%l0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x00]
-	std		%l2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x08]
-	std		%l4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x10]
+1:	std		%l0, [%g3 + TI_REG_WINDOW + 0x00]
+	std		%l2, [%g3 + TI_REG_WINDOW + 0x08]
+	std		%l4, [%g3 + TI_REG_WINDOW + 0x10]
 
-	std		%l6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x18]
-	std		%i0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x20]
-	std		%i2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x28]
-	std		%i4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x30]
-	std		%i6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x38]
+	std		%l6, [%g3 + TI_REG_WINDOW + 0x18]
+	std		%i0, [%g3 + TI_REG_WINDOW + 0x20]
+	std		%i2, [%g3 + TI_REG_WINDOW + 0x28]
+	std		%i4, [%g3 + TI_REG_WINDOW + 0x30]
+	std		%i6, [%g3 + TI_REG_WINDOW + 0x38]
 	add		%g1, 1, %g1
-2:	stb		%g1, [%g6 + AOFF_task_thread + AOFF_thread_w_saved]
+2:	stb		%g1, [%g6 + TI_WSAVED]
 	rdpr		%tstate, %g1
 
 	andcc		%g1, TSTATE_PRIV, %g0
@@ -311,47 +311,47 @@
 	b,pt		%xcc, rtrap
 	 nop						! yes, the nop is correct
 spill_fixup_dax:
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_flags], %g1
-	andcc		%g1, SPARC_FLAG_32BIT, %g0
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_w_saved], %g1
+	ldx		[%g6 + TI_FLAGS], %g1
+	andcc		%g1, _TIF_32BIT, %g0
+	ldub		[%g6 + TI_WSAVED], %g1
 	sll		%g1, 3, %g3
 	add		%g6, %g3, %g3
-	stx		%sp, [%g3 + AOFF_task_thread + AOFF_thread_rwbuf_stkptrs]
+	stx		%sp, [%g3 + TI_RWIN_SPTRS]
 
 	sll		%g1, 7, %g3
 	bne,pt		%xcc, 1f
 	 add		%g6, %g3, %g3
-	stx		%l0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x00]
-	stx		%l1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x08]
-	stx		%l2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x10]
-	stx		%l3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x18]
-	stx		%l4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x20]
+	stx		%l0, [%g3 + TI_REG_WINDOW + 0x00]
+	stx		%l1, [%g3 + TI_REG_WINDOW + 0x08]
+	stx		%l2, [%g3 + TI_REG_WINDOW + 0x10]
+	stx		%l3, [%g3 + TI_REG_WINDOW + 0x18]
+	stx		%l4, [%g3 + TI_REG_WINDOW + 0x20]
 
-	stx		%l5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x28]
-	stx		%l6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x30]
-	stx		%l7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x38]
-	stx		%i0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x40]
-	stx		%i1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x48]
-	stx		%i2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x50]
-	stx		%i3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x58]
-	stx		%i4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x60]
+	stx		%l5, [%g3 + TI_REG_WINDOW + 0x28]
+	stx		%l6, [%g3 + TI_REG_WINDOW + 0x30]
+	stx		%l7, [%g3 + TI_REG_WINDOW + 0x38]
+	stx		%i0, [%g3 + TI_REG_WINDOW + 0x40]
+	stx		%i1, [%g3 + TI_REG_WINDOW + 0x48]
+	stx		%i2, [%g3 + TI_REG_WINDOW + 0x50]
+	stx		%i3, [%g3 + TI_REG_WINDOW + 0x58]
+	stx		%i4, [%g3 + TI_REG_WINDOW + 0x60]
 
-	stx		%i5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x68]
-	stx		%i6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x70]
-	stx		%i7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x78]
+	stx		%i5, [%g3 + TI_REG_WINDOW + 0x68]
+	stx		%i6, [%g3 + TI_REG_WINDOW + 0x70]
+	stx		%i7, [%g3 + TI_REG_WINDOW + 0x78]
 	b,pt		%xcc, 2f
 	 add		%g1, 1, %g1
-1:	std		%l0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x00]
-	std		%l2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x08]
-	std		%l4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x10]
+1:	std		%l0, [%g3 + TI_REG_WINDOW + 0x00]
+	std		%l2, [%g3 + TI_REG_WINDOW + 0x08]
+	std		%l4, [%g3 + TI_REG_WINDOW + 0x10]
 
-	std		%l6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x18]
-	std		%i0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x20]
-	std		%i2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x28]
-	std		%i4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x30]
-	std		%i6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x38]
+	std		%l6, [%g3 + TI_REG_WINDOW + 0x18]
+	std		%i0, [%g3 + TI_REG_WINDOW + 0x20]
+	std		%i2, [%g3 + TI_REG_WINDOW + 0x28]
+	std		%i4, [%g3 + TI_REG_WINDOW + 0x30]
+	std		%i6, [%g3 + TI_REG_WINDOW + 0x38]
 	add		%g1, 1, %g1
-2:	stb		%g1, [%g6 + AOFF_task_thread + AOFF_thread_w_saved]
+2:	stb		%g1, [%g6 + TI_WSAVED]
 	rdpr		%tstate, %g1
 
 	andcc		%g1, TSTATE_PRIV, %g0
diff --git a/arch/sparc64/lib/VIScopy.S b/arch/sparc64/lib/VIScopy.S
index 17f9d71..7ee0bda 100644
--- a/arch/sparc64/lib/VIScopy.S
+++ b/arch/sparc64/lib/VIScopy.S
@@ -1,4 +1,4 @@
-/* $Id: VIScopy.S,v 1.26 2001/09/27 04:36:24 kanoj Exp $
+/* $Id: VIScopy.S,v 1.27 2002/02/09 19:49:30 davem Exp $
  * VIScopy.S: High speed copy operations utilizing the UltraSparc
  *            Visual Instruction Set.
  *
@@ -26,24 +26,24 @@
 #ifdef __KERNEL__
 
 #include <asm/visasm.h>
-#include <asm/asm_offsets.h>
+#include <asm/thread_info.h>
 
-#define FPU_CLEAN_RETL								\
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_current_ds], %o1;	\
-	VISExit									\
-	clr		%o0;							\
-	retl;									\
+#define FPU_CLEAN_RETL					\
+	ldub		[%g6 + TI_CURRENT_DS], %o1;	\
+	VISExit						\
+	clr		%o0;				\
+	retl;						\
 	 wr		%o1, %g0, %asi;
-#define FPU_RETL								\
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_current_ds], %o1;	\
-	VISExit									\
-	clr		%o0;							\
-	retl;									\
+#define FPU_RETL					\
+	ldub		[%g6 + TI_CURRENT_DS], %o1;	\
+	VISExit						\
+	clr		%o0;				\
+	retl;						\
 	 wr		%o1, %g0, %asi;
-#define NORMAL_RETL								\
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_current_ds], %o1;	\
-	clr		%o0;							\
-	retl;									\
+#define NORMAL_RETL					\
+	ldub		[%g6 + TI_CURRENT_DS], %o1;	\
+	clr		%o0;				\
+	retl;						\
 	 wr		%o1, %g0, %asi;
 #define EX(x,y,a,b) 				\
 98: 	x,y;					\
@@ -1032,7 +1032,7 @@
 		/* If this is copy_from_user(), zero out the rest of the
 		 * kernel buffer.
 		 */
-		ldub		[%g6 + AOFF_task_thread + AOFF_thread_current_ds], %o4
+		ldub		[%g6 + TI_CURRENT_DS], %o4
 		andcc		asi_src, 0x1, %g0
 		be,pt		%icc, 1f
 		 VISExit
diff --git a/arch/sparc64/lib/VIScsum.S b/arch/sparc64/lib/VIScsum.S
index 9f77c8c..d399f97 100644
--- a/arch/sparc64/lib/VIScsum.S
+++ b/arch/sparc64/lib/VIScsum.S
@@ -1,4 +1,4 @@
-/* $Id: VIScsum.S,v 1.6 2000/02/20 23:21:39 davem Exp $
+/* $Id: VIScsum.S,v 1.7 2002/02/09 19:49:30 davem Exp $
  * VIScsum.S: High bandwidth IP checksumming utilizing the UltraSparc
  *            Visual Instruction Set.
  *
@@ -28,7 +28,7 @@
 #include <asm/head.h>
 #include <asm/asi.h>
 #include <asm/visasm.h>
-#include <asm/asm_offsets.h>
+#include <asm/thread_info.h>
 #else
 #define ASI_BLK_P	0xf0
 #define FRPS_FEF	0x04
@@ -342,7 +342,7 @@
 	DO_THE_TRICK(f44,f46,f48,f50,f52,f54,f56,f58,f60,f62,f0,f2,f4,f6,f8,f10,f12,f14)
 	END_THE_TRICK(f60,f62,f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30)
 #ifdef __KERNEL__
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_current_ds], %g7
+	ldub		[%g6 + TI_CURRENT_DS], %g7
 #endif
 	and		%o1, 0x3f, %o1		/*  IEU0	Group		*/
 #ifdef __KERNEL__
diff --git a/arch/sparc64/lib/VISsave.S b/arch/sparc64/lib/VISsave.S
index d1b2571..65e328d 100644
--- a/arch/sparc64/lib/VISsave.S
+++ b/arch/sparc64/lib/VISsave.S
@@ -1,4 +1,4 @@
-/* $Id: VISsave.S,v 1.5 2001/03/08 22:08:51 davem Exp $
+/* $Id: VISsave.S,v 1.6 2002/02/09 19:49:30 davem Exp $
  * VISsave.S: Code for saving FPU register state for
  *            VIS routines. One should not call this directly,
  *            but use macros provided in <asm/visasm.h>.
@@ -10,6 +10,7 @@
 #include <asm/page.h>
 #include <asm/ptrace.h>
 #include <asm/visasm.h>
+#include <asm/thread_info.h>
 
 	.text
 	.globl		VISenter, VISenterhalf
@@ -17,47 +18,51 @@
 	/* On entry: %o5=current FPRS value, %g7 is callers address */
 	/* May clobber %o5, %g1, %g2, %g3, %g7, %icc, %xcc */
 
+	/* Nothing special need be done here to handle pre-emption, this
+	 * FPU save/restore mechanism is already preemption safe.
+	 */
+
 	.align		32
 VISenter:
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %g1
+	ldub		[%g6 + TI_FPDEPTH], %g1
 	brnz,a,pn	%g1, 1f
 	 cmp		%g1, 1
-	stb		%g0, [%g6 + AOFF_task_thread + AOFF_thread_fpsaved]
-	stx		%fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr]
+	stb		%g0, [%g6 + TI_FPSAVED]
+	stx		%fsr, [%g6 + TI_XFSR]
 9:	jmpl		%g7 + %g0, %g0
 	 nop
 1:	bne,pn		%icc, 2f
 
 	 srl		%g1, 1, %g1
-vis1:	ldub		[%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g3
-	stx		%fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr]
+vis1:	ldub		[%g6 + TI_FPSAVED], %g3
+	stx		%fsr, [%g6 + TI_XFSR]
 	or		%g3, %o5, %g3
-	stb		%g3, [%g6 + AOFF_task_thread + AOFF_thread_fpsaved]
+	stb		%g3, [%g6 + TI_FPSAVED]
 	rd		%gsr, %g3
 	clr		%g1
 	ba,pt		%xcc, 3f
 
-	 stx		%g3, [%g6 + AOFF_task_thread + AOFF_thread_gsr]
+	 stx		%g3, [%g6 + TI_GSR]
 2:	add		%g6, %g1, %g3
 	cmp		%o5, FPRS_DU
 	be,pn		%icc, 6f
 	 sll		%g1, 3, %g1
-	stb		%o5, [%g3 + AOFF_task_thread + AOFF_thread_fpsaved]
+	stb		%o5, [%g3 + TI_FPSAVED]
 	rd		%gsr, %g2
 	add		%g6, %g1, %g3
-	stx		%g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr]
+	stx		%g2, [%g3 + TI_GSR]
 
 	add		%g6, %g1, %g2
-	stx		%fsr, [%g2 + AOFF_task_thread + AOFF_thread_xfsr]
+	stx		%fsr, [%g2 + TI_XFSR]
 	sll		%g1, 5, %g1
 3:	andcc		%o5, FPRS_DL|FPRS_DU, %g0
 	be,pn		%icc, 9b
-	 add		%g6, AOFF_task_fpregs, %g2
+	 add		%g6, TI_FPREGS, %g2
 	andcc		%o5, FPRS_DL, %g0
 	membar		#StoreStore | #LoadStore
 
 	be,pn		%icc, 4f
-	 add		%g6, AOFF_task_fpregs+0x40, %g3
+	 add		%g6, TI_FPREGS+0x40, %g3
 	stda		%f0, [%g2 + %g1] ASI_BLK_P
 	stda		%f16, [%g3 + %g1] ASI_BLK_P
 	andcc		%o5, FPRS_DU, %g0
@@ -70,13 +75,13 @@
 	jmpl		%g7 + %g0, %g0
 	 nop
 
-6:	ldub		[%g3 + AOFF_task_thread + AOFF_thread_fpsaved], %o5
+6:	ldub		[%g3 + TI_FPSAVED], %o5
 	or		%o5, FPRS_DU, %o5
-	add		%g6, AOFF_task_fpregs+0x80, %g2
-	stb		%o5, [%g3 + AOFF_task_thread + AOFF_thread_fpsaved]
+	add		%g6, TI_FPREGS+0x80, %g2
+	stb		%o5, [%g3 + TI_FPSAVED]
 
 	sll		%g1, 5, %g1
-	add		%g6, AOFF_task_fpregs+0xc0, %g3
+	add		%g6, TI_FPREGS+0xc0, %g3
 	wr		%g0, FPRS_FEF, %fprs
 	membar		#StoreStore | #LoadStore
 	stda		%f32, [%g2 + %g1] ASI_BLK_P
@@ -88,11 +93,11 @@
 
 	.align		32
 VISenterhalf:
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %g1
+	ldub		[%g6 + TI_FPDEPTH], %g1
 	brnz,a,pn	%g1, 1f
 	 cmp		%g1, 1
-	stb		%g0, [%g6 + AOFF_task_thread + AOFF_thread_fpsaved]
-	stx		%fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr]
+	stb		%g0, [%g6 + TI_FPSAVED]
+	stx		%fsr, [%g6 + TI_XFSR]
 	clr		%o5
 	jmpl		%g7 + %g0, %g0
 	 wr		%g0, FPRS_FEF, %fprs
@@ -104,20 +109,20 @@
 2:	addcc		%g6, %g1, %g3
 	sll		%g1, 3, %g1
 	andn		%o5, FPRS_DU, %g2
-	stb		%g2, [%g3 + AOFF_task_thread + AOFF_thread_fpsaved]
+	stb		%g2, [%g3 + TI_FPSAVED]
 
 	rd		%gsr, %g2
 	add		%g6, %g1, %g3
-	stx		%g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr]
+	stx		%g2, [%g3 + TI_GSR]
 	add		%g6, %g1, %g2
-	stx		%fsr, [%g2 + AOFF_task_thread + AOFF_thread_xfsr]
+	stx		%fsr, [%g2 + TI_XFSR]
 	sll		%g1, 5, %g1
 3:	andcc		%o5, FPRS_DL, %g0
 	be,pn		%icc, 4f
-	 add		%g6, AOFF_task_fpregs, %g2
+	 add		%g6, TI_FPREGS, %g2
 
 	membar		#StoreStore | #LoadStore
-	add		%g6, AOFF_task_fpregs+0x40, %g3
+	add		%g6, TI_FPREGS+0x40, %g3
 	stda		%f0, [%g2 + %g1] ASI_BLK_P
 	stda		%f16, [%g3 + %g1] ASI_BLK_P
 	membar		#Sync
diff --git a/arch/sparc64/lib/blockops.S b/arch/sparc64/lib/blockops.S
index 7042ae2..ad5d9bb 100644
--- a/arch/sparc64/lib/blockops.S
+++ b/arch/sparc64/lib/blockops.S
@@ -1,4 +1,4 @@
-/* $Id: blockops.S,v 1.41 2001/12/05 06:05:35 davem Exp $
+/* $Id: blockops.S,v 1.42 2002/02/09 19:49:30 davem Exp $
  * blockops.S: UltraSparc block zero optimized routines.
  *
  * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com)
@@ -7,9 +7,9 @@
 
 #include "VIS.h"
 #include <asm/visasm.h>
+#include <asm/thread_info.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <asm/asm_offsets.h>
 
 #define TOUCH(reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7)	\
 	fmovd	%reg0, %f48; 	fmovd	%reg1, %f50;		\
@@ -61,7 +61,7 @@
 	 * so we do not risk a multiple TLB match condition later when
 	 * restoring those entries.
 	 */
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_use_blkcommit], %g3
+	ldx		[%g6 + TI_FLAGS], %g3
 
 	/* Spitfire Errata #32 workaround */
 	mov		0x8, %o4
@@ -100,7 +100,7 @@
 	stxa		%g2, [%o3] ASI_DTLB_DATA_ACCESS
 	membar		#Sync
 
-	cmp		%g3, 0
+	andcc		%g3, _TIF_BLKCOMMIT, %g0
 	bne,pn		%xcc, copy_page_using_blkcommit
 	 nop
 
diff --git a/arch/sparc64/lib/checksum.S b/arch/sparc64/lib/checksum.S
index 4e962ed..f87faa5 100644
--- a/arch/sparc64/lib/checksum.S
+++ b/arch/sparc64/lib/checksum.S
@@ -18,7 +18,7 @@
 #include <asm/ptrace.h>
 #include <asm/asi.h>
 #include <asm/page.h>
-#include <asm/asm_offsets.h>
+#include <asm/thread_info.h>
 
 	/* The problem with the "add with carry" instructions on Ultra
 	 * are two fold.  Firstly, they cannot pair with jack shit,
@@ -498,7 +498,7 @@
 	.globl	cpc_handler
 cpc_handler:
 	ldx	[%sp + 0x7ff + 128], %g1
-	ldub	[%g6 + AOFF_task_thread + AOFF_thread_current_ds], %g3
+	ldub	[%g6 + TI_CURRENT_DS], %g3
 	sub	%g0, EFAULT, %g2
 	brnz,a,pt %g1, 1f
 	 st	%g2, [%g1]
diff --git a/arch/sparc64/lib/dec_and_lock.S b/arch/sparc64/lib/dec_and_lock.S
index b7c2631..575f25e 100644
--- a/arch/sparc64/lib/dec_and_lock.S
+++ b/arch/sparc64/lib/dec_and_lock.S
@@ -5,6 +5,7 @@
  * Copyright (C) 2000 David S. Miller (davem@redhat.com)
  */
 #include <linux/config.h>
+#include <asm/thread_info.h>
 
 #ifndef CONFIG_DEBUG_SPINLOCK
 	.text
@@ -40,6 +41,11 @@
 	membar	#StoreLoad | #StoreStore
 	retl
 	 mov	%g1, %o0
+#ifdef CONFIG_PREEMPT
+	ldsw	[%g6 + TI_PRE_COUNT], %g3
+	add	%g3, 1, %g3
+	stw	%g3, [%g6 + TI_PRE_COUNT]
+#endif
 to_zero:
 	ldstub	[%o1], %g3
 	brnz,pn	%g3, spin_on_lock
@@ -55,6 +61,11 @@
 	 nop
 	membar	#StoreStore | #LoadStore
 	stb	%g0, [%o1]
+#ifdef CONFIG_PREEMPT
+	ldsw	[%g6 + TI_PRE_COUNT], %g3
+	sub	%g3, 1, %g3
+	stw	%g3, [%g6 + TI_PRE_COUNT]
+#endif
 
 	b,pt	%xcc, nzero
 	 nop
diff --git a/arch/sparc64/math-emu/math.c b/arch/sparc64/math-emu/math.c
index 2a05c0d..ace4866 100644
--- a/arch/sparc64/math-emu/math.c
+++ b/arch/sparc64/math-emu/math.c
@@ -1,4 +1,4 @@
-/* $Id: math.c,v 1.11 1999/12/20 05:02:25 davem Exp $
+/* $Id: math.c,v 1.12 2002/02/09 19:49:31 davem Exp $
  * arch/sparc64/math-emu/math.c
  *
  * Copyright (C) 1997,1999 Jakub Jelinek (jj@ultra.linux.cz)
@@ -90,25 +90,25 @@
  */
 static inline int record_exception(struct pt_regs *regs, int eflag)
 {
-	u64 fsr = current->thread.xfsr[0];
+	u64 fsr = current_thread_info()->xfsr[0];
 	int would_trap;
 
 	/* Determine if this exception would have generated a trap. */
 	would_trap = (fsr & ((long)eflag << FSR_TEM_SHIFT)) != 0UL;
 
 	/* If trapping, we only want to signal one bit. */
-	if(would_trap != 0) {
+	if (would_trap != 0) {
 		eflag &= ((fsr & FSR_TEM_MASK) >> FSR_TEM_SHIFT);
-		if((eflag & (eflag - 1)) != 0) {
-			if(eflag & FP_EX_INVALID)
+		if ((eflag & (eflag - 1)) != 0) {
+			if (eflag & FP_EX_INVALID)
 				eflag = FP_EX_INVALID;
-			else if(eflag & FP_EX_OVERFLOW)
+			else if (eflag & FP_EX_OVERFLOW)
 				eflag = FP_EX_OVERFLOW;
-			else if(eflag & FP_EX_UNDERFLOW)
+			else if (eflag & FP_EX_UNDERFLOW)
 				eflag = FP_EX_UNDERFLOW;
-			else if(eflag & FP_EX_DIVZERO)
+			else if (eflag & FP_EX_DIVZERO)
 				eflag = FP_EX_DIVZERO;
-			else if(eflag & FP_EX_INEXACT)
+			else if (eflag & FP_EX_INEXACT)
 				eflag = FP_EX_INEXACT;
 		}
 	}
@@ -128,19 +128,19 @@
 	 *    CEXC just generated is OR'd into the
 	 *    existing value of AEXC.
 	 */
-	if(would_trap == 0)
+	if (would_trap == 0)
 		fsr |= ((long)eflag << FSR_AEXC_SHIFT);
 
 	/* If trapping, indicate fault trap type IEEE. */
-	if(would_trap != 0)
+	if (would_trap != 0)
 		fsr |= (1UL << 14);
 
-	current->thread.xfsr[0] = fsr;
+	current_thread_info()->xfsr[0] = fsr;
 
 	/* If we will not trap, advance the program counter over
 	 * the instruction being handled.
 	 */
-	if(would_trap == 0) {
+	if (would_trap == 0) {
 		regs->tpc = regs->tnpc;
 		regs->tnpc += 4;
 	}
@@ -174,10 +174,10 @@
 	int IR;
 	long XR, xfsr;
 
-	if(tstate & TSTATE_PRIV)
+	if (tstate & TSTATE_PRIV)
 		die_if_kernel("FPQuad from kernel", regs);
-	if(current->thread.flags & SPARC_FLAG_32BIT)
-		pc = (u32)pc;
+	if (test_thread_flag(TIF_32BIT))
+		pc &= 0xffffffff;
 	if (get_user(insn, (u32 *)pc) != -EFAULT) {
 		if ((insn & 0xc1f80000) == 0x81a00000) /* FPOP1 */ {
 			switch ((insn >> 5) & 0x1ff) {
@@ -231,9 +231,9 @@
 			case FMOVQ3:
 				/* fmovq %fccX, %fY, %fZ */
 				if (!((insn >> 11) & 3))
-					XR = current->thread.xfsr[0] >> 10;
+					XR = current_thread_info()->xfsr[0] >> 10;
 				else
-					XR = current->thread.xfsr[0] >> (30 + ((insn >> 10) & 0x6));
+					XR = current_thread_info()->xfsr[0] >> (30 + ((insn >> 10) & 0x6));
 				XR &= 3;
 				IR = 0;
 				switch ((insn >> 14) & 0x7) {
@@ -282,7 +282,7 @@
 					XR = 0;
 				else if (freg < 16)
 					XR = regs->u_regs[freg];
-				else if (current->thread.flags & SPARC_FLAG_32BIT) {
+				else if (test_thread_flag(TIF_32BIT)) {
 					struct reg_window32 *win32;
 					flushw_user ();
 					win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
@@ -305,7 +305,7 @@
 			}
 			if (IR == 0) {
 				/* The fmov test was false. Do a nop instead */
-				current->thread.xfsr[0] &= ~(FSR_CEXC_MASK);
+				current_thread_info()->xfsr[0] &= ~(FSR_CEXC_MASK);
 				regs->tpc = regs->tnpc;
 				regs->tnpc += 4;
 				return 1;
@@ -319,20 +319,20 @@
 	if (type) {
 		argp rs1 = NULL, rs2 = NULL, rd = NULL;
 		
-		freg = (current->thread.xfsr[0] >> 14) & 0xf;
+		freg = (current_thread_info()->xfsr[0] >> 14) & 0xf;
 		if (freg != (type >> 9))
 			goto err;
-		current->thread.xfsr[0] &= ~0x1c000;
+		current_thread_info()->xfsr[0] &= ~0x1c000;
 		freg = ((insn >> 14) & 0x1f);
 		switch (type & 0x3) {
 		case 3: if (freg & 2) {
-				current->thread.xfsr[0] |= (6 << 14) /* invalid_fp_register */;
+				current_thread_info()->xfsr[0] |= (6 << 14) /* invalid_fp_register */;
 				goto err;
 			}
 		case 2: freg = ((freg & 1) << 5) | (freg & 0x1e);
 		case 1: rs1 = (argp)&f->regs[freg];
 			flags = (freg < 32) ? FPRS_DL : FPRS_DU; 
-			if (!(current->thread.fpsaved[0] & flags))
+			if (!(current_thread_info()->fpsaved[0] & flags))
 				rs1 = (argp)&zero;
 			break;
 		}
@@ -344,13 +344,13 @@
 		freg = (insn & 0x1f);
 		switch ((type >> 3) & 0x3) {
 		case 3: if (freg & 2) {
-				current->thread.xfsr[0] |= (6 << 14) /* invalid_fp_register */;
+				current_thread_info()->xfsr[0] |= (6 << 14) /* invalid_fp_register */;
 				goto err;
 			}
 		case 2: freg = ((freg & 1) << 5) | (freg & 0x1e);
 		case 1: rs2 = (argp)&f->regs[freg];
 			flags = (freg < 32) ? FPRS_DL : FPRS_DU; 
-			if (!(current->thread.fpsaved[0] & flags))
+			if (!(current_thread_info()->fpsaved[0] & flags))
 				rs2 = (argp)&zero;
 			break;
 		}
@@ -362,23 +362,23 @@
 		freg = ((insn >> 25) & 0x1f);
 		switch ((type >> 6) & 0x3) {
 		case 3: if (freg & 2) {
-				current->thread.xfsr[0] |= (6 << 14) /* invalid_fp_register */;
+				current_thread_info()->xfsr[0] |= (6 << 14) /* invalid_fp_register */;
 				goto err;
 			}
 		case 2: freg = ((freg & 1) << 5) | (freg & 0x1e);
 		case 1: rd = (argp)&f->regs[freg];
 			flags = (freg < 32) ? FPRS_DL : FPRS_DU; 
-			if (!(current->thread.fpsaved[0] & FPRS_FEF)) {
-				current->thread.fpsaved[0] = FPRS_FEF;
-				current->thread.gsr[0] = 0;
+			if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) {
+				current_thread_info()->fpsaved[0] = FPRS_FEF;
+				current_thread_info()->gsr[0] = 0;
 			}
-			if (!(current->thread.fpsaved[0] & flags)) {
+			if (!(current_thread_info()->fpsaved[0] & flags)) {
 				if (freg < 32)
 					memset(f->regs, 0, 32*sizeof(u32));
 				else
 					memset(f->regs+32, 0, 32*sizeof(u32));
 			}
-			current->thread.fpsaved[0] |= flags;
+			current_thread_info()->fpsaved[0] |= flags;
 			break;
 		}
 		switch ((insn >> 5) & 0x1ff) {
@@ -439,7 +439,7 @@
 		}
 		if (!FP_INHIBIT_RESULTS) {
 			switch ((type >> 6) & 0x7) {
-			case 0: xfsr = current->thread.xfsr[0];
+			case 0: xfsr = current_thread_info()->xfsr[0];
 				if (XR == -1) XR = 2;
 				switch (freg & 3) {
 				/* fcc0, 1, 2, 3 */
@@ -448,7 +448,7 @@
 				case 2: xfsr &= ~0xc00000000UL; xfsr |= (XR << 34); break;
 				case 3: xfsr &= ~0x3000000000UL; xfsr |= (XR << 36); break;
 				}
-				current->thread.xfsr[0] = xfsr;
+				current_thread_info()->xfsr[0] = xfsr;
 				break;
 			case 1: rd->s = IR; break;
 			case 2: rd->d = XR; break;
@@ -458,11 +458,11 @@
 			}
 		}
 
-		if(_fex != 0)
+		if (_fex != 0)
 			return record_exception(regs, _fex);
 
 		/* Success and no exceptions detected. */
-		current->thread.xfsr[0] &= ~(FSR_CEXC_MASK);
+		current_thread_info()->xfsr[0] &= ~(FSR_CEXC_MASK);
 		regs->tpc = regs->tnpc;
 		regs->tnpc += 4;
 		return 1;
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 78b9fab..7969278 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.58 2001/09/01 00:11:16 kanoj Exp $
+/* $Id: fault.c,v 1.59 2002/02/09 19:49:31 davem Exp $
  * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -287,8 +287,8 @@
 	unsigned long address;
 
 	si_code = SEGV_MAPERR;
-	fault_code = current->thread.fault_code;
-	address = current->thread.fault_address;
+	fault_code = get_thread_fault_code();
+	address = current_thread_info()->fault_address;
 
 	if ((fault_code & FAULT_CODE_ITLB) &&
 	    (fault_code & FAULT_CODE_DTLB))
@@ -301,7 +301,7 @@
 	if (in_interrupt() || !mm)
 		goto intr_or_no_mm;
 
-	if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
 		address &= 0xffffffff;
 	}
@@ -358,7 +358,7 @@
 		if (tlb_type == spitfire &&
 		    (vma->vm_flags & VM_EXEC) != 0 &&
 		    vma->vm_file != NULL)
-			current->thread.use_blkcommit = 1;
+			set_thread_flag(TIF_BLKCOMMIT);
 	} else {
 		/* Allow reads even for write-only mappings */
 		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
@@ -426,7 +426,7 @@
 
 fault_done:
 	/* These values are no longer needed, clear them. */
-	current->thread.fault_code = 0;
-	current->thread.use_blkcommit = 0;
-	current->thread.fault_address = 0;
+	set_thread_fault_code(0);
+	clear_thread_flag(TIF_BLKCOMMIT);
+	current_thread_info()->fault_address = 0;
 }
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index d088a7f..4671ca6 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.208 2001/12/21 04:56:15 davem Exp $
+/*  $Id: init.c,v 1.209 2002/02/09 19:49:31 davem Exp $
  *  arch/sparc64/mm/init.c
  *
  *  Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -111,8 +111,6 @@
         return freed;
 }
 
-extern void __update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
-
 #ifdef CONFIG_DEBUG_DCFLUSH
 atomic_t dcpage_flushes = ATOMIC_INIT(0);
 #ifdef CONFIG_SMP
@@ -181,6 +179,8 @@
 			     : "g5", "g7");
 }
 
+extern void __update_mmu_cache(unsigned long mmu_context_hw, unsigned long address, pte_t pte, int code);
+
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
 	struct page *page = pte_page(pte);
@@ -201,7 +201,9 @@
 
 		clear_dcache_dirty_cpu(page, cpu);
 	}
-	__update_mmu_cache(vma, address, pte);
+	if (get_thread_fault_code())
+		__update_mmu_cache(vma->vm_mm->context & TAG_CONTEXT_BITS,
+				   address, pte, get_thread_fault_code());
 }
 
 void flush_dcache_page(struct page *page)
@@ -706,7 +708,7 @@
 	int i;
 
 	if (!enter)
-		set_fs(current->thread.current_ds);
+		set_fs((mm_segment_t) { get_thread_current_ds() });
 
 	if (!prom_ditlb_set)
 		return;
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S
index 0fdf597..514326d 100644
--- a/arch/sparc64/mm/ultra.S
+++ b/arch/sparc64/mm/ultra.S
@@ -1,4 +1,4 @@
-/* $Id: ultra.S,v 1.71 2002/01/23 11:27:36 davem Exp $
+/* $Id: ultra.S,v 1.72 2002/02/09 19:49:31 davem Exp $
  * ultra.S: Don't expand these all over the place...
  *
  * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com)
@@ -391,8 +391,8 @@
 	rdpr		%pstate, %g7
 	wrpr		%g7, PSTATE_IE, %pstate
 	mov		TLB_TAG_ACCESS, %g1
-	stxa		%o0, [%g1] ASI_DMMU
-	stxa		%o1, [%g0] ASI_DTLB_DATA_IN
+	stxa		%o5, [%g1] ASI_DMMU
+	stxa		%o2, [%g0] ASI_DTLB_DATA_IN
 	flush		%g6
 	retl
 	 wrpr		%g7, %pstate
@@ -400,28 +400,20 @@
 	rdpr		%pstate, %g7
 	wrpr		%g7, PSTATE_IE, %pstate
 	mov		TLB_TAG_ACCESS, %g1
-	stxa		%o0, [%g1] ASI_IMMU
-	stxa		%o1, [%g0] ASI_ITLB_DATA_IN
+	stxa		%o5, [%g1] ASI_IMMU
+	stxa		%o2, [%g0] ASI_ITLB_DATA_IN
 	flush		%g6
 	retl
 	 wrpr		%g7, %pstate
 
 	.globl		__update_mmu_cache
-__update_mmu_cache:	/* %o0=vma, %o1=address, %o2=pte */
-	ldub		[%g6 + AOFF_task_thread + AOFF_thread_fault_code], %o3
+__update_mmu_cache:	/* %o0=hw_context, %o1=address, %o2=pte, %o3=fault_code */
 	srlx		%o1, PAGE_SHIFT, %o1
-	ldx		[%o0 + 0x0], %o4		/* XXX vma->vm_mm */
-	brz,pn		%o3, 1f
-	 sllx		%o1, PAGE_SHIFT, %o0
-	ldx		[%o4 + AOFF_mm_context], %o5
 	andcc		%o3, FAULT_CODE_DTLB, %g0
-	mov		%o2, %o1
-	and		%o5, TAG_CONTEXT_BITS, %o5
+	sllx		%o1, PAGE_SHIFT, %o5
 	bne,pt		%xcc, __prefill_dtlb
-	 or		%o0, %o5, %o0
+	 or		%o5, %o0, %o5
 	ba,a,pt		%xcc, __prefill_itlb
-1:	retl
-	 nop
 
 #ifdef CONFIG_SMP
 	/* These are all called by the slaves of a cross call, at
@@ -501,8 +493,8 @@
 109:	 or		%g7, %lo(109b), %g7
 	call		__show_regs
 	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
-	b,pt		%xcc, rtrap
-	 clr		%l6
+	b,pt		%xcc, rtrap_irq
+	 nop
 
 	.align		32
 	.globl		xcall_flush_dcache_page_cheetah
@@ -562,8 +554,8 @@
 109:	 or		%g7, %lo(109b), %g7
 	call		smp_penguin_jailcell
 	 nop
-	b,pt		%xcc, rtrap
-	 clr		%l6
+	b,pt		%xcc, rtrap_irq
+	 nop
 
 	.globl		xcall_promstop
 xcall_promstop:
@@ -689,8 +681,8 @@
 109:	 or		%g7, %lo(109b), %g7
 	call		smp_call_function_client
 	 nop
-	b,pt		%xcc, rtrap
-	 clr		%l6
+	b,pt		%xcc, rtrap_irq
+	 nop
 
 	.globl		xcall_migrate_task
 xcall_migrate_task:
diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S
index eb9cf3d..702dfb0 100644
--- a/arch/sparc64/solaris/entry64.S
+++ b/arch/sparc64/solaris/entry64.S
@@ -1,4 +1,4 @@
-/* $Id: entry64.S,v 1.6 2000/01/12 02:59:26 davem Exp $
+/* $Id: entry64.S,v 1.7 2002/02/09 19:49:31 davem Exp $
  * entry64.S:  Solaris syscall emulation entry point.
  *
  * Copyright (C) 1996,1997,1998 Jakub Jelinek   (jj@sunsite.mff.cuni.cz)
@@ -68,9 +68,11 @@
 
 	/* Solaris system calls enter here... */
 	.align	32
-	.globl	solaris_sparc_syscall
+	.globl	solaris_sparc_syscall, entry64_personality_patch
 solaris_sparc_syscall:
-	ldub		[%g6 + AOFF_task_personality + ASIZ_task_personality - 1], %l0
+	ldx		[%g6 + TI_TASK], %l0
+entry64_personality_patch:
+	ldub		[%l0 + 0x0], %l0
 	cmp		%g1, 255
 	bg,pn		%icc, solaris_unimplemented
 	 srl		%g1, 0, %g1
@@ -83,7 +85,7 @@
 1:	 srl		%i0, 0, %o0
 	lduw		[%l7 + %l4], %l3
 	srl		%i1, 0, %o1
-	ldx		[%g6 + AOFF_task_flags], %l5
+	ldx		[%g6 + TI_FLAGS], %l5
 	cmp		%l3, NR_SYSCALLS
 	bleu,a,pn	%xcc, linux_syscall_for_solaris
 	 sethi		%hi(sys_call_table32), %l6
@@ -93,21 +95,21 @@
 10:	srl		%i2, 0, %o2
 	mov		%i5, %o5
 	andn		%l3, 3, %l7
-	andcc		%l5, 0x20, %g0				
+	andcc		%l5, _TIF_SYSCALL_TRACE, %g0				
 	bne,pn		%icc, solaris_syscall_trace		
 	 mov		%i0, %l5
 2:	call		%l7
 	 srl		%i3, 0, %o3
 ret_from_solaris:
 	stx		%o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0]
-	ldx		[%g6 + AOFF_task_flags], %l6
+	ldx		[%g6 + TI_FLAGS], %l6
 	sra		%o0, 0, %o0
 	mov		%ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
 	ldx		[%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE], %g3
 	cmp		%o0, -ENOIOCTLCMD
 	sllx		%g2, 32, %g2
 	bgeu,pn		%xcc, 1f
-	 andcc		%l6, 0x20, %l6	
+	 andcc		%l6, _TIF_SYSCALL_TRACE, %l6	
 
 	/* System call success, clear Carry condition code. */
 	andn		%g3, %g2, %g3
@@ -175,25 +177,30 @@
 
 	.globl		solaris_getpid
 solaris_getpid:
-	call		sys_getppid	/* This is tricky, so don't do it in assembly */
+	call		sys_getppid
 	 nop
-	stx		%o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1]
+	call		sys_getpid
+	 stx		%o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1]
 	b,pt		%xcc, ret_from_solaris
-	 lduw		[%g6 + AOFF_task_pid], %o0
+	 nop
 
 	.globl	solaris_getuid
 solaris_getuid:
-	lduw		[%g6 + AOFF_task_euid], %o1
-	lduw		[%g6 + AOFF_task_uid], %o0
-	b,pt		%xcc, ret_from_solaris
+	call		sys_geteuid
+	 nop
+	call		sys_getuid
 	 stx		%o1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1]
+	b,pt		%xcc, ret_from_solaris
+	 nop
 
 	.globl	solaris_getgid
 solaris_getgid:
-	lduw		[%g6 + AOFF_task_egid], %o1
-	lduw		[%g6 + AOFF_task_gid], %o0
-	b,pt		%xcc, ret_from_solaris
+	call		sys_getegid
+	 nop
+	call		sys_getgid
 	 stx		%o1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1]
+	b,pt		%xcc, ret_from_solaris
+	 nop
 
 	.globl		solaris_unimplemented
 solaris_unimplemented:
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
index 82f941d..59373b5 100644
--- a/arch/sparc64/solaris/fs.c
+++ b/arch/sparc64/solaris/fs.c
@@ -1,4 +1,4 @@
-/* $Id: fs.c,v 1.26 2002/01/08 16:00:21 davem Exp $
+/* $Id: fs.c,v 1.27 2002/02/08 03:57:14 davem Exp $
  * fs.c: fs related syscall emulation for Solaris
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c
index a920499..0b19196 100644
--- a/arch/sparc64/solaris/ioctl.c
+++ b/arch/sparc64/solaris/ioctl.c
@@ -1,4 +1,4 @@
-/* $Id: ioctl.c,v 1.16 2000/11/18 02:10:59 davem Exp $
+/* $Id: ioctl.c,v 1.17 2002/02/08 03:57:14 davem Exp $
  * ioctl.c: Solaris ioctl emulation.
  *
  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index 3393729..9831464 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.35 2002/01/08 16:00:21 davem Exp $
+/* $Id: misc.c,v 1.36 2002/02/09 19:49:31 davem Exp $
  * misc.c: Miscelaneous syscall emulation for Solaris
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -739,6 +739,8 @@
 extern u32 solaris_syscall[];
 extern void cleanup_socksys(void);
 
+extern u32 entry64_personality_patch;
+
 int init_module(void)
 {
 	int ret;
@@ -750,6 +752,11 @@
 		return ret;
 	}
 	update_ttable(solaris_sparc_syscall);
+	entry64_personality_patch |=
+		(offsetof(struct task_struct, personality) +
+		 (sizeof(unsigned long) - 1));
+	__asm__ __volatile__("membar #StoreStore; flush %0"
+			     : : "r" (&entry64_personality_patch));
 	return 0;
 }
 
diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c
index 6233516..a7b71b2 100644
--- a/arch/sparc64/solaris/socket.c
+++ b/arch/sparc64/solaris/socket.c
@@ -1,4 +1,4 @@
-/* $Id: socket.c,v 1.5 2001/02/13 01:16:44 davem Exp $
+/* $Id: socket.c,v 1.6 2002/02/08 03:57:14 davem Exp $
  * socket.c: Socket syscall emulation for Solaris 2.6+
  *
  * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
index f6d5fab..5a91f34 100644
--- a/arch/sparc64/solaris/socksys.c
+++ b/arch/sparc64/solaris/socksys.c
@@ -1,4 +1,4 @@
-/* $Id: socksys.c,v 1.20 2002/01/08 16:00:21 davem Exp $
+/* $Id: socksys.c,v 1.21 2002/02/08 03:57:14 davem Exp $
  * socksys.c: /dev/inet/ stuff for Solaris emulation.
  *
  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
index 06e9590..59e633f 100644
--- a/arch/sparc64/solaris/timod.c
+++ b/arch/sparc64/solaris/timod.c
@@ -1,4 +1,4 @@
-/* $Id: timod.c,v 1.18 2002/01/08 16:00:21 davem Exp $
+/* $Id: timod.c,v 1.19 2002/02/08 03:57:14 davem Exp $
  * timod.c: timod emulation.
  *
  * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
diff --git a/drivers/sbus/char/sunkbd.c b/drivers/sbus/char/sunkbd.c
index 82ed633..6d150d9 100644
--- a/drivers/sbus/char/sunkbd.c
+++ b/drivers/sbus/char/sunkbd.c
@@ -1338,7 +1338,7 @@
 		spin_unlock_irqrestore(&kbd_queue_lock, flags);
 
 #ifdef CONFIG_SPARC32_COMPAT
-		if (current->thread.flags & SPARC_FLAG_32BIT) {
+		if (test_thread_flag(TIF_32BIT)) {
 			if (copy_to_user((Firm_event *)p, &this_event,
 					 sizeof(Firm_event)-sizeof(struct timeval)))
 				return -EFAULT;
diff --git a/drivers/sbus/char/sunmouse.c b/drivers/sbus/char/sunmouse.c
index 8bb45cb..c006a52 100644
--- a/drivers/sbus/char/sunmouse.c
+++ b/drivers/sbus/char/sunmouse.c
@@ -462,7 +462,7 @@
 			spin_unlock_irqrestore(&sunmouse.lock, flags);
 
 #ifdef CONFIG_SPARC32_COMPAT
-			if (current->thread.flags & SPARC_FLAG_32BIT) {
+			if (test_thread_flag(TIF_32BIT)) {
 				if ((end - p) <
 				    ((sizeof(Firm_event) - sizeof(struct timeval) +
 				      (sizeof(u32) * 2))))
diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c
index 1252d73..ca2700a 100644
--- a/drivers/video/aty/mach64_accel.c
+++ b/drivers/video/aty/mach64_accel.c
@@ -3,6 +3,7 @@
  *  ATI Mach64 Hardware Acceleration
  */
 
+#include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 5c71d5a..c184990 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -16,6 +16,7 @@
 #define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/smp_lock.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index d830237..ec48a38 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -439,9 +439,9 @@
 /*
  * Return saved PC of a blocked thread.
  */
-static inline unsigned long thread_saved_pc(struct thread_struct *t)
+static inline unsigned long thread_saved_pc(struct task_struct *tsk)
 {
-	return ((unsigned long *)t->esp)[3];
+	return ((unsigned long *)tsk->thread->esp)[3];
 }
 
 unsigned long get_wchan(struct task_struct *p);
diff --git a/include/asm-sparc/checksum.h b/include/asm-sparc/checksum.h
index 2f92efb..cfe871c 100644
--- a/include/asm-sparc/checksum.h
+++ b/include/asm-sparc/checksum.h
@@ -1,4 +1,4 @@
-/* $Id: checksum.h,v 1.32 2001/10/30 04:32:24 davem Exp $ */
+/* $Id: checksum.h,v 1.33 2002/02/01 22:01:05 davem Exp $ */
 #ifndef __SPARC_CHECKSUM_H
 #define __SPARC_CHECKSUM_H
 
@@ -16,6 +16,7 @@
  *      RFC1071 Computing the Internet Checksum
  */
  
+#include <linux/in6.h>
 #include <asm/uaccess.h>
 #include <asm/cprefix.h>
 
diff --git a/include/asm-sparc/siginfo.h b/include/asm-sparc/siginfo.h
index 816a08a..629641b 100644
--- a/include/asm-sparc/siginfo.h
+++ b/include/asm-sparc/siginfo.h
@@ -1,4 +1,4 @@
-/* $Id: siginfo.h,v 1.8 2000/05/27 00:49:37 davem Exp $
+/* $Id: siginfo.h,v 1.9 2002/02/08 03:57:18 davem Exp $
  * siginfo.c:
  */
 
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index cbed9be..5fc0f36 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.73 2002/01/31 03:30:13 davem Exp $ */
+/* $Id: unistd.h,v 1.74 2002/02/08 03:57:18 davem Exp $ */
 #ifndef _SPARC_UNISTD_H
 #define _SPARC_UNISTD_H
 
@@ -202,7 +202,7 @@
 #define __NR_query_module	184 /* Linux Specific				   */
 #define __NR_setpgid            185 /* Common                                      */
 #define __NR_fremovexattr       186 /* SunOS: pathconf                             */
-/* #define __NR_fpathconf       187    SunOS Specific                              */
+#define __NR_tkill              187 /* SunOS: fpathconf                            */
 /* #define __NR_sysconf         188    SunOS Specific                              */
 #define __NR_uname              189 /* Linux Specific                              */
 #define __NR_init_module        190 /* Linux Specific                              */
@@ -271,7 +271,6 @@
 #define __NR_fdatasync          253
 #define __NR_nfsservctl         254
 #define __NR_aplib              255
-#define __NR_tkill              257
 
 #define _syscall0(type,name) \
 type name(void) \
diff --git a/include/asm-sparc64/a.out.h b/include/asm-sparc64/a.out.h
index 2b9ee5c..02af289 100644
--- a/include/asm-sparc64/a.out.h
+++ b/include/asm-sparc64/a.out.h
@@ -1,4 +1,4 @@
-/* $Id: a.out.h,v 1.7 2001/04/24 01:09:12 davem Exp $ */
+/* $Id: a.out.h,v 1.8 2002/02/09 19:49:31 davem Exp $ */
 #ifndef __SPARC64_A_OUT_H__
 #define __SPARC64_A_OUT_H__
 
@@ -95,7 +95,7 @@
 
 #ifdef __KERNEL__
 
-#define STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L)
+#define STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L)
 
 #endif
 
diff --git a/include/asm-sparc64/checksum.h b/include/asm-sparc64/checksum.h
index 5fbda25..6128f20 100644
--- a/include/asm-sparc64/checksum.h
+++ b/include/asm-sparc64/checksum.h
@@ -1,4 +1,4 @@
-/* $Id: checksum.h,v 1.17 2001/04/24 01:09:12 davem Exp $ */
+/* $Id: checksum.h,v 1.19 2002/02/09 19:49:31 davem Exp $ */
 #ifndef __SPARC64_CHECKSUM_H
 #define __SPARC64_CHECKSUM_H
 
@@ -16,7 +16,8 @@
  *      RFC1071 Computing the Internet Checksum
  */
 
-#include <asm/uaccess.h> 
+#include <linux/in6.h>
+#include <asm/uaccess.h>
 
 /* computes the checksum of a memory block at buff, length len,
  * and adds in "sum" (32-bit)
@@ -44,7 +45,7 @@
 			   unsigned int sum)
 {
 	int ret;
-	unsigned char cur_ds = current->thread.current_ds.seg;
+	unsigned char cur_ds = get_thread_current_ds();
 	__asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "i" (ASI_P));
 	ret = csum_partial_copy_sparc64(src, dst, len, sum);
 	__asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" (cur_ds));
diff --git a/include/asm-sparc64/current.h b/include/asm-sparc64/current.h
index 80652fb..7683c6b 100644
--- a/include/asm-sparc64/current.h
+++ b/include/asm-sparc64/current.h
@@ -1,7 +1,8 @@
 #ifndef _SPARC64_CURRENT_H
 #define _SPARC64_CURRENT_H
 
-/* Sparc rules... */
-register struct task_struct *current asm("g6");
+#include <asm/thread_info.h>
+
+#define current		(current_thread_info()->task)
 
 #endif /* !(_SPARC64_CURRENT_H) */
diff --git a/include/asm-sparc64/delay.h b/include/asm-sparc64/delay.h
index 61a833a..400c5eb 100644
--- a/include/asm-sparc64/delay.h
+++ b/include/asm-sparc64/delay.h
@@ -1,4 +1,4 @@
-/* $Id: delay.h,v 1.12 2001/04/24 01:09:12 davem Exp $
+/* $Id: delay.h,v 1.13 2002/02/02 03:33:48 kanoj Exp $
  * delay.h: Linux delay routines on the V9.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu).
@@ -9,9 +9,13 @@
 
 #include <linux/config.h>
 #include <linux/param.h>
+
+#ifndef __ASSEMBLY__
+
 #ifdef CONFIG_SMP
-#include <linux/sched.h>
 #include <asm/smp.h>
+#else
+extern unsigned long loops_per_jiffy;
 #endif 
 
 extern __inline__ void __delay(unsigned long loops)
@@ -49,4 +53,6 @@
 
 #define udelay(usecs) __udelay((usecs),__udelay_val)
 
+#endif /* !__ASSEMBLY__ */
+
 #endif /* defined(__SPARC64_DELAY_H) */
diff --git a/include/asm-sparc64/elf.h b/include/asm-sparc64/elf.h
index dd584ac..e6aca41 100644
--- a/include/asm-sparc64/elf.h
+++ b/include/asm-sparc64/elf.h
@@ -1,4 +1,4 @@
-/* $Id: elf.h,v 1.31 2002/01/08 16:00:20 davem Exp $ */
+/* $Id: elf.h,v 1.32 2002/02/09 19:49:31 davem Exp $ */
 #ifndef __ASM_SPARC64_ELF_H
 #define __ASM_SPARC64_ELF_H
 
@@ -69,16 +69,11 @@
 
 #ifdef __KERNEL__
 #define SET_PERSONALITY(ex, ibcs2)			\
-do {	unsigned char flags = current->thread.flags;	\
-	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)	\
-		flags |= SPARC_FLAG_32BIT;		\
+do {	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)	\
+		set_thread_flag(TIF_32BIT);		\
 	else						\
-		flags &= ~SPARC_FLAG_32BIT;		\
-	if (flags != current->thread.flags) {		\
-		/* flush_thread will update pgd cache */\
-		current->thread.flags = flags;		\
-	}						\
-							\
+		clear_thread_flag(TIF_32BIT);		\
+	/* flush_thread will update pgd cache */	\
 	if (ibcs2)					\
 		set_personality(PER_SVR4);		\
 	else if (current->personality != PER_LINUX32)	\
diff --git a/include/asm-sparc64/fpumacro.h b/include/asm-sparc64/fpumacro.h
index 3fd5cab..21d2740 100644
--- a/include/asm-sparc64/fpumacro.h
+++ b/include/asm-sparc64/fpumacro.h
@@ -14,7 +14,7 @@
 	u32	regs[64];
 };
 
-#define FPUSTATE (struct fpustate *)(((unsigned long)current) + AOFF_task_fpregs)
+#define FPUSTATE (struct fpustate *)(current_thread_info()->fpregs)
 
 extern __inline__ unsigned long fprs_read(void)
 {
diff --git a/include/asm-sparc64/hardirq.h b/include/asm-sparc64/hardirq.h
index 62bfae5..d55bd01 100644
--- a/include/asm-sparc64/hardirq.h
+++ b/include/asm-sparc64/hardirq.h
@@ -56,6 +56,8 @@
 
 #define synchronize_irq()	barrier()
 
+#define release_irqlock(cpu)	do { } while (0)
+
 #else /* (CONFIG_SMP) */
 
 static __inline__ int irqs_running(void)
diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h
index 41e9ddf..ec8de33 100644
--- a/include/asm-sparc64/mmu_context.h
+++ b/include/asm-sparc64/mmu_context.h
@@ -1,4 +1,4 @@
-/* $Id: mmu_context.h,v 1.53 2002/01/30 01:40:00 davem Exp $ */
+/* $Id: mmu_context.h,v 1.54 2002/02/09 19:49:31 davem Exp $ */
 #ifndef __SPARC64_MMU_CONTEXT_H
 #define __SPARC64_MMU_CONTEXT_H
 
@@ -101,7 +101,7 @@
 	register unsigned long pgd_cache asm("o4"); \
 	paddr = __pa((__mm)->pgd); \
 	pgd_cache = 0UL; \
-	if ((__tsk)->thread.flags & SPARC_FLAG_32BIT) \
+	if ((__tsk)->thread_info->flags & _TIF_32BIT) \
 		pgd_cache = pgd_val((__mm)->pgd[0]) << 11UL; \
 	__asm__ __volatile__("wrpr	%%g0, 0x494, %%pstate\n\t" \
 			     "mov	%3, %%g4\n\t" \
diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h
index c5de1e2..c2cdb4c 100644
--- a/include/asm-sparc64/page.h
+++ b/include/asm-sparc64/page.h
@@ -1,4 +1,4 @@
-/* $Id: page.h,v 1.38 2001/11/30 01:04:10 davem Exp $ */
+/* $Id: page.h,v 1.39 2002/02/09 19:49:31 davem Exp $ */
 
 #ifndef _SPARC64_PAGE_H
 #define _SPARC64_PAGE_H
@@ -95,7 +95,7 @@
 
 #endif /* (STRICT_MM_TYPECHECKS) */
 
-#define TASK_UNMAPPED_BASE	((current->thread.flags & SPARC_FLAG_32BIT) ? \
+#define TASK_UNMAPPED_BASE	(test_thread_flag(TIF_32BIT) ? \
 				 (0x0000000070000000UL) : (PAGE_OFFSET))
 
 #endif /* !(__ASSEMBLY__) */
diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h
index ed5d98e..e244d89 100644
--- a/include/asm-sparc64/pgalloc.h
+++ b/include/asm-sparc64/pgalloc.h
@@ -158,6 +158,7 @@
 {
 	struct page *page = virt_to_page(pgd);
 
+	preempt_disable();
 	if (!page->pprev_hash) {
 		(unsigned long *)page->next_hash = pgd_quicklist;
 		pgd_quicklist = (unsigned long *)page;
@@ -165,12 +166,14 @@
 	(unsigned long)page->pprev_hash |=
 		(((unsigned long)pgd & (PAGE_SIZE / 2)) ? 2 : 1);
 	pgd_cache_size++;
+	preempt_enable();
 }
 
 extern __inline__ pgd_t *get_pgd_fast(void)
 {
         struct page *ret;
 
+	preempt_disable();
         if ((ret = (struct page *)pgd_quicklist) != NULL) {
                 unsigned long mask = (unsigned long)ret->pprev_hash;
 		unsigned long off = 0;
@@ -186,16 +189,22 @@
 			pgd_quicklist = (unsigned long *)ret->next_hash;
                 ret = (struct page *)(__page_address(ret) + off);
                 pgd_cache_size--;
+		preempt_enable();
         } else {
-		struct page *page = alloc_page(GFP_KERNEL);
+		struct page *page;
 
+		preempt_enable();
+		page = alloc_page(GFP_KERNEL);
 		if (page) {
 			ret = (struct page *)page_address(page);
 			clear_page(ret);
 			(unsigned long)page->pprev_hash = 2;
+
+			preempt_disable();
 			(unsigned long *)page->next_hash = pgd_quicklist;
 			pgd_quicklist = (unsigned long *)page;
 			pgd_cache_size++;
+			preempt_enable();
 		}
         }
         return (pgd_t *)ret;
@@ -205,20 +214,25 @@
 
 extern __inline__ void free_pgd_fast(pgd_t *pgd)
 {
+	preempt_disable();
 	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
 	pgd_quicklist = (unsigned long *) pgd;
 	pgtable_cache_size++;
+	preempt_enable();
 }
 
 extern __inline__ pgd_t *get_pgd_fast(void)
 {
 	unsigned long *ret;
 
+	preempt_disable();
 	if((ret = pgd_quicklist) != NULL) {
 		pgd_quicklist = (unsigned long *)(*ret);
 		ret[0] = 0;
 		pgtable_cache_size--;
+		preempt_enable();
 	} else {
+		preempt_enable();
 		ret = (unsigned long *) __get_free_page(GFP_KERNEL);
 		if(ret)
 			memset(ret, 0, PAGE_SIZE);
@@ -258,20 +272,27 @@
 
 	if (pte_quicklist[color] == NULL)
 		color = 1;
+
+	preempt_disable();
 	if((ret = (unsigned long *)pte_quicklist[color]) != NULL) {
 		pte_quicklist[color] = (unsigned long *)(*ret);
 		ret[0] = 0;
 		pgtable_cache_size--;
 	}
+	preempt_enable();
+
 	return (pmd_t *)ret;
 }
 
 extern __inline__ void free_pmd_fast(pmd_t *pmd)
 {
 	unsigned long color = DCACHE_COLOR((unsigned long)pmd);
+
+	preempt_disable();
 	*(unsigned long *)pmd = (unsigned long) pte_quicklist[color];
 	pte_quicklist[color] = (unsigned long *) pmd;
 	pgtable_cache_size++;
+	preempt_enable();
 }
 
 extern __inline__ void free_pmd_slow(pmd_t *pmd)
@@ -288,20 +309,25 @@
 	unsigned long color = VPTE_COLOR(address);
 	unsigned long *ret;
 
+	preempt_disable();
 	if((ret = (unsigned long *)pte_quicklist[color]) != NULL) {
 		pte_quicklist[color] = (unsigned long *)(*ret);
 		ret[0] = 0;
 		pgtable_cache_size--;
 	}
+	preempt_enable();
 	return (pte_t *)ret;
 }
 
 extern __inline__ void free_pte_fast(pte_t *pte)
 {
 	unsigned long color = DCACHE_COLOR((unsigned long)pte);
+
+	preempt_disable();
 	*(unsigned long *)pte = (unsigned long) pte_quicklist[color];
 	pte_quicklist[color] = (unsigned long *) pte;
 	pgtable_cache_size++;
+	preempt_enable();
 }
 
 extern __inline__ void free_pte_slow(pte_t *pte)
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index 95060ec..0df0026 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.155 2001/12/21 04:56:17 davem Exp $
+/* $Id: pgtable.h,v 1.156 2002/02/09 19:49:31 davem Exp $
  * pgtable.h: SpitFire page table operations.
  *
  * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -76,7 +76,7 @@
  * is different so we can optimize correctly for 32-bit tasks.
  */
 #define REAL_PTRS_PER_PMD	(1UL << PMD_BITS)
-#define PTRS_PER_PMD		((const int)((current->thread.flags & SPARC_FLAG_32BIT) ? \
+#define PTRS_PER_PMD		((const int)(test_thread_flag(TIF_32BIT) ? \
 				 (1UL << (32 - (PAGE_SHIFT-3) - PAGE_SHIFT)) : (REAL_PTRS_PER_PMD)))
 
 /*
@@ -90,8 +90,8 @@
 			(PAGE_SHIFT-3) + PMD_BITS)))
 
 /* Kernel has a separate 44bit address space. */
-#define USER_PTRS_PER_PGD	((const int)((current->thread.flags & SPARC_FLAG_32BIT) ? \
-				 (1) : (PTRS_PER_PGD)))
+#define USER_PTRS_PER_PGD	((const int)(test_thread_flag(TIF_32BIT)) ? \
+				 (1) : (PTRS_PER_PGD))
 #define FIRST_USER_PGD_NR	0
 
 #define pte_ERROR(e)	__builtin_trap()
diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h
index dc0e882..1815502 100644
--- a/include/asm-sparc64/processor.h
+++ b/include/asm-sparc64/processor.h
@@ -1,4 +1,4 @@
-/* $Id: processor.h,v 1.80 2001/11/17 00:10:48 davem Exp $
+/* $Id: processor.h,v 1.83 2002/02/10 06:04:33 davem Exp $
  * include/asm-sparc64/processor.h
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -21,6 +21,7 @@
 #include <asm/signal.h>
 #include <asm/segment.h>
 #include <asm/page.h>
+#include <asm/delay.h>
 
 /* Bus types */
 #define EISA_bus 0
@@ -43,29 +44,13 @@
 
 #ifndef __ASSEMBLY__
 
-#define NSWINS		7
-
 typedef struct {
 	unsigned char seg;
 } mm_segment_t;
 
 /* The Sparc processor specific thread struct. */
+/* XXX This should die, everything can go into thread_info now. */
 struct thread_struct {
-	/* D$ line 1 */
-	unsigned long ksp __attribute__ ((aligned(16)));
-	unsigned char wstate, cwp, flags;
-	mm_segment_t current_ds;
-	unsigned char w_saved, fpdepth, fault_code, use_blkcommit;
-	unsigned long fault_address;
-	unsigned char fpsaved[7];
-	unsigned char __pad2;
-	
-	/* D$ line 2, 3, 4 */
-	struct pt_regs *kregs;
-	unsigned long *utraps;
-	unsigned long gsr[7];
-	unsigned long xfsr[7];
-
 #ifdef CONFIG_DEBUG_SPINLOCK
 	/* How many spinlocks held by this thread.
 	 * Used with spin lock debugging to catch tasks
@@ -73,96 +58,29 @@
 	 */
 	int smp_lock_count;
 	unsigned int smp_lock_pc;
+#else
+	int dummy; /* f'in gcc bug... */
 #endif
-
-	struct reg_window reg_window[NSWINS];
-	unsigned long rwbuf_stkptrs[NSWINS];
-	
-	/* Performance counter state */
-	u64 *user_cntd0, *user_cntd1;
-	u64 kernel_cntd0, kernel_cntd1;
-	u64 pcr_reg;
 };
 
 #endif /* !(__ASSEMBLY__) */
 
-#define SPARC_FLAG_UNALIGNED    0x01    /* is allowed to do unaligned accesses	*/
-#define SPARC_FLAG_NEWSIGNALS   0x02    /* task wants new-style signals		*/
-#define SPARC_FLAG_32BIT        0x04    /* task is older 32-bit binary		*/
-#define SPARC_FLAG_NEWCHILD     0x08    /* task is just-spawned child process	*/
-#define SPARC_FLAG_PERFCTR	0x10    /* task has performance counters active	*/
-
-#define FAULT_CODE_WRITE	0x01	/* Write access, implies D-TLB		*/
-#define FAULT_CODE_DTLB		0x02	/* Miss happened in D-TLB		*/
-#define FAULT_CODE_ITLB		0x04	/* Miss happened in I-TLB		*/
-#define FAULT_CODE_WINFIXUP	0x08	/* Miss happened during spill/fill	*/
-
 #ifndef CONFIG_DEBUG_SPINLOCK
-#define INIT_THREAD  {					\
-/* ksp, wstate, cwp, flags, current_ds, */ 		\
-   0,   0,      0,   0,     KERNEL_DS,			\
-/* w_saved, fpdepth, fault_code, use_blkcommit, */	\
-   0,       0,       0,          0,			\
-/* fault_address, fpsaved, __pad2, kregs, */		\
-   0,             { 0 },   0,      0,			\
-/* utraps, gsr,   xfsr, */				\
-   0,	   { 0 }, { 0 },				\
-/* reg_window */					\
-   { { { 0, }, { 0, } }, }, 				\
-/* rwbuf_stkptrs */					\
-   { 0, 0, 0, 0, 0, 0, 0, },				\
-/* user_cntd0, user_cndd1, kernel_cntd0, kernel_cntd0, pcr_reg */ \
-   0,          0,          0,		 0,            0, \
+#define INIT_THREAD  {			\
+	0,				\
 }
 #else /* CONFIG_DEBUG_SPINLOCK */
 #define INIT_THREAD  {					\
-/* ksp, wstate, cwp, flags, current_ds, */ 		\
-   0,   0,      0,   0,     KERNEL_DS,			\
-/* w_saved, fpdepth, fault_code, use_blkcommit, */	\
-   0,       0,       0,          0,			\
-/* fault_address, fpsaved, __pad2, kregs, */		\
-   0,             { 0 },   0,      0,			\
-/* utraps, gsr,   xfsr,  smp_lock_count, smp_lock_pc, */\
-   0,	   { 0 }, { 0 }, 0,		 0,		\
-/* reg_window */					\
-   { { { 0, }, { 0, } }, }, 				\
-/* rwbuf_stkptrs */					\
-   { 0, 0, 0, 0, 0, 0, 0, },				\
-/* user_cntd0, user_cndd1, kernel_cntd0, kernel_cntd0, pcr_reg */ \
-   0,          0,          0,		 0,            0, \
+/* smp_lock_count, smp_lock_pc, */			\
+   0,		   0,					\
 }
 #endif /* !(CONFIG_DEBUG_SPINLOCK) */
 
-#ifdef __KERNEL__
-#if PAGE_SHIFT == 13
-#define THREAD_SIZE (2*PAGE_SIZE)
-#define THREAD_SHIFT (PAGE_SHIFT + 1)
-#else /* PAGE_SHIFT == 13 */
-#define THREAD_SIZE PAGE_SIZE
-#define THREAD_SHIFT PAGE_SHIFT
-#endif /* PAGE_SHIFT == 13 */
-#endif /* __KERNEL__ */
-
 #ifndef __ASSEMBLY__
 
 /* Return saved PC of a blocked thread. */
-extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t)
-{
-	unsigned long ret = 0xdeadbeefUL;
-	
-	if (t->ksp) {
-		unsigned long *sp;
-		sp = (unsigned long *)(t->ksp + STACK_BIAS);
-		if (((unsigned long)sp & (sizeof(long) - 1)) == 0UL &&
-		    sp[14]) {
-			unsigned long *fp;
-			fp = (unsigned long *)(sp[14] + STACK_BIAS);
-			if (((unsigned long)fp & (sizeof(long) - 1)) == 0UL)
-				ret = fp[15];
-		}
-	}
-	return ret;
-}
+struct task_struct;
+extern unsigned long thread_saved_pc(struct task_struct *);
 
 /* On Uniprocessor, even in RMO processes see TSO semantics */
 #ifdef CONFIG_SMP
@@ -178,13 +96,13 @@
 	regs->tpc = ((pc & (~3)) - 4); \
 	regs->tnpc = regs->tpc + 4; \
 	regs->y = 0; \
-	current->thread.wstate = (1 << 3); \
-	if (current->thread.utraps) { \
-		if (*(current->thread.utraps) < 2) \
-			kfree (current->thread.utraps); \
+	set_thread_wstate(1 << 3); \
+	if (current_thread_info()->utraps) { \
+		if (*(current_thread_info()->utraps) < 2) \
+			kfree(current_thread_info()->utraps); \
 		else \
-			(*(current->thread.utraps))--; \
-		current->thread.utraps = NULL; \
+			(*(current_thread_info()->utraps))--; \
+		current_thread_info()->utraps = NULL; \
 	} \
 	__asm__ __volatile__( \
 	"stx		%%g0, [%0 + %2 + 0x00]\n\t" \
@@ -207,7 +125,7 @@
 	: \
 	: "r" (regs), "r" (sp - REGWIN_SZ - STACK_BIAS), \
 	  "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \
-} while(0)
+} while (0)
 
 #define start_thread32(regs, pc, sp) \
 do { \
@@ -218,13 +136,13 @@
 	regs->tpc = ((pc & (~3)) - 4); \
 	regs->tnpc = regs->tpc + 4; \
 	regs->y = 0; \
-	current->thread.wstate = (2 << 3); \
-	if (current->thread.utraps) { \
-		if (*(current->thread.utraps) < 2) \
-			kfree (current->thread.utraps); \
+	set_thread_wstate(2 << 3); \
+	if (current_thread_info()->utraps) { \
+		if (*(current_thread_info()->utraps) < 2) \
+			kfree(current_thread_info()->utraps); \
 		else \
-			(*(current->thread.utraps))--; \
-		current->thread.utraps = NULL; \
+			(*(current_thread_info()->utraps))--; \
+		current_thread_info()->utraps = NULL; \
 	} \
 	__asm__ __volatile__( \
 	"stx		%%g0, [%0 + %2 + 0x00]\n\t" \
@@ -247,10 +165,10 @@
 	: \
 	: "r" (regs), "r" (sp - REGWIN32_SZ), \
 	  "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \
-} while(0)
+} while (0)
 
 /* Free all resources held by a thread. */
-#define release_thread(tsk)		do { } while(0)
+#define release_thread(tsk)		do { } while (0)
 
 extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
@@ -261,19 +179,20 @@
 ({	extern void scheduling_functions_start_here(void); \
 	extern void scheduling_functions_end_here(void); \
 	unsigned long pc, fp, bias = 0; \
-	unsigned long task_base = (unsigned long) (__TSK); \
+	unsigned long thread_info_base; \
 	struct reg_window *rw; \
         unsigned long __ret = 0; \
 	int count = 0; \
 	if (!(__TSK) || (__TSK) == current || \
             (__TSK)->state == TASK_RUNNING) \
 		goto __out; \
+	thread_info_base = (unsigned long) ((__TSK)->thread_info); \
 	bias = STACK_BIAS; \
-	fp = (__TSK)->thread.ksp + bias; \
+	fp = (__TSK)->thread_info->ksp + bias; \
 	do { \
 		/* Bogus frame pointer? */ \
-		if (fp < (task_base + sizeof(struct task_struct)) || \
-		    fp >= (task_base + THREAD_SIZE)) \
+		if (fp < (thread_info_base + sizeof(struct thread_info)) || \
+		    fp >= (thread_info_base + THREAD_SIZE)) \
 			break; \
 		rw = (struct reg_window *) fp; \
 		pc = rw->ins[7]; \
@@ -287,26 +206,10 @@
 __out:	__ret; \
 })
 
-#define KSTK_EIP(tsk)  ((tsk)->thread.kregs->tpc)
-#define KSTK_ESP(tsk)  ((tsk)->thread.kregs->u_regs[UREG_FP])
+#define KSTK_EIP(tsk)  ((tsk)->thread_info->kregs->tpc)
+#define KSTK_ESP(tsk)  ((tsk)->thread_info->kregs->u_regs[UREG_FP])
 
-#ifdef __KERNEL__
-/* Allocation and freeing of task_struct and kernel stack. */
-#if PAGE_SHIFT == 13
-#define alloc_task_struct()   ((struct task_struct *)__get_free_pages(GFP_KERNEL, 1))
-#define free_task_struct(tsk) free_pages((unsigned long)(tsk),1)
-#else /* PAGE_SHIFT == 13 */
-#define alloc_task_struct()   ((struct task_struct *)__get_free_pages(GFP_KERNEL, 0))
-#define free_task_struct(tsk) free_pages((unsigned long)(tsk),0)
-#endif /* PAGE_SHIFT == 13 */
-#define get_task_struct(tsk)      atomic_inc(&virt_to_page(tsk)->count)
-
-#define init_task	(init_task_union.task)
-#define init_stack	(init_task_union.stack)
-
-#define cpu_relax()	do { } while (0)
-
-#endif /* __KERNEL__ */
+#define cpu_relax()	udelay(1 + smp_processor_id())
 
 #endif /* !(__ASSEMBLY__) */
 
diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h
index 39bb820..e464335 100644
--- a/include/asm-sparc64/ptrace.h
+++ b/include/asm-sparc64/ptrace.h
@@ -1,4 +1,4 @@
-/* $Id: ptrace.h,v 1.13 1997/09/17 17:27:51 davem Exp $ */
+/* $Id: ptrace.h,v 1.14 2002/02/09 19:49:32 davem Exp $ */
 #ifndef _SPARC64_PTRACE_H
 #define _SPARC64_PTRACE_H
 
@@ -110,8 +110,6 @@
 #define TRACEREG32_SZ		0x50
 #define STACKFRAME32_SZ		0x60
 #define REGWIN32_SZ		0x40
-
-#include <asm/asm_offsets.h>
 #endif
 
 #ifdef __KERNEL__
diff --git a/include/asm-sparc64/sfp-machine.h b/include/asm-sparc64/sfp-machine.h
index 49c77bd..5015bb8 100644
--- a/include/asm-sparc64/sfp-machine.h
+++ b/include/asm-sparc64/sfp-machine.h
@@ -74,7 +74,7 @@
 
 /* Obtain the current rounding mode. */
 #ifndef FP_ROUNDMODE
-#define FP_ROUNDMODE	((current->thread.xfsr[0] >> 30) & 0x3)
+#define FP_ROUNDMODE	((current_thread_info()->xfsr[0] >> 30) & 0x3)
 #endif
 
 /* Exception flags. */
@@ -86,6 +86,6 @@
 
 #define FP_HANDLE_EXCEPTIONS return _fex
 
-#define FP_INHIBIT_RESULTS ((current->thread.xfsr[0] >> 23) & _fex)
+#define FP_INHIBIT_RESULTS ((current_thread_info()->xfsr[0] >> 23) & _fex)
 
 #endif
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
index d73d3e6..ae53073 100644
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -103,7 +103,7 @@
 	}
 }
 
-#define smp_processor_id() (current->cpu)
+#define smp_processor_id() (current_thread_info()->cpu)
 
 /* This needn't do anything as we do not sleep the cpu
  * inside of the idler task, so an interrupt is not needed
diff --git a/include/asm-sparc64/smplock.h b/include/asm-sparc64/smplock.h
index dd2cc2b..d9c8754 100644
--- a/include/asm-sparc64/smplock.h
+++ b/include/asm-sparc64/smplock.h
@@ -9,9 +9,17 @@
 
 extern spinlock_t kernel_flag;
 
+#ifdef CONFIG_SMP
 #define kernel_locked()			\
 	(spin_is_locked(&kernel_flag) &&\
 	 (current->lock_depth >= 0))
+#else
+#ifdef CONFIG_PREEMPT
+#define kernel_locked()			preempt_get_count()
+#else
+#define kernel_locked()			1
+#endif
+#endif
 
 /*
  * Release global kernel lock and global interrupt lock
diff --git a/include/asm-sparc64/softirq.h b/include/asm-sparc64/softirq.h
index e97b25e..0239b72 100644
--- a/include/asm-sparc64/softirq.h
+++ b/include/asm-sparc64/softirq.h
@@ -10,14 +10,15 @@
 #include <asm/hardirq.h>
 #include <asm/system.h>		/* for membar() */
 
-#define local_bh_disable()	(local_bh_count(smp_processor_id())++)
-#define __local_bh_enable()	(local_bh_count(smp_processor_id())--)
+#define local_bh_disable()	do { barrier(); preempt_disable(); local_bh_count(smp_processor_id())++; } while (0)
+#define __local_bh_enable()	do { local_bh_count(smp_processor_id())--; preempt_enable(); barrier(); } while (0)
 #define local_bh_enable()			  \
 do { if (!--local_bh_count(smp_processor_id()) && \
 	 softirq_pending(smp_processor_id())) {   \
 		do_softirq();			  \
 		__sti();			  \
      }						  \
+     preempt_enable();				  \
 } while (0)
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
index ce905b4..55fef65 100644
--- a/include/asm-sparc64/spinlock.h
+++ b/include/asm-sparc64/spinlock.h
@@ -40,7 +40,7 @@
 do {	membar("#LoadLoad");	\
 } while(*((volatile unsigned char *)lock))
 
-extern __inline__ void spin_lock(spinlock_t *lock)
+extern __inline__ void _raw_spin_lock(spinlock_t *lock)
 {
 	__asm__ __volatile__(
 "1:	ldstub		[%0], %%g7\n"
@@ -57,7 +57,7 @@
 	: "g7", "memory");
 }
 
-extern __inline__ int spin_trylock(spinlock_t *lock)
+extern __inline__ int _raw_spin_trylock(spinlock_t *lock)
 {
 	unsigned int result;
 	__asm__ __volatile__("ldstub [%1], %0\n\t"
@@ -68,7 +68,7 @@
 	return (result == 0);
 }
 
-extern __inline__ void spin_unlock(spinlock_t *lock)
+extern __inline__ void _raw_spin_unlock(spinlock_t *lock)
 {
 	__asm__ __volatile__("membar	#StoreStore | #LoadStore\n\t"
 			     "stb	%%g0, [%0]"
@@ -99,9 +99,9 @@
 extern void _do_spin_unlock (spinlock_t *lock);
 extern int _spin_trylock (spinlock_t *lock);
 
-#define spin_trylock(lp)	_spin_trylock(lp)
-#define spin_lock(lock)		_do_spin_lock(lock, "spin_lock")
-#define spin_unlock(lock)	_do_spin_unlock(lock)
+#define _raw_spin_trylock(lp)	_spin_trylock(lp)
+#define _raw_spin_lock(lock)	_do_spin_lock(lock, "spin_lock")
+#define _raw_spin_unlock(lock)	_do_spin_unlock(lock)
 
 #endif /* CONFIG_DEBUG_SPINLOCK */
 
@@ -118,10 +118,10 @@
 extern void __write_lock(rwlock_t *);
 extern void __write_unlock(rwlock_t *);
 
-#define read_lock(p)	__read_lock(p)
-#define read_unlock(p)	__read_unlock(p)
-#define write_lock(p)	__write_lock(p)
-#define write_unlock(p)	__write_unlock(p)
+#define _raw_read_lock(p)	__read_lock(p)
+#define _raw_read_unlock(p)	__read_unlock(p)
+#define _raw_write_lock(p)	__write_lock(p)
+#define _raw_write_unlock(p)	__write_unlock(p)
 
 #else /* !(CONFIG_DEBUG_SPINLOCK) */
 
@@ -138,28 +138,28 @@
 extern void _do_write_lock(rwlock_t *rw, char *str);
 extern void _do_write_unlock(rwlock_t *rw);
 
-#define read_lock(lock)	\
+#define _raw_read_lock(lock) \
 do {	unsigned long flags; \
 	__save_and_cli(flags); \
 	_do_read_lock(lock, "read_lock"); \
 	__restore_flags(flags); \
 } while(0)
 
-#define read_unlock(lock) \
+#define _raw_read_unlock(lock) \
 do {	unsigned long flags; \
 	__save_and_cli(flags); \
 	_do_read_unlock(lock, "read_unlock"); \
 	__restore_flags(flags); \
 } while(0)
 
-#define write_lock(lock) \
+#define _raw_write_lock(lock) \
 do {	unsigned long flags; \
 	__save_and_cli(flags); \
 	_do_write_lock(lock, "write_lock"); \
 	__restore_flags(flags); \
 } while(0)
 
-#define write_unlock(lock) \
+#define _raw_write_unlock(lock) \
 do {	unsigned long flags; \
 	__save_and_cli(flags); \
 	_do_write_unlock(lock); \
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index d5b497d..5896956 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -1,12 +1,12 @@
-/* $Id: system.h,v 1.68 2001/11/18 00:12:56 davem Exp $ */
+/* $Id: system.h,v 1.69 2002/02/09 19:49:31 davem Exp $ */
 #ifndef __SPARC64_SYSTEM_H
 #define __SPARC64_SYSTEM_H
 
 #include <linux/config.h>
 #include <asm/ptrace.h>
 #include <asm/processor.h>
-#include <asm/asm_offsets.h>
 #include <asm/visasm.h>
+#include <asm/thread_info.h>
 
 #ifndef __ASSEMBLY__
 /*
@@ -174,19 +174,19 @@
 	 */
 #define switch_to(prev, next, last)						\
 do {	CHECK_LOCKS(prev);							\
-	if (current->thread.flags & SPARC_FLAG_PERFCTR) {			\
+	if (test_thread_flag(TIF_PERFCTR)) {					\
 		unsigned long __tmp;						\
 		read_pcr(__tmp);						\
-		current->thread.pcr_reg = __tmp;				\
+		current_thread_info()->pcr_reg = __tmp;				\
 		read_pic(__tmp);						\
-		current->thread.kernel_cntd0 += (unsigned int)(__tmp);		\
-		current->thread.kernel_cntd1 += ((__tmp) >> 32);		\
+		current_thread_info()->kernel_cntd0 += (unsigned int)(__tmp);	\
+		current_thread_info()->kernel_cntd1 += ((__tmp) >> 32);		\
 	}									\
 	save_and_clear_fpu();							\
 	/* If you are tempted to conditionalize the following */		\
 	/* so that ASI is only written if it changes, think again. */		\
 	__asm__ __volatile__("wr %%g0, %0, %%asi"				\
-			     : : "r" (next->thread.current_ds.seg));		\
+	: : "r" (__thread_flag_byte_ptr(next->thread_info)[TI_FLAG_BYTE_CURRENT_DS]));	\
 	__asm__ __volatile__(							\
 	"mov	%%g6, %%g5\n\t"							\
 	"wrpr	%%g0, 0x95, %%pstate\n\t"					\
@@ -202,7 +202,7 @@
 	"wrpr	%%g1, %%cwp\n\t"						\
 	"ldx	[%%g6 + %3], %%o6\n\t"						\
 	"ldub	[%%g6 + %2], %%o5\n\t"						\
-	"ldub	[%%g6 + %4], %%o7\n\t"						\
+	"ldx	[%%g6 + %4], %%o7\n\t"						\
 	"mov	%%g6, %%l2\n\t"							\
 	"wrpr	%%o5, 0x0, %%wstate\n\t"					\
 	"ldx	[%%sp + 2047 + 0x70], %%i6\n\t"					\
@@ -212,21 +212,18 @@
 	"wrpr	%%g0, 0x96, %%pstate\n\t"					\
 	"andcc	%%o7, %6, %%g0\n\t"						\
 	"bne,pn	%%icc, ret_from_syscall\n\t"					\
-	" mov	%%g5, %0\n\t"							\
+	" ldx	[%%g5 + %7], %0\n\t"						\
 	: "=&r" (last)								\
-	: "r" (next),								\
-	  "i" ((const unsigned long)(&((struct task_struct *)0)->thread.wstate)),\
-	  "i" ((const unsigned long)(&((struct task_struct *)0)->thread.ksp)),	\
-	  "i" ((const unsigned long)(&((struct task_struct *)0)->thread.flags)),\
-	  "i" ((const unsigned long)(&((struct task_struct *)0)->thread.cwp)),	\
-	  "i" (SPARC_FLAG_NEWCHILD)						\
+	: "r" (next->thread_info),						\
+	  "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_FLAGS), "i" (TI_CWP),		\
+	  "i" (_TIF_NEWCHILD), "i" (TI_TASK)					\
 	: "cc", "g1", "g2", "g3", "g5", "g7",					\
 	  "l2", "l3", "l4", "l5", "l6", "l7",					\
 	  "i0", "i1", "i2", "i3", "i4", "i5",					\
 	  "o0", "o1", "o2", "o3", "o4", "o5", "o7");				\
 	/* If you fuck with this, update ret_from_syscall code too. */		\
-	if (current->thread.flags & SPARC_FLAG_PERFCTR) {			\
-		write_pcr(current->thread.pcr_reg);				\
+	if (test_thread_flag(TIF_PERFCTR)) {					\
+		write_pcr(current_thread_info()->pcr_reg);			\
 		reset_pic();							\
 	}									\
 } while(0)
diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
new file mode 100644
index 0000000..30224a2
--- /dev/null
+++ b/include/asm-sparc64/thread_info.h
@@ -0,0 +1,214 @@
+/* $Id: thread_info.h,v 1.1 2002/02/10 00:00:58 davem Exp $
+ * thread_info.h: sparc64 low-level thread information
+ *
+ * Copyright (C) 2002  David S. Miller (davem@redhat.com)
+ */
+
+#ifndef _ASM_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#define NSWINS		7
+
+#define TI_FLAG_BYTE_FAULT_CODE		0
+#define TI_FLAG_FAULT_CODE_SHIFT	56
+#define TI_FLAG_BYTE_WSTATE		1
+#define TI_FLAG_WSTATE_SHIFT		48
+#define TI_FLAG_BYTE_CWP		2
+#define TI_FLAG_CWP_SHIFT		40
+#define TI_FLAG_BYTE_CURRENT_DS		3
+#define TI_FLAG_CURRENT_DS_SHIFT	32
+#define TI_FLAG_BYTE_FPDEPTH		4
+#define TI_FLAG_FPDEPTH_SHIFT		24
+#define TI_FLAG_BYTE_WSAVED		5
+#define TI_FLAG_WSAVED_SHIFT		16
+
+#ifndef __ASSEMBLY__
+
+#include <asm/ptrace.h>
+#include <asm/types.h>
+
+struct task_struct;
+struct exec_domain;
+
+struct thread_info {
+	/* D$ line 1 */
+	struct task_struct	*task;
+	unsigned long		flags;
+	__u8			cpu;
+	__u8			fpsaved[7];
+	unsigned long		ksp;
+
+	/* D$ line 2 */
+	unsigned long		fault_address;
+	struct pt_regs		*kregs;
+	struct exec_domain	*exec_domain;
+	int			preempt_count;
+
+	unsigned long		*utraps;
+
+	struct reg_window 	reg_window[NSWINS];
+	unsigned long 		rwbuf_stkptrs[NSWINS];
+
+	unsigned long		gsr[7];
+	unsigned long		xfsr[7];
+
+	__u64			*user_cntd0, *user_cntd1;
+	__u64			kernel_cntd0, kernel_cntd1;
+	__u64			pcr_reg;
+
+	__u64			cee_stuff;
+
+	unsigned long		fpregs[0] __attribute__ ((aligned(64)));
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+/* offsets into the thread_info struct for assembly code access */
+#define TI_TASK		0x00000000
+#define TI_FLAGS	0x00000008
+#define TI_FAULT_CODE	(TI_FLAGS + TI_FLAG_BYTE_FAULT_CODE)
+#define TI_WSTATE	(TI_FLAGS + TI_FLAG_BYTE_WSTATE)
+#define TI_CWP		(TI_FLAGS + TI_FLAG_BYTE_CWP)
+#define TI_CURRENT_DS	(TI_FLAGS + TI_FLAG_BYTE_CURRENT_DS)
+#define TI_FPDEPTH	(TI_FLAGS + TI_FLAG_BYTE_FPDEPTH)
+#define TI_WSAVED	(TI_FLAGS + TI_FLAG_BYTE_WSAVED)
+#define TI_CPU		0x00000010
+#define TI_FPSAVED	0x00000011
+#define TI_KSP		0x00000018
+#define TI_FAULT_ADDR	0x00000020
+#define TI_KREGS	0x00000028
+#define TI_EXEC_DOMAIN	0x00000030
+#define TI_PRE_COUNT	0x00000038
+#define TI_UTRAPS	0x00000040
+#define TI_REG_WINDOW	0x00000048
+#define TI_RWIN_SPTRS	0x000003c8	
+#define TI_GSR		0x00000400
+#define TI_XFSR		0x00000438
+#define TI_USER_CNTD0	0x00000470
+#define TI_USER_CNTD1	0x00000478
+#define TI_KERN_CNTD0	0x00000480
+#define TI_KERN_CNTD1	0x00000488
+#define TI_PCR		0x00000490
+#define TI_CEE_STUFF	0x00000498
+#define TI_FPREGS	0x000004c0
+
+/* We embed this in the uppermost byte of thread_info->flags */
+#define FAULT_CODE_WRITE	0x01	/* Write access, implies D-TLB		*/
+#define FAULT_CODE_DTLB		0x02	/* Miss happened in D-TLB		*/
+#define FAULT_CODE_ITLB		0x04	/* Miss happened in I-TLB		*/
+#define FAULT_CODE_WINFIXUP	0x08	/* Miss happened during spill/fill	*/
+
+#if PAGE_SHIFT == 13
+#define THREAD_SIZE (2*PAGE_SIZE)
+#define THREAD_SHIFT (PAGE_SHIFT + 1)
+#else /* PAGE_SHIFT == 13 */
+#define THREAD_SIZE PAGE_SIZE
+#define THREAD_SHIFT PAGE_SHIFT
+#endif /* PAGE_SHIFT == 13 */
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ */
+#ifndef __ASSEMBLY__
+
+#define INIT_THREAD_INFO(tsk)				\
+{							\
+	task:		&tsk,				\
+	flags:		((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT,	\
+	exec_domain:	&default_exec_domain,		\
+}
+
+#define init_thread_info	(init_thread_union.thread_info)
+#define init_stack		(init_thread_union.stack)
+
+/* how to get the thread information struct from C */
+register struct thread_info *current_thread_info_reg asm("g6");
+#define current_thread_info()	(current_thread_info_reg)
+
+/* thread information allocation */
+#if PAGE_SHIFT == 13
+#define alloc_thread_info()   ((struct thread_info *)__get_free_pages(GFP_KERNEL, 1))
+#define free_thread_info(ti)  free_pages((unsigned long)(ti),1)
+#else /* PAGE_SHIFT == 13 */
+#define alloc_thread_info()   ((struct thread_info *)__get_free_pages(GFP_KERNEL, 0))
+#define free_thread_info(ti)  free_pages((unsigned long)(ti),0)
+#endif /* PAGE_SHIFT == 13 */
+
+#define __thread_flag_byte_ptr(ti)	\
+	((unsigned char *)(&((ti)->flags)))
+#define __cur_thread_flag_byte_ptr	__thread_flag_byte_ptr(current_thread_info())
+
+#define get_thread_fault_code()		(__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FAULT_CODE])
+#define set_thread_fault_code(val)	(__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FAULT_CODE] = (val))
+#define get_thread_wstate()		(__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE])
+#define set_thread_wstate(val)		(__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE] = (val))
+#define get_thread_cwp()		(__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP])
+#define set_thread_cwp(val)		(__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP] = (val))
+#define get_thread_current_ds()		(__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS])
+#define set_thread_current_ds(val)	(__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS] = (val))
+#define get_thread_fpdepth()		(__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH])
+#define set_thread_fpdepth(val)		(__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH] = (val))
+#define get_thread_wsaved()		(__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED])
+#define set_thread_wsaved(val)		(__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED] = (val))
+
+#endif /* !(__ASSEMBLY__) */
+
+/*
+ * Thread information flags, only 16 bits are available as we encode
+ * other values into the upper 6 bytes.
+ *
+ * On trap return we need to test several values:
+ *
+ * user:	need_resched, notify_resume, sigpending, wsaved, perfctr
+ * kernel:	fpdepth
+ *
+ * So to check for work in the kernel case we simply load the fpdepth
+ * byte out of the flags and test it.  For the user case we encode the
+ * lower 3 bytes of flags as follows:
+ *	----------------------------------------
+ *	| wsaved | flags byte 1 | flags byte 2 |
+ *	----------------------------------------
+ * This optimizes the user test into:
+ *	ldx		[%g6 + TI_FLAGS], REG1
+ *	sethi		%hi(_TIF_USER_WORK_MASK), REG2
+ *	or		REG2, %lo(_TIF_USER_WORK_MASK), REG2
+ *	andcc		REG1, REG2, %g0
+ *	be,pt		no_work_to_do
+ *	 nop
+ */
+#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+#define TIF_NOTIFY_RESUME	1	/* resumption notification requested */
+#define TIF_SIGPENDING		2	/* signal pending */
+#define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+#define TIF_PERFCTR		4	/* performance counters active */
+#define TIF_UNALIGNED		5	/* allowed to do unaligned accesses */
+#define TIF_NEWSIGNALS		6	/* wants new-style signals */
+#define TIF_32BIT		7	/* 32-bit binary */
+#define TIF_NEWCHILD		8	/* just-spawned child process */
+
+/* XXX Make this one FAULT_CODE_BLKCOMMIT XXX */
+#define TIF_BLKCOMMIT		9	/* use ASI_BLK_COMMIT_* in copy_user_page */
+
+#define TIF_POLLING_NRFLAG	10
+
+#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+#define _TIF_PERFCTR		(1<<TIF_PERFCTR)
+#define _TIF_UNALIGNED		(1<<TIF_UNALIGNED)
+#define _TIF_NEWSIGNALS		(1<<TIF_NEWSIGNALS)
+#define _TIF_32BIT		(1<<TIF_32BIT)
+#define _TIF_NEWCHILD		(1<<TIF_NEWCHILD)
+#define _TIF_BLKCOMMIT		(1<<TIF_BLKCOMMIT)
+#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+
+#define _TIF_USER_WORK_MASK	((0xff << TI_FLAG_WSAVED_SHIFT) | \
+				 (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
+				  _TIF_NEED_RESCHED | _TIF_PERFCTR))
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_THREAD_INFO_H */
diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h
index 8ed23fd..0e08a25 100644
--- a/include/asm-sparc64/ttable.h
+++ b/include/asm-sparc64/ttable.h
@@ -1,9 +1,9 @@
-/* $Id: ttable.h,v 1.17 2001/11/28 23:32:16 davem Exp $ */
+/* $Id: ttable.h,v 1.18 2002/02/09 19:49:32 davem Exp $ */
 #ifndef _SPARC64_TTABLE_H
 #define _SPARC64_TTABLE_H
 
 #include <linux/config.h>
-#include <asm/asm_offsets.h>
+#include <asm/thread_info.h>
 #include <asm/utrap.h>
 
 #define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop;
@@ -104,14 +104,14 @@
 	 mov	num, %g1;				\
 	nop;nop;nop;
 	
-#define TRAP_UTRAP(handler,lvl)						\
-	ldx	[%g6 + AOFF_task_thread + AOFF_thread_utraps], %g1;	\
-	sethi	%hi(109f), %g7;						\
-	brz,pn	%g1, utrap;						\
-	 or	%g7, %lo(109f), %g7;					\
-	ba,pt	%xcc, utrap;						\
-109:	 ldx	[%g1 + handler*8], %g1;					\
-	ba,pt	%xcc, utrap_ill;					\
+#define TRAP_UTRAP(handler,lvl)				\
+	ldx	[%g6 + TI_UTRAPS], %g1;			\
+	sethi	%hi(109f), %g7;				\
+	brz,pn	%g1, utrap;				\
+	 or	%g7, %lo(109f), %g7;			\
+	ba,pt	%xcc, utrap;				\
+109:	 ldx	[%g1 + handler*8], %g1;			\
+	ba,pt	%xcc, utrap_ill;			\
 	 mov	lvl, %o1;
 
 #ifdef CONFIG_SUNOS_EMUL
@@ -140,7 +140,7 @@
 	mov	level, %o0;				\
 	call	routine;				\
 	 add	%sp, STACK_BIAS + REGWIN_SZ, %o1;	\
-	ba,a,pt	%xcc, rtrap_clr_l6;
+	ba,a,pt	%xcc, rtrap_irq;
 	
 #define TICK_SMP_IRQ					\
 	rdpr	%pil, %g2;				\
@@ -150,7 +150,7 @@
 109:	 or	%g7, %lo(109b), %g7;			\
 	call	smp_percpu_timer_interrupt;		\
 	 add	%sp, STACK_BIAS + REGWIN_SZ, %o0;	\
-	ba,a,pt	%xcc, rtrap_clr_l6;
+	ba,a,pt	%xcc, rtrap_irq;
 
 #define TRAP_IVEC TRAP_NOSAVE(do_ivec)
 
diff --git a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h
index a5590b8..a52de7d 100644
--- a/include/asm-sparc64/uaccess.h
+++ b/include/asm-sparc64/uaccess.h
@@ -1,4 +1,4 @@
-/* $Id: uaccess.h,v 1.34 2001/09/27 04:36:24 kanoj Exp $ */
+/* $Id: uaccess.h,v 1.35 2002/02/09 19:49:31 davem Exp $ */
 #ifndef _ASM_UACCESS_H
 #define _ASM_UACCESS_H
 
@@ -36,14 +36,14 @@
 #define VERIFY_READ	0
 #define VERIFY_WRITE	1
 
-#define get_fs() (current->thread.current_ds)
+#define get_fs() ((mm_segment_t) { get_thread_current_ds() })
 #define get_ds() (KERNEL_DS)
 
 #define segment_eq(a,b)  ((a).seg == (b).seg)
 
 #define set_fs(val)								\
 do {										\
-	current->thread.current_ds = (val);					\
+	set_thread_current_ds((val).seg);					\
 	__asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg));	\
 } while(0)
 
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index 1b32581..c5a635c 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.49 2001/10/18 08:27:05 davem Exp $ */
+/* $Id: unistd.h,v 1.50 2002/02/08 03:57:18 davem Exp $ */
 #ifndef _SPARC64_UNISTD_H
 #define _SPARC64_UNISTD_H
 
@@ -202,7 +202,7 @@
 #define __NR_query_module	184 /* Linux Specific				   */
 #define __NR_setpgid            185 /* Common                                      */
 /* #define __NR_pathconf        186    SunOS Specific                              */
-/* #define __NR_fpathconf       187    SunOS Specific                              */
+#define __NR_tkill              187 /* SunOS: fpathconf                            */
 /* #define __NR_sysconf         188    SunOS Specific                              */
 #define __NR_uname              189 /* Linux Specific                              */
 #define __NR_init_module        190 /* Linux Specific                              */
@@ -273,7 +273,6 @@
 #define __NR_fdatasync          253
 #define __NR_nfsservctl         254
 #define __NR_aplib              255
-#define __NR_tkill              256
 
 #define _syscall0(type,name) \
 type name(void) \
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index e53859f..3f0b16c 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -250,6 +250,9 @@
 EXPORT_SYMBOL(vfs_unlink);
 EXPORT_SYMBOL(vfs_rename);
 EXPORT_SYMBOL(vfs_statfs);
+EXPORT_SYMBOL(vfs_fstat);
+EXPORT_SYMBOL(vfs_stat);
+EXPORT_SYMBOL(vfs_lstat);
 EXPORT_SYMBOL(generic_read_dir);
 EXPORT_SYMBOL(generic_file_llseek);
 EXPORT_SYMBOL(remote_llseek);
diff --git a/kernel/sched.c b/kernel/sched.c
index 19d5451..c8b0115 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1256,12 +1256,12 @@
 	if (p == current)
 		printk(" current  ");
 	else
-		printk(" %08lX ", thread_saved_pc(&p->thread));
+		printk(" %08lX ", thread_saved_pc(p));
 #else
 	if (p == current)
 		printk("   current task   ");
 	else
-		printk(" %016lx ", thread_saved_pc(&p->thread));
+		printk(" %016lx ", thread_saved_pc(p));
 #endif
 	{
 		unsigned long * n = (unsigned long *) (p+1);