[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-ia64
Subject:    [Linux-ia64] updatd kernel diff (relative to 2.4.0-test1)
From:       David Mosberger <davidm () hpl ! hp ! com>
Date:       2000-06-22 6:51:45
[Download RAW message or body]

Here is an updated kernel diff.

 IMPORTANT NOTICE

	- Per request from Jes, the "stat" structure was changed to
	  make it match with glibc-2.2.  This provides for a more
	  efficient implementation of stat and friends.  However, the
	  new format makes the stat, lstat, and fstat system calls
	  incompatible with current binaries.  Thus, rather than
	  replacing the existing syscalls, we added new versions of
	  them.  The old versions continue to be available (for the
	  time being) as old_stat, old_fstat, and old_lstat.

	  WARNING: If you plan on re-compiling glibc-2.1 with this
	  kernel you MUST update syscalls.list first by applying this
	  patch (WARNING^2: I didn't test this glibc patch, but you
	  get the idea...).

--- sysdeps/unix/sysv/linux/ia64/syscalls.list~	Tue May  9 17:59:12 2000
+++ sysdeps/unix/sysv/linux/ia64/syscalls.list	Mon Jun 19 20:55:36 2000
@@ -72,11 +72,11 @@
 s_getdents	getdents getdents	3	__syscall_getdents	getdents
 
 # System calls with wrappers.
-sys_fstat	fxstat	fstat		2	__syscall_fstat
-sys_lstat	lxstat	lstat		2	__syscall_lstat
+sys_fstat	fxstat	old_fstat	2	__syscall_fstat
+sys_lstat	lxstat	old_lstat	2	__syscall_lstat
 sys_mknod	xmknod	mknod		3	__syscall_mknod
 sys_readv	readv	readv		3	__syscall_readv
-sys_stat	xstat	stat		2	__syscall_stat
+sys_stat	xstat	old_stat	2	__syscall_stat
 sys_writev	writev	writev		3	__syscall_writev
 s_getpagesize	getpagesize getpagesize	0	__syscall_getpagesize
 s_poll		poll	poll		3	__syscall_poll

OK, having said that, what else's new since last patch:

 - Completed unwind functionality.  I don't think things are final
   yet, but the last missing piece, core-dump support, hs been added
   now, so the new unwind support should now be functionally complete.
   On a kernel panic, you should now get a call trace in addition to
   the register dump.  That's the theory at least, as I haven't been
   able to test it out yet.  There are still some unwind related bugs
   in the toolchain, so I'd recommend not to turn on
   CONFIG_IA64_NEW_UNWIND unless you're willing to live dangerously...

 - Make the Alt DTLB handler work again for speculative faults (they
   always get NaT'ted now).

 - Most of Asit's patch: updates for IA-32 emulation, send_sig_info ->
   force_sig_info fixes, and the SMP ptc.g workaround fix.

 - Goutham's PCI DMA fix.

 - Fix Rules.make so the integer division routines don't get
   recompile all the time.

 - Add missing #include <linux/init.h> to hpsim_irq.c.  This
   should make things build for the HP simulator again.

 - mmap() is now supposed to return EINVAL when attempting to map into
   or across the address space hole in the middle of the region (also
   untested so far).

I tested this patch (with kdb patch applied) on a 4-way Lion, 1-way
Big Sur and the HP simulator.  Some known problems:

 - "make -j" seems to reliably lock up the kernel (the system doesn't
   freeze, you can still get into kdb, but the processes don't seem
   to be making forward progress anymore)

 - there are still occasionaly random user-level deaths (usually in
   the compiler); anyone who finds a half-way reproducible test case:
   please let me know (I'm currently working with the gcc test case
   that Richard found, but a simpler test-case would be very helpful)

As usual, the patch can be found at:

 ftp://ftp.kernel.org/pub/linux/kernel/ports/ia64

Look for file linux-2.4.0-test1-ia64-000621.diff*

Enjoy,

	--david

diff -urN linux-davidm/Rules.make linux-2.4.0-test1-lia/Rules.make
--- linux-davidm/Rules.make	Thu Mar 30 16:56:04 2000
+++ linux-2.4.0-test1-lia/Rules.make	Wed Jun 21 16:23:36 2000
@@ -291,9 +291,12 @@
 	))
 
 # A kludge: .S files don't get flag dependencies (yet),
-#   because that will involve changing a lot of Makefiles.
+#   because that will involve changing a lot of Makefiles.  Also
+#   suppress object files explicitly listed in $(IGNORE_FLAGS_OBJS).
+#   This allows handling of assembly files that get translated into
+#   multiple object files (see arch/ia64/lib/idiv.S, for example).
 FILES_FLAGS_CHANGED := $(strip \
-    $(filter-out $(patsubst %.S, %.o, $(wildcard *.S)), \
+    $(filter-out $(patsubst %.S, %.o, $(wildcard *.S) $(IGNORE_FLAGS_OBJS)), \
     $(FILES_FLAGS_CHANGED)))
 
 ifneq ($(FILES_FLAGS_CHANGED),)
diff -urN linux-davidm/arch/ia64/hp/hpsim_irq.c \
                linux-2.4.0-test1-lia/arch/ia64/hp/hpsim_irq.c
--- linux-davidm/arch/ia64/hp/hpsim_irq.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/hp/hpsim_irq.c	Wed Jun 21 16:23:54 2000
@@ -5,6 +5,7 @@
  * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/irq.h>
diff -urN linux-davidm/arch/ia64/ia32/binfmt_elf32.c \
                linux-2.4.0-test1-lia/arch/ia64/ia32/binfmt_elf32.c
--- linux-davidm/arch/ia64/ia32/binfmt_elf32.c	Fri Apr 21 15:21:23 2000
+++ linux-2.4.0-test1-lia/arch/ia64/ia32/binfmt_elf32.c	Wed Jun 21 16:24:10 2000
@@ -2,6 +2,8 @@
  * IA-32 ELF support.
  *
  * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
+ *
+ * 06/16/00	A. Mallick	initialize csd/ssd/tssd/cflg for ia32_load_state
  */
 #include <linux/config.h>
 #include <linux/posix_types.h>
@@ -84,6 +86,15 @@
 
 	current->thread.map_base = 0x40000000;
 
+ 
+	/* setup ia32 state for ia32_load_state */
+
+	current->thread.eflag = IA32_EFLAG;
+	current->thread.csd = IA64_SEG_DESCRIPTOR(0L, 0xFFFFFL, 0xBL, 1L, 3L, 1L, 1L, 1L);
+	current->thread.ssd = IA64_SEG_DESCRIPTOR(0L, 0xFFFFFL, 0x3L, 1L, 3L, 1L, 1L, 1L);
+	current->thread.tssd = IA64_SEG_DESCRIPTOR(IA32_PAGE_OFFSET + PAGE_SIZE, 0x1FFFL, \
0xBL, +						   1L, 3L, 1L, 1L, 1L);
+
 	/* CS descriptor */
 	__asm__("mov ar.csd = %0" : /* no outputs */
 		: "r" IA64_SEG_DESCRIPTOR(0L, 0xFFFFFL, 0xBL, 1L,
@@ -96,9 +107,6 @@
 	__asm__("mov ar.eflag = %0" : /* no outputs */ : "r" (IA32_EFLAG));
 
 	/* Control registers */
-	__asm__("mov ar.cflg = %0"
-		: /* no outputs */
-		: "r" (((ulong) IA32_CR4 << 32) | IA32_CR0));
 	__asm__("mov ar.fsr = %0"
 		: /* no outputs */
 		: "r" ((ulong)IA32_FSR_DEFAULT));
diff -urN linux-davidm/arch/ia64/ia32/ia32_entry.S \
                linux-2.4.0-test1-lia/arch/ia64/ia32/ia32_entry.S
--- linux-davidm/arch/ia64/ia32/ia32_entry.S	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/ia32/ia32_entry.S	Wed Jun 21 16:24:27 2000
@@ -41,7 +41,7 @@
 	.previous
 
 GLOBAL_ENTRY(ia32_ret_from_syscall)
-	PT_REGS_UNWIND_INFO
+	PT_REGS_UNWIND_INFO(0)
 
 	cmp.ge p6,p7=r8,r0                      // syscall executed successfully?
 	adds r2=IA64_PT_REGS_R8_OFFSET+16,sp    // r2 = &pt_regs.r8
@@ -61,7 +61,7 @@
 	//	b6  = syscall entry point
 	//
 GLOBAL_ENTRY(ia32_trace_syscall)
-	PT_REGS_UNWIND_INFO
+	PT_REGS_UNWIND_INFO(0)
 	br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch syscall \
                args
 .Lret4:	br.call.sptk.few rp=b6			// do the syscall
 .Lret5:	cmp.lt p6,p0=r8,r0			// syscall failed?
diff -urN linux-davidm/arch/ia64/ia32/ia32_signal.c \
                linux-2.4.0-test1-lia/arch/ia64/ia32/ia32_signal.c
--- linux-davidm/arch/ia64/ia32/ia32_signal.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/ia32/ia32_signal.c	Wed Jun 21 16:24:46 2000
@@ -104,6 +104,7 @@
                 struct pt_regs *regs, unsigned long mask)
 {
        int  err = 0;
+       unsigned long flag;
 
        err |= __put_user((regs->r16 >> 32) & 0xffff , (unsigned int *)&sc->fs);
        err |= __put_user((regs->r16 >> 48) & 0xffff , (unsigned int *)&sc->gs);
@@ -124,9 +125,11 @@
 #endif
        err |= __put_user(regs->cr_iip, &sc->eip);
        err |= __put_user(regs->r17 & 0xffff, (unsigned int *)&sc->cs);
-#if 0
-       err |= __put_user(regs->eflags, &sc->eflags);
-#endif
+       /*
+	*  `eflags' is in an ar register for this context
+	*/
+       asm volatile ("mov %0=ar.eflag ;;" : "=r"(flag));
+       err |= __put_user((unsigned int)flag, &sc->eflags);
        
        err |= __put_user(regs->r12, &sc->esp_at_signal);
        err |= __put_user((regs->r17 >> 16) & 0xffff, (unsigned int *)&sc->ss);
@@ -190,15 +193,26 @@
        COPY(cr_iip, eip);
        COPY_SEG_STRICT(cs);
        COPY_SEG_STRICT(ss);
-#if 0
        {
-               unsigned int tmpflags;
-               err |= __get_user(tmpflags, &sc->eflags);
-               /* XXX: Change this to ar.eflags */
-               regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
-               regs->orig_eax = -1;            /* disable syscall checks */
+		unsigned int tmpflags;
+		unsigned long flag;
+
+		/*
+		 *  IA32 `eflags' is not part of `pt_regs', it's
+		 *  in an ar register which is part of the thread
+		 *  context.  Fortunately, we are executing in the
+		 *  IA32 process's context.
+		 */
+		err |= __get_user(tmpflags, &sc->eflags);
+		asm volatile ("mov %0=ar.eflag ;;" : "=r"(flag));
+		flag &= ~0x40DD5;
+		flag |= (tmpflags & 0x40DD5);
+		asm volatile ("mov ar.eflag=%0 ;;" :: "r"(flag));
+
+		regs->r1 = -1;	/* disable syscall checks, r1 is orig_eax */
        }
 
+#if 0
        {
                struct _fpstate * buf;
                err |= __get_user(buf, &sc->fpstate);
diff -urN linux-davidm/arch/ia64/ia32/ia32_support.c \
                linux-2.4.0-test1-lia/arch/ia64/ia32/ia32_support.c
--- linux-davidm/arch/ia64/ia32/ia32_support.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/ia32/ia32_support.c	Wed Jun 21 16:25:02 2000
@@ -1,6 +1,9 @@
 /*
  * IA32 helper functions
+ *
+ * 06/16/00	A. Mallick	added csd/ssd/tssd for ia32 thread context
  */
+
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mm.h>
@@ -19,38 +22,52 @@
 void
 ia32_save_state (struct thread_struct *thread)
 {
-	unsigned long eflag, fsr, fcr, fir, fdr;
+	unsigned long eflag, fsr, fcr, fir, fdr, csd, ssd, tssd;
 
 	asm ("mov %0=ar.eflag;"
 	     "mov %1=ar.fsr;"
 	     "mov %2=ar.fcr;"
 	     "mov %3=ar.fir;"
-	     "mov %4=ar.fdr"
-	     : "=r"(eflag), "=r"(fsr), "=r"(fcr), "=r"(fir), "=r"(fdr));
+	     "mov %4=ar.fdr;"
+	     "mov %5=ar.csd;"
+	     "mov %6=ar.ssd;"
+	     "mov %7=ar.k1"
+	     : "=r"(eflag), "=r"(fsr), "=r"(fcr), "=r"(fir), "=r"(fdr),
+	       "=r"(csd), "=r"(ssd), "=r"(tssd));
 	thread->eflag = eflag;
 	thread->fsr = fsr;
 	thread->fcr = fcr;
 	thread->fir = fir;
 	thread->fdr = fdr;
+	thread->csd = csd;
+	thread->ssd = ssd;
+	thread->tssd = tssd;
 }
 
 void
 ia32_load_state (struct thread_struct *thread)
 {
-	unsigned long eflag, fsr, fcr, fir, fdr;
+	unsigned long eflag, fsr, fcr, fir, fdr, csd, ssd, tssd;
 
 	eflag = thread->eflag;
 	fsr = thread->fsr;
 	fcr = thread->fcr;
 	fir = thread->fir;
 	fdr = thread->fdr;
+	csd = thread->csd;
+	ssd = thread->ssd;
+	tssd = thread->tssd;
 
 	asm volatile ("mov ar.eflag=%0;"
 		      "mov ar.fsr=%1;"
 		      "mov ar.fcr=%2;"
 		      "mov ar.fir=%3;"
-		      "mov ar.fdr=%4"
-		      :: "r"(eflag), "r"(fsr), "r"(fcr), "r"(fir), "r"(fdr));
+		      "mov ar.fdr=%4;"
+		      "mov ar.csd=%5;"
+		      "mov ar.ssd=%6;"
+		      "mov ar.k1=%7"
+		      :: "r"(eflag), "r"(fsr), "r"(fcr), "r"(fir), "r"(fdr),
+		         "r"(csd), "r"(ssd), "r"(tssd));
 }
 
 /*
diff -urN linux-davidm/arch/ia64/ia32/ia32_traps.c \
                linux-2.4.0-test1-lia/arch/ia64/ia32/ia32_traps.c
--- linux-davidm/arch/ia64/ia32/ia32_traps.c	Fri Apr 21 15:21:23 2000
+++ linux-2.4.0-test1-lia/arch/ia64/ia32/ia32_traps.c	Wed Jun 21 16:25:14 2000
@@ -1,3 +1,9 @@
+/*
+ * IA32 exceptions handler
+ *
+ * 06/16/00	A. Mallick	added siginfo for most cases (close to IA32)
+ */
+
 #include <linux/kernel.h>
 #include <linux/sched.h>
 
@@ -9,9 +15,11 @@
 {
 	struct siginfo siginfo;
 
+	siginfo.si_errno = 0;
 	switch ((isr >> 16) & 0xff) {
 	      case 1:
 	      case 2:
+		siginfo.si_signo = SIGTRAP;
 		if (isr == 0)
 			siginfo.si_code = TRAP_TRACE;
 		else if (isr & 0x4)
@@ -21,27 +29,96 @@
 		break;
 
 	      case 3:
+		siginfo.si_signo = SIGTRAP;
 		siginfo.si_code = TRAP_BRKPT;
 		break;
 
 	      case 0:	/* Divide fault */
+		siginfo.si_signo = SIGFPE;
+		siginfo.si_code = FPE_INTDIV;
+		break;
+
 	      case 4:	/* Overflow */
 	      case 5:	/* Bounds fault */
+		siginfo.si_signo = SIGFPE;
+		siginfo.si_code = 0;
+		break;
+
 	      case 6:	/* Invalid Op-code */
+		siginfo.si_signo = SIGILL;
+		siginfo.si_code = ILL_ILLOPN;
+		break;
+
 	      case 7:	/* FP DNA */
 	      case 8:	/* Double Fault */
 	      case 9:	/* Invalid TSS */
 	      case 11:	/* Segment not present */
 	      case 12:	/* Stack fault */
 	      case 13:	/* General Protection Fault */
+		siginfo.si_signo = SIGSEGV;
+		siginfo.si_code = 0;
+		break;
+
 	      case 16:	/* Pending FP error */
+		{
+			unsigned long fsr, fcr;
+
+			asm ("mov %0=ar.fsr;"
+			     "mov %1=ar.fcr;"
+			     : "=r"(fsr), "=r"(fcr));
+
+			siginfo.si_signo = SIGFPE;
+			/*
+			 * (~cwd & swd) will mask out exceptions that are not set to unmasked
+			 * status.  0x3f is the exception bits in these regs, 0x200 is the
+			 * C1 reg you need in case of a stack fault, 0x040 is the stack
+			 * fault bit.  We should only be taking one exception at a time,
+			 * so if this combination doesn't produce any single exception,
+			 * then we have a bad program that isn't syncronizing its FPU usage
+			 * and it will suffer the consequences since we won't be able to
+			 * fully reproduce the context of the exception
+			 */
+			switch(((~fcr) & (fsr & 0x3f)) | (fsr & 0x240)) {
+				case 0x000:
+				default:
+					siginfo.si_code = 0;
+					break;
+				case 0x001: /* Invalid Op */
+				case 0x040: /* Stack Fault */
+				case 0x240: /* Stack Fault | Direction */
+					siginfo.si_code = FPE_FLTINV;
+					break;
+				case 0x002: /* Denormalize */
+				case 0x010: /* Underflow */
+					siginfo.si_code = FPE_FLTUND;
+					break;
+				case 0x004: /* Zero Divide */
+					siginfo.si_code = FPE_FLTDIV;
+					break;
+				case 0x008: /* Overflow */
+					siginfo.si_code = FPE_FLTOVF;
+					break;
+				case 0x020: /* Precision */
+					siginfo.si_code = FPE_FLTRES;
+					break;
+			}
+
+			break;
+		}
+
 	      case 17:	/* Alignment check */
+		siginfo.si_signo = SIGSEGV;
+		siginfo.si_code = BUS_ADRALN;
+		break;
+
 	      case 19:	/* SSE Numeric error */
+		siginfo.si_signo = SIGFPE;
+		siginfo.si_code = 0;
+		break;
+
 	      default:
 		return -1;
 	}
-	siginfo.si_signo = SIGTRAP;
-	siginfo.si_errno = 0;
-	send_sig_info(SIGTRAP, &siginfo, current);
+	force_sig_info(SIGTRAP, &siginfo, current);
 	return 0;
 }
diff -urN linux-davidm/arch/ia64/kernel/efi.c \
                linux-2.4.0-test1-lia/arch/ia64/kernel/efi.c
--- linux-davidm/arch/ia64/kernel/efi.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/efi.c	Wed Jun 21 16:27:14 2000
@@ -14,6 +14,9 @@
  * in a future version.  --drummond 1999-07-20
  *
  * Implemented EFI runtime services and virtual mode calls.  --davidm
+ *
+ * Goutham Rao: <goutham.rao@intel.com>
+ * 	Skip non-WB memory and ignore empty memory ranges.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -170,6 +173,14 @@
 				printk("Warning: ignoring %luMB of memory above 1GB!\n",
 				       md->num_pages >> 8);
 				md->type = EFI_UNUSABLE_MEMORY;
+				continue;
+			}
+
+			if (!(md->attribute & EFI_MEMORY_WB))
+				continue;
+			if (md->num_pages == 0) {
+				printk("efi_memmap_walk: ignoring empty region at 0x%lx",
+				       md->phys_addr);
 				continue;
 			}
 
diff -urN linux-davidm/arch/ia64/kernel/entry.S \
                linux-2.4.0-test1-lia/arch/ia64/kernel/entry.S
--- linux-davidm/arch/ia64/kernel/entry.S	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/entry.S	Wed Jun 21 21:41:21 2000
@@ -413,7 +413,7 @@
 
 GLOBAL_ENTRY(ia64_strace_clear_r8)
 	// this is where we return after cloning when PF_TRACESYS is on
-	PT_REGS_UNWIND_INFO
+	PT_REGS_UNWIND_INFO(0)
 # ifdef CONFIG_SMP
 	br.call.sptk.few rp=invoke_schedule_tail
 # endif
@@ -422,7 +422,7 @@
 END(ia64_strace_clear_r8)
 
 ENTRY(ia64_trace_syscall)
-	PT_REGS_UNWIND_INFO
+	PT_REGS_UNWIND_INFO(0)
 	br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch syscall \
                args
 .ret4:	br.call.sptk.few rp=b6			// do the syscall
 strace_check_retval:
@@ -469,7 +469,7 @@
 #define rB6		r21
 
 GLOBAL_ENTRY(ia64_ret_from_syscall_clear_r8)
-	PT_REGS_UNWIND_INFO
+	PT_REGS_UNWIND_INFO(0)
 #ifdef CONFIG_SMP
 	// In SMP mode, we need to call schedule_tail to complete the scheduling process.
 	// Called by ia64_switch_to after do_fork()->copy_thread().  r8 contains the
@@ -482,7 +482,7 @@
 END(ia64_ret_from_syscall_clear_r8)
 	// fall through
 GLOBAL_ENTRY(ia64_ret_from_syscall)
-	PT_REGS_UNWIND_INFO
+	PT_REGS_UNWIND_INFO(0)
 	cmp.ge p6,p7=r8,r0			// syscall executed successfully?
 	adds r2=IA64_PT_REGS_R8_OFFSET+16,sp	// r2 = &pt_regs.r8
 	adds r3=IA64_PT_REGS_R8_OFFSET+32,sp	// r3 = &pt_regs.r10
@@ -497,7 +497,7 @@
 GLOBAL_ENTRY(ia64_leave_kernel)
 	// check & deliver software interrupts:
 
-	PT_REGS_UNWIND_INFO
+	PT_REGS_UNWIND_INFO(0)
 #ifdef CONFIG_SMP
 	adds r2=IA64_TASK_PROCESSOR_OFFSET,r13
 	movl r3=softirq_state
@@ -721,7 +721,7 @@
 	 * If pt_regs.r8 is zero, we assume that the call completed
 	 * successfully.
 	 */
-	PT_REGS_UNWIND_INFO
+	PT_REGS_UNWIND_INFO(0)
 	ld8 r3=[r2]		// load pt_regs.r8
 	sub r9=0,r8		// negate return value to get errno
 	;;
@@ -819,7 +819,6 @@
 	alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall \
restart!  mov r9=ar.unat
 	mov loc0=rp				// save return address
-	.body
 	mov out0=0				// there is no "oldset"
 	adds out1=0,sp				// out1=&sigscratch
 (pSys)	mov out2=1				// out2==1 => we're in a syscall
@@ -828,6 +827,7 @@
 	.fframe 16
 	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)
 	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
+	.body
 	br.call.sptk.few rp=ia64_do_signal
 .ret11:
 	.restore sp
@@ -903,7 +903,7 @@
 ENTRY(sys_rt_sigreturn)
 #ifdef CONFIG_IA64_NEW_UNWIND
 	.regstk 0,0,3,0	// inherited from gate.s:invoke_sighandler()
-	PT_REGS_UNWIND_INFO
+	PT_REGS_UNWIND_INFO(0)
 	.prologue
 	PT_REGS_SAVES(16)
 	adds sp=-16,sp
@@ -914,7 +914,7 @@
 	br.call.sptk.few rp=ia64_rt_sigreturn
 .ret13:
 	adds sp=16,sp		// doesn't drop pt_regs, so don't mark it as restoring sp!
-	PT_REGS_UNWIND_INFO	// instead, create a new body section with the smaller frame
+	PT_REGS_UNWIND_INFO(0)	// instead, create a new body section with the smaller frame
 	;;
 	ld8 r9=[sp]				// load new ar.unat
 	mov b7=r8
@@ -923,7 +923,7 @@
 	br b7
 #else /* !CONFIG_IA64_NEW_UNWIND */
 	.regstk 0,0,3,0	// inherited from gate.s:invoke_sighandler()
-	PT_REGS_UNWIND_INFO
+	PT_REGS_UNWIND_INFO(0)
 	UNW(.prologue)
 	UNW(.fframe IA64_PT_REGS_SIZE+IA64_SWITCH_STACK_SIZE)
 	UNW(.spillsp rp, PT(CR_IIP)+IA64_SWITCH_STACK_SIZE)
@@ -943,7 +943,7 @@
 	ld8 r9=[r3]			// load new ar.unat
 	mov b7=r8
 	;;
-	PT_REGS_UNWIND_INFO
+	PT_REGS_UNWIND_INFO(0)
 	adds sp=IA64_SWITCH_STACK_SIZE,sp	// drop (dummy) switch-stack frame
 	mov ar.unat=r9
 	br b7
@@ -955,15 +955,64 @@
 	// r16 = fake ar.pfs, we simply need to make sure 
 	// privilege is still 0
 	//
-	PT_REGS_UNWIND_INFO
+	PT_REGS_UNWIND_INFO(0)
 	mov r16=r0 				
 	DO_SAVE_SWITCH_STACK
 	br.call.sptk.few rp=ia64_handle_unaligned // stack frame setup in ivt
 .ret14:
-	DO_LOAD_SWITCH_STACK(PT_REGS_UNWIND_INFO)
+	DO_LOAD_SWITCH_STACK(PT_REGS_UNWIND_INFO(0))
 	br.cond.sptk.many rp			  // goes to ia64_leave_kernel
 END(ia64_prepare_handle_unaligned)
 
+#ifdef CONFIG_IA64_NEW_UNWIND
+
+	//
+	// unw_init_running(void (*callback)(info, arg), void *arg)
+	//
+#	define EXTRA_FRAME_SIZE	((UNW_FRAME_INFO_SIZE+15)&~15)
+
+GLOBAL_ENTRY(unw_init_running)
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
+	alloc loc1=ar.pfs,2,3,3,0
+	;;
+	ld8 loc2=[in0],8
+	mov loc0=rp
+	mov r16=loc1
+	DO_SAVE_SWITCH_STACK
+	.body
+
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
+	.fframe IA64_SWITCH_STACK_SIZE+EXTRA_FRAME_SIZE
+	SWITCH_STACK_SAVES(EXTRA_FRAME_SIZE)
+	adds sp=-EXTRA_FRAME_SIZE,sp
+	.body
+	;;
+	adds out0=16,sp				// &info
+	mov out1=r13				// current
+	adds out2=16+EXTRA_FRAME_SIZE,sp	// &switch_stack
+	br.call.sptk.few rp=unw_init_frame_info
+1:	adds out0=16,sp				// &info
+	mov b6=loc2
+	mov loc2=gp				// save gp across indirect function call
+	;;
+	ld8 gp=[in0]
+	mov out1=in1				// arg
+	br.call.sptk.few rp=b6			// invoke the callback function
+1:	mov gp=loc2				// restore gp
+
+	// For now, we don't allow changing registers from within
+	// unw_init_running; if we ever want to allow that, we'd
+	// have to do a load_switch_stack here:
+	.restore sp
+	adds sp=IA64_SWITCH_STACK_SIZE+EXTRA_FRAME_SIZE,sp
+
+	mov ar.pfs=loc1
+	mov rp=loc0
+	br.ret.sptk.many rp
+END(unw_init_running)
+
+#endif
+
 	.rodata
 	.align 8
 	.globl sys_call_table
@@ -1064,9 +1113,9 @@
 	data8 sys_syslog
 	data8 sys_setitimer
 	data8 sys_getitimer
-	data8 sys_newstat			// 1120
-	data8 sys_newlstat
-	data8 sys_newfstat
+	data8 ia64_oldstat			// 1120
+	data8 ia64_oldlstat
+	data8 ia64_oldfstat
 	data8 sys_vhangup
 	data8 sys_lchown
 	data8 sys_vm86				// 1125
@@ -1154,9 +1203,9 @@
 	data8 sys_pivot_root
 	data8 sys_mincore
 	data8 sys_madvise
-	data8 ia64_ni_syscall			// 1210
-	data8 ia64_ni_syscall
-	data8 ia64_ni_syscall
+	data8 sys_newstat			// 1210
+	data8 sys_newlstat
+	data8 sys_newfstat
 	data8 ia64_ni_syscall
 	data8 ia64_ni_syscall
 	data8 ia64_ni_syscall			// 1215
diff -urN linux-davidm/arch/ia64/kernel/entry.h \
                linux-2.4.0-test1-lia/arch/ia64/kernel/entry.h
--- linux-davidm/arch/ia64/kernel/entry.h	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/entry.h	Wed Jun 21 21:41:45 2000
@@ -9,37 +9,41 @@
 #define PT(f)		(IA64_PT_REGS_##f##_OFFSET + 16)
 #define SW(f)		(IA64_SWITCH_STACK_##f##_OFFSET + 16)
 
-#define PT_REGS_UNWIND_INFO			\
+#define PT_REGS_SAVES(off)				\
+	UNW(.unwabi @svr4, 'i');			\
+	UNW(.fframe IA64_PT_REGS_SIZE+16+(off));	\
+	UNW(.spillsp rp, PT(CR_IIP)+(off));		\
+	UNW(.spillsp ar.pfs, PT(CR_IFS)+(off));		\
+	UNW(.spillsp ar.unat, PT(AR_UNAT)+(off));	\
+	UNW(.spillsp ar.fpsr, PT(AR_FPSR)+(off));	\
+	UNW(.spillsp pr, PT(PR)+(off));
+
+#define PT_REGS_UNWIND_INFO(off)		\
 	UNW(.prologue);				\
-	UNW(.unwabi @svr4, 'i');		\
-	UNW(.fframe IA64_PT_REGS_SIZE+16);	\
-	UNW(.spillsp rp, PT(CR_IIP));		\
-	UNW(.spillsp ar.pfs, PT(CR_IFS));	\
-	UNW(.spillsp ar.unat, PT(AR_UNAT));	\
-	UNW(.spillsp pr, PT(PR));		\
+	PT_REGS_SAVES(off);			\
 	UNW(.body)
 
-#define SAVE_SWITCH_STACK_UNWIND_INFO							\
-	.savesp ar.unat,SW(CALLER_UNAT); .savesp ar.fpsr,SW(AR_FPSR));			\
-	UNW(.spillsp f2,SW(F2)); UNW(.spillsp f3,SW(F3));				\
-	UNW(.spillsp f4,SW(F4)); UNW(.spillsp f5,SW(F5));				\
-	UNW(.spillsp f16,SW(F16)); UNW(.spillsp f17,SW(F17));				\
-	UNW(.spillsp f18,SW(F18)); UNW(.spillsp f19,SW(F19));				\
-	UNW(.spillsp f20,SW(F20)); UNW(.spillsp f21,SW(F21));				\
-	UNW(.spillsp f22,SW(F22)); UNW(.spillsp f23,SW(F23));				\
-	UNW(.spillsp f24,SW(F24)); UNW(.spillsp f25,SW(F25));				\
-	UNW(.spillsp f26,SW(F26)); UNW(.spillsp f27,SW(F27));				\
-	UNW(.spillsp f28,SW(F28)); UNW(.spillsp f29,SW(F29));				\
-	UNW(.spillsp f30,SW(F30)); UNW(.spillsp f31,SW(F31));				\
-	UNW(.spillsp r4,SW(R4)); UNW(.spillsp r5,SW(R5));				\
-	UNW(.spillsp r6,SW(R6)); UNW(.spillsp r7,SW(R7));				\
-	UNW(.spillsp b1,SW(B1)); UNW(.spillsp b2,SW(B2));				\
-	UNW(.spillsp b3,SW(B3)); UNW(.spillsp b4,SW(B4));				\
-	UNW(.spillsp b5,SW(B5));							\
-	UNW(.spillsp ar.pfs,SW(AR_PFS)); UNW(.spillsp ar.lc,SW(AR_LC));			\
-	UNW(.spillsp @priunat,SW(AR_UNAT));						\
-	UNW(.spillsp ar.rnat,SW(AR_RNAT)); UNW(.spillsp ar.bspstore,SW(AR_BSPSTORE));	\
-	UNW(.spillsp pr,SW(PR))
+#define SWITCH_STACK_SAVES(off)									  \
+	UNW(.savesp ar.unat,SW(CALLER_UNAT)+(off)); UNW(.savesp \
ar.fpsr,SW(AR_FPSR)+(off));	  \ +	UNW(.spillsp f2,SW(F2)+(off)); UNW(.spillsp \
f3,SW(F3)+(off));				  \ +	UNW(.spillsp f4,SW(F4)+(off)); UNW(.spillsp \
f5,SW(F5)+(off));				  \ +	UNW(.spillsp f16,SW(F16)+(off)); UNW(.spillsp \
f17,SW(F17)+(off));			  \ +	UNW(.spillsp f18,SW(F18)+(off)); UNW(.spillsp \
f19,SW(F19)+(off));			  \ +	UNW(.spillsp f20,SW(F20)+(off)); UNW(.spillsp \
f21,SW(F21)+(off));			  \ +	UNW(.spillsp f22,SW(F22)+(off)); UNW(.spillsp \
f23,SW(F23)+(off));			  \ +	UNW(.spillsp f24,SW(F24)+(off)); UNW(.spillsp \
f25,SW(F25)+(off));			  \ +	UNW(.spillsp f26,SW(F26)+(off)); UNW(.spillsp \
f27,SW(F27)+(off));			  \ +	UNW(.spillsp f28,SW(F28)+(off)); UNW(.spillsp \
f29,SW(F29)+(off));			  \ +	UNW(.spillsp f30,SW(F30)+(off)); UNW(.spillsp \
f31,SW(F31)+(off));			  \ +	UNW(.spillsp r4,SW(R4)+(off)); UNW(.spillsp \
r5,SW(R5)+(off));				  \ +	UNW(.spillsp r6,SW(R6)+(off)); UNW(.spillsp \
r7,SW(R7)+(off));				  \ +	UNW(.spillsp b0,SW(B0)+(off)); UNW(.spillsp \
b1,SW(B1)+(off));				  \ +	UNW(.spillsp b2,SW(B2)+(off)); UNW(.spillsp \
b3,SW(B3)+(off));				  \ +	UNW(.spillsp b4,SW(B4)+(off)); UNW(.spillsp \
b5,SW(B5)+(off));				  \ +	UNW(.spillsp ar.pfs,SW(AR_PFS)+(off)); UNW(.spillsp \
ar.lc,SW(AR_LC)+(off));		  \ +	UNW(.spillsp @priunat,SW(AR_UNAT)+(off));						  \
+	UNW(.spillsp ar.rnat,SW(AR_RNAT)+(off)); UNW(.spillsp \
ar.bspstore,SW(AR_BSPSTORE)+(off)); \ +	UNW(.spillsp pr,SW(PR)+(off))
 
 #define DO_SAVE_SWITCH_STACK			\
 	movl r28=1f;				\
@@ -47,7 +51,7 @@
 	.fframe IA64_SWITCH_STACK_SIZE;		\
 	adds sp=-IA64_SWITCH_STACK_SIZE,sp;	\
 	mov b7=r28;				\
-	SAVE_SWITCH_STACK_UNWIND_INFO;		\
+	SWITCH_STACK_SAVES(0);			\
 	br.cond.sptk.many save_switch_stack;	\
 1:
 
diff -urN linux-davidm/arch/ia64/kernel/head.S \
                linux-2.4.0-test1-lia/arch/ia64/kernel/head.S
--- linux-davidm/arch/ia64/kernel/head.S	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/head.S	Wed Jun 21 21:41:55 2000
@@ -60,7 +60,7 @@
 	UNW(.prologue)
 	UNW(.save rp, r4)		// terminate unwind chain with a NULL rp
 	UNW(mov r4=r0)
-	.body
+	UNW(.body)
 	// set IVT entry point---can't access I/O ports without it
 	movl r3=ia64_ivt
 	;;
diff -urN linux-davidm/arch/ia64/kernel/irq.c \
                linux-2.4.0-test1-lia/arch/ia64/kernel/irq.c
--- linux-davidm/arch/ia64/kernel/irq.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/irq.c	Wed Jun 21 21:42:11 2000
@@ -201,10 +201,14 @@
 		printk(" %d",local_bh_count(i));
 
 	printk(" ]\nStack dumps:");
-#ifdef __ia64__
-	printk(" ]\nStack dumps: <unimplemented on IA-64---please fix me>");
-	/* for now we don't have stack dumping support... */
-#elif __i386__
+#if defined(__ia64__)
+	/*
+	 * We can't unwind the stack of another CPU without access to
+	 * the registers of that CPU.  And sending an IPI when we're
+	 * in a potentially wedged state doesn't sound like a smart
+	 * idea.
+	 */
+#elif defined(__i386__)
 	for(i=0;i< smp_num_cpus;i++) {
 		unsigned long esp;
 		if(i==cpu)
@@ -227,9 +231,7 @@
 	You lose...
 #endif
 	printk("\nCPU %d:",cpu);
-#ifdef __i386__
 	show_stack(NULL);
-#endif
 	printk("\n");
 }
 	
diff -urN linux-davidm/arch/ia64/kernel/ivt.S \
                linux-2.4.0-test1-lia/arch/ia64/kernel/ivt.S
--- linux-davidm/arch/ia64/kernel/ivt.S	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/ivt.S	Wed Jun 21 21:55:57 2000
@@ -339,6 +339,7 @@
 	shr.u r18=r16,57	// move address bit 61 to bit 4
 	dep r16=0,r16,IA64_MAX_PHYS_BITS,(64-IA64_MAX_PHYS_BITS) // clear ed & reserved \
bits  ;;
+	dep r21=-1,r21,IA64_PSR_ED_BIT,1
 	andcm r18=0x10,r18	// bit 4=~address-bit(61)
 	dep r16=r17,r16,0,12	// insert PTE control bits into r16
 	;;
diff -urN linux-davidm/arch/ia64/kernel/pal.S \
                linux-2.4.0-test1-lia/arch/ia64/kernel/pal.S
--- linux-davidm/arch/ia64/kernel/pal.S	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/pal.S	Wed Jun 21 21:42:38 2000
@@ -59,31 +59,31 @@
  */
 GLOBAL_ENTRY(ia64_pal_call_static)
 	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6))
-	alloc	loc1 = ar.pfs,6,90,0,0
-	movl	loc2 = pal_entry_point
+	alloc loc1 = ar.pfs,6,90,0,0
+	movl loc2 = pal_entry_point
 1:	{
-	  mov	r28 = in0
-	  mov	r29 = in1
-	  mov	r8 = ip
+	  mov r28 = in0
+	  mov r29 = in1
+	  mov r8 = ip
 	}
 	;;
-	ld8	loc2 = [loc2]		// loc2 <- entry point
-	mov	r30 = in2
-	mov	r31 = in3
-	;;
-	mov	loc3 = psr
-	mov	loc0 = rp
-	.body
-	adds	r8 = .ret0-1b,r8
+	ld8 loc2 = [loc2]		// loc2 <- entry point
+	mov r30 = in2
+	mov r31 = in3
+	;;
+	mov loc3 = psr
+	mov loc0 = rp
+	UNW(.body)
+	adds r8 = .ret0-1b,r8
 	;; 
-	rsm	psr.i
-	mov	b7 = loc2
-	mov	rp = r8
+	rsm psr.i
+	mov b7 = loc2
+	mov rp = r8
 	;; 
 	br.cond.sptk.few b7
-.ret0:	mov	psr.l = loc3
-	mov	ar.pfs = loc1
-	mov	rp = loc0
+.ret0:	mov psr.l = loc3
+	mov ar.pfs = loc1
+	mov rp = loc0
 	;;
 	srlz.d				// seralize restoration of psr.l
 	br.ret.sptk.few	b0
@@ -98,28 +98,28 @@
  */
 GLOBAL_ENTRY(ia64_pal_call_stacked)
 	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5))
-	alloc	loc1 = ar.pfs,5,4,87,0
-	movl	loc2 = pal_entry_point
+	alloc loc1 = ar.pfs,5,4,87,0
+	movl loc2 = pal_entry_point
 
-	mov	r28  = in0		// Index MUST be copied to r28
-	mov	out0 = in0		// AND in0 of PAL function
-	mov	loc0 = rp
-	.body
-	;;
-	ld8	loc2 = [loc2]		// loc2 <- entry point
-	mov	out1 = in1
-	mov	out2 = in2
-	mov	out3 = in3
-	mov	loc3 = psr
+	mov r28  = in0			// Index MUST be copied to r28
+	mov out0 = in0			// AND in0 of PAL function
+	mov loc0 = rp
+	UNW(.body)
+	;;
+	ld8 loc2 = [loc2]		// loc2 <- entry point
+	mov out1 = in1
+	mov out2 = in2
+	mov out3 = in3
+	mov loc3 = psr
 	;;
-	rsm	psr.i
-	mov	b7 = loc2
+	rsm psr.i
+	mov b7 = loc2
 	;; 
 	br.call.sptk.many rp=b7		// now make the call
 .ret2:
-	mov	psr.l  = loc3
-	mov	ar.pfs = loc1
-	mov	rp = loc0
+	mov psr.l  = loc3
+	mov ar.pfs = loc1
+	mov rp = loc0
 	;;
 	srlz.d				// serialize restoration of psr.l
 	br.ret.sptk.few	b0
@@ -140,28 +140,28 @@
 	 IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED |	\
 	 IA64_PSR_DFL | IA64_PSR_DFH)
 
-#define PAL_PSR_BITS_TO_SET							\
+#define PAL_PSR_BITS_TO_SET						\
 	(IA64_PSR_BN)
 
 
 GLOBAL_ENTRY(ia64_pal_call_phys_static)
 	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6))
-	alloc	loc1 = ar.pfs,6,90,0,0
-	movl	loc2 = pal_entry_point
+	alloc loc1 = ar.pfs,6,90,0,0
+	movl loc2 = pal_entry_point
 1:	{
-	  mov	r28  = in0		// copy procedure index
-	  mov	r8   = ip		// save ip to compute branch
-	  mov	loc0 = rp		// save rp
+	  mov r28  = in0		// copy procedure index
+	  mov r8   = ip			// save ip to compute branch
+	  mov loc0 = rp			// save rp
 	}
-	.body
+	UNW(.body)
 	;;
-	ld8	loc2 = [loc2]		// loc2 <- entry point
-	mov	r29  = in1		// first argument
-	mov	r30  = in2		// copy arg2
-	mov	r31  = in3		// copy arg3
+	ld8 loc2 = [loc2]		// loc2 <- entry point
+	mov r29  = in1			// first argument
+	mov r30  = in2			// copy arg2
+	mov r31  = in3			// copy arg3
 	;;
-	mov	loc3 = psr		// save psr
-	adds	r8   = .ret4-1b,r8	// calculate return address for call
+	mov loc3 = psr			// save psr
+	adds r8   = .ret4-1b,r8		// calculate return address for call
 	;; 
 	mov loc4=ar.rsc			// save RSE configuration
 	dep.z loc2=loc2,0,61		// convert pal entry point to physical
@@ -184,10 +184,10 @@
 	mov r16=loc3			// r16= original psr
 	br.call.sptk.few rp=ia64_switch_mode // return to virtual mode
 
-.ret5:	mov	psr.l = loc3		// restore init PSR
+.ret5:	mov psr.l = loc3		// restore init PSR
 
-	mov	ar.pfs = loc1
-	mov	rp = loc0
+	mov ar.pfs = loc1
+	mov rp = loc0
 	;;
 	mov ar.rsc=loc4			// restore RSE configuration
 	srlz.d				// seralize restoration of psr.l
diff -urN linux-davidm/arch/ia64/kernel/pci-dma.c \
                linux-2.4.0-test1-lia/arch/ia64/kernel/pci-dma.c
--- linux-davidm/arch/ia64/kernel/pci-dma.c	Mon Feb 14 15:34:21 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/pci-dma.c	Wed Jun 21 21:42:48 2000
@@ -23,8 +23,8 @@
 	void *ret;
 	int gfp = GFP_ATOMIC;
 
-	if (!hwdev || hwdev->dma_mask != 0xffffffff)
-		gfp |= GFP_DMA;
+	if (!hwdev || hwdev->dma_mask == 0xffffffff)
+		gfp |= GFP_DMA;	/* XXX fix me: should change this to GFP_32BIT or ZONE_32BIT */
 	ret = (void *)__get_free_pages(gfp, get_order(size));
 
 	if (ret) {
diff -urN linux-davidm/arch/ia64/kernel/pci.c \
                linux-2.4.0-test1-lia/arch/ia64/kernel/pci.c
--- linux-davidm/arch/ia64/kernel/pci.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/pci.c	Wed Jun 21 21:42:54 2000
@@ -133,7 +133,7 @@
  * Initialization. Uses the SAL interface
  */
 
-#define PCI_BUSSES_TO_SCAN 255
+#define PCI_BUSES_TO_SCAN 255
 
 void __init 
 pcibios_init(void)
@@ -147,7 +147,7 @@
 	}
 
 	printk("PCI: Probing PCI hardware\n");
-	for (i = 0; i < PCI_BUSSES_TO_SCAN; i++) 
+	for (i = 0; i < PCI_BUSES_TO_SCAN; i++) 
 		pci_scan_bus(i, ops, NULL);
 	platform_pci_fixup();
 	return;
diff -urN linux-davidm/arch/ia64/kernel/process.c \
                linux-2.4.0-test1-lia/arch/ia64/kernel/process.c
--- linux-davidm/arch/ia64/kernel/process.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/process.c	Wed Jun 21 21:56:11 2000
@@ -23,8 +23,40 @@
 #include <asm/processor.h>
 #include <asm/sal.h>
 #include <asm/uaccess.h>
+#include <asm/unwind.h>
 #include <asm/user.h>
 
+static void
+do_show_stack (struct unw_frame_info *info, void *arg)
+{
+	unsigned long ip, sp, bsp;
+
+	printk("\nCall Trace: ");
+	do {
+		unw_get_ip(info, &ip);
+		if (ip == 0)
+			break;
+
+		unw_get_sp(info, &sp);
+		unw_get_bsp(info, &bsp);
+		printk("[<%016lx>] sp=0x%016lx bsp=0x%016lx\n", ip, sp, bsp);
+	} while (unw_unwind(info) >= 0);
+}
+
+void
+show_stack (struct task_struct *task)
+{
+#ifdef CONFIG_IA64_NEW_UNWIND
+	if (!task)
+		unw_init_running(do_show_stack, 0);
+	else {
+		struct unw_frame_info info;
+
+		unw_init_from_blocked_task(&info, task);
+		do_show_stack(&info, 0);
+	}
+#endif
+}
 
 void
 show_regs (struct pt_regs *regs)
@@ -71,6 +103,10 @@
 			       ((i == sof - 1) || (i % 3) == 2) ? "\n" : " ");
 		}
 	}
+#ifdef CONFIG_IA64_NEW_UNWIND
+	if (!user_mode(regs))
+		show_stack(0);
+#endif
 }
 
 void __attribute__((noreturn))
@@ -104,7 +140,7 @@
 
 			itc = ia64_get_itc();
 			itm = ia64_get_itm();
-			if (time_after(itc, itm)) {
+			if (time_after(itc, itm + 1000)) {
 				extern void ia64_reset_itm (void);
 
 				printk("cpu_idle: ITM in past (itc=%lx,itm=%lx:%lums)\n",
@@ -267,9 +303,103 @@
 	return 0;
 }
 
+#ifdef CONFIG_IA64_NEW_UNWIND
+
+void
+do_copy_regs (struct unw_frame_info *info, void *arg)
+{
+	unsigned long ar_bsp, ndirty, *krbs, addr, mask, sp, nat_bits = 0, ip;
+	elf_greg_t *dst = arg;
+	struct pt_regs *pt;
+	char nat;
+	long val;
+	int i;
+
+	memset(dst, 0, sizeof(elf_gregset_t));	/* don't leak any kernel bits to user-level \
*/ +
+	if (unw_unwind_to_user(info) < 0)
+		return;
+
+	unw_get_sp(info, &sp);
+	pt = (struct pt_regs *) (sp + 16);
+
+	krbs = (unsigned long *) current + IA64_RBS_OFFSET/8;
+	ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19));
+	ar_bsp = (unsigned long) ia64_rse_skip_regs((long *) pt->ar_bspstore, ndirty);
+
+	/*
+	 * Write portion of RSE backing store living on the kernel
+	 * stack to the VM of the process.
+	 */
+	for (addr = pt->ar_bspstore; addr < ar_bsp; addr += 8)
+		if (ia64_peek(pt, current, addr, &val) == 0)
+			access_process_vm(current, addr, &val, sizeof(val), 1);
+
+	/* r0 is zero */
+	for (i = 1, mask = (1UL << i); i < 32; ++i) {
+		unw_get_gr(info, i, &dst[i], &nat);
+		if (nat)
+			nat_bits |= mask;
+		mask <<= 1;
+	}
+	dst[32] = nat_bits;
+	unw_get_pr(info, &dst[33]);
+
+	for (i = 0; i < 8; ++i)
+		unw_get_br(info, i, &dst[34 + i]);
+
+	unw_get_rp(info, &ip);
+	dst[42] = ip + ia64_psr(pt)->ri;
+	dst[43] = pt->cr_ifs & 0x3fffffffff;
+	dst[44] = pt->cr_ipsr & IA64_PSR_UM;
+
+	unw_get_ar(info, UNW_AR_RSC, &dst[45]);
+	/*
+	 * For bsp and bspstore, unw_get_ar() would return the kernel
+	 * addresses, but we need the user-level addresses instead:
+	 */
+	dst[46] = ar_bsp;
+	dst[47] = pt->ar_bspstore;
+	unw_get_ar(info, UNW_AR_RNAT, &dst[48]);
+	unw_get_ar(info, UNW_AR_CCV, &dst[49]);
+	unw_get_ar(info, UNW_AR_UNAT, &dst[50]);
+	unw_get_ar(info, UNW_AR_FPSR, &dst[51]);
+	dst[52] = pt->ar_pfs;	/* UNW_AR_PFS is == to pt->cr_ifs for interrupt frames */
+	unw_get_ar(info, UNW_AR_LC, &dst[53]);
+	unw_get_ar(info, UNW_AR_EC, &dst[54]);
+}
+
+void
+do_dump_fpu (struct unw_frame_info *info, void *arg)
+{
+	struct task_struct *fpu_owner = ia64_get_fpu_owner();
+	elf_fpreg_t *dst = arg;
+	int i;
+
+	memset(dst, 0, sizeof(elf_fpregset_t));	/* don't leak any "random" bits */
+
+	if (unw_unwind_to_user(info) < 0)
+		return;
+
+	/* f0 is 0.0, f1 is 1.0 */
+
+	for (i = 2; i < 32; ++i)
+		unw_get_fr(info, i, dst + i);
+
+	if ((fpu_owner == current) || (current->thread.flags & IA64_THREAD_FPH_VALID)) {
+		ia64_sync_fph(current);
+		memcpy(dst + 32, current->thread.fph, 96*16);
+	}
+}
+
+#endif /* CONFIG_IA64_NEW_UNWIND */
+
 void
 ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst)
 {
+#ifdef CONFIG_IA64_NEW_UNWIND
+	unw_init_running(do_copy_regs, dst);
+#else
 	struct switch_stack *sw = ((struct switch_stack *) pt) - 1;
 	unsigned long ar_ec, cfm, ar_bsp, ndirty, *krbs, addr;
 
@@ -303,7 +433,7 @@
 	 *	ar.rsc ar.bsp ar.bspstore ar.rnat
 	 *	ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec
 	 */
-	memset(dst, 0, sizeof (dst));	/* don't leak any "random" bits */
+	memset(dst, 0, sizeof(dst));	/* don't leak any "random" bits */
 
 	/* r0 is zero */   dst[ 1] =  pt->r1; dst[ 2] =  pt->r2; dst[ 3] = pt->r3;
 	dst[ 4] =  sw->r4; dst[ 5] =  sw->r5; dst[ 6] =  sw->r6; dst[ 7] = sw->r7;
@@ -311,36 +441,32 @@
 	dst[12] = pt->r12; dst[13] = pt->r13; dst[14] = pt->r14; dst[15] = pt->r15;
 	memcpy(dst + 16, &pt->r16, 16*8);	/* r16-r31 are contiguous */
 
-#ifdef CONFIG_IA64_NEW_UNWIND
-	printk("ia64_elf_core_copy_regs: fix me, please?");
-	dst[32] = 0;
-#else
 	dst[32] = ia64_get_nat_bits(pt, sw);
-#endif
 	dst[33] = pt->pr;
 
 	/* branch regs: */
 	dst[34] = pt->b0; dst[35] = sw->b1; dst[36] = sw->b2; dst[37] = sw->b3;
 	dst[38] = sw->b4; dst[39] = sw->b5; dst[40] = pt->b6; dst[41] = pt->b7;
 
-	dst[42] = pt->cr_iip; dst[43] = pt->cr_ifs;
-	dst[44] = pt->cr_ipsr;	/* XXX perhaps we should filter out some bits here? --davidm \
*/ +	dst[42] = pt->cr_iip + ia64_psr(pt)->ri;
+	dst[43] = pt->cr_ifs;
+	dst[44] = pt->cr_ipsr & IA64_PSR_UM;
 
 	dst[45] = pt->ar_rsc; dst[46] = ar_bsp; dst[47] = pt->ar_bspstore;  dst[48] = \
pt->ar_rnat;  dst[49] = pt->ar_ccv; dst[50] = pt->ar_unat; dst[51] = sw->ar_fpsr; \
dst[52] = pt->ar_pfs;  dst[53] = sw->ar_lc; dst[54] = (sw->ar_pfs >> 52) & 0x3f;
+#endif /* !CONFIG_IA64_NEW_UNWIND */
 }
 
 int
 dump_fpu (struct pt_regs *pt, elf_fpregset_t dst)
 {
+#ifdef CONFIG_IA64_NEW_UNWIND
+	unw_init_running(do_dump_fpu, dst);
+#else
 	struct switch_stack *sw = ((struct switch_stack *) pt) - 1;
 	struct task_struct *fpu_owner = ia64_get_fpu_owner();
 
-#ifdef CONFIG_IA64_NEW_UNWIND
-	printk("dump_fpu: fix me, please?");
-#endif
-
 	memset(dst, 0, sizeof (dst));	/* don't leak any "random" bits */
 
 	/* f0 is 0.0 */  /* f1 is 1.0 */  dst[2] = sw->f2; dst[3] = sw->f3;
@@ -354,6 +480,7 @@
 		}
 		memcpy(dst + 32, current->thread.fph, 96*16);
 	}
+#endif
 	return 1;	/* f0-f31 are always valid so we always return 1 */
 }
 
diff -urN linux-davidm/arch/ia64/kernel/ptrace.c \
                linux-2.4.0-test1-lia/arch/ia64/kernel/ptrace.c
--- linux-davidm/arch/ia64/kernel/ptrace.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/ptrace.c	Wed Jun 21 21:43:40 2000
@@ -29,8 +29,10 @@
  *	id (instruction debug fault disable; one bit)
  *	dd (data debug fault disable; one bit)
  *	ri (restart instruction; two bits)
+ *	is (instruction set; one bit)
  */
-#define IPSR_WRITE_MASK	0x000006a00100003eUL
+#define IPSR_WRITE_MASK \
+	(IA64_PSR_UM | IA64_PSR_DB | IA64_PSR_IS | IA64_PSR_ID | IA64_PSR_DD | IA64_PSR_RI)
 #define IPSR_READ_MASK	IPSR_WRITE_MASK
 
 #ifdef CONFIG_IA64_NEW_UNWIND
@@ -44,26 +46,6 @@
 # define dprintk(format...)
 #endif
 
-static int
-unwind_to_user (struct unw_frame_info *info, struct task_struct *child)
-{
-	unsigned long ip;
-
-	unw_init_from_blocked_task(info, child);
-	while (unw_unwind(info) >= 0) {
-		if (unw_get_rp(info, &ip) < 0) {
-			unw_get_ip(info, &ip);
-			dprintk("ptrace: failed to read return pointer (ip=0x%lx)\n", ip);
-			return -1;
-		}
-		if (ip < TASK_SIZE)
-			return 0;
-	}
-	unw_get_ip(info, &ip);
-	dprintk("ptrace: failed to unwind to user-level (ip=0x%lx)\n", ip);
-	return -1;
-}
-
 /*
  * Collect the NaT bits for r1-r31 from scratch_unat and return a NaT
  * bitset where bit i is set iff the NaT bit of register i is set.
@@ -488,7 +470,8 @@
 	struct unw_frame_info info;
 	unsigned long cfm, sof;
 
-	if (unwind_to_user(&info, child) < 0)
+	unw_init_from_blocked_task(&info, child);
+	if (unw_unwind_to_user(&info) < 0)
 		return -1;
 
 	unw_get_bsp(&info, (unsigned long *) &kbspstore);
@@ -561,10 +544,11 @@
 /*
  * Ensure the state in child->thread.fph is up-to-date.
  */
-static void
-sync_fph (struct task_struct *child)
+void
+ia64_sync_fph (struct task_struct *child)
 {
 	if (ia64_psr(ia64_task_regs(child))->mfh && ia64_get_fpu_owner() == child) {
+		ia64_set_fpu_owner(0);
 		ia64_save_fpu(&child->thread.fph[0]);
 		child->thread.flags |= IA64_THREAD_FPH_VALID;
 	}
@@ -614,7 +598,7 @@
 
 	if (addr < PT_F127 + 16) {
 		/* accessing fph */
-		sync_fph(child);
+		ia64_sync_fph(child);
 		ptr = (unsigned long *) ((unsigned long) &child->thread.fph + addr);
 	} else if (addr >= PT_F10 && addr < PT_F15 + 16) {
 		/* scratch registers untouched by kernel (saved in switch_stack) */
@@ -626,7 +610,8 @@
 		char nat = 0;
 		int ret;
 
-		if (unwind_to_user(&info, child) < 0)
+		unw_init_from_blocked_task(&info, child);
+		if (unw_unwind_to_user(&info) < 0)
 			return -1;
 
 		switch (addr) {
@@ -706,7 +691,8 @@
 					struct unw_frame_info info;
 					unsigned long cfm;
 
-					if (unwind_to_user(&info, child) < 0)
+					unw_init_from_blocked_task(&info, child);
+					if (unw_unwind_to_user(&info) < 0)
 						return -1;
 
 					unw_get_cfm(&info, &cfm);
@@ -727,7 +713,8 @@
 				/* kernel was entered through a system call */
 				unsigned long cfm;
 
-				if (unwind_to_user(&info, child) < 0)
+				unw_init_from_blocked_task(&info, child);
+				if (unw_unwind_to_user(&info) < 0)
 					return -1;
 
 				unw_get_cfm(&info, &cfm);
@@ -814,7 +801,7 @@
 
 	if (addr < PT_F127+16) {
 		/* accessing fph */
-		sync_fph(child);
+		ia64_sync_fph(child);
 		ptr = (unsigned long *) ((unsigned long) &child->thread.fph + addr);
 	} else if (addr < PT_F9+16) {
 		/* accessing switch_stack or pt_regs: */
diff -urN linux-davidm/arch/ia64/kernel/setup.c \
                linux-2.4.0-test1-lia/arch/ia64/kernel/setup.c
--- linux-davidm/arch/ia64/kernel/setup.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/setup.c	Wed Jun 21 21:44:17 2000
@@ -28,6 +28,7 @@
 #include <linux/console.h>
 
 #include <asm/acpi-ext.h>
+#include <asm/ia32.h>
 #include <asm/page.h>
 #include <asm/machvec.h>
 #include <asm/processor.h>
@@ -361,6 +362,13 @@
 
 	ia64_rid_init();
 	ia64_tlb_init();
+
+#ifdef	CONFIG_IA32_SUPPORT
+	/* initialize global ia32 state - CR0 and CR4 */
+	__asm__("mov ar.cflg = %0"
+		: /* no outputs */
+		: "r" (((ulong) IA32_CR4 << 32) | IA32_CR0));
+#endif
 
 #ifdef CONFIG_SMP
 	normal_xtp();
diff -urN linux-davidm/arch/ia64/kernel/sys_ia64.c \
                linux-2.4.0-test1-lia/arch/ia64/kernel/sys_ia64.c
--- linux-davidm/arch/ia64/kernel/sys_ia64.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/sys_ia64.c	Wed Jun 21 21:44:56 2000
@@ -14,6 +14,9 @@
 #include <linux/file.h>		/* doh, must come after sched.h... */
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/highuid.h>
+
+#include <asm/uaccess.h>
 
 asmlinkage long
 ia64_getpriority (int which, int who, long arg2, long arg3, long arg4, long arg5, \
long arg6,  @@ -94,7 +97,11 @@
 static inline unsigned long
 do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, \
unsigned long pgoff)  {
+	long start_low, end_low, starting_region, ending_region;
+	unsigned long loff, hoff;
 	struct file *file = 0;
+	/* the virtual address space that is mappable in each region: */
+#	define OCTANT_SIZE	((PTRS_PER_PGD<<PGDIR_SHIFT)/8)
 
 	/*
 	 * A zero mmap always succeeds in Linux, independent of
@@ -103,15 +110,19 @@
 	if (PAGE_ALIGN(len) == 0)
 		return addr;
 
-#ifdef notyet
-	/* Don't permit mappings that would cross a region boundary: */
-	region_start = IA64_GET_REGION(addr);
-	region_end   = IA64_GET_REGION(addr + len);
-	if (region_start != region_end)
+	/* Don't permit mappings into or across the address hole in a region: */
+	loff = REGION_OFFSET(addr);
+	hoff = loff - (REGION_SIZE - OCTANT_SIZE/2);
+	if ((len | loff | (loff + len)) >= OCTANT_SIZE/2
+	    && (len | hoff | (hoff + len)) >= OCTANT_SIZE/2)
 		return -EINVAL;
 
-	<<x??x>>
-#endif
+	/* Don't permit mappings that would cross a region boundary: */
+
+	starting_region = REGION_NUMBER(addr);
+	ending_region   = REGION_NUMBER(addr + len);
+	if (starting_region != ending_region)
+		return -EINVAL;
 
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 	if (!(flags & MAP_ANONYMOUS)) {
@@ -212,6 +223,136 @@
 		regs->r8 = 0;	/* ensure large addresses are not mistaken as failures... */
 	return addr;
 }
+
+#if 1
+/*
+ * This is here for a while to keep compatibillity with the old stat()
+ * call - it will be removed later once everybody migrates to the new
+ * kernel stat structure that matches the glibc one - Jes
+ */
+static __inline__ int
+do_revalidate (struct dentry *dentry)
+{
+	struct inode * inode = dentry->d_inode;
+	if (inode->i_op && inode->i_op->revalidate)
+		return inode->i_op->revalidate(dentry);
+	return 0;
+}
+
+static int
+cp_ia64_old_stat (struct inode *inode, struct ia64_oldstat *statbuf)
+{
+	struct ia64_oldstat tmp;
+	unsigned int blocks, indirect;
+
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
+	tmp.st_ino = inode->i_ino;
+	tmp.st_mode = inode->i_mode;
+	tmp.st_nlink = inode->i_nlink;
+	SET_STAT_UID(tmp, inode->i_uid);
+	SET_STAT_GID(tmp, inode->i_gid);
+	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
+	tmp.st_size = inode->i_size;
+	tmp.st_atime = inode->i_atime;
+	tmp.st_mtime = inode->i_mtime;
+	tmp.st_ctime = inode->i_ctime;
+/*
+ * st_blocks and st_blksize are approximated with a simple algorithm if
+ * they aren't supported directly by the filesystem. The minix and msdos
+ * filesystems don't keep track of blocks, so they would either have to
+ * be counted explicitly (by delving into the file itself), or by using
+ * this simple algorithm to get a reasonable (although not 100% accurate)
+ * value.
+ */
+
+/*
+ * Use minix fs values for the number of direct and indirect blocks.  The
+ * count is now exact for the minix fs except that it counts zero blocks.
+ * Everything is in units of BLOCK_SIZE until the assignment to
+ * tmp.st_blksize.
+ */
+#define D_B   7
+#define I_B   (BLOCK_SIZE / sizeof(unsigned short))
+
+	if (!inode->i_blksize) {
+		blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
+		if (blocks > D_B) {
+			indirect = (blocks - D_B + I_B - 1) / I_B;
+			blocks += indirect;
+			if (indirect > 1) {
+				indirect = (indirect - 1 + I_B - 1) / I_B;
+				blocks += indirect;
+				if (indirect > 1)
+					blocks++;
+			}
+		}
+		tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
+		tmp.st_blksize = BLOCK_SIZE;
+	} else {
+		tmp.st_blocks = inode->i_blocks;
+		tmp.st_blksize = inode->i_blksize;
+	}
+	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
+
+asmlinkage long
+ia64_oldstat (char *filename, struct ia64_oldstat *statbuf)
+{
+	struct nameidata nd;
+	int error;
+
+	lock_kernel();
+	error = user_path_walk(filename, &nd);
+	if (!error) {
+		error = do_revalidate(nd.dentry);
+		if (!error)
+		error = cp_ia64_old_stat(nd.dentry->d_inode, statbuf);
+		path_release(&nd);
+	}
+	unlock_kernel();
+	return error;
+}
+
+
+asmlinkage long
+ia64_oldlstat (char *filename, struct ia64_oldstat *statbuf) {
+	struct nameidata nd;
+	int error;
+
+	lock_kernel();
+	error = user_path_walk_link(filename, &nd);
+	if (!error) {
+		error = do_revalidate(nd.dentry);
+		if (!error)
+			error = cp_ia64_old_stat(nd.dentry->d_inode, statbuf);
+		path_release(&nd);
+	}
+	unlock_kernel();
+	return error;
+}
+
+asmlinkage long
+ia64_oldfstat (unsigned int fd, struct ia64_oldstat *statbuf)
+{
+	struct file * f;
+	int err = -EBADF;
+
+	lock_kernel();
+	f = fget(fd);
+	if (f) {
+		struct dentry * dentry = f->f_dentry;
+
+		err = do_revalidate(dentry);
+		if (!err)
+			err = cp_ia64_old_stat(dentry->d_inode, statbuf);
+		fput(f);
+	}
+	unlock_kernel();
+	return err;
+}
+ 
+#endif
 
 #ifndef CONFIG_PCI
 
diff -urN linux-davidm/arch/ia64/kernel/traps.c \
                linux-2.4.0-test1-lia/arch/ia64/kernel/traps.c
--- linux-davidm/arch/ia64/kernel/traps.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/traps.c	Wed Jun 21 21:45:23 2000
@@ -172,7 +172,7 @@
 	siginfo.si_signo = sig;
 	siginfo.si_errno = 0;
 	siginfo.si_code = code;
-	send_sig_info(sig, &siginfo, current);
+	force_sig_info(sig, &siginfo, current);
 }
 
 /*
@@ -337,7 +337,7 @@
 				siginfo.si_code = FPE_FLTDIV;
 			}
 			siginfo.si_isr = isr;
-			send_sig_info(SIGFPE, &siginfo, current);
+			force_sig_info(SIGFPE, &siginfo, current);
 		}
 	} else {
 		if (exception == -1) {
@@ -357,7 +357,7 @@
 				siginfo.si_code = FPE_FLTRES;
 			}
 			siginfo.si_isr = isr;
-			send_sig_info(SIGFPE, &siginfo, current);
+			force_sig_info(SIGFPE, &siginfo, current);
 		}
 	}
 	return 0;
diff -urN linux-davidm/arch/ia64/kernel/unaligned.c \
                linux-2.4.0-test1-lia/arch/ia64/kernel/unaligned.c
--- linux-davidm/arch/ia64/kernel/unaligned.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/unaligned.c	Wed Jun 21 21:45:50 2000
@@ -460,32 +460,15 @@
 	 * enabled.
 	 *
 	 * The registers [32-127] are ususally saved in the tss. When get here,
-	 * they are NECESSARY live because they are only saved explicitely.
+	 * they are NECESSARILY live because they are only saved explicitely.
 	 * We have 3 ways of updating the values: force a save of the range
 	 * in tss, use a gigantic switch/case statement or generate code on the
 	 * fly to store to the right register.
 	 * For now, we are using the (slow) save/restore way.
 	 */
  	if (regnum >= IA64_FIRST_ROTATING_FR) {
-		/*
-		 * force a save of [32-127] to tss
-		 * we use the __() form to avoid fiddling with the dfh bit
-		 */
-		__ia64_save_fpu(&current->thread.fph[0]);
-
+		ia64_sync_fph(current);
 		current->thread.fph[IA64_FPH_OFFS(regnum)] = *fpval;
-
-		__ia64_load_fpu(&current->thread.fph[0]);
-
-		/*
-	 	 * mark the high partition as being used now
-		 *
-		 * This is REQUIRED because the disabled_fph_fault() does
-		 * not set it, it's relying on the faulting instruction to
-		 * do it. In our case the faulty instruction never gets executed
-		 * completely, so we need to toggle the bit.
-	 	 */
-		regs->cr_ipsr |= IA64_PSR_MFH;
 	} else {
 		/*
 		 * pt_regs or switch_stack ?
@@ -544,15 +527,8 @@
 	 * See discussion in setfpreg() for reasons and other ways of doing this.
 	 */
  	if (regnum >= IA64_FIRST_ROTATING_FR) {
-	
-		/*
-		 * force a save of [32-127] to tss
-		 * we use the__ia64_save_fpu() form to avoid fiddling with
-		 * the dfh bit.
-		 */
-		__ia64_save_fpu(&current->thread.fph[0]);
-
-		*fpval =  current->thread.fph[IA64_FPH_OFFS(regnum)];
+		ia64_sync_fph(current);
+		*fpval = current->thread.fph[IA64_FPH_OFFS(regnum)];
 	} else {
 		/*
 		 * f0 = 0.0, f1= 1.0. Those registers are constant and are thus
@@ -1425,7 +1401,7 @@
 		si.si_errno = 0;
 		si.si_code = BUS_ADRALN;
 		si.si_addr = (void *) ifa;
-		send_sig_info(SIGBUS, &si, current);
+		force_sig_info(SIGBUS, &si, current);
 		return;
 	}
 
@@ -1436,7 +1412,7 @@
 		si.si_errno = 0;
 		si.si_code = BUS_ADRALN;
 		si.si_addr = (void *) ifa;
-		send_sig_info(SIGBUS, &si, current);
+		force_sig_info(SIGBUS, &si, current);
 		return;
 	}
 
diff -urN linux-davidm/arch/ia64/kernel/unwind.c \
                linux-2.4.0-test1-lia/arch/ia64/kernel/unwind.c
--- linux-davidm/arch/ia64/kernel/unwind.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/kernel/unwind.c	Wed Jun 21 21:43:19 2000
@@ -3,6 +3,18 @@
  * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 /*
+ * This file implements call frame unwind support for the Linux
+ * kernel.  Parsing and processing the unwind information is
+ * time-consuming, so this implementation translates the the unwind
+ * descriptors into unwind scripts.  These scripts are very simple
+ * (basically a sequence of assignments) and efficient to execute.
+ * They are cached for later re-use.  Each script is specific for a
+ * given instruction pointer address and the set of predicate values
+ * that the script depends on (most unwind descriptors are
+ * unconditional and scripts often do not depend on predicates at
+ * all).  This code is based on the unwind conventions described in
+ * the "IA-64 Software Conventions and Runtime Architecture" manual.
+ *
  * SMP conventions:
  *	o updates to the global unwind data (in structure "unw") are serialized
  *	  by the unw.lock spinlock
@@ -22,6 +34,7 @@
 #ifdef CONFIG_IA64_NEW_UNWIND
 
 #include <asm/delay.h>
+#include <asm/page.h>
 #include <asm/ptrace.h>
 #include <asm/ptrace_offsets.h>
 #include <asm/rse.h>
@@ -74,19 +87,30 @@
 #define struct_offset(str,fld)	((char *)&((str *)NULL)->fld - (char *) 0)
 
 static struct {
+	spinlock_t lock;			/* spinlock for unwind data */
+
+	/* list of unwind tables (one per load-module) */
 	struct unw_table *tables;
 
+	/* table of registers that prologues can save (and order in which they're saved): \
*/  const unsigned char save_order[8];
-	/* Maps a preserved register index (preg_index) to corresponding switch_stack \
offset: */ +
+	/* maps a preserved register index (preg_index) to corresponding switch_stack \
offset: */  unsigned short sw_off[sizeof(struct unw_frame_info) / 8];
 
-	unsigned short lru_head;
-	unsigned short lru_tail;
+	unsigned short lru_head;		/* index of lead-recently used script */
+	unsigned short lru_tail;		/* index of most-recently used script */
+
+	/* index into unw_frame_info for preserved register i */
 	unsigned short preg_index[UNW_NUM_REGS];
+
+	/* unwind table for the kernel: */
 	struct unw_table kernel_table;
 
-	spinlock_t lock;
+	/* hash table that maps instruction pointer to script index: */
 	unw_hash_index_t hash[UNW_HASH_SIZE];
+
+	/* script cache: */
 	struct unw_script cache[UNW_CACHE_SIZE];
 
 # if UNW_DEBUG
@@ -228,8 +252,8 @@
 					break;
 
 				      case UNW_NAT_SCRATCH:
-					if (info->unat)
-						nat_addr = info->unat;
+					if (info->pri_unat)
+						nat_addr = info->pri_unat;
 					else
 						nat_addr = &info->sw->caller_unat;
 				      case UNW_NAT_PRI_UNAT:
@@ -241,7 +265,7 @@
 					if ((unsigned long) addr < info->regstk.limit
 					    || (unsigned long) addr >= info->regstk.top)
 					{
-						dprintk("unwind: %lx outside of regstk "
+						dprintk("unwind: 0x%p outside of regstk "
 							"[0x%lx-0x%lx)\n", addr,
 							info->regstk.limit, info->regstk.top);
 						return -1;
@@ -258,7 +282,10 @@
 			}
 		} else {
 			/* access a scratch register */
-			pt = (struct pt_regs *) info->sp - 1;
+			if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
+				pt = (struct pt_regs *) info->psp - 1;
+			else
+				pt = (struct pt_regs *) info->sp - 1;
 			if (regnum <= 3)
 				addr = &pt->r1 + (regnum - 1);
 			else if (regnum <= 11)
@@ -267,8 +294,8 @@
 				addr = &pt->r12 + (regnum - 12);
 			else
 				addr = &pt->r16 + (regnum - 16);
-			if (info->unat)
-				nat_addr = info->unat;
+			if (info->pri_unat)
+				nat_addr = info->pri_unat;
 			else
 				nat_addr = &info->sw->caller_unat;
 			nat_mask = (1UL << ((long) addr & 0x1f8)/8);
@@ -304,7 +331,10 @@
 	unsigned long *addr;
 	struct pt_regs *pt;
 
-	pt = (struct pt_regs *) info->sp - 1;
+	if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
+		pt = (struct pt_regs *) info->psp - 1;
+	else
+		pt = (struct pt_regs *) info->sp - 1;
 	switch (regnum) {
 		/* scratch: */
 	      case 0: addr = &pt->b0; break;
@@ -335,12 +365,15 @@
 	struct ia64_fpreg *addr = 0;
 	struct pt_regs *pt;
 
-	if ((unsigned) (regnum - 2) >= 30) {
+	if ((unsigned) (regnum - 2) >= 126) {
 		dprintk("unwind: trying to access non-existent f%u\n", regnum);
 		return -1;
 	}
 
-	pt = (struct pt_regs *) info->sp - 1;
+	if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
+		pt = (struct pt_regs *) info->psp - 1;
+	else
+		pt = (struct pt_regs *) info->sp - 1;
 
 	if (regnum <= 5) {
 		addr = *(&info->f2 + (regnum - 2));
@@ -352,9 +385,14 @@
 		else
 			addr = &info->sw->f10 + (regnum - 10);
 	} else if (regnum <= 31) {
-		addr = *(&info->fr[regnum - 16]);
+		addr = info->fr[regnum - 16];
 		if (!addr)
 			addr = &info->sw->f16 + (regnum - 16);
+	} else {
+		struct task_struct *t = info->task;
+
+		ia64_sync_fph(t);
+		addr = t->thread.fph + (regnum - 32);
 	}
 
 	if (write)
@@ -370,7 +408,10 @@
 	unsigned long *addr;
 	struct pt_regs *pt;
 
-	pt = (struct pt_regs *) info->sp - 1;
+	if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
+		pt = (struct pt_regs *) info->psp - 1;
+	else
+		pt = (struct pt_regs *) info->sp - 1;
 
 	switch (regnum) {
 	      case UNW_AR_BSP:
@@ -409,6 +450,15 @@
 			addr = &info->sw->ar_lc;
 		break;
 
+	      case UNW_AR_EC:
+		if (!info->cfm)
+			return -1;
+		if (write)
+			*info->cfm = (*info->cfm & ~(0x3fUL << 52)) | ((*val & 0x3f) << 52);
+		else
+			*val = (*info->cfm >> 52) & 0x3f;
+		return 0;
+
 	      case UNW_AR_FPSR:
 		addr = info->fpsr;
 		if (!addr)
@@ -523,7 +573,7 @@
 	for (reg = hi; reg >= lo; --reg) {
 		if (reg->where == UNW_WHERE_SPILL_HOME) {
 			reg->where = UNW_WHERE_PSPREL;
-			reg->val = *offp;
+			reg->val = 0x10 - *offp;
 			*offp += regsize;
 		}
 	}
@@ -1046,27 +1096,34 @@
 script_new (unsigned long ip)
 {
 	struct unw_script *script, *prev, *tmp;
-	unsigned short head;
 	unsigned long flags;
 	unsigned char index;
+	unsigned short head;
 
 	STAT(++unw.stat.script.news);
 
 	/*
-	 * Atomically fetch the least recently used script.  We can't
-	 * do this via unw.lock because we also need to acquire the
-	 * script's lock and to avoid deadlock, we must acquire the
-	 * latter before the former.
+	 * Can't (easily) use cmpxchg() here because of ABA problem
+	 * that is intrinsic in cmpxchg()...
 	 */
-	do {
+	spin_lock_irqsave(&unw.lock, flags);
+	{
 		head = unw.lru_head;
-	} while (cmpxchg(&unw.lru_head, head, unw.cache[head].lru_chain) != head);
-
-	script = unw.cache + head;
+		script = unw.cache + head;
+		unw.lru_head = script->lru_chain;
+	}
+	spin_unlock(&unw.lock);
 
+	/*
+	 * XXX We'll deadlock here if we interrupt a thread that is
+	 * holding a read lock on script->lock.  A try_write_lock()
+	 * might be mighty handy here...  Alternatively, we could
+	 * disable interrupts whenever we hold a read-lock, but that
+	 * seems silly.
+	 */
 	write_lock(&script->lock);
 
-	spin_lock_irqsave(&unw.lock, flags);
+	spin_lock(&unw.lock);
 	{
 		/* re-insert script at the tail of the LRU chain: */
 		unw.cache[unw.lru_tail].lru_chain = head;
@@ -1543,7 +1600,9 @@
 	int have_write_lock = 0;
 	struct unw_script *scr;
 
-	if (info->ip & (my_cpu_data.unimpl_va_mask | 0xf)) {
+	if ((info->ip & (my_cpu_data.unimpl_va_mask | 0xf))
+	    || REGION_NUMBER(info->ip) != REGION_KERNEL)
+	{
 		/* don't let obviously bad addresses pollute the cache */
 		dprintk("unwind: rejecting bad ip=0x%lx\n", info->ip);
 		info->rp = 0;
@@ -1593,7 +1652,11 @@
 		return -1;
 	}
 	ip = info->ip = *info->rp;
-	if (ip <= TASK_SIZE) {
+	if (ip < GATE_ADDR + PAGE_SIZE) {
+		/*
+		 * We don't have unwind info for the gate page, so we consider that part
+		 * of user-space for the purpose of unwinding.
+		 */
 		dprintk("unwind: reached user-space (ip=0x%lx)\n", ip);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; \
local_irq_restore(flags));  return -1;
@@ -1648,7 +1711,30 @@
 	return retval;
 }
 
-static void
+int
+unw_unwind_to_user (struct unw_frame_info *info)
+{
+	unsigned long ip;
+
+	while (unw_unwind(info) >= 0) {
+		if (unw_get_rp(info, &ip) < 0) {
+			unw_get_ip(info, &ip);
+			dprintk("unwind: failed to read return pointer (ip=0x%lx)\n", ip);
+			return -1;
+		}
+		/*
+		 * We don't have unwind info for the gate page, so we consider that part
+		 * of user-space for the purpose of unwinding.
+		 */
+		if (ip < GATE_ADDR + PAGE_SIZE)
+			return 0;
+	}
+	unw_get_ip(info, &ip);
+	dprintk("unwind: failed to unwind to user-level (ip=0x%lx)\n", ip);
+	return -1;
+}
+
+void
 unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct \
switch_stack *sw)  {
 	unsigned long rbslimit, rbstop, stklimit, stktop, sol;
@@ -1682,6 +1768,7 @@
 	info->regstk.top   = rbstop;
 	info->memstk.limit = stklimit;
 	info->memstk.top   = stktop;
+	info->task = t;
 	info->sw  = sw;
 	info->sp = info->psp = (unsigned long) (sw + 1) - 16;
 	info->cfm = &sw->ar_pfs;
@@ -1961,7 +2048,7 @@
 	extern void unw_hash_index_t_is_too_narrow (void);
 	long i, off;
 
-	if (8*sizeof (unw_hash_index_t) < UNW_LOG_HASH_SIZE)
+	if (8*sizeof(unw_hash_index_t) < UNW_LOG_HASH_SIZE)
 		unw_hash_index_t_is_too_narrow();
 
 	unw.sw_off[unw.preg_index[UNW_REG_PRI_UNAT_GR]] = SW(AR_UNAT);
diff -urN linux-davidm/arch/ia64/lib/Makefile \
                linux-2.4.0-test1-lia/arch/ia64/lib/Makefile
--- linux-davidm/arch/ia64/lib/Makefile	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/lib/Makefile	Wed Jun 21 21:57:29 2000
@@ -16,6 +16,9 @@
 
 LX_OBJS = io.o
 
+IGNORE_FLAGS_OBJS = __divdi3.o __divsi3.o __udivdi3.o __udivsi3.o \
+		    __moddi3.o __modsi3.o __umoddi3.o __umodsi3.o
+
 include $(TOPDIR)/Rules.make
 
 __divdi3.o: idiv.S
diff -urN linux-davidm/arch/ia64/mm/init.c linux-2.4.0-test1-lia/arch/ia64/mm/init.c
--- linux-davidm/arch/ia64/mm/init.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/mm/init.c	Wed Jun 21 21:47:35 2000
@@ -346,7 +346,7 @@
 
 	memset(zones_size, 0, sizeof(zones_size));
 
-	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS);
+	max_dma = (PAGE_ALIGN(MAX_DMA_ADDRESS) >> PAGE_SHIFT);
 	if (max_low_pfn < max_dma)
 		zones_size[ZONE_DMA] = max_low_pfn;
 	else {
diff -urN linux-davidm/arch/ia64/mm/tlb.c linux-2.4.0-test1-lia/arch/ia64/mm/tlb.c
--- linux-davidm/arch/ia64/mm/tlb.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/mm/tlb.c	Wed Jun 21 21:48:13 2000
@@ -73,6 +73,7 @@
 		local_irq_enable();
 	}
 
+	spin_lock(&ptcg_lock);
 	flush_rid = ia64_get_rr(start);
 	ia64_srlz_d();
 	flush_start = start;
@@ -205,10 +206,10 @@
 	}
 	start &= ~((1UL << nbits) - 1);
 
-	spin_lock(&ptcg_lock);
 #if defined(CONFIG_SMP) && !defined(CONFIG_ITANIUM_PTCG)
 	flush_tlb_no_ptcg(start, end, nbits);
 #else
+	spin_lock(&ptcg_lock);
 	do {
 # ifdef CONFIG_SMP
 		/*
diff -urN linux-davidm/arch/ia64/tools/print_offsets.c \
                linux-2.4.0-test1-lia/arch/ia64/tools/print_offsets.c
--- linux-davidm/arch/ia64/tools/print_offsets.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/arch/ia64/tools/print_offsets.c	Wed Jun 21 21:48:47 2000
@@ -45,6 +45,9 @@
     { "IA64_PT_REGS_SIZE",		sizeof (struct pt_regs) },
     { "IA64_SWITCH_STACK_SIZE",		sizeof (struct switch_stack) },
     { "IA64_SIGINFO_SIZE",		sizeof (struct siginfo) },
+#ifdef CONFIG_IA64_NEW_UNWIND
+    { "UNW_FRAME_INFO_SIZE",		sizeof (struct unw_frame_info) },
+#endif
     { "", 0 },			/* spacer */
     { "IA64_TASK_FLAGS_OFFSET",		offsetof (struct task_struct, flags) },
     { "IA64_TASK_SIGPENDING_OFFSET",	offsetof (struct task_struct, sigpending) },
diff -urN linux-davidm/drivers/char/simserial.c \
                linux-2.4.0-test1-lia/drivers/char/simserial.c
--- linux-davidm/drivers/char/simserial.c	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/drivers/char/simserial.c	Wed Jun 21 21:49:39 2000
@@ -30,10 +30,6 @@
 #include <linux/serial.h>
 #include <linux/serialP.h>
 
-#ifdef CONFIG_KDB
-# include <linux/kdb.h>
-#endif
-
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
@@ -158,9 +154,6 @@
 			} else if ( seen_esc == 2 ) {
 				if ( ch == 'P' ) show_state();		/* F1 key */
 				if ( ch == 'Q' ) show_buffers();	/* F2 key */
-#ifdef CONFIG_KDB
-				if ( ch == 'S' ) KDB_ENTER();		/* F4 key */
-#endif
 				seen_esc = 0;
 				continue;
 			}
diff -urN linux-davidm/include/asm-ia64/dma.h \
                linux-2.4.0-test1-lia/include/asm-ia64/dma.h
--- linux-davidm/include/asm-ia64/dma.h	Sun Feb 13 10:30:44 2000
+++ linux-2.4.0-test1-lia/include/asm-ia64/dma.h	Wed Jun 21 21:57:58 2000
@@ -21,7 +21,7 @@
 #define dma_inb		inb
 
 #define MAX_DMA_CHANNELS	8
-#define MAX_DMA_ADDRESS		(~0UL)		/* no limits on DMAing, for now */
+#define MAX_DMA_ADDRESS		0xffffffffUL
 
 extern spinlock_t  dma_spin_lock;
 
diff -urN linux-davidm/include/asm-ia64/ia32.h \
                linux-2.4.0-test1-lia/include/asm-ia64/ia32.h
--- linux-davidm/include/asm-ia64/ia32.h	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/include/asm-ia64/ia32.h	Wed Jun 21 21:50:32 2000
@@ -112,10 +112,16 @@
        sigset32_t sa_mask;     /* A 32 bit mask */
 };
 
+typedef struct sigaltstack_ia32 {
+	unsigned int	ss_sp;
+	int		ss_flags;
+	unsigned int	ss_size;
+} stack_ia32_t;
+
 struct ucontext_ia32 {
-	unsigned long	  uc_flags;
-	struct ucontext_ia32  *uc_link;
-	stack_t		  uc_stack;
+	unsigned int	  uc_flags;
+	unsigned int 	  uc_link;
+	stack_ia32_t	  uc_stack;
 	struct sigcontext_ia32 uc_mcontext;
 	sigset_t	  uc_sigmask;	/* mask last for extensibility */
 };
@@ -343,8 +349,8 @@
  *  IA32 floating point control registers starting values
  */
 
-#define IA32_FSR_DEFAULT	0x55550000	/* set all tag bits */
-#define IA32_FCR_DEFAULT	0x33f		/* single precision, all masks */
+#define IA32_FSR_DEFAULT	0x55550000		/* set all tag bits */
+#define IA32_FCR_DEFAULT	0x17800000037fULL	/* extended precision, all masks */
 
 #define IA32_PTRACE_GETREGS	12
 #define IA32_PTRACE_SETREGS	13
diff -urN linux-davidm/include/asm-ia64/page.h \
                linux-2.4.0-test1-lia/include/asm-ia64/page.h
--- linux-davidm/include/asm-ia64/page.h	Wed Mar 15 09:59:06 2000
+++ linux-2.4.0-test1-lia/include/asm-ia64/page.h	Wed Jun 21 21:50:50 2000
@@ -127,6 +127,12 @@
 #define __pa(x)		({ia64_va _v; _v.l = (long) (x); _v.f.reg = 0; _v.l;})
 #define __va(x)		({ia64_va _v; _v.l = (long) (x); _v.f.reg = -1; _v.p;})
 
+#define REGION_NUMBER(x)	({ia64_va _v; _v.l = (long) (x); _v.f.reg;})
+#define REGION_OFFSET(x)	({ia64_va _v; _v.l = (long) (x); _v.f.off;})
+
+#define REGION_SIZE		REGION_NUMBER(1)
+#define REGION_KERNEL	7
+
 #define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int \
*)0=0; } while (0)  #define PAGE_BUG(page) do { BUG(); } while (0)
 
diff -urN linux-davidm/include/asm-ia64/pal.h \
                linux-2.4.0-test1-lia/include/asm-ia64/pal.h
--- linux-davidm/include/asm-ia64/pal.h	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/include/asm-ia64/pal.h	Wed Jun 21 21:51:10 2000
@@ -951,7 +951,7 @@
 /* Return information about processor's optional power management capabilities. */
 extern inline s64 
 ia64_pal_halt_info (pal_power_mgmt_info_u_t *power_buf) 
-{	
+{
 	struct ia64_pal_retval iprv;
 	PAL_CALL_STK(iprv, PAL_HALT_INFO, (unsigned long) power_buf, 0, 0);
 	return iprv.status; 
diff -urN linux-davidm/include/asm-ia64/processor.h \
                linux-2.4.0-test1-lia/include/asm-ia64/processor.h
--- linux-davidm/include/asm-ia64/processor.h	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/include/asm-ia64/processor.h	Wed Jun 21 21:51:21 2000
@@ -10,6 +10,7 @@
  *
  * 11/24/98	S.Eranian	added ia64_set_iva()
  * 12/03/99	D. Mosberger	implement thread_saved_pc() via kernel unwind API
+ * 06/16/00	A. Mallick	added csd/ssd/tssd for ia32 support
  */
 
 #include <linux/config.h>
@@ -291,10 +292,13 @@
 	__u64 fcr;			/* IA32 floating pt control reg */
 	__u64 fir;			/* IA32 fp except. instr. reg */
 	__u64 fdr;			/* IA32 fp except. data reg */
+	__u64 csd;			/* IA32 code selector descriptor */
+	__u64 ssd;			/* IA32 stack selector descriptor */
+	__u64 tssd;			/* IA32 TSS descriptor */
 	union {
 		__u64 sigmask;		/* aligned mask for sigsuspend scall */
 	} un;
-# define INIT_THREAD_IA32	, 0, 0, 0, 0, 0, {0}
+# define INIT_THREAD_IA32	, 0, 0, 0x17800000037fULL, 0, 0, 0, 0, 0, {0}
 #else
 # define INIT_THREAD_IA32
 #endif /* CONFIG_IA32_SUPPORT */
diff -urN linux-davidm/include/asm-ia64/ptrace.h \
                linux-2.4.0-test1-lia/include/asm-ia64/ptrace.h
--- linux-davidm/include/asm-ia64/ptrace.h	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/include/asm-ia64/ptrace.h	Wed Jun 21 21:51:33 2000
@@ -136,8 +136,8 @@
 	unsigned long r30;		/* scratch */
 	unsigned long r31;		/* scratch */
 
-	unsigned long ar_ccv;		/* compare/exchange value  */
-	unsigned long ar_fpsr;		/* floating point status*/
+	unsigned long ar_ccv;		/* compare/exchange value (scratch) */
+	unsigned long ar_fpsr;		/* floating point status (preserved) */
 
 	unsigned long b0;		/* return pointer (bp) */
 	unsigned long b7;		/* scratch */
@@ -219,6 +219,7 @@
   extern void show_regs (struct pt_regs *);
   extern long ia64_peek (struct pt_regs *, struct task_struct *, unsigned long addr, \
long *val);  extern long ia64_poke (struct pt_regs *, struct task_struct *, unsigned \
long addr, long val); +  extern void ia64_sync_fph (struct task_struct *t);
 
 #ifdef CONFIG_IA64_NEW_UNWIND
   /* get nat bits for scratch registers such that bit N==1 iff scratch register rN \
                is a NaT */
diff -urN linux-davidm/include/asm-ia64/stat.h \
                linux-2.4.0-test1-lia/include/asm-ia64/stat.h
--- linux-davidm/include/asm-ia64/stat.h	Sun Feb  6 18:42:40 2000
+++ linux-2.4.0-test1-lia/include/asm-ia64/stat.h	Wed Jun 21 21:51:44 2000
@@ -7,6 +7,27 @@
  */
 
 struct stat {
+	unsigned long	st_dev;
+	unsigned long	st_ino;
+	unsigned long	st_nlink;
+	unsigned int	st_mode;
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+	unsigned int	__pad0;
+	unsigned long	st_rdev;
+	unsigned long	st_size;
+	unsigned long	st_atime;
+	unsigned long	__reserved0;	/* reserved for atime.nanoseconds */
+	unsigned long	st_mtime;
+	unsigned long	__reserved1;	/* reserved for mtime.nanoseconds */
+	unsigned long	st_ctime;
+	unsigned long	__reserved2;	/* reserved for ctime.nanoseconds */
+	unsigned long	st_blksize;
+	long		st_blocks;
+	unsigned long	__unused[3];
+};
+
+struct ia64_oldstat {
 	unsigned int	st_dev;
 	unsigned int	st_ino;
 	unsigned int	st_mode;
diff -urN linux-davidm/include/asm-ia64/unistd.h \
                linux-2.4.0-test1-lia/include/asm-ia64/unistd.h
--- linux-davidm/include/asm-ia64/unistd.h	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/include/asm-ia64/unistd.h	Wed Jun 21 21:51:52 2000
@@ -109,9 +109,9 @@
 #define __NR_syslog			1117
 #define __NR_setitimer			1118
 #define __NR_getitimer			1119
-#define __NR_stat			1120
-#define __NR_lstat			1121
-#define __NR_fstat			1122
+#define __NR_old_stat			1120
+#define __NR_old_lstat			1121
+#define __NR_old_fstat			1122
 #define __NR_vhangup			1123
 #define __NR_lchown			1124
 #define __NR_vm86			1125
@@ -199,6 +199,9 @@
 #define __NR_sys_pivot_root		1207
 #define __NR_mincore			1208
 #define __NR_madvise			1209
+#define __NR_stat			1210
+#define __NR_lstat			1211
+#define __NR_fstat			1212
 
 #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
 
diff -urN linux-davidm/include/asm-ia64/unwind.h \
                linux-2.4.0-test1-lia/include/asm-ia64/unwind.h
--- linux-davidm/include/asm-ia64/unwind.h	Wed Jun 21 22:07:19 2000
+++ linux-2.4.0-test1-lia/include/asm-ia64/unwind.h	Wed Jun 21 21:52:01 2000
@@ -23,6 +23,7 @@
 	UNW_AR_RNAT,
 	UNW_AR_UNAT,
 	UNW_AR_LC,
+	UNW_AR_EC,
 	UNW_AR_FPSR,
 	UNW_AR_RSC,
 	UNW_AR_CCV
@@ -58,6 +59,7 @@
 	unsigned long pr_val;		/* current predicates */
 	unsigned long *cfm;
 
+	struct task_struct *task;
 	struct switch_stack *sw;
 
 	/* preserved state: */
@@ -101,6 +103,9 @@
  */
 extern void unw_init_from_blocked_task (struct unw_frame_info *info, struct \
task_struct *t);  
+extern void unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t,
+				 struct switch_stack *sw);
+
 /*
  * Prepare to unwind the current task.  For this to work, the kernel
  * stack identified by REGS must look like this:
@@ -118,10 +123,22 @@
 extern void unw_init_from_current (struct unw_frame_info *info, struct pt_regs \
*regs);  
 /*
+ * Prepare to unwind the currently running thread.
+ */
+extern void unw_init_running (void (*callback)(struct unw_frame_info *info, void \
*arg), void *arg); +
+/*
  * Unwind to previous to frame.  Returns 0 if successful, negative
  * number in case of an error.
  */
 extern int unw_unwind (struct unw_frame_info *info);
+
+/*
+ * Unwind until the return pointer is in user-land (or until an error
+ * occurs).  Returns 0 if successful, negative number in case of
+ * error.
+ */
+extern int unw_unwind_to_user (struct unw_frame_info *info);
 
 #define unw_get_ip(info,vp)	({*(vp) = (info)->ip; 0;})
 #define unw_get_sp(info,vp)	({*(vp) = (unsigned long) (info)->sp; 0;})


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic