Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
diff --git a/Documentation/Changes b/Documentation/Changes
index 5eaab04..27232be 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -237,6 +237,12 @@
 udev is a userspace application for populating /dev dynamically with
 only entries for devices actually present. udev replaces devfs.
 
+FUSE
+----
+
+Needs libfuse 2.4.0 or later.  Absolute minimum is 2.3.0 but mount
+options 'direct_io' and 'kernel_cache' won't work.
+
 Networking
 ==========
 
@@ -390,6 +396,10 @@
 ----
 o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html>
 
+FUSE
+----
+o <http://sourceforge.net/projects/fuse>
+
 Networking
 **********
 
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index 0321ded..b22e7c8 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -195,8 +195,8 @@
 ======================
 
 Keys have an owner user ID, a group access ID, and a permissions mask. The mask
-has up to eight bits each for user, group and other access. Only five of each
-set of eight bits are defined. These permissions granted are:
+has up to eight bits each for possessor, user, group and other access. Only
+five of each set of eight bits are defined. These permissions granted are:
 
  (*) View
 
@@ -241,16 +241,16 @@
      type, description and permissions. The payload of the key is not available
      this way:
 
-	SERIAL   FLAGS  USAGE EXPY PERM   UID   GID   TYPE      DESCRIPTION: SUMMARY
-	00000001 I-----    39 perm 1f0000     0     0 keyring   _uid_ses.0: 1/4
-	00000002 I-----     2 perm 1f0000     0     0 keyring   _uid.0: empty
-	00000007 I-----     1 perm 1f0000     0     0 keyring   _pid.1: empty
-	0000018d I-----     1 perm 1f0000     0     0 keyring   _pid.412: empty
-	000004d2 I--Q--     1 perm 1f0000    32    -1 keyring   _uid.32: 1/4
-	000004d3 I--Q--     3 perm 1f0000    32    -1 keyring   _uid_ses.32: empty
-	00000892 I--QU-     1 perm 1f0000     0     0 user      metal:copper: 0
-	00000893 I--Q-N     1  35s 1f0000     0     0 user      metal:silver: 0
-	00000894 I--Q--     1  10h 1f0000     0     0 user      metal:gold: 0
+	SERIAL   FLAGS  USAGE EXPY PERM     UID   GID   TYPE      DESCRIPTION: SUMMARY
+	00000001 I-----    39 perm 1f1f0000     0     0 keyring   _uid_ses.0: 1/4
+	00000002 I-----     2 perm 1f1f0000     0     0 keyring   _uid.0: empty
+	00000007 I-----     1 perm 1f1f0000     0     0 keyring   _pid.1: empty
+	0000018d I-----     1 perm 1f1f0000     0     0 keyring   _pid.412: empty
+	000004d2 I--Q--     1 perm 1f1f0000    32    -1 keyring   _uid.32: 1/4
+	000004d3 I--Q--     3 perm 1f1f0000    32    -1 keyring   _uid_ses.32: empty
+	00000892 I--QU-     1 perm 1f000000     0     0 user      metal:copper: 0
+	00000893 I--Q-N     1  35s 1f1f0000     0     0 user      metal:silver: 0
+	00000894 I--Q--     1  10h 001f0000     0     0 user      metal:gold: 0
 
      The flags are:
 
@@ -637,6 +637,34 @@
 two different users opening the same file is left to the filesystem author to
 solve.
 
+Note that there are two different types of pointers to keys that may be
+encountered:
+
+ (*) struct key *
+
+     This simply points to the key structure itself. Key structures will be at
+     least four-byte aligned.
+
+ (*) key_ref_t
+
+     This is equivalent to a struct key *, but the least significant bit is set
+     if the caller "possesses" the key. By "possession" it is meant that the
+     calling processes has a searchable link to the key from one of its
+     keyrings. There are three functions for dealing with these:
+
+	key_ref_t make_key_ref(const struct key *key,
+			       unsigned long possession);
+
+	struct key *key_ref_to_ptr(const key_ref_t key_ref);
+
+	unsigned long is_key_possessed(const key_ref_t key_ref);
+
+     The first function constructs a key reference from a key pointer and
+     possession information (which must be 0 or 1 and not any other value).
+
+     The second function retrieves the key pointer from a reference and the
+     third retrieves the possession flag.
+
 When accessing a key's payload contents, certain precautions must be taken to
 prevent access vs modification races. See the section "Notes on accessing
 payload contents" for more information.
@@ -665,7 +693,11 @@
 
 	void key_put(struct key *key);
 
-    This can be called from interrupt context. If CONFIG_KEYS is not set then
+    Or:
+
+	void key_ref_put(key_ref_t key_ref);
+
+    These can be called from interrupt context. If CONFIG_KEYS is not set then
     the argument will not be parsed.
 
 
@@ -689,13 +721,17 @@
 
 (*) If a keyring was found in the search, this can be further searched by:
 
-	struct key *keyring_search(struct key *keyring,
-				   const struct key_type *type,
-				   const char *description)
+	key_ref_t keyring_search(key_ref_t keyring_ref,
+				 const struct key_type *type,
+				 const char *description)
 
     This searches the keyring tree specified for a matching key. Error ENOKEY
-    is returned upon failure. If successful, the returned key will need to be
-    released.
+    is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful,
+    the returned key will need to be released.
+
+    The possession attribute from the keyring reference is used to control
+    access through the permissions mask and is propagated to the returned key
+    reference pointer if successful.
 
 
 (*) To check the validity of a key, this function can be called:
@@ -732,7 +768,7 @@
 key->payload.data. One of the following ways must be selected to access the
 data:
 
- (1) Unmodifyable key type.
+ (1) Unmodifiable key type.
 
      If the key type does not have a modify method, then the key's payload can
      be accessed without any form of locking, provided that it's known to be
diff --git a/MAINTAINERS b/MAINTAINERS
index 7d1dd5b..c1bc9a8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -604,6 +604,15 @@
 M:	hpa@zytor.com
 S:	Maintained
 
+CPUSETS
+P:	Paul Jackson
+P:	Simon Derr
+M:	pj@sgi.com
+M:	simon.derr@bull.net
+L:	linux-kernel@vger.kernel.org
+W:	http://www.bullopensource.org/cpuset/
+S:	Supported
+
 CRAMFS FILESYSTEM
 W:     http://sourceforge.net/projects/cramfs/
 S:     Orphan
@@ -1906,6 +1915,13 @@
 L:	linux-mtd@lists.infradead.org
 S:	Maintained
 
+PKTCDVD DRIVER
+P:	Peter Osterlund
+M:	petero2@telia.com
+L:	linux-kernel@vger.kernel.org
+L:	packet-writing@suse.com
+S:	Maintained
+
 POSIX CLOCKS and TIMERS
 P:	George Anzinger
 M:	george@mvista.com
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 3c8862f..58c1330d 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -52,8 +52,9 @@
  *
  * Setup a VA for the Versatile Vectored Interrupt Controller.
  */
-#define VA_VIC_BASE		 IO_ADDRESS(VERSATILE_VIC_BASE)
-#define VA_SIC_BASE		 IO_ADDRESS(VERSATILE_SIC_BASE)
+#define __io_address(n)		__io(IO_ADDRESS(n))
+#define VA_VIC_BASE		__io_address(VERSATILE_VIC_BASE)
+#define VA_SIC_BASE		__io_address(VERSATILE_SIC_BASE)
 
 static void vic_mask_irq(unsigned int irq)
 {
@@ -214,7 +215,7 @@
 	iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
 }
 
-#define VERSATILE_REFCOUNTER	(IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
+#define VERSATILE_REFCOUNTER	(__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
 
 /*
  * This is the Versatile sched_clock implementation.  This has
@@ -231,7 +232,7 @@
 }
 
 
-#define VERSATILE_FLASHCTRL    (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
+#define VERSATILE_FLASHCTRL    (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
 
 static int versatile_flash_init(void)
 {
@@ -309,7 +310,7 @@
 	.resource	= smc91x_resources,
 };
 
-#define VERSATILE_SYSMCI	(IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
+#define VERSATILE_SYSMCI	(__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
 
 unsigned int mmc_status(struct device *dev)
 {
@@ -343,11 +344,11 @@
 
 static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco)
 {
-	unsigned long sys_lock = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET;
+	void __iomem *sys_lock = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET;
 #if defined(CONFIG_ARCH_VERSATILE_PB)
-	unsigned long sys_osc = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC4_OFFSET;
+	void __iomem *sys_osc = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC4_OFFSET;
 #elif defined(CONFIG_MACH_VERSATILE_AB)
-	unsigned long sys_osc = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC1_OFFSET;
+	void __iomem *sys_osc = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC1_OFFSET;
 #endif
 	u32 val;
 
@@ -483,7 +484,7 @@
  */
 static struct clcd_panel *versatile_clcd_panel(void)
 {
-	unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
+	void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
 	struct clcd_panel *panel = &vga;
 	u32 val;
 
@@ -510,7 +511,7 @@
  */
 static void versatile_clcd_disable(struct clcd_fb *fb)
 {
-	unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
+	void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
 	u32 val;
 
 	val = readl(sys_clcd);
@@ -522,7 +523,7 @@
 	 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off
 	 */
 	if (fb->panel == &sanyo_2_5_in) {
-		unsigned long versatile_ib2_ctrl = IO_ADDRESS(VERSATILE_IB2_CTRL);
+		void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
 		unsigned long ctrl;
 
 		ctrl = readl(versatile_ib2_ctrl);
@@ -537,7 +538,7 @@
  */
 static void versatile_clcd_enable(struct clcd_fb *fb)
 {
-	unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
+	void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
 	u32 val;
 
 	val = readl(sys_clcd);
@@ -571,7 +572,7 @@
 	 * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on
 	 */
 	if (fb->panel == &sanyo_2_5_in) {
-		unsigned long versatile_ib2_ctrl = IO_ADDRESS(VERSATILE_IB2_CTRL);
+		void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
 		unsigned long ctrl;
 
 		ctrl = readl(versatile_ib2_ctrl);
@@ -720,7 +721,7 @@
 };
 
 #ifdef CONFIG_LEDS
-#define VA_LEDS_BASE (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
+#define VA_LEDS_BASE (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
 
 static void versatile_leds_event(led_event_t ledevt)
 {
@@ -778,11 +779,11 @@
 /*
  * Where is the timer (VA)?
  */
-#define TIMER0_VA_BASE		 IO_ADDRESS(VERSATILE_TIMER0_1_BASE)
-#define TIMER1_VA_BASE		(IO_ADDRESS(VERSATILE_TIMER0_1_BASE) + 0x20)
-#define TIMER2_VA_BASE		 IO_ADDRESS(VERSATILE_TIMER2_3_BASE)
-#define TIMER3_VA_BASE		(IO_ADDRESS(VERSATILE_TIMER2_3_BASE) + 0x20)
-#define VA_IC_BASE		 IO_ADDRESS(VERSATILE_VIC_BASE) 
+#define TIMER0_VA_BASE		 __io_address(VERSATILE_TIMER0_1_BASE)
+#define TIMER1_VA_BASE		(__io_address(VERSATILE_TIMER0_1_BASE) + 0x20)
+#define TIMER2_VA_BASE		 __io_address(VERSATILE_TIMER2_3_BASE)
+#define TIMER3_VA_BASE		(__io_address(VERSATILE_TIMER2_3_BASE) + 0x20)
+#define VA_IC_BASE		 __io_address(VERSATILE_VIC_BASE) 
 
 /*
  * How long is the timer interval?
@@ -877,12 +878,12 @@
 	 *	VERSATILE_REFCLK is 32KHz
 	 *	VERSATILE_TIMCLK is 1MHz
 	 */
-	val = readl(IO_ADDRESS(VERSATILE_SCTL_BASE));
+	val = readl(__io_address(VERSATILE_SCTL_BASE));
 	writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
 	       (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 
 	       (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
 	       (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
-	       IO_ADDRESS(VERSATILE_SCTL_BASE));
+	       __io_address(VERSATILE_SCTL_BASE));
 
 	/*
 	 * Initialise to a known state (all timers off)
diff --git a/arch/ppc/boot/ld.script b/arch/ppc/boot/ld.script
index 9362193..d4dd8f1 100644
--- a/arch/ppc/boot/ld.script
+++ b/arch/ppc/boot/ld.script
@@ -1,4 +1,4 @@
-OUTPUT_ARCH(powerpc)
+OUTPUT_ARCH(powerpc:common)
 SECTIONS
 {
   /* Read-only sections, merged into text segment: */
diff --git a/arch/ppc/kernel/perfmon.c b/arch/ppc/kernel/perfmon.c
index 04c1878..22df9a5 100644
--- a/arch/ppc/kernel/perfmon.c
+++ b/arch/ppc/kernel/perfmon.c
@@ -45,9 +45,8 @@
 	mtpmr(PMRN_PMGC0, pmgc0);
 }
 
-#elif CONFIG_6xx
+#elif defined(CONFIG_6xx)
 /* Ensure exceptions are disabled */
-
 static void dummy_perf(struct pt_regs *regs)
 {
 	unsigned int mmcr0 = mfspr(SPRN_MMCR0);
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 839f887..4849850 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -34,7 +34,7 @@
 DEFINE_SPINLOCK(mv64x60_lock);
 
 static phys_addr_t 	mv64x60_bridge_pbase;
-static void 		*mv64x60_bridge_vbase;
+static void 		__iomem *mv64x60_bridge_vbase;
 static u32		mv64x60_bridge_type = MV64x60_TYPE_INVALID;
 static u32		mv64x60_bridge_rev;
 #if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260)
@@ -938,7 +938,7 @@
  *
  * Return the virtual address of the bridge's registers.
  */
-void *
+void __iomem *
 mv64x60_get_bridge_vbase(void)
 {
 	return mv64x60_bridge_vbase;
diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/ppc64/kernel/machine_kexec.c
index 4775f12..bf7cc4f 100644
--- a/arch/ppc64/kernel/machine_kexec.c
+++ b/arch/ppc64/kernel/machine_kexec.c
@@ -205,6 +205,7 @@
 			continue;
 
 		while (paca[i].hw_cpu_id != -1) {
+			barrier();
 			if (!cpu_possible(i)) {
 				printk("kexec: cpu %d hw_cpu_id %d is not"
 						" possible, ignoring\n",
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c
index eb1bbb5..bfd385b 100644
--- a/arch/ppc64/mm/hash_native.c
+++ b/arch/ppc64/mm/hash_native.c
@@ -343,7 +343,7 @@
 	hpte_t *hptep;
 	unsigned long hpte_v;
 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
-	unsigned long large;
+	unsigned long large = batch->large;
 
 	local_irq_save(flags);
 
@@ -356,7 +356,6 @@
 
 		va = (vsid << 28) | (batch->addr[i] & 0x0fffffff);
 		batch->vaddr[j] = va;
-		large = pte_huge(batch->pte[i]);
 		if (large)
 			vpn = va >> HPAGE_SHIFT;
 		else
@@ -406,7 +405,7 @@
 		asm volatile("ptesync":::"memory");
 
 		for (i = 0; i < j; i++)
-			__tlbie(batch->vaddr[i], 0);
+			__tlbie(batch->vaddr[i], large);
 
 		asm volatile("eieio; tlbsync; ptesync":::"memory");
 
diff --git a/arch/ppc64/mm/tlb.c b/arch/ppc64/mm/tlb.c
index d8a6593..21fbffb 100644
--- a/arch/ppc64/mm/tlb.c
+++ b/arch/ppc64/mm/tlb.c
@@ -143,7 +143,8 @@
 	 * up scanning and resetting referenced bits then our batch context
 	 * will change mid stream.
 	 */
-	if (unlikely(i != 0 && context != batch->context)) {
+	if (i != 0 && (context != batch->context ||
+		       batch->large != pte_huge(pte))) {
 		flush_tlb_pending();
 		i = 0;
 	}
@@ -151,6 +152,7 @@
 	if (i == 0) {
 		batch->context = context;
 		batch->mm = mm;
+		batch->large = pte_huge(pte);
 	}
 	batch->pte[i] = __pte(pte);
 	batch->addr[i] = addr;
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index 7358cdb..4ff6808 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -143,7 +143,7 @@
 			break;
 		case __SI_FAULT >> 16:
 			err |= __get_user(tmp, &from->si_addr);
-			to->si_addr = (void *)(u64) (tmp & PSW32_ADDR_INSN);
+			to->si_addr = (void __user *)(u64) (tmp & PSW32_ADDR_INSN);
 			break;
 		case __SI_POLL >> 16:
 			err |= __get_user(to->si_band, &from->si_band);
@@ -338,7 +338,7 @@
 		err |= __get_user(kss.ss_flags, &uss->ss_flags);
 		if (err)
 			return -EFAULT;
-		kss.ss_sp = (void *) ss_sp;
+		kss.ss_sp = (void __user *) ss_sp;
 	}
 
 	set_fs (KERNEL_DS);
@@ -461,7 +461,7 @@
 		goto badframe;
 
 	err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp);
-	st.ss_sp = (void *) A((unsigned long)ss_sp);
+	st.ss_sp = compat_ptr(ss_sp);
 	err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size);
 	err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags);
 	if (err)
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 6a3f5b7..6e0110d 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -376,8 +376,8 @@
 
 	/* Create the ucontext.  */
 	err |= __put_user(0, &frame->uc.uc_flags);
-	err |= __put_user(0, &frame->uc.uc_link);
-	err |= __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(NULL, &frame->uc.uc_link);
+	err |= __put_user((void __user *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
 	err |= __put_user(sas_ss_flags(regs->gprs[15]),
 			  &frame->uc.uc_stack.ss_flags);
 	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c
index 4875695..77ef5df 100644
--- a/arch/sparc64/kernel/cpu.c
+++ b/arch/sparc64/kernel/cpu.c
@@ -39,6 +39,8 @@
   { 0x3e, 0x15, 0, "UltraSparc III+ integrated FPU"},
   { 0x3e, 0x16, 0, "UltraSparc IIIi integrated FPU"},
   { 0x3e, 0x18, 0, "UltraSparc IV integrated FPU"},
+  { 0x3e, 0x19, 0, "UltraSparc IV+ integrated FPU"},
+  { 0x3e, 0x22, 0, "UltraSparc IIIi+ integrated FPU"},
 };
 
 #define NSPARCFPU  (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info))
@@ -53,6 +55,8 @@
   { 0x3e, 0x15, "TI UltraSparc III+ (Cheetah+)"},
   { 0x3e, 0x16, "TI UltraSparc IIIi (Jalapeno)"},
   { 0x3e, 0x18, "TI UltraSparc IV (Jaguar)"},
+  { 0x3e, 0x19, "TI UltraSparc IV+ (Panther)"},
+  { 0x3e, 0x22, "TI UltraSparc IIIi+ (Serrano)"},
 };
 
 #define NSPARCCHIPS  (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info))
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
index 42718f6..02af08f 100644
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -294,7 +294,7 @@
 
 		kernel_mna_trap_fault();
 	} else {
-		unsigned long addr;
+		unsigned long addr, *reg_addr;
 		int orig_asi, asi;
 
 		addr = compute_effective_address(regs, insn,
@@ -319,11 +319,11 @@
 		};
 		switch (dir) {
 		case load:
-			do_int_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
-				    size, (unsigned long *) addr,
+			reg_addr = fetch_reg_addr(((insn>>25)&0x1f), regs);
+			do_int_load(reg_addr, size, (unsigned long *) addr,
 				    decode_signedness(insn), asi);
 			if (unlikely(asi != orig_asi)) {
-				unsigned long val_in = *(unsigned long *) addr;
+				unsigned long val_in = *reg_addr;
 				switch (size) {
 				case 2:
 					val_in = swab16(val_in);
@@ -339,7 +339,7 @@
 					BUG();
 					break;
 				};
-				*(unsigned long *) addr = val_in;
+				*reg_addr = val_in;
 			}
 			break;
 
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
index 9080e7c..0340041 100644
--- a/arch/sparc64/kernel/us3_cpufreq.c
+++ b/arch/sparc64/kernel/us3_cpufreq.c
@@ -208,7 +208,10 @@
 	impl  = ((ver >> 32) & 0xffff);
 
 	if (manuf == CHEETAH_MANUF &&
-	    (impl == CHEETAH_IMPL || impl == CHEETAH_PLUS_IMPL)) {
+	    (impl == CHEETAH_IMPL ||
+	     impl == CHEETAH_PLUS_IMPL ||
+	     impl == JAGUAR_IMPL ||
+	     impl == PANTHER_IMPL)) {
 		struct cpufreq_driver *driver;
 
 		ret = -ENOMEM;
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 5b5af95..7af37e3 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -28,8 +28,6 @@
 ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
 	$(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
 
-GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
-
 um-modes-$(CONFIG_MODE_TT) += tt
 um-modes-$(CONFIG_MODE_SKAS) += skas
 
@@ -45,9 +43,7 @@
 
 ARCH_INCLUDE	:= -I$(ARCH_DIR)/include
 ifneq ($(KBUILD_SRC),)
-ARCH_INCLUDE	+= -I$(ARCH_DIR)/include2
 ARCH_INCLUDE	+= -I$(srctree)/$(ARCH_DIR)/include
-MRPROPER_DIRS	+= $(ARCH_DIR)/include2
 endif
 SYS_DIR		:= $(ARCH_DIR)/include/sysdep-$(SUBARCH)
 
@@ -87,10 +83,6 @@
 
 SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
 
-ifeq ($(CONFIG_MODE_SKAS), y)
-$(SYS_HEADERS) : $(ARCH_DIR)/include/skas_ptregs.h
-endif
-
 .PHONY: linux
 
 all: linux
@@ -111,7 +103,8 @@
 $(shell cd $(ARCH_DIR) && ln -sf Kconfig.$(SUBARCH) Kconfig.arch)
 endif
 
-archprepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS)
+archprepare: $(ARCH_SYMLINKS) $(ARCH_DIR)/include/user_constants.h
+prepare: $(ARCH_DIR)/include/kern_constants.h
 
 LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
 LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib
@@ -146,15 +139,13 @@
 #When cleaning we don't include .config, so we don't include
 #TT or skas makefiles and don't clean skas_ptregs.h.
 CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \
-	$(GEN_HEADERS) $(ARCH_DIR)/include/skas_ptregs.h \
-	$(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/Kconfig.arch
+	$(ARCH_DIR)/include/user_constants.h \
+	$(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch
 
 MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \
 	$(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os
 
 archclean:
-	$(Q)$(MAKE) $(clean)=$(ARCH_DIR)/util
-	$(Q)$(MAKE) $(clean)=$(ARCH_DIR)/os-$(OS)/util
 	@find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
 		-o -name '*.gcov' \) -type f -print | xargs rm -f
 
@@ -180,9 +171,7 @@
 	@echo '  SYMLINK $@'
 ifneq ($(KBUILD_SRC),)
 	$(Q)mkdir -p $(ARCH_DIR)/include
-	$(Q)mkdir -p $(ARCH_DIR)/include2
-	$(Q)ln -fsn sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep
-	$(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include2/sysdep
+	$(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep
 else
 	$(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep
 endif
@@ -202,8 +191,6 @@
 
 define filechk_gen-asm-offsets
         (set -e; \
-         echo "#ifndef __ASM_OFFSETS_H__"; \
-         echo "#define __ASM_OFFSETS_H__"; \
          echo "/*"; \
          echo " * DO NOT MODIFY."; \
          echo " *"; \
@@ -212,8 +199,7 @@
          echo " */"; \
          echo ""; \
          sed -ne "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"; \
-         echo ""; \
-         echo "#endif" )
+         echo ""; )
 endef
 
 $(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h
@@ -222,50 +208,18 @@
 $(ARCH_DIR)/user-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.c
 	$(CC) $(USER_CFLAGS) -S -o $@ $<
 
-$(ARCH_DIR)/user-offsets.h: $(ARCH_DIR)/user-offsets.s
+$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/user-offsets.s
 	$(call filechk,gen-asm-offsets)
 
-CLEAN_FILES += $(ARCH_DIR)/user-offsets.s  $(ARCH_DIR)/user-offsets.h
+CLEAN_FILES += $(ARCH_DIR)/user-offsets.s
 
 $(ARCH_DIR)/kernel-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/kernel-offsets.c \
-				   $(ARCH_SYMLINKS) \
-				   $(SYS_DIR)/sc.h \
-				   include/asm include/linux/version.h \
-				   include/config/MARKER \
-				   $(ARCH_DIR)/include/user_constants.h
+				   archprepare
 	$(CC) $(CFLAGS) $(NOSTDINC_FLAGS) $(CPPFLAGS) -S -o $@ $<
 
-$(ARCH_DIR)/kernel-offsets.h: $(ARCH_DIR)/kernel-offsets.s
+$(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/kernel-offsets.s
 	$(call filechk,gen-asm-offsets)
 
-CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s  $(ARCH_DIR)/kernel-offsets.h
-
-$(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task
-	$(call filechk,gen_header)
-
-$(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os-$(OS)/util/mk_user_constants
-	$(call filechk,gen_header)
-
-$(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants
-	$(call filechk,gen_header)
-
-$(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs
-	$(call filechk,gen_header)
-
-$(ARCH_DIR)/os-$(OS)/util/mk_user_constants: $(ARCH_DIR)/os-$(OS)/util FORCE ;
-
-$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \
-	FORCE ;
-
-$(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ;
-
-$(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h $(ARCH_DIR)/kernel-offsets.h FORCE
-	$(Q)$(MAKE) $(build)=$@
-
-$(ARCH_DIR)/kernel/skas/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
-	$(Q)$(MAKE) $(build)=$@
-
-$(ARCH_DIR)/os-$(OS)/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
-	$(Q)$(MAKE) $(build)=$@
+CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s
 
 export SUBARCH USER_CFLAGS OS
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 1ab431a..2ee8a28 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -32,25 +32,3 @@
 ifneq ($(CONFIG_GPROF),y)
 ARCH_CFLAGS += -DUM_FASTCALL
 endif
-
-SYS_UTIL_DIR	:= $(ARCH_DIR)/sys-i386/util
-SYS_HEADERS	:= $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
-
-prepare: $(SYS_HEADERS)
-
-$(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
-	$(call filechk,gen_header)
-
-$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread 
-	$(call filechk,gen_header)
-
-$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
-	$(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-
-$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_DIR)/kernel-offsets.h FORCE
-	$(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-
-$(SYS_UTIL_DIR): scripts_basic include/asm FORCE
-	$(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR)
-
-CLEAN_FILES += $(SYS_HEADERS)
diff --git a/arch/um/Makefile-skas b/arch/um/Makefile-skas
index fd18ec5..ac35de5 100644
--- a/arch/um/Makefile-skas
+++ b/arch/um/Makefile-skas
@@ -10,5 +10,3 @@
 CFLAGS-$(CONFIG_GPROF) += $(GPROF_OPT)
 LINK-$(CONFIG_GCOV) += $(GCOV_OPT)
 LINK-$(CONFIG_GPROF) += $(GPROF_OPT)
-
-GEN_HEADERS += $(ARCH_DIR)/include/skas_ptregs.h
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index 436abbb..4f118d5 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -12,24 +12,3 @@
 
 ELF_ARCH := i386:x86-64
 ELF_FORMAT := elf64-x86-64
-
-SYS_UTIL_DIR := $(ARCH_DIR)/sys-x86_64/util
-SYS_DIR := $(ARCH_DIR)/include/sysdep-x86_64
-
-SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
-
-prepare: $(SYS_HEADERS)
-
-$(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
-	$(call filechk,gen_header)
-
-$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
-	$(call filechk,gen_header)
-
-$(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
-	$(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-
-$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(GEN_HEADERS) $(ARCH_DIR)/kernel-offsets.h FORCE
-	$(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
-
-CLEAN_FILES += $(SYS_HEADERS)
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
index 782ac3a..356390d 100644
--- a/arch/um/include/common-offsets.h
+++ b/arch/um/include/common-offsets.h
@@ -1,7 +1,7 @@
 /* for use by sys-$SUBARCH/kernel-offsets.c */
 
-OFFSET(TASK_REGS, task_struct, thread.regs);
-OFFSET(TASK_PID, task_struct, pid);
+OFFSET(HOST_TASK_REGS, task_struct, thread.regs);
+OFFSET(HOST_TASK_PID, task_struct, pid);
 DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE);
 DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
 DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
diff --git a/arch/um/include/skas_ptregs.h b/arch/um/include/skas_ptregs.h
new file mode 100644
index 0000000..73db19e
--- /dev/null
+++ b/arch/um/include/skas_ptregs.h
@@ -0,0 +1,6 @@
+#ifndef __SKAS_PT_REGS_
+#define __SKAS_PT_REGS_
+
+#include <user_constants.h>
+
+#endif
diff --git a/arch/um/include/sysdep-i386/sc.h b/arch/um/include/sysdep-i386/sc.h
new file mode 100644
index 0000000..c57d178
--- /dev/null
+++ b/arch/um/include/sysdep-i386/sc.h
@@ -0,0 +1,44 @@
+#ifndef __SYSDEP_I386_SC_H
+#define __SYSDEP_I386_SC_H
+
+#include <user_constants.h>
+
+#define SC_OFFSET(sc, field) \
+	*((unsigned long *) &(((char *) (sc))[HOST_##field]))
+#define SC_FP_OFFSET(sc, field) \
+	*((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[HOST_##field]))
+#define SC_FP_OFFSET_PTR(sc, field, type) \
+	((type *) &(((char *) (SC_FPSTATE(sc)))[HOST_##field]))
+
+#define SC_IP(sc) SC_OFFSET(sc, SC_IP)
+#define SC_SP(sc) SC_OFFSET(sc, SC_SP)
+#define SC_FS(sc) SC_OFFSET(sc, SC_FS)
+#define SC_GS(sc) SC_OFFSET(sc, SC_GS)
+#define SC_DS(sc) SC_OFFSET(sc, SC_DS)
+#define SC_ES(sc) SC_OFFSET(sc, SC_ES)
+#define SC_SS(sc) SC_OFFSET(sc, SC_SS)
+#define SC_CS(sc) SC_OFFSET(sc, SC_CS)
+#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS)
+#define SC_EAX(sc) SC_OFFSET(sc, SC_EAX)
+#define SC_EBX(sc) SC_OFFSET(sc, SC_EBX)
+#define SC_ECX(sc) SC_OFFSET(sc, SC_ECX)
+#define SC_EDX(sc) SC_OFFSET(sc, SC_EDX)
+#define SC_EDI(sc) SC_OFFSET(sc, SC_EDI)
+#define SC_ESI(sc) SC_OFFSET(sc, SC_ESI)
+#define SC_EBP(sc) SC_OFFSET(sc, SC_EBP)
+#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO)
+#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR)
+#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2)
+#define SC_FPSTATE(sc) SC_OFFSET(sc, SC_FPSTATE)
+#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK)
+#define SC_FP_CW(sc) SC_FP_OFFSET(sc, SC_FP_CW)
+#define SC_FP_SW(sc) SC_FP_OFFSET(sc, SC_FP_SW)
+#define SC_FP_TAG(sc) SC_FP_OFFSET(sc, SC_FP_TAG)
+#define SC_FP_IPOFF(sc) SC_FP_OFFSET(sc, SC_FP_IPOFF)
+#define SC_FP_CSSEL(sc) SC_FP_OFFSET(sc, SC_FP_CSSEL)
+#define SC_FP_DATAOFF(sc) SC_FP_OFFSET(sc, SC_FP_DATAOFF)
+#define SC_FP_DATASEL(sc) SC_FP_OFFSET(sc, SC_FP_DATASEL)
+#define SC_FP_ST(sc) SC_FP_OFFSET_PTR(sc, SC_FP_ST, struct _fpstate)
+#define SC_FXSR_ENV(sc) SC_FP_OFFSET_PTR(sc, SC_FXSR_ENV, void)
+
+#endif
diff --git a/arch/um/include/sysdep-i386/thread.h b/arch/um/include/sysdep-i386/thread.h
new file mode 100644
index 0000000..e2bd6bae
--- /dev/null
+++ b/arch/um/include/sysdep-i386/thread.h
@@ -0,0 +1,11 @@
+#ifndef __UM_THREAD_H
+#define __UM_THREAD_H
+
+#include <kern_constants.h>
+
+#define TASK_DEBUGREGS(task) ((unsigned long *) &(((char *) (task))[HOST_TASK_DEBUGREGS]))
+#ifdef CONFIG_MODE_TT
+#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID]))
+#endif
+
+#endif
diff --git a/arch/um/include/sysdep-x86_64/sc.h b/arch/um/include/sysdep-x86_64/sc.h
new file mode 100644
index 0000000..a160d9f
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/sc.h
@@ -0,0 +1,45 @@
+#ifndef __SYSDEP_X86_64_SC_H
+#define __SYSDEP_X86_64_SC_H
+
+/* Copyright (C) 2003 - 2004 PathScale, Inc
+ * Released under the GPL
+ */
+
+#include <user_constants.h>
+
+#define SC_OFFSET(sc, field) \
+	 *((unsigned long *) &(((char *) (sc))[HOST_##field]))
+
+#define SC_RBX(sc) SC_OFFSET(sc, SC_RBX)
+#define SC_RCX(sc) SC_OFFSET(sc, SC_RCX)
+#define SC_RDX(sc) SC_OFFSET(sc, SC_RDX)
+#define SC_RSI(sc) SC_OFFSET(sc, SC_RSI)
+#define SC_RDI(sc) SC_OFFSET(sc, SC_RDI)
+#define SC_RBP(sc) SC_OFFSET(sc, SC_RBP)
+#define SC_RAX(sc) SC_OFFSET(sc, SC_RAX)
+#define SC_R8(sc) SC_OFFSET(sc, SC_R8)
+#define SC_R9(sc) SC_OFFSET(sc, SC_R9)
+#define SC_R10(sc) SC_OFFSET(sc, SC_R10)
+#define SC_R11(sc) SC_OFFSET(sc, SC_R11)
+#define SC_R12(sc) SC_OFFSET(sc, SC_R12)
+#define SC_R13(sc) SC_OFFSET(sc, SC_R13)
+#define SC_R14(sc) SC_OFFSET(sc, SC_R14)
+#define SC_R15(sc) SC_OFFSET(sc, SC_R15)
+#define SC_IP(sc) SC_OFFSET(sc, SC_IP)
+#define SC_SP(sc) SC_OFFSET(sc, SC_SP)
+#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2)
+#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR)
+#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO)
+#define SC_CS(sc) SC_OFFSET(sc, SC_CS)
+#define SC_FS(sc) SC_OFFSET(sc, SC_FS)
+#define SC_GS(sc) SC_OFFSET(sc, SC_GS)
+#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS)
+#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK)
+#if 0
+#define SC_ORIG_RAX(sc) SC_OFFSET(sc, SC_ORIG_RAX)
+#define SC_DS(sc) SC_OFFSET(sc, SC_DS)
+#define SC_ES(sc) SC_OFFSET(sc, SC_ES)
+#define SC_SS(sc) SC_OFFSET(sc, SC_SS)
+#endif
+
+#endif
diff --git a/arch/um/include/sysdep-x86_64/thread.h b/arch/um/include/sysdep-x86_64/thread.h
new file mode 100644
index 0000000..6a76a7f
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/thread.h
@@ -0,0 +1,10 @@
+#ifndef __UM_THREAD_H
+#define __UM_THREAD_H
+
+#include <kern_constants.h>
+
+#ifdef CONFIG_MODE_TT
+#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID]))
+#endif
+
+#endif
diff --git a/arch/um/include/task.h b/arch/um/include/task.h
new file mode 100644
index 0000000..6375ba7
--- /dev/null
+++ b/arch/um/include/task.h
@@ -0,0 +1,9 @@
+#ifndef __TASK_H
+#define __TASK_H
+
+#include <kern_constants.h>
+
+#define TASK_REGS(task) ((union uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS]))
+#define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID]))
+
+#endif
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index db36c7c..8de471b 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -6,8 +6,6 @@
 obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
 	syscall.o tlb.o trap_user.o uaccess.o
 
-subdir- := util
-
 USER_OBJS := process.o clone.o
 
 include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile
deleted file mode 100644
index f7b7eba..0000000
--- a/arch/um/kernel/skas/util/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-hostprogs-y		:= mk_ptregs
-always			:= $(hostprogs-y)
-
-mk_ptregs-objs := mk_ptregs-$(SUBARCH).o
-HOSTCFLAGS_mk_ptregs-$(SUBARCH).o := -I$(objtree)/arch/um
diff --git a/arch/um/kernel/skas/util/mk_ptregs-i386.c b/arch/um/kernel/skas/util/mk_ptregs-i386.c
deleted file mode 100644
index 1f96e1e..0000000
--- a/arch/um/kernel/skas/util/mk_ptregs-i386.c
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SHOW(name) printf("#define %s %d\n", #name, name)
-
-int main(int argc, char **argv)
-{
-	printf("/* Automatically generated by "
-	       "arch/um/kernel/skas/util/mk_ptregs */\n");
-	printf("\n");
-	printf("#ifndef __SKAS_PT_REGS_\n");
-	printf("#define __SKAS_PT_REGS_\n");
-	printf("\n");
-	SHOW(HOST_FRAME_SIZE);
-	SHOW(HOST_FP_SIZE);
-	SHOW(HOST_XFP_SIZE);
-
-	SHOW(HOST_IP);
-	SHOW(HOST_SP);
-	SHOW(HOST_EFLAGS);
-	SHOW(HOST_EAX);
-	SHOW(HOST_EBX);
-	SHOW(HOST_ECX);
-	SHOW(HOST_EDX);
-	SHOW(HOST_ESI);
-	SHOW(HOST_EDI);
-	SHOW(HOST_EBP);
-	SHOW(HOST_CS);
-	SHOW(HOST_SS);
-	SHOW(HOST_DS);
-	SHOW(HOST_FS);
-	SHOW(HOST_ES);
-	SHOW(HOST_GS);
-
-	printf("\n");
-	printf("#endif\n");
-	return(0);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
deleted file mode 100644
index 5fccbfe3..0000000
--- a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2003 PathScale, Inc.
- *
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SHOW(name) \
-	printf("#define %s (%d / sizeof(unsigned long))\n", #name, name)
-
-int main(int argc, char **argv)
-{
-	printf("/* Automatically generated by "
-	       "arch/um/kernel/skas/util/mk_ptregs */\n");
-	printf("\n");
-	printf("#ifndef __SKAS_PT_REGS_\n");
-	printf("#define __SKAS_PT_REGS_\n");
-	SHOW(HOST_FRAME_SIZE);
-	SHOW(HOST_RBX);
-	SHOW(HOST_RCX);
-	SHOW(HOST_RDI);
-	SHOW(HOST_RSI);
-	SHOW(HOST_RDX);
-	SHOW(HOST_RBP);
-	SHOW(HOST_RAX);
-	SHOW(HOST_R8);
-	SHOW(HOST_R9);
-	SHOW(HOST_R10);
-	SHOW(HOST_R11);
-	SHOW(HOST_R12);
-	SHOW(HOST_R13);
-	SHOW(HOST_R14);
-	SHOW(HOST_R15);
-	SHOW(HOST_ORIG_RAX);
-	SHOW(HOST_CS);
-	SHOW(HOST_SS);
-	SHOW(HOST_EFLAGS);
-#if 0
-	SHOW(HOST_FS);
-	SHOW(HOST_GS);
-	SHOW(HOST_DS);
-	SHOW(HOST_ES);
-#endif
-
-	SHOW(HOST_IP);
-	SHOW(HOST_SP);
-	printf("#define HOST_FP_SIZE 0\n");
-	printf("#define HOST_XFP_SIZE 0\n");
-	printf("\n");
-	printf("\n");
-	printf("#endif\n");
-	return(0);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index ab33cb3..5a99dd3 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -12,7 +12,7 @@
 #include "init.h"
 #include "elf_user.h"
 #include "mem_user.h"
-#include <kernel-offsets.h>
+#include <kern_constants.h>
 
 /* Use the one from the kernel - the host may miss it, if having old headers. */
 #if UM_ELF_CLASS == UM_ELFCLASS32
diff --git a/arch/um/os-Linux/util/Makefile b/arch/um/os-Linux/util/Makefile
deleted file mode 100644
index 9778aed..0000000
--- a/arch/um/os-Linux/util/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-hostprogs-y		:= mk_user_constants
-always			:= $(hostprogs-y)
-
-HOSTCFLAGS_mk_user_constants.o := -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/util/mk_user_constants.c b/arch/um/os-Linux/util/mk_user_constants.c
deleted file mode 100644
index 4838f30..0000000
--- a/arch/um/os-Linux/util/mk_user_constants.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <stdio.h>
-#include <user-offsets.h>
-
-int main(int argc, char **argv)
-{
-  printf("/*\n");
-  printf(" * Generated by mk_user_constants\n");
-  printf(" */\n");
-  printf("\n");
-  printf("#ifndef __UM_USER_CONSTANTS_H\n");
-  printf("#define __UM_USER_CONSTANTS_H\n");
-  printf("\n");
-  /* I'd like to use FRAME_SIZE from ptrace.h here, but that's wrong on
-   * x86_64 (216 vs 168 bytes).  user_regs_struct is the correct size on
-   * both x86_64 and i386.
-   */
-  printf("#define UM_FRAME_SIZE %d\n", __UM_FRAME_SIZE);
-
-  printf("\n");
-  printf("#endif\n");
-
-  return(0);
-}
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 4ca2a22..6dfeb70f 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -18,6 +18,4 @@
 
 $(obj)/stub_segv.o : _c_flags = $(call unprofile,$(CFLAGS))
 
-subdir- := util
-
 include arch/um/scripts/Makefile.unmap
diff --git a/arch/um/sys-i386/kernel-offsets.c b/arch/um/sys-i386/kernel-offsets.c
index a1070af..35db850 100644
--- a/arch/um/sys-i386/kernel-offsets.c
+++ b/arch/um/sys-i386/kernel-offsets.c
@@ -18,9 +18,9 @@
 
 void foo(void)
 {
-	OFFSET(TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
+	OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
 #ifdef CONFIG_MODE_TT
-	OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
+	OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
 #endif
 #include <common-offsets.h>
 }
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
index 3ceaabc..677fc26 100644
--- a/arch/um/sys-i386/user-offsets.c
+++ b/arch/um/sys-i386/user-offsets.c
@@ -7,47 +7,48 @@
 #define DEFINE(sym, val) \
         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
 
+#define DEFINE_LONGS(sym, val) \
+        asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long)))
+
 #define OFFSET(sym, str, mem) \
 	DEFINE(sym, offsetof(struct str, mem));
 
 void foo(void)
 {
-	OFFSET(SC_IP, sigcontext, eip);
-	OFFSET(SC_SP, sigcontext, esp);
-	OFFSET(SC_FS, sigcontext, fs);
-	OFFSET(SC_GS, sigcontext, gs);
-	OFFSET(SC_DS, sigcontext, ds);
-	OFFSET(SC_ES, sigcontext, es);
-	OFFSET(SC_SS, sigcontext, ss);
-	OFFSET(SC_CS, sigcontext, cs);
-	OFFSET(SC_EFLAGS, sigcontext, eflags);
-	OFFSET(SC_EAX, sigcontext, eax);
-	OFFSET(SC_EBX, sigcontext, ebx);
-	OFFSET(SC_ECX, sigcontext, ecx);
-	OFFSET(SC_EDX, sigcontext, edx);
-	OFFSET(SC_EDI, sigcontext, edi);
-	OFFSET(SC_ESI, sigcontext, esi);
-	OFFSET(SC_EBP, sigcontext, ebp);
-	OFFSET(SC_TRAPNO, sigcontext, trapno);
-	OFFSET(SC_ERR, sigcontext, err);
-	OFFSET(SC_CR2, sigcontext, cr2);
-	OFFSET(SC_FPSTATE, sigcontext, fpstate);
-	OFFSET(SC_SIGMASK, sigcontext, oldmask);
-	OFFSET(SC_FP_CW, _fpstate, cw);
-	OFFSET(SC_FP_SW, _fpstate, sw);
-	OFFSET(SC_FP_TAG, _fpstate, tag);
-	OFFSET(SC_FP_IPOFF, _fpstate, ipoff);
-	OFFSET(SC_FP_CSSEL, _fpstate, cssel);
-	OFFSET(SC_FP_DATAOFF, _fpstate, dataoff);
-	OFFSET(SC_FP_DATASEL, _fpstate, datasel);
-	OFFSET(SC_FP_ST, _fpstate, _st);
-	OFFSET(SC_FXSR_ENV, _fpstate, _fxsr_env);
+	OFFSET(HOST_SC_IP, sigcontext, eip);
+	OFFSET(HOST_SC_SP, sigcontext, esp);
+	OFFSET(HOST_SC_FS, sigcontext, fs);
+	OFFSET(HOST_SC_GS, sigcontext, gs);
+	OFFSET(HOST_SC_DS, sigcontext, ds);
+	OFFSET(HOST_SC_ES, sigcontext, es);
+	OFFSET(HOST_SC_SS, sigcontext, ss);
+	OFFSET(HOST_SC_CS, sigcontext, cs);
+	OFFSET(HOST_SC_EFLAGS, sigcontext, eflags);
+	OFFSET(HOST_SC_EAX, sigcontext, eax);
+	OFFSET(HOST_SC_EBX, sigcontext, ebx);
+	OFFSET(HOST_SC_ECX, sigcontext, ecx);
+	OFFSET(HOST_SC_EDX, sigcontext, edx);
+	OFFSET(HOST_SC_EDI, sigcontext, edi);
+	OFFSET(HOST_SC_ESI, sigcontext, esi);
+	OFFSET(HOST_SC_EBP, sigcontext, ebp);
+	OFFSET(HOST_SC_TRAPNO, sigcontext, trapno);
+	OFFSET(HOST_SC_ERR, sigcontext, err);
+	OFFSET(HOST_SC_CR2, sigcontext, cr2);
+	OFFSET(HOST_SC_FPSTATE, sigcontext, fpstate);
+	OFFSET(HOST_SC_SIGMASK, sigcontext, oldmask);
+	OFFSET(HOST_SC_FP_CW, _fpstate, cw);
+	OFFSET(HOST_SC_FP_SW, _fpstate, sw);
+	OFFSET(HOST_SC_FP_TAG, _fpstate, tag);
+	OFFSET(HOST_SC_FP_IPOFF, _fpstate, ipoff);
+	OFFSET(HOST_SC_FP_CSSEL, _fpstate, cssel);
+	OFFSET(HOST_SC_FP_DATAOFF, _fpstate, dataoff);
+	OFFSET(HOST_SC_FP_DATASEL, _fpstate, datasel);
+	OFFSET(HOST_SC_FP_ST, _fpstate, _st);
+	OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env);
 
-	DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
-	DEFINE(HOST_FP_SIZE,
-		sizeof(struct user_i387_struct) / sizeof(unsigned long));
-	DEFINE(HOST_XFP_SIZE,
-	       sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
+	DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE);
+	DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_i387_struct));
+	DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fxsr_struct));
 
 	DEFINE(HOST_IP, EIP);
 	DEFINE(HOST_SP, UESP);
@@ -65,5 +66,5 @@
 	DEFINE(HOST_FS, FS);
 	DEFINE(HOST_ES, ES);
 	DEFINE(HOST_GS, GS);
-	DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
+	DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct));
 }
diff --git a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile
deleted file mode 100644
index bf61afd..0000000
--- a/arch/um/sys-i386/util/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-hostprogs-y	:= mk_sc mk_thread
-always		:= $(hostprogs-y)
-
-HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
-HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
diff --git a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c
deleted file mode 100644
index 04c0d73..0000000
--- a/arch/um/sys-i386/util/mk_sc.c
+++ /dev/null
@@ -1,51 +0,0 @@
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SC_OFFSET(name, field) \
-  printf("#define " #name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
-	 name)
-
-#define SC_FP_OFFSET(name, field) \
-  printf("#define " #name \
-	 "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
-	 name)
-
-#define SC_FP_OFFSET_PTR(name, field, type) \
-  printf("#define " #name \
-	 "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
-	 name)
-
-int main(int argc, char **argv)
-{
-  SC_OFFSET(SC_IP, eip);
-  SC_OFFSET(SC_SP, esp);
-  SC_OFFSET(SC_FS, fs);
-  SC_OFFSET(SC_GS, gs);
-  SC_OFFSET(SC_DS, ds);
-  SC_OFFSET(SC_ES, es);
-  SC_OFFSET(SC_SS, ss);
-  SC_OFFSET(SC_CS, cs);
-  SC_OFFSET(SC_EFLAGS, eflags);
-  SC_OFFSET(SC_EAX, eax);
-  SC_OFFSET(SC_EBX, ebx);
-  SC_OFFSET(SC_ECX, ecx);
-  SC_OFFSET(SC_EDX, edx);
-  SC_OFFSET(SC_EDI, edi);
-  SC_OFFSET(SC_ESI, esi);
-  SC_OFFSET(SC_EBP, ebp);
-  SC_OFFSET(SC_TRAPNO, trapno);
-  SC_OFFSET(SC_ERR, err);
-  SC_OFFSET(SC_CR2, cr2);
-  SC_OFFSET(SC_FPSTATE, fpstate);
-  SC_OFFSET(SC_SIGMASK, oldmask);
-  SC_FP_OFFSET(SC_FP_CW, cw);
-  SC_FP_OFFSET(SC_FP_SW, sw);
-  SC_FP_OFFSET(SC_FP_TAG, tag);
-  SC_FP_OFFSET(SC_FP_IPOFF, ipoff);
-  SC_FP_OFFSET(SC_FP_CSSEL, cssel);
-  SC_FP_OFFSET(SC_FP_DATAOFF, dataoff);
-  SC_FP_OFFSET(SC_FP_DATASEL, datasel);
-  SC_FP_OFFSET_PTR(SC_FP_ST, _st, "struct _fpstate");
-  SC_FP_OFFSET_PTR(SC_FXSR_ENV, _fxsr_env, "void");
-  return(0);
-}
diff --git a/arch/um/sys-i386/util/mk_thread.c b/arch/um/sys-i386/util/mk_thread.c
deleted file mode 100644
index 7470d0dd..0000000
--- a/arch/um/sys-i386/util/mk_thread.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <stdio.h>
-#include <kernel-offsets.h>
-
-int main(int argc, char **argv)
-{
-  printf("/*\n");
-  printf(" * Generated by mk_thread\n");
-  printf(" */\n");
-  printf("\n");
-  printf("#ifndef __UM_THREAD_H\n");
-  printf("#define __UM_THREAD_H\n");
-  printf("\n");
-  printf("#define TASK_DEBUGREGS(task) ((unsigned long *) "
-	 "&(((char *) (task))[%d]))\n", TASK_DEBUGREGS);
-#ifdef TASK_EXTERN_PID
-  printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
-	 TASK_EXTERN_PID);
-#endif
-  printf("\n");
-  printf("#endif\n");
-  return(0);
-}
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index f0ab574d..06c3633 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -29,6 +29,4 @@
 
 $(obj)/stub_segv.o: _c_flags = $(call unprofile,$(CFLAGS))
 
-subdir- := util
-
 include arch/um/scripts/Makefile.unmap
diff --git a/arch/um/sys-x86_64/kernel-offsets.c b/arch/um/sys-x86_64/kernel-offsets.c
index 998541e..bfcb104 100644
--- a/arch/um/sys-x86_64/kernel-offsets.c
+++ b/arch/um/sys-x86_64/kernel-offsets.c
@@ -19,7 +19,7 @@
 void foo(void)
 {
 #ifdef CONFIG_MODE_TT
-	OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
+	OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
 #endif
 #include <common-offsets.h>
 }
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 513d17c..5a585bf 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -16,71 +16,76 @@
 #define DEFINE(sym, val) \
         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
 
+#define DEFINE_LONGS(sym, val) \
+        asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long)))
+
 #define OFFSET(sym, str, mem) \
 	DEFINE(sym, offsetof(struct str, mem));
 
 void foo(void)
 {
-	OFFSET(SC_RBX, sigcontext, rbx);
-	OFFSET(SC_RCX, sigcontext, rcx);
-	OFFSET(SC_RDX, sigcontext, rdx);
-	OFFSET(SC_RSI, sigcontext, rsi);
-	OFFSET(SC_RDI, sigcontext, rdi);
-	OFFSET(SC_RBP, sigcontext, rbp);
-	OFFSET(SC_RAX, sigcontext, rax);
-	OFFSET(SC_R8, sigcontext, r8);
-	OFFSET(SC_R9, sigcontext, r9);
-	OFFSET(SC_R10, sigcontext, r10);
-	OFFSET(SC_R11, sigcontext, r11);
-	OFFSET(SC_R12, sigcontext, r12);
-	OFFSET(SC_R13, sigcontext, r13);
-	OFFSET(SC_R14, sigcontext, r14);
-	OFFSET(SC_R15, sigcontext, r15);
-	OFFSET(SC_IP, sigcontext, rip);
-	OFFSET(SC_SP, sigcontext, rsp);
-	OFFSET(SC_CR2, sigcontext, cr2);
-	OFFSET(SC_ERR, sigcontext, err);
-	OFFSET(SC_TRAPNO, sigcontext, trapno);
-	OFFSET(SC_CS, sigcontext, cs);
-	OFFSET(SC_FS, sigcontext, fs);
-	OFFSET(SC_GS, sigcontext, gs);
-	OFFSET(SC_EFLAGS, sigcontext, eflags);
-	OFFSET(SC_SIGMASK, sigcontext, oldmask);
+	OFFSET(HOST_SC_RBX, sigcontext, rbx);
+	OFFSET(HOST_SC_RCX, sigcontext, rcx);
+	OFFSET(HOST_SC_RDX, sigcontext, rdx);
+	OFFSET(HOST_SC_RSI, sigcontext, rsi);
+	OFFSET(HOST_SC_RDI, sigcontext, rdi);
+	OFFSET(HOST_SC_RBP, sigcontext, rbp);
+	OFFSET(HOST_SC_RAX, sigcontext, rax);
+	OFFSET(HOST_SC_R8, sigcontext, r8);
+	OFFSET(HOST_SC_R9, sigcontext, r9);
+	OFFSET(HOST_SC_R10, sigcontext, r10);
+	OFFSET(HOST_SC_R11, sigcontext, r11);
+	OFFSET(HOST_SC_R12, sigcontext, r12);
+	OFFSET(HOST_SC_R13, sigcontext, r13);
+	OFFSET(HOST_SC_R14, sigcontext, r14);
+	OFFSET(HOST_SC_R15, sigcontext, r15);
+	OFFSET(HOST_SC_IP, sigcontext, rip);
+	OFFSET(HOST_SC_SP, sigcontext, rsp);
+	OFFSET(HOST_SC_CR2, sigcontext, cr2);
+	OFFSET(HOST_SC_ERR, sigcontext, err);
+	OFFSET(HOST_SC_TRAPNO, sigcontext, trapno);
+	OFFSET(HOST_SC_CS, sigcontext, cs);
+	OFFSET(HOST_SC_FS, sigcontext, fs);
+	OFFSET(HOST_SC_GS, sigcontext, gs);
+	OFFSET(HOST_SC_EFLAGS, sigcontext, eflags);
+	OFFSET(HOST_SC_SIGMASK, sigcontext, oldmask);
 #if 0
-	OFFSET(SC_ORIG_RAX, sigcontext, orig_rax);
-	OFFSET(SC_DS, sigcontext, ds);
-	OFFSET(SC_ES, sigcontext, es);
-	OFFSET(SC_SS, sigcontext, ss);
+	OFFSET(HOST_SC_ORIG_RAX, sigcontext, orig_rax);
+	OFFSET(HOST_SC_DS, sigcontext, ds);
+	OFFSET(HOST_SC_ES, sigcontext, es);
+	OFFSET(HOST_SC_SS, sigcontext, ss);
 #endif
 
-	DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
-	DEFINE(HOST_RBX, RBX);
-	DEFINE(HOST_RCX, RCX);
-	DEFINE(HOST_RDI, RDI);
-	DEFINE(HOST_RSI, RSI);
-	DEFINE(HOST_RDX, RDX);
-	DEFINE(HOST_RBP, RBP);
-	DEFINE(HOST_RAX, RAX);
-	DEFINE(HOST_R8, R8);
-	DEFINE(HOST_R9, R9);
-	DEFINE(HOST_R10, R10);
-	DEFINE(HOST_R11, R11);
-	DEFINE(HOST_R12, R12);
-	DEFINE(HOST_R13, R13);
-	DEFINE(HOST_R14, R14);
-	DEFINE(HOST_R15, R15);
-	DEFINE(HOST_ORIG_RAX, ORIG_RAX);
-	DEFINE(HOST_CS, CS);
-	DEFINE(HOST_SS, SS);
-	DEFINE(HOST_EFLAGS, EFLAGS);
+	DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE);
+	DEFINE(HOST_FP_SIZE, 0);
+	DEFINE(HOST_XFP_SIZE, 0);
+	DEFINE_LONGS(HOST_RBX, RBX);
+	DEFINE_LONGS(HOST_RCX, RCX);
+	DEFINE_LONGS(HOST_RDI, RDI);
+	DEFINE_LONGS(HOST_RSI, RSI);
+	DEFINE_LONGS(HOST_RDX, RDX);
+	DEFINE_LONGS(HOST_RBP, RBP);
+	DEFINE_LONGS(HOST_RAX, RAX);
+	DEFINE_LONGS(HOST_R8, R8);
+	DEFINE_LONGS(HOST_R9, R9);
+	DEFINE_LONGS(HOST_R10, R10);
+	DEFINE_LONGS(HOST_R11, R11);
+	DEFINE_LONGS(HOST_R12, R12);
+	DEFINE_LONGS(HOST_R13, R13);
+	DEFINE_LONGS(HOST_R14, R14);
+	DEFINE_LONGS(HOST_R15, R15);
+	DEFINE_LONGS(HOST_ORIG_RAX, ORIG_RAX);
+	DEFINE_LONGS(HOST_CS, CS);
+	DEFINE_LONGS(HOST_SS, SS);
+	DEFINE_LONGS(HOST_EFLAGS, EFLAGS);
 #if 0
-	DEFINE(HOST_FS, FS);
-	DEFINE(HOST_GS, GS);
-	DEFINE(HOST_DS, DS);
-	DEFINE(HOST_ES, ES);
+	DEFINE_LONGS(HOST_FS, FS);
+	DEFINE_LONGS(HOST_GS, GS);
+	DEFINE_LONGS(HOST_DS, DS);
+	DEFINE_LONGS(HOST_ES, ES);
 #endif
 
-	DEFINE(HOST_IP, RIP);
-	DEFINE(HOST_SP, RSP);
-	DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct));
+	DEFINE_LONGS(HOST_IP, RIP);
+	DEFINE_LONGS(HOST_SP, RSP);
+	DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct));
 }
diff --git a/arch/um/sys-x86_64/util/Makefile b/arch/um/sys-x86_64/util/Makefile
deleted file mode 100644
index 75b052c..0000000
--- a/arch/um/sys-x86_64/util/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2003 - 2004 Pathscale, Inc
-# Released under the GPL
-
-hostprogs-y	:= mk_sc mk_thread
-always		:= $(hostprogs-y)
-
-HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um
-HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um
diff --git a/arch/um/sys-x86_64/util/mk_sc.c b/arch/um/sys-x86_64/util/mk_sc.c
deleted file mode 100644
index 7619bc3..0000000
--- a/arch/um/sys-x86_64/util/mk_sc.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (C) 2003 - 2004 PathScale, Inc
- * Released under the GPL
- */
-
-#include <stdio.h>
-#include <user-offsets.h>
-
-#define SC_OFFSET(name) \
-  printf("#define " #name \
-	 "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
-	 name)
-
-int main(int argc, char **argv)
-{
-  SC_OFFSET(SC_RBX);
-  SC_OFFSET(SC_RCX);
-  SC_OFFSET(SC_RDX);
-  SC_OFFSET(SC_RSI);
-  SC_OFFSET(SC_RDI);
-  SC_OFFSET(SC_RBP);
-  SC_OFFSET(SC_RAX);
-  SC_OFFSET(SC_R8);
-  SC_OFFSET(SC_R9);
-  SC_OFFSET(SC_R10);
-  SC_OFFSET(SC_R11);
-  SC_OFFSET(SC_R12);
-  SC_OFFSET(SC_R13);
-  SC_OFFSET(SC_R14);
-  SC_OFFSET(SC_R15);
-  SC_OFFSET(SC_IP);
-  SC_OFFSET(SC_SP);
-  SC_OFFSET(SC_CR2);
-  SC_OFFSET(SC_ERR);
-  SC_OFFSET(SC_TRAPNO);
-  SC_OFFSET(SC_CS);
-  SC_OFFSET(SC_FS);
-  SC_OFFSET(SC_GS);
-  SC_OFFSET(SC_EFLAGS);
-  SC_OFFSET(SC_SIGMASK);
-#if 0
-  SC_OFFSET(SC_ORIG_RAX);
-  SC_OFFSET(SC_DS);
-  SC_OFFSET(SC_ES);
-  SC_OFFSET(SC_SS);
-#endif
-  return(0);
-}
diff --git a/arch/um/sys-x86_64/util/mk_thread.c b/arch/um/sys-x86_64/util/mk_thread.c
deleted file mode 100644
index 1551739..0000000
--- a/arch/um/sys-x86_64/util/mk_thread.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <stdio.h>
-#include <kernel-offsets.h>
-
-int main(int argc, char **argv)
-{
-  printf("/*\n");
-  printf(" * Generated by mk_thread\n");
-  printf(" */\n");
-  printf("\n");
-  printf("#ifndef __UM_THREAD_H\n");
-  printf("#define __UM_THREAD_H\n");
-  printf("\n");
-#ifdef TASK_EXTERN_PID
-  printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n",
-	 TASK_EXTERN_PID);
-#endif
-  printf("\n");
-  printf("#endif\n");
-  return(0);
-}
diff --git a/arch/um/util/Makefile b/arch/um/util/Makefile
deleted file mode 100644
index 4c7551c..0000000
--- a/arch/um/util/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-hostprogs-y		:= mk_task mk_constants
-always			:= $(hostprogs-y)
-
-HOSTCFLAGS_mk_task.o := -I$(objtree)/arch/um
-HOSTCFLAGS_mk_constants.o := -I$(objtree)/arch/um
diff --git a/arch/um/util/mk_constants.c b/arch/um/util/mk_constants.c
deleted file mode 100644
index ab217becc..0000000
--- a/arch/um/util/mk_constants.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <stdio.h>
-#include <kernel-offsets.h>
-
-#define SHOW_INT(sym) printf("#define %s %d\n", #sym, sym)
-#define SHOW_STR(sym) printf("#define %s %s\n", #sym, sym)
-
-int main(int argc, char **argv)
-{
-  printf("/*\n");
-  printf(" * Generated by mk_constants\n");
-  printf(" */\n");
-  printf("\n");
-  printf("#ifndef __UM_CONSTANTS_H\n");
-  printf("#define __UM_CONSTANTS_H\n");
-  printf("\n");
-
-  SHOW_INT(UM_KERN_PAGE_SIZE);
-
-  SHOW_STR(UM_KERN_EMERG);
-  SHOW_STR(UM_KERN_ALERT);
-  SHOW_STR(UM_KERN_CRIT);
-  SHOW_STR(UM_KERN_ERR);
-  SHOW_STR(UM_KERN_WARNING);
-  SHOW_STR(UM_KERN_NOTICE);
-  SHOW_STR(UM_KERN_INFO);
-  SHOW_STR(UM_KERN_DEBUG);
-
-  SHOW_INT(UM_NSEC_PER_SEC);
-  printf("\n");
-  printf("#endif\n");
-  return(0);
-}
diff --git a/arch/um/util/mk_task.c b/arch/um/util/mk_task.c
deleted file mode 100644
index 36c9606..0000000
--- a/arch/um/util/mk_task.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <stdio.h>
-#include <kernel-offsets.h>
-
-void print_ptr(char *name, char *type, int offset)
-{
-  printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
-	 offset);
-}
-
-void print(char *name, char *type, int offset)
-{
-  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
-	 offset);
-}
-
-int main(int argc, char **argv)
-{
-  printf("/*\n");
-  printf(" * Generated by mk_task\n");
-  printf(" */\n");
-  printf("\n");
-  printf("#ifndef __TASK_H\n");
-  printf("#define __TASK_H\n");
-  printf("\n");
-  print_ptr("TASK_REGS", "union uml_pt_regs", TASK_REGS);
-  print("TASK_PID", "int", TASK_PID);
-  printf("\n");
-  printf("#endif\n");
-  return(0);
-}
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 2373cb8..703acde 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -959,9 +959,6 @@
  	   are handled in the OEM check above. */
  	if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
  		return 0;
- 	/* All in a single socket - should be synchronized */
- 	if (cpus_weight(cpu_core_map[0]) == num_online_cpus())
- 		return 0;
 #endif
  	/* Assume multi socket systems are not synchronized */
  	return num_online_cpus() > 1;
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 6ba48f3..041bb47 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -376,7 +376,7 @@
 		goto err_p2;
 	}
 
-	drm_proc_root = create_proc_entry("dri", S_IFDIR, NULL);
+	drm_proc_root = proc_mkdir("dri", NULL);
 	if (!drm_proc_root) {
 		DRM_ERROR("Cannot create /proc/dri\n");
 		ret = -1;
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index 32d2bb9..9779610 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -95,7 +95,7 @@
 	char                  name[64];
 
 	sprintf(name, "%d", minor);
-	*dev_root = create_proc_entry(name, S_IFDIR, root);
+	*dev_root = proc_mkdir(name, root);
 	if (!*dev_root) {
 		DRM_ERROR("Cannot create /proc/dri/%s\n", name);
 		return -1;
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index e82a96b..f669477 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -55,7 +55,7 @@
 static int poweroff_powercycle;
 
 /* parameter definition to allow user to flag power cycle */
-module_param(poweroff_powercycle, int, 0);
+module_param(poweroff_powercycle, int, 0644);
 MODULE_PARM_DESC(poweroff_powercycles, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
 
 /* Stuff from the get device id command. */
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 2291a87..97d6dc2 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -229,8 +229,8 @@
        TRACE_L("line discipline %d registered", N_R3964);
        TRACE_L("flags=%x num=%x", tty_ldisc_N_R3964.flags, 
                tty_ldisc_N_R3964.num);
-       TRACE_L("open=%x", (int)tty_ldisc_N_R3964.open);
-       TRACE_L("tty_ldisc_N_R3964 = %x", (int)&tty_ldisc_N_R3964);
+       TRACE_L("open=%p", tty_ldisc_N_R3964.open);
+       TRACE_L("tty_ldisc_N_R3964 = %p", &tty_ldisc_N_R3964);
      }
    else
      {
@@ -267,8 +267,8 @@
    
    spin_unlock_irqrestore(&pInfo->lock, flags);
 
-   TRACE_Q("add_tx_queue %x, length %d, tx_first = %x", 
-          (int)pHeader, pHeader->length, (int)pInfo->tx_first );
+   TRACE_Q("add_tx_queue %p, length %d, tx_first = %p", 
+          pHeader, pHeader->length, pInfo->tx_first );
 }
 
 static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code)
@@ -285,10 +285,10 @@
       return;
 
 #ifdef DEBUG_QUEUE
-   printk("r3964: remove_from_tx_queue: %x, length %d - ",
-          (int)pHeader, (int)pHeader->length );
+   printk("r3964: remove_from_tx_queue: %p, length %u - ",
+          pHeader, pHeader->length );
    for(pDump=pHeader;pDump;pDump=pDump->next)
-	 printk("%x ", (int)pDump);
+	 printk("%p ", pDump);
    printk("\n");
 #endif
 
@@ -319,10 +319,10 @@
    spin_unlock_irqrestore(&pInfo->lock, flags);
 
    kfree(pHeader);
-   TRACE_M("remove_from_tx_queue - kfree %x",(int)pHeader);
+   TRACE_M("remove_from_tx_queue - kfree %p",pHeader);
 
-   TRACE_Q("remove_from_tx_queue: tx_first = %x, tx_last = %x",
-          (int)pInfo->tx_first, (int)pInfo->tx_last );
+   TRACE_Q("remove_from_tx_queue: tx_first = %p, tx_last = %p",
+          pInfo->tx_first, pInfo->tx_last );
 }
 
 static void add_rx_queue(struct r3964_info *pInfo, struct r3964_block_header *pHeader)
@@ -346,9 +346,9 @@
    
    spin_unlock_irqrestore(&pInfo->lock, flags);
 
-   TRACE_Q("add_rx_queue: %x, length = %d, rx_first = %x, count = %d",
-          (int)pHeader, pHeader->length,
-          (int)pInfo->rx_first, pInfo->blocks_in_rx_queue);
+   TRACE_Q("add_rx_queue: %p, length = %d, rx_first = %p, count = %d",
+          pHeader, pHeader->length,
+          pInfo->rx_first, pInfo->blocks_in_rx_queue);
 }
 
 static void remove_from_rx_queue(struct r3964_info *pInfo,
@@ -360,10 +360,10 @@
    if(pHeader==NULL)
       return;
 
-   TRACE_Q("remove_from_rx_queue: rx_first = %x, rx_last = %x, count = %d",
-          (int)pInfo->rx_first, (int)pInfo->rx_last, pInfo->blocks_in_rx_queue );
-   TRACE_Q("remove_from_rx_queue: %x, length %d",
-          (int)pHeader, (int)pHeader->length );
+   TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
+          pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue );
+   TRACE_Q("remove_from_rx_queue: %p, length %u",
+          pHeader, pHeader->length );
 
    spin_lock_irqsave(&pInfo->lock, flags);
 
@@ -401,10 +401,10 @@
    spin_unlock_irqrestore(&pInfo->lock, flags);
 
    kfree(pHeader);
-   TRACE_M("remove_from_rx_queue - kfree %x",(int)pHeader);
+   TRACE_M("remove_from_rx_queue - kfree %p",pHeader);
 
-   TRACE_Q("remove_from_rx_queue: rx_first = %x, rx_last = %x, count = %d",
-          (int)pInfo->rx_first, (int)pInfo->rx_last, pInfo->blocks_in_rx_queue );
+   TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
+          pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue );
 }
 
 static void put_char(struct r3964_info *pInfo, unsigned char ch)
@@ -506,8 +506,8 @@
    if(tty->driver->write_room)
       room=tty->driver->write_room(tty);
 
-   TRACE_PS("transmit_block %x, room %d, length %d", 
-          (int)pBlock, room, pBlock->length);
+   TRACE_PS("transmit_block %p, room %d, length %d", 
+          pBlock, room, pBlock->length);
    
    while(pInfo->tx_position < pBlock->length)
    {
@@ -588,7 +588,7 @@
 
    /* prepare struct r3964_block_header: */
    pBlock = kmalloc(length+sizeof(struct r3964_block_header), GFP_KERNEL);
-   TRACE_M("on_receive_block - kmalloc %x",(int)pBlock);
+   TRACE_M("on_receive_block - kmalloc %p",pBlock);
 
    if(pBlock==NULL)
       return;
@@ -868,11 +868,11 @@
                if(pMsg)
                {
                   kfree(pMsg);
-                  TRACE_M("enable_signals - msg kfree %x",(int)pMsg);
+                  TRACE_M("enable_signals - msg kfree %p",pMsg);
                }
             }
             kfree(pClient);
-            TRACE_M("enable_signals - kfree %x",(int)pClient);
+            TRACE_M("enable_signals - kfree %p",pClient);
             return 0;
          }
       }
@@ -890,7 +890,7 @@
       {
          /* add client to client list */
          pClient=kmalloc(sizeof(struct r3964_client_info), GFP_KERNEL);
-         TRACE_M("enable_signals - kmalloc %x",(int)pClient);
+         TRACE_M("enable_signals - kmalloc %p",pClient);
          if(pClient==NULL)
             return -ENOMEM;
 
@@ -954,7 +954,7 @@
 queue_the_message:
 
       pMsg = kmalloc(sizeof(struct r3964_message), GFP_KERNEL);
-      TRACE_M("add_msg - kmalloc %x",(int)pMsg);
+      TRACE_M("add_msg - kmalloc %p",pMsg);
       if(pMsg==NULL) {
          return;
       }
@@ -1067,11 +1067,11 @@
    struct r3964_info *pInfo;
    
    TRACE_L("open");
-   TRACE_L("tty=%x, PID=%d, disc_data=%x", 
-          (int)tty, current->pid, (int)tty->disc_data);
+   TRACE_L("tty=%p, PID=%d, disc_data=%p", 
+          tty, current->pid, tty->disc_data);
    
    pInfo=kmalloc(sizeof(struct r3964_info), GFP_KERNEL); 
-   TRACE_M("r3964_open - info kmalloc %x",(int)pInfo);
+   TRACE_M("r3964_open - info kmalloc %p",pInfo);
 
    if(!pInfo)
    {
@@ -1080,26 +1080,26 @@
    }
 
    pInfo->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL);
-   TRACE_M("r3964_open - rx_buf kmalloc %x",(int)pInfo->rx_buf);
+   TRACE_M("r3964_open - rx_buf kmalloc %p",pInfo->rx_buf);
 
    if(!pInfo->rx_buf)
    {
       printk(KERN_ERR "r3964: failed to alloc receive buffer\n");
       kfree(pInfo);
-      TRACE_M("r3964_open - info kfree %x",(int)pInfo);
+      TRACE_M("r3964_open - info kfree %p",pInfo);
       return -ENOMEM;
    }
    
    pInfo->tx_buf = kmalloc(TX_BUF_SIZE, GFP_KERNEL);
-   TRACE_M("r3964_open - tx_buf kmalloc %x",(int)pInfo->tx_buf);
+   TRACE_M("r3964_open - tx_buf kmalloc %p",pInfo->tx_buf);
 
    if(!pInfo->tx_buf)
    {
       printk(KERN_ERR "r3964: failed to alloc transmit buffer\n");
       kfree(pInfo->rx_buf);
-      TRACE_M("r3964_open - rx_buf kfree %x",(int)pInfo->rx_buf);
+      TRACE_M("r3964_open - rx_buf kfree %p",pInfo->rx_buf);
       kfree(pInfo);
-      TRACE_M("r3964_open - info kfree %x",(int)pInfo);
+      TRACE_M("r3964_open - info kfree %p",pInfo);
       return -ENOMEM;
    }
 
@@ -1154,11 +1154,11 @@
           if(pMsg)
           {
              kfree(pMsg);
-             TRACE_M("r3964_close - msg kfree %x",(int)pMsg);
+             TRACE_M("r3964_close - msg kfree %p",pMsg);
           }
        }
        kfree(pClient);
-       TRACE_M("r3964_close - client kfree %x",(int)pClient);
+       TRACE_M("r3964_close - client kfree %p",pClient);
        pClient=pNext;
     }
     /* Remove jobs from tx_queue: */
@@ -1177,11 +1177,11 @@
     /* Free buffers: */
     wake_up_interruptible(&pInfo->read_wait);
     kfree(pInfo->rx_buf);
-    TRACE_M("r3964_close - rx_buf kfree %x",(int)pInfo->rx_buf);
+    TRACE_M("r3964_close - rx_buf kfree %p",pInfo->rx_buf);
     kfree(pInfo->tx_buf);
-    TRACE_M("r3964_close - tx_buf kfree %x",(int)pInfo->tx_buf);
+    TRACE_M("r3964_close - tx_buf kfree %p",pInfo->tx_buf);
     kfree(pInfo);
-    TRACE_M("r3964_close - info kfree %x",(int)pInfo);
+    TRACE_M("r3964_close - info kfree %p",pInfo);
 }
 
 static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
@@ -1234,7 +1234,7 @@
       count = sizeof(struct r3964_client_message);
 
       kfree(pMsg);
-      TRACE_M("r3964_read - msg kfree %x",(int)pMsg);
+      TRACE_M("r3964_read - msg kfree %p",pMsg);
 
       if (copy_to_user(buf,&theMsg, count))
 	return -EFAULT;
@@ -1279,7 +1279,7 @@
  * Allocate a buffer for the data and copy it from the buffer with header prepended
  */
    new_data = kmalloc (count+sizeof(struct r3964_block_header), GFP_KERNEL);
-   TRACE_M("r3964_write - kmalloc %x",(int)new_data);
+   TRACE_M("r3964_write - kmalloc %p",new_data);
    if (new_data == NULL) {
       if (pInfo->flags & R3964_DEBUG)
       {
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c
index 1436aea..6d3ff08 100644
--- a/drivers/char/watchdog/mv64x60_wdt.c
+++ b/drivers/char/watchdog/mv64x60_wdt.c
@@ -87,6 +87,8 @@
 	mv64x60_wdt_service();
 	mv64x60_wdt_handler_enable();
 
+	nonseekable_open(inode, file);
+
 	return 0;
 }
 
@@ -103,12 +105,9 @@
 	return 0;
 }
 
-static ssize_t mv64x60_wdt_write(struct file *file, const char *data,
+static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
 				 size_t len, loff_t * ppos)
 {
-	if (*ppos != file->f_pos)
-		return -ESPIPE;
-
 	if (len)
 		mv64x60_wdt_service();
 
@@ -119,6 +118,7 @@
 			     unsigned int cmd, unsigned long arg)
 {
 	int timeout;
+	void __user *argp = (void __user *)arg;
 	static struct watchdog_info info = {
 		.options = WDIOF_KEEPALIVEPING,
 		.firmware_version = 0,
@@ -127,13 +127,13 @@
 
 	switch (cmd) {
 	case WDIOC_GETSUPPORT:
-		if (copy_to_user((void *)arg, &info, sizeof(info)))
+		if (copy_to_user(argp, &info, sizeof(info)))
 			return -EFAULT;
 		break;
 
 	case WDIOC_GETSTATUS:
 	case WDIOC_GETBOOTSTATUS:
-		if (put_user(wdt_status, (int *)arg))
+		if (put_user(wdt_status, (int __user *)argp))
 			return -EFAULT;
 		wdt_status &= ~WDIOF_KEEPALIVEPING;
 		break;
@@ -154,7 +154,7 @@
 
 	case WDIOC_GETTIMEOUT:
 		timeout = mv64x60_wdt_timeout * HZ;
-		if (put_user(timeout, (int *)arg))
+		if (put_user(timeout, (int __user *)argp))
 			return -EFAULT;
 		break;
 
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index b1897be..cc12434 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -69,6 +69,7 @@
 
 struct ib_uverbs_file {
 	struct kref				ref;
+	struct semaphore			mutex;
 	struct ib_uverbs_device		       *device;
 	struct ib_ucontext		       *ucontext;
 	struct ib_event_handler			event_handler;
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index e91ebde..5624451 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -76,8 +76,9 @@
 	struct ib_uverbs_get_context_resp resp;
 	struct ib_udata                   udata;
 	struct ib_device                 *ibdev = file->device->ib_dev;
+	struct ib_ucontext		 *ucontext;
 	int i;
-	int ret = in_len;
+	int ret;
 
 	if (out_len < sizeof resp)
 		return -ENOSPC;
@@ -85,45 +86,56 @@
 	if (copy_from_user(&cmd, buf, sizeof cmd))
 		return -EFAULT;
 
+	down(&file->mutex);
+
+	if (file->ucontext) {
+		ret = -EINVAL;
+		goto err;
+	}
+
 	INIT_UDATA(&udata, buf + sizeof cmd,
 		   (unsigned long) cmd.response + sizeof resp,
 		   in_len - sizeof cmd, out_len - sizeof resp);
 
-	file->ucontext = ibdev->alloc_ucontext(ibdev, &udata);
-	if (IS_ERR(file->ucontext)) {
-		ret = PTR_ERR(file->ucontext);
-		file->ucontext = NULL;
-		return ret;
-	}
+	ucontext = ibdev->alloc_ucontext(ibdev, &udata);
+	if (IS_ERR(ucontext))
+		return PTR_ERR(file->ucontext);
 
-	file->ucontext->device = ibdev;
-	INIT_LIST_HEAD(&file->ucontext->pd_list);
-	INIT_LIST_HEAD(&file->ucontext->mr_list);
-	INIT_LIST_HEAD(&file->ucontext->mw_list);
-	INIT_LIST_HEAD(&file->ucontext->cq_list);
-	INIT_LIST_HEAD(&file->ucontext->qp_list);
-	INIT_LIST_HEAD(&file->ucontext->srq_list);
-	INIT_LIST_HEAD(&file->ucontext->ah_list);
-	spin_lock_init(&file->ucontext->lock);
+	ucontext->device = ibdev;
+	INIT_LIST_HEAD(&ucontext->pd_list);
+	INIT_LIST_HEAD(&ucontext->mr_list);
+	INIT_LIST_HEAD(&ucontext->mw_list);
+	INIT_LIST_HEAD(&ucontext->cq_list);
+	INIT_LIST_HEAD(&ucontext->qp_list);
+	INIT_LIST_HEAD(&ucontext->srq_list);
+	INIT_LIST_HEAD(&ucontext->ah_list);
 
 	resp.async_fd = file->async_file.fd;
 	for (i = 0; i < file->device->num_comp; ++i)
 		if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab +
 				 i * sizeof (__u32),
-				 &file->comp_file[i].fd, sizeof (__u32)))
-			goto err;
+				 &file->comp_file[i].fd, sizeof (__u32))) {
+			ret = -EFAULT;
+			goto err_free;
+		}
 
 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
-			 &resp, sizeof resp))
-		goto err;
+			 &resp, sizeof resp)) {
+		ret = -EFAULT;
+		goto err_free;
+	}
+
+	file->ucontext = ucontext;
+	up(&file->mutex);
 
 	return in_len;
 
-err:
-	ibdev->dealloc_ucontext(file->ucontext);
-	file->ucontext = NULL;
+err_free:
+	ibdev->dealloc_ucontext(ucontext);
 
-	return -EFAULT;
+err:
+	up(&file->mutex);
+	return ret;
 }
 
 ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
@@ -352,9 +364,9 @@
 	if (ret)
 		goto err_pd;
 
-	spin_lock_irq(&file->ucontext->lock);
+	down(&file->mutex);
 	list_add_tail(&uobj->list, &file->ucontext->pd_list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 	memset(&resp, 0, sizeof resp);
 	resp.pd_handle = uobj->id;
@@ -368,9 +380,9 @@
 	return in_len;
 
 err_list:
- 	spin_lock_irq(&file->ucontext->lock);
+ 	down(&file->mutex);
 	list_del(&uobj->list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 	down(&ib_uverbs_idr_mutex);
 	idr_remove(&ib_uverbs_pd_idr, uobj->id);
@@ -410,9 +422,9 @@
 
 	idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle);
 
-	spin_lock_irq(&file->ucontext->lock);
+	down(&file->mutex);
 	list_del(&uobj->list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 	kfree(uobj);
 
@@ -512,9 +524,9 @@
 
 	resp.mr_handle = obj->uobject.id;
 
-	spin_lock_irq(&file->ucontext->lock);
+	down(&file->mutex);
 	list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
 			 &resp, sizeof resp)) {
@@ -527,9 +539,9 @@
 	return in_len;
 
 err_list:
-	spin_lock_irq(&file->ucontext->lock);
+	down(&file->mutex);
 	list_del(&obj->uobject.list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 err_unreg:
 	ib_dereg_mr(mr);
@@ -570,9 +582,9 @@
 
 	idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle);
 
-	spin_lock_irq(&file->ucontext->lock);
+	down(&file->mutex);
 	list_del(&memobj->uobject.list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 	ib_umem_release(file->device->ib_dev, &memobj->umem);
 	kfree(memobj);
@@ -647,9 +659,9 @@
 	if (ret)
 		goto err_cq;
 
-	spin_lock_irq(&file->ucontext->lock);
+	down(&file->mutex);
 	list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 	memset(&resp, 0, sizeof resp);
 	resp.cq_handle = uobj->uobject.id;
@@ -664,9 +676,9 @@
 	return in_len;
 
 err_list:
- 	spin_lock_irq(&file->ucontext->lock);
+ 	down(&file->mutex);
 	list_del(&uobj->uobject.list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 	down(&ib_uverbs_idr_mutex);
 	idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id);
@@ -712,9 +724,9 @@
 
 	idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle);
 
-	spin_lock_irq(&file->ucontext->lock);
+	down(&file->mutex);
 	list_del(&uobj->uobject.list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 	spin_lock_irq(&file->comp_file[0].lock);
 	list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) {
@@ -847,9 +859,9 @@
 
 	resp.qp_handle = uobj->uobject.id;
 
-	spin_lock_irq(&file->ucontext->lock);
+	down(&file->mutex);
 	list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
 			 &resp, sizeof resp)) {
@@ -862,9 +874,9 @@
 	return in_len;
 
 err_list:
-	spin_lock_irq(&file->ucontext->lock);
+	down(&file->mutex);
 	list_del(&uobj->uobject.list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 err_destroy:
 	ib_destroy_qp(qp);
@@ -989,9 +1001,9 @@
 
 	idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle);
 
-	spin_lock_irq(&file->ucontext->lock);
+	down(&file->mutex);
 	list_del(&uobj->uobject.list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 	spin_lock_irq(&file->async_file.lock);
 	list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
@@ -1136,9 +1148,9 @@
 
 	resp.srq_handle = uobj->uobject.id;
 
-	spin_lock_irq(&file->ucontext->lock);
+	down(&file->mutex);
 	list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 	if (copy_to_user((void __user *) (unsigned long) cmd.response,
 			 &resp, sizeof resp)) {
@@ -1151,9 +1163,9 @@
 	return in_len;
 
 err_list:
-	spin_lock_irq(&file->ucontext->lock);
+	down(&file->mutex);
 	list_del(&uobj->uobject.list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 err_destroy:
 	ib_destroy_srq(srq);
@@ -1227,9 +1239,9 @@
 
 	idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle);
 
-	spin_lock_irq(&file->ucontext->lock);
+	down(&file->mutex);
 	list_del(&uobj->uobject.list);
-	spin_unlock_irq(&file->ucontext->lock);
+	up(&file->mutex);
 
 	spin_lock_irq(&file->async_file.lock);
 	list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index ce5bdb7..1251180 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -448,7 +448,9 @@
 	if (hdr.in_words * 4 != count)
 		return -EINVAL;
 
-	if (hdr.command < 0 || hdr.command >= ARRAY_SIZE(uverbs_cmd_table))
+	if (hdr.command < 0				||
+	    hdr.command >= ARRAY_SIZE(uverbs_cmd_table) ||
+	    !uverbs_cmd_table[hdr.command])
 		return -EINVAL;
 
 	if (!file->ucontext                               &&
@@ -484,27 +486,29 @@
 	file = kmalloc(sizeof *file +
 		       (dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file),
 		       GFP_KERNEL);
-	if (!file)
-		return -ENOMEM;
+	if (!file) {
+		ret = -ENOMEM;
+		goto err;
+	}
 
 	file->device = dev;
 	kref_init(&file->ref);
+	init_MUTEX(&file->mutex);
 
 	file->ucontext = NULL;
 
+	kref_get(&file->ref);
 	ret = ib_uverbs_event_init(&file->async_file, file);
 	if (ret)
-		goto err;
+		goto err_kref;
 
 	file->async_file.is_async = 1;
 
-	kref_get(&file->ref);
-
 	for (i = 0; i < dev->num_comp; ++i) {
+		kref_get(&file->ref);
 		ret = ib_uverbs_event_init(&file->comp_file[i], file);
 		if (ret)
 			goto err_async;
-		kref_get(&file->ref);
 		file->comp_file[i].is_async = 0;
 	}
 
@@ -524,9 +528,16 @@
 
 	ib_uverbs_event_release(&file->async_file);
 
-err:
+err_kref:
+	/*
+	 * One extra kref_put() because we took a reference before the
+	 * event file creation that failed and got us here.
+	 */
+	kref_put(&file->ref, ib_uverbs_release_file);
 	kref_put(&file->ref, ib_uverbs_release_file);
 
+err:
+	module_put(dev->ib_dev->owner);
 	return ret;
 }
 
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index cc758a2..f6a8ac0 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -605,7 +605,7 @@
 			err = -EINVAL;
 			goto out;
 		}
-		for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i, ++nent) {
+		for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i) {
 			if (virt != -1) {
 				pages[nent * 2] = cpu_to_be64(virt);
 				virt += 1 << lg;
@@ -616,7 +616,7 @@
 			ts += 1 << (lg - 10);
 			++tc;
 
-			if (nent == MTHCA_MAILBOX_SIZE / 16) {
+			if (++nent == MTHCA_MAILBOX_SIZE / 16) {
 				err = mthca_cmd(dev, mailbox->dma, nent, 0, op,
 						CMD_TIME_CLASS_B, status);
 				if (err || *status)
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
index 78152a8..c81fa8e 100644
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -836,7 +836,7 @@
 		dev->eq_table.clr_mask =
 			swab32(1 << (dev->eq_table.inta_pin & 31));
 		dev->eq_table.clr_int  = dev->clr_base +
-			(dev->eq_table.inta_pin < 31 ? 4 : 0);
+			(dev->eq_table.inta_pin < 32 ? 4 : 0);
 	}
 
 	dev->eq_table.arm_mask = 0;
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 1827400..7bd7a4b 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -290,7 +290,7 @@
 	int i;
 	u8 status;
 
-	num_icm = obj_size * nobj / MTHCA_TABLE_CHUNK_SIZE;
+	num_icm = (obj_size * nobj + MTHCA_TABLE_CHUNK_SIZE - 1) / MTHCA_TABLE_CHUNK_SIZE;
 
 	table = kmalloc(sizeof *table + num_icm * sizeof *table->icm, GFP_KERNEL);
 	if (!table)
@@ -529,12 +529,25 @@
 			goto found;
 		}
 
+	for (i = start; i != end; i += dir)
+		if (!dev->db_tab->page[i].db_rec) {
+			page = dev->db_tab->page + i;
+			goto alloc;
+		}
+
 	if (dev->db_tab->max_group1 >= dev->db_tab->min_group2 - 1) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
+	if (group == 0)
+		++dev->db_tab->max_group1;
+	else
+		--dev->db_tab->min_group2;
+
 	page = dev->db_tab->page + end;
+
+alloc:
 	page->db_rec = dma_alloc_coherent(&dev->pdev->dev, 4096,
 					  &page->mapping, GFP_KERNEL);
 	if (!page->db_rec) {
@@ -554,10 +567,6 @@
 	}
 
 	bitmap_zero(page->used, MTHCA_DB_REC_PER_PAGE);
-	if (group == 0)
-		++dev->db_tab->max_group1;
-	else
-		--dev->db_tab->min_group2;
 
 found:
 	j = find_first_zero_bit(page->used, MTHCA_DB_REC_PER_PAGE);
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 1c1c2e2..3f5319a 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -84,7 +84,7 @@
 	props->vendor_id           = be32_to_cpup((__be32 *) (out_mad->data + 36)) &
 		0xffffff;
 	props->vendor_part_id      = be16_to_cpup((__be16 *) (out_mad->data + 30));
-	props->hw_ver              = be16_to_cpup((__be16 *) (out_mad->data + 32));
+	props->hw_ver              = be32_to_cpup((__be32 *) (out_mad->data + 32));
 	memcpy(&props->sys_image_guid, out_mad->data +  4, 8);
 	memcpy(&props->node_guid,      out_mad->data + 12, 8);
 
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index e1f0d87..0b0ea26 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -287,12 +287,12 @@
 	init_waitqueue_head(&rd_queue);
 
 #ifdef CONFIG_PROC_FS
-	isdn_proc_entry = create_proc_entry("isdn", S_IFDIR | S_IRUGO | S_IXUGO, proc_net);
+	isdn_proc_entry = proc_mkdir("net/isdn", NULL);
 	if (!isdn_proc_entry)
 		return (-1);
 	isdn_divert_entry = create_proc_entry("divert", S_IFREG | S_IRUGO, isdn_proc_entry);
 	if (!isdn_divert_entry) {
-		remove_proc_entry("isdn", proc_net);
+		remove_proc_entry("net/isdn", NULL);
 		return (-1);
 	}
 	isdn_divert_entry->proc_fops = &isdn_fops; 
@@ -312,7 +312,7 @@
 
 #ifdef CONFIG_PROC_FS
 	remove_proc_entry("divert", isdn_proc_entry);
-	remove_proc_entry("isdn", proc_net);
+	remove_proc_entry("net/isdn", NULL);
 #endif	/* CONFIG_PROC_FS */
 
 	return (0);
diff --git a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c
index 7fdf8ae..27204f4 100644
--- a/drivers/isdn/hardware/eicon/diva_didd.c
+++ b/drivers/isdn/hardware/eicon/diva_didd.c
@@ -30,8 +30,6 @@
 static char *DRIVERLNAME = "divadidd";
 char *DRIVERRELEASE_DIDD = "2.0";
 
-static char *main_proc_dir = "eicon";
-
 MODULE_DESCRIPTION("DIDD table driver for diva drivers");
 MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
 MODULE_SUPPORTED_DEVICE("Eicon diva drivers");
@@ -89,7 +87,7 @@
 
 static int DIVA_INIT_FUNCTION create_proc(void)
 {
-	proc_net_eicon = create_proc_entry(main_proc_dir, S_IFDIR, proc_net);
+	proc_net_eicon = proc_mkdir("net/eicon", NULL);
 
 	if (proc_net_eicon) {
 		if ((proc_didd =
@@ -105,7 +103,7 @@
 static void DIVA_EXIT_FUNCTION remove_proc(void)
 {
 	remove_proc_entry(DRIVERLNAME, proc_net_eicon);
-	remove_proc_entry(main_proc_dir, proc_net);
+	remove_proc_entry("net/eicon", NULL);
 }
 
 static int DIVA_INIT_FUNCTION divadidd_init(void)
diff --git a/drivers/isdn/hardware/eicon/divasproc.c b/drivers/isdn/hardware/eicon/divasproc.c
index b643558..c12efa6 100644
--- a/drivers/isdn/hardware/eicon/divasproc.c
+++ b/drivers/isdn/hardware/eicon/divasproc.c
@@ -381,7 +381,7 @@
 	char tmp[16];
 
 	sprintf(tmp, "%s%d", adapter_dir_name, a->controller);
-	if (!(de = create_proc_entry(tmp, S_IFDIR, proc_net_eicon)))
+	if (!(de = proc_mkdir(tmp, proc_net_eicon)))
 		return (0);
 	a->proc_adapter_dir = (void *) de;
 
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 5da507e..639582f 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -394,7 +394,7 @@
 	hysdn_card *card;
 	uchar conf_name[20];
 
-	hysdn_proc_entry = create_proc_entry(PROC_SUBDIR_NAME, S_IFDIR | S_IRUGO | S_IXUGO, proc_net);
+	hysdn_proc_entry = proc_mkdir(PROC_SUBDIR_NAME, proc_net);
 	if (!hysdn_proc_entry) {
 		printk(KERN_ERR "HYSDN: unable to create hysdn subdir\n");
 		return (-1);
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 200a068..54ec737 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -230,11 +230,20 @@
 
 static void __hash_remove(struct hash_cell *hc)
 {
+	struct dm_table *table;
+
 	/* remove from the dev hash */
 	list_del(&hc->uuid_list);
 	list_del(&hc->name_list);
 	unregister_with_devfs(hc);
 	dm_set_mdptr(hc->md, NULL);
+
+	table = dm_get_table(hc->md);
+	if (table) {
+		dm_table_event(table);
+		dm_table_put(table);
+	}
+
 	dm_put(hc->md);
 	if (hc->new_map)
 		dm_table_put(hc->new_map);
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 785806b..f9b7b32 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -329,13 +329,17 @@
 /*
  * If we run out of usable paths, should we queue I/O or error it?
  */
-static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path)
+static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path,
+			    unsigned save_old_value)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&m->lock, flags);
 
-	m->saved_queue_if_no_path = m->queue_if_no_path;
+	if (save_old_value)
+		m->saved_queue_if_no_path = m->queue_if_no_path;
+	else
+		m->saved_queue_if_no_path = queue_if_no_path;
 	m->queue_if_no_path = queue_if_no_path;
 	if (!m->queue_if_no_path && m->queue_size)
 		queue_work(kmultipathd, &m->process_queued_ios);
@@ -677,7 +681,7 @@
 		return 0;
 
 	if (!strnicmp(shift(as), MESG_STR("queue_if_no_path")))
-		return queue_if_no_path(m, 1);
+		return queue_if_no_path(m, 1, 0);
 	else {
 		ti->error = "Unrecognised multipath feature request";
 		return -EINVAL;
@@ -1077,7 +1081,7 @@
 {
 	struct multipath *m = (struct multipath *) ti->private;
 
-	queue_if_no_path(m, 0);
+	queue_if_no_path(m, 0, 1);
 }
 
 /*
@@ -1222,9 +1226,9 @@
 
 	if (argc == 1) {
 		if (!strnicmp(argv[0], MESG_STR("queue_if_no_path")))
-			return queue_if_no_path(m, 1);
+			return queue_if_no_path(m, 1, 0);
 		else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path")))
-			return queue_if_no_path(m, 0);
+			return queue_if_no_path(m, 0, 0);
 	}
 
 	if (argc != 2)
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index 87d5f4d..eaf130e 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -100,8 +100,8 @@
 
 	ret = i2c_transfer (state->i2c, msg, 2);
 	if (ret != 2)
-		printk("DVB: TDA10021(%d): %s: readreg error (ret == %i)\n",
-				state->frontend.dvb->num, __FUNCTION__, ret);
+		printk("DVB: TDA10021: %s: readreg error (ret == %i)\n",
+				__FUNCTION__, ret);
 	return b1[0];
 }
 
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 8c08b7f..b7ec9bf 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -1397,7 +1397,7 @@
 
 static void proc_cpia_create(void)
 {
-	cpia_proc_root = create_proc_entry("cpia", S_IFDIR, NULL);
+	cpia_proc_root = proc_mkdir("cpia", NULL);
 
 	if (cpia_proc_root)
 		cpia_proc_root->owner = THIS_MODULE;
diff --git a/drivers/media/video/rds.h b/drivers/media/video/rds.h
index 30337d0..0d30eb7 100644
--- a/drivers/media/video/rds.h
+++ b/drivers/media/video/rds.h
@@ -31,7 +31,7 @@
 struct rds_command {
 	unsigned int  block_count;
 	int           result;
-	unsigned char *buffer;
+	unsigned char __user *buffer;
 	struct file   *instance;
 	poll_table    *event_list;
 };
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index 1a657a7..72b70eb 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -157,7 +157,7 @@
 
 /* ---------------------------------------------------------------------- */
 
-static int block_to_user_buf(struct saa6588 *s, unsigned char *user_buf)
+static int block_to_user_buf(struct saa6588 *s, unsigned char __user *user_buf)
 {
 	int i;
 
@@ -191,7 +191,7 @@
 {
 	unsigned long flags;
 
-	unsigned char *buf_ptr = a->buffer;	/* This is a user space buffer! */
+	unsigned char __user *buf_ptr = a->buffer;
 	unsigned int i;
 	unsigned int rd_blocks;
 
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index 5afe660..bbb0e6e 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -254,6 +254,6 @@
 module_exit(ixp4xx_flash_exit);
 
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems")
+MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems");
 MODULE_AUTHOR("Deepak Saxena");
 
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 32d5fab..a2c4dd4 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -99,7 +99,7 @@
 static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter*);
 
 #ifdef CONFIG_PROC_FS
-#define IBMVETH_PROC_DIR "ibmveth"
+#define IBMVETH_PROC_DIR "net/ibmveth"
 static struct proc_dir_entry *ibmveth_proc_dir;
 #endif
 
@@ -1010,7 +1010,7 @@
 #ifdef CONFIG_PROC_FS
 static void ibmveth_proc_register_driver(void)
 {
-	ibmveth_proc_dir = create_proc_entry(IBMVETH_PROC_DIR, S_IFDIR, proc_net);
+	ibmveth_proc_dir = proc_mkdir(IBMVETH_PROC_DIR, NULL);
 	if (ibmveth_proc_dir) {
 		SET_MODULE_OWNER(ibmveth_proc_dir);
 	}
@@ -1018,7 +1018,7 @@
 
 static void ibmveth_proc_unregister_driver(void)
 {
-	remove_proc_entry(IBMVETH_PROC_DIR, proc_net);
+	remove_proc_entry(IBMVETH_PROC_DIR, NULL);
 }
 
 static void *ibmveth_seq_start(struct seq_file *seq, loff_t *pos) 
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index 6d9de62..651c5a6 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -1875,11 +1875,11 @@
 
 	sirpulse = !!sirpulse;
 
-	/* create_proc_entry returns NULL if !CONFIG_PROC_FS.
+	/* proc_mkdir returns NULL if !CONFIG_PROC_FS.
 	 * Failure to create the procfs entry is handled like running
 	 * without procfs - it's not required for the driver to work.
 	 */
-	vlsi_proc_root = create_proc_entry(PROC_DIR, S_IFDIR, NULL);
+	vlsi_proc_root = proc_mkdir(PROC_DIR, NULL);
 	if (vlsi_proc_root) {
 		/* protect registered procdir against module removal.
 		 * Because we are in the module init path there's no race
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 82f236c..a842ecc 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -1070,7 +1070,7 @@
 {
 	struct proc_dir_entry *p;
 
-	p = create_proc_entry("pppoe", S_IRUGO, proc_net);
+	p = create_proc_entry("net/pppoe", S_IRUGO, NULL);
 	if (!p)
 		return -ENOMEM;
 
@@ -1142,7 +1142,7 @@
 	dev_remove_pack(&pppoes_ptype);
 	dev_remove_pack(&pppoed_ptype);
 	unregister_netdevice_notifier(&pppoe_notifier);
-	remove_proc_entry("pppoe", proc_net);
+	remove_proc_entry("net/pppoe", NULL);
 	proto_unregister(&pppoe_sk_proto);
 }
 
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index 2e72d79..b18c92c 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -235,7 +235,7 @@
  * Extern Function Prototypes
  *
  ******************************************************************************/
-static const char 	SKRootName[] = "sk98lin";
+static const char 	SKRootName[] = "net/sk98lin";
 static struct		proc_dir_entry *pSkRootDir;
 extern struct	file_operations sk_proc_fops;
 
@@ -5242,20 +5242,20 @@
 {
 	int error;
 
-	pSkRootDir = proc_mkdir(SKRootName, proc_net);
+	pSkRootDir = proc_mkdir(SKRootName, NULL);
 	if (pSkRootDir) 
 		pSkRootDir->owner = THIS_MODULE;
 	
 	error = pci_register_driver(&skge_driver);
 	if (error)
-		proc_net_remove(SKRootName);
+		remove_proc_entry(SKRootName, NULL);
 	return error;
 }
 
 static void __exit skge_exit(void)
 {
 	pci_unregister_driver(&skge_driver);
-	proc_net_remove(SKRootName);
+	remove_proc_entry(SKRootName, NULL);
 
 }
 
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 8de49fe..6deb7cc 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -2458,7 +2458,6 @@
 	dev->watchdog_timeo = HZ; /* 1 second timeout */
 	dev->get_stats = orinoco_get_stats;
 	dev->ethtool_ops = &orinoco_ethtool_ops;
-	dev->get_wireless_stats = orinoco_get_wireless_stats;
 	dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
 	dev->change_mtu = orinoco_change_mtu;
 	dev->set_multicast_list = orinoco_set_multicast_list;
@@ -4399,6 +4398,7 @@
 	.standard = orinoco_handler,
 	.private = orinoco_private_handler,
 	.private_args = orinoco_privtab,
+	.get_wireless_stats = orinoco_get_wireless_stats,
 };
 
 static void orinoco_get_drvinfo(struct net_device *dev,
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index c42455d..f9a5c70 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -691,7 +691,7 @@
 	unsigned long size = end - start + 1;
 	int ret = 0;
 
-	if (end <= start)
+	if (end < start)
 		return -EINVAL;
 
 	down(&rsrc_sem);
@@ -724,7 +724,7 @@
 	unsigned long size = end - start + 1;
 	int ret = 0;
 
-	if (end <= start)
+	if (end < start)
 		return -EINVAL;
 
 	if (end > IO_SPACE_LIMIT)
@@ -817,7 +817,7 @@
 
 	/* if we got at least one of IO, and one of MEM, we can be glad and
 	 * activate the PCMCIA subsystem */
-	if (done & (IORESOURCE_MEM | IORESOURCE_IO))
+	if (done == (IORESOURCE_MEM | IORESOURCE_IO))
 		s->resource_setup_done = 1;
 
 	return 0;
@@ -925,7 +925,7 @@
 				return -EINVAL;
 		}
 	}
-	if (end_addr <= start_addr)
+	if (end_addr < start_addr)
 		return -EINVAL;
 
 	ret = adjust_io(s, add, start_addr, end_addr);
@@ -977,7 +977,7 @@
 				return -EINVAL;
 		}
 	}
-	if (end_addr <= start_addr)
+	if (end_addr < start_addr)
 		return -EINVAL;
 
 	ret = adjust_memory(s, add, start_addr, end_addr);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 4d09a6e..ad94367 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -2849,8 +2849,7 @@
 	struct proc_dir_entry *pdep;
 	struct sg_proc_leaf * leaf;
 
-	sg_proc_sgp = create_proc_entry(sg_proc_sg_dirname,
-					S_IFDIR | S_IRUGO | S_IXUGO, NULL);
+	sg_proc_sgp = proc_mkdir(sg_proc_sg_dirname, NULL);
 	if (!sg_proc_sgp)
 		return 1;
 	for (k = 0; k < num_leaves; ++k) {
diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
index 4a5857c..0bc0b12 100644
--- a/drivers/usb/media/vicam.c
+++ b/drivers/usb/media/vicam.c
@@ -1148,7 +1148,7 @@
 static void
 vicam_create_proc_root(void)
 {
-	vicam_proc_root = create_proc_entry("video/vicam", S_IFDIR, 0);
+	vicam_proc_root = proc_mkdir("video/vicam", NULL);
 
 	if (vicam_proc_root)
 		vicam_proc_root->owner = THIS_MODULE;
@@ -1181,7 +1181,7 @@
 
 	sprintf(name, "video%d", cam->vdev.minor);
 
-	cam->proc_dir = create_proc_entry(name, S_IFDIR, vicam_proc_root);
+	cam->proc_dir = proc_mkdir(name, vicam_proc_root);
 
 	if ( !cam->proc_dir )
 		return; // FIXME: We should probably return an error here
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 773ae11..1cd942a 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -768,6 +768,7 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
+	select FB_SOFT_CURSOR
 	help
 	  This driver supports the on-board graphics built in to the Intel
           830M/845G/852GM/855GM/865G chipsets.
diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c
index ae2762c..6992100 100644
--- a/drivers/video/cyblafb.c
+++ b/drivers/video/cyblafb.c
@@ -410,20 +410,21 @@
 	out32(GE0C,point(image->dx+image->width-1,image->dy+image->height-1));
 
 	while(index < index_end) {
+		const char *p = image->data + index;
 		for(i=0;i<width_dds;i++) {
-			out32(GE9C,*((u32*) ((u32)image->data + index)));
+			out32(GE9C,*(u32*)p);
+			p+=4;
 			index+=4;
 		}
 		switch(width_dbs) {
 		case 0: break;
-		case 8:	out32(GE9C,*((u8*)((u32)image->data+index)));
+		case 8:	out32(GE9C,*(u8*)p);
 			index+=1;
 			break;
-		case 16: out32(GE9C,*((u16*)((u32)image->data+index)));
+		case 16: out32(GE9C,*(u16*)p);
 			index+=2;
 			break;
-		case 24: out32(GE9C,(u32)(*((u16*)((u32)image->data+index))) |
-			       (u32)(*((u8*)((u32)image->data+index+2)))<<16);
+		case 24: out32(GE9C,*(u16*)p | *(u8*)(p+2)<<16);
 			index+=3;
 			break;
 		}
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index fda53aa..689d258 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -44,7 +44,7 @@
 {
         struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
         struct i810fb_par         *par = chan->par;
-	u8                        *mmio = par->mmio_start_virtual;
+	u8                        __iomem *mmio = par->mmio_start_virtual;
 
 	i810_writel(mmio, GPIOB, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
 		    SCL_DIR_MASK | SCL_VAL_MASK);
@@ -55,7 +55,7 @@
 {
         struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
         struct i810fb_par         *par = chan->par;
-	u8                        *mmio = par->mmio_start_virtual;
+	u8                        __iomem *mmio = par->mmio_start_virtual;
 
  	i810_writel(mmio, GPIOB, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
 		    SDA_DIR_MASK | SDA_VAL_MASK);
@@ -66,7 +66,7 @@
 {
         struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
         struct i810fb_par         *par = chan->par;
-	u8                        *mmio = par->mmio_start_virtual;
+	u8                        __iomem *mmio = par->mmio_start_virtual;
 
 	i810_writel(mmio, GPIOB, SCL_DIR_MASK);
 	i810_writel(mmio, GPIOB, 0);
@@ -77,7 +77,7 @@
 {
         struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
         struct i810fb_par         *par = chan->par;
-	u8                        *mmio = par->mmio_start_virtual;
+	u8                        __iomem *mmio = par->mmio_start_virtual;
 
 	i810_writel(mmio, GPIOB, SDA_DIR_MASK);
 	i810_writel(mmio, GPIOB, 0);
@@ -88,7 +88,7 @@
 {
         struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
         struct i810fb_par       *par = chan->par;
-	u8                      *mmio = par->mmio_start_virtual;
+	u8                      __iomem *mmio = par->mmio_start_virtual;
 
 	i810_writel(mmio, GPIOA, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
 		    SCL_DIR_MASK | SCL_VAL_MASK);
@@ -99,7 +99,7 @@
 {
         struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
         struct i810fb_par         *par = chan->par;
-	u8                      *mmio = par->mmio_start_virtual;
+	u8                      __iomem *mmio = par->mmio_start_virtual;
 
  	i810_writel(mmio, GPIOA, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
 		    SDA_DIR_MASK | SDA_VAL_MASK);
@@ -110,7 +110,7 @@
 {
         struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
         struct i810fb_par         *par = chan->par;
-	u8                      *mmio = par->mmio_start_virtual;
+	u8                      __iomem *mmio = par->mmio_start_virtual;
 
 	i810_writel(mmio, GPIOA, SCL_DIR_MASK);
 	i810_writel(mmio, GPIOA, 0);
@@ -121,7 +121,7 @@
 {
         struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
         struct i810fb_par         *par = chan->par;
-	u8                      *mmio = par->mmio_start_virtual;
+	u8                      __iomem *mmio = par->mmio_start_virtual;
 
 	i810_writel(mmio, GPIOA, SDA_DIR_MASK);
 	i810_writel(mmio, GPIOA, 0);
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index bf62e6e..80a0934 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -226,7 +226,7 @@
 
 static int accel        = 1;
 static int vram         = 4;
-static int hwcursor     = 1;
+static int hwcursor     = 0;
 static int mtrr         = 1;
 static int fixed        = 0;
 static int noinit       = 0;
@@ -609,15 +609,9 @@
 		dinfo->accel = 0;
 	}
 
-	if (MB(voffset) < stolen_size)
-		offset = (stolen_size >> 12);
-	else
-		offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE;
-
 	/* Framebuffer parameters - Use all the stolen memory if >= vram */
-	if (ROUND_UP_TO_PAGE(stolen_size) >= ((offset << 12) +  MB(vram))) {
+	if (ROUND_UP_TO_PAGE(stolen_size) >= MB(vram)) {
 		dinfo->fb.size = ROUND_UP_TO_PAGE(stolen_size);
-		dinfo->fb.offset = 0;
 		dinfo->fbmem_gart = 0;
 	} else {
 		dinfo->fb.size =  MB(vram);
@@ -648,6 +642,11 @@
 		return -ENODEV;
 	}
 
+	if (MB(voffset) < stolen_size)
+		offset = (stolen_size >> 12);
+	else
+		offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE;
+
 	/* set the mem offsets - set them after the already used pages */
 	if (dinfo->accel) {
 		dinfo->ring.offset = offset + gtt_info.current_memory;
@@ -662,10 +661,11 @@
 			+ (dinfo->cursor.size >> 12);
 	}
 
+	/* Allocate memories (which aren't stolen) */
 	/* Map the fb and MMIO regions */
 	/* ioremap only up to the end of used aperture */
 	dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache
-		(dinfo->aperture.physical, (dinfo->fb.offset << 12)
+		(dinfo->aperture.physical, ((offset + dinfo->fb.offset) << 12)
 		 + dinfo->fb.size);
 	if (!dinfo->aperture.virtual) {
 		ERR_MSG("Cannot remap FB region.\n");
@@ -682,7 +682,6 @@
 		return -ENODEV;
 	}
 
-	/* Allocate memories (which aren't stolen) */
 	if (dinfo->accel) {
 		if (!(dinfo->gtt_ring_mem =
 		      agp_allocate_memory(bridge, dinfo->ring.size >> 12,
@@ -1484,7 +1483,7 @@
 #endif
 
 	if (!dinfo->hwcursor)
-		return -ENXIO;
+		return soft_cursor(info, cursor);
 
 	intelfbhw_cursor_hide(dinfo);
 
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 00c0223..5ab79af 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -228,8 +228,8 @@
  * information
 */
 
-static int s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
-				  struct fb_var_screeninfo *var)
+static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
+				   struct fb_var_screeninfo *var)
 {
 	fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK;
 
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index 821c9c4..d95f862 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -71,21 +71,28 @@
  *
  */
 
-struct v9fs_fid *v9fs_fid_create(struct dentry *dentry)
+struct v9fs_fid *v9fs_fid_create(struct dentry *dentry,
+	struct v9fs_session_info *v9ses, int fid, int create)
 {
 	struct v9fs_fid *new;
 
+	dprintk(DEBUG_9P, "fid create dentry %p, fid %d, create %d\n",
+		dentry, fid, create);
+
 	new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
 	if (new == NULL) {
 		dprintk(DEBUG_ERROR, "Out of Memory\n");
 		return ERR_PTR(-ENOMEM);
 	}
 
-	new->fid = -1;
+	new->fid = fid;
+	new->v9ses = v9ses;
 	new->fidopen = 0;
-	new->fidcreate = 0;
+	new->fidcreate = create;
 	new->fidclunked = 0;
 	new->iounit = 0;
+	new->rdir_pos = 0;
+	new->rdir_fcall = NULL;
 
 	if (v9fs_fid_insert(new, dentry) == 0)
 		return new;
@@ -109,6 +116,59 @@
 }
 
 /**
+ * v9fs_fid_walk_up - walks from the process current directory
+ * 	up to the specified dentry.
+ */
+static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry)
+{
+	int fidnum, cfidnum, err;
+	struct v9fs_fid *cfid;
+	struct dentry *cde;
+	struct v9fs_session_info *v9ses;
+
+	v9ses = v9fs_inode2v9ses(current->fs->pwd->d_inode);
+	cfid = v9fs_fid_lookup(current->fs->pwd);
+	if (cfid == NULL) {
+		dprintk(DEBUG_ERROR, "process cwd doesn't have a fid\n");
+		return ERR_PTR(-ENOENT);
+	}
+
+	cfidnum = cfid->fid;
+	cde = current->fs->pwd;
+	/* TODO: take advantage of multiwalk */
+
+	fidnum = v9fs_get_idpool(&v9ses->fidpool);
+	if (fidnum < 0) {
+		dprintk(DEBUG_ERROR, "could not get a new fid num\n");
+		err = -ENOENT;
+		goto clunk_fid;
+	}
+
+	while (cde != dentry) {
+		if (cde == cde->d_parent) {
+			dprintk(DEBUG_ERROR, "can't find dentry\n");
+			err = -ENOENT;
+			goto clunk_fid;
+		}
+
+		err = v9fs_t_walk(v9ses, cfidnum, fidnum, "..", NULL);
+		if (err < 0) {
+			dprintk(DEBUG_ERROR, "problem walking to parent\n");
+			goto clunk_fid;
+		}
+
+		cfidnum = fidnum;
+		cde = cde->d_parent;
+	}
+
+	return v9fs_fid_create(dentry, v9ses, fidnum, 0);
+
+clunk_fid:
+	v9fs_t_clunk(v9ses, fidnum, NULL);
+	return ERR_PTR(err);
+}
+
+/**
  * v9fs_fid_lookup - retrieve the right fid from a  particular dentry
  * @dentry: dentry to look for fid in
  * @type: intent of lookup (operation or traversal)
@@ -119,49 +179,25 @@
  *
  */
 
-struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry, int type)
+struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry)
 {
 	struct list_head *fid_list = (struct list_head *)dentry->d_fsdata;
 	struct v9fs_fid *current_fid = NULL;
 	struct v9fs_fid *temp = NULL;
 	struct v9fs_fid *return_fid = NULL;
-	int found_parent = 0;
-	int found_user = 0;
 
-	dprintk(DEBUG_9P, " dentry: %s (%p) type %d\n", dentry->d_iname, dentry,
-		type);
+	dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry);
 
-	if (fid_list && !list_empty(fid_list)) {
+	if (fid_list) {
 		list_for_each_entry_safe(current_fid, temp, fid_list, list) {
-			if (current_fid->uid == current->uid) {
-				if (return_fid == NULL) {
-					if ((type == FID_OP)
-					    || (!current_fid->fidopen)) {
-						return_fid = current_fid;
-						found_user = 1;
-					}
-				}
-			}
-			if (current_fid->pid == current->real_parent->pid) {
-				if ((return_fid == NULL) || (found_parent)
-				    || (found_user)) {
-					if ((type == FID_OP)
-					    || (!current_fid->fidopen)) {
-						return_fid = current_fid;
-						found_parent = 1;
-						found_user = 0;
-					}
-				}
-			}
-			if (current_fid->pid == current->pid) {
-				if ((type == FID_OP) ||
-				    (!current_fid->fidopen)) {
-					return_fid = current_fid;
-					found_parent = 0;
-					found_user = 0;
-				}
+			if (!current_fid->fidcreate) {
+				return_fid = current_fid;
+				break;
 			}
 		}
+
+		if (!return_fid)
+			return_fid = current_fid;
 	}
 
 	/* we are at the root but didn't match */
@@ -187,55 +223,33 @@
 
 /* XXX - there may be some duplication we can get rid of */
 		if (par == dentry) {
-			/* we need to fid_lookup the starting point */
-			int fidnum = -1;
-			int oldfid = -1;
-			int result = -1;
-			struct v9fs_session_info *v9ses =
-			    v9fs_inode2v9ses(current->fs->pwd->d_inode);
-
-			current_fid =
-			    v9fs_fid_lookup(current->fs->pwd, FID_WALK);
-			if (current_fid == NULL) {
-				dprintk(DEBUG_ERROR,
-					"process cwd doesn't have a fid\n");
-				return return_fid;
-			}
-			oldfid = current_fid->fid;
-			par = current->fs->pwd;
-			/* TODO: take advantage of multiwalk */
-
-			fidnum = v9fs_get_idpool(&v9ses->fidpool);
-			if (fidnum < 0) {
-				dprintk(DEBUG_ERROR,
-					"could not get a new fid num\n");
-				return return_fid;
-			}
-
-			while (par != dentry) {
-				result =
-				    v9fs_t_walk(v9ses, oldfid, fidnum, "..",
-						NULL);
-				if (result < 0) {
-					dprintk(DEBUG_ERROR,
-						"problem walking to parent\n");
-
-					break;
-				}
-				oldfid = fidnum;
-				if (par == par->d_parent) {
-					dprintk(DEBUG_ERROR,
-						"can't find dentry\n");
-					break;
-				}
-				par = par->d_parent;
-			}
-			if (par == dentry) {
-				return_fid = v9fs_fid_create(dentry);
-				return_fid->fid = fidnum;
-			}
+			return_fid = v9fs_fid_walk_up(dentry);
+			if (IS_ERR(return_fid))
+				return_fid = NULL;
 		}
 	}
 
 	return return_fid;
 }
+
+struct v9fs_fid *v9fs_fid_get_created(struct dentry *dentry)
+{
+	struct list_head *fid_list;
+	struct v9fs_fid *fid, *ftmp, *ret;
+
+	dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry);
+	fid_list = (struct list_head *)dentry->d_fsdata;
+	ret = NULL;
+	if (fid_list) {
+		list_for_each_entry_safe(fid, ftmp, fid_list, list) {
+			if (fid->fidcreate && fid->pid == current->pid) {
+				list_del(&fid->list);
+				ret = fid;
+				break;
+			}
+		}
+	}
+
+	dprintk(DEBUG_9P, "return %p\n", ret);
+	return ret;
+}
diff --git a/fs/9p/fid.h b/fs/9p/fid.h
index 7db478c..84c673a 100644
--- a/fs/9p/fid.h
+++ b/fs/9p/fid.h
@@ -25,6 +25,7 @@
 
 #define FID_OP   0
 #define FID_WALK 1
+#define FID_CREATE 2
 
 struct v9fs_fid {
 	struct list_head list;	 /* list of fids associated with a dentry */
@@ -52,6 +53,8 @@
 	struct v9fs_session_info *v9ses;	/* session info for this FID */
 };
 
-struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry, int type);
+struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry);
+struct v9fs_fid *v9fs_fid_get_created(struct dentry *);
 void v9fs_fid_destroy(struct v9fs_fid *fid);
-struct v9fs_fid *v9fs_fid_create(struct dentry *);
+struct v9fs_fid *v9fs_fid_create(struct dentry *,
+	struct v9fs_session_info *v9ses, int fid, int create);
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
index 306c967..a6aa947 100644
--- a/fs/9p/vfs_dentry.c
+++ b/fs/9p/vfs_dentry.c
@@ -67,7 +67,7 @@
 	struct dentry *dc = current->fs->pwd;
 
 	dprintk(DEBUG_VFS, "dentry: %s (%p)\n", dentry->d_iname, dentry);
-	if (v9fs_fid_lookup(dentry, FID_OP)) {
+	if (v9fs_fid_lookup(dentry)) {
 		dprintk(DEBUG_VFS, "VALID\n");
 		return 1;
 	}
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index c478a73..57a43b8 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -197,21 +197,18 @@
 	filemap_fdatawait(inode->i_mapping);
 
 	if (fidnum >= 0) {
-		fid->fidopen--;
 		dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen,
 			fid->fid);
 
-		if (fid->fidopen == 0) {
-			if (v9fs_t_clunk(v9ses, fidnum, NULL))
-				dprintk(DEBUG_ERROR, "clunk failed\n");
+		if (v9fs_t_clunk(v9ses, fidnum, NULL))
+			dprintk(DEBUG_ERROR, "clunk failed\n");
 
-			v9fs_put_idpool(fid->fid, &v9ses->fidpool);
-		}
+		v9fs_put_idpool(fid->fid, &v9ses->fidpool);
 
 		kfree(fid->rdir_fcall);
+		kfree(fid);
 
 		filp->private_data = NULL;
-		v9fs_fid_destroy(fid);
 	}
 
 	d_drop(filp->f_dentry);
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 1f8ae7d..a4799e9 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -53,30 +53,36 @@
 int v9fs_file_open(struct inode *inode, struct file *file)
 {
 	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
-	struct v9fs_fid *v9fid = v9fs_fid_lookup(file->f_dentry, FID_WALK);
-	struct v9fs_fid *v9newfid = NULL;
+	struct v9fs_fid *v9fid, *fid;
 	struct v9fs_fcall *fcall = NULL;
 	int open_mode = 0;
 	unsigned int iounit = 0;
 	int newfid = -1;
 	long result = -1;
 
-	dprintk(DEBUG_VFS, "inode: %p file: %p v9fid= %p\n", inode, file,
-		v9fid);
+	dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file);
+
+	v9fid = v9fs_fid_get_created(file->f_dentry);
+	if (!v9fid)
+		v9fid = v9fs_fid_lookup(file->f_dentry);
 
 	if (!v9fid) {
-		struct dentry *dentry = file->f_dentry;
 		dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n");
+		return -EBADF;
+	}
 
-		/* XXX - some duplication from lookup, generalize later */
-		/* basically vfs_lookup is too heavy weight */
-		v9fid = v9fs_fid_lookup(file->f_dentry, FID_OP);
-		if (!v9fid)
-			return -EBADF;
+	if (!v9fid->fidcreate) {
+		fid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
+		if (fid == NULL) {
+			dprintk(DEBUG_ERROR, "Out of Memory\n");
+			return -ENOMEM;
+		}
 
-		v9fid = v9fs_fid_lookup(dentry->d_parent, FID_WALK);
-		if (!v9fid)
-			return -EBADF;
+		fid->fidopen = 0;
+		fid->fidcreate = 0;
+		fid->fidclunked = 0;
+		fid->iounit = 0;
+		fid->v9ses = v9ses;
 
 		newfid = v9fs_get_idpool(&v9ses->fidpool);
 		if (newfid < 0) {
@@ -85,58 +91,16 @@
 		}
 
 		result =
-		    v9fs_t_walk(v9ses, v9fid->fid, newfid,
-				(char *)file->f_dentry->d_name.name, NULL);
+		    v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, NULL);
+
 		if (result < 0) {
 			v9fs_put_idpool(newfid, &v9ses->fidpool);
 			dprintk(DEBUG_ERROR, "rewalk didn't work\n");
 			return -EBADF;
 		}
 
-		v9fid = v9fs_fid_create(dentry);
-		if (v9fid == NULL) {
-			dprintk(DEBUG_ERROR, "couldn't insert\n");
-			return -ENOMEM;
-		}
-		v9fid->fid = newfid;
-	}
-
-	if (v9fid->fidcreate) {
-		/* create case */
-		newfid = v9fid->fid;
-		iounit = v9fid->iounit;
-		v9fid->fidcreate = 0;
-	} else {
-		if (!S_ISDIR(inode->i_mode))
-			newfid = v9fid->fid;
-		else {
-			newfid = v9fs_get_idpool(&v9ses->fidpool);
-			if (newfid < 0) {
-				eprintk(KERN_WARNING, "allocation failed\n");
-				return -ENOSPC;
-			}
-			/* This would be a somewhat critical clone */
-			result =
-			    v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL,
-					&fcall);
-			if (result < 0) {
-				dprintk(DEBUG_ERROR, "clone error: %s\n",
-					FCALL_ERROR(fcall));
-				kfree(fcall);
-				return result;
-			}
-
-			v9newfid = v9fs_fid_create(file->f_dentry);
-			v9newfid->fid = newfid;
-			v9newfid->qid = v9fid->qid;
-			v9newfid->iounit = v9fid->iounit;
-			v9newfid->fidopen = 0;
-			v9newfid->fidclunked = 0;
-			v9newfid->v9ses = v9ses;
-			v9fid = v9newfid;
-			kfree(fcall);
-		}
-
+		fid->fid = newfid;
+		v9fid = fid;
 		/* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
 		/* translate open mode appropriately */
 		open_mode = file->f_flags & 0x3;
@@ -163,9 +127,13 @@
 
 		iounit = fcall->params.ropen.iounit;
 		kfree(fcall);
+	} else {
+		/* create case */
+		newfid = v9fid->fid;
+		iounit = v9fid->iounit;
+		v9fid->fidcreate = 0;
 	}
 
-
 	file->private_data = v9fid;
 
 	v9fid->rdir_pos = 0;
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index b16322d..2b696ae 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -307,7 +307,7 @@
 	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
 	struct super_block *sb = dir->i_sb;
 	struct v9fs_fid *dirfid =
-	    v9fs_fid_lookup(file_dentry->d_parent, FID_WALK);
+	    v9fs_fid_lookup(file_dentry->d_parent);
 	struct v9fs_fid *fid = NULL;
 	struct inode *file_inode = NULL;
 	struct v9fs_fcall *fcall = NULL;
@@ -317,6 +317,7 @@
 	long newfid = -1;
 	int result = 0;
 	unsigned int iounit = 0;
+	int wfidno = -1;
 
 	perm = unixmode2p9mode(v9ses, perm);
 
@@ -350,7 +351,7 @@
 	if (result < 0) {
 		dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall));
 		v9fs_put_idpool(newfid, &v9ses->fidpool);
-		newfid = 0;
+		newfid = -1;
 		goto CleanUpFid;
 	}
 
@@ -369,20 +370,39 @@
 	qid = fcall->params.rcreate.qid;
 	kfree(fcall);
 
-	fid = v9fs_fid_create(file_dentry);
+	fid = v9fs_fid_create(file_dentry, v9ses, newfid, 1);
+	dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate);
 	if (!fid) {
 		result = -ENOMEM;
 		goto CleanUpFid;
 	}
 
-	fid->fid = newfid;
-	fid->fidopen = 0;
-	fid->fidcreate = 1;
 	fid->qid = qid;
 	fid->iounit = iounit;
-	fid->rdir_pos = 0;
-	fid->rdir_fcall = NULL;
-	fid->v9ses = v9ses;
+
+	/* walk to the newly created file and put the fid in the dentry */
+	wfidno = v9fs_get_idpool(&v9ses->fidpool);
+	if (newfid < 0) {
+		eprintk(KERN_WARNING, "no free fids available\n");
+		return -ENOSPC;
+	}
+
+	result = v9fs_t_walk(v9ses, dirfidnum, wfidno,
+		(char *) file_dentry->d_name.name, NULL);
+	if (result < 0) {
+		dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall));
+		v9fs_put_idpool(wfidno, &v9ses->fidpool);
+		wfidno = -1;
+		goto CleanUpFid;
+	}
+
+	if (!v9fs_fid_create(file_dentry, v9ses, wfidno, 0)) {
+		if (!v9fs_t_clunk(v9ses, newfid, &fcall)) {
+			v9fs_put_idpool(wfidno, &v9ses->fidpool);
+		}
+
+		goto CleanUpFid;
+	}
 
 	if ((perm & V9FS_DMSYMLINK) || (perm & V9FS_DMLINK) ||
 	    (perm & V9FS_DMNAMEDPIPE) || (perm & V9FS_DMSOCKET) ||
@@ -410,11 +430,11 @@
 	d_instantiate(file_dentry, file_inode);
 
 	if (perm & V9FS_DMDIR) {
-		if (v9fs_t_clunk(v9ses, newfid, &fcall))
+		if (!v9fs_t_clunk(v9ses, newfid, &fcall))
+			v9fs_put_idpool(newfid, &v9ses->fidpool);
+		else
 			dprintk(DEBUG_ERROR, "clunk for mkdir failed: %s\n",
 				FCALL_ERROR(fcall));
-
-		v9fs_put_idpool(newfid, &v9ses->fidpool);
 		kfree(fcall);
 		fid->fidopen = 0;
 		fid->fidcreate = 0;
@@ -426,12 +446,22 @@
       CleanUpFid:
 	kfree(fcall);
 
-	if (newfid) {
-		if (v9fs_t_clunk(v9ses, newfid, &fcall))
+	if (newfid >= 0) {
+		if (!v9fs_t_clunk(v9ses, newfid, &fcall))
+			v9fs_put_idpool(newfid, &v9ses->fidpool);
+		else
 			dprintk(DEBUG_ERROR, "clunk failed: %s\n",
 				FCALL_ERROR(fcall));
 
-		v9fs_put_idpool(newfid, &v9ses->fidpool);
+		kfree(fcall);
+	}
+	if (wfidno >= 0) {
+		if (!v9fs_t_clunk(v9ses, wfidno, &fcall))
+			v9fs_put_idpool(wfidno, &v9ses->fidpool);
+		else
+			dprintk(DEBUG_ERROR, "clunk failed: %s\n",
+				FCALL_ERROR(fcall));
+
 		kfree(fcall);
 	}
 	return result;
@@ -461,7 +491,7 @@
 	file_inode = file->d_inode;
 	sb = file_inode->i_sb;
 	v9ses = v9fs_inode2v9ses(file_inode);
-	v9fid = v9fs_fid_lookup(file, FID_OP);
+	v9fid = v9fs_fid_lookup(file);
 
 	if (!v9fid) {
 		dprintk(DEBUG_ERROR,
@@ -545,7 +575,7 @@
 
 	sb = dir->i_sb;
 	v9ses = v9fs_inode2v9ses(dir);
-	dirfid = v9fs_fid_lookup(dentry->d_parent, FID_WALK);
+	dirfid = v9fs_fid_lookup(dentry->d_parent);
 
 	if (!dirfid) {
 		dprintk(DEBUG_ERROR, "no dirfid\n");
@@ -573,7 +603,7 @@
 		v9fs_put_idpool(newfid, &v9ses->fidpool);
 		if (result == -ENOENT) {
 			d_add(dentry, NULL);
-			dprintk(DEBUG_ERROR,
+			dprintk(DEBUG_VFS,
 				"Return negative dentry %p count %d\n",
 				dentry, atomic_read(&dentry->d_count));
 			return NULL;
@@ -601,16 +631,13 @@
 
 	inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat->qid);
 
-	fid = v9fs_fid_create(dentry);
+	fid = v9fs_fid_create(dentry, v9ses, newfid, 0);
 	if (fid == NULL) {
 		dprintk(DEBUG_ERROR, "couldn't insert\n");
 		result = -ENOMEM;
 		goto FreeFcall;
 	}
 
-	fid->fid = newfid;
-	fid->fidopen = 0;
-	fid->v9ses = v9ses;
 	fid->qid = fcall->params.rstat.stat->qid;
 
 	dentry->d_op = &v9fs_dentry_operations;
@@ -665,11 +692,11 @@
 {
 	struct inode *old_inode = old_dentry->d_inode;
 	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode);
-	struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry, FID_WALK);
+	struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry);
 	struct v9fs_fid *olddirfid =
-	    v9fs_fid_lookup(old_dentry->d_parent, FID_WALK);
+	    v9fs_fid_lookup(old_dentry->d_parent);
 	struct v9fs_fid *newdirfid =
-	    v9fs_fid_lookup(new_dentry->d_parent, FID_WALK);
+	    v9fs_fid_lookup(new_dentry->d_parent);
 	struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
 	struct v9fs_fcall *fcall = NULL;
 	int fid = -1;
@@ -744,7 +771,7 @@
 {
 	struct v9fs_fcall *fcall = NULL;
 	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
-	struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP);
+	struct v9fs_fid *fid = v9fs_fid_lookup(dentry);
 	int err = -EPERM;
 
 	dprintk(DEBUG_VFS, "dentry: %p\n", dentry);
@@ -778,7 +805,7 @@
 static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
 {
 	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
-	struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP);
+	struct v9fs_fid *fid = v9fs_fid_lookup(dentry);
 	struct v9fs_fcall *fcall = NULL;
 	struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
 	int res = -EPERM;
@@ -960,7 +987,7 @@
 	if (retval != 0)
 		goto FreeFcall;
 
-	newfid = v9fs_fid_lookup(dentry, FID_OP);
+	newfid = v9fs_fid_lookup(dentry);
 
 	/* issue a twstat */
 	v9fs_blank_mistat(v9ses, mistat);
@@ -1004,7 +1031,7 @@
 
 	struct v9fs_fcall *fcall = NULL;
 	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
-	struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP);
+	struct v9fs_fid *fid = v9fs_fid_lookup(dentry);
 
 	if (!fid) {
 		dprintk(DEBUG_ERROR, "could not resolve fid from dentry\n");
@@ -1148,7 +1175,7 @@
 	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
 	struct v9fs_fcall *fcall = NULL;
 	struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
-	struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry, FID_OP);
+	struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry);
 	struct v9fs_fid *newfid = NULL;
 	char *symname = __getname();
 
@@ -1168,7 +1195,7 @@
 	if (retval != 0)
 		goto FreeMem;
 
-	newfid = v9fs_fid_lookup(dentry, FID_OP);
+	newfid = v9fs_fid_lookup(dentry);
 	if (!newfid) {
 		dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n");
 		goto FreeMem;
@@ -1246,7 +1273,7 @@
 	if (retval != 0)
 		goto FreeMem;
 
-	newfid = v9fs_fid_lookup(dentry, FID_OP);
+	newfid = v9fs_fid_lookup(dentry);
 	if (!newfid) {
 		dprintk(DEBUG_ERROR, "coudn't resove fid from dentry\n");
 		retval = -EINVAL;
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 1e2b2b5..0957f4d 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -129,8 +129,7 @@
 
 	if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) {
 		dprintk(DEBUG_ERROR, "problem initiating session\n");
-		kfree(v9ses);
-		return ERR_PTR(newfid);
+		return newfid;
 	}
 
 	sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
@@ -155,23 +154,19 @@
 
 	sb->s_root = root;
 
-	/* Setup the Root Inode */
-	root_fid = v9fs_fid_create(root);
-	if (root_fid == NULL) {
-		retval = -ENOMEM;
-		goto put_back_sb;
-	}
-
-	root_fid->fidopen = 0;
-	root_fid->v9ses = v9ses;
-
 	stat_result = v9fs_t_stat(v9ses, newfid, &fcall);
 	if (stat_result < 0) {
 		dprintk(DEBUG_ERROR, "stat error\n");
 		v9fs_t_clunk(v9ses, newfid, NULL);
 		v9fs_put_idpool(newfid, &v9ses->fidpool);
 	} else {
-		root_fid->fid = newfid;
+		/* Setup the Root Inode */
+		root_fid = v9fs_fid_create(root, v9ses, newfid, 0);
+		if (root_fid == NULL) {
+			retval = -ENOMEM;
+			goto put_back_sb;
+		}
+
 		root_fid->qid = fcall->params.rstat.stat->qid;
 		root->d_inode->i_ino =
 		    v9fs_qid2ino(&fcall->params.rstat.stat->qid);
diff --git a/fs/Kconfig b/fs/Kconfig
index 068ccea..48f5422 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -472,6 +472,9 @@
 	  utilities is available from the FUSE homepage:
 	  <http://fuse.sourceforge.net/>
 
+	  See <file:Documentation/filesystems/fuse.txt> for more information.
+	  See <file:Documentation/Changes> for needed library/utility version.
+
 	  If you want to develop a userspace FS, or if you want to use
 	  a filesystem based on FUSE, answer Y or M.
 
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 403b90a..4284cd3 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -101,6 +101,10 @@
 /* Maximum number of poll wake up nests we are allowing */
 #define EP_MAX_POLLWAKE_NESTS 4
 
+/* Maximum msec timeout value storeable in a long int */
+#define EP_MAX_MSTIMEO min(1000ULL * MAX_SCHEDULE_TIMEOUT / HZ, (LONG_MAX - 999ULL) / HZ)
+
+
 struct epoll_filefd {
 	struct file *file;
 	int fd;
@@ -1506,8 +1510,8 @@
 	 * and the overflow condition. The passed timeout is in milliseconds,
 	 * that why (t * HZ) / 1000.
 	 */
-	jtimeout = timeout == -1 || timeout > (MAX_SCHEDULE_TIMEOUT - 1000) / HZ ?
-		MAX_SCHEDULE_TIMEOUT: (timeout * HZ + 999) / 1000;
+	jtimeout = (timeout < 0 || timeout >= EP_MAX_MSTIMEO) ?
+		MAX_SCHEDULE_TIMEOUT : (timeout * HZ + 999) / 1000;
 
 retry:
 	write_lock_irqsave(&ep->lock, flags);
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index c8d0703..e2d6208 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -605,27 +605,28 @@
 	insert_inode_hash(inode);
 
 	if (DQUOT_ALLOC_INODE(inode)) {
-		DQUOT_DROP(inode);
 		err = -ENOSPC;
-		goto fail2;
+		goto fail_drop;
 	}
+
 	err = ext2_init_acl(inode, dir);
-	if (err) {
-		DQUOT_FREE_INODE(inode);
-		DQUOT_DROP(inode);
-		goto fail2;
-	}
+	if (err)
+		goto fail_free_drop;
+
 	err = ext2_init_security(inode,dir);
-	if (err) {
-		DQUOT_FREE_INODE(inode);
-		goto fail2;
-	}
+	if (err)
+		goto fail_free_drop;
+
 	mark_inode_dirty(inode);
 	ext2_debug("allocating inode %lu\n", inode->i_ino);
 	ext2_preread_inode(inode);
 	return inode;
 
-fail2:
+fail_free_drop:
+	DQUOT_FREE_INODE(inode);
+
+fail_drop:
+	DQUOT_DROP(inode);
 	inode->i_flags |= S_NOQUOTA;
 	inode->i_nlink = 0;
 	iput(inode);
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 9655276..6549945 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -597,27 +597,22 @@
 
 	ret = inode;
 	if(DQUOT_ALLOC_INODE(inode)) {
-		DQUOT_DROP(inode);
 		err = -EDQUOT;
-		goto fail2;
+		goto fail_drop;
 	}
+
 	err = ext3_init_acl(handle, inode, dir);
-	if (err) {
-		DQUOT_FREE_INODE(inode);
-		DQUOT_DROP(inode);
-		goto fail2;
-  	}
+	if (err)
+		goto fail_free_drop;
+
 	err = ext3_init_security(handle,inode, dir);
-	if (err) {
-		DQUOT_FREE_INODE(inode);
-		goto fail2;
-	}
+	if (err)
+		goto fail_free_drop;
+
 	err = ext3_mark_inode_dirty(handle, inode);
 	if (err) {
 		ext3_std_error(sb, err);
-		DQUOT_FREE_INODE(inode);
-		DQUOT_DROP(inode);
-		goto fail2;
+		goto fail_free_drop;
 	}
 
 	ext3_debug("allocating inode %lu\n", inode->i_ino);
@@ -631,7 +626,11 @@
 	brelse(bitmap_bh);
 	return ret;
 
-fail2:
+fail_free_drop:
+	DQUOT_FREE_INODE(inode);
+
+fail_drop:
+	DQUOT_DROP(inode);
 	inode->i_flags |= S_NOQUOTA;
 	inode->i_nlink = 0;
 	iput(inode);
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index e79e49b..29f1e9f 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -96,6 +96,8 @@
 	fuse_lookup_init(req, dir, entry, &outarg);
 	request_send(fc, req);
 	err = req->out.h.error;
+	if (!err && (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID))
+		err = -EIO;
 	if (!err) {
 		inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
 				  &outarg.attr);
@@ -152,6 +154,10 @@
 		fuse_put_request(fc, req);
 		return err;
 	}
+	if (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID) {
+		fuse_put_request(fc, req);
+		return -EIO;
+	}
 	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
 			  &outarg.attr);
 	if (!inode) {
diff --git a/include/asm-arm/arch-rpc/hardware.h b/include/asm-arm/arch-rpc/hardware.h
index be9754a..9d7f873 100644
--- a/include/asm-arm/arch-rpc/hardware.h
+++ b/include/asm-arm/arch-rpc/hardware.h
@@ -15,7 +15,7 @@
 #include <asm/arch/memory.h>
 
 #ifndef __ASSEMBLY__
-#define IOMEM(x) ((void __iomem *)(x))
+#define IOMEM(x) ((void __iomem *)(unsigned long)(x))
 #else
 #define IOMEM(x) x
 #endif /* __ASSEMBLY__ */
@@ -52,7 +52,7 @@
 /*
  * IO Addresses
  */
-#define VIDC_BASE		(void __iomem *)0xe0400000
+#define VIDC_BASE		IOMEM(0xe0400000)
 #define EXPMASK_BASE		0xe0360000
 #define IOMD_BASE		IOMEM(0xe0200000)
 #define IOC_BASE		IOMEM(0xe0200000)
diff --git a/include/asm-arm/arch-versatile/io.h b/include/asm-arm/arch-versatile/io.h
index 9f895bf..47e904c 100644
--- a/include/asm-arm/arch-versatile/io.h
+++ b/include/asm-arm/arch-versatile/io.h
@@ -22,7 +22,11 @@
 
 #define IO_SPACE_LIMIT 0xffffffff
 
-#define __io(a)			((void __iomem *)(a))
+static inline void __iomem *__io(unsigned long addr)
+{
+	return (void __iomem *)addr;
+}
+#define __io(a)	__io(a)
 #define __mem_pci(a)		(a)
 #define __mem_isa(a)		(a)
 
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index f86c1e5..ff28c8b 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -158,6 +158,19 @@
 #define lazy_mmu_prot_update(pte)	do { } while (0)
 #endif
 
+#ifndef __HAVE_ARCH_MULTIPLE_ZERO_PAGE
+#define move_pte(pte, prot, old_addr, new_addr)	(pte)
+#else
+#define move_pte(pte, prot, old_addr, new_addr)				\
+({									\
+ 	pte_t newpte = (pte);						\
+	if (pte_present(pte) && pfn_valid(pte_pfn(pte)) &&		\
+			pte_page(pte) == ZERO_PAGE(old_addr))		\
+		newpte = mk_pte(ZERO_PAGE(new_addr), (prot));		\
+	newpte;								\
+})
+#endif
+
 /*
  * When walking page tables, get the address of the next boundary,
  * or the end address of the range if that comes earlier.  Although no
diff --git a/include/asm-ia64/uaccess.h b/include/asm-ia64/uaccess.h
index 3a7829b..9adb512 100644
--- a/include/asm-ia64/uaccess.h
+++ b/include/asm-ia64/uaccess.h
@@ -187,8 +187,8 @@
 ({											\
 	const __typeof__(*(ptr)) __user *__gu_ptr = (ptr);				\
 	__typeof__ (size) __gu_size = (size);						\
-	long __gu_err = -EFAULT, __gu_val = 0;						\
-											\
+	long __gu_err = -EFAULT;							\
+	unsigned long __gu_val = 0;							\
 	if (!check || __access_ok(__gu_ptr, size, segment))				\
 		switch (__gu_size) {							\
 		      case 1: __get_user_size(__gu_val, __gu_ptr, 1, __gu_err); break;	\
@@ -240,13 +240,13 @@
 static inline unsigned long
 __copy_to_user (void __user *to, const void *from, unsigned long count)
 {
-	return __copy_user(to, (void __user *) from, count);
+	return __copy_user(to, (__force void __user *) from, count);
 }
 
 static inline unsigned long
 __copy_from_user (void *to, const void __user *from, unsigned long count)
 {
-	return __copy_user((void __user *) to, from, count);
+	return __copy_user((__force void __user *) to, from, count);
 }
 
 #define __copy_to_user_inatomic		__copy_to_user
@@ -258,7 +258,7 @@
 	long __cu_len = (n);								\
 											\
 	if (__access_ok(__cu_to, __cu_len, get_fs()))					\
-		__cu_len = __copy_user(__cu_to, (void __user *) __cu_from, __cu_len);	\
+		__cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len);	\
 	__cu_len;									\
 })
 
@@ -270,7 +270,7 @@
 											\
 	__chk_user_ptr(__cu_from);							\
 	if (__access_ok(__cu_from, __cu_len, get_fs()))					\
-		__cu_len = __copy_user((void __user *) __cu_to, __cu_from, __cu_len);	\
+		__cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len);	\
 	__cu_len;									\
 })
 
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
index cbd1672..eaf5d9b 100644
--- a/include/asm-mips/pgtable.h
+++ b/include/asm-mips/pgtable.h
@@ -68,6 +68,8 @@
 #define ZERO_PAGE(vaddr) \
 	(virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))
 
+#define __HAVE_ARCH_MULTIPLE_ZERO_PAGE
+
 extern void paging_init(void);
 
 /*
diff --git a/include/asm-ppc/mv64x60.h b/include/asm-ppc/mv64x60.h
index 75c2ffa..ee2f918 100644
--- a/include/asm-ppc/mv64x60.h
+++ b/include/asm-ppc/mv64x60.h
@@ -233,7 +233,7 @@
 struct mv64x60_handle {
 	u32		type;		/* type of bridge */
 	u32		rev;		/* revision of bridge */
-	void		*v_base;	/* virtual base addr of bridge regs */
+	void		__iomem *v_base;/* virtual base addr of bridge regs */
 	phys_addr_t	p_base;		/* physical base addr of bridge regs */
 
 	u32		pci_mode_a;	/* pci 0 mode: conventional pci, pci-x*/
@@ -303,7 +303,7 @@
 	u32 cfg_data, struct pci_controller **hose);
 int mv64x60_get_type(struct mv64x60_handle *bh);
 int mv64x60_setup_for_chip(struct mv64x60_handle *bh);
-void *mv64x60_get_bridge_vbase(void);
+void __iomem *mv64x60_get_bridge_vbase(void);
 u32 mv64x60_get_bridge_type(void);
 u32 mv64x60_get_bridge_rev(void);
 void mv64x60_get_mem_windows(struct mv64x60_handle *bh,
diff --git a/include/asm-ppc64/tlbflush.h b/include/asm-ppc64/tlbflush.h
index 45411a6..74271d7 100644
--- a/include/asm-ppc64/tlbflush.h
+++ b/include/asm-ppc64/tlbflush.h
@@ -25,6 +25,7 @@
 	pte_t pte[PPC64_TLB_BATCH_NR];
 	unsigned long addr[PPC64_TLB_BATCH_NR];
 	unsigned long vaddr[PPC64_TLB_BATCH_NR];
+	unsigned int large;
 };
 DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
 
diff --git a/include/asm-ppc64/uaccess.h b/include/asm-ppc64/uaccess.h
index c181a60d..132c127 100644
--- a/include/asm-ppc64/uaccess.h
+++ b/include/asm-ppc64/uaccess.h
@@ -164,7 +164,8 @@
 
 #define __get_user_nocheck(x,ptr,size)				\
 ({								\
-	long __gu_err, __gu_val;				\
+	long __gu_err;						\
+	unsigned long __gu_val;					\
 	might_sleep();						\
 	__get_user_size(__gu_val,(ptr),(size),__gu_err,-EFAULT);\
 	(x) = (__typeof__(*(ptr)))__gu_val;			\
@@ -173,7 +174,8 @@
 
 #define __get_user_check(x,ptr,size)					\
 ({									\
-	long __gu_err = -EFAULT, __gu_val = 0;				\
+	long __gu_err = -EFAULT;					\
+	unsigned long __gu_val = 0;					\
 	const __typeof__(*(ptr)) __user *__gu_addr = (ptr);		\
 	might_sleep();							\
 	if (access_ok(VERIFY_READ,__gu_addr,size))			\
diff --git a/include/asm-s390/sigcontext.h b/include/asm-s390/sigcontext.h
index d57bc0c..8035453 100644
--- a/include/asm-s390/sigcontext.h
+++ b/include/asm-s390/sigcontext.h
@@ -61,7 +61,7 @@
 struct sigcontext
 {
 	unsigned long	oldmask[_SIGCONTEXT_NSIG_WORDS];
-	_sigregs        *sregs;
+	_sigregs        __user *sregs;
 };
 
 
diff --git a/include/asm-s390/signal.h b/include/asm-s390/signal.h
index 3d6e11c..7084626 100644
--- a/include/asm-s390/signal.h
+++ b/include/asm-s390/signal.h
@@ -165,7 +165,7 @@
 #endif /* __KERNEL__ */
 
 typedef struct sigaltstack {
-        void *ss_sp;
+        void __user *ss_sp;
         int ss_flags;
         size_t ss_size;
 } stack_t;
diff --git a/include/asm-sparc64/head.h b/include/asm-sparc64/head.h
index b63a33c..0abd3a6 100644
--- a/include/asm-sparc64/head.h
+++ b/include/asm-sparc64/head.h
@@ -12,9 +12,12 @@
 #define __JALAPENO_ID	0x003e0016
 
 #define CHEETAH_MANUF		0x003e
-#define CHEETAH_IMPL		0x0014
-#define CHEETAH_PLUS_IMPL	0x0015
-#define JALAPENO_IMPL		0x0016
+#define CHEETAH_IMPL		0x0014 /* Ultra-III   */
+#define CHEETAH_PLUS_IMPL	0x0015 /* Ultra-III+  */
+#define JALAPENO_IMPL		0x0016 /* Ultra-IIIi  */
+#define JAGUAR_IMPL		0x0018 /* Ultra-IV    */
+#define PANTHER_IMPL		0x0019 /* Ultra-IV+   */
+#define SERRANO_IMPL		0x0022 /* Ultra-IIIi+ */
 
 #define BRANCH_IF_CHEETAH_BASE(tmp1,tmp2,label)	\
 	rdpr	%ver, %tmp1;			\
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index 43cbb08..53d612a 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -98,7 +98,9 @@
 #define _PAGE_NFO	_AC(0x1000000000000000,UL) /* No Fault Only          */
 #define _PAGE_IE	_AC(0x0800000000000000,UL) /* Invert Endianness      */
 #define _PAGE_SOFT2	_AC(0x07FC000000000000,UL) /* Software bits, set 2   */
-#define _PAGE_RES1	_AC(0x0003000000000000,UL) /* Reserved               */
+#define _PAGE_RES1	_AC(0x0002000000000000,UL) /* Reserved               */
+#define _PAGE_SZ32MB	_AC(0x0001000000000000,UL) /* (Panther) 32MB page    */
+#define _PAGE_SZ256MB	_AC(0x2001000000000000,UL) /* (Panther) 256MB page   */
 #define _PAGE_SN	_AC(0x0000800000000000,UL) /* (Cheetah) Snoop        */
 #define _PAGE_RES2	_AC(0x0000780000000000,UL) /* Reserved               */
 #define _PAGE_PADDR_SF	_AC(0x000001FFFFFFE000,UL) /* (Spitfire) paddr[40:13]*/
diff --git a/include/linux/key-ui.h b/include/linux/key-ui.h
index cc326174..918c34a 100644
--- a/include/linux/key-ui.h
+++ b/include/linux/key-ui.h
@@ -42,11 +42,14 @@
 /*
  * check to see whether permission is granted to use a key in the desired way
  */
-static inline int key_permission(const struct key *key, key_perm_t perm)
+static inline int key_permission(const key_ref_t key_ref, key_perm_t perm)
 {
+	struct key *key = key_ref_to_ptr(key_ref);
 	key_perm_t kperm;
 
-	if (key->uid == current->fsuid)
+	if (is_key_possessed(key_ref))
+		kperm = key->perm >> 24;
+	else if (key->uid == current->fsuid)
 		kperm = key->perm >> 16;
 	else if (key->gid != -1 &&
 		 key->perm & KEY_GRP_ALL &&
@@ -65,11 +68,14 @@
  * check to see whether permission is granted to use a key in at least one of
  * the desired ways
  */
-static inline int key_any_permission(const struct key *key, key_perm_t perm)
+static inline int key_any_permission(const key_ref_t key_ref, key_perm_t perm)
 {
+	struct key *key = key_ref_to_ptr(key_ref);
 	key_perm_t kperm;
 
-	if (key->uid == current->fsuid)
+	if (is_key_possessed(key_ref))
+		kperm = key->perm >> 24;
+	else if (key->uid == current->fsuid)
 		kperm = key->perm >> 16;
 	else if (key->gid != -1 &&
 		 key->perm & KEY_GRP_ALL &&
@@ -94,13 +100,17 @@
 	return ret;
 }
 
-static inline int key_task_permission(const struct key *key,
+static inline int key_task_permission(const key_ref_t key_ref,
 				      struct task_struct *context,
 				      key_perm_t perm)
 {
+	struct key *key = key_ref_to_ptr(key_ref);
 	key_perm_t kperm;
 
-	if (key->uid == context->fsuid) {
+	if (is_key_possessed(key_ref)) {
+		kperm = key->perm >> 24;
+	}
+	else if (key->uid == context->fsuid) {
 		kperm = key->perm >> 16;
 	}
 	else if (key->gid != -1 &&
@@ -121,9 +131,9 @@
 
 }
 
-extern struct key *lookup_user_key(struct task_struct *context,
-				   key_serial_t id, int create, int partial,
-				   key_perm_t perm);
+extern key_ref_t lookup_user_key(struct task_struct *context,
+				 key_serial_t id, int create, int partial,
+				 key_perm_t perm);
 
 extern long join_session_keyring(const char *name);
 
diff --git a/include/linux/key.h b/include/linux/key.h
index 970bbd9..f1efa01 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -35,11 +35,18 @@
 
 #undef KEY_DEBUGGING
 
-#define KEY_USR_VIEW	0x00010000	/* user can view a key's attributes */
-#define KEY_USR_READ	0x00020000	/* user can read key payload / view keyring */
-#define KEY_USR_WRITE	0x00040000	/* user can update key payload / add link to keyring */
-#define KEY_USR_SEARCH	0x00080000	/* user can find a key in search / search a keyring */
-#define KEY_USR_LINK	0x00100000	/* user can create a link to a key/keyring */
+#define KEY_POS_VIEW	0x01000000	/* possessor can view a key's attributes */
+#define KEY_POS_READ	0x02000000	/* possessor can read key payload / view keyring */
+#define KEY_POS_WRITE	0x04000000	/* possessor can update key payload / add link to keyring */
+#define KEY_POS_SEARCH	0x08000000	/* possessor can find a key in search / search a keyring */
+#define KEY_POS_LINK	0x10000000	/* possessor can create a link to a key/keyring */
+#define KEY_POS_ALL	0x1f000000
+
+#define KEY_USR_VIEW	0x00010000	/* user permissions... */
+#define KEY_USR_READ	0x00020000
+#define KEY_USR_WRITE	0x00040000
+#define KEY_USR_SEARCH	0x00080000
+#define KEY_USR_LINK	0x00100000
 #define KEY_USR_ALL	0x001f0000
 
 #define KEY_GRP_VIEW	0x00000100	/* group permissions... */
@@ -67,6 +74,38 @@
 
 /*****************************************************************************/
 /*
+ * key reference with possession attribute handling
+ *
+ * NOTE! key_ref_t is a typedef'd pointer to a type that is not actually
+ * defined. This is because we abuse the bottom bit of the reference to carry a
+ * flag to indicate whether the calling process possesses that key in one of
+ * its keyrings.
+ *
+ * the key_ref_t has been made a separate type so that the compiler can reject
+ * attempts to dereference it without proper conversion.
+ *
+ * the three functions are used to assemble and disassemble references
+ */
+typedef struct __key_reference_with_attributes *key_ref_t;
+
+static inline key_ref_t make_key_ref(const struct key *key,
+				     unsigned long possession)
+{
+	return (key_ref_t) ((unsigned long) key | possession);
+}
+
+static inline struct key *key_ref_to_ptr(const key_ref_t key_ref)
+{
+	return (struct key *) ((unsigned long) key_ref & ~1UL);
+}
+
+static inline unsigned long is_key_possessed(const key_ref_t key_ref)
+{
+	return (unsigned long) key_ref & 1UL;
+}
+
+/*****************************************************************************/
+/*
  * authentication token / access credential / keyring
  * - types of key include:
  *   - keyrings
@@ -215,20 +254,25 @@
 	return key;
 }
 
+static inline void key_ref_put(key_ref_t key_ref)
+{
+	key_put(key_ref_to_ptr(key_ref));
+}
+
 extern struct key *request_key(struct key_type *type,
 			       const char *description,
 			       const char *callout_info);
 
 extern int key_validate(struct key *key);
 
-extern struct key *key_create_or_update(struct key *keyring,
-					const char *type,
-					const char *description,
-					const void *payload,
-					size_t plen,
-					int not_in_quota);
+extern key_ref_t key_create_or_update(key_ref_t keyring,
+				      const char *type,
+				      const char *description,
+				      const void *payload,
+				      size_t plen,
+				      int not_in_quota);
 
-extern int key_update(struct key *key,
+extern int key_update(key_ref_t key,
 		      const void *payload,
 		      size_t plen);
 
@@ -243,9 +287,9 @@
 
 extern int keyring_clear(struct key *keyring);
 
-extern struct key *keyring_search(struct key *keyring,
-				  struct key_type *type,
-				  const char *description);
+extern key_ref_t keyring_search(key_ref_t keyring,
+				struct key_type *type,
+				const char *description);
 
 extern int keyring_add_key(struct key *keyring,
 			   struct key *key);
@@ -285,6 +329,10 @@
 #define key_serial(k)			0
 #define key_get(k) 			({ NULL; })
 #define key_put(k)			do { } while(0)
+#define key_ref_put(k)			do { } while(0)
+#define make_key_ref(k)			({ NULL; })
+#define key_ref_to_ptr(k)		({ NULL; })
+#define is_key_possessed(k)		0
 #define alloc_uid_keyring(u)		0
 #define switch_uid_keyring(u)		do { } while(0)
 #define __install_session_keyring(t, k)	({ NULL; })
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index e16cf94..e6f4c9e 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -665,7 +665,6 @@
 	struct list_head	qp_list;
 	struct list_head	srq_list;
 	struct list_head	ah_list;
-	spinlock_t              lock;
 };
 
 struct ib_uobject {
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 79866bc..6a6e87b 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -969,7 +969,7 @@
 	ssize_t retval = 0;
 	char *s;
 	char *start;
-	size_t n;
+	ssize_t n;
 
 	if (!(page = (char *)__get_free_page(GFP_KERNEL)))
 		return -ENOMEM;
@@ -999,12 +999,13 @@
 	*s++ = '\n';
 	*s = '\0';
 
-	/* Do nothing if *ppos is at the eof or beyond the eof. */
-	if (s - page <= *ppos)
-		return 0;
-
 	start = page + *ppos;
 	n = s - start;
+
+	/* Do nothing if *ppos is at the eof or beyond the eof. */
+	if (n <= 0)
+		goto out;
+
 	retval = n - copy_to_user(buf, start, min(n, nbytes));
 	*ppos += retval;
 out:
diff --git a/kernel/params.c b/kernel/params.c
index fbf1732..1a8614b 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -80,8 +80,6 @@
 	int in_quote = 0, quoted = 0;
 	char *next;
 
-	/* Chew any extra spaces */
-	while (*args == ' ') args++;
 	if (*args == '"') {
 		args++;
 		in_quote = 1;
@@ -121,6 +119,10 @@
 		next = args + i + 1;
 	} else
 		next = args + i;
+
+	/* Chew up trailing spaces. */
+	while (*next == ' ')
+		next++;
 	return next;
 }
 
@@ -135,6 +137,10 @@
 
 	DEBUGP("Parsing ARGS: %s\n", args);
 
+	/* Chew leading spaces */
+	while (*args == ' ')
+		args++;
+
 	while (*args) {
 		int ret;
 
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 9c9167d..6748de2 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -9,6 +9,9 @@
 #define SUSPEND_CONSOLE	(MAX_NR_CONSOLES-1)
 #endif
 
+#define MAX_PBES	((PAGE_SIZE - sizeof(struct new_utsname) \
+			- 4 - 3*sizeof(unsigned long) - sizeof(int) \
+			- sizeof(void *)) / sizeof(swp_entry_t))
 
 struct swsusp_info {
 	struct new_utsname	uts;
@@ -18,7 +21,7 @@
 	unsigned long		image_pages;
 	unsigned long		pagedir_pages;
 	suspend_pagedir_t	* suspend_pagedir;
-	swp_entry_t		pagedir[768];
+	swp_entry_t		pagedir[MAX_PBES];
 } __attribute__((aligned(PAGE_SIZE)));
 
 
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 1cc9ff2..acf79ac 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -402,15 +402,14 @@
 static void data_free(void)
 {
 	swp_entry_t entry;
-	int i;
+	struct pbe * p;
 
-	for (i = 0; i < nr_copy_pages; i++) {
-		entry = (pagedir_nosave + i)->swap_address;
+	for_each_pbe(p, pagedir_nosave) {
+		entry = p->swap_address;
 		if (entry.val)
 			swap_free(entry);
 		else
 			break;
-		(pagedir_nosave + i)->swap_address = (swp_entry_t){0};
 	}
 }
 
@@ -932,6 +931,10 @@
 	if (!enough_swap())
 		return -ENOSPC;
 
+	if (MAX_PBES < nr_copy_pages / PBES_PER_PAGE +
+	    !!(nr_copy_pages % PBES_PER_PAGE))
+		return -ENOSPC;
+
 	if (!(pagedir_save = alloc_pagedir(nr_copy_pages))) {
 		printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
 		return -ENOMEM;
@@ -1438,9 +1441,9 @@
 	}
 
 	if (error)
-		free_page((unsigned long)pblist);
-
-	BUG_ON(i != swsusp_info.pagedir_pages);
+		free_pagedir(pblist);
+	else
+		BUG_ON(i != swsusp_info.pagedir_pages);
 
 	return error;
 }
diff --git a/mm/mremap.c b/mm/mremap.c
index a32fed4..f343fc7 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -141,10 +141,10 @@
 			if (dst) {
 				pte_t pte;
 				pte = ptep_clear_flush(vma, old_addr, src);
+
 				/* ZERO_PAGE can be dependant on virtual addr */
-				if (pfn_valid(pte_pfn(pte)) &&
-					pte_page(pte) == ZERO_PAGE(old_addr))
-					pte = pte_wrprotect(mk_pte(ZERO_PAGE(new_addr), new_vma->vm_page_prot));
+				pte = move_pte(pte, new_vma->vm_page_prot,
+							old_addr, new_addr);
 				set_pte_at(mm, new_addr, dst, pte);
 			} else
 				error = -ENOMEM;
diff --git a/mm/slab.c b/mm/slab.c
index c9adfce..5cbbdfa6 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2510,16 +2510,12 @@
 #define cache_alloc_debugcheck_after(a,b,objp,d) (objp)
 #endif
 
-
-static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast flags)
+static inline void *____cache_alloc(kmem_cache_t *cachep, unsigned int __nocast flags)
 {
-	unsigned long save_flags;
 	void* objp;
 	struct array_cache *ac;
 
-	cache_alloc_debugcheck_before(cachep, flags);
-
-	local_irq_save(save_flags);
+	check_irq_off();
 	ac = ac_data(cachep);
 	if (likely(ac->avail)) {
 		STATS_INC_ALLOCHIT(cachep);
@@ -2529,6 +2525,18 @@
 		STATS_INC_ALLOCMISS(cachep);
 		objp = cache_alloc_refill(cachep, flags);
 	}
+	return objp;
+}
+
+static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast flags)
+{
+	unsigned long save_flags;
+	void* objp;
+
+	cache_alloc_debugcheck_before(cachep, flags);
+
+	local_irq_save(save_flags);
+	objp = ____cache_alloc(cachep, flags);
 	local_irq_restore(save_flags);
 	objp = cache_alloc_debugcheck_after(cachep, flags, objp,
 					__builtin_return_address(0));
@@ -2856,7 +2864,10 @@
 
 	cache_alloc_debugcheck_before(cachep, flags);
 	local_irq_save(save_flags);
-	ptr = __cache_alloc_node(cachep, flags, nodeid);
+	if (nodeid == numa_node_id())
+		ptr = ____cache_alloc(cachep, flags);
+	else
+		ptr = __cache_alloc_node(cachep, flags, nodeid);
 	local_irq_restore(save_flags);
 	ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, __builtin_return_address(0));
 
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index ef430b1e..b7f2d65 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -186,7 +186,7 @@
 
 /* Used to help with determining the pkts on receive */
 #define PKTGEN_MAGIC 0xbe9be955
-#define PG_PROC_DIR "pktgen"
+#define PG_PROC_DIR "net/pktgen"
 
 #define MAX_CFLOWS  65536
 
@@ -1476,18 +1476,7 @@
 
 static int create_proc_dir(void)
 {
-        int     len;
-        /*  does proc_dir already exists */
-        len = strlen(PG_PROC_DIR);
-
-        for (pg_proc_dir = proc_net->subdir; pg_proc_dir; pg_proc_dir=pg_proc_dir->next) {
-                if ((pg_proc_dir->namelen == len) &&
-		    (! memcmp(pg_proc_dir->name, PG_PROC_DIR, len))) 
-                        break;
-        }
-        
-        if (!pg_proc_dir) 
-                pg_proc_dir = create_proc_entry(PG_PROC_DIR, S_IFDIR, proc_net);
+	pg_proc_dir = proc_mkdir(PG_PROC_DIR, NULL);
         
         if (!pg_proc_dir) 
                 return -ENODEV;
@@ -1497,7 +1486,7 @@
 
 static int remove_proc_dir(void)
 {
-        remove_proc_entry(PG_PROC_DIR, proc_net);
+        remove_proc_entry(PG_PROC_DIR, NULL);
         return 0;
 }
 
@@ -2908,7 +2897,7 @@
                 pkt_dev->udp_dst_max = 9;
 
                 strncpy(pkt_dev->ifname, ifname, 31);
-                sprintf(pkt_dev->fname, "net/%s/%s", PG_PROC_DIR, ifname);
+                sprintf(pkt_dev->fname, "%s/%s", PG_PROC_DIR, ifname);
 
                 if (! pktgen_setup_dev(pkt_dev)) {
                         printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
@@ -2981,7 +2970,7 @@
         spin_lock_init(&t->if_lock);
 	t->cpu = cpu;
         
-        sprintf(t->fname, "net/%s/%s", PG_PROC_DIR, t->name);
+        sprintf(t->fname, "%s/%s", PG_PROC_DIR, t->name);
         t->proc_ent = create_proc_entry(t->fname, 0600, NULL);
         if (!t->proc_ent) {
                 printk("pktgen: cannot create %s procfs entry.\n", t->fname);
@@ -3064,7 +3053,7 @@
 
 	create_proc_dir();
 
-        sprintf(module_fname, "net/%s/pgctrl", PG_PROC_DIR);
+        sprintf(module_fname, "%s/pgctrl", PG_PROC_DIR);
         module_proc_ent = create_proc_entry(module_fname, 0600, NULL);
         if (!module_proc_ent) {
                 printk("pktgen: ERROR: cannot create %s procfs entry.\n", module_fname);
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
index 03a4734..6059e9e 100644
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -230,7 +230,7 @@
 	struct proc_dir_entry *e;
 
 	ieee80211_debug_level = debug;
-	ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
+	ieee80211_proc = proc_mkdir(DRV_NAME, proc_net);
 	if (ieee80211_proc == NULL) {
 		IEEE80211_ERROR("Unable to create " DRV_NAME
 				" proc directory\n");
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 46c8602..db99ed4 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -71,26 +71,26 @@
 
 extern int __key_link(struct key *keyring, struct key *key);
 
-extern struct key *__keyring_search_one(struct key *keyring,
-					const struct key_type *type,
-					const char *description,
-					key_perm_t perm);
+extern key_ref_t __keyring_search_one(key_ref_t keyring_ref,
+				      const struct key_type *type,
+				      const char *description,
+				      key_perm_t perm);
 
 extern struct key *keyring_search_instkey(struct key *keyring,
 					  key_serial_t target_id);
 
 typedef int (*key_match_func_t)(const struct key *, const void *);
 
-extern struct key *keyring_search_aux(struct key *keyring,
-				      struct task_struct *tsk,
-				      struct key_type *type,
-				      const void *description,
-				      key_match_func_t match);
+extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
+				    struct task_struct *tsk,
+				    struct key_type *type,
+				    const void *description,
+				    key_match_func_t match);
 
-extern struct key *search_process_keyrings(struct key_type *type,
-					   const void *description,
-					   key_match_func_t match,
-					   struct task_struct *tsk);
+extern key_ref_t search_process_keyrings(struct key_type *type,
+					 const void *description,
+					 key_match_func_t match,
+					 struct task_struct *tsk);
 
 extern struct key *find_keyring_by_name(const char *name, key_serial_t bound);
 
diff --git a/security/keys/key.c b/security/keys/key.c
index fb89f98..2182be9 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -693,14 +693,15 @@
  * - the key has an incremented refcount
  * - we need to put the key if we get an error
  */
-static inline struct key *__key_update(struct key *key, const void *payload,
-				       size_t plen)
+static inline key_ref_t __key_update(key_ref_t key_ref,
+				     const void *payload, size_t plen)
 {
+	struct key *key = key_ref_to_ptr(key_ref);
 	int ret;
 
 	/* need write permission on the key to update it */
 	ret = -EACCES;
-	if (!key_permission(key, KEY_WRITE))
+	if (!key_permission(key_ref, KEY_WRITE))
 		goto error;
 
 	ret = -EEXIST;
@@ -719,12 +720,12 @@
 
 	if (ret < 0)
 		goto error;
- out:
-	return key;
+out:
+	return key_ref;
 
- error:
+error:
 	key_put(key);
-	key = ERR_PTR(ret);
+	key_ref = ERR_PTR(ret);
 	goto out;
 
 } /* end __key_update() */
@@ -734,52 +735,56 @@
  * search the specified keyring for a key of the same description; if one is
  * found, update it, otherwise add a new one
  */
-struct key *key_create_or_update(struct key *keyring,
-				 const char *type,
-				 const char *description,
-				 const void *payload,
-				 size_t plen,
-				 int not_in_quota)
+key_ref_t key_create_or_update(key_ref_t keyring_ref,
+			       const char *type,
+			       const char *description,
+			       const void *payload,
+			       size_t plen,
+			       int not_in_quota)
 {
 	struct key_type *ktype;
-	struct key *key = NULL;
+	struct key *keyring, *key = NULL;
 	key_perm_t perm;
+	key_ref_t key_ref;
 	int ret;
 
-	key_check(keyring);
-
 	/* look up the key type to see if it's one of the registered kernel
 	 * types */
 	ktype = key_type_lookup(type);
 	if (IS_ERR(ktype)) {
-		key = ERR_PTR(-ENODEV);
+		key_ref = ERR_PTR(-ENODEV);
 		goto error;
 	}
 
-	ret = -EINVAL;
+	key_ref = ERR_PTR(-EINVAL);
 	if (!ktype->match || !ktype->instantiate)
 		goto error_2;
 
+	keyring = key_ref_to_ptr(keyring_ref);
+
+	key_check(keyring);
+
+	down_write(&keyring->sem);
+
+	/* if we're going to allocate a new key, we're going to have
+	 * to modify the keyring */
+	key_ref = ERR_PTR(-EACCES);
+	if (!key_permission(keyring_ref, KEY_WRITE))
+		goto error_3;
+
 	/* search for an existing key of the same type and description in the
 	 * destination keyring
 	 */
-	down_write(&keyring->sem);
-
-	key = __keyring_search_one(keyring, ktype, description, 0);
-	if (!IS_ERR(key))
+	key_ref = __keyring_search_one(keyring_ref, ktype, description, 0);
+	if (!IS_ERR(key_ref))
 		goto found_matching_key;
 
-	/* if we're going to allocate a new key, we're going to have to modify
-	 * the keyring */
-	ret = -EACCES;
-	if (!key_permission(keyring, KEY_WRITE))
-		goto error_3;
-
 	/* decide on the permissions we want */
-	perm = KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK;
+	perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK;
+	perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK;
 
 	if (ktype->read)
-		perm |= KEY_USR_READ;
+		perm |= KEY_POS_READ | KEY_USR_READ;
 
 	if (ktype == &key_type_keyring || ktype->update)
 		perm |= KEY_USR_WRITE;
@@ -788,7 +793,7 @@
 	key = key_alloc(ktype, description, current->fsuid, current->fsgid,
 			perm, not_in_quota);
 	if (IS_ERR(key)) {
-		ret = PTR_ERR(key);
+		key_ref = ERR_PTR(PTR_ERR(key));
 		goto error_3;
 	}
 
@@ -796,15 +801,18 @@
 	ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL);
 	if (ret < 0) {
 		key_put(key);
-		key = ERR_PTR(ret);
+		key_ref = ERR_PTR(ret);
+		goto error_3;
 	}
 
+	key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
+
  error_3:
 	up_write(&keyring->sem);
  error_2:
 	key_type_put(ktype);
  error:
-	return key;
+	return key_ref;
 
  found_matching_key:
 	/* we found a matching key, so we're going to try to update it
@@ -813,7 +821,7 @@
 	up_write(&keyring->sem);
 	key_type_put(ktype);
 
-	key = __key_update(key, payload, plen);
+	key_ref = __key_update(key_ref, payload, plen);
 	goto error;
 
 } /* end key_create_or_update() */
@@ -824,15 +832,16 @@
 /*
  * update a key
  */
-int key_update(struct key *key, const void *payload, size_t plen)
+int key_update(key_ref_t key_ref, const void *payload, size_t plen)
 {
+	struct key *key = key_ref_to_ptr(key_ref);
 	int ret;
 
 	key_check(key);
 
 	/* the key must be writable */
 	ret = -EACCES;
-	if (!key_permission(key, KEY_WRITE))
+	if (!key_permission(key_ref, KEY_WRITE))
 		goto error;
 
 	/* attempt to update it if supported */
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index a6516a6..4c670ee 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -34,7 +34,7 @@
 			    size_t plen,
 			    key_serial_t ringid)
 {
-	struct key *keyring, *key;
+	key_ref_t keyring_ref, key_ref;
 	char type[32], *description;
 	void *payload;
 	long dlen, ret;
@@ -86,25 +86,25 @@
 	}
 
 	/* find the target keyring (which must be writable) */
-	keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
-	if (IS_ERR(keyring)) {
-		ret = PTR_ERR(keyring);
+	keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
+	if (IS_ERR(keyring_ref)) {
+		ret = PTR_ERR(keyring_ref);
 		goto error3;
 	}
 
 	/* create or update the requested key and add it to the target
 	 * keyring */
-	key = key_create_or_update(keyring, type, description,
-				   payload, plen, 0);
-	if (!IS_ERR(key)) {
-		ret = key->serial;
-		key_put(key);
+	key_ref = key_create_or_update(keyring_ref, type, description,
+				       payload, plen, 0);
+	if (!IS_ERR(key_ref)) {
+		ret = key_ref_to_ptr(key_ref)->serial;
+		key_ref_put(key_ref);
 	}
 	else {
-		ret = PTR_ERR(key);
+		ret = PTR_ERR(key_ref);
 	}
 
-	key_put(keyring);
+	key_ref_put(keyring_ref);
  error3:
 	kfree(payload);
  error2:
@@ -131,7 +131,8 @@
 				key_serial_t destringid)
 {
 	struct key_type *ktype;
-	struct key *key, *dest;
+	struct key *key;
+	key_ref_t dest_ref;
 	char type[32], *description, *callout_info;
 	long dlen, ret;
 
@@ -187,11 +188,11 @@
 	}
 
 	/* get the destination keyring if specified */
-	dest = NULL;
+	dest_ref = NULL;
 	if (destringid) {
-		dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
-		if (IS_ERR(dest)) {
-			ret = PTR_ERR(dest);
+		dest_ref = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
+		if (IS_ERR(dest_ref)) {
+			ret = PTR_ERR(dest_ref);
 			goto error3;
 		}
 	}
@@ -204,7 +205,8 @@
 	}
 
 	/* do the search */
-	key = request_key_and_link(ktype, description, callout_info, dest);
+	key = request_key_and_link(ktype, description, callout_info,
+				   key_ref_to_ptr(dest_ref));
 	if (IS_ERR(key)) {
 		ret = PTR_ERR(key);
 		goto error5;
@@ -216,7 +218,7 @@
  error5:
 	key_type_put(ktype);
  error4:
-	key_put(dest);
+	key_ref_put(dest_ref);
  error3:
 	kfree(callout_info);
  error2:
@@ -234,17 +236,17 @@
  */
 long keyctl_get_keyring_ID(key_serial_t id, int create)
 {
-	struct key *key;
+	key_ref_t key_ref;
 	long ret;
 
-	key = lookup_user_key(NULL, id, create, 0, KEY_SEARCH);
-	if (IS_ERR(key)) {
-		ret = PTR_ERR(key);
+	key_ref = lookup_user_key(NULL, id, create, 0, KEY_SEARCH);
+	if (IS_ERR(key_ref)) {
+		ret = PTR_ERR(key_ref);
 		goto error;
 	}
 
-	ret = key->serial;
-	key_put(key);
+	ret = key_ref_to_ptr(key_ref)->serial;
+	key_ref_put(key_ref);
  error:
 	return ret;
 
@@ -302,7 +304,7 @@
 		       const void __user *_payload,
 		       size_t plen)
 {
-	struct key *key;
+	key_ref_t key_ref;
 	void *payload;
 	long ret;
 
@@ -324,16 +326,16 @@
 	}
 
 	/* find the target key (which must be writable) */
-	key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
-	if (IS_ERR(key)) {
-		ret = PTR_ERR(key);
+	key_ref = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
+	if (IS_ERR(key_ref)) {
+		ret = PTR_ERR(key_ref);
 		goto error2;
 	}
 
 	/* update the key */
-	ret = key_update(key, payload, plen);
+	ret = key_update(key_ref, payload, plen);
 
-	key_put(key);
+	key_ref_put(key_ref);
  error2:
 	kfree(payload);
  error:
@@ -349,19 +351,19 @@
  */
 long keyctl_revoke_key(key_serial_t id)
 {
-	struct key *key;
+	key_ref_t key_ref;
 	long ret;
 
-	key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
-	if (IS_ERR(key)) {
-		ret = PTR_ERR(key);
+	key_ref = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
+	if (IS_ERR(key_ref)) {
+		ret = PTR_ERR(key_ref);
 		goto error;
 	}
 
-	key_revoke(key);
+	key_revoke(key_ref_to_ptr(key_ref));
 	ret = 0;
 
-	key_put(key);
+	key_ref_put(key_ref);
  error:
 	return ret;
 
@@ -375,18 +377,18 @@
  */
 long keyctl_keyring_clear(key_serial_t ringid)
 {
-	struct key *keyring;
+	key_ref_t keyring_ref;
 	long ret;
 
-	keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
-	if (IS_ERR(keyring)) {
-		ret = PTR_ERR(keyring);
+	keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
+	if (IS_ERR(keyring_ref)) {
+		ret = PTR_ERR(keyring_ref);
 		goto error;
 	}
 
-	ret = keyring_clear(keyring);
+	ret = keyring_clear(key_ref_to_ptr(keyring_ref));
 
-	key_put(keyring);
+	key_ref_put(keyring_ref);
  error:
 	return ret;
 
@@ -401,26 +403,26 @@
  */
 long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
 {
-	struct key *keyring, *key;
+	key_ref_t keyring_ref, key_ref;
 	long ret;
 
-	keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
-	if (IS_ERR(keyring)) {
-		ret = PTR_ERR(keyring);
+	keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
+	if (IS_ERR(keyring_ref)) {
+		ret = PTR_ERR(keyring_ref);
 		goto error;
 	}
 
-	key = lookup_user_key(NULL, id, 1, 0, KEY_LINK);
-	if (IS_ERR(key)) {
-		ret = PTR_ERR(key);
+	key_ref = lookup_user_key(NULL, id, 1, 0, KEY_LINK);
+	if (IS_ERR(key_ref)) {
+		ret = PTR_ERR(key_ref);
 		goto error2;
 	}
 
-	ret = key_link(keyring, key);
+	ret = key_link(key_ref_to_ptr(keyring_ref), key_ref_to_ptr(key_ref));
 
-	key_put(key);
+	key_ref_put(key_ref);
  error2:
-	key_put(keyring);
+	key_ref_put(keyring_ref);
  error:
 	return ret;
 
@@ -435,26 +437,26 @@
  */
 long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
 {
-	struct key *keyring, *key;
+	key_ref_t keyring_ref, key_ref;
 	long ret;
 
-	keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE);
-	if (IS_ERR(keyring)) {
-		ret = PTR_ERR(keyring);
+	keyring_ref = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE);
+	if (IS_ERR(keyring_ref)) {
+		ret = PTR_ERR(keyring_ref);
 		goto error;
 	}
 
-	key = lookup_user_key(NULL, id, 0, 0, 0);
-	if (IS_ERR(key)) {
-		ret = PTR_ERR(key);
+	key_ref = lookup_user_key(NULL, id, 0, 0, 0);
+	if (IS_ERR(key_ref)) {
+		ret = PTR_ERR(key_ref);
 		goto error2;
 	}
 
-	ret = key_unlink(keyring, key);
+	ret = key_unlink(key_ref_to_ptr(keyring_ref), key_ref_to_ptr(key_ref));
 
-	key_put(key);
+	key_ref_put(key_ref);
  error2:
-	key_put(keyring);
+	key_ref_put(keyring_ref);
  error:
 	return ret;
 
@@ -476,24 +478,26 @@
 			 size_t buflen)
 {
 	struct key *key, *instkey;
+	key_ref_t key_ref;
 	char *tmpbuf;
 	long ret;
 
-	key = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
-	if (IS_ERR(key)) {
+	key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
+	if (IS_ERR(key_ref)) {
 		/* viewing a key under construction is permitted if we have the
 		 * authorisation token handy */
-		if (PTR_ERR(key) == -EACCES) {
+		if (PTR_ERR(key_ref) == -EACCES) {
 			instkey = key_get_instantiation_authkey(keyid);
 			if (!IS_ERR(instkey)) {
 				key_put(instkey);
-				key = lookup_user_key(NULL, keyid, 0, 1, 0);
-				if (!IS_ERR(key))
+				key_ref = lookup_user_key(NULL, keyid,
+							  0, 1, 0);
+				if (!IS_ERR(key_ref))
 					goto okay;
 			}
 		}
 
-		ret = PTR_ERR(key);
+		ret = PTR_ERR(key_ref);
 		goto error;
 	}
 
@@ -504,13 +508,16 @@
 	if (!tmpbuf)
 		goto error2;
 
+	key = key_ref_to_ptr(key_ref);
+
 	ret = snprintf(tmpbuf, PAGE_SIZE - 1,
-		       "%s;%d;%d;%06x;%s",
-		       key->type->name,
-		       key->uid,
-		       key->gid,
-		       key->perm,
-		       key->description ? key->description :""
+		       "%s;%d;%d;%08x;%s",
+		       key_ref_to_ptr(key_ref)->type->name,
+		       key_ref_to_ptr(key_ref)->uid,
+		       key_ref_to_ptr(key_ref)->gid,
+		       key_ref_to_ptr(key_ref)->perm,
+		       key_ref_to_ptr(key_ref)->description ?
+		       key_ref_to_ptr(key_ref)->description : ""
 		       );
 
 	/* include a NUL char at the end of the data */
@@ -530,7 +537,7 @@
 
 	kfree(tmpbuf);
  error2:
-	key_put(key);
+	key_ref_put(key_ref);
  error:
 	return ret;
 
@@ -552,7 +559,7 @@
 			   key_serial_t destringid)
 {
 	struct key_type *ktype;
-	struct key *keyring, *key, *dest;
+	key_ref_t keyring_ref, key_ref, dest_ref;
 	char type[32], *description;
 	long dlen, ret;
 
@@ -581,18 +588,18 @@
 		goto error2;
 
 	/* get the keyring at which to begin the search */
-	keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH);
-	if (IS_ERR(keyring)) {
-		ret = PTR_ERR(keyring);
+	keyring_ref = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH);
+	if (IS_ERR(keyring_ref)) {
+		ret = PTR_ERR(keyring_ref);
 		goto error2;
 	}
 
 	/* get the destination keyring if specified */
-	dest = NULL;
+	dest_ref = NULL;
 	if (destringid) {
-		dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
-		if (IS_ERR(dest)) {
-			ret = PTR_ERR(dest);
+		dest_ref = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
+		if (IS_ERR(dest_ref)) {
+			ret = PTR_ERR(dest_ref);
 			goto error3;
 		}
 	}
@@ -605,9 +612,9 @@
 	}
 
 	/* do the search */
-	key = keyring_search(keyring, ktype, description);
-	if (IS_ERR(key)) {
-		ret = PTR_ERR(key);
+	key_ref = keyring_search(keyring_ref, ktype, description);
+	if (IS_ERR(key_ref)) {
+		ret = PTR_ERR(key_ref);
 
 		/* treat lack or presence of a negative key the same */
 		if (ret == -EAGAIN)
@@ -616,26 +623,26 @@
 	}
 
 	/* link the resulting key to the destination keyring if we can */
-	if (dest) {
+	if (dest_ref) {
 		ret = -EACCES;
-		if (!key_permission(key, KEY_LINK))
+		if (!key_permission(key_ref, KEY_LINK))
 			goto error6;
 
-		ret = key_link(dest, key);
+		ret = key_link(key_ref_to_ptr(dest_ref), key_ref_to_ptr(key_ref));
 		if (ret < 0)
 			goto error6;
 	}
 
-	ret = key->serial;
+	ret = key_ref_to_ptr(key_ref)->serial;
 
  error6:
-	key_put(key);
+	key_ref_put(key_ref);
  error5:
 	key_type_put(ktype);
  error4:
-	key_put(dest);
+	key_ref_put(dest_ref);
  error3:
-	key_put(keyring);
+	key_ref_put(keyring_ref);
  error2:
 	kfree(description);
  error:
@@ -645,16 +652,6 @@
 
 /*****************************************************************************/
 /*
- * see if the key we're looking at is the target key
- */
-static int keyctl_read_key_same(const struct key *key, const void *target)
-{
-	return key == target;
-
-} /* end keyctl_read_key_same() */
-
-/*****************************************************************************/
-/*
  * read a user key's payload
  * - the keyring must be readable or the key must be searchable from the
  *   process's keyrings
@@ -665,38 +662,33 @@
  */
 long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
 {
-	struct key *key, *skey;
+	struct key *key;
+	key_ref_t key_ref;
 	long ret;
 
 	/* find the key first */
-	key = lookup_user_key(NULL, keyid, 0, 0, 0);
-	if (!IS_ERR(key)) {
-		/* see if we can read it directly */
-		if (key_permission(key, KEY_READ))
-			goto can_read_key;
+	key_ref = lookup_user_key(NULL, keyid, 0, 0, 0);
+	if (IS_ERR(key_ref)) {
+		ret = -ENOKEY;
+		goto error;
+	}
 
-		/* we can't; see if it's searchable from this process's
-		 * keyrings
-		 * - we automatically take account of the fact that it may be
-		 *   dangling off an instantiation key
-		 */
-		skey = search_process_keyrings(key->type, key,
-					       keyctl_read_key_same, current);
-		if (!IS_ERR(skey))
-			goto can_read_key2;
+	key = key_ref_to_ptr(key_ref);
 
-		ret = PTR_ERR(skey);
-		if (ret == -EAGAIN)
-			ret = -EACCES;
+	/* see if we can read it directly */
+	if (key_permission(key_ref, KEY_READ))
+		goto can_read_key;
+
+	/* we can't; see if it's searchable from this process's keyrings
+	 * - we automatically take account of the fact that it may be
+	 *   dangling off an instantiation key
+	 */
+	if (!is_key_possessed(key_ref)) {
+		ret = -EACCES;
 		goto error2;
 	}
 
-	ret = -ENOKEY;
-	goto error;
-
 	/* the key is probably readable - now try to read it */
- can_read_key2:
-	key_put(skey);
  can_read_key:
 	ret = key_validate(key);
 	if (ret == 0) {
@@ -727,18 +719,21 @@
 long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
 {
 	struct key *key;
+	key_ref_t key_ref;
 	long ret;
 
 	ret = 0;
 	if (uid == (uid_t) -1 && gid == (gid_t) -1)
 		goto error;
 
-	key = lookup_user_key(NULL, id, 1, 1, 0);
-	if (IS_ERR(key)) {
-		ret = PTR_ERR(key);
+	key_ref = lookup_user_key(NULL, id, 1, 1, 0);
+	if (IS_ERR(key_ref)) {
+		ret = PTR_ERR(key_ref);
 		goto error;
 	}
 
+	key = key_ref_to_ptr(key_ref);
+
 	/* make the changes with the locks held to prevent chown/chown races */
 	ret = -EACCES;
 	down_write(&key->sem);
@@ -784,18 +779,21 @@
 long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
 {
 	struct key *key;
+	key_ref_t key_ref;
 	long ret;
 
 	ret = -EINVAL;
-	if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
+	if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
 		goto error;
 
-	key = lookup_user_key(NULL, id, 1, 1, 0);
-	if (IS_ERR(key)) {
-		ret = PTR_ERR(key);
+	key_ref = lookup_user_key(NULL, id, 1, 1, 0);
+	if (IS_ERR(key_ref)) {
+		ret = PTR_ERR(key_ref);
 		goto error;
 	}
 
+	key = key_ref_to_ptr(key_ref);
+
 	/* make the changes with the locks held to prevent chown/chmod races */
 	ret = -EACCES;
 	down_write(&key->sem);
@@ -824,7 +822,8 @@
 			    key_serial_t ringid)
 {
 	struct request_key_auth *rka;
-	struct key *instkey, *keyring;
+	struct key *instkey;
+	key_ref_t keyring_ref;
 	void *payload;
 	long ret;
 
@@ -857,21 +856,21 @@
 
 	/* find the destination keyring amongst those belonging to the
 	 * requesting task */
-	keyring = NULL;
+	keyring_ref = NULL;
 	if (ringid) {
-		keyring = lookup_user_key(rka->context, ringid, 1, 0,
-					  KEY_WRITE);
-		if (IS_ERR(keyring)) {
-			ret = PTR_ERR(keyring);
+		keyring_ref = lookup_user_key(rka->context, ringid, 1, 0,
+					      KEY_WRITE);
+		if (IS_ERR(keyring_ref)) {
+			ret = PTR_ERR(keyring_ref);
 			goto error3;
 		}
 	}
 
 	/* instantiate the key and link it into a keyring */
 	ret = key_instantiate_and_link(rka->target_key, payload, plen,
-				       keyring, instkey);
+				       key_ref_to_ptr(keyring_ref), instkey);
 
-	key_put(keyring);
+	key_ref_put(keyring_ref);
  error3:
 	key_put(instkey);
  error2:
@@ -889,7 +888,8 @@
 long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
 {
 	struct request_key_auth *rka;
-	struct key *instkey, *keyring;
+	struct key *instkey;
+	key_ref_t keyring_ref;
 	long ret;
 
 	/* find the instantiation authorisation key */
@@ -903,19 +903,20 @@
 
 	/* find the destination keyring if present (which must also be
 	 * writable) */
-	keyring = NULL;
+	keyring_ref = NULL;
 	if (ringid) {
-		keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
-		if (IS_ERR(keyring)) {
-			ret = PTR_ERR(keyring);
+		keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
+		if (IS_ERR(keyring_ref)) {
+			ret = PTR_ERR(keyring_ref);
 			goto error2;
 		}
 	}
 
 	/* instantiate the key and link it into a keyring */
-	ret = key_negate_and_link(rka->target_key, timeout, keyring, instkey);
+	ret = key_negate_and_link(rka->target_key, timeout,
+				  key_ref_to_ptr(keyring_ref), instkey);
 
-	key_put(keyring);
+	key_ref_put(keyring_ref);
  error2:
 	key_put(instkey);
  error:
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 9c208c7..0639396 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -309,7 +309,7 @@
 	int ret;
 
 	keyring = key_alloc(&key_type_keyring, description,
-			    uid, gid, KEY_USR_ALL, not_in_quota);
+			    uid, gid, KEY_POS_ALL | KEY_USR_ALL, not_in_quota);
 
 	if (!IS_ERR(keyring)) {
 		ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
@@ -333,12 +333,13 @@
  * - we rely on RCU to prevent the keyring lists from disappearing on us
  * - we return -EAGAIN if we didn't find any matching key
  * - we return -ENOKEY if we only found negative matching keys
+ * - we propagate the possession attribute from the keyring ref to the key ref
  */
-struct key *keyring_search_aux(struct key *keyring,
-			       struct task_struct *context,
-			       struct key_type *type,
-			       const void *description,
-			       key_match_func_t match)
+key_ref_t keyring_search_aux(key_ref_t keyring_ref,
+			     struct task_struct *context,
+			     struct key_type *type,
+			     const void *description,
+			     key_match_func_t match)
 {
 	struct {
 		struct keyring_list *keylist;
@@ -347,29 +348,33 @@
 
 	struct keyring_list *keylist;
 	struct timespec now;
-	struct key *key;
+	unsigned long possessed;
+	struct key *keyring, *key;
+	key_ref_t key_ref;
 	long err;
 	int sp, kix;
 
+	keyring = key_ref_to_ptr(keyring_ref);
+	possessed = is_key_possessed(keyring_ref);
 	key_check(keyring);
 
-	rcu_read_lock();
-
 	/* top keyring must have search permission to begin the search */
-	key = ERR_PTR(-EACCES);
-	if (!key_task_permission(keyring, context, KEY_SEARCH))
+	key_ref = ERR_PTR(-EACCES);
+	if (!key_task_permission(keyring_ref, context, KEY_SEARCH))
 		goto error;
 
-	key = ERR_PTR(-ENOTDIR);
+	key_ref = ERR_PTR(-ENOTDIR);
 	if (keyring->type != &key_type_keyring)
 		goto error;
 
+	rcu_read_lock();
+
 	now = current_kernel_time();
 	err = -EAGAIN;
 	sp = 0;
 
 	/* start processing a new keyring */
- descend:
+descend:
 	if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
 		goto not_this_keyring;
 
@@ -397,7 +402,8 @@
 			continue;
 
 		/* key must have search permissions */
-		if (!key_task_permission(key, context, KEY_SEARCH))
+		if (!key_task_permission(make_key_ref(key, possessed),
+					 context, KEY_SEARCH))
 			continue;
 
 		/* we set a different error code if we find a negative key */
@@ -411,7 +417,7 @@
 
 	/* search through the keyrings nested in this one */
 	kix = 0;
- ascend:
+ascend:
 	for (; kix < keylist->nkeys; kix++) {
 		key = keylist->keys[kix];
 		if (key->type != &key_type_keyring)
@@ -423,7 +429,8 @@
 		if (sp >= KEYRING_SEARCH_MAX_DEPTH)
 			continue;
 
-		if (!key_task_permission(key, context, KEY_SEARCH))
+		if (!key_task_permission(make_key_ref(key, possessed),
+					 context, KEY_SEARCH))
 			continue;
 
 		/* stack the current position */
@@ -438,7 +445,7 @@
 
 	/* the keyring we're looking at was disqualified or didn't contain a
 	 * matching key */
- not_this_keyring:
+not_this_keyring:
 	if (sp > 0) {
 		/* resume the processing of a keyring higher up in the tree */
 		sp--;
@@ -447,16 +454,18 @@
 		goto ascend;
 	}
 
-	key = ERR_PTR(err);
-	goto error;
+	key_ref = ERR_PTR(err);
+	goto error_2;
 
 	/* we found a viable match */
- found:
+found:
 	atomic_inc(&key->usage);
 	key_check(key);
- error:
+	key_ref = make_key_ref(key, possessed);
+error_2:
 	rcu_read_unlock();
-	return key;
+error:
+	return key_ref;
 
 } /* end keyring_search_aux() */
 
@@ -469,9 +478,9 @@
  * - we return -EAGAIN if we didn't find any matching key
  * - we return -ENOKEY if we only found negative matching keys
  */
-struct key *keyring_search(struct key *keyring,
-			   struct key_type *type,
-			   const char *description)
+key_ref_t keyring_search(key_ref_t keyring,
+			 struct key_type *type,
+			 const char *description)
 {
 	if (!type->match)
 		return ERR_PTR(-ENOKEY);
@@ -488,15 +497,19 @@
  * search the given keyring only (no recursion)
  * - keyring must be locked by caller
  */
-struct key *__keyring_search_one(struct key *keyring,
-				 const struct key_type *ktype,
-				 const char *description,
-				 key_perm_t perm)
+key_ref_t __keyring_search_one(key_ref_t keyring_ref,
+			       const struct key_type *ktype,
+			       const char *description,
+			       key_perm_t perm)
 {
 	struct keyring_list *klist;
-	struct key *key;
+	unsigned long possessed;
+	struct key *keyring, *key;
 	int loop;
 
+	keyring = key_ref_to_ptr(keyring_ref);
+	possessed = is_key_possessed(keyring_ref);
+
 	rcu_read_lock();
 
 	klist = rcu_dereference(keyring->payload.subscriptions);
@@ -507,21 +520,21 @@
 			if (key->type == ktype &&
 			    (!key->type->match ||
 			     key->type->match(key, description)) &&
-			    key_permission(key, perm) &&
+			    key_permission(make_key_ref(key, possessed),
+					   perm) &&
 			    !test_bit(KEY_FLAG_REVOKED, &key->flags)
 			    )
 				goto found;
 		}
 	}
 
-	key = ERR_PTR(-ENOKEY);
-	goto error;
+	rcu_read_unlock();
+	return ERR_PTR(-ENOKEY);
 
  found:
 	atomic_inc(&key->usage);
- error:
 	rcu_read_unlock();
-	return key;
+	return make_key_ref(key, possessed);
 
 } /* end __keyring_search_one() */
 
@@ -603,7 +616,8 @@
 			if (strcmp(keyring->description, name) != 0)
 				continue;
 
-			if (!key_permission(keyring, KEY_SEARCH))
+			if (!key_permission(make_key_ref(keyring, 0),
+					    KEY_SEARCH))
 				continue;
 
 			/* found a potential candidate, but we still need to
diff --git a/security/keys/proc.c b/security/keys/proc.c
index c55cf1f..12b750e 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -167,7 +167,7 @@
 #define showflag(KEY, LETTER, FLAG) \
 	(test_bit(FLAG,	&(KEY)->flags) ? LETTER : '-')
 
-	seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %06x %5d %5d %-9.9s ",
+	seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ",
 		   key->serial,
 		   showflag(key, 'I', KEY_FLAG_INSTANTIATED),
 		   showflag(key, 'R', KEY_FLAG_REVOKED),
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index c089f78..d42d215 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -39,7 +39,7 @@
 	.type		= &key_type_keyring,
 	.user		= &root_key_user,
 	.sem		= __RWSEM_INITIALIZER(root_user_keyring.sem),
-	.perm		= KEY_USR_ALL,
+	.perm		= KEY_POS_ALL | KEY_USR_ALL,
 	.flags		= 1 << KEY_FLAG_INSTANTIATED,
 	.description	= "_uid.0",
 #ifdef KEY_DEBUGGING
@@ -54,7 +54,7 @@
 	.type		= &key_type_keyring,
 	.user		= &root_key_user,
 	.sem		= __RWSEM_INITIALIZER(root_session_keyring.sem),
-	.perm		= KEY_USR_ALL,
+	.perm		= KEY_POS_ALL | KEY_USR_ALL,
 	.flags		= 1 << KEY_FLAG_INSTANTIATED,
 	.description	= "_uid_ses.0",
 #ifdef KEY_DEBUGGING
@@ -98,7 +98,7 @@
 	user->session_keyring = session_keyring;
 	ret = 0;
 
- error:
+error:
 	return ret;
 
 } /* end alloc_uid_keyring() */
@@ -156,7 +156,7 @@
 	ret = 0;
 
 	key_put(old);
- error:
+error:
 	return ret;
 
 } /* end install_thread_keyring() */
@@ -193,7 +193,7 @@
 	}
 
 	ret = 0;
- error:
+error:
 	return ret;
 
 } /* end install_process_keyring() */
@@ -236,7 +236,7 @@
 	/* we're using RCU on the pointer */
 	synchronize_rcu();
 	key_put(old);
- error:
+error:
 	return ret;
 
 } /* end install_session_keyring() */
@@ -376,13 +376,13 @@
  * - we return -EAGAIN if we didn't find any matching key
  * - we return -ENOKEY if we found only negative matching keys
  */
-struct key *search_process_keyrings(struct key_type *type,
-				    const void *description,
-				    key_match_func_t match,
-				    struct task_struct *context)
+key_ref_t search_process_keyrings(struct key_type *type,
+				  const void *description,
+				  key_match_func_t match,
+				  struct task_struct *context)
 {
 	struct request_key_auth *rka;
-	struct key *key, *ret, *err, *instkey;
+	key_ref_t key_ref, ret, err, instkey_ref;
 
 	/* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
 	 * searchable, but we failed to find a key or we found a negative key;
@@ -391,46 +391,48 @@
 	 *
 	 * in terms of priority: success > -ENOKEY > -EAGAIN > other error
 	 */
-	key = NULL;
+	key_ref = NULL;
 	ret = NULL;
 	err = ERR_PTR(-EAGAIN);
 
 	/* search the thread keyring first */
 	if (context->thread_keyring) {
-		key = keyring_search_aux(context->thread_keyring,
-					 context, type, description, match);
-		if (!IS_ERR(key))
+		key_ref = keyring_search_aux(
+			make_key_ref(context->thread_keyring, 1),
+			context, type, description, match);
+		if (!IS_ERR(key_ref))
 			goto found;
 
-		switch (PTR_ERR(key)) {
+		switch (PTR_ERR(key_ref)) {
 		case -EAGAIN: /* no key */
 			if (ret)
 				break;
 		case -ENOKEY: /* negative key */
-			ret = key;
+			ret = key_ref;
 			break;
 		default:
-			err = key;
+			err = key_ref;
 			break;
 		}
 	}
 
 	/* search the process keyring second */
 	if (context->signal->process_keyring) {
-		key = keyring_search_aux(context->signal->process_keyring,
-					 context, type, description, match);
-		if (!IS_ERR(key))
+		key_ref = keyring_search_aux(
+			make_key_ref(context->signal->process_keyring, 1),
+			context, type, description, match);
+		if (!IS_ERR(key_ref))
 			goto found;
 
-		switch (PTR_ERR(key)) {
+		switch (PTR_ERR(key_ref)) {
 		case -EAGAIN: /* no key */
 			if (ret)
 				break;
 		case -ENOKEY: /* negative key */
-			ret = key;
+			ret = key_ref;
 			break;
 		default:
-			err = key;
+			err = key_ref;
 			break;
 		}
 	}
@@ -438,23 +440,25 @@
 	/* search the session keyring */
 	if (context->signal->session_keyring) {
 		rcu_read_lock();
-		key = keyring_search_aux(
-			rcu_dereference(context->signal->session_keyring),
+		key_ref = keyring_search_aux(
+			make_key_ref(rcu_dereference(
+					     context->signal->session_keyring),
+				     1),
 			context, type, description, match);
 		rcu_read_unlock();
 
-		if (!IS_ERR(key))
+		if (!IS_ERR(key_ref))
 			goto found;
 
-		switch (PTR_ERR(key)) {
+		switch (PTR_ERR(key_ref)) {
 		case -EAGAIN: /* no key */
 			if (ret)
 				break;
 		case -ENOKEY: /* negative key */
-			ret = key;
+			ret = key_ref;
 			break;
 		default:
-			err = key;
+			err = key_ref;
 			break;
 		}
 
@@ -465,51 +469,54 @@
 			goto no_key;
 
 		rcu_read_lock();
-		instkey = __keyring_search_one(
-			rcu_dereference(context->signal->session_keyring),
+		instkey_ref = __keyring_search_one(
+			make_key_ref(rcu_dereference(
+					     context->signal->session_keyring),
+				     1),
 			&key_type_request_key_auth, NULL, 0);
 		rcu_read_unlock();
 
-		if (IS_ERR(instkey))
+		if (IS_ERR(instkey_ref))
 			goto no_key;
 
-		rka = instkey->payload.data;
+		rka = key_ref_to_ptr(instkey_ref)->payload.data;
 
-		key = search_process_keyrings(type, description, match,
-					      rka->context);
-		key_put(instkey);
+		key_ref = search_process_keyrings(type, description, match,
+						  rka->context);
+		key_ref_put(instkey_ref);
 
-		if (!IS_ERR(key))
+		if (!IS_ERR(key_ref))
 			goto found;
 
-		switch (PTR_ERR(key)) {
+		switch (PTR_ERR(key_ref)) {
 		case -EAGAIN: /* no key */
 			if (ret)
 				break;
 		case -ENOKEY: /* negative key */
-			ret = key;
+			ret = key_ref;
 			break;
 		default:
-			err = key;
+			err = key_ref;
 			break;
 		}
 	}
 	/* or search the user-session keyring */
 	else {
-		key = keyring_search_aux(context->user->session_keyring,
-					 context, type, description, match);
-		if (!IS_ERR(key))
+		key_ref = keyring_search_aux(
+			make_key_ref(context->user->session_keyring, 1),
+			context, type, description, match);
+		if (!IS_ERR(key_ref))
 			goto found;
 
-		switch (PTR_ERR(key)) {
+		switch (PTR_ERR(key_ref)) {
 		case -EAGAIN: /* no key */
 			if (ret)
 				break;
 		case -ENOKEY: /* negative key */
-			ret = key;
+			ret = key_ref;
 			break;
 		default:
-			err = key;
+			err = key_ref;
 			break;
 		}
 	}
@@ -517,29 +524,40 @@
 
 no_key:
 	/* no key - decide on the error we're going to go for */
-	key = ret ? ret : err;
+	key_ref = ret ? ret : err;
 
 found:
-	return key;
+	return key_ref;
 
 } /* end search_process_keyrings() */
 
 /*****************************************************************************/
 /*
+ * see if the key we're looking at is the target key
+ */
+static int lookup_user_key_possessed(const struct key *key, const void *target)
+{
+	return key == target;
+
+} /* end lookup_user_key_possessed() */
+
+/*****************************************************************************/
+/*
  * lookup a key given a key ID from userspace with a given permissions mask
  * - don't create special keyrings unless so requested
  * - partially constructed keys aren't found unless requested
  */
-struct key *lookup_user_key(struct task_struct *context, key_serial_t id,
-			    int create, int partial, key_perm_t perm)
+key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
+			  int create, int partial, key_perm_t perm)
 {
+	key_ref_t key_ref, skey_ref;
 	struct key *key;
 	int ret;
 
 	if (!context)
 		context = current;
 
-	key = ERR_PTR(-ENOKEY);
+	key_ref = ERR_PTR(-ENOKEY);
 
 	switch (id) {
 	case KEY_SPEC_THREAD_KEYRING:
@@ -556,6 +574,7 @@
 
 		key = context->thread_keyring;
 		atomic_inc(&key->usage);
+		key_ref = make_key_ref(key, 1);
 		break;
 
 	case KEY_SPEC_PROCESS_KEYRING:
@@ -572,6 +591,7 @@
 
 		key = context->signal->process_keyring;
 		atomic_inc(&key->usage);
+		key_ref = make_key_ref(key, 1);
 		break;
 
 	case KEY_SPEC_SESSION_KEYRING:
@@ -579,7 +599,7 @@
 			/* always install a session keyring upon access if one
 			 * doesn't exist yet */
 			ret = install_session_keyring(
-			       context, context->user->session_keyring);
+				context, context->user->session_keyring);
 			if (ret < 0)
 				goto error;
 		}
@@ -588,16 +608,19 @@
 		key = rcu_dereference(context->signal->session_keyring);
 		atomic_inc(&key->usage);
 		rcu_read_unlock();
+		key_ref = make_key_ref(key, 1);
 		break;
 
 	case KEY_SPEC_USER_KEYRING:
 		key = context->user->uid_keyring;
 		atomic_inc(&key->usage);
+		key_ref = make_key_ref(key, 1);
 		break;
 
 	case KEY_SPEC_USER_SESSION_KEYRING:
 		key = context->user->session_keyring;
 		atomic_inc(&key->usage);
+		key_ref = make_key_ref(key, 1);
 		break;
 
 	case KEY_SPEC_GROUP_KEYRING:
@@ -606,13 +629,28 @@
 		goto error;
 
 	default:
-		key = ERR_PTR(-EINVAL);
+		key_ref = ERR_PTR(-EINVAL);
 		if (id < 1)
 			goto error;
 
 		key = key_lookup(id);
-		if (IS_ERR(key))
+		if (IS_ERR(key)) {
+			key_ref = ERR_PTR(PTR_ERR(key));
 			goto error;
+		}
+
+		key_ref = make_key_ref(key, 0);
+
+		/* check to see if we possess the key */
+		skey_ref = search_process_keyrings(key->type, key,
+						   lookup_user_key_possessed,
+						   current);
+
+		if (!IS_ERR(skey_ref)) {
+			key_put(key);
+			key_ref = skey_ref;
+		}
+
 		break;
 	}
 
@@ -630,15 +668,15 @@
 	/* check the permissions */
 	ret = -EACCES;
 
-	if (!key_task_permission(key, context, perm))
+	if (!key_task_permission(key_ref, context, perm))
 		goto invalid_key;
 
- error:
-	return key;
+error:
+	return key_ref;
 
- invalid_key:
-	key_put(key);
-	key = ERR_PTR(ret);
+invalid_key:
+	key_ref_put(key_ref);
+	key_ref = ERR_PTR(ret);
 	goto error;
 
 } /* end lookup_user_key() */
@@ -694,9 +732,9 @@
 	ret = keyring->serial;
 	key_put(keyring);
 
- error2:
+error2:
 	up(&key_session_sem);
- error:
+error:
 	return ret;
 
 } /* end join_session_keyring() */
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 90c1506..e6dd366 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -129,7 +129,7 @@
 
 	/* create a key and add it to the queue */
 	key = key_alloc(type, description,
-			current->fsuid, current->fsgid, KEY_USR_ALL, 0);
+			current->fsuid, current->fsgid, KEY_POS_ALL, 0);
 	if (IS_ERR(key))
 		goto alloc_failed;
 
@@ -365,14 +365,24 @@
 {
 	struct key_user *user;
 	struct key *key;
+	key_ref_t key_ref;
 
 	kenter("%s,%s,%s,%p",
 	       type->name, description, callout_info, dest_keyring);
 
 	/* search all the process keyrings for a key */
-	key = search_process_keyrings(type, description, type->match, current);
+	key_ref = search_process_keyrings(type, description, type->match,
+					  current);
 
-	if (PTR_ERR(key) == -EAGAIN) {
+	kdebug("search 1: %p", key_ref);
+
+	if (!IS_ERR(key_ref)) {
+		key = key_ref_to_ptr(key_ref);
+	}
+	else if (PTR_ERR(key_ref) != -EAGAIN) {
+		key = ERR_PTR(PTR_ERR(key_ref));
+	}
+	else  {
 		/* the search failed, but the keyrings were searchable, so we
 		 * should consult userspace if we can */
 		key = ERR_PTR(-ENOKEY);
@@ -384,7 +394,7 @@
 		if (!user)
 			goto nomem;
 
-		do {
+		for (;;) {
 			if (signal_pending(current))
 				goto interrupted;
 
@@ -397,10 +407,22 @@
 
 			/* someone else made the key we want, so we need to
 			 * search again as it might now be available to us */
-			key = search_process_keyrings(type, description,
-						      type->match, current);
+			key_ref = search_process_keyrings(type, description,
+							  type->match,
+							  current);
 
-		} while (PTR_ERR(key) == -EAGAIN);
+			kdebug("search 2: %p", key_ref);
+
+			if (!IS_ERR(key_ref)) {
+				key = key_ref_to_ptr(key_ref);
+				break;
+			}
+
+			if (PTR_ERR(key_ref) != -EAGAIN) {
+				key = ERR_PTR(PTR_ERR(key_ref));
+				break;
+			}
+		}
 
 		key_user_put(user);
 
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index f222646..1ecd3d3 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -126,7 +126,7 @@
 
 	rkakey = key_alloc(&key_type_request_key_auth, desc,
 			   current->fsuid, current->fsgid,
-			   KEY_USR_VIEW, 1);
+			   KEY_POS_VIEW | KEY_USR_VIEW, 1);
 	if (IS_ERR(rkakey)) {
 		key_put(keyring);
 		kleave("= %ld", PTR_ERR(rkakey));