diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/alpha/kernel/err_marvel.c linux-libre-2.6.34.15-gnu1/arch/alpha/kernel/err_marvel.c
--- linux-libre-2.6.34-gnu1/arch/alpha/kernel/err_marvel.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/alpha/kernel/err_marvel.c	2014-02-10 17:31:40.000000000 -0500
@@ -109,7 +109,7 @@ marvel_print_err_cyc(u64 err_cyc)
 #define IO7__ERR_CYC__CYCLE__M	(0x7)
 
 	printk("%s        Packet In Error: %s\n"
-	       "%s        Error in %s, cycle %ld%s%s\n",
+	       "%s        Error in %s, cycle %lld%s%s\n",
 	       err_print_prefix, 
 	       packet_desc[EXTRACT(err_cyc, IO7__ERR_CYC__PACKET)],
 	       err_print_prefix,
@@ -313,7 +313,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym
 	}
 
 	printk("%s      Up Hose Garbage Symptom:\n"
-	       "%s        Source Port: %ld - Dest PID: %ld - OpCode: %s\n", 
+	       "%s        Source Port: %lld - Dest PID: %lld - OpCode: %s\n",
 	       err_print_prefix,
 	       err_print_prefix, 
 	       EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_SRC_PORT),
@@ -552,7 +552,7 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt
 #define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__M	(0xfff)
 
 	printk("%s      Split Completion Error:\n"	
-	       "%s         Source (Bus:Dev:Func): %ld:%ld:%ld\n",
+	       "%s         Source (Bus:Dev:Func): %lld:%lld:%lld\n",
 	       err_print_prefix,
 	       err_print_prefix,
 	       EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_BUS),
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/alpha/kernel/osf_sys.c linux-libre-2.6.34.15-gnu1/arch/alpha/kernel/osf_sys.c
--- linux-libre-2.6.34-gnu1/arch/alpha/kernel/osf_sys.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/alpha/kernel/osf_sys.c	2014-02-10 17:31:40.000000000 -0500
@@ -432,7 +432,7 @@ SYSCALL_DEFINE2(osf_getdomainname, char
 		return -EFAULT;
 
 	len = namelen;
-	if (namelen > 32)
+	if (len > 32)
 		len = 32;
 
 	down_read(&uts_sem);
@@ -619,7 +619,7 @@ SYSCALL_DEFINE3(osf_sysinfo, int, comman
 	down_read(&uts_sem);
 	res = sysinfo_table[offset];
 	len = strlen(res)+1;
-	if (len > count)
+	if ((unsigned long)len > (unsigned long)count)
 		len = count;
 	if (copy_to_user(buf, res, len))
 		err = -EFAULT;
@@ -674,7 +674,7 @@ SYSCALL_DEFINE5(osf_getsysinfo, unsigned
 		return 1;
 
 	case GSI_GET_HWRPB:
-		if (nbytes < sizeof(*hwrpb))
+		if (nbytes > sizeof(*hwrpb))
 			return -EINVAL;
 		if (copy_to_user(buffer, hwrpb, nbytes) != 0)
 			return -EFAULT;
@@ -1036,6 +1036,7 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, i
 {
 	struct rusage r;
 	long ret, err;
+	unsigned int status = 0;
 	mm_segment_t old_fs;
 
 	if (!ur)
@@ -1044,13 +1045,15 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, i
 	old_fs = get_fs();
 		
 	set_fs (KERNEL_DS);
-	ret = sys_wait4(pid, ustatus, options, (struct rusage __user *) &r);
+	ret = sys_wait4(pid, (unsigned int __user *) &status, options,
+			(struct rusage __user *) &r);
 	set_fs (old_fs);
 
 	if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
 		return -EFAULT;
 
 	err = 0;
+	err |= put_user(status, ustatus);
 	err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
 	err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
 	err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/common/sa1111.c linux-libre-2.6.34.15-gnu1/arch/arm/common/sa1111.c
--- linux-libre-2.6.34-gnu1/arch/arm/common/sa1111.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/common/sa1111.c	2014-02-10 17:31:40.000000000 -0500
@@ -951,8 +951,6 @@ static int sa1111_resume(struct platform
 	if (!save)
 		return 0;
 
-	spin_lock_irqsave(&sachip->lock, flags);
-
 	/*
 	 * Ensure that the SA1111 is still here.
 	 * FIXME: shouldn't do this here.
@@ -969,6 +967,13 @@ static int sa1111_resume(struct platform
 	 * First of all, wake up the chip.
 	 */
 	sa1111_wake(sachip);
+
+	/*
+	 * Only lock for write ops. Also, sa1111_wake must be called with
+	 * released spinlock!
+	 */
+	spin_lock_irqsave(&sachip->lock, flags);
+
 	sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN0);
 	sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN1);
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/include/asm/assembler.h linux-libre-2.6.34.15-gnu1/arch/arm/include/asm/assembler.h
--- linux-libre-2.6.34-gnu1/arch/arm/include/asm/assembler.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/include/asm/assembler.h	2014-02-10 17:31:40.000000000 -0500
@@ -215,7 +215,7 @@
 	@ Slightly optimised to avoid incrementing the pointer twice
 	usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort
 	.if	\rept == 2
-	usraccoff \instr, \reg, \ptr, \inc, 4, \cond, \abort
+	usraccoff \instr, \reg, \ptr, \inc, \inc, \cond, \abort
 	.endif
 
 	add\cond \ptr, #\rept * \inc
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/include/asm/atomic.h linux-libre-2.6.34.15-gnu1/arch/arm/include/asm/atomic.h
--- linux-libre-2.6.34-gnu1/arch/arm/include/asm/atomic.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/include/asm/atomic.h	2014-02-10 17:31:40.000000000 -0500
@@ -40,12 +40,12 @@ static inline void atomic_add(int i, ato
 	int result;
 
 	__asm__ __volatile__("@ atomic_add\n"
-"1:	ldrex	%0, [%2]\n"
-"	add	%0, %0, %3\n"
-"	strex	%1, %0, [%2]\n"
+"1:	ldrex	%0, [%3]\n"
+"	add	%0, %0, %4\n"
+"	strex	%1, %0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
-	: "=&r" (result), "=&r" (tmp)
+	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
 	: "r" (&v->counter), "Ir" (i)
 	: "cc");
 }
@@ -58,12 +58,12 @@ static inline int atomic_add_return(int
 	smp_mb();
 
 	__asm__ __volatile__("@ atomic_add_return\n"
-"1:	ldrex	%0, [%2]\n"
-"	add	%0, %0, %3\n"
-"	strex	%1, %0, [%2]\n"
+"1:	ldrex	%0, [%3]\n"
+"	add	%0, %0, %4\n"
+"	strex	%1, %0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
-	: "=&r" (result), "=&r" (tmp)
+	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
 	: "r" (&v->counter), "Ir" (i)
 	: "cc");
 
@@ -78,12 +78,12 @@ static inline void atomic_sub(int i, ato
 	int result;
 
 	__asm__ __volatile__("@ atomic_sub\n"
-"1:	ldrex	%0, [%2]\n"
-"	sub	%0, %0, %3\n"
-"	strex	%1, %0, [%2]\n"
+"1:	ldrex	%0, [%3]\n"
+"	sub	%0, %0, %4\n"
+"	strex	%1, %0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
-	: "=&r" (result), "=&r" (tmp)
+	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
 	: "r" (&v->counter), "Ir" (i)
 	: "cc");
 }
@@ -96,12 +96,12 @@ static inline int atomic_sub_return(int
 	smp_mb();
 
 	__asm__ __volatile__("@ atomic_sub_return\n"
-"1:	ldrex	%0, [%2]\n"
-"	sub	%0, %0, %3\n"
-"	strex	%1, %0, [%2]\n"
+"1:	ldrex	%0, [%3]\n"
+"	sub	%0, %0, %4\n"
+"	strex	%1, %0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
-	: "=&r" (result), "=&r" (tmp)
+	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
 	: "r" (&v->counter), "Ir" (i)
 	: "cc");
 
@@ -118,11 +118,11 @@ static inline int atomic_cmpxchg(atomic_
 
 	do {
 		__asm__ __volatile__("@ atomic_cmpxchg\n"
-		"ldrex	%1, [%2]\n"
+		"ldrex	%1, [%3]\n"
 		"mov	%0, #0\n"
-		"teq	%1, %3\n"
-		"strexeq %0, %4, [%2]\n"
-		    : "=&r" (res), "=&r" (oldval)
+		"teq	%1, %4\n"
+		"strexeq %0, %5, [%3]\n"
+		    : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
 		    : "r" (&ptr->counter), "Ir" (old), "r" (new)
 		    : "cc");
 	} while (res);
@@ -137,12 +137,12 @@ static inline void atomic_clear_mask(uns
 	unsigned long tmp, tmp2;
 
 	__asm__ __volatile__("@ atomic_clear_mask\n"
-"1:	ldrex	%0, [%2]\n"
-"	bic	%0, %0, %3\n"
-"	strex	%1, %0, [%2]\n"
+"1:	ldrex	%0, [%3]\n"
+"	bic	%0, %0, %4\n"
+"	strex	%1, %0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
-	: "=&r" (tmp), "=&r" (tmp2)
+	: "=&r" (tmp), "=&r" (tmp2), "+Qo" (*addr)
 	: "r" (addr), "Ir" (mask)
 	: "cc");
 }
@@ -249,7 +249,7 @@ static inline u64 atomic64_read(atomic64
 	__asm__ __volatile__("@ atomic64_read\n"
 "	ldrexd	%0, %H0, [%1]"
 	: "=&r" (result)
-	: "r" (&v->counter)
+	: "r" (&v->counter), "Qo" (v->counter)
 	);
 
 	return result;
@@ -260,11 +260,11 @@ static inline void atomic64_set(atomic64
 	u64 tmp;
 
 	__asm__ __volatile__("@ atomic64_set\n"
-"1:	ldrexd	%0, %H0, [%1]\n"
-"	strexd	%0, %2, %H2, [%1]\n"
+"1:	ldrexd	%0, %H0, [%2]\n"
+"	strexd	%0, %3, %H3, [%2]\n"
 "	teq	%0, #0\n"
 "	bne	1b"
-	: "=&r" (tmp)
+	: "=&r" (tmp), "=Qo" (v->counter)
 	: "r" (&v->counter), "r" (i)
 	: "cc");
 }
@@ -275,13 +275,13 @@ static inline void atomic64_add(u64 i, a
 	unsigned long tmp;
 
 	__asm__ __volatile__("@ atomic64_add\n"
-"1:	ldrexd	%0, %H0, [%2]\n"
-"	adds	%0, %0, %3\n"
-"	adc	%H0, %H0, %H3\n"
-"	strexd	%1, %0, %H0, [%2]\n"
+"1:	ldrexd	%0, %H0, [%3]\n"
+"	adds	%0, %0, %4\n"
+"	adc	%H0, %H0, %H4\n"
+"	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
-	: "=&r" (result), "=&r" (tmp)
+	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
 	: "r" (&v->counter), "r" (i)
 	: "cc");
 }
@@ -294,13 +294,13 @@ static inline u64 atomic64_add_return(u6
 	smp_mb();
 
 	__asm__ __volatile__("@ atomic64_add_return\n"
-"1:	ldrexd	%0, %H0, [%2]\n"
-"	adds	%0, %0, %3\n"
-"	adc	%H0, %H0, %H3\n"
-"	strexd	%1, %0, %H0, [%2]\n"
+"1:	ldrexd	%0, %H0, [%3]\n"
+"	adds	%0, %0, %4\n"
+"	adc	%H0, %H0, %H4\n"
+"	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
-	: "=&r" (result), "=&r" (tmp)
+	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
 	: "r" (&v->counter), "r" (i)
 	: "cc");
 
@@ -315,13 +315,13 @@ static inline void atomic64_sub(u64 i, a
 	unsigned long tmp;
 
 	__asm__ __volatile__("@ atomic64_sub\n"
-"1:	ldrexd	%0, %H0, [%2]\n"
-"	subs	%0, %0, %3\n"
-"	sbc	%H0, %H0, %H3\n"
-"	strexd	%1, %0, %H0, [%2]\n"
+"1:	ldrexd	%0, %H0, [%3]\n"
+"	subs	%0, %0, %4\n"
+"	sbc	%H0, %H0, %H4\n"
+"	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
-	: "=&r" (result), "=&r" (tmp)
+	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
 	: "r" (&v->counter), "r" (i)
 	: "cc");
 }
@@ -334,13 +334,13 @@ static inline u64 atomic64_sub_return(u6
 	smp_mb();
 
 	__asm__ __volatile__("@ atomic64_sub_return\n"
-"1:	ldrexd	%0, %H0, [%2]\n"
-"	subs	%0, %0, %3\n"
-"	sbc	%H0, %H0, %H3\n"
-"	strexd	%1, %0, %H0, [%2]\n"
+"1:	ldrexd	%0, %H0, [%3]\n"
+"	subs	%0, %0, %4\n"
+"	sbc	%H0, %H0, %H4\n"
+"	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
-	: "=&r" (result), "=&r" (tmp)
+	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
 	: "r" (&v->counter), "r" (i)
 	: "cc");
 
@@ -358,12 +358,12 @@ static inline u64 atomic64_cmpxchg(atomi
 
 	do {
 		__asm__ __volatile__("@ atomic64_cmpxchg\n"
-		"ldrexd		%1, %H1, [%2]\n"
+		"ldrexd		%1, %H1, [%3]\n"
 		"mov		%0, #0\n"
-		"teq		%1, %3\n"
-		"teqeq		%H1, %H3\n"
-		"strexdeq	%0, %4, %H4, [%2]"
-		: "=&r" (res), "=&r" (oldval)
+		"teq		%1, %4\n"
+		"teqeq		%H1, %H4\n"
+		"strexdeq	%0, %5, %H5, [%3]"
+		: "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
 		: "r" (&ptr->counter), "r" (old), "r" (new)
 		: "cc");
 	} while (res);
@@ -381,11 +381,11 @@ static inline u64 atomic64_xchg(atomic64
 	smp_mb();
 
 	__asm__ __volatile__("@ atomic64_xchg\n"
-"1:	ldrexd	%0, %H0, [%2]\n"
-"	strexd	%1, %3, %H3, [%2]\n"
+"1:	ldrexd	%0, %H0, [%3]\n"
+"	strexd	%1, %4, %H4, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
-	: "=&r" (result), "=&r" (tmp)
+	: "=&r" (result), "=&r" (tmp), "+Qo" (ptr->counter)
 	: "r" (&ptr->counter), "r" (new)
 	: "cc");
 
@@ -402,16 +402,16 @@ static inline u64 atomic64_dec_if_positi
 	smp_mb();
 
 	__asm__ __volatile__("@ atomic64_dec_if_positive\n"
-"1:	ldrexd	%0, %H0, [%2]\n"
+"1:	ldrexd	%0, %H0, [%3]\n"
 "	subs	%0, %0, #1\n"
 "	sbc	%H0, %H0, #0\n"
 "	teq	%H0, #0\n"
 "	bmi	2f\n"
-"	strexd	%1, %0, %H0, [%2]\n"
+"	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b\n"
 "2:"
-	: "=&r" (result), "=&r" (tmp)
+	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
 	: "r" (&v->counter)
 	: "cc");
 
@@ -429,18 +429,18 @@ static inline int atomic64_add_unless(at
 	smp_mb();
 
 	__asm__ __volatile__("@ atomic64_add_unless\n"
-"1:	ldrexd	%0, %H0, [%3]\n"
-"	teq	%0, %4\n"
-"	teqeq	%H0, %H4\n"
+"1:	ldrexd	%0, %H0, [%4]\n"
+"	teq	%0, %5\n"
+"	teqeq	%H0, %H5\n"
 "	moveq	%1, #0\n"
 "	beq	2f\n"
-"	adds	%0, %0, %5\n"
-"	adc	%H0, %H0, %H5\n"
-"	strexd	%2, %0, %H0, [%3]\n"
+"	adds	%0, %0, %6\n"
+"	adc	%H0, %H0, %H6\n"
+"	strexd	%2, %0, %H0, [%4]\n"
 "	teq	%2, #0\n"
 "	bne	1b\n"
 "2:"
-	: "=&r" (val), "=&r" (ret), "=&r" (tmp)
+	: "=&r" (val), "+r" (ret), "=&r" (tmp), "+Qo" (v->counter)
 	: "r" (&v->counter), "r" (u), "r" (a)
 	: "cc");
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/include/asm/ptrace.h linux-libre-2.6.34.15-gnu1/arch/arm/include/asm/ptrace.h
--- linux-libre-2.6.34-gnu1/arch/arm/include/asm/ptrace.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/include/asm/ptrace.h	2014-02-10 17:31:40.000000000 -0500
@@ -158,15 +158,24 @@ struct pt_regs {
  */
 static inline int valid_user_regs(struct pt_regs *regs)
 {
-	if (user_mode(regs) && (regs->ARM_cpsr & PSR_I_BIT) == 0) {
-		regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT);
-		return 1;
+	unsigned long mode = regs->ARM_cpsr & MODE_MASK;
+
+	/*
+	 * Always clear the F (FIQ) and A (delayed abort) bits
+	 */
+	regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT);
+
+	if ((regs->ARM_cpsr & PSR_I_BIT) == 0) {
+		if (mode == USR_MODE)
+			return 1;
+		if (elf_hwcap & HWCAP_26BIT && mode == USR26_MODE)
+			return 1;
 	}
 
 	/*
 	 * Force CPSR to something logical...
 	 */
-	regs->ARM_cpsr &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | PSR_T_BIT | MODE32_BIT;
+	regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT;
 	if (!(elf_hwcap & HWCAP_26BIT))
 		regs->ARM_cpsr |= USR_MODE;
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/include/asm/tlbflush.h linux-libre-2.6.34.15-gnu1/arch/arm/include/asm/tlbflush.h
--- linux-libre-2.6.34-gnu1/arch/arm/include/asm/tlbflush.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/include/asm/tlbflush.h	2014-02-10 17:31:40.000000000 -0500
@@ -378,7 +378,11 @@ static inline void local_flush_tlb_mm(st
 	if (tlb_flag(TLB_V6_I_ASID))
 		asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
 	if (tlb_flag(TLB_V7_UIS_ASID))
+#ifdef CONFIG_ARM_ERRATA_720789
+		asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
+#else
 		asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc");
+#endif
 
 	if (tlb_flag(TLB_BTB)) {
 		/* flush the branch target cache */
@@ -424,7 +428,11 @@ local_flush_tlb_page(struct vm_area_stru
 	if (tlb_flag(TLB_V6_I_PAGE))
 		asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
 	if (tlb_flag(TLB_V7_UIS_PAGE))
+#ifdef CONFIG_ARM_ERRATA_720789
+		asm("mcr p15, 0, %0, c8, c3, 3" : : "r" (uaddr & PAGE_MASK) : "cc");
+#else
 		asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc");
+#endif
 
 	if (tlb_flag(TLB_BTB)) {
 		/* flush the branch target cache */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/Kconfig linux-libre-2.6.34.15-gnu1/arch/arm/Kconfig
--- linux-libre-2.6.34-gnu1/arch/arm/Kconfig	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/Kconfig	2014-02-10 17:31:40.000000000 -0500
@@ -1025,6 +1025,18 @@ config PL310_ERRATA_588369
 	   is not correctly implemented in PL310 as clean lines are not
 	   invalidated as a result of these operations. Note that this errata
 	   uses Texas Instrument's secure monitor api.
+
+config ARM_ERRATA_720789
+	bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID"
+	depends on CPU_V7 && SMP
+	help
+	  This option enables the workaround for the 720789 Cortex-A9 (prior to
+	  r2p0) erratum. A faulty ASID can be sent to the other CPUs for the
+	  broadcasted CP15 TLB maintenance operations TLBIASIDIS and TLBIMVAIS.
+	  As a consequence of this erratum, some TLB entries which should be
+	  invalidated are not, resulting in an incoherency in the system page
+	  tables. The workaround changes the TLB flushing routines to invalidate
+	  entries regardless of the ASID.
 endmenu
 
 source "arch/arm/common/Kconfig"
@@ -1368,6 +1380,18 @@ config UACCESS_WITH_MEMCPY
 	  However, if the CPU data cache is using a write-allocate mode,
 	  this option is unlikely to provide any performance gain.
 
+config PL310_ERRATA_769419
+	bool "PL310 errata: no automatic Store Buffer drain"
+	depends on CACHE_L2X0
+	help
+	  On revisions of the PL310 prior to r3p2, the Store Buffer does
+	  not automatically drain. This can cause normal, non-cacheable
+	  writes to be retained when the memory system is idle, leading
+	  to suboptimal I/O performance for drivers using coherent DMA.
+	  This option adds a write barrier to the cpu_idle loop so that,
+	  on systems with an outer cache, the store buffer is drained
+	  explicitly.
+
 endmenu
 
 menu "Boot options"
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/kernel/entry-common.S linux-libre-2.6.34.15-gnu1/arch/arm/kernel/entry-common.S
--- linux-libre-2.6.34-gnu1/arch/arm/kernel/entry-common.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/kernel/entry-common.S	2014-02-10 17:31:40.000000000 -0500
@@ -382,11 +382,13 @@ ENDPROC(sys_clone_wrapper)
 
 sys_sigreturn_wrapper:
 		add	r0, sp, #S_OFF
+		mov	why, #0		@ prevent syscall restart handling
 		b	sys_sigreturn
 ENDPROC(sys_sigreturn_wrapper)
 
 sys_rt_sigreturn_wrapper:
 		add	r0, sp, #S_OFF
+		mov	why, #0		@ prevent syscall restart handling
 		b	sys_rt_sigreturn
 ENDPROC(sys_rt_sigreturn_wrapper)
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/kernel/kprobes-decode.c linux-libre-2.6.34.15-gnu1/arch/arm/kernel/kprobes-decode.c
--- linux-libre-2.6.34-gnu1/arch/arm/kernel/kprobes-decode.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/kernel/kprobes-decode.c	2014-02-10 17:31:40.000000000 -0500
@@ -583,13 +583,14 @@ static void __kprobes emulate_ldr(struct
 {
 	insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0];
 	kprobe_opcode_t insn = p->opcode;
+	long ppc = (long)p->addr + 8;
 	union reg_pair fnr;
 	int rd = (insn >> 12) & 0xf;
 	int rn = (insn >> 16) & 0xf;
 	int rm = insn & 0xf;
 	long rdv;
-	long rnv  = regs->uregs[rn];
-	long rmv  = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */
+	long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+	long rmv = (rm == 15) ? ppc : regs->uregs[rm];
 	long cpsr = regs->ARM_cpsr;
 
 	fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/kernel/perf_event.c linux-libre-2.6.34.15-gnu1/arch/arm/kernel/perf_event.c
--- linux-libre-2.6.34-gnu1/arch/arm/kernel/perf_event.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/kernel/perf_event.c	2014-02-10 17:31:40.000000000 -0500
@@ -165,7 +165,7 @@ armpmu_event_update(struct perf_event *e
 {
 	int shift = 64 - 32;
 	s64 prev_raw_count, new_raw_count;
-	s64 delta;
+	u64 delta;
 
 again:
 	prev_raw_count = atomic64_read(&hwc->prev_count);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/kernel/process.c linux-libre-2.6.34.15-gnu1/arch/arm/kernel/process.c
--- linux-libre-2.6.34-gnu1/arch/arm/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/kernel/process.c	2014-02-10 17:31:40.000000000 -0500
@@ -155,6 +155,9 @@ void cpu_idle(void)
 #endif
 
 			local_irq_disable();
+#ifdef CONFIG_PL310_ERRATA_769419
+			wmb();
+#endif
 			if (hlt_counter) {
 				local_irq_enable();
 				cpu_relax();
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/kernel/signal.c linux-libre-2.6.34.15-gnu1/arch/arm/kernel/signal.c
--- linux-libre-2.6.34-gnu1/arch/arm/kernel/signal.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/kernel/signal.c	2014-02-10 17:31:40.000000000 -0500
@@ -474,7 +474,9 @@ setup_return(struct pt_regs *regs, struc
 	unsigned long handler = (unsigned long)ka->sa.sa_handler;
 	unsigned long retcode;
 	int thumb = 0;
-	unsigned long cpsr = regs->ARM_cpsr & ~PSR_f;
+	unsigned long cpsr = regs->ARM_cpsr & ~(PSR_f | PSR_E_BIT);
+
+	cpsr |= PSR_ENDSTATE;
 
 	/*
 	 * Maybe we need to deliver a 32-bit signal to a 26-bit task.
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/kernel/sys_oabi-compat.c linux-libre-2.6.34.15-gnu1/arch/arm/kernel/sys_oabi-compat.c
--- linux-libre-2.6.34-gnu1/arch/arm/kernel/sys_oabi-compat.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/kernel/sys_oabi-compat.c	2014-02-10 17:31:40.000000000 -0500
@@ -311,7 +311,7 @@ asmlinkage long sys_oabi_semtimedop(int
 	long err;
 	int i;
 
-	if (nsops < 1)
+	if (nsops < 1 || nsops > SEMOPM)
 		return -EINVAL;
 	sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
 	if (!sops)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/lib/findbit.S linux-libre-2.6.34.15-gnu1/arch/arm/lib/findbit.S
--- linux-libre-2.6.34-gnu1/arch/arm/lib/findbit.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/lib/findbit.S	2014-02-10 17:31:40.000000000 -0500
@@ -174,8 +174,8 @@ ENDPROC(_find_next_bit_be)
  */
 .L_found:
 #if __LINUX_ARM_ARCH__ >= 5
-		rsb	r1, r3, #0
-		and	r3, r3, r1
+		rsb	r0, r3, #0
+		and	r3, r3, r0
 		clz	r3, r3
 		rsb	r3, r3, #31
 		add	r0, r2, r3
@@ -190,5 +190,7 @@ ENDPROC(_find_next_bit_be)
 		addeq	r2, r2, #1
 		mov	r0, r2
 #endif
+		cmp	r1, r0			@ Clamp to maxbit
+		movlo	r0, r1
 		mov	pc, lr
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mach-at91/at91sam9g45_devices.c linux-libre-2.6.34.15-gnu1/arch/arm/mach-at91/at91sam9g45_devices.c
--- linux-libre-2.6.34-gnu1/arch/arm/mach-at91/at91sam9g45_devices.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mach-at91/at91sam9g45_devices.c	2014-02-10 17:31:40.000000000 -0500
@@ -46,7 +46,7 @@ static struct resource hdmac_resources[]
 		.end	= AT91_BASE_SYS + AT91_DMA + SZ_512 - 1,
 		.flags	= IORESOURCE_MEM,
 	},
-	[2] = {
+	[1] = {
 		.start	= AT91SAM9G45_ID_DMA,
 		.end	= AT91SAM9G45_ID_DMA,
 		.flags	= IORESOURCE_IRQ,
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-da850-evm.c linux-libre-2.6.34.15-gnu1/arch/arm/mach-davinci/board-da850-evm.c
--- linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-da850-evm.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mach-davinci/board-da850-evm.c	2014-02-10 17:31:40.000000000 -0500
@@ -44,6 +44,32 @@
 
 #define DA850_MII_MDIO_CLKEN_PIN	GPIO_TO_PIN(2, 6)
 
+#ifdef CONFIG_MTD
+static void da850_evm_m25p80_notify_add(struct mtd_info *mtd)
+{
+	char *mac_addr = davinci_soc_info.emac_pdata->mac_addr;
+	size_t retlen;
+
+	if (!strcmp(mtd->name, "MAC-Address")) {
+		mtd->read(mtd, 0, ETH_ALEN, &retlen, mac_addr);
+		if (retlen == ETH_ALEN)
+			pr_info("Read MAC addr from SPI Flash: %pM\n",
+				mac_addr);
+	}
+}
+
+static struct mtd_notifier da850evm_spi_notifier = {
+	.add	= da850_evm_m25p80_notify_add,
+};
+
+static void da850_evm_setup_mac_addr(void)
+{
+	register_mtd_user(&da850evm_spi_notifier);
+}
+#else
+static void da850_evm_setup_mac_addr(void) { }
+#endif
+
 static struct mtd_partition da850_evm_norflash_partition[] = {
 	{
 		.name           = "bootloaders + env",
@@ -726,6 +752,8 @@ static __init void da850_evm_init(void)
 	if (ret)
 		pr_warning("da850_evm_init: suspend registration failed: %d\n",
 				ret);
+
+	da850_evm_setup_mac_addr();
 }
 
 #ifdef CONFIG_SERIAL_8250_CONSOLE
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-dm365-evm.c linux-libre-2.6.34.15-gnu1/arch/arm/mach-davinci/board-dm365-evm.c
--- linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-dm365-evm.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mach-davinci/board-dm365-evm.c	2014-02-10 17:31:40.000000000 -0500
@@ -525,7 +525,7 @@ fail:
 	 */
 	if (have_imager()) {
 		label = "HD imager";
-		mux |= 1;
+		mux |= 2;
 
 		/* externally mux MMC1/ENET/AIC33 to imager */
 		mux |= BIT(6) | BIT(5) | BIT(3);
@@ -546,7 +546,7 @@ fail:
 		resets &= ~BIT(1);
 
 		if (have_tvp7002()) {
-			mux |= 2;
+			mux |= 1;
 			resets &= ~BIT(2);
 			label = "tvp7002 HD";
 		} else {
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-dm646x-evm.c linux-libre-2.6.34.15-gnu1/arch/arm/mach-davinci/board-dm646x-evm.c
--- linux-libre-2.6.34-gnu1/arch/arm/mach-davinci/board-dm646x-evm.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mach-davinci/board-dm646x-evm.c	2014-02-10 17:31:40.000000000 -0500
@@ -555,7 +555,7 @@ static int setup_vpif_input_channel_mode
 	int val;
 	u32 value;
 
-	if (!vpif_vsclkdis_reg || !cpld_client)
+	if (!vpif_vidclkctl_reg || !cpld_client)
 		return -ENXIO;
 
 	val = i2c_smbus_read_byte(cpld_client);
@@ -563,7 +563,7 @@ static int setup_vpif_input_channel_mode
 		return val;
 
 	spin_lock_irqsave(&vpif_reg_lock, flags);
-	value = __raw_readl(vpif_vsclkdis_reg);
+	value = __raw_readl(vpif_vidclkctl_reg);
 	if (mux_mode) {
 		val &= VPIF_INPUT_TWO_CHANNEL;
 		value |= VIDCH1CLK;
@@ -571,7 +571,7 @@ static int setup_vpif_input_channel_mode
 		val |= VPIF_INPUT_ONE_CHANNEL;
 		value &= ~VIDCH1CLK;
 	}
-	__raw_writel(value, vpif_vsclkdis_reg);
+	__raw_writel(value, vpif_vidclkctl_reg);
 	spin_unlock_irqrestore(&vpif_reg_lock, flags);
 
 	err = i2c_smbus_write_byte(cpld_client, val);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/ixdp425-setup.c linux-libre-2.6.34.15-gnu1/arch/arm/mach-ixp4xx/ixdp425-setup.c
--- linux-libre-2.6.34-gnu1/arch/arm/mach-ixp4xx/ixdp425-setup.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mach-ixp4xx/ixdp425-setup.c	2014-02-10 17:31:40.000000000 -0500
@@ -100,6 +100,7 @@ ixdp425_flash_nand_cmd_ctrl(struct mtd_i
 
 static struct platform_nand_data ixdp425_flash_nand_data = {
 	.chip = {
+		.nr_chips		= 1,
 		.chip_delay		= 30,
 		.options		= NAND_NO_AUTOINCR,
 #ifdef CONFIG_MTD_PARTITIONS
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/devices.c linux-libre-2.6.34.15-gnu1/arch/arm/mach-mx2/devices.c
--- linux-libre-2.6.34-gnu1/arch/arm/mach-mx2/devices.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mach-mx2/devices.c	2014-02-10 17:31:40.000000000 -0500
@@ -483,8 +483,8 @@ int __init mxc_register_gpios(void)
 #ifdef CONFIG_MACH_MX21
 static struct resource mx21_usbhc_resources[] = {
 	{
-		.start	= MX21_BASE_ADDR,
-		.end	= MX21_BASE_ADDR + 0x1FFF,
+		.start	= MX21_USBOTG_BASE_ADDR,
+		.end	= MX21_USBOTG_BASE_ADDR + SZ_8K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-qong.c linux-libre-2.6.34.15-gnu1/arch/arm/mach-mx3/mach-qong.c
--- linux-libre-2.6.34-gnu1/arch/arm/mach-mx3/mach-qong.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mach-mx3/mach-qong.c	2014-02-10 17:31:40.000000000 -0500
@@ -169,6 +169,7 @@ static void qong_nand_select_chip(struct
 
 static struct platform_nand_data qong_nand_data = {
 	.chip = {
+		.nr_chips		= 1,
 		.chip_delay		= 20,
 		.options		= 0,
 	},
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c linux-libre-2.6.34.15-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c
--- linux-libre-2.6.34-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mach-omap2/board-rx51-peripherals.c	2014-02-10 17:31:40.000000000 -0500
@@ -147,6 +147,10 @@ static void __init rx51_add_gpio_keys(vo
 #endif /* CONFIG_KEYBOARD_GPIO || CONFIG_KEYBOARD_GPIO_MODULE */
 
 static int board_keymap[] = {
+	/*
+	 * Note that KEY(x, 8, KEY_XXX) entries represent "entrire row
+	 * connected to the ground" matrix state.
+	 */
 	KEY(0, 0, KEY_Q),
 	KEY(0, 1, KEY_O),
 	KEY(0, 2, KEY_P),
@@ -154,6 +158,7 @@ static int board_keymap[] = {
 	KEY(0, 4, KEY_BACKSPACE),
 	KEY(0, 6, KEY_A),
 	KEY(0, 7, KEY_S),
+
 	KEY(1, 0, KEY_W),
 	KEY(1, 1, KEY_D),
 	KEY(1, 2, KEY_F),
@@ -162,6 +167,7 @@ static int board_keymap[] = {
 	KEY(1, 5, KEY_J),
 	KEY(1, 6, KEY_K),
 	KEY(1, 7, KEY_L),
+
 	KEY(2, 0, KEY_E),
 	KEY(2, 1, KEY_DOT),
 	KEY(2, 2, KEY_UP),
@@ -169,6 +175,8 @@ static int board_keymap[] = {
 	KEY(2, 5, KEY_Z),
 	KEY(2, 6, KEY_X),
 	KEY(2, 7, KEY_C),
+	KEY(2, 8, KEY_F9),
+
 	KEY(3, 0, KEY_R),
 	KEY(3, 1, KEY_V),
 	KEY(3, 2, KEY_B),
@@ -177,20 +185,23 @@ static int board_keymap[] = {
 	KEY(3, 5, KEY_SPACE),
 	KEY(3, 6, KEY_SPACE),
 	KEY(3, 7, KEY_LEFT),
+
 	KEY(4, 0, KEY_T),
 	KEY(4, 1, KEY_DOWN),
 	KEY(4, 2, KEY_RIGHT),
 	KEY(4, 4, KEY_LEFTCTRL),
 	KEY(4, 5, KEY_RIGHTALT),
 	KEY(4, 6, KEY_LEFTSHIFT),
+	KEY(4, 8, KEY_F10),
+
 	KEY(5, 0, KEY_Y),
+	KEY(5, 8, KEY_F11),
+
 	KEY(6, 0, KEY_U),
+
 	KEY(7, 0, KEY_I),
 	KEY(7, 1, KEY_F7),
 	KEY(7, 2, KEY_F8),
-	KEY(0xff, 2, KEY_F9),
-	KEY(0xff, 4, KEY_F10),
-	KEY(0xff, 5, KEY_F11),
 };
 
 static struct matrix_keymap_data board_map_data = {
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/ts78xx-setup.c linux-libre-2.6.34.15-gnu1/arch/arm/mach-orion5x/ts78xx-setup.c
--- linux-libre-2.6.34-gnu1/arch/arm/mach-orion5x/ts78xx-setup.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mach-orion5x/ts78xx-setup.c	2014-02-10 17:31:40.000000000 -0500
@@ -216,6 +216,7 @@ static struct mtd_partition ts78xx_ts_na
 
 static struct platform_nand_data ts78xx_ts_nand_data = {
 	.chip	= {
+		.nr_chips		= 1,
 		.part_probe_types	= ts_nand_part_probes,
 		.partitions		= ts78xx_ts_nand_parts,
 		.nr_partitions		= ARRAY_SIZE(ts78xx_ts_nand_parts),
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/cm-x300.c linux-libre-2.6.34.15-gnu1/arch/arm/mach-pxa/cm-x300.c
--- linux-libre-2.6.34-gnu1/arch/arm/mach-pxa/cm-x300.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mach-pxa/cm-x300.c	2014-02-10 17:31:40.000000000 -0500
@@ -154,10 +154,10 @@ static mfp_cfg_t cm_x3xx_mfp_cfg[] __ini
 	GPIO99_GPIO,			/* Ethernet IRQ */
 
 	/* RTC GPIOs */
-	GPIO95_GPIO,			/* RTC CS */
-	GPIO96_GPIO,			/* RTC WR */
-	GPIO97_GPIO,			/* RTC RD */
-	GPIO98_GPIO,			/* RTC IO */
+	GPIO95_GPIO | MFP_LPM_DRIVE_HIGH,	/* RTC CS */
+	GPIO96_GPIO | MFP_LPM_DRIVE_HIGH,	/* RTC WR */
+	GPIO97_GPIO | MFP_LPM_DRIVE_HIGH,	/* RTC RD */
+	GPIO98_GPIO,				/* RTC IO */
 
 	/* Standard I2C */
 	GPIO21_I2C_SCL,
@@ -667,9 +667,10 @@ static void __init cm_x300_init(void)
 {
 	cm_x300_init_mfp();
 
-	pxa_set_ffuart_info(NULL);
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
+	if (cpu_is_pxa300())
+		pxa_set_ffuart_info(NULL);
 
 	cm_x300_init_da9030();
 	cm_x300_init_dm9000();
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mach-realview/include/mach/barriers.h linux-libre-2.6.34.15-gnu1/arch/arm/mach-realview/include/mach/barriers.h
--- linux-libre-2.6.34-gnu1/arch/arm/mach-realview/include/mach/barriers.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mach-realview/include/mach/barriers.h	2014-02-10 17:31:40.000000000 -0500
@@ -0,0 +1,8 @@
+/*
+ * Barriers redefined for RealView ARM11MPCore platforms with L220 cache
+ * controller to work around hardware errata causing the outer_sync()
+ * operation to deadlock the system.
+ */
+#define mb()		dsb()
+#define rmb()		dmb()
+#define wmb()		mb()
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mach-realview/Kconfig linux-libre-2.6.34.15-gnu1/arch/arm/mach-realview/Kconfig
--- linux-libre-2.6.34-gnu1/arch/arm/mach-realview/Kconfig	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mach-realview/Kconfig	2014-02-10 17:31:40.000000000 -0500
@@ -18,6 +18,7 @@ config REALVIEW_EB_ARM11MP
 	bool "Support ARM11MPCore tile"
 	depends on MACH_REALVIEW_EB
 	select CPU_V6
+	select ARCH_HAS_BARRIERS if SMP
 	help
 	  Enable support for the ARM11MPCore tile on the Realview platform.
 
@@ -35,6 +36,7 @@ config MACH_REALVIEW_PB11MP
 	select CPU_V6
 	select ARM_GIC
 	select HAVE_PATA_PLATFORM
+	select ARCH_HAS_BARRIERS if SMP
 	help
 	  Include support for the ARM(R) RealView MPCore Platform Baseboard.
 	  PB11MPCore is a platform with an on-board ARM11MPCore and has
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v7.S linux-libre-2.6.34.15-gnu1/arch/arm/mm/cache-v7.S
--- linux-libre-2.6.34-gnu1/arch/arm/mm/cache-v7.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mm/cache-v7.S	2014-02-10 17:31:40.000000000 -0500
@@ -91,7 +91,11 @@ ENTRY(v7_flush_kern_cache_all)
  THUMB(	stmfd	sp!, {r4-r7, r9-r11, lr}	)
 	bl	v7_flush_dcache_all
 	mov	r0, #0
+#ifdef CONFIG_SMP
+	mcr	p15, 0, r0, c7, c1, 0		@ invalidate I-cache inner shareable
+#else
 	mcr	p15, 0, r0, c7, c5, 0		@ I+BTB cache invalidate
+#endif
  ARM(	ldmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
  THUMB(	ldmfd	sp!, {r4-r7, r9-r11, lr}	)
 	mov	pc, lr
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-feroceon.c linux-libre-2.6.34.15-gnu1/arch/arm/mm/copypage-feroceon.c
--- linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-feroceon.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mm/copypage-feroceon.c	2014-02-10 17:31:40.000000000 -0500
@@ -18,7 +18,7 @@ feroceon_copy_user_page(void *kto, const
 {
 	asm("\
 	stmfd	sp!, {r4-r9, lr}		\n\
-	mov	ip, %0				\n\
+	mov	ip, %2				\n\
 1:	mov	lr, r1				\n\
 	ldmia	r1!, {r2 - r9}			\n\
 	pld	[lr, #32]			\n\
@@ -64,7 +64,7 @@ feroceon_copy_user_page(void *kto, const
 	mcr	p15, 0, ip, c7, c10, 4		@ drain WB\n\
 	ldmfd	sp!, {r4-r9, pc}"
 	:
-	: "I" (PAGE_SIZE));
+	: "r" (kto), "r" (kfrom), "I" (PAGE_SIZE));
 }
 
 void feroceon_copy_user_highpage(struct page *to, struct page *from,
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v4wb.c linux-libre-2.6.34.15-gnu1/arch/arm/mm/copypage-v4wb.c
--- linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v4wb.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mm/copypage-v4wb.c	2014-02-10 17:31:40.000000000 -0500
@@ -27,7 +27,7 @@ v4wb_copy_user_page(void *kto, const voi
 {
 	asm("\
 	stmfd	sp!, {r4, lr}			@ 2\n\
-	mov	r2, %0				@ 1\n\
+	mov	r2, %2				@ 1\n\
 	ldmia	r1!, {r3, r4, ip, lr}		@ 4\n\
 1:	mcr	p15, 0, r0, c7, c6, 1		@ 1   invalidate D line\n\
 	stmia	r0!, {r3, r4, ip, lr}		@ 4\n\
@@ -44,7 +44,7 @@ v4wb_copy_user_page(void *kto, const voi
 	mcr	p15, 0, r1, c7, c10, 4		@ 1   drain WB\n\
 	ldmfd	 sp!, {r4, pc}			@ 3"
 	:
-	: "I" (PAGE_SIZE / 64));
+	: "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
 }
 
 void v4wb_copy_user_highpage(struct page *to, struct page *from,
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v4wt.c linux-libre-2.6.34.15-gnu1/arch/arm/mm/copypage-v4wt.c
--- linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-v4wt.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mm/copypage-v4wt.c	2014-02-10 17:31:40.000000000 -0500
@@ -25,7 +25,7 @@ v4wt_copy_user_page(void *kto, const voi
 {
 	asm("\
 	stmfd	sp!, {r4, lr}			@ 2\n\
-	mov	r2, %0				@ 1\n\
+	mov	r2, %2				@ 1\n\
 	ldmia	r1!, {r3, r4, ip, lr}		@ 4\n\
 1:	stmia	r0!, {r3, r4, ip, lr}		@ 4\n\
 	ldmia	r1!, {r3, r4, ip, lr}		@ 4+1\n\
@@ -40,7 +40,7 @@ v4wt_copy_user_page(void *kto, const voi
 	mcr	p15, 0, r2, c7, c7, 0		@ flush ID cache\n\
 	ldmfd	sp!, {r4, pc}			@ 3"
 	:
-	: "I" (PAGE_SIZE / 64));
+	: "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
 }
 
 void v4wt_copy_user_highpage(struct page *to, struct page *from,
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-xsc3.c linux-libre-2.6.34.15-gnu1/arch/arm/mm/copypage-xsc3.c
--- linux-libre-2.6.34-gnu1/arch/arm/mm/copypage-xsc3.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mm/copypage-xsc3.c	2014-02-10 17:31:40.000000000 -0500
@@ -34,7 +34,7 @@ xsc3_mc_copy_user_page(void *kto, const
 {
 	asm("\
 	stmfd	sp!, {r4, r5, lr}		\n\
-	mov	lr, %0				\n\
+	mov	lr, %2				\n\
 						\n\
 	pld	[r1, #0]			\n\
 	pld	[r1, #32]			\n\
@@ -67,7 +67,7 @@ xsc3_mc_copy_user_page(void *kto, const
 						\n\
 	ldmfd	sp!, {r4, r5, pc}"
 	:
-	: "I" (PAGE_SIZE / 64 - 1));
+	: "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64 - 1));
 }
 
 void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mm/fault.c linux-libre-2.6.34.15-gnu1/arch/arm/mm/fault.c
--- linux-libre-2.6.34-gnu1/arch/arm/mm/fault.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mm/fault.c	2014-02-10 17:31:40.000000000 -0500
@@ -393,6 +393,9 @@ do_translation_fault(unsigned long addr,
 	if (addr < TASK_SIZE)
 		return do_page_fault(addr, fsr, regs);
 
+	if (user_mode(regs))
+		goto bad_area;
+
 	index = pgd_index(addr);
 
 	/*
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/mm/init.c linux-libre-2.6.34.15-gnu1/arch/arm/mm/init.c
--- linux-libre-2.6.34-gnu1/arch/arm/mm/init.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/mm/init.c	2014-02-10 17:31:40.000000000 -0500
@@ -712,10 +712,10 @@ void __init mem_init(void)
 void free_initmem(void)
 {
 #ifdef CONFIG_HAVE_TCM
-	extern char *__tcm_start, *__tcm_end;
+	extern char __tcm_start, __tcm_end;
 
-	totalram_pages += free_area(__phys_to_pfn(__pa(__tcm_start)),
-				    __phys_to_pfn(__pa(__tcm_end)),
+	totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)),
+				    __phys_to_pfn(__pa(&__tcm_end)),
 				    "TCM link");
 #endif
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/gpio.c linux-libre-2.6.34.15-gnu1/arch/arm/plat-mxc/gpio.c
--- linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/gpio.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/plat-mxc/gpio.c	2014-02-10 17:31:40.000000000 -0500
@@ -215,13 +215,16 @@ static void _set_gpio_direction(struct g
 	struct mxc_gpio_port *port =
 		container_of(chip, struct mxc_gpio_port, chip);
 	u32 l;
+	unsigned long flags;
 
+	spin_lock_irqsave(&port->lock, flags);
 	l = __raw_readl(port->base + GPIO_GDIR);
 	if (dir)
 		l |= 1 << offset;
 	else
 		l &= ~(1 << offset);
 	__raw_writel(l, port->base + GPIO_GDIR);
+	spin_unlock_irqrestore(&port->lock, flags);
 }
 
 static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
@@ -230,9 +233,12 @@ static void mxc_gpio_set(struct gpio_chi
 		container_of(chip, struct mxc_gpio_port, chip);
 	void __iomem *reg = port->base + GPIO_DR;
 	u32 l;
+	unsigned long flags;
 
+	spin_lock_irqsave(&port->lock, flags);
 	l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset);
 	__raw_writel(l, reg);
+	spin_unlock_irqrestore(&port->lock, flags);
 }
 
 static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -286,6 +292,8 @@ int __init mxc_gpio_init(struct mxc_gpio
 		port[i].chip.base = i * 32;
 		port[i].chip.ngpio = 32;
 
+		spin_lock_init(&port[i].lock);
+
 		/* its a serious configuration bug when it fails */
 		BUG_ON( gpiochip_add(&port[i].chip) < 0 );
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/gpio.h linux-libre-2.6.34.15-gnu1/arch/arm/plat-mxc/include/mach/gpio.h
--- linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/gpio.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/plat-mxc/include/mach/gpio.h	2014-02-10 17:31:40.000000000 -0500
@@ -19,6 +19,7 @@
 #ifndef __ASM_ARCH_MXC_GPIO_H__
 #define __ASM_ARCH_MXC_GPIO_H__
 
+#include <linux/spinlock.h>
 #include <mach/hardware.h>
 #include <asm-generic/gpio.h>
 
@@ -36,6 +37,7 @@ struct mxc_gpio_port {
 	int virtual_irq_start;
 	struct gpio_chip chip;
 	u32 both_edges;
+	spinlock_t lock;
 };
 
 int mxc_gpio_init(struct mxc_gpio_port*, int);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-v3.h linux-libre-2.6.34.15-gnu1/arch/arm/plat-mxc/include/mach/iomux-v3.h
--- linux-libre-2.6.34-gnu1/arch/arm/plat-mxc/include/mach/iomux-v3.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/plat-mxc/include/mach/iomux-v3.h	2014-02-10 17:31:40.000000000 -0500
@@ -73,11 +73,11 @@ struct pad_desc {
 #define PAD_CTL_HYS			(1 << 8)
 
 #define PAD_CTL_PKE			(1 << 7)
-#define PAD_CTL_PUE			(1 << 6)
-#define PAD_CTL_PUS_100K_DOWN		(0 << 4)
-#define PAD_CTL_PUS_47K_UP		(1 << 4)
-#define PAD_CTL_PUS_100K_UP		(2 << 4)
-#define PAD_CTL_PUS_22K_UP		(3 << 4)
+#define PAD_CTL_PUE			(1 << 6 | PAD_CTL_PKE)
+#define PAD_CTL_PUS_100K_DOWN		(0 << 4 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_47K_UP		(1 << 4 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_100K_UP		(2 << 4 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_22K_UP		(3 << 4 | PAD_CTL_PUE)
 
 #define PAD_CTL_ODE			(1 << 3)
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/arm/vfp/vfphw.S linux-libre-2.6.34.15-gnu1/arch/arm/vfp/vfphw.S
--- linux-libre-2.6.34-gnu1/arch/arm/vfp/vfphw.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/arm/vfp/vfphw.S	2014-02-10 17:31:40.000000000 -0500
@@ -277,7 +277,7 @@ ENTRY(vfp_put_double)
 #ifdef CONFIG_VFPv3
 	@ d16 - d31 registers
 	.irp	dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
-1:	mcrr	p11, 3, r1, r2, c\dr	@ fmdrr	r1, r2, d\dr
+1:	mcrr	p11, 3, r0, r1, c\dr	@ fmdrr	r0, r1, d\dr
 	mov	pc, lr
 	.org	1b + 8
 	.endr
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/cache.h linux-libre-2.6.34.15-gnu1/arch/blackfin/include/asm/cache.h
--- linux-libre-2.6.34-gnu1/arch/blackfin/include/asm/cache.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/blackfin/include/asm/cache.h	2014-02-10 17:31:40.000000000 -0500
@@ -15,6 +15,8 @@
 #define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
 #define SMP_CACHE_BYTES	L1_CACHE_BYTES
 
+#define ARCH_KMALLOC_MINALIGN	L1_CACHE_BYTES
+
 #ifdef CONFIG_SMP
 #define __cacheline_aligned
 #else
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/stamp.c linux-libre-2.6.34.15-gnu1/arch/blackfin/mach-bf537/boards/stamp.c
--- linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf537/boards/stamp.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/blackfin/mach-bf537/boards/stamp.c	2014-02-10 17:31:40.000000000 -0500
@@ -400,6 +400,7 @@ static int bfin_plat_nand_dev_ready(stru
 
 static struct platform_nand_data bfin_plat_nand_data = {
 	.chip = {
+		.nr_chips = 1,
 		.chip_delay = 30,
 #ifdef CONFIG_MTD_PARTITIONS
 		.part_probe_types = part_probes,
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/boards/acvilon.c linux-libre-2.6.34.15-gnu1/arch/blackfin/mach-bf561/boards/acvilon.c
--- linux-libre-2.6.34-gnu1/arch/blackfin/mach-bf561/boards/acvilon.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/blackfin/mach-bf561/boards/acvilon.c	2014-02-10 17:31:40.000000000 -0500
@@ -283,6 +283,7 @@ static int bfin_plat_nand_dev_ready(stru
 
 static struct platform_nand_data bfin_plat_nand_data = {
 	.chip = {
+		 .nr_chips = 1,
 		 .chip_delay = 30,
 #ifdef CONFIG_MTD_PARTITIONS
 		 .part_probe_types = part_probes,
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/frv/include/asm/cache.h linux-libre-2.6.34.15-gnu1/arch/frv/include/asm/cache.h
--- linux-libre-2.6.34-gnu1/arch/frv/include/asm/cache.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/frv/include/asm/cache.h	2014-02-10 17:31:40.000000000 -0500
@@ -17,6 +17,8 @@
 #define L1_CACHE_SHIFT		(CONFIG_FRV_L1_CACHE_SHIFT)
 #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
+#define ARCH_KMALLOC_MINALIGN	L1_CACHE_BYTES
+
 #define __cacheline_aligned	__attribute__((aligned(L1_CACHE_BYTES)))
 #define ____cacheline_aligned	__attribute__((aligned(L1_CACHE_BYTES)))
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/ia64/hp/sim/simserial.c linux-libre-2.6.34.15-gnu1/arch/ia64/hp/sim/simserial.c
--- linux-libre-2.6.34-gnu1/arch/ia64/hp/sim/simserial.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/ia64/hp/sim/simserial.c	2014-02-10 17:31:40.000000000 -0500
@@ -395,7 +395,7 @@ static int rs_ioctl(struct tty_struct *t
 {
 	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
 	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
-	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+	    (cmd != TIOCMIWAIT)) {
 		if (tty->flags & (1 << TTY_IO_ERROR))
 		    return -EIO;
 	}
@@ -433,16 +433,6 @@ static int rs_ioctl(struct tty_struct *t
 		case TIOCMIWAIT:
 			printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n");
 			return 0;
-		/*
-		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
-		 * Return: write counters to the user passed counter struct
-		 * NB: both 1->0 and 0->1 transitions are counted except for
-		 *     RI where only 0->1 is counted.
-		 */
-		case TIOCGICOUNT:
-			printk(KERN_INFO "rs_ioctl: TIOCGICOUNT called\n");
-			return 0;
-
 		case TIOCSERGWILD:
 		case TIOCSERSWILD:
 			/* "setserial -W" is called in Debian boot */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/ia64/include/asm/compat.h linux-libre-2.6.34.15-gnu1/arch/ia64/include/asm/compat.h
--- linux-libre-2.6.34-gnu1/arch/ia64/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/ia64/include/asm/compat.h	2014-02-10 17:31:40.000000000 -0500
@@ -199,7 +199,7 @@ ptr_to_compat(void __user *uptr)
 }
 
 static __inline__ void __user *
-compat_alloc_user_space (long len)
+arch_compat_alloc_user_space (long len)
 {
 	struct pt_regs *regs = task_pt_regs(current);
 	return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/ia64/kernel/fsys.S linux-libre-2.6.34.15-gnu1/arch/ia64/kernel/fsys.S
--- linux-libre-2.6.34-gnu1/arch/ia64/kernel/fsys.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/ia64/kernel/fsys.S	2014-02-10 17:31:40.000000000 -0500
@@ -420,22 +420,31 @@ EX(.fail_efault, ld8 r14=[r33])			// r14
 	;;
 
 	RSM_PSR_I(p0, r18, r19)			// mask interrupt delivery
-	mov ar.ccv=0
 	andcm r14=r14,r17			// filter out SIGKILL & SIGSTOP
+	mov r8=EINVAL			// default to EINVAL
 
 #ifdef CONFIG_SMP
-	mov r17=1
+	// __ticket_spin_trylock(r31)
+	ld4 r17=[r31]
 	;;
-	cmpxchg4.acq r18=[r31],r17,ar.ccv	// try to acquire the lock
-	mov r8=EINVAL			// default to EINVAL
+	mov.m ar.ccv=r17
+	extr.u r9=r17,17,15
+	adds r19=1,r17
+	extr.u r18=r17,0,15
+	;;
+	cmp.eq p6,p7=r9,r18
+	;;
+(p6)	cmpxchg4.acq r9=[r31],r19,ar.ccv
+(p6)	dep.z r20=r19,1,15		// next serving ticket for unlock
+(p7)	br.cond.spnt.many .lock_contention
 	;;
+	cmp4.eq p0,p7=r9,r17
+	adds r31=2,r31
+(p7)	br.cond.spnt.many .lock_contention
 	ld8 r3=[r2]			// re-read current->blocked now that we hold the lock
-	cmp4.ne p6,p0=r18,r0
-(p6)	br.cond.spnt.many .lock_contention
 	;;
 #else
 	ld8 r3=[r2]			// re-read current->blocked now that we hold the lock
-	mov r8=EINVAL			// default to EINVAL
 #endif
 	add r18=IA64_TASK_PENDING_OFFSET+IA64_SIGPENDING_SIGNAL_OFFSET,r16
 	add r19=IA64_TASK_SIGNAL_OFFSET,r16
@@ -490,7 +499,9 @@ EX(.fail_efault, ld8 r14=[r33])			// r14
 (p6)	br.cond.spnt.few 1b			// yes -> retry
 
 #ifdef CONFIG_SMP
-	st4.rel [r31]=r0			// release the lock
+	// __ticket_spin_unlock(r31)
+	st2.rel [r31]=r20
+	mov r20=0					// i must not leak kernel bits...
 #endif
 	SSM_PSR_I(p0, p9, r31)
 	;;
@@ -512,7 +523,8 @@ EX(.fail_efault, (p15) st8 [r34]=r3)
 
 .sig_pending:
 #ifdef CONFIG_SMP
-	st4.rel [r31]=r0			// release the lock
+	// __ticket_spin_unlock(r31)
+	st2.rel [r31]=r20			// release the lock
 #endif
 	SSM_PSR_I(p0, p9, r17)
 	;;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/ia64/kernel/irq_ia64.c linux-libre-2.6.34.15-gnu1/arch/ia64/kernel/irq_ia64.c
--- linux-libre-2.6.34-gnu1/arch/ia64/kernel/irq_ia64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/ia64/kernel/irq_ia64.c	2014-02-10 17:31:40.000000000 -0500
@@ -23,7 +23,6 @@
 #include <linux/ioport.h>
 #include <linux/kernel_stat.h>
 #include <linux/ptrace.h>
-#include <linux/random.h>	/* for rand_initialize_irq() */
 #include <linux/signal.h>
 #include <linux/smp.h>
 #include <linux/threads.h>
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/ia64/kernel/mca.c linux-libre-2.6.34.15-gnu1/arch/ia64/kernel/mca.c
--- linux-libre-2.6.34-gnu1/arch/ia64/kernel/mca.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/ia64/kernel/mca.c	2014-02-10 17:31:40.000000000 -0500
@@ -1859,7 +1859,8 @@ ia64_mca_cpu_init(void *cpu_data)
 			data = mca_bootmem();
 			first_time = 0;
 		} else
-			data = __get_free_pages(GFP_KERNEL, get_order(sz));
+			data = (void *)__get_free_pages(GFP_KERNEL,
+							get_order(sz));
 		if (!data)
 			panic("Could not allocate MCA memory for cpu %d\n",
 					cpu);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/ia64/kernel/msi_ia64.c linux-libre-2.6.34.15-gnu1/arch/ia64/kernel/msi_ia64.c
--- linux-libre-2.6.34-gnu1/arch/ia64/kernel/msi_ia64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/ia64/kernel/msi_ia64.c	2014-02-10 17:31:40.000000000 -0500
@@ -25,7 +25,7 @@ static int ia64_set_msi_irq_affinity(uns
 	if (irq_prepare_move(irq, cpu))
 		return -1;
 
-	read_msi_msg(irq, &msg);
+	get_cached_msi_msg(irq, &msg);
 
 	addr = msg.address_lo;
 	addr &= MSI_ADDR_DEST_ID_MASK;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/ia64/kvm/kvm-ia64.c linux-libre-2.6.34.15-gnu1/arch/ia64/kvm/kvm-ia64.c
--- linux-libre-2.6.34-gnu1/arch/ia64/kvm/kvm-ia64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/ia64/kvm/kvm-ia64.c	2014-02-10 17:31:40.000000000 -0500
@@ -1179,6 +1179,11 @@ out:
 
 #define PALE_RESET_ENTRY    0x80000000ffffffb0UL
 
+bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu)
+{
+	return irqchip_in_kernel(vcpu->kcm) == (vcpu->arch.apic != NULL);
+}
+
 int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 {
 	struct kvm_vcpu *v;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/ia64/mm/tlb.c linux-libre-2.6.34.15-gnu1/arch/ia64/mm/tlb.c
--- linux-libre-2.6.34-gnu1/arch/ia64/mm/tlb.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/ia64/mm/tlb.c	2014-02-10 17:31:40.000000000 -0500
@@ -121,7 +121,7 @@ static inline void down_spin(struct spin
 	ia64_invala();
 
 	for (;;) {
-		asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory");
+		asm volatile ("ld8.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory");
 		if (time_before(t, serve))
 			return;
 		cpu_relax();
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/msi_sn.c linux-libre-2.6.34.15-gnu1/arch/ia64/sn/kernel/msi_sn.c
--- linux-libre-2.6.34-gnu1/arch/ia64/sn/kernel/msi_sn.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/ia64/sn/kernel/msi_sn.c	2014-02-10 17:31:40.000000000 -0500
@@ -175,7 +175,7 @@ static int sn_set_msi_irq_affinity(unsig
 	 * Release XIO resources for the old MSI PCI address
 	 */
 
-	read_msi_msg(irq, &msg);
+	get_cached_msi_msg(irq, &msg);
         sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
 	pdev = sn_pdev->pdi_linux_pcidev;
 	provider = SN_PCIDEV_BUSPROVIDER(pdev);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/ia64/sn/pci/tioca_provider.c linux-libre-2.6.34.15-gnu1/arch/ia64/sn/pci/tioca_provider.c
--- linux-libre-2.6.34-gnu1/arch/ia64/sn/pci/tioca_provider.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/ia64/sn/pci/tioca_provider.c	2014-02-10 17:31:40.000000000 -0500
@@ -509,7 +509,7 @@ tioca_dma_unmap(struct pci_dev *pdev, dm
  * use the GART mapped mode.
  */
 static u64
-tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags)
+tioca_dma_map(struct pci_dev *pdev, unsigned long paddr, size_t byte_count, int dma_flags)
 {
 	u64 mapaddr;
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/m68k/include/asm/cache.h linux-libre-2.6.34.15-gnu1/arch/m68k/include/asm/cache.h
--- linux-libre-2.6.34-gnu1/arch/m68k/include/asm/cache.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/m68k/include/asm/cache.h	2014-02-10 17:31:40.000000000 -0500
@@ -8,4 +8,6 @@
 #define        L1_CACHE_SHIFT  4
 #define        L1_CACHE_BYTES  (1<< L1_CACHE_SHIFT)
 
+#define ARCH_KMALLOC_MINALIGN	L1_CACHE_BYTES
+
 #endif
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/m68k/mm/motorola.c linux-libre-2.6.34.15-gnu1/arch/m68k/mm/motorola.c
--- linux-libre-2.6.34-gnu1/arch/m68k/mm/motorola.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/m68k/mm/motorola.c	2014-02-10 17:31:40.000000000 -0500
@@ -300,6 +300,8 @@ void __init paging_init(void)
 		zones_size[ZONE_DMA] = m68k_memory[i].size >> PAGE_SHIFT;
 		free_area_init_node(i, zones_size,
 				    m68k_memory[i].addr >> PAGE_SHIFT, NULL);
+		if (node_present_pages(i))
+			node_set_state(i, N_NORMAL_MEMORY);
 	}
 }
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/microblaze/Makefile linux-libre-2.6.34.15-gnu1/arch/microblaze/Makefile
--- linux-libre-2.6.34-gnu1/arch/microblaze/Makefile	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/microblaze/Makefile	2014-02-10 17:31:40.000000000 -0500
@@ -72,12 +72,16 @@ export MMU DTB
 
 all: linux.bin
 
-BOOT_TARGETS = linux.bin linux.bin.gz simpleImage.%
+# With make 3.82 we cannot mix normal and wildcard targets
+BOOT_TARGETS1 = linux.bin linux.bin.gz
+BOOT_TARGETS2 = simpleImage.%
 
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
 
-$(BOOT_TARGETS): vmlinux
+$(BOOT_TARGETS1): vmlinux
+	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+$(BOOT_TARGETS2): vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 define archhelp
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/mips/alchemy/mtx-1/board_setup.c linux-libre-2.6.34.15-gnu1/arch/mips/alchemy/mtx-1/board_setup.c
--- linux-libre-2.6.34-gnu1/arch/mips/alchemy/mtx-1/board_setup.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/mips/alchemy/mtx-1/board_setup.c	2014-02-10 17:31:40.000000000 -0500
@@ -67,8 +67,6 @@ static void mtx1_power_off(void)
 
 void __init board_setup(void)
 {
-	alchemy_gpio2_enable();
-
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 	/* Enable USB power switch */
 	alchemy_gpio_direction_output(204, 0);
@@ -117,11 +115,11 @@ mtx1_pci_idsel(unsigned int devsel, int
 
 	if (assert && devsel != 0)
 		/* Suppress signal to Cardbus */
-		gpio_set_value(1, 0);	/* set EXT_IO3 OFF */
+		alchemy_gpio_set_value(1, 0);	/* set EXT_IO3 OFF */
 	else
-		gpio_set_value(1, 1);	/* set EXT_IO3 ON */
+		alchemy_gpio_set_value(1, 1);	/* set EXT_IO3 ON */
 
-	au_sync_udelay(1);
+	udelay(1);
 	return 1;
 }
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/mips/alchemy/mtx-1/platform.c linux-libre-2.6.34.15-gnu1/arch/mips/alchemy/mtx-1/platform.c
--- linux-libre-2.6.34-gnu1/arch/mips/alchemy/mtx-1/platform.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/mips/alchemy/mtx-1/platform.c	2014-02-10 17:31:40.000000000 -0500
@@ -28,6 +28,8 @@
 #include <linux/mtd/physmap.h>
 #include <mtd/mtd-abi.h>
 
+#include <asm/mach-au1x00/au1xxx_eth.h>
+
 static struct gpio_keys_button mtx1_gpio_button[] = {
 	{
 		.gpio = 207,
@@ -140,10 +142,17 @@ static struct __initdata platform_device
 	&mtx1_mtd,
 };
 
+static struct au1000_eth_platform_data mtx1_au1000_eth0_pdata = {
+	.phy_search_highest_addr	= 1,
+	.phy1_search_mac0 		= 1,
+};
+
 static int __init mtx1_register_devices(void)
 {
 	int rc;
 
+	au1xxx_override_eth_cfg(0, &mtx1_au1000_eth0_pdata);
+
 	rc = gpio_request(mtx1_gpio_button[0].gpio,
 					mtx1_gpio_button[0].desc);
 	if (rc < 0) {
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/mips/include/asm/atomic.h linux-libre-2.6.34.15-gnu1/arch/mips/include/asm/atomic.h
--- linux-libre-2.6.34-gnu1/arch/mips/include/asm/atomic.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/mips/include/asm/atomic.h	2014-02-10 17:31:40.000000000 -0500
@@ -434,7 +434,7 @@ static __inline__ void atomic64_add(long
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"1:	lld	%0, %1		# atomic64_add		\n"
-		"	addu	%0, %2					\n"
+		"	daddu	%0, %2					\n"
 		"	scd	%0, %1					\n"
 		"	beqzl	%0, 1b					\n"
 		"	.set	mips0					\n"
@@ -446,7 +446,7 @@ static __inline__ void atomic64_add(long
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"1:	lld	%0, %1		# atomic64_add		\n"
-		"	addu	%0, %2					\n"
+		"	daddu	%0, %2					\n"
 		"	scd	%0, %1					\n"
 		"	beqz	%0, 2f					\n"
 		"	.subsection 2					\n"
@@ -479,7 +479,7 @@ static __inline__ void atomic64_sub(long
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"1:	lld	%0, %1		# atomic64_sub		\n"
-		"	subu	%0, %2					\n"
+		"	dsubu	%0, %2					\n"
 		"	scd	%0, %1					\n"
 		"	beqzl	%0, 1b					\n"
 		"	.set	mips0					\n"
@@ -491,7 +491,7 @@ static __inline__ void atomic64_sub(long
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"1:	lld	%0, %1		# atomic64_sub		\n"
-		"	subu	%0, %2					\n"
+		"	dsubu	%0, %2					\n"
 		"	scd	%0, %1					\n"
 		"	beqz	%0, 2f					\n"
 		"	.subsection 2					\n"
@@ -524,10 +524,10 @@ static __inline__ long atomic64_add_retu
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"1:	lld	%1, %2		# atomic64_add_return	\n"
-		"	addu	%0, %1, %3				\n"
+		"	daddu	%0, %1, %3				\n"
 		"	scd	%0, %2					\n"
 		"	beqzl	%0, 1b					\n"
-		"	addu	%0, %1, %3				\n"
+		"	daddu	%0, %1, %3				\n"
 		"	.set	mips0					\n"
 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter)
@@ -538,10 +538,10 @@ static __inline__ long atomic64_add_retu
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"1:	lld	%1, %2		# atomic64_add_return	\n"
-		"	addu	%0, %1, %3				\n"
+		"	daddu	%0, %1, %3				\n"
 		"	scd	%0, %2					\n"
 		"	beqz	%0, 2f					\n"
-		"	addu	%0, %1, %3				\n"
+		"	daddu	%0, %1, %3				\n"
 		"	.subsection 2					\n"
 		"2:	b	1b					\n"
 		"	.previous					\n"
@@ -576,10 +576,10 @@ static __inline__ long atomic64_sub_retu
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"1:	lld	%1, %2		# atomic64_sub_return	\n"
-		"	subu	%0, %1, %3				\n"
+		"	dsubu	%0, %1, %3				\n"
 		"	scd	%0, %2					\n"
 		"	beqzl	%0, 1b					\n"
-		"	subu	%0, %1, %3				\n"
+		"	dsubu	%0, %1, %3				\n"
 		"	.set	mips0					\n"
 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter)
@@ -590,10 +590,10 @@ static __inline__ long atomic64_sub_retu
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"1:	lld	%1, %2		# atomic64_sub_return	\n"
-		"	subu	%0, %1, %3				\n"
+		"	dsubu	%0, %1, %3				\n"
 		"	scd	%0, %2					\n"
 		"	beqz	%0, 2f					\n"
-		"	subu	%0, %1, %3				\n"
+		"	dsubu	%0, %1, %3				\n"
 		"	.subsection 2					\n"
 		"2:	b	1b					\n"
 		"	.previous					\n"
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/mips/include/asm/compat.h linux-libre-2.6.34.15-gnu1/arch/mips/include/asm/compat.h
--- linux-libre-2.6.34-gnu1/arch/mips/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/mips/include/asm/compat.h	2014-02-10 17:31:40.000000000 -0500
@@ -145,7 +145,7 @@ static inline compat_uptr_t ptr_to_compa
 	return (u32)(unsigned long)uptr;
 }
 
-static inline void __user *compat_alloc_user_space(long len)
+static inline void __user *arch_compat_alloc_user_space(long len)
 {
 	struct pt_regs *regs = (struct pt_regs *)
 		((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/mips/kernel/ptrace.c linux-libre-2.6.34.15-gnu1/arch/mips/kernel/ptrace.c
--- linux-libre-2.6.34-gnu1/arch/mips/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/mips/kernel/ptrace.c	2014-02-10 17:31:40.000000000 -0500
@@ -536,7 +536,7 @@ asmlinkage void do_syscall_trace(struct
 {
 	/* do the secure computing check first */
 	if (!entryexit)
-		secure_computing(regs->regs[0]);
+		secure_computing(regs->regs[2]);
 
 	if (unlikely(current->audit_context) && entryexit)
 		audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]),
@@ -565,7 +565,7 @@ asmlinkage void do_syscall_trace(struct
 
 out:
 	if (unlikely(current->audit_context) && !entryexit)
-		audit_syscall_entry(audit_arch(), regs->regs[0],
+		audit_syscall_entry(audit_arch(), regs->regs[2],
 				    regs->regs[4], regs->regs[5],
 				    regs->regs[6], regs->regs[7]);
 }
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/mips/mti-malta/malta-pci.c linux-libre-2.6.34.15-gnu1/arch/mips/mti-malta/malta-pci.c
--- linux-libre-2.6.34-gnu1/arch/mips/mti-malta/malta-pci.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/mips/mti-malta/malta-pci.c	2014-02-10 17:31:40.000000000 -0500
@@ -247,6 +247,8 @@ void __init mips_pcibios_init(void)
 	iomem_resource.end &= 0xfffffffffULL;			/* 64 GB */
 	ioport_resource.end = controller->io_resource->end;
 
+	controller->io_map_base = mips_io_port_base;
+
 	register_pci_controller(controller);
 }
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx8550/common/pci.c linux-libre-2.6.34.15-gnu1/arch/mips/nxp/pnx8550/common/pci.c
--- linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx8550/common/pci.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/mips/nxp/pnx8550/common/pci.c	2014-02-10 17:31:40.000000000 -0500
@@ -44,6 +44,7 @@ extern struct pci_ops pnx8550_pci_ops;
 
 static struct pci_controller pnx8550_controller = {
 	.pci_ops	= &pnx8550_pci_ops,
+	.io_map_base	= PNX8550_PORT_BASE,
 	.io_resource	= &pci_io_resource,
 	.mem_resource	= &pci_mem_resource,
 };
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx8550/common/setup.c linux-libre-2.6.34.15-gnu1/arch/mips/nxp/pnx8550/common/setup.c
--- linux-libre-2.6.34-gnu1/arch/mips/nxp/pnx8550/common/setup.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/mips/nxp/pnx8550/common/setup.c	2014-02-10 17:31:40.000000000 -0500
@@ -113,7 +113,7 @@ void __init plat_mem_setup(void)
 	PNX8550_GLB2_ENAB_INTA_O = 0;
 
 	/* IO/MEM resources. */
-	set_io_port_base(KSEG1);
+	set_io_port_base(PNX8550_PORT_BASE);
 	ioport_resource.start = 0;
 	ioport_resource.end = ~0;
 	iomem_resource.start = 0;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/mips/pci/ops-pmcmsp.c linux-libre-2.6.34.15-gnu1/arch/mips/pci/ops-pmcmsp.c
--- linux-libre-2.6.34-gnu1/arch/mips/pci/ops-pmcmsp.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/mips/pci/ops-pmcmsp.c	2014-02-10 17:31:40.000000000 -0500
@@ -944,6 +944,7 @@ static struct pci_controller msp_pci_con
 	.pci_ops	= &msp_pci_ops,
 	.mem_resource	= &pci_mem_resource,
 	.mem_offset	= 0,
+	.io_map_base	= MSP_PCI_IOSPACE_BASE,
 	.io_resource	= &pci_io_resource,
 	.io_offset	= 0
 };
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/mips/pci/pci-yosemite.c linux-libre-2.6.34.15-gnu1/arch/mips/pci/pci-yosemite.c
--- linux-libre-2.6.34-gnu1/arch/mips/pci/pci-yosemite.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/mips/pci/pci-yosemite.c	2014-02-10 17:31:40.000000000 -0500
@@ -54,6 +54,7 @@ static int __init pmc_yosemite_setup(voi
 		panic(ioremap_failed);
 
 	set_io_port_base(io_v_base);
+	py_controller.io_map_base = io_v_base;
 	TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1);
 
 	ioport_resource.end = TITAN_IO_SIZE - 1;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/mn10300/include/asm/cache.h linux-libre-2.6.34.15-gnu1/arch/mn10300/include/asm/cache.h
--- linux-libre-2.6.34-gnu1/arch/mn10300/include/asm/cache.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/mn10300/include/asm/cache.h	2014-02-10 17:31:40.000000000 -0500
@@ -21,6 +21,8 @@
 #define L1_CACHE_DISPARITY	L1_CACHE_NENTRIES * L1_CACHE_BYTES
 #endif
 
+#define ARCH_KMALLOC_MINALIGN	L1_CACHE_BYTES
+
 /* data cache purge registers
  * - read from the register to unconditionally purge that cache line
  * - write address & 0xffffff00 to conditionally purge that cache line
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/parisc/include/asm/compat.h linux-libre-2.6.34.15-gnu1/arch/parisc/include/asm/compat.h
--- linux-libre-2.6.34-gnu1/arch/parisc/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/parisc/include/asm/compat.h	2014-02-10 17:31:40.000000000 -0500
@@ -147,7 +147,7 @@ static inline compat_uptr_t ptr_to_compa
 	return (u32)(unsigned long)uptr;
 }
 
-static __inline__ void __user *compat_alloc_user_space(long len)
+static __inline__ void __user *arch_compat_alloc_user_space(long len)
 {
 	struct pt_regs *regs = &current->thread.regs;
 	return (void __user *)regs->gr[30];
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/parisc/kernel/firmware.c linux-libre-2.6.34.15-gnu1/arch/parisc/kernel/firmware.c
--- linux-libre-2.6.34-gnu1/arch/parisc/kernel/firmware.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/parisc/kernel/firmware.c	2014-02-10 17:31:40.000000000 -0500
@@ -1123,42 +1123,23 @@ static char __attribute__((aligned(64)))
  */
 int pdc_iodc_print(const unsigned char *str, unsigned count)
 {
-	static int posx;        /* for simple TAB-Simulation... */
 	unsigned int i;
 	unsigned long flags;
 
-	for (i = 0; i < count && i < 79;) {
+	for (i = 0; i < count;) {
 		switch(str[i]) {
 		case '\n':
 			iodc_dbuf[i+0] = '\r';
 			iodc_dbuf[i+1] = '\n';
 			i += 2;
-			posx = 0;
 			goto print;
-		case '\t':
-			while (posx & 7) {
-				iodc_dbuf[i] = ' ';
-				i++, posx++;
-			}
-			break;
-		case '\b':	/* BS */
-			posx -= 2;
 		default:
 			iodc_dbuf[i] = str[i];
-			i++, posx++;
+			i++;
 			break;
 		}
 	}
 
-	/* if we're at the end of line, and not already inserting a newline,
-	 * insert one anyway. iodc console doesn't claim to support >79 char
-	 * lines. don't account for this in the return value.
-	 */
-	if (i == 79 && iodc_dbuf[i-1] != '\n') {
-		iodc_dbuf[i+0] = '\r';
-		iodc_dbuf[i+1] = '\n';
-	}
-
 print:
         spin_lock_irqsave(&pdc_lock, flags);
         real32_call(PAGE0->mem_cons.iodc_io,
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/parisc/kernel/irq.c linux-libre-2.6.34.15-gnu1/arch/parisc/kernel/irq.c
--- linux-libre-2.6.34-gnu1/arch/parisc/kernel/irq.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/parisc/kernel/irq.c	2014-02-10 17:31:40.000000000 -0500
@@ -117,7 +117,7 @@ int cpu_check_affinity(unsigned int irq,
 	int cpu_dest;
 
 	/* timer and ipi have to always be received on all CPUs */
-	if (CHECK_IRQ_PER_CPU(irq)) {
+	if (CHECK_IRQ_PER_CPU(irq_to_desc(irq)->status)) {
 		/* Bad linux design decision.  The mask has already
 		 * been set; we must reset it */
 		cpumask_setall(irq_desc[irq].affinity);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/parisc/math-emu/decode_exc.c linux-libre-2.6.34.15-gnu1/arch/parisc/math-emu/decode_exc.c
--- linux-libre-2.6.34-gnu1/arch/parisc/math-emu/decode_exc.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/parisc/math-emu/decode_exc.c	2014-02-10 17:31:40.000000000 -0500
@@ -342,6 +342,7 @@ decode_fpu(unsigned int Fpu_register[],
 		return SIGNALCODE(SIGFPE, FPE_FLTINV);
 	  case DIVISIONBYZEROEXCEPTION:
 		update_trap_counts(Fpu_register, aflags, bflags, trap_counts);
+		Clear_excp_register(exception_index);
 	  	return SIGNALCODE(SIGFPE, FPE_FLTDIV);
 	  case INEXACTEXCEPTION:
 		update_trap_counts(Fpu_register, aflags, bflags, trap_counts);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/parisc/mm/init.c linux-libre-2.6.34.15-gnu1/arch/parisc/mm/init.c
--- linux-libre-2.6.34-gnu1/arch/parisc/mm/init.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/parisc/mm/init.c	2014-02-10 17:31:40.000000000 -0500
@@ -266,8 +266,10 @@ static void __init setup_bootmem(void)
 	}
 	memset(pfnnid_map, 0xff, sizeof(pfnnid_map));
 
-	for (i = 0; i < npmem_ranges; i++)
+	for (i = 0; i < npmem_ranges; i++) {
+		node_set_state(i, N_NORMAL_MEMORY);
 		node_set_online(i);
+	}
 #endif
 
 	/*
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/boot/Makefile linux-libre-2.6.34.15-gnu1/arch/powerpc/boot/Makefile
--- linux-libre-2.6.34-gnu1/arch/powerpc/boot/Makefile	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/boot/Makefile	2014-02-10 17:31:40.000000000 -0500
@@ -367,7 +367,7 @@ INSTALL := install
 extra-installed		:= $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(extra-y))
 hostprogs-installed	:= $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(hostprogs-y))
 wrapper-installed	:= $(DESTDIR)$(WRAPPER_BINDIR)/wrapper
-dts-installed		:= $(patsubst $(obj)/dts/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(obj)/dts/*.dts))
+dts-installed		:= $(patsubst $(dtstree)/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(dtstree)/*.dts))
 
 all-installed		:= $(extra-installed) $(hostprogs-installed) $(wrapper-installed) $(dts-installed)
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/compat.h linux-libre-2.6.34.15-gnu1/arch/powerpc/include/asm/compat.h
--- linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/include/asm/compat.h	2014-02-10 17:31:40.000000000 -0500
@@ -134,7 +134,7 @@ static inline compat_uptr_t ptr_to_compa
 	return (u32)(unsigned long)uptr;
 }
 
-static inline void __user *compat_alloc_user_space(long len)
+static inline void __user *arch_compat_alloc_user_space(long len)
 {
 	struct pt_regs *regs = current->thread.regs;
 	unsigned long usp = regs->gpr[1];
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/cpm.h linux-libre-2.6.34.15-gnu1/arch/powerpc/include/asm/cpm.h
--- linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/cpm.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/include/asm/cpm.h	2014-02-10 17:31:40.000000000 -0500
@@ -7,6 +7,30 @@
 #include <linux/of.h>
 
 /*
+ * SPI Parameter RAM common to QE and CPM.
+ */
+struct spi_pram {
+	__be16	rbase;	/* Rx Buffer descriptor base address */
+	__be16	tbase;	/* Tx Buffer descriptor base address */
+	u8	rfcr;	/* Rx function code */
+	u8	tfcr;	/* Tx function code */
+	__be16	mrblr;	/* Max receive buffer length */
+	__be32	rstate;	/* Internal */
+	__be32	rdp;	/* Internal */
+	__be16	rbptr;	/* Internal */
+	__be16	rbc;	/* Internal */
+	__be32	rxtmp;	/* Internal */
+	__be32	tstate;	/* Internal */
+	__be32	tdp;	/* Internal */
+	__be16	tbptr;	/* Internal */
+	__be16	tbc;	/* Internal */
+	__be32	txtmp;	/* Internal */
+	__be32	res;	/* Tx temp. */
+	__be16  rpbase;	/* Relocation pointer (CPM1 only) */
+	__be16	res1;	/* Reserved */
+};
+
+/*
  * USB Controller pram common to QE and CPM.
  */
 struct usb_ctlr {
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/hvcall.h linux-libre-2.6.34.15-gnu1/arch/powerpc/include/asm/hvcall.h
--- linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/hvcall.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/include/asm/hvcall.h	2014-02-10 17:31:40.000000000 -0500
@@ -281,6 +281,7 @@ long plpar_hcall_raw(unsigned long opcod
  */
 #define PLPAR_HCALL9_BUFSIZE 9
 long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...);
+long plpar_hcall9_raw(unsigned long opcode, unsigned long *retbuf, ...);
 
 /* For hcall instrumentation.  One structure per-hcall, per-CPU */
 struct hcall_stats {
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kexec.h linux-libre-2.6.34.15-gnu1/arch/powerpc/include/asm/kexec.h
--- linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/kexec.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/include/asm/kexec.h	2014-02-10 17:31:40.000000000 -0500
@@ -31,6 +31,10 @@
 #define KEXEC_ARCH KEXEC_ARCH_PPC
 #endif
 
+#define KEXEC_STATE_NONE 0
+#define KEXEC_STATE_IRQS_OFF 1
+#define KEXEC_STATE_REAL_MODE 2
+
 #ifndef __ASSEMBLY__
 #include <linux/cpumask.h>
 #include <asm/reg.h>
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/paca.h linux-libre-2.6.34.15-gnu1/arch/powerpc/include/asm/paca.h
--- linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/paca.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/include/asm/paca.h	2014-02-10 17:31:40.000000000 -0500
@@ -82,6 +82,7 @@ struct paca_struct {
 	s16 hw_cpu_id;			/* Physical processor number */
 	u8 cpu_start;			/* At startup, processor spins until */
 					/* this becomes non-zero. */
+	u8 kexec_state;		/* set when kexec down has irqs off */
 #ifdef CONFIG_PPC_STD_MMU_64
 	struct slb_shadow *slb_shadow_ptr;
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/reg.h linux-libre-2.6.34.15-gnu1/arch/powerpc/include/asm/reg.h
--- linux-libre-2.6.34-gnu1/arch/powerpc/include/asm/reg.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/include/asm/reg.h	2014-02-10 17:31:40.000000000 -0500
@@ -864,6 +864,7 @@
 #define PV_970		0x0039
 #define PV_POWER5	0x003A
 #define PV_POWER5p	0x003B
+#define PV_POWER7	0x003F
 #define PV_970FX	0x003C
 #define PV_630		0x0040
 #define PV_630p	0x0041
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/asm-offsets.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/asm-offsets.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/asm-offsets.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/asm-offsets.c	2014-02-10 17:31:40.000000000 -0500
@@ -183,6 +183,7 @@ int main(void)
 #endif /* CONFIG_PPC_STD_MMU_64 */
 	DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
 	DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
+	DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
 	DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
 	DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
 	DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
@@ -447,6 +448,14 @@ int main(void)
 	DEFINE(PGD_T_LOG2, PGD_T_LOG2);
 	DEFINE(PTE_T_LOG2, PTE_T_LOG2);
 #endif
+#ifdef CONFIG_FSL_BOOKE
+	DEFINE(TLBCAM_SIZE, sizeof(struct tlbcam));
+	DEFINE(TLBCAM_MAS0, offsetof(struct tlbcam, MAS0));
+	DEFINE(TLBCAM_MAS1, offsetof(struct tlbcam, MAS1));
+	DEFINE(TLBCAM_MAS2, offsetof(struct tlbcam, MAS2));
+	DEFINE(TLBCAM_MAS3, offsetof(struct tlbcam, MAS3));
+	DEFINE(TLBCAM_MAS7, offsetof(struct tlbcam, MAS7));
+#endif
 
 #ifdef CONFIG_KVM_EXIT_TIMING
 	DEFINE(VCPU_TIMING_EXIT_TBU, offsetof(struct kvm_vcpu,
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/cpu_setup_6xx.S linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/cpu_setup_6xx.S
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/cpu_setup_6xx.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/cpu_setup_6xx.S	2014-02-10 17:31:40.000000000 -0500
@@ -18,7 +18,7 @@
 #include <asm/mmu.h>
 
 _GLOBAL(__setup_cpu_603)
-	mflr	r4
+	mflr	r5
 BEGIN_MMU_FTR_SECTION
 	li	r10,0
 	mtspr	SPRN_SPRG_603_LRU,r10		/* init SW LRU tracking */
@@ -27,60 +27,60 @@ BEGIN_FTR_SECTION
 	bl	__init_fpu_registers
 END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE)
 	bl	setup_common_caches
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_604)
-	mflr	r4
+	mflr	r5
 	bl	setup_common_caches
 	bl	setup_604_hid0
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_750)
-	mflr	r4
+	mflr	r5
 	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_750cx)
-	mflr	r4
+	mflr	r5
 	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	bl	setup_750cx
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_750fx)
-	mflr	r4
+	mflr	r5
 	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	bl	setup_750fx
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_7400)
-	mflr	r4
+	mflr	r5
 	bl	__init_fpu_registers
 	bl	setup_7400_workarounds
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_7410)
-	mflr	r4
+	mflr	r5
 	bl	__init_fpu_registers
 	bl	setup_7410_workarounds
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	li	r3,0
 	mtspr	SPRN_L2CR2,r3
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_745x)
-	mflr	r4
+	mflr	r5
 	bl	setup_common_caches
 	bl	setup_745x_specifics
-	mtlr	r4
+	mtlr	r5
 	blr
 
 /* Enable caches for 603's, 604, 750 & 7400 */
@@ -194,10 +194,10 @@ setup_750cx:
 	cror	4*cr0+eq,4*cr0+eq,4*cr1+eq
 	cror	4*cr0+eq,4*cr0+eq,4*cr2+eq
 	bnelr
-	lwz	r6,CPU_SPEC_FEATURES(r5)
+	lwz	r6,CPU_SPEC_FEATURES(r4)
 	li	r7,CPU_FTR_CAN_NAP
 	andc	r6,r6,r7
-	stw	r6,CPU_SPEC_FEATURES(r5)
+	stw	r6,CPU_SPEC_FEATURES(r4)
 	blr
 
 /* 750fx specific
@@ -225,12 +225,12 @@ BEGIN_FTR_SECTION
 	andis.	r11,r11,L3CR_L3E@h
 	beq	1f
 END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
-	lwz	r6,CPU_SPEC_FEATURES(r5)
+	lwz	r6,CPU_SPEC_FEATURES(r4)
 	andi.	r0,r6,CPU_FTR_L3_DISABLE_NAP
 	beq	1f
 	li	r7,CPU_FTR_CAN_NAP
 	andc	r6,r6,r7
-	stw	r6,CPU_SPEC_FEATURES(r5)
+	stw	r6,CPU_SPEC_FEATURES(r4)
 1:
 	mfspr	r11,SPRN_HID0
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/crash.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/crash.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/crash.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/crash.c	2014-02-10 17:31:40.000000000 -0500
@@ -162,6 +162,30 @@ static void crash_kexec_prepare_cpus(int
 	/* Leave the IPI callback set */
 }
 
+/* wait for all the CPUs to hit real mode but timeout if they don't come in */
+#if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP)
+static void crash_kexec_wait_realmode(int cpu)
+{
+	unsigned int msecs;
+	int i;
+
+	msecs = 10000;
+	for (i=0; i < NR_CPUS && msecs > 0; i++) {
+		if (i == cpu)
+			continue;
+
+		while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) {
+			barrier();
+			if (!cpu_possible(i) || !cpu_online(i) || (msecs <= 0))
+				break;
+			msecs--;
+			mdelay(1);
+		}
+	}
+	mb();
+}
+#endif
+
 /*
  * This function will be called by secondary cpus or by kexec cpu
  * if soft-reset is activated to stop some CPUs.
@@ -347,10 +371,12 @@ int crash_shutdown_unregister(crash_shut
 EXPORT_SYMBOL(crash_shutdown_unregister);
 
 static unsigned long crash_shutdown_buf[JMP_BUF_LEN];
+static int crash_shutdown_cpu = -1;
 
 static int handle_fault(struct pt_regs *regs)
 {
-	longjmp(crash_shutdown_buf, 1);
+	if (crash_shutdown_cpu == smp_processor_id())
+		longjmp(crash_shutdown_buf, 1);
 	return 0;
 }
 
@@ -375,11 +401,14 @@ void default_machine_crash_shutdown(stru
 	for_each_irq(i) {
 		struct irq_desc *desc = irq_to_desc(i);
 
+		if (!desc || !desc->chip || !desc->chip->eoi)
+			continue;
+
 		if (desc->status & IRQ_INPROGRESS)
 			desc->chip->eoi(i);
 
 		if (!(desc->status & IRQ_DISABLED))
-			desc->chip->disable(i);
+			desc->chip->shutdown(i);
 	}
 
 	/*
@@ -388,6 +417,7 @@ void default_machine_crash_shutdown(stru
 	 */
 	old_handler = __debugger_fault_handler;
 	__debugger_fault_handler = handle_fault;
+	crash_shutdown_cpu = smp_processor_id();
 	for (i = 0; crash_shutdown_handles[i]; i++) {
 		if (setjmp(crash_shutdown_buf) == 0) {
 			/*
@@ -401,6 +431,7 @@ void default_machine_crash_shutdown(stru
 			asm volatile("sync; isync");
 		}
 	}
+	crash_shutdown_cpu = -1;
 	__debugger_fault_handler = old_handler;
 
 	/*
@@ -412,6 +443,9 @@ void default_machine_crash_shutdown(stru
 	crash_kexec_prepare_cpus(crashing_cpu);
 	cpu_set(crashing_cpu, cpus_in_crash);
 	crash_kexec_stop_spus();
+#if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP)
+	crash_kexec_wait_realmode(crashing_cpu);
+#endif
 	if (ppc_md.kexec_cpu_down)
 		ppc_md.kexec_cpu_down(1, 0);
 }
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/head_64.S linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/head_64.S
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/head_64.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/head_64.S	2014-02-10 17:31:40.000000000 -0500
@@ -572,15 +572,21 @@ __secondary_start:
 	/* Set thread priority to MEDIUM */
 	HMT_MEDIUM
 
-	/* Do early setup for that CPU (stab, slb, hash table pointer) */
-	bl	.early_setup_secondary
-
 	/* Initialize the kernel stack.  Just a repeat for iSeries.	 */
 	LOAD_REG_ADDR(r3, current_set)
 	sldi	r28,r24,3		/* get current_set[cpu#]	 */
-	ldx	r1,r3,r28
-	addi	r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
-	std	r1,PACAKSAVE(r13)
+	ldx	r14,r3,r28
+	addi	r14,r14,THREAD_SIZE-STACK_FRAME_OVERHEAD
+	std	r14,PACAKSAVE(r13)
+
+	/* Do early setup for that CPU (stab, slb, hash table pointer) */
+	bl	.early_setup_secondary
+
+	/*
+	 * setup the new stack pointer, but *don't* use this until
+	 * translation is on.
+	 */
+	mr	r1, r14
 
 	/* Clear backchain so we get nice backtraces */
 	li	r7,0
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/head_fsl_booke.S linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/head_fsl_booke.S
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/head_fsl_booke.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/head_fsl_booke.S	2014-02-10 17:31:40.000000000 -0500
@@ -639,6 +639,13 @@ interrupt_base:
 	rlwinm	r12,r12,0,16,1
 	mtspr	SPRN_MAS1,r12
 
+	/* Make up the required permissions for kernel code */
+#ifdef CONFIG_PTE_64BIT
+	li	r13,_PAGE_PRESENT | _PAGE_BAP_SX
+	oris	r13,r13,_PAGE_ACCESSED@h
+#else
+	li	r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
+#endif
 	b	4f
 
 	/* Get the PGD for the current thread */
@@ -646,15 +653,15 @@ interrupt_base:
 	mfspr	r11,SPRN_SPRG_THREAD
 	lwz	r11,PGDIR(r11)
 
-4:
-	/* Make up the required permissions */
+	/* Make up the required permissions for user code */
 #ifdef CONFIG_PTE_64BIT
-	li	r13,_PAGE_PRESENT | _PAGE_EXEC
+	li	r13,_PAGE_PRESENT | _PAGE_BAP_UX
 	oris	r13,r13,_PAGE_ACCESSED@h
 #else
 	li	r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
 #endif
 
+4:
 	FIND_PTE
 	andc.	r13,r13,r11		/* Check permission */
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/irq.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/irq.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/irq.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/irq.c	2014-02-10 17:31:40.000000000 -0500
@@ -294,7 +294,10 @@ void fixup_irqs(cpumask_t map)
 		cpumask_t mask;
 
 		desc = irq_to_desc(irq);
-		if (desc && desc->status & IRQ_PER_CPU)
+		if (!desc)
+			continue;
+
+		if (desc->status & IRQ_PER_CPU)
 			continue;
 
 		cpumask_and(&mask, desc->affinity, &map);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/machine_kexec_64.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/machine_kexec_64.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/machine_kexec_64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/machine_kexec_64.c	2014-02-10 17:31:40.000000000 -0500
@@ -15,6 +15,7 @@
 #include <linux/thread_info.h>
 #include <linux/init_task.h>
 #include <linux/errno.h>
+#include <linux/cpu.h>
 
 #include <asm/page.h>
 #include <asm/current.h>
@@ -155,33 +156,62 @@ void kexec_copy_flush(struct kimage *ima
 
 #ifdef CONFIG_SMP
 
-/* FIXME: we should schedule this function to be called on all cpus based
- * on calling the interrupts, but we would like to call it off irq level
- * so that the interrupt controller is clean.
- */
+static int kexec_all_irq_disabled = 0;
+
 static void kexec_smp_down(void *arg)
 {
+	local_irq_disable();
+	mb(); /* make sure our irqs are disabled before we say they are */
+	get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF;
+	while(kexec_all_irq_disabled == 0)
+		cpu_relax();
+	mb(); /* make sure all irqs are disabled before this */
+	/*
+	 * Now every CPU has IRQs off, we can clear out any pending
+	 * IPIs and be sure that no more will come in after this.
+	 */
 	if (ppc_md.kexec_cpu_down)
 		ppc_md.kexec_cpu_down(0, 1);
 
-	local_irq_disable();
 	kexec_smp_wait();
 	/* NOTREACHED */
 }
 
-static void kexec_prepare_cpus(void)
+/*
+ * We need to make sure each present CPU is online.  The next kernel will scan
+ * the device tree and assume primary threads are online and query secondary
+ * threads via RTAS to online them if required.  If we don't online primary
+ * threads, they will be stuck.  However, we also online secondary threads as we
+ * may be using 'cede offline'.  In this case RTAS doesn't see the secondary
+ * threads as offline -- and again, these CPUs will be stuck.
+ *
+ * So, we online all CPUs that should be running, including secondary threads.
+ */
+static void wake_offline_cpus(void)
+{
+	int cpu = 0;
+
+	for_each_present_cpu(cpu) {
+		if (!cpu_online(cpu)) {
+			printk(KERN_INFO "kexec: Waking offline cpu %d.\n",
+			       cpu);
+			cpu_up(cpu);
+		}
+	}
+}
+
+static void kexec_prepare_cpus_wait(int wait_state)
 {
 	int my_cpu, i, notified=-1;
 
-	smp_call_function(kexec_smp_down, NULL, /* wait */0);
+	wake_offline_cpus();
 	my_cpu = get_cpu();
-
-	/* check the others cpus are now down (via paca hw cpu id == -1) */
+	/* Make sure each CPU has atleast made it to the state we need */
 	for (i=0; i < NR_CPUS; i++) {
 		if (i == my_cpu)
 			continue;
 
-		while (paca[i].hw_cpu_id != -1) {
+		while (paca[i].kexec_state < wait_state) {
 			barrier();
 			if (!cpu_possible(i)) {
 				printk("kexec: cpu %d hw_cpu_id %d is not"
@@ -201,20 +231,35 @@ static void kexec_prepare_cpus(void)
 			}
 			if (i != notified) {
 				printk( "kexec: waiting for cpu %d (physical"
-						" %d) to go down\n",
-						i, paca[i].hw_cpu_id);
+						" %d) to enter %i state\n",
+					i, paca[i].hw_cpu_id, wait_state);
 				notified = i;
 			}
 		}
 	}
+	mb();
+}
+
+static void kexec_prepare_cpus(void)
+{
+
+	smp_call_function(kexec_smp_down, NULL, /* wait */0);
+	local_irq_disable();
+	mb(); /* make sure IRQs are disabled before we say they are */
+	get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF;
+
+	kexec_prepare_cpus_wait(KEXEC_STATE_IRQS_OFF);
+	/* we are sure every CPU has IRQs off at this point */
+	kexec_all_irq_disabled = 1;
 
 	/* after we tell the others to go down */
 	if (ppc_md.kexec_cpu_down)
 		ppc_md.kexec_cpu_down(0, 0);
 
-	put_cpu();
+	/* Before removing MMU mapings make sure all CPUs have entered real mode */
+	kexec_prepare_cpus_wait(KEXEC_STATE_REAL_MODE);
 
-	local_irq_disable();
+	put_cpu();
 }
 
 #else /* ! SMP */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/misc_64.S linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/misc_64.S
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/misc_64.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/misc_64.S	2014-02-10 17:31:40.000000000 -0500
@@ -24,6 +24,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/cputable.h>
 #include <asm/thread_info.h>
+#include <asm/kexec.h>
 
 	.text
 
@@ -462,7 +463,8 @@ _GLOBAL(disable_kernel_fp)
  * wait for the flag to change, indicating this kernel is going away but
  * the slave code for the next one is at addresses 0 to 100.
  *
- * This is used by all slaves.
+ * This is used by all slaves, even those that did not find a matching
+ * paca in the secondary startup code.
  *
  * Physical (hardware) cpu id should be in r3.
  */
@@ -494,15 +496,18 @@ kexec_flag:
  * note: this is a terminal routine, it does not save lr
  *
  * get phys id from paca
- * set paca id to -1 to say we got here
  * switch to real mode
+ * mark the paca as no longer used
  * join other cpus in kexec_wait(phys_id)
  */
 _GLOBAL(kexec_smp_wait)
 	lhz	r3,PACAHWCPUID(r13)
-	li	r4,-1
-	sth	r4,PACAHWCPUID(r13)	/* let others know we left */
 	bl	real_mode
+
+	li	r4,KEXEC_STATE_REAL_MODE
+	stb	r4,PACAKEXECSTATE(r13)
+	SYNC
+
 	b	.kexec_wait
 
 /*
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/paca.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/paca.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/paca.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/paca.c	2014-02-10 17:31:40.000000000 -0500
@@ -18,6 +18,7 @@
 #include <asm/pgtable.h>
 #include <asm/iseries/lpar_map.h>
 #include <asm/iseries/hv_types.h>
+#include <asm/kexec.h>
 
 /* This symbol is provided by the linker - let it fill in the paca
  * field correctly */
@@ -97,6 +98,7 @@ void __init initialise_paca(struct paca_
 	new_paca->kernelbase = (unsigned long) _stext;
 	new_paca->kernel_msr = MSR_KERNEL;
 	new_paca->hw_cpu_id = 0xffff;
+	new_paca->kexec_state = KEXEC_STATE_NONE;
 	new_paca->__current = &init_task;
 #ifdef CONFIG_PPC_STD_MMU_64
 	new_paca->slb_shadow_ptr = &slb_shadow[cpu];
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pci_of_scan.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/pci_of_scan.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/pci_of_scan.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/pci_of_scan.c	2014-02-10 17:31:40.000000000 -0500
@@ -310,6 +310,8 @@ static void __devinit __of_scan_bus(stru
 	/* Scan direct children */
 	for_each_child_of_node(node, child) {
 		pr_debug("  * %s\n", child->full_name);
+		if (!of_device_is_available(child))
+			continue;
 		reg = of_get_property(child, "reg", &reglen);
 		if (reg == NULL || reglen < 20)
 			continue;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/perf_event.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/perf_event.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/perf_event.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/perf_event.c	2014-02-10 17:31:40.000000000 -0500
@@ -1220,6 +1220,28 @@ unsigned long perf_instruction_pointer(s
 	return ip;
 }
 
+static bool pmc_overflow(unsigned long val)
+{
+	if ((int)val < 0)
+		return true;
+
+	/*
+	 * Events on POWER7 can roll back if a speculative event doesn't
+	 * eventually complete. Unfortunately in some rare cases they will
+	 * raise a performance monitor exception. We need to catch this to
+	 * ensure we reset the PMC. In all cases the PMC will be 256 or less
+	 * cycles from overflow.
+	 *
+	 * We only do this if the first pass fails to find any overflowing
+	 * PMCs because a user might set a period of less than 256 and we
+	 * don't want to mistakenly reset them.
+	 */
+	if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256))
+		return true;
+
+	return false;
+}
+
 /*
  * Performance monitor interrupt stuff
  */
@@ -1267,7 +1289,7 @@ static void perf_event_interrupt(struct
 			if (is_limited_pmc(i + 1))
 				continue;
 			val = read_pmc(i + 1);
-			if ((int)val < 0)
+			if (pmc_overflow(val))
 				write_pmc(i + 1, 0);
 		}
 	}
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/ppc970-pmu.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/ppc970-pmu.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/ppc970-pmu.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/ppc970-pmu.c	2014-02-10 17:31:40.000000000 -0500
@@ -169,9 +169,11 @@ static int p970_marked_instr_event(u64 e
 	switch (unit) {
 	case PM_VPU:
 		mask = 0x4c;		/* byte 0 bits 2,3,6 */
+		break;
 	case PM_LSU0:
 		/* byte 2 bits 0,2,3,4,6; all of byte 1 */
 		mask = 0x085dff00;
+		break;
 	case PM_LSU1L:
 		mask = 0x50 << 24;	/* byte 3 bits 4,6 */
 		break;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/prom_init.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/prom_init.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/prom_init.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/prom_init.c	2014-02-10 17:31:40.000000000 -0500
@@ -968,7 +968,7 @@ static unsigned long __init alloc_up(uns
 	}
 	if (addr == 0)
 		return 0;
-	RELOC(alloc_bottom) = addr;
+	RELOC(alloc_bottom) = addr + size;
 
 	prom_debug(" -> %x\n", addr);
 	prom_debug("  alloc_bottom : %x\n", RELOC(alloc_bottom));
@@ -1782,7 +1782,7 @@ static void __init *make_room(unsigned l
 		chunk = alloc_up(room, 0);
 		if (chunk == 0)
 			prom_panic("No memory for flatten_device_tree (claim failed)");
-		*mem_end = RELOC(alloc_top);
+		*mem_end = chunk + room;
 	}
 
 	ret = (void *)*mem_start;
@@ -2001,7 +2001,7 @@ static void __init flatten_device_tree(v
 	mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
 	if (mem_start == 0)
 		prom_panic("Can't allocate initial device-tree chunk\n");
-	mem_end = RELOC(alloc_top);
+	mem_end = mem_start + room;
 
 	/* Get root of tree */
 	root = call_prom("peer", 1, 1, (phandle)0);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/rtas_flash.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/rtas_flash.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/rtas_flash.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/rtas_flash.c	2014-02-10 17:31:40.000000000 -0500
@@ -94,12 +94,8 @@ struct flash_block_list {
 	struct flash_block_list *next;
 	struct flash_block blocks[FLASH_BLOCKS_PER_NODE];
 };
-struct flash_block_list_header { /* just the header of flash_block_list */
-	unsigned long num_blocks;
-	struct flash_block_list *next;
-};
 
-static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
+static struct flash_block_list *rtas_firmware_flash_list;
 
 /* Use slab cache to guarantee 4k alignment */
 static struct kmem_cache *flash_block_cache = NULL;
@@ -108,13 +104,14 @@ static struct kmem_cache *flash_block_ca
 
 /* Local copy of the flash block list.
  * We only allow one open of the flash proc file and create this
- * list as we go.  This list will be put in the
- * rtas_firmware_flash_list var once it is fully read.
+ * list as we go.  The rtas_firmware_flash_list varable will be
+ * set once the data is fully read.
  *
  * For convenience as we build the list we use virtual addrs,
  * we do not fill in the version number, and the length field
  * is treated as the number of entries currently in the block
- * (i.e. not a byte count).  This is all fixed on release.
+ * (i.e. not a byte count).  This is all fixed when calling
+ * the flash routine.
  */
 
 /* Status int must be first member of struct */
@@ -201,16 +198,16 @@ static int rtas_flash_release(struct ino
 	if (uf->flist) {    
 		/* File was opened in write mode for a new flash attempt */
 		/* Clear saved list */
-		if (rtas_firmware_flash_list.next) {
-			free_flash_list(rtas_firmware_flash_list.next);
-			rtas_firmware_flash_list.next = NULL;
+		if (rtas_firmware_flash_list) {
+			free_flash_list(rtas_firmware_flash_list);
+			rtas_firmware_flash_list = NULL;
 		}
 
 		if (uf->status != FLASH_AUTH)  
 			uf->status = flash_list_valid(uf->flist);
 
 		if (uf->status == FLASH_IMG_READY) 
-			rtas_firmware_flash_list.next = uf->flist;
+			rtas_firmware_flash_list = uf->flist;
 		else
 			free_flash_list(uf->flist);
 
@@ -593,7 +590,7 @@ static void rtas_flash_firmware(int rebo
 	unsigned long rtas_block_list;
 	int i, status, update_token;
 
-	if (rtas_firmware_flash_list.next == NULL)
+	if (rtas_firmware_flash_list == NULL)
 		return;		/* nothing to do */
 
 	if (reboot_type != SYS_RESTART) {
@@ -610,20 +607,25 @@ static void rtas_flash_firmware(int rebo
 		return;
 	}
 
-	/* NOTE: the "first" block list is a global var with no data
-	 * blocks in the kernel data segment.  We do this because
-	 * we want to ensure this block_list addr is under 4GB.
+	/*
+	 * NOTE: the "first" block must be under 4GB, so we create
+	 * an entry with no data blocks in the reserved buffer in
+	 * the kernel data segment.
 	 */
-	rtas_firmware_flash_list.num_blocks = 0;
-	flist = (struct flash_block_list *)&rtas_firmware_flash_list;
+	spin_lock(&rtas_data_buf_lock);
+	flist = (struct flash_block_list *)&rtas_data_buf[0];
+	flist->num_blocks = 0;
+	flist->next = rtas_firmware_flash_list;
 	rtas_block_list = virt_to_abs(flist);
 	if (rtas_block_list >= 4UL*1024*1024*1024) {
 		printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
+		spin_unlock(&rtas_data_buf_lock);
 		return;
 	}
 
 	printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n");
 	/* Update the block_list in place. */
+	rtas_firmware_flash_list = NULL; /* too hard to backout on error */
 	image_size = 0;
 	for (f = flist; f; f = next) {
 		/* Translate data addrs to absolute */
@@ -664,6 +666,7 @@ static void rtas_flash_firmware(int rebo
 		printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status);
 		break;
 	}
+	spin_unlock(&rtas_data_buf_lock);
 }
 
 static void remove_flash_pde(struct proc_dir_entry *dp)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kernel/setup_64.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/setup_64.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kernel/setup_64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kernel/setup_64.c	2014-02-10 17:31:40.000000000 -0500
@@ -424,9 +424,18 @@ void __init setup_system(void)
 	DBG(" <- setup_system()\n");
 }
 
+static u64 slb0_limit(void)
+{
+	if (cpu_has_feature(CPU_FTR_1T_SEGMENT)) {
+		return 1UL << SID_SHIFT_1T;
+	}
+	return 1UL << SID_SHIFT;
+}
+
 #ifdef CONFIG_IRQSTACKS
 static void __init irqstack_early_init(void)
 {
+	u64 limit = slb0_limit();
 	unsigned int i;
 
 	/*
@@ -436,10 +445,10 @@ static void __init irqstack_early_init(v
 	for_each_possible_cpu(i) {
 		softirq_ctx[i] = (struct thread_info *)
 			__va(lmb_alloc_base(THREAD_SIZE,
-					    THREAD_SIZE, 0x10000000));
+					    THREAD_SIZE, limit));
 		hardirq_ctx[i] = (struct thread_info *)
 			__va(lmb_alloc_base(THREAD_SIZE,
-					    THREAD_SIZE, 0x10000000));
+					    THREAD_SIZE, limit));
 	}
 }
 #else
@@ -470,7 +479,7 @@ static void __init exc_lvl_early_init(vo
  */
 static void __init emergency_stack_init(void)
 {
-	unsigned long limit;
+	u64 limit;
 	unsigned int i;
 
 	/*
@@ -482,7 +491,7 @@ static void __init emergency_stack_init(
 	 * bringup, we need to get at them in real mode. This means they
 	 * must also be within the RMO region.
 	 */
-	limit = min(0x10000000ULL, lmb.rmo_size);
+	limit = min(slb0_limit(), lmb.rmo_size);
 
 	for_each_possible_cpu(i) {
 		unsigned long sp;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kvm/book3s.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kvm/book3s.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kvm/book3s.c	2014-02-10 17:31:40.000000000 -0500
@@ -922,6 +922,8 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct
 	struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu);
 	int i;
 
+	vcpu_load(vcpu);
+
 	sregs->pvr = vcpu->arch.pvr;
 
 	sregs->u.s.sdr1 = to_book3s(vcpu)->sdr1;
@@ -940,6 +942,9 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct
 			sregs->u.s.ppc32.dbat[i] = vcpu3s->dbat[i].raw;
 		}
 	}
+
+	vcpu_put(vcpu);
+
 	return 0;
 }
 
@@ -949,6 +954,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct
 	struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu);
 	int i;
 
+	vcpu_load(vcpu);
+
 	kvmppc_set_pvr(vcpu, sregs->pvr);
 
 	vcpu3s->sdr1 = sregs->u.s.sdr1;
@@ -975,6 +982,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct
 
 	/* Flush the MMU after messing with the segments */
 	kvmppc_mmu_pte_flush(vcpu, 0, 0);
+
+	vcpu_put(vcpu);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kvm/booke.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kvm/booke.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kvm/booke.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kvm/booke.c	2014-02-10 17:31:40.000000000 -0500
@@ -479,6 +479,8 @@ int kvm_arch_vcpu_ioctl_get_regs(struct
 {
 	int i;
 
+	vcpu_load(vcpu);
+
 	regs->pc = vcpu->arch.pc;
 	regs->cr = kvmppc_get_cr(vcpu);
 	regs->ctr = vcpu->arch.ctr;
@@ -499,6 +501,8 @@ int kvm_arch_vcpu_ioctl_get_regs(struct
 	for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
 		regs->gpr[i] = kvmppc_get_gpr(vcpu, i);
 
+	vcpu_put(vcpu);
+
 	return 0;
 }
 
@@ -506,6 +510,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct
 {
 	int i;
 
+	vcpu_load(vcpu);
+
 	vcpu->arch.pc = regs->pc;
 	kvmppc_set_cr(vcpu, regs->cr);
 	vcpu->arch.ctr = regs->ctr;
@@ -525,6 +531,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct
 	for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
 		kvmppc_set_gpr(vcpu, i, regs->gpr[i]);
 
+	vcpu_put(vcpu);
+
 	return 0;
 }
 
@@ -553,7 +561,12 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct k
 int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
                                   struct kvm_translation *tr)
 {
-	return kvmppc_core_vcpu_translate(vcpu, tr);
+	int r;
+
+	vcpu_load(vcpu);
+	r = kvmppc_core_vcpu_translate(vcpu, tr);
+	vcpu_put(vcpu);
+	return r;
 }
 
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/kvm/powerpc.c linux-libre-2.6.34.15-gnu1/arch/powerpc/kvm/powerpc.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/kvm/powerpc.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/kvm/powerpc.c	2014-02-10 17:31:40.000000000 -0500
@@ -193,7 +193,8 @@ struct kvm_vcpu *kvm_arch_vcpu_create(st
 {
 	struct kvm_vcpu *vcpu;
 	vcpu = kvmppc_core_vcpu_create(kvm, id);
-	kvmppc_create_vcpu_debugfs(vcpu, id);
+	if (!IS_ERR(vcpu))
+		kvmppc_create_vcpu_debugfs(vcpu, id);
 	return vcpu;
 }
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/lib/string.S linux-libre-2.6.34.15-gnu1/arch/powerpc/lib/string.S
--- linux-libre-2.6.34-gnu1/arch/powerpc/lib/string.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/lib/string.S	2014-02-10 17:31:40.000000000 -0500
@@ -71,7 +71,7 @@ _GLOBAL(strcmp)
 
 _GLOBAL(strncmp)
 	PPC_LCMPI r5,0
-	beqlr
+	ble-	2f
 	mtctr	r5
 	addi	r5,r3,-1
 	addi	r4,r4,-1
@@ -82,6 +82,8 @@ _GLOBAL(strncmp)
 	beqlr	1
 	bdnzt	eq,1b
 	blr
+2:	li	r3,0
+	blr
 
 _GLOBAL(strlen)
 	addi	r4,r3,-1
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/Makefile linux-libre-2.6.34.15-gnu1/arch/powerpc/Makefile
--- linux-libre-2.6.34-gnu1/arch/powerpc/Makefile	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/Makefile	2014-02-10 17:31:40.000000000 -0500
@@ -158,9 +158,11 @@ drivers-$(CONFIG_OPROFILE)	+= arch/power
 # Default to zImage, override when needed
 all: zImage
 
-BOOT_TARGETS = zImage zImage.initrd uImage zImage% dtbImage% treeImage.% cuImage.% simpleImage.%
+# With make 3.82 we cannot mix normal and wildcard targets
+BOOT_TARGETS1 := zImage zImage.initrd uImage
+BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.%
 
-PHONY += $(BOOT_TARGETS)
+PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2)
 
 boot := arch/$(ARCH)/boot
 
@@ -175,10 +177,16 @@ relocs_check: arch/powerpc/relocs_check.
 zImage: relocs_check
 endif
 
-$(BOOT_TARGETS): vmlinux
+$(BOOT_TARGETS1): vmlinux
+	$(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
+$(BOOT_TARGETS2): vmlinux
 	$(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
 
-bootwrapper_install %.dtb:
+
+bootwrapper_install:
+	$(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
+
+%.dtb:
 	$(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
 
 define archhelp
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/mm/fsl_booke_mmu.c linux-libre-2.6.34.15-gnu1/arch/powerpc/mm/fsl_booke_mmu.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/mm/fsl_booke_mmu.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/mm/fsl_booke_mmu.c	2014-02-10 17:31:40.000000000 -0500
@@ -2,7 +2,7 @@
  * Modifications by Kumar Gala (galak@kernel.crashing.org) to support
  * E500 Book E processors.
  *
- * Copyright 2004 Freescale Semiconductor, Inc
+ * Copyright 2004,2010 Freescale Semiconductor, Inc.
  *
  * This file contains the routines for initializing the MMU
  * on the 4xx series of chips.
@@ -56,19 +56,13 @@
 
 unsigned int tlbcam_index;
 
-#define NUM_TLBCAMS	(64)
 
 #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS)
 #error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS"
 #endif
 
-struct tlbcam {
-	u32	MAS0;
-	u32	MAS1;
-	unsigned long	MAS2;
-	u32	MAS3;
-	u32	MAS7;
-} TLBCAM[NUM_TLBCAMS];
+#define NUM_TLBCAMS	(64)
+struct tlbcam TLBCAM[NUM_TLBCAMS];
 
 struct tlbcamrange {
 	unsigned long start;
@@ -109,19 +103,6 @@ unsigned long p_mapped_by_tlbcam(phys_ad
 	return 0;
 }
 
-void loadcam_entry(int idx)
-{
-	mtspr(SPRN_MAS0, TLBCAM[idx].MAS0);
-	mtspr(SPRN_MAS1, TLBCAM[idx].MAS1);
-	mtspr(SPRN_MAS2, TLBCAM[idx].MAS2);
-	mtspr(SPRN_MAS3, TLBCAM[idx].MAS3);
-
-	if (mmu_has_feature(MMU_FTR_BIG_PHYS))
-		mtspr(SPRN_MAS7, TLBCAM[idx].MAS7);
-
-	asm volatile("isync;tlbwe;isync" : : : "memory");
-}
-
 /*
  * Set up one of the I/D BAT (block address translation) register pairs.
  * The parameters are not checked; in particular size must be a power
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/mm/mmu_decl.h linux-libre-2.6.34.15-gnu1/arch/powerpc/mm/mmu_decl.h
--- linux-libre-2.6.34-gnu1/arch/powerpc/mm/mmu_decl.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/mm/mmu_decl.h	2014-02-10 17:31:40.000000000 -0500
@@ -149,7 +149,15 @@ extern unsigned long mmu_mapin_ram(unsig
 extern void MMU_init_hw(void);
 extern unsigned long mmu_mapin_ram(unsigned long top);
 extern void adjust_total_lowmem(void);
+extern void loadcam_entry(unsigned int index);
 
+struct tlbcam {
+	u32	MAS0;
+	u32	MAS1;
+	unsigned long	MAS2;
+	u32	MAS3;
+	u32	MAS7;
+};
 #elif defined(CONFIG_PPC32)
 /* anything 32-bit except 4xx or 8xx */
 extern void MMU_init_hw(void);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/mm/pgtable_32.c linux-libre-2.6.34.15-gnu1/arch/powerpc/mm/pgtable_32.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/mm/pgtable_32.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/mm/pgtable_32.c	2014-02-10 17:31:40.000000000 -0500
@@ -146,6 +146,14 @@ ioremap_flags(phys_addr_t addr, unsigned
 	/* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
 	flags &= ~(_PAGE_USER | _PAGE_EXEC);
 
+#ifdef _PAGE_BAP_SR
+	/* _PAGE_USER contains _PAGE_BAP_SR on BookE using the new PTE format
+	 * which means that we just cleared supervisor access... oops ;-) This
+	 * restores it
+	 */
+	flags |= _PAGE_BAP_SR;
+#endif
+
 	return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(ioremap_flags);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/mm/pgtable_64.c linux-libre-2.6.34.15-gnu1/arch/powerpc/mm/pgtable_64.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/mm/pgtable_64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/mm/pgtable_64.c	2014-02-10 17:31:40.000000000 -0500
@@ -265,6 +265,14 @@ void __iomem * ioremap_flags(phys_addr_t
 	/* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
 	flags &= ~(_PAGE_USER | _PAGE_EXEC);
 
+#ifdef _PAGE_BAP_SR
+	/* _PAGE_USER contains _PAGE_BAP_SR on BookE using the new PTE format
+	 * which means that we just cleared supervisor access... oops ;-) This
+	 * restores it
+	 */
+	flags |= _PAGE_BAP_SR;
+#endif
+
 	if (ppc_md.ioremap)
 		return ppc_md.ioremap(addr, size, flags, caller);
 	return __ioremap_caller(addr, size, flags, caller);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/mm/tlb_nohash_low.S linux-libre-2.6.34.15-gnu1/arch/powerpc/mm/tlb_nohash_low.S
--- linux-libre-2.6.34-gnu1/arch/powerpc/mm/tlb_nohash_low.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/mm/tlb_nohash_low.S	2014-02-10 17:31:40.000000000 -0500
@@ -271,3 +271,31 @@ _GLOBAL(set_context)
 #else
 #error Unsupported processor type !
 #endif
+
+#if defined(CONFIG_FSL_BOOKE)
+/*
+ * extern void loadcam_entry(unsigned int index)
+ *
+ * Load TLBCAM[index] entry in to the L2 CAM MMU
+ */
+_GLOBAL(loadcam_entry)
+	LOAD_REG_ADDR(r4, TLBCAM)
+	mulli	r5,r3,TLBCAM_SIZE
+	add	r3,r5,r4
+	lwz	r4,TLBCAM_MAS0(r3)
+	mtspr	SPRN_MAS0,r4
+	lwz	r4,TLBCAM_MAS1(r3)
+	mtspr	SPRN_MAS1,r4
+	PPC_LL	r4,TLBCAM_MAS2(r3)
+	mtspr	SPRN_MAS2,r4
+	lwz	r4,TLBCAM_MAS3(r3)
+	mtspr	SPRN_MAS3,r4
+BEGIN_MMU_FTR_SECTION
+	lwz	r4,TLBCAM_MAS7(r3)
+	mtspr	SPRN_MAS7,r4
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
+	isync
+	tlbwe
+	isync
+	blr
+#endif
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/oprofile/op_model_cell.c linux-libre-2.6.34.15-gnu1/arch/powerpc/oprofile/op_model_cell.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/oprofile/op_model_cell.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/oprofile/op_model_cell.c	2014-02-10 17:31:40.000000000 -0500
@@ -1077,7 +1077,7 @@ static int calculate_lfsr(int n)
 		index = ENTRIES-1;
 
 	/* make sure index is valid */
-	if ((index > ENTRIES) || (index < 0))
+	if ((index >= ENTRIES) || (index < 0))
 		index = ENTRIES-1;
 
 	return initial_lfsr[index];
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/oprofile/op_model_power4.c linux-libre-2.6.34.15-gnu1/arch/powerpc/oprofile/op_model_power4.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/oprofile/op_model_power4.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/oprofile/op_model_power4.c	2014-02-10 17:31:40.000000000 -0500
@@ -261,6 +261,28 @@ static int get_kernel(unsigned long pc,
 	return is_kernel;
 }
 
+static bool pmc_overflow(unsigned long val)
+{
+	if ((int)val < 0)
+		return true;
+
+	/*
+	 * Events on POWER7 can roll back if a speculative event doesn't
+	 * eventually complete. Unfortunately in some rare cases they will
+	 * raise a performance monitor exception. We need to catch this to
+	 * ensure we reset the PMC. In all cases the PMC will be 256 or less
+	 * cycles from overflow.
+	 *
+	 * We only do this if the first pass fails to find any overflowing
+	 * PMCs because a user might set a period of less than 256 and we
+	 * don't want to mistakenly reset them.
+	 */
+	if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256))
+		return true;
+
+	return false;
+}
+
 static void power4_handle_interrupt(struct pt_regs *regs,
 				    struct op_counter_config *ctr)
 {
@@ -281,7 +303,7 @@ static void power4_handle_interrupt(stru
 
 	for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {
 		val = classic_ctr_read(i);
-		if (val < 0) {
+		if (pmc_overflow(val)) {
 			if (oprofile_running && ctr[i].enabled) {
 				oprofile_add_ext_sample(pc, regs, i, is_kernel);
 				classic_ctr_write(i, reset_value[i]);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/hotplug-cpu.c linux-libre-2.6.34.15-gnu1/arch/powerpc/platforms/pseries/hotplug-cpu.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/hotplug-cpu.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/platforms/pseries/hotplug-cpu.c	2014-02-10 17:31:40.000000000 -0500
@@ -154,30 +154,6 @@ static void pseries_mach_cpu_die(void)
 	for(;;);
 }
 
-static int qcss_tok;	/* query-cpu-stopped-state token */
-
-/* Get state of physical CPU.
- * Return codes:
- *	0	- The processor is in the RTAS stopped state
- *	1	- stop-self is in progress
- *	2	- The processor is not in the RTAS stopped state
- *	-1	- Hardware Error
- *	-2	- Hardware Busy, Try again later.
- */
-static int query_cpu_stopped(unsigned int pcpu)
-{
-	int cpu_status, status;
-
-	status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu);
-	if (status != 0) {
-		printk(KERN_ERR
-		       "RTAS query-cpu-stopped-state failed: %i\n", status);
-		return status;
-	}
-
-	return cpu_status;
-}
-
 static int pseries_cpu_disable(void)
 {
 	int cpu = smp_processor_id();
@@ -224,8 +200,9 @@ static void pseries_cpu_die(unsigned int
 	} else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
 
 		for (tries = 0; tries < 25; tries++) {
-			cpu_status = query_cpu_stopped(pcpu);
-			if (cpu_status == 0 || cpu_status == -1)
+			cpu_status = smp_query_cpu_stopped(pcpu);
+			if (cpu_status == QCSS_STOPPED ||
+			    cpu_status == QCSS_HARDWARE_ERROR)
 				break;
 			cpu_relax();
 		}
@@ -388,6 +365,7 @@ static int __init pseries_cpu_hotplug_in
 	struct device_node *np;
 	const char *typep;
 	int cpu;
+	int qcss_tok;
 
 	for_each_node_by_name(np, "interrupt-controller") {
 		typep = of_get_property(np, "compatible", NULL);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/hvCall.S linux-libre-2.6.34.15-gnu1/arch/powerpc/platforms/pseries/hvCall.S
--- linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/hvCall.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/platforms/pseries/hvCall.S	2014-02-10 17:31:40.000000000 -0500
@@ -228,3 +228,41 @@ _GLOBAL(plpar_hcall9)
 	mtcrf	0xff,r0
 
 	blr				/* return r3 = status */
+
+/* See plpar_hcall_raw to see why this is needed */
+_GLOBAL(plpar_hcall9_raw)
+	HMT_MEDIUM
+
+	mfcr	r0
+	stw	r0,8(r1)
+
+	std     r4,STK_PARM(r4)(r1)     /* Save ret buffer */
+
+	mr	r4,r5
+	mr	r5,r6
+	mr	r6,r7
+	mr	r7,r8
+	mr	r8,r9
+	mr	r9,r10
+	ld	r10,STK_PARM(r11)(r1)	 /* put arg7 in R10 */
+	ld	r11,STK_PARM(r12)(r1)	 /* put arg8 in R11 */
+	ld	r12,STK_PARM(r13)(r1)    /* put arg9 in R12 */
+
+	HVSC				/* invoke the hypervisor */
+
+	mr	r0,r12
+	ld	r12,STK_PARM(r4)(r1)
+	std	r4,  0(r12)
+	std	r5,  8(r12)
+	std	r6, 16(r12)
+	std	r7, 24(r12)
+	std	r8, 32(r12)
+	std	r9, 40(r12)
+	std	r10,48(r12)
+	std	r11,56(r12)
+	std	r0, 64(r12)
+
+	lwz	r0,8(r1)
+	mtcrf	0xff,r0
+
+	blr				/* return r3 = status */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/hvconsole.c linux-libre-2.6.34.15-gnu1/arch/powerpc/platforms/pseries/hvconsole.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/hvconsole.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/platforms/pseries/hvconsole.c	2014-02-10 17:31:40.000000000 -0500
@@ -73,7 +73,7 @@ int hvc_put_chars(uint32_t vtermno, cons
 	if (ret == H_SUCCESS)
 		return count;
 	if (ret == H_BUSY)
-		return 0;
+		return -EAGAIN;
 	return -EIO;
 }
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/lpar.c linux-libre-2.6.34.15-gnu1/arch/powerpc/platforms/pseries/lpar.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/lpar.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/platforms/pseries/lpar.c	2014-02-10 17:31:40.000000000 -0500
@@ -367,21 +367,28 @@ static void pSeries_lpar_hptab_clear(voi
 {
 	unsigned long size_bytes = 1UL << ppc64_pft_size;
 	unsigned long hpte_count = size_bytes >> 4;
-	unsigned long dummy1, dummy2, dword0;
+	struct {
+		unsigned long pteh;
+		unsigned long ptel;
+	} ptes[4];
 	long lpar_rc;
-	int i;
+	unsigned long i, j;
 
-	/* TODO: Use bulk call */
-	for (i = 0; i < hpte_count; i++) {
-		/* dont remove HPTEs with VRMA mappings */
-		lpar_rc = plpar_pte_remove_raw(H_ANDCOND, i, HPTE_V_1TB_SEG,
-						&dummy1, &dummy2);
-		if (lpar_rc == H_NOT_FOUND) {
-			lpar_rc = plpar_pte_read_raw(0, i, &dword0, &dummy1);
-			if (!lpar_rc && ((dword0 & HPTE_V_VRMA_MASK)
-				!= HPTE_V_VRMA_MASK))
-				/* Can be hpte for 1TB Seg. So remove it */
-				plpar_pte_remove_raw(0, i, 0, &dummy1, &dummy2);
+	/* Read in batches of 4,
+	 * invalidate only valid entries not in the VRMA
+	 * hpte_count will be a multiple of 4
+         */
+	for (i = 0; i < hpte_count; i += 4) {
+		lpar_rc = plpar_pte_read_4_raw(0, i, (void *)ptes);
+		if (lpar_rc != H_SUCCESS)
+			continue;
+		for (j = 0; j < 4; j++){
+			if ((ptes[j].pteh & HPTE_V_VRMA_MASK) ==
+				HPTE_V_VRMA_MASK)
+				continue;
+			if (ptes[j].pteh & HPTE_V_VALID)
+				plpar_pte_remove_raw(0, i + j, 0,
+					&(ptes[j].pteh), &(ptes[j].ptel));
 		}
 	}
 }
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h linux-libre-2.6.34.15-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h
--- linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/platforms/pseries/plpar_wrappers.h	2014-02-10 17:31:40.000000000 -0500
@@ -4,6 +4,14 @@
 #include <asm/hvcall.h>
 #include <asm/page.h>
 
+/* Get state of physical CPU from query_cpu_stopped */
+int smp_query_cpu_stopped(unsigned int pcpu);
+#define QCSS_STOPPED 0
+#define QCSS_STOPPING 1
+#define QCSS_NOT_STOPPED 2
+#define QCSS_HARDWARE_ERROR -1
+#define QCSS_HARDWARE_BUSY -2
+
 static inline long poll_pending(void)
 {
 	return plpar_hcall_norets(H_POLL_PENDING);
@@ -182,6 +190,24 @@ static inline long plpar_pte_read_raw(un
 
 	return rc;
 }
+
+/*
+ * plpar_pte_read_4_raw can be called in real mode.
+ * ptes must be 8*sizeof(unsigned long)
+ */
+static inline long plpar_pte_read_4_raw(unsigned long flags, unsigned long ptex,
+					unsigned long *ptes)
+
+{
+	long rc;
+	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+
+	rc = plpar_hcall9_raw(H_READ, retbuf, flags | H_READ_4, ptex);
+
+	memcpy(ptes, retbuf, 8*sizeof(unsigned long));
+
+	return rc;
+}
 
 static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
 		unsigned long avpn)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/smp.c linux-libre-2.6.34.15-gnu1/arch/powerpc/platforms/pseries/smp.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/platforms/pseries/smp.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/platforms/pseries/smp.c	2014-02-10 17:31:40.000000000 -0500
@@ -57,6 +57,28 @@
  */
 static cpumask_t of_spin_map;
 
+/* Query where a cpu is now.  Return codes #defined in plpar_wrappers.h */
+int smp_query_cpu_stopped(unsigned int pcpu)
+{
+	int cpu_status, status;
+	int qcss_tok = rtas_token("query-cpu-stopped-state");
+
+	if (qcss_tok == RTAS_UNKNOWN_SERVICE) {
+		printk(KERN_INFO "Firmware doesn't support "
+				"query-cpu-stopped-state\n");
+		return QCSS_HARDWARE_ERROR;
+	}
+
+	status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu);
+	if (status != 0) {
+		printk(KERN_ERR
+		       "RTAS query-cpu-stopped-state failed: %i\n", status);
+		return status;
+	}
+
+	return cpu_status;
+}
+
 /**
  * smp_startup_cpu() - start the given cpu
  *
@@ -82,6 +104,12 @@ static inline int __devinit smp_startup_
 
 	pcpu = get_hard_smp_processor_id(lcpu);
 
+	/* Check to see if the CPU out of FW already for kexec */
+	if (smp_query_cpu_stopped(pcpu) == QCSS_NOT_STOPPED){
+		cpu_set(lcpu, of_spin_map);
+		return 1;
+	}
+
 	/* Fixup atomic count: it exited inside IRQ handler. */
 	task_thread_info(paca[lcpu].__current)->preempt_count	= 0;
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/fsl_rio.c linux-libre-2.6.34.15-gnu1/arch/powerpc/sysdev/fsl_rio.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/fsl_rio.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/sysdev/fsl_rio.c	2014-02-10 17:31:40.000000000 -0500
@@ -833,7 +833,6 @@ fsl_rio_dbell_handler(int irq, void *dev
 	if (dsr & DOORBELL_DSR_QFI) {
 		pr_info("RIO: doorbell queue full\n");
 		out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_QFI);
-		goto out;
 	}
 
 	/* XXX Need to check/dispatch until queue empty */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/micropatch.c linux-libre-2.6.34.15-gnu1/arch/powerpc/sysdev/micropatch.c
--- linux-libre-2.6.34-gnu1/arch/powerpc/sysdev/micropatch.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/powerpc/sysdev/micropatch.c	2014-02-10 17:31:40.000000000 -0500
@@ -16,6 +16,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/8xx_immap.h>
+#include <asm/cpm.h>
 #include <asm/cpm1.h>
 
 /*
@@ -625,9 +626,14 @@ cpm_load_patch(cpm8xx_t	*cp)
 {
 	volatile uint		*dp;		/* Dual-ported RAM. */
 	volatile cpm8xx_t	*commproc;
+#if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \
+    defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)
 	volatile iic_t		*iip;
-	volatile spi_t		*spp;
+	volatile struct spi_pram *spp;
+#ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH
 	volatile smc_uart_t	*smp;
+#endif
+#endif
 	int	i;
 
 	commproc = cp;
@@ -668,8 +674,8 @@ cpm_load_patch(cpm8xx_t	*cp)
 	/* Put SPI above the IIC, also 32-byte aligned.
 	*/
 	i = (RPBASE + sizeof(iic_t) + 31) & ~31;
-	spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI];
-	spp->spi_rpbase = i;
+	spp = (struct spi_pram *)&commproc->cp_dparam[PROFF_SPI];
+	spp->rpbase = i;
 
 # if defined(CONFIG_I2C_SPI_UCODE_PATCH)
 	commproc->cp_cpmcr1 = 0x802a;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/s390/include/asm/compat.h linux-libre-2.6.34.15-gnu1/arch/s390/include/asm/compat.h
--- linux-libre-2.6.34-gnu1/arch/s390/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/s390/include/asm/compat.h	2014-02-10 17:31:40.000000000 -0500
@@ -181,7 +181,7 @@ static inline int is_compat_task(void)
 
 #endif
 
-static inline void __user *compat_alloc_user_space(long len)
+static inline void __user *arch_compat_alloc_user_space(long len)
 {
 	unsigned long stack;
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/s390/include/asm/processor.h linux-libre-2.6.34.15-gnu1/arch/s390/include/asm/processor.h
--- linux-libre-2.6.34-gnu1/arch/s390/include/asm/processor.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/s390/include/asm/processor.h	2014-02-10 17:31:40.000000000 -0500
@@ -150,11 +150,6 @@ extern int kernel_thread(int (*fn)(void
  */
 extern unsigned long thread_saved_pc(struct task_struct *t);
 
-/*
- * Print register of task into buffer. Used in fs/proc/array.c.
- */
-extern void task_show_regs(struct seq_file *m, struct task_struct *task);
-
 extern void show_code(struct pt_regs *regs);
 
 unsigned long get_wchan(struct task_struct *p);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/s390/kernel/nmi.c linux-libre-2.6.34.15-gnu1/arch/s390/kernel/nmi.c
--- linux-libre-2.6.34-gnu1/arch/s390/kernel/nmi.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/s390/kernel/nmi.c	2014-02-10 17:31:40.000000000 -0500
@@ -95,7 +95,6 @@ EXPORT_SYMBOL_GPL(s390_handle_mcck);
 static int notrace s390_revalidate_registers(struct mci *mci)
 {
 	int kill_task;
-	u64 tmpclock;
 	u64 zero;
 	void *fpt_save_area, *fpt_creg_save_area;
 
@@ -214,11 +213,10 @@ static int notrace s390_revalidate_regis
 			: "0", "cc");
 #endif
 	/* Revalidate clock comparator register */
-	asm volatile(
-		"	stck	0(%1)\n"
-		"	sckc	0(%1)"
-		: "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
-
+	if (S390_lowcore.clock_comparator == -1)
+		set_clock_comparator(S390_lowcore.mcck_clock);
+	else
+		set_clock_comparator(S390_lowcore.clock_comparator);
 	/* Check if old PSW is valid */
 	if (!mci->wp)
 		/*
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/s390/kernel/traps.c linux-libre-2.6.34.15-gnu1/arch/s390/kernel/traps.c
--- linux-libre-2.6.34-gnu1/arch/s390/kernel/traps.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/s390/kernel/traps.c	2014-02-10 17:31:40.000000000 -0500
@@ -243,43 +243,6 @@ void show_regs(struct pt_regs *regs)
 	show_last_breaking_event(regs);
 }
 
-/* This is called from fs/proc/array.c */
-void task_show_regs(struct seq_file *m, struct task_struct *task)
-{
-	struct pt_regs *regs;
-
-	regs = task_pt_regs(task);
-	seq_printf(m, "task: %p, ksp: %p\n",
-		       task, (void *)task->thread.ksp);
-	seq_printf(m, "User PSW : %p %p\n",
-		       (void *) regs->psw.mask, (void *)regs->psw.addr);
-
-	seq_printf(m, "User GPRS: " FOURLONG,
-			  regs->gprs[0], regs->gprs[1],
-			  regs->gprs[2], regs->gprs[3]);
-	seq_printf(m, "           " FOURLONG,
-			  regs->gprs[4], regs->gprs[5],
-			  regs->gprs[6], regs->gprs[7]);
-	seq_printf(m, "           " FOURLONG,
-			  regs->gprs[8], regs->gprs[9],
-			  regs->gprs[10], regs->gprs[11]);
-	seq_printf(m, "           " FOURLONG,
-			  regs->gprs[12], regs->gprs[13],
-			  regs->gprs[14], regs->gprs[15]);
-	seq_printf(m, "User ACRS: %08x %08x %08x %08x\n",
-			  task->thread.acrs[0], task->thread.acrs[1],
-			  task->thread.acrs[2], task->thread.acrs[3]);
-	seq_printf(m, "           %08x %08x %08x %08x\n",
-			  task->thread.acrs[4], task->thread.acrs[5],
-			  task->thread.acrs[6], task->thread.acrs[7]);
-	seq_printf(m, "           %08x %08x %08x %08x\n",
-			  task->thread.acrs[8], task->thread.acrs[9],
-			  task->thread.acrs[10], task->thread.acrs[11]);
-	seq_printf(m, "           %08x %08x %08x %08x\n",
-			  task->thread.acrs[12], task->thread.acrs[13],
-			  task->thread.acrs[14], task->thread.acrs[15]);
-}
-
 static DEFINE_SPINLOCK(die_lock);
 
 void die(const char * str, struct pt_regs * regs, long err)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/s390/kvm/kvm-s390.c linux-libre-2.6.34.15-gnu1/arch/s390/kvm/kvm-s390.c
--- linux-libre-2.6.34-gnu1/arch/s390/kvm/kvm-s390.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/s390/kvm/kvm-s390.c	2014-02-10 17:31:40.000000000 -0500
@@ -311,11 +311,17 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu
 struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
 				      unsigned int id)
 {
-	struct kvm_vcpu *vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
-	int rc = -ENOMEM;
+	struct kvm_vcpu *vcpu;
+	int rc = -EINVAL;
+
+	if (id >= KVM_MAX_VCPUS)
+		goto out;
+
+	rc = -ENOMEM;
 
+	vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
 	if (!vcpu)
-		goto out_nomem;
+		goto out;
 
 	vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
 					get_zeroed_page(GFP_KERNEL);
@@ -341,14 +347,16 @@ struct kvm_vcpu *kvm_arch_vcpu_create(st
 
 	rc = kvm_vcpu_init(vcpu, kvm, id);
 	if (rc)
-		goto out_free_cpu;
+		goto out_free_sie_block;
 	VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
 		 vcpu->arch.sie_block);
 
 	return vcpu;
+out_free_sie_block:
+	free_page((unsigned long)(vcpu->arch.sie_block));
 out_free_cpu:
 	kfree(vcpu);
-out_nomem:
+out:
 	return ERR_PTR(rc);
 }
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/s390/lib/delay.c linux-libre-2.6.34.15-gnu1/arch/s390/lib/delay.c
--- linux-libre-2.6.34-gnu1/arch/s390/lib/delay.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/s390/lib/delay.c	2014-02-10 17:31:40.000000000 -0500
@@ -29,17 +29,21 @@ static void __udelay_disabled(unsigned l
 {
 	unsigned long mask, cr0, cr0_saved;
 	u64 clock_saved;
+	u64 end;
 
+	mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
+	end = get_clock() + (usecs << 12);
 	clock_saved = local_tick_disable();
-	set_clock_comparator(get_clock() + (usecs << 12));
 	__ctl_store(cr0_saved, 0, 0);
 	cr0 = (cr0_saved & 0xffff00e0) | 0x00000800;
 	__ctl_load(cr0 , 0, 0);
-	mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
 	lockdep_off();
-	trace_hardirqs_on();
-	__load_psw_mask(mask);
-	local_irq_disable();
+	do {
+		set_clock_comparator(end);
+		trace_hardirqs_on();
+		__load_psw_mask(mask);
+		local_irq_disable();
+	} while (get_clock() < end);
 	lockdep_on();
 	__ctl_load(cr0_saved, 0, 0);
 	local_tick_enable(clock_saved);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/score/kernel/entry.S linux-libre-2.6.34.15-gnu1/arch/score/kernel/entry.S
--- linux-libre-2.6.34-gnu1/arch/score/kernel/entry.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/score/kernel/entry.S	2014-02-10 17:31:40.000000000 -0500
@@ -408,7 +408,7 @@ ENTRY(handle_sys)
 	sw	r9, [r0, PT_EPC]
 
 	cmpi.c	r27, __NR_syscalls 	# check syscall number
-	bgtu	illegal_syscall
+	bgeu	illegal_syscall
 
 	slli	r8, r27, 2		# get syscall routine
 	la	r11, sys_call_table
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/include/asm/atomic_64.h linux-libre-2.6.34.15-gnu1/arch/sparc/include/asm/atomic_64.h
--- linux-libre-2.6.34-gnu1/arch/sparc/include/asm/atomic_64.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/include/asm/atomic_64.h	2014-02-10 17:31:40.000000000 -0500
@@ -20,14 +20,14 @@
 #define atomic64_set(v, i)	(((v)->counter) = i)
 
 extern void atomic_add(int, atomic_t *);
-extern void atomic64_add(int, atomic64_t *);
+extern void atomic64_add(long, atomic64_t *);
 extern void atomic_sub(int, atomic_t *);
-extern void atomic64_sub(int, atomic64_t *);
+extern void atomic64_sub(long, atomic64_t *);
 
 extern int atomic_add_ret(int, atomic_t *);
-extern int atomic64_add_ret(int, atomic64_t *);
+extern long atomic64_add_ret(long, atomic64_t *);
 extern int atomic_sub_ret(int, atomic_t *);
-extern int atomic64_sub_ret(int, atomic64_t *);
+extern long atomic64_sub_ret(long, atomic64_t *);
 
 #define atomic_dec_return(v) atomic_sub_ret(1, v)
 #define atomic64_dec_return(v) atomic64_sub_ret(1, v)
@@ -91,7 +91,7 @@ static inline int atomic_add_unless(atom
 	((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
 #define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
 
-static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
+static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
 {
 	long c, old;
 	c = atomic64_read(v);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/include/asm/compat.h linux-libre-2.6.34.15-gnu1/arch/sparc/include/asm/compat.h
--- linux-libre-2.6.34-gnu1/arch/sparc/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/include/asm/compat.h	2014-02-10 17:31:40.000000000 -0500
@@ -167,7 +167,7 @@ static inline compat_uptr_t ptr_to_compa
 	return (u32)(unsigned long)uptr;
 }
 
-static inline void __user *compat_alloc_user_space(long len)
+static inline void __user *arch_compat_alloc_user_space(long len)
 {
 	struct pt_regs *regs = current_thread_info()->kregs;
 	unsigned long usp = regs->u_regs[UREG_I6];
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/include/asm/oplib_64.h linux-libre-2.6.34.15-gnu1/arch/sparc/include/asm/oplib_64.h
--- linux-libre-2.6.34-gnu1/arch/sparc/include/asm/oplib_64.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/include/asm/oplib_64.h	2014-02-10 17:31:40.000000000 -0500
@@ -185,9 +185,8 @@ extern int prom_getunumber(int syndrome_
 			   char *buf, int buflen);
 
 /* Retain physical memory to the caller across soft resets. */
-extern unsigned long prom_retain(const char *name,
-				 unsigned long pa_low, unsigned long pa_high,
-				 long size, long align);
+extern int prom_retain(const char *name, unsigned long size,
+		       unsigned long align, unsigned long *paddr);
 
 /* Load explicit I/D TLB entries into the calling processor. */
 extern long prom_itlb_load(unsigned long index,
@@ -287,26 +286,6 @@ extern void prom_sun4v_guest_soft_state(
 extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
 
 /* Client interface level routines. */
-extern long p1275_cmd(const char *, long, ...);
-
-#if 0
-#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x))
-#else
-#define P1275_SIZE(x) x
-#endif
-
-/* We support at most 16 input and 1 output argument */
-#define P1275_ARG_NUMBER		0
-#define P1275_ARG_IN_STRING		1
-#define P1275_ARG_OUT_BUF		2
-#define P1275_ARG_OUT_32B		3
-#define P1275_ARG_IN_FUNCTION		4
-#define P1275_ARG_IN_BUF		5
-#define P1275_ARG_IN_64B		6
-
-#define P1275_IN(x) ((x) & 0xf)
-#define P1275_OUT(x) (((x) << 4) & 0xf0)
-#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o))
-#define P1275_ARG(n,x) ((x) << ((n)*3 + 8))
+extern void p1275_cmd_direct(unsigned long *);
 
 #endif /* !(__SPARC64_OPLIB_H) */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/include/asm/parport.h linux-libre-2.6.34.15-gnu1/arch/sparc/include/asm/parport.h
--- linux-libre-2.6.34-gnu1/arch/sparc/include/asm/parport.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/include/asm/parport.h	2014-02-10 17:31:40.000000000 -0500
@@ -228,6 +228,10 @@ static const struct of_device_id ecpp_ma
 		.name = "parallel",
 		.compatible = "ns87317-ecpp",
 	},
+	{
+		.name = "parallel",
+		.compatible = "pnpALI,1533,3",
+	},
 	{},
 };
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/include/asm/rwsem-const.h linux-libre-2.6.34.15-gnu1/arch/sparc/include/asm/rwsem-const.h
--- linux-libre-2.6.34-gnu1/arch/sparc/include/asm/rwsem-const.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/include/asm/rwsem-const.h	2014-02-10 17:31:40.000000000 -0500
@@ -5,7 +5,7 @@
 #define RWSEM_UNLOCKED_VALUE		0x00000000
 #define RWSEM_ACTIVE_BIAS		0x00000001
 #define RWSEM_ACTIVE_MASK		0x0000ffff
-#define RWSEM_WAITING_BIAS		0xffff0000
+#define RWSEM_WAITING_BIAS		(-0x00010000)
 #define RWSEM_ACTIVE_READ_BIAS		RWSEM_ACTIVE_BIAS
 #define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/include/asm/sigcontext.h linux-libre-2.6.34.15-gnu1/arch/sparc/include/asm/sigcontext.h
--- linux-libre-2.6.34-gnu1/arch/sparc/include/asm/sigcontext.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/include/asm/sigcontext.h	2014-02-10 17:31:40.000000000 -0500
@@ -45,6 +45,19 @@ typedef struct {
 	int			si_mask;
 } __siginfo32_t;
 
+#define __SIGC_MAXWIN	7
+
+typedef struct {
+	unsigned long locals[8];
+	unsigned long ins[8];
+} __siginfo_reg_window;
+
+typedef struct {
+	int			wsaved;
+	__siginfo_reg_window	reg_window[__SIGC_MAXWIN];
+	unsigned long		rwbuf_stkptrs[__SIGC_MAXWIN];
+} __siginfo_rwin_t;
+
 #ifdef CONFIG_SPARC64
 typedef struct {
 	unsigned   int si_float_regs [64];
@@ -73,6 +86,7 @@ struct sigcontext {
 		unsigned long	ss_size;
 	}			sigc_stack;
 	unsigned long		sigc_mask;
+	__siginfo_rwin_t *	sigc_rwin_save;
 };
 
 #else
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/kernel/Makefile linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/Makefile
--- linux-libre-2.6.34-gnu1/arch/sparc/kernel/Makefile	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/Makefile	2014-02-10 17:31:40.000000000 -0500
@@ -32,6 +32,7 @@ obj-$(CONFIG_SPARC32)   += sun4m_irq.o s
 
 obj-y                   += process_$(BITS).o
 obj-y                   += signal_$(BITS).o
+obj-y                   += sigutil_$(BITS).o
 obj-$(CONFIG_SPARC32)   += ioport.o
 obj-y                   += setup_$(BITS).o
 obj-y                   += idprom.o
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/kernel/pcic.c linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/pcic.c
--- linux-libre-2.6.34-gnu1/arch/sparc/kernel/pcic.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/pcic.c	2014-02-10 17:31:40.000000000 -0500
@@ -349,8 +349,8 @@ int __init pcic_probe(void)
 	strcpy(pbm->prom_name, namebuf);
 
 	{
-		extern volatile int t_nmi[1];
-		extern int pcic_nmi_trap_patch[1];
+		extern volatile int t_nmi[4];
+		extern int pcic_nmi_trap_patch[4];
 
 		t_nmi[0] = pcic_nmi_trap_patch[0];
 		t_nmi[1] = pcic_nmi_trap_patch[1];
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/kernel/signal_32.c linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/signal_32.c
--- linux-libre-2.6.34-gnu1/arch/sparc/kernel/signal_32.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/signal_32.c	2014-02-10 17:31:40.000000000 -0500
@@ -26,6 +26,8 @@
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>	/* flush_sig_insns */
 
+#include "sigutil.h"
+
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
@@ -39,8 +41,8 @@ struct signal_frame {
 	unsigned long		insns[2] __attribute__ ((aligned (8)));
 	unsigned int		extramask[_NSIG_WORDS - 1];
 	unsigned int		extra_size; /* Should be 0 */
-	__siginfo_fpu_t		fpu_state;
-};
+	__siginfo_rwin_t __user	*rwin_save;
+} __attribute__((aligned(8)));
 
 struct rt_signal_frame {
 	struct sparc_stackf	ss;
@@ -51,8 +53,8 @@ struct rt_signal_frame {
 	unsigned int		insns[2];
 	stack_t			stack;
 	unsigned int		extra_size; /* Should be 0 */
-	__siginfo_fpu_t		fpu_state;
-};
+	__siginfo_rwin_t __user	*rwin_save;
+} __attribute__((aligned(8)));
 
 /* Align macros */
 #define SF_ALIGNEDSZ  (((sizeof(struct signal_frame) + 7) & (~7)))
@@ -79,43 +81,13 @@ asmlinkage int sys_sigsuspend(old_sigset
 	return _sigpause_common(set);
 }
 
-static inline int
-restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
-{
-	int err;
-#ifdef CONFIG_SMP
-	if (test_tsk_thread_flag(current, TIF_USEDFPU))
-		regs->psr &= ~PSR_EF;
-#else
-	if (current == last_task_used_math) {
-		last_task_used_math = NULL;
-		regs->psr &= ~PSR_EF;
-	}
-#endif
-	set_used_math();
-	clear_tsk_thread_flag(current, TIF_USEDFPU);
-
-	if (!access_ok(VERIFY_READ, fpu, sizeof(*fpu)))
-		return -EFAULT;
-
-	err = __copy_from_user(&current->thread.float_regs[0], &fpu->si_float_regs[0],
-			       (sizeof(unsigned long) * 32));
-	err |= __get_user(current->thread.fsr, &fpu->si_fsr);
-	err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
-	if (current->thread.fpqdepth != 0)
-		err |= __copy_from_user(&current->thread.fpqueue[0],
-					&fpu->si_fpqueue[0],
-					((sizeof(unsigned long) +
-					(sizeof(unsigned long *)))*16));
-	return err;
-}
-
 asmlinkage void do_sigreturn(struct pt_regs *regs)
 {
 	struct signal_frame __user *sf;
 	unsigned long up_psr, pc, npc;
 	sigset_t set;
 	__siginfo_fpu_t __user *fpu_save;
+	__siginfo_rwin_t __user *rwin_save;
 	int err;
 
 	/* Always make any pending restarted system calls return -EINTR */
@@ -150,9 +122,11 @@ asmlinkage void do_sigreturn(struct pt_r
 	pt_regs_clear_syscall(regs);
 
 	err |= __get_user(fpu_save, &sf->fpu_save);
-
 	if (fpu_save)
 		err |= restore_fpu_state(regs, fpu_save);
+	err |= __get_user(rwin_save, &sf->rwin_save);
+	if (rwin_save)
+		err |= restore_rwin_state(rwin_save);
 
 	/* This is pretty much atomic, no amount locking would prevent
 	 * the races which exist anyways.
@@ -180,6 +154,7 @@ asmlinkage void do_rt_sigreturn(struct p
 	struct rt_signal_frame __user *sf;
 	unsigned int psr, pc, npc;
 	__siginfo_fpu_t __user *fpu_save;
+	__siginfo_rwin_t __user *rwin_save;
 	mm_segment_t old_fs;
 	sigset_t set;
 	stack_t st;
@@ -207,8 +182,7 @@ asmlinkage void do_rt_sigreturn(struct p
 	pt_regs_clear_syscall(regs);
 
 	err |= __get_user(fpu_save, &sf->fpu_save);
-
-	if (fpu_save)
+	if (!err && fpu_save)
 		err |= restore_fpu_state(regs, fpu_save);
 	err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
 	
@@ -228,6 +202,12 @@ asmlinkage void do_rt_sigreturn(struct p
 	do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf);
 	set_fs(old_fs);
 
+	err |= __get_user(rwin_save, &sf->rwin_save);
+	if (!err && rwin_save) {
+		if (restore_rwin_state(rwin_save))
+			goto segv;
+	}
+
 	sigdelsetmask(&set, ~_BLOCKABLE);
 	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
@@ -280,53 +260,23 @@ static inline void __user *get_sigframe(
 	return (void __user *) sp;
 }
 
-static inline int
-save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
-{
-	int err = 0;
-#ifdef CONFIG_SMP
-	if (test_tsk_thread_flag(current, TIF_USEDFPU)) {
-		put_psr(get_psr() | PSR_EF);
-		fpsave(&current->thread.float_regs[0], &current->thread.fsr,
-		       &current->thread.fpqueue[0], &current->thread.fpqdepth);
-		regs->psr &= ~(PSR_EF);
-		clear_tsk_thread_flag(current, TIF_USEDFPU);
-	}
-#else
-	if (current == last_task_used_math) {
-		put_psr(get_psr() | PSR_EF);
-		fpsave(&current->thread.float_regs[0], &current->thread.fsr,
-		       &current->thread.fpqueue[0], &current->thread.fpqdepth);
-		last_task_used_math = NULL;
-		regs->psr &= ~(PSR_EF);
-	}
-#endif
-	err |= __copy_to_user(&fpu->si_float_regs[0],
-			      &current->thread.float_regs[0],
-			      (sizeof(unsigned long) * 32));
-	err |= __put_user(current->thread.fsr, &fpu->si_fsr);
-	err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
-	if (current->thread.fpqdepth != 0)
-		err |= __copy_to_user(&fpu->si_fpqueue[0],
-				      &current->thread.fpqueue[0],
-				      ((sizeof(unsigned long) +
-				      (sizeof(unsigned long *)))*16));
-	clear_used_math();
-	return err;
-}
-
-static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
-			int signo, sigset_t *oldset)
+static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
+		       int signo, sigset_t *oldset)
 {
 	struct signal_frame __user *sf;
-	int sigframe_size, err;
+	int sigframe_size, err, wsaved;
+	void __user *tail;
 
 	/* 1. Make sure everything is clean */
 	synchronize_user_stack();
 
-	sigframe_size = SF_ALIGNEDSZ;
-	if (!used_math())
-		sigframe_size -= sizeof(__siginfo_fpu_t);
+	wsaved = current_thread_info()->w_saved;
+
+	sigframe_size = sizeof(*sf);
+	if (used_math())
+		sigframe_size += sizeof(__siginfo_fpu_t);
+	if (wsaved)
+		sigframe_size += sizeof(__siginfo_rwin_t);
 
 	sf = (struct signal_frame __user *)
 		get_sigframe(&ka->sa, regs, sigframe_size);
@@ -334,8 +284,7 @@ static void setup_frame(struct k_sigacti
 	if (invalid_frame_pointer(sf, sigframe_size))
 		goto sigill_and_return;
 
-	if (current_thread_info()->w_saved != 0)
-		goto sigill_and_return;
+	tail = sf + 1;
 
 	/* 2. Save the current process state */
 	err = __copy_to_user(&sf->info.si_regs, regs, sizeof(struct pt_regs));
@@ -343,17 +292,34 @@ static void setup_frame(struct k_sigacti
 	err |= __put_user(0, &sf->extra_size);
 
 	if (used_math()) {
-		err |= save_fpu_state(regs, &sf->fpu_state);
-		err |= __put_user(&sf->fpu_state, &sf->fpu_save);
+		__siginfo_fpu_t __user *fp = tail;
+		tail += sizeof(*fp);
+		err |= save_fpu_state(regs, fp);
+		err |= __put_user(fp, &sf->fpu_save);
 	} else {
 		err |= __put_user(0, &sf->fpu_save);
 	}
+	if (wsaved) {
+		__siginfo_rwin_t __user *rwp = tail;
+		tail += sizeof(*rwp);
+		err |= save_rwin_state(wsaved, rwp);
+		err |= __put_user(rwp, &sf->rwin_save);
+	} else {
+		err |= __put_user(0, &sf->rwin_save);
+	}
 
 	err |= __put_user(oldset->sig[0], &sf->info.si_mask);
 	err |= __copy_to_user(sf->extramask, &oldset->sig[1],
 			      (_NSIG_WORDS - 1) * sizeof(unsigned int));
-	err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
-			      sizeof(struct reg_window32));
+	if (!wsaved) {
+		err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
+				      sizeof(struct reg_window32));
+	} else {
+		struct reg_window32 *rp;
+
+		rp = &current_thread_info()->reg_window[wsaved - 1];
+		err |= __copy_to_user(sf, rp, sizeof(struct reg_window32));
+	}
 	if (err)
 		goto sigsegv;
 	
@@ -384,33 +350,39 @@ static void setup_frame(struct k_sigacti
 		/* Flush instruction space. */
 		flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
 	}
-	return;
+	return 0;
 
 sigill_and_return:
 	do_exit(SIGILL);
+	return -EINVAL;
+
 sigsegv:
 	force_sigsegv(signo, current);
+	return -EFAULT;
 }
 
-static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
-			   int signo, sigset_t *oldset, siginfo_t *info)
+static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
+			  int signo, sigset_t *oldset, siginfo_t *info)
 {
 	struct rt_signal_frame __user *sf;
-	int sigframe_size;
+	int sigframe_size, wsaved;
+	void __user *tail;
 	unsigned int psr;
 	int err;
 
 	synchronize_user_stack();
-	sigframe_size = RT_ALIGNEDSZ;
-	if (!used_math())
-		sigframe_size -= sizeof(__siginfo_fpu_t);
+	wsaved = current_thread_info()->w_saved;
+	sigframe_size = sizeof(*sf);
+	if (used_math())
+		sigframe_size += sizeof(__siginfo_fpu_t);
+	if (wsaved)
+		sigframe_size += sizeof(__siginfo_rwin_t);
 	sf = (struct rt_signal_frame __user *)
 		get_sigframe(&ka->sa, regs, sigframe_size);
 	if (invalid_frame_pointer(sf, sigframe_size))
 		goto sigill;
-	if (current_thread_info()->w_saved != 0)
-		goto sigill;
 
+	tail = sf + 1;
 	err  = __put_user(regs->pc, &sf->regs.pc);
 	err |= __put_user(regs->npc, &sf->regs.npc);
 	err |= __put_user(regs->y, &sf->regs.y);
@@ -422,11 +394,21 @@ static void setup_rt_frame(struct k_siga
 	err |= __put_user(0, &sf->extra_size);
 
 	if (psr & PSR_EF) {
-		err |= save_fpu_state(regs, &sf->fpu_state);
-		err |= __put_user(&sf->fpu_state, &sf->fpu_save);
+		__siginfo_fpu_t *fp = tail;
+		tail += sizeof(*fp);
+		err |= save_fpu_state(regs, fp);
+		err |= __put_user(fp, &sf->fpu_save);
 	} else {
 		err |= __put_user(0, &sf->fpu_save);
 	}
+	if (wsaved) {
+		__siginfo_rwin_t *rwp = tail;
+		tail += sizeof(*rwp);
+		err |= save_rwin_state(wsaved, rwp);
+		err |= __put_user(rwp, &sf->rwin_save);
+	} else {
+		err |= __put_user(0, &sf->rwin_save);
+	}
 	err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));
 	
 	/* Setup sigaltstack */
@@ -434,8 +416,15 @@ static void setup_rt_frame(struct k_siga
 	err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
 	err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
 	
-	err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
-			      sizeof(struct reg_window32));
+	if (!wsaved) {
+		err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
+				      sizeof(struct reg_window32));
+	} else {
+		struct reg_window32 *rp;
+
+		rp = &current_thread_info()->reg_window[wsaved - 1];
+		err |= __copy_to_user(sf, rp, sizeof(struct reg_window32));
+	}
 
 	err |= copy_siginfo_to_user(&sf->info, info);
 
@@ -466,22 +455,30 @@ static void setup_rt_frame(struct k_siga
 		/* Flush instruction space. */
 		flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
 	}
-	return;
+	return 0;
 
 sigill:
 	do_exit(SIGILL);
+	return -EINVAL;
+
 sigsegv:
 	force_sigsegv(signo, current);
+	return -EFAULT;
 }
 
-static inline void
+static inline int
 handle_signal(unsigned long signr, struct k_sigaction *ka,
 	      siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
 {
+	int err;
+
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame(ka, regs, signr, oldset, info);
+		err = setup_rt_frame(ka, regs, signr, oldset, info);
 	else
-		setup_frame(ka, regs, signr, oldset);
+		err = setup_frame(ka, regs, signr, oldset);
+
+	if (err)
+		return err;
 
 	spin_lock_irq(&current->sighand->siglock);
 	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -489,6 +486,10 @@ handle_signal(unsigned long signr, struc
 		sigaddset(&current->blocked, signr);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
+
+	tracehook_signal_handler(signr, info, ka, regs, 0);
+
+	return 0;
 }
 
 static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
@@ -546,17 +547,15 @@ static void do_signal(struct pt_regs *re
 	if (signr > 0) {
 		if (restart_syscall)
 			syscall_restart(orig_i0, regs, &ka.sa);
-		handle_signal(signr, &ka, &info, oldset, regs);
-
-		/* a signal was successfully delivered; the saved
-		 * sigmask will have been stored in the signal frame,
-		 * and will be restored by sigreturn, so we can simply
-		 * clear the TIF_RESTORE_SIGMASK flag.
-		 */
-		if (test_thread_flag(TIF_RESTORE_SIGMASK))
-			clear_thread_flag(TIF_RESTORE_SIGMASK);
-
-		tracehook_signal_handler(signr, &info, &ka, regs, 0);
+		if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
+			/* a signal was successfully delivered; the saved
+			 * sigmask will have been stored in the signal frame,
+			 * and will be restored by sigreturn, so we can simply
+			 * clear the TIF_RESTORE_SIGMASK flag.
+			 */
+			if (test_thread_flag(TIF_RESTORE_SIGMASK))
+				clear_thread_flag(TIF_RESTORE_SIGMASK);
+		}
 		return;
 	}
 	if (restart_syscall &&
@@ -567,12 +566,14 @@ static void do_signal(struct pt_regs *re
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->pc -= 4;
 		regs->npc -= 4;
+		pt_regs_clear_syscall(regs);
 	}
 	if (restart_syscall &&
 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->pc -= 4;
 		regs->npc -= 4;
+		pt_regs_clear_syscall(regs);
 	}
 
 	/* if there's no signal to deliver, we just put the saved sigmask
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/kernel/signal32.c linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/signal32.c
--- linux-libre-2.6.34-gnu1/arch/sparc/kernel/signal32.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/signal32.c	2014-02-10 17:31:40.000000000 -0500
@@ -29,6 +29,8 @@
 #include <asm/visasm.h>
 #include <asm/compat_signal.h>
 
+#include "sigutil.h"
+
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 /* This magic should be in g_upper[0] for all upper parts
@@ -44,14 +46,14 @@ typedef struct {
 struct signal_frame32 {
 	struct sparc_stackf32	ss;
 	__siginfo32_t		info;
-	/* __siginfo_fpu32_t * */ u32 fpu_save;
+	/* __siginfo_fpu_t * */ u32 fpu_save;
 	unsigned int		insns[2];
 	unsigned int		extramask[_COMPAT_NSIG_WORDS - 1];
 	unsigned int		extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
 	/* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
 	siginfo_extra_v8plus_t	v8plus;
-	__siginfo_fpu_t		fpu_state;
-};
+	/* __siginfo_rwin_t * */u32 rwin_save;
+} __attribute__((aligned(8)));
 
 typedef struct compat_siginfo{
 	int si_signo;
@@ -110,18 +112,14 @@ struct rt_signal_frame32 {
 	compat_siginfo_t	info;
 	struct pt_regs32	regs;
 	compat_sigset_t		mask;
-	/* __siginfo_fpu32_t * */ u32 fpu_save;
+	/* __siginfo_fpu_t * */ u32 fpu_save;
 	unsigned int		insns[2];
 	stack_t32		stack;
 	unsigned int		extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
 	/* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
 	siginfo_extra_v8plus_t	v8plus;
-	__siginfo_fpu_t		fpu_state;
-};
-
-/* Align macros */
-#define SF_ALIGNEDSZ  (((sizeof(struct signal_frame32) + 15) & (~15)))
-#define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame32) + 15) & (~15)))
+	/* __siginfo_rwin_t * */u32 rwin_save;
+} __attribute__((aligned(8)));
 
 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 {
@@ -192,30 +190,13 @@ int copy_siginfo_from_user32(siginfo_t *
 	return 0;
 }
 
-static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
-{
-	unsigned long *fpregs = current_thread_info()->fpregs;
-	unsigned long fprs;
-	int err;
-	
-	err = __get_user(fprs, &fpu->si_fprs);
-	fprs_write(0);
-	regs->tstate &= ~TSTATE_PEF;
-	if (fprs & FPRS_DL)
-		err |= copy_from_user(fpregs, &fpu->si_float_regs[0], (sizeof(unsigned int) * 32));
-	if (fprs & FPRS_DU)
-		err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], (sizeof(unsigned int) * 32));
-	err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
-	err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
-	current_thread_info()->fpsaved[0] |= fprs;
-	return err;
-}
-
 void do_sigreturn32(struct pt_regs *regs)
 {
 	struct signal_frame32 __user *sf;
+	compat_uptr_t fpu_save;
+	compat_uptr_t rwin_save;
 	unsigned int psr;
-	unsigned pc, npc, fpu_save;
+	unsigned pc, npc;
 	sigset_t set;
 	unsigned seta[_COMPAT_NSIG_WORDS];
 	int err, i;
@@ -273,8 +254,13 @@ void do_sigreturn32(struct pt_regs *regs
 	pt_regs_clear_syscall(regs);
 
 	err |= __get_user(fpu_save, &sf->fpu_save);
-	if (fpu_save)
-		err |= restore_fpu_state32(regs, &sf->fpu_state);
+	if (!err && fpu_save)
+		err |= restore_fpu_state(regs, compat_ptr(fpu_save));
+	err |= __get_user(rwin_save, &sf->rwin_save);
+	if (!err && rwin_save) {
+		if (restore_rwin_state(compat_ptr(rwin_save)))
+			goto segv;
+	}
 	err |= __get_user(seta[0], &sf->info.si_mask);
 	err |= copy_from_user(seta+1, &sf->extramask,
 			      (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
@@ -300,7 +286,9 @@ segv:
 asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
 {
 	struct rt_signal_frame32 __user *sf;
-	unsigned int psr, pc, npc, fpu_save, u_ss_sp;
+	unsigned int psr, pc, npc, u_ss_sp;
+	compat_uptr_t fpu_save;
+	compat_uptr_t rwin_save;
 	mm_segment_t old_fs;
 	sigset_t set;
 	compat_sigset_t seta;
@@ -359,8 +347,8 @@ asmlinkage void do_rt_sigreturn32(struct
 	pt_regs_clear_syscall(regs);
 
 	err |= __get_user(fpu_save, &sf->fpu_save);
-	if (fpu_save)
-		err |= restore_fpu_state32(regs, &sf->fpu_state);
+	if (!err && fpu_save)
+		err |= restore_fpu_state(regs, compat_ptr(fpu_save));
 	err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
 	err |= __get_user(u_ss_sp, &sf->stack.ss_sp);
 	st.ss_sp = compat_ptr(u_ss_sp);
@@ -376,6 +364,12 @@ asmlinkage void do_rt_sigreturn32(struct
 	do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf);
 	set_fs(old_fs);
 	
+	err |= __get_user(rwin_save, &sf->rwin_save);
+	if (!err && rwin_save) {
+		if (restore_rwin_state(compat_ptr(rwin_save)))
+			goto segv;
+	}
+
 	switch (_NSIG_WORDS) {
 		case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32);
 		case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32);
@@ -433,42 +427,85 @@ static void __user *get_sigframe(struct
 	return (void __user *) sp;
 }
 
-static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
+/* The I-cache flush instruction only works in the primary ASI, which
+ * right now is the nucleus, aka. kernel space.
+ *
+ * Therefore we have to kick the instructions out using the kernel
+ * side linear mapping of the physical address backing the user
+ * instructions.
+ */
+static void flush_signal_insns(unsigned long address)
 {
-	unsigned long *fpregs = current_thread_info()->fpregs;
-	unsigned long fprs;
-	int err = 0;
-	
-	fprs = current_thread_info()->fpsaved[0];
-	if (fprs & FPRS_DL)
-		err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
-				    (sizeof(unsigned int) * 32));
-	if (fprs & FPRS_DU)
-		err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
-				    (sizeof(unsigned int) * 32));
-	err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
-	err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
-	err |= __put_user(fprs, &fpu->si_fprs);
+	unsigned long pstate, paddr;
+	pte_t *ptep, pte;
+	pgd_t *pgdp;
+	pud_t *pudp;
+	pmd_t *pmdp;
+
+	/* Commit all stores of the instructions we are about to flush.  */
+	wmb();
+
+	/* Disable cross-call reception.  In this way even a very wide
+	 * munmap() on another cpu can't tear down the page table
+	 * hierarchy from underneath us, since that can't complete
+	 * until the IPI tlb flush returns.
+	 */
+
+	__asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
+	__asm__ __volatile__("wrpr %0, %1, %%pstate"
+				: : "r" (pstate), "i" (PSTATE_IE));
+
+	pgdp = pgd_offset(current->mm, address);
+	if (pgd_none(*pgdp))
+		goto out_irqs_on;
+	pudp = pud_offset(pgdp, address);
+	if (pud_none(*pudp))
+		goto out_irqs_on;
+	pmdp = pmd_offset(pudp, address);
+	if (pmd_none(*pmdp))
+		goto out_irqs_on;
+
+	ptep = pte_offset_map(pmdp, address);
+	pte = *ptep;
+	if (!pte_present(pte))
+		goto out_unmap;
+
+	paddr = (unsigned long) page_address(pte_page(pte));
+
+	__asm__ __volatile__("flush	%0 + %1"
+			     : /* no outputs */
+			     : "r" (paddr),
+			       "r" (address & (PAGE_SIZE - 1))
+			     : "memory");
+
+out_unmap:
+	pte_unmap(ptep);
+out_irqs_on:
+	__asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
 
-	return err;
 }
 
-static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
-			  int signo, sigset_t *oldset)
+static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
+			 int signo, sigset_t *oldset)
 {
 	struct signal_frame32 __user *sf;
+	int i, err, wsaved;
+	void __user *tail;
 	int sigframe_size;
 	u32 psr;
-	int i, err;
 	unsigned int seta[_COMPAT_NSIG_WORDS];
 
 	/* 1. Make sure everything is clean */
 	synchronize_user_stack();
 	save_and_clear_fpu();
 	
-	sigframe_size = SF_ALIGNEDSZ;
-	if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
-		sigframe_size -= sizeof(__siginfo_fpu_t);
+	wsaved = get_thread_wsaved();
+
+	sigframe_size = sizeof(*sf);
+	if (current_thread_info()->fpsaved[0] & FPRS_FEF)
+		sigframe_size += sizeof(__siginfo_fpu_t);
+	if (wsaved)
+		sigframe_size += sizeof(__siginfo_rwin_t);
 
 	sf = (struct signal_frame32 __user *)
 		get_sigframe(&ka->sa, regs, sigframe_size);
@@ -476,8 +513,7 @@ static void setup_frame32(struct k_sigac
 	if (invalid_frame_pointer(sf, sigframe_size))
 		goto sigill;
 
-	if (get_thread_wsaved() != 0)
-		goto sigill;
+	tail = (sf + 1);
 
 	/* 2. Save the current process state */
 	if (test_thread_flag(TIF_32BIT)) {
@@ -502,11 +538,22 @@ static void setup_frame32(struct k_sigac
 			  &sf->v8plus.asi);
 
 	if (psr & PSR_EF) {
-		err |= save_fpu_state32(regs, &sf->fpu_state);
-		err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
+		__siginfo_fpu_t __user *fp = tail;
+		tail += sizeof(*fp);
+		err |= save_fpu_state(regs, fp);
+		err |= __put_user((u64)fp, &sf->fpu_save);
 	} else {
 		err |= __put_user(0, &sf->fpu_save);
 	}
+	if (wsaved) {
+		__siginfo_rwin_t __user *rwp = tail;
+		tail += sizeof(*rwp);
+		err |= save_rwin_state(wsaved, rwp);
+		err |= __put_user((u64)rwp, &sf->rwin_save);
+		set_thread_wsaved(0);
+	} else {
+		err |= __put_user(0, &sf->rwin_save);
+	}
 
 	switch (_NSIG_WORDS) {
 	case 4: seta[7] = (oldset->sig[3] >> 32);
@@ -522,10 +569,21 @@ static void setup_frame32(struct k_sigac
 	err |= __copy_to_user(sf->extramask, seta + 1,
 			      (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
 
-	err |= copy_in_user((u32 __user *)sf,
-			    (u32 __user *)(regs->u_regs[UREG_FP]),
-			    sizeof(struct reg_window32));
-	
+	if (!wsaved) {
+		err |= copy_in_user((u32 __user *)sf,
+				    (u32 __user *)(regs->u_regs[UREG_FP]),
+				    sizeof(struct reg_window32));
+	} else {
+		struct reg_window *rp;
+
+		rp = &current_thread_info()->reg_window[wsaved - 1];
+		for (i = 0; i < 8; i++)
+			err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
+		for (i = 0; i < 6; i++)
+			err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
+		err |= __put_user(rp->ins[6], &sf->ss.fp);
+		err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
+	}
 	if (err)
 		goto sigsegv;
 
@@ -547,13 +605,7 @@ static void setup_frame32(struct k_sigac
 	if (ka->ka_restorer) {
 		regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
 	} else {
-		/* Flush instruction space. */
 		unsigned long address = ((unsigned long)&(sf->insns[0]));
-		pgd_t *pgdp = pgd_offset(current->mm, address);
-		pud_t *pudp = pud_offset(pgdp, address);
-		pmd_t *pmdp = pmd_offset(pudp, address);
-		pte_t *ptep;
-		pte_t pte;
 
 		regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
 	
@@ -561,49 +613,41 @@ static void setup_frame32(struct k_sigac
 		err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
 		if (err)
 			goto sigsegv;
-
-		preempt_disable();
-		ptep = pte_offset_map(pmdp, address);
-		pte = *ptep;
-		if (pte_present(pte)) {
-			unsigned long page = (unsigned long)
-				page_address(pte_page(pte));
-
-			wmb();
-			__asm__ __volatile__("flush	%0 + %1"
-					     : /* no outputs */
-					     : "r" (page),
-					       "r" (address & (PAGE_SIZE - 1))
-					     : "memory");
-		}
-		pte_unmap(ptep);
-		preempt_enable();
+		flush_signal_insns(address);
 	}
-	return;
+	return 0;
 
 sigill:
 	do_exit(SIGILL);
+	return -EINVAL;
+
 sigsegv:
 	force_sigsegv(signo, current);
+	return -EFAULT;
 }
 
-static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
-			     unsigned long signr, sigset_t *oldset,
-			     siginfo_t *info)
+static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
+			    unsigned long signr, sigset_t *oldset,
+			    siginfo_t *info)
 {
 	struct rt_signal_frame32 __user *sf;
+	int i, err, wsaved;
+	void __user *tail;
 	int sigframe_size;
 	u32 psr;
-	int i, err;
 	compat_sigset_t seta;
 
 	/* 1. Make sure everything is clean */
 	synchronize_user_stack();
 	save_and_clear_fpu();
 	
-	sigframe_size = RT_ALIGNEDSZ;
-	if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
-		sigframe_size -= sizeof(__siginfo_fpu_t);
+	wsaved = get_thread_wsaved();
+
+	sigframe_size = sizeof(*sf);
+	if (current_thread_info()->fpsaved[0] & FPRS_FEF)
+		sigframe_size += sizeof(__siginfo_fpu_t);
+	if (wsaved)
+		sigframe_size += sizeof(__siginfo_rwin_t);
 
 	sf = (struct rt_signal_frame32 __user *)
 		get_sigframe(&ka->sa, regs, sigframe_size);
@@ -611,8 +655,7 @@ static void setup_rt_frame32(struct k_si
 	if (invalid_frame_pointer(sf, sigframe_size))
 		goto sigill;
 
-	if (get_thread_wsaved() != 0)
-		goto sigill;
+	tail = (sf + 1);
 
 	/* 2. Save the current process state */
 	if (test_thread_flag(TIF_32BIT)) {
@@ -637,11 +680,22 @@ static void setup_rt_frame32(struct k_si
 			  &sf->v8plus.asi);
 
 	if (psr & PSR_EF) {
-		err |= save_fpu_state32(regs, &sf->fpu_state);
-		err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
+		__siginfo_fpu_t __user *fp = tail;
+		tail += sizeof(*fp);
+		err |= save_fpu_state(regs, fp);
+		err |= __put_user((u64)fp, &sf->fpu_save);
 	} else {
 		err |= __put_user(0, &sf->fpu_save);
 	}
+	if (wsaved) {
+		__siginfo_rwin_t __user *rwp = tail;
+		tail += sizeof(*rwp);
+		err |= save_rwin_state(wsaved, rwp);
+		err |= __put_user((u64)rwp, &sf->rwin_save);
+		set_thread_wsaved(0);
+	} else {
+		err |= __put_user(0, &sf->rwin_save);
+	}
 
 	/* Update the siginfo structure.  */
 	err |= copy_siginfo_to_user32(&sf->info, info);
@@ -663,9 +717,21 @@ static void setup_rt_frame32(struct k_si
 	}
 	err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
 
-	err |= copy_in_user((u32 __user *)sf,
-			    (u32 __user *)(regs->u_regs[UREG_FP]),
-			    sizeof(struct reg_window32));
+	if (!wsaved) {
+		err |= copy_in_user((u32 __user *)sf,
+				    (u32 __user *)(regs->u_regs[UREG_FP]),
+				    sizeof(struct reg_window32));
+	} else {
+		struct reg_window *rp;
+
+		rp = &current_thread_info()->reg_window[wsaved - 1];
+		for (i = 0; i < 8; i++)
+			err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
+		for (i = 0; i < 6; i++)
+			err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
+		err |= __put_user(rp->ins[6], &sf->ss.fp);
+		err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
+	}
 	if (err)
 		goto sigsegv;
 	
@@ -687,12 +753,7 @@ static void setup_rt_frame32(struct k_si
 	if (ka->ka_restorer)
 		regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
 	else {
-		/* Flush instruction space. */
 		unsigned long address = ((unsigned long)&(sf->insns[0]));
-		pgd_t *pgdp = pgd_offset(current->mm, address);
-		pud_t *pudp = pud_offset(pgdp, address);
-		pmd_t *pmdp = pmd_offset(pudp, address);
-		pte_t *ptep;
 
 		regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
 	
@@ -704,38 +765,32 @@ static void setup_rt_frame32(struct k_si
 		if (err)
 			goto sigsegv;
 
-		preempt_disable();
-		ptep = pte_offset_map(pmdp, address);
-		if (pte_present(*ptep)) {
-			unsigned long page = (unsigned long)
-				page_address(pte_page(*ptep));
-
-			wmb();
-			__asm__ __volatile__("flush	%0 + %1"
-					     : /* no outputs */
-					     : "r" (page),
-					       "r" (address & (PAGE_SIZE - 1))
-					     : "memory");
-		}
-		pte_unmap(ptep);
-		preempt_enable();
+		flush_signal_insns(address);
 	}
-	return;
+	return 0;
 
 sigill:
 	do_exit(SIGILL);
+	return -EINVAL;
+
 sigsegv:
 	force_sigsegv(signr, current);
+	return -EFAULT;
 }
 
-static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
-				   siginfo_t *info,
-				   sigset_t *oldset, struct pt_regs *regs)
+static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
+				  siginfo_t *info,
+				  sigset_t *oldset, struct pt_regs *regs)
 {
+	int err;
+
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame32(ka, regs, signr, oldset, info);
+		err = setup_rt_frame32(ka, regs, signr, oldset, info);
 	else
-		setup_frame32(ka, regs, signr, oldset);
+		err = setup_frame32(ka, regs, signr, oldset);
+
+	if (err)
+		return err;
 
 	spin_lock_irq(&current->sighand->siglock);
 	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -743,6 +798,10 @@ static inline void handle_signal32(unsig
 		sigaddset(&current->blocked,signr);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
+
+	tracehook_signal_handler(signr, info, ka, regs, 0);
+
+	return 0;
 }
 
 static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
@@ -789,16 +848,14 @@ void do_signal32(sigset_t *oldset, struc
 	if (signr > 0) {
 		if (restart_syscall)
 			syscall_restart32(orig_i0, regs, &ka.sa);
-		handle_signal32(signr, &ka, &info, oldset, regs);
-
-		/* A signal was successfully delivered; the saved
-		 * sigmask will have been stored in the signal frame,
-		 * and will be restored by sigreturn, so we can simply
-		 * clear the TS_RESTORE_SIGMASK flag.
-		 */
-		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
-
-		tracehook_signal_handler(signr, &info, &ka, regs, 0);
+		if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) {
+			/* A signal was successfully delivered; the saved
+			 * sigmask will have been stored in the signal frame,
+			 * and will be restored by sigreturn, so we can simply
+			 * clear the TS_RESTORE_SIGMASK flag.
+			 */
+			current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+		}
 		return;
 	}
 	if (restart_syscall &&
@@ -809,12 +866,14 @@ void do_signal32(sigset_t *oldset, struc
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
+		pt_regs_clear_syscall(regs);
 	}
 	if (restart_syscall &&
 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
+		pt_regs_clear_syscall(regs);
 	}
 
 	/* If there's no signal to deliver, we just put the saved sigmask
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/kernel/signal_64.c linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/signal_64.c
--- linux-libre-2.6.34-gnu1/arch/sparc/kernel/signal_64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/signal_64.c	2014-02-10 17:31:40.000000000 -0500
@@ -34,6 +34,7 @@
 
 #include "entry.h"
 #include "systbls.h"
+#include "sigutil.h"
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
@@ -236,7 +237,7 @@ struct rt_signal_frame {
 	__siginfo_fpu_t __user	*fpu_save;
 	stack_t			stack;
 	sigset_t		mask;
-	__siginfo_fpu_t		fpu_state;
+	__siginfo_rwin_t	*rwin_save;
 };
 
 static long _sigpause_common(old_sigset_t set)
@@ -266,33 +267,12 @@ asmlinkage long sys_sigsuspend(old_sigse
 	return _sigpause_common(set);
 }
 
-static inline int
-restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
-{
-	unsigned long *fpregs = current_thread_info()->fpregs;
-	unsigned long fprs;
-	int err;
-
-	err = __get_user(fprs, &fpu->si_fprs);
-	fprs_write(0);
-	regs->tstate &= ~TSTATE_PEF;
-	if (fprs & FPRS_DL)
-		err |= copy_from_user(fpregs, &fpu->si_float_regs[0],
-		       	       (sizeof(unsigned int) * 32));
-	if (fprs & FPRS_DU)
-		err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32],
-		       	       (sizeof(unsigned int) * 32));
-	err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
-	err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
-	current_thread_info()->fpsaved[0] |= fprs;
-	return err;
-}
-
 void do_rt_sigreturn(struct pt_regs *regs)
 {
 	struct rt_signal_frame __user *sf;
 	unsigned long tpc, tnpc, tstate;
 	__siginfo_fpu_t __user *fpu_save;
+	__siginfo_rwin_t __user *rwin_save;
 	sigset_t set;
 	int err;
 
@@ -325,8 +305,8 @@ void do_rt_sigreturn(struct pt_regs *reg
 	regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));
 
 	err |= __get_user(fpu_save, &sf->fpu_save);
-	if (fpu_save)
-		err |= restore_fpu_state(regs, &sf->fpu_state);
+	if (!err && fpu_save)
+		err |= restore_fpu_state(regs, fpu_save);
 
 	err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
 	err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf);
@@ -334,6 +314,12 @@ void do_rt_sigreturn(struct pt_regs *reg
 	if (err)
 		goto segv;
 
+	err |= __get_user(rwin_save, &sf->rwin_save);
+	if (!err && rwin_save) {
+		if (restore_rwin_state(rwin_save))
+			goto segv;
+	}
+
 	regs->tpc = tpc;
 	regs->tnpc = tnpc;
 
@@ -351,34 +337,13 @@ segv:
 }
 
 /* Checks if the fp is valid */
-static int invalid_frame_pointer(void __user *fp, int fplen)
+static int invalid_frame_pointer(void __user *fp)
 {
 	if (((unsigned long) fp) & 15)
 		return 1;
 	return 0;
 }
 
-static inline int
-save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
-{
-	unsigned long *fpregs = current_thread_info()->fpregs;
-	unsigned long fprs;
-	int err = 0;
-	
-	fprs = current_thread_info()->fpsaved[0];
-	if (fprs & FPRS_DL)
-		err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
-				    (sizeof(unsigned int) * 32));
-	if (fprs & FPRS_DU)
-		err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
-				    (sizeof(unsigned int) * 32));
-	err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
-	err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
-	err |= __put_user(fprs, &fpu->si_fprs);
-
-	return err;
-}
-
 static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
 {
 	unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
@@ -409,39 +374,53 @@ static inline void __user *get_sigframe(
 	return (void __user *) sp;
 }
 
-static inline void
+static inline int
 setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
 	       int signo, sigset_t *oldset, siginfo_t *info)
 {
 	struct rt_signal_frame __user *sf;
-	int sigframe_size, err;
+	int wsaved, err, sf_size;
+	void __user *tail;
 
 	/* 1. Make sure everything is clean */
 	synchronize_user_stack();
 	save_and_clear_fpu();
 	
-	sigframe_size = sizeof(struct rt_signal_frame);
-	if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
-		sigframe_size -= sizeof(__siginfo_fpu_t);
+	wsaved = get_thread_wsaved();
 
+	sf_size = sizeof(struct rt_signal_frame);
+	if (current_thread_info()->fpsaved[0] & FPRS_FEF)
+		sf_size += sizeof(__siginfo_fpu_t);
+	if (wsaved)
+		sf_size += sizeof(__siginfo_rwin_t);
 	sf = (struct rt_signal_frame __user *)
-		get_sigframe(ka, regs, sigframe_size);
-	
-	if (invalid_frame_pointer (sf, sigframe_size))
-		goto sigill;
+		get_sigframe(ka, regs, sf_size);
 
-	if (get_thread_wsaved() != 0)
+	if (invalid_frame_pointer (sf))
 		goto sigill;
 
+	tail = (sf + 1);
+
 	/* 2. Save the current process state */
 	err = copy_to_user(&sf->regs, regs, sizeof (*regs));
 
 	if (current_thread_info()->fpsaved[0] & FPRS_FEF) {
-		err |= save_fpu_state(regs, &sf->fpu_state);
-		err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
+		__siginfo_fpu_t __user *fpu_save = tail;
+		tail += sizeof(__siginfo_fpu_t);
+		err |= save_fpu_state(regs, fpu_save);
+		err |= __put_user((u64)fpu_save, &sf->fpu_save);
 	} else {
 		err |= __put_user(0, &sf->fpu_save);
 	}
+	if (wsaved) {
+		__siginfo_rwin_t __user *rwin_save = tail;
+		tail += sizeof(__siginfo_rwin_t);
+		err |= save_rwin_state(wsaved, rwin_save);
+		err |= __put_user((u64)rwin_save, &sf->rwin_save);
+		set_thread_wsaved(0);
+	} else {
+		err |= __put_user(0, &sf->rwin_save);
+	}
 	
 	/* Setup sigaltstack */
 	err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
@@ -450,10 +429,17 @@ setup_rt_frame(struct k_sigaction *ka, s
 
 	err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t));
 
-	err |= copy_in_user((u64 __user *)sf,
-			    (u64 __user *)(regs->u_regs[UREG_FP]+STACK_BIAS),
-			    sizeof(struct reg_window));
+	if (!wsaved) {
+		err |= copy_in_user((u64 __user *)sf,
+				    (u64 __user *)(regs->u_regs[UREG_FP] +
+						   STACK_BIAS),
+				    sizeof(struct reg_window));
+	} else {
+		struct reg_window *rp;
 
+		rp = &current_thread_info()->reg_window[wsaved - 1];
+		err |= copy_to_user(sf, rp, sizeof(struct reg_window));
+	}
 	if (info)
 		err |= copy_siginfo_to_user(&sf->info, info);
 	else {
@@ -483,26 +469,37 @@ setup_rt_frame(struct k_sigaction *ka, s
 	}
 	/* 4. return to kernel instructions */
 	regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
-	return;
+	return 0;
 
 sigill:
 	do_exit(SIGILL);
+	return -EINVAL;
+
 sigsegv:
 	force_sigsegv(signo, current);
+	return -EFAULT;
 }
 
-static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
-				 siginfo_t *info,
-				 sigset_t *oldset, struct pt_regs *regs)
+static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
+				siginfo_t *info,
+				sigset_t *oldset, struct pt_regs *regs)
 {
-	setup_rt_frame(ka, regs, signr, oldset,
-		       (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
+	int err;
+
+	err = setup_rt_frame(ka, regs, signr, oldset,
+			     (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
+	if (err)
+		return err;
 	spin_lock_irq(&current->sighand->siglock);
 	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 	if (!(ka->sa.sa_flags & SA_NOMASK))
 		sigaddset(&current->blocked,signr);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
+
+	tracehook_signal_handler(signr, info, ka, regs, 0);
+
+	return 0;
 }
 
 static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
@@ -571,16 +568,14 @@ static void do_signal(struct pt_regs *re
 	if (signr > 0) {
 		if (restart_syscall)
 			syscall_restart(orig_i0, regs, &ka.sa);
-		handle_signal(signr, &ka, &info, oldset, regs);
-
-		/* A signal was successfully delivered; the saved
-		 * sigmask will have been stored in the signal frame,
-		 * and will be restored by sigreturn, so we can simply
-		 * clear the TS_RESTORE_SIGMASK flag.
-		 */
-		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
-
-		tracehook_signal_handler(signr, &info, &ka, regs, 0);
+		if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
+			/* A signal was successfully delivered; the saved
+			 * sigmask will have been stored in the signal frame,
+			 * and will be restored by sigreturn, so we can simply
+			 * clear the TS_RESTORE_SIGMASK flag.
+			 */
+			current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+		}
 		return;
 	}
 	if (restart_syscall &&
@@ -591,12 +586,14 @@ static void do_signal(struct pt_regs *re
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
+		pt_regs_clear_syscall(regs);
 	}
 	if (restart_syscall &&
 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
+		pt_regs_clear_syscall(regs);
 	}
 
 	/* If there's no signal to deliver, we just put the saved sigmask
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/kernel/sigutil_32.c linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/sigutil_32.c
--- linux-libre-2.6.34-gnu1/arch/sparc/kernel/sigutil_32.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/sigutil_32.c	2014-02-10 17:31:40.000000000 -0500
@@ -0,0 +1,120 @@
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/thread_info.h>
+#include <linux/uaccess.h>
+#include <linux/sched.h>
+
+#include <asm/sigcontext.h>
+#include <asm/fpumacro.h>
+#include <asm/ptrace.h>
+
+#include "sigutil.h"
+
+int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
+{
+	int err = 0;
+#ifdef CONFIG_SMP
+	if (test_tsk_thread_flag(current, TIF_USEDFPU)) {
+		put_psr(get_psr() | PSR_EF);
+		fpsave(&current->thread.float_regs[0], &current->thread.fsr,
+		       &current->thread.fpqueue[0], &current->thread.fpqdepth);
+		regs->psr &= ~(PSR_EF);
+		clear_tsk_thread_flag(current, TIF_USEDFPU);
+	}
+#else
+	if (current == last_task_used_math) {
+		put_psr(get_psr() | PSR_EF);
+		fpsave(&current->thread.float_regs[0], &current->thread.fsr,
+		       &current->thread.fpqueue[0], &current->thread.fpqdepth);
+		last_task_used_math = NULL;
+		regs->psr &= ~(PSR_EF);
+	}
+#endif
+	err |= __copy_to_user(&fpu->si_float_regs[0],
+			      &current->thread.float_regs[0],
+			      (sizeof(unsigned long) * 32));
+	err |= __put_user(current->thread.fsr, &fpu->si_fsr);
+	err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
+	if (current->thread.fpqdepth != 0)
+		err |= __copy_to_user(&fpu->si_fpqueue[0],
+				      &current->thread.fpqueue[0],
+				      ((sizeof(unsigned long) +
+				      (sizeof(unsigned long *)))*16));
+	clear_used_math();
+	return err;
+}
+
+int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
+{
+	int err;
+#ifdef CONFIG_SMP
+	if (test_tsk_thread_flag(current, TIF_USEDFPU))
+		regs->psr &= ~PSR_EF;
+#else
+	if (current == last_task_used_math) {
+		last_task_used_math = NULL;
+		regs->psr &= ~PSR_EF;
+	}
+#endif
+	set_used_math();
+	clear_tsk_thread_flag(current, TIF_USEDFPU);
+
+	if (!access_ok(VERIFY_READ, fpu, sizeof(*fpu)))
+		return -EFAULT;
+
+	err = __copy_from_user(&current->thread.float_regs[0], &fpu->si_float_regs[0],
+			       (sizeof(unsigned long) * 32));
+	err |= __get_user(current->thread.fsr, &fpu->si_fsr);
+	err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
+	if (current->thread.fpqdepth != 0)
+		err |= __copy_from_user(&current->thread.fpqueue[0],
+					&fpu->si_fpqueue[0],
+					((sizeof(unsigned long) +
+					(sizeof(unsigned long *)))*16));
+	return err;
+}
+
+int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin)
+{
+	int i, err = __put_user(wsaved, &rwin->wsaved);
+
+	for (i = 0; i < wsaved; i++) {
+		struct reg_window32 *rp;
+		unsigned long fp;
+
+		rp = &current_thread_info()->reg_window[i];
+		fp = current_thread_info()->rwbuf_stkptrs[i];
+		err |= copy_to_user(&rwin->reg_window[i], rp,
+				    sizeof(struct reg_window32));
+		err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]);
+	}
+	return err;
+}
+
+int restore_rwin_state(__siginfo_rwin_t __user *rp)
+{
+	struct thread_info *t = current_thread_info();
+	int i, wsaved, err;
+
+	__get_user(wsaved, &rp->wsaved);
+	if (wsaved > NSWINS)
+		return -EFAULT;
+
+	err = 0;
+	for (i = 0; i < wsaved; i++) {
+		err |= copy_from_user(&t->reg_window[i],
+				      &rp->reg_window[i],
+				      sizeof(struct reg_window32));
+		err |= __get_user(t->rwbuf_stkptrs[i],
+				  &rp->rwbuf_stkptrs[i]);
+	}
+	if (err)
+		return err;
+
+	t->w_saved = wsaved;
+	synchronize_user_stack();
+	if (t->w_saved)
+		return -EFAULT;
+	return 0;
+
+}
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/kernel/sigutil_64.c linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/sigutil_64.c
--- linux-libre-2.6.34-gnu1/arch/sparc/kernel/sigutil_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/sigutil_64.c	2014-02-10 17:31:40.000000000 -0500
@@ -0,0 +1,93 @@
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/thread_info.h>
+#include <linux/uaccess.h>
+
+#include <asm/sigcontext.h>
+#include <asm/fpumacro.h>
+#include <asm/ptrace.h>
+
+#include "sigutil.h"
+
+int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
+{
+	unsigned long *fpregs = current_thread_info()->fpregs;
+	unsigned long fprs;
+	int err = 0;
+
+	fprs = current_thread_info()->fpsaved[0];
+	if (fprs & FPRS_DL)
+		err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
+				    (sizeof(unsigned int) * 32));
+	if (fprs & FPRS_DU)
+		err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
+				    (sizeof(unsigned int) * 32));
+	err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
+	err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
+	err |= __put_user(fprs, &fpu->si_fprs);
+
+	return err;
+}
+
+int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
+{
+	unsigned long *fpregs = current_thread_info()->fpregs;
+	unsigned long fprs;
+	int err;
+
+	err = __get_user(fprs, &fpu->si_fprs);
+	fprs_write(0);
+	regs->tstate &= ~TSTATE_PEF;
+	if (fprs & FPRS_DL)
+		err |= copy_from_user(fpregs, &fpu->si_float_regs[0],
+				      (sizeof(unsigned int) * 32));
+	if (fprs & FPRS_DU)
+		err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32],
+				      (sizeof(unsigned int) * 32));
+	err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
+	err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
+	current_thread_info()->fpsaved[0] |= fprs;
+	return err;
+}
+
+int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin)
+{
+	int i, err = __put_user(wsaved, &rwin->wsaved);
+
+	for (i = 0; i < wsaved; i++) {
+		struct reg_window *rp = &current_thread_info()->reg_window[i];
+		unsigned long fp = current_thread_info()->rwbuf_stkptrs[i];
+
+		err |= copy_to_user(&rwin->reg_window[i], rp,
+				    sizeof(struct reg_window));
+		err |= __put_user(fp, &rwin->rwbuf_stkptrs[i]);
+	}
+	return err;
+}
+
+int restore_rwin_state(__siginfo_rwin_t __user *rp)
+{
+	struct thread_info *t = current_thread_info();
+	int i, wsaved, err;
+
+	__get_user(wsaved, &rp->wsaved);
+	if (wsaved > NSWINS)
+		return -EFAULT;
+
+	err = 0;
+	for (i = 0; i < wsaved; i++) {
+		err |= copy_from_user(&t->reg_window[i],
+				      &rp->reg_window[i],
+				      sizeof(struct reg_window));
+		err |= __get_user(t->rwbuf_stkptrs[i],
+				  &rp->rwbuf_stkptrs[i]);
+	}
+	if (err)
+		return err;
+
+	set_thread_wsaved(wsaved);
+	synchronize_user_stack();
+	if (get_thread_wsaved())
+		return -EFAULT;
+	return 0;
+}
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/kernel/sigutil.h linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/sigutil.h
--- linux-libre-2.6.34-gnu1/arch/sparc/kernel/sigutil.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/kernel/sigutil.h	2014-02-10 17:31:40.000000000 -0500
@@ -0,0 +1,9 @@
+#ifndef _SIGUTIL_H
+#define _SIGUTIL_H
+
+int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu);
+int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu);
+int save_rwin_state(int wsaved, __siginfo_rwin_t __user *rwin);
+int restore_rwin_state(__siginfo_rwin_t __user *rp);
+
+#endif /* _SIGUTIL_H */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/prom/cif.S linux-libre-2.6.34.15-gnu1/arch/sparc/prom/cif.S
--- linux-libre-2.6.34-gnu1/arch/sparc/prom/cif.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/prom/cif.S	2014-02-10 17:31:40.000000000 -0500
@@ -9,18 +9,18 @@
 #include <asm/thread_info.h>
 
 	.text
-	.globl	prom_cif_interface
-prom_cif_interface:
-	sethi	%hi(p1275buf), %o0
-	or	%o0, %lo(p1275buf), %o0
-	ldx	[%o0 + 0x010], %o1	! prom_cif_stack
-	save	%o1, -192, %sp
-	ldx	[%i0 + 0x008], %l2	! prom_cif_handler
+	.globl	prom_cif_direct
+prom_cif_direct:
+	sethi	%hi(p1275buf), %o1
+	or	%o1, %lo(p1275buf), %o1
+	ldx	[%o1 + 0x0010], %o2	! prom_cif_stack
+	save	%o2, -192, %sp
+	ldx	[%i1 + 0x0008], %l2	! prom_cif_handler
 	mov	%g4, %l0
 	mov	%g5, %l1
 	mov	%g6, %l3
 	call	%l2
-	 add	%i0, 0x018, %o0		! prom_args
+	 mov	%i0, %o0		! prom_args
 	mov	%l0, %g4
 	mov	%l1, %g5
 	mov	%l3, %g6
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/prom/console_64.c linux-libre-2.6.34.15-gnu1/arch/sparc/prom/console_64.c
--- linux-libre-2.6.34-gnu1/arch/sparc/prom/console_64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/prom/console_64.c	2014-02-10 17:31:40.000000000 -0500
@@ -21,14 +21,22 @@ extern int prom_stdin, prom_stdout;
 inline int
 prom_nbgetchar(void)
 {
+	unsigned long args[7];
 	char inc;
 
-	if (p1275_cmd("read", P1275_ARG(1,P1275_ARG_OUT_BUF)|
-			      P1275_INOUT(3,1),
-			      prom_stdin, &inc, P1275_SIZE(1)) == 1)
+	args[0] = (unsigned long) "read";
+	args[1] = 3;
+	args[2] = 1;
+	args[3] = (unsigned int) prom_stdin;
+	args[4] = (unsigned long) &inc;
+	args[5] = 1;
+	args[6] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	if (args[6] == 1)
 		return inc;
-	else
-		return -1;
+	return -1;
 }
 
 /* Non blocking put character to console device, returns -1 if
@@ -37,12 +45,22 @@ prom_nbgetchar(void)
 inline int
 prom_nbputchar(char c)
 {
+	unsigned long args[7];
 	char outc;
 	
 	outc = c;
-	if (p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
-			       P1275_INOUT(3,1),
-			       prom_stdout, &outc, P1275_SIZE(1)) == 1)
+
+	args[0] = (unsigned long) "write";
+	args[1] = 3;
+	args[2] = 1;
+	args[3] = (unsigned int) prom_stdout;
+	args[4] = (unsigned long) &outc;
+	args[5] = 1;
+	args[6] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	if (args[6] == 1)
 		return 0;
 	else
 		return -1;
@@ -67,7 +85,15 @@ prom_putchar(char c)
 void
 prom_puts(const char *s, int len)
 {
-	p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
-			   P1275_INOUT(3,1),
-			   prom_stdout, s, P1275_SIZE(len));
+	unsigned long args[7];
+
+	args[0] = (unsigned long) "write";
+	args[1] = 3;
+	args[2] = 1;
+	args[3] = (unsigned int) prom_stdout;
+	args[4] = (unsigned long) s;
+	args[5] = len;
+	args[6] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
 }
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/prom/devops_64.c linux-libre-2.6.34.15-gnu1/arch/sparc/prom/devops_64.c
--- linux-libre-2.6.34-gnu1/arch/sparc/prom/devops_64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/prom/devops_64.c	2014-02-10 17:31:40.000000000 -0500
@@ -18,16 +18,32 @@
 int
 prom_devopen(const char *dstr)
 {
-	return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)|
-				  P1275_INOUT(1,1),
-				  dstr);
+	unsigned long args[5];
+
+	args[0] = (unsigned long) "open";
+	args[1] = 1;
+	args[2] = 1;
+	args[3] = (unsigned long) dstr;
+	args[4] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	return (int) args[4];
 }
 
 /* Close the device described by device handle 'dhandle'. */
 int
 prom_devclose(int dhandle)
 {
-	p1275_cmd ("close", P1275_INOUT(1,0), dhandle);
+	unsigned long args[4];
+
+	args[0] = (unsigned long) "close";
+	args[1] = 1;
+	args[2] = 0;
+	args[3] = (unsigned int) dhandle;
+
+	p1275_cmd_direct(args);
+
 	return 0;
 }
 
@@ -37,5 +53,15 @@ prom_devclose(int dhandle)
 void
 prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
 {
-	p1275_cmd ("seek", P1275_INOUT(3,1), dhandle, seekhi, seeklo);
+	unsigned long args[7];
+
+	args[0] = (unsigned long) "seek";
+	args[1] = 3;
+	args[2] = 1;
+	args[3] = (unsigned int) dhandle;
+	args[4] = seekhi;
+	args[5] = seeklo;
+	args[6] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
 }
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/prom/misc_64.c linux-libre-2.6.34.15-gnu1/arch/sparc/prom/misc_64.c
--- linux-libre-2.6.34-gnu1/arch/sparc/prom/misc_64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/prom/misc_64.c	2014-02-10 17:31:40.000000000 -0500
@@ -20,10 +20,17 @@
 
 int prom_service_exists(const char *service_name)
 {
-	int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) |
-			    P1275_INOUT(1, 1), service_name);
+	unsigned long args[5];
 
-	if (err)
+	args[0] = (unsigned long) "test";
+	args[1] = 1;
+	args[2] = 1;
+	args[3] = (unsigned long) service_name;
+	args[4] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	if (args[4])
 		return 0;
 	return 1;
 }
@@ -31,30 +38,47 @@ int prom_service_exists(const char *serv
 void prom_sun4v_guest_soft_state(void)
 {
 	const char *svc = "SUNW,soft-state-supported";
+	unsigned long args[3];
 
 	if (!prom_service_exists(svc))
 		return;
-	p1275_cmd(svc, P1275_INOUT(0, 0));
+	args[0] = (unsigned long) svc;
+	args[1] = 0;
+	args[2] = 0;
+	p1275_cmd_direct(args);
 }
 
 /* Reset and reboot the machine with the command 'bcommand'. */
 void prom_reboot(const char *bcommand)
 {
+	unsigned long args[4];
+
 #ifdef CONFIG_SUN_LDOMS
 	if (ldom_domaining_enabled)
 		ldom_reboot(bcommand);
 #endif
-	p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) |
-		  P1275_INOUT(1, 0), bcommand);
+	args[0] = (unsigned long) "boot";
+	args[1] = 1;
+	args[2] = 0;
+	args[3] = (unsigned long) bcommand;
+
+	p1275_cmd_direct(args);
 }
 
 /* Forth evaluate the expression contained in 'fstring'. */
 void prom_feval(const char *fstring)
 {
+	unsigned long args[5];
+
 	if (!fstring || fstring[0] == 0)
 		return;
-	p1275_cmd("interpret", P1275_ARG(0, P1275_ARG_IN_STRING) |
-		  P1275_INOUT(1, 1), fstring);
+	args[0] = (unsigned long) "interpret";
+	args[1] = 1;
+	args[2] = 1;
+	args[3] = (unsigned long) fstring;
+	args[4] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
 }
 EXPORT_SYMBOL(prom_feval);
 
@@ -68,6 +92,7 @@ extern void smp_release(void);
  */
 void prom_cmdline(void)
 {
+	unsigned long args[3];
 	unsigned long flags;
 
 	local_irq_save(flags);
@@ -76,7 +101,11 @@ void prom_cmdline(void)
 	smp_capture();
 #endif
 
-	p1275_cmd("enter", P1275_INOUT(0, 0));
+	args[0] = (unsigned long) "enter";
+	args[1] = 0;
+	args[2] = 0;
+
+	p1275_cmd_direct(args);
 
 #ifdef CONFIG_SMP
 	smp_release();
@@ -90,22 +119,32 @@ void prom_cmdline(void)
  */
 void notrace prom_halt(void)
 {
+	unsigned long args[3];
+
 #ifdef CONFIG_SUN_LDOMS
 	if (ldom_domaining_enabled)
 		ldom_power_off();
 #endif
 again:
-	p1275_cmd("exit", P1275_INOUT(0, 0));
+	args[0] = (unsigned long) "exit";
+	args[1] = 0;
+	args[2] = 0;
+	p1275_cmd_direct(args);
 	goto again; /* PROM is out to get me -DaveM */
 }
 
 void prom_halt_power_off(void)
 {
+	unsigned long args[3];
+
 #ifdef CONFIG_SUN_LDOMS
 	if (ldom_domaining_enabled)
 		ldom_power_off();
 #endif
-	p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0));
+	args[0] = (unsigned long) "SUNW,power-off";
+	args[1] = 0;
+	args[2] = 0;
+	p1275_cmd_direct(args);
 
 	/* if nothing else helps, we just halt */
 	prom_halt();
@@ -114,10 +153,15 @@ void prom_halt_power_off(void)
 /* Set prom sync handler to call function 'funcp'. */
 void prom_setcallback(callback_func_t funcp)
 {
+	unsigned long args[5];
 	if (!funcp)
 		return;
-	p1275_cmd("set-callback", P1275_ARG(0, P1275_ARG_IN_FUNCTION) |
-		  P1275_INOUT(1, 1), funcp);
+	args[0] = (unsigned long) "set-callback";
+	args[1] = 1;
+	args[2] = 1;
+	args[3] = (unsigned long) funcp;
+	args[4] = (unsigned long) -1;
+	p1275_cmd_direct(args);
 }
 
 /* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
@@ -173,57 +217,61 @@ static int prom_get_memory_ihandle(void)
 }
 
 /* Load explicit I/D TLB entries. */
+static long tlb_load(const char *type, unsigned long index,
+		     unsigned long tte_data, unsigned long vaddr)
+{
+	unsigned long args[9];
+
+	args[0] = (unsigned long) prom_callmethod_name;
+	args[1] = 5;
+	args[2] = 1;
+	args[3] = (unsigned long) type;
+	args[4] = (unsigned int) prom_get_mmu_ihandle();
+	args[5] = vaddr;
+	args[6] = tte_data;
+	args[7] = index;
+	args[8] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	return (long) args[8];
+}
+
 long prom_itlb_load(unsigned long index,
 		    unsigned long tte_data,
 		    unsigned long vaddr)
 {
-	return p1275_cmd(prom_callmethod_name,
-			 (P1275_ARG(0, P1275_ARG_IN_STRING) |
-			  P1275_ARG(2, P1275_ARG_IN_64B) |
-			  P1275_ARG(3, P1275_ARG_IN_64B) |
-			  P1275_INOUT(5, 1)),
-			 "SUNW,itlb-load",
-			 prom_get_mmu_ihandle(),
-			 /* And then our actual args are pushed backwards. */
-			 vaddr,
-			 tte_data,
-			 index);
+	return tlb_load("SUNW,itlb-load", index, tte_data, vaddr);
 }
 
 long prom_dtlb_load(unsigned long index,
 		    unsigned long tte_data,
 		    unsigned long vaddr)
 {
-	return p1275_cmd(prom_callmethod_name,
-			 (P1275_ARG(0, P1275_ARG_IN_STRING) |
-			  P1275_ARG(2, P1275_ARG_IN_64B) |
-			  P1275_ARG(3, P1275_ARG_IN_64B) |
-			  P1275_INOUT(5, 1)),
-			 "SUNW,dtlb-load",
-			 prom_get_mmu_ihandle(),
-			 /* And then our actual args are pushed backwards. */
-			 vaddr,
-			 tte_data,
-			 index);
+	return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr);
 }
 
 int prom_map(int mode, unsigned long size,
 	     unsigned long vaddr, unsigned long paddr)
 {
-	int ret = p1275_cmd(prom_callmethod_name,
-			    (P1275_ARG(0, P1275_ARG_IN_STRING) |
-			     P1275_ARG(3, P1275_ARG_IN_64B) |
-			     P1275_ARG(4, P1275_ARG_IN_64B) |
-			     P1275_ARG(6, P1275_ARG_IN_64B) |
-			     P1275_INOUT(7, 1)),
-			    prom_map_name,
-			    prom_get_mmu_ihandle(),
-			    mode,
-			    size,
-			    vaddr,
-			    0,
-			    paddr);
+	unsigned long args[11];
+	int ret;
 
+	args[0] = (unsigned long) prom_callmethod_name;
+	args[1] = 7;
+	args[2] = 1;
+	args[3] = (unsigned long) prom_map_name;
+	args[4] = (unsigned int) prom_get_mmu_ihandle();
+	args[5] = (unsigned int) mode;
+	args[6] = size;
+	args[7] = vaddr;
+	args[8] = 0;
+	args[9] = paddr;
+	args[10] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	ret = (int) args[10];
 	if (ret == 0)
 		ret = -1;
 	return ret;
@@ -231,40 +279,51 @@ int prom_map(int mode, unsigned long siz
 
 void prom_unmap(unsigned long size, unsigned long vaddr)
 {
-	p1275_cmd(prom_callmethod_name,
-		  (P1275_ARG(0, P1275_ARG_IN_STRING) |
-		   P1275_ARG(2, P1275_ARG_IN_64B) |
-		   P1275_ARG(3, P1275_ARG_IN_64B) |
-		   P1275_INOUT(4, 0)),
-		  prom_unmap_name,
-		  prom_get_mmu_ihandle(),
-		  size,
-		  vaddr);
+	unsigned long args[7];
+
+	args[0] = (unsigned long) prom_callmethod_name;
+	args[1] = 4;
+	args[2] = 0;
+	args[3] = (unsigned long) prom_unmap_name;
+	args[4] = (unsigned int) prom_get_mmu_ihandle();
+	args[5] = size;
+	args[6] = vaddr;
+
+	p1275_cmd_direct(args);
 }
 
 /* Set aside physical memory which is not touched or modified
  * across soft resets.
  */
-unsigned long prom_retain(const char *name,
-			  unsigned long pa_low, unsigned long pa_high,
-			  long size, long align)
+int prom_retain(const char *name, unsigned long size,
+		unsigned long align, unsigned long *paddr)
 {
-	/* XXX I don't think we return multiple values correctly.
-	 * XXX OBP supposedly returns pa_low/pa_high here, how does
-	 * XXX it work?
-	 */
+	unsigned long args[11];
 
-	/* If align is zero, the pa_low/pa_high args are passed,
-	 * else they are not.
+	args[0] = (unsigned long) prom_callmethod_name;
+	args[1] = 5;
+	args[2] = 3;
+	args[3] = (unsigned long) "SUNW,retain";
+	args[4] = (unsigned int) prom_get_memory_ihandle();
+	args[5] = align;
+	args[6] = size;
+	args[7] = (unsigned long) name;
+	args[8] = (unsigned long) -1;
+	args[9] = (unsigned long) -1;
+	args[10] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	if (args[8])
+		return (int) args[8];
+
+	/* Next we get "phys_high" then "phys_low".  On 64-bit
+	 * the phys_high cell is don't care since the phys_low
+	 * cell has the full value.
 	 */
-	if (align == 0)
-		return p1275_cmd("SUNW,retain",
-				 (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 2)),
-				 name, pa_low, pa_high, size, align);
-	else
-		return p1275_cmd("SUNW,retain",
-				 (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(3, 2)),
-				 name, size, align);
+	*paddr = args[10];
+
+	return 0;
 }
 
 /* Get "Unumber" string for the SIMM at the given
@@ -277,62 +336,129 @@ int prom_getunumber(int syndrome_code,
 		    unsigned long phys_addr,
 		    char *buf, int buflen)
 {
-	return p1275_cmd(prom_callmethod_name,
-			 (P1275_ARG(0, P1275_ARG_IN_STRING)	|
-			  P1275_ARG(3, P1275_ARG_OUT_BUF)	|
-			  P1275_ARG(6, P1275_ARG_IN_64B)	|
-			  P1275_INOUT(8, 2)),
-			 "SUNW,get-unumber", prom_get_memory_ihandle(),
-			 buflen, buf, P1275_SIZE(buflen),
-			 0, phys_addr, syndrome_code);
+	unsigned long args[12];
+
+	args[0] = (unsigned long) prom_callmethod_name;
+	args[1] = 7;
+	args[2] = 2;
+	args[3] = (unsigned long) "SUNW,get-unumber";
+	args[4] = (unsigned int) prom_get_memory_ihandle();
+	args[5] = buflen;
+	args[6] = (unsigned long) buf;
+	args[7] = 0;
+	args[8] = phys_addr;
+	args[9] = (unsigned int) syndrome_code;
+	args[10] = (unsigned long) -1;
+	args[11] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	return (int) args[10];
 }
 
 /* Power management extensions. */
 void prom_sleepself(void)
 {
-	p1275_cmd("SUNW,sleep-self", P1275_INOUT(0, 0));
+	unsigned long args[3];
+
+	args[0] = (unsigned long) "SUNW,sleep-self";
+	args[1] = 0;
+	args[2] = 0;
+	p1275_cmd_direct(args);
 }
 
 int prom_sleepsystem(void)
 {
-	return p1275_cmd("SUNW,sleep-system", P1275_INOUT(0, 1));
+	unsigned long args[4];
+
+	args[0] = (unsigned long) "SUNW,sleep-system";
+	args[1] = 0;
+	args[2] = 1;
+	args[3] = (unsigned long) -1;
+	p1275_cmd_direct(args);
+
+	return (int) args[3];
 }
 
 int prom_wakeupsystem(void)
 {
-	return p1275_cmd("SUNW,wakeup-system", P1275_INOUT(0, 1));
+	unsigned long args[4];
+
+	args[0] = (unsigned long) "SUNW,wakeup-system";
+	args[1] = 0;
+	args[2] = 1;
+	args[3] = (unsigned long) -1;
+	p1275_cmd_direct(args);
+
+	return (int) args[3];
 }
 
 #ifdef CONFIG_SMP
 void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg)
 {
-	p1275_cmd("SUNW,start-cpu", P1275_INOUT(3, 0), cpunode, pc, arg);
+	unsigned long args[6];
+
+	args[0] = (unsigned long) "SUNW,start-cpu";
+	args[1] = 3;
+	args[2] = 0;
+	args[3] = (unsigned int) cpunode;
+	args[4] = pc;
+	args[5] = arg;
+	p1275_cmd_direct(args);
 }
 
 void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg)
 {
-	p1275_cmd("SUNW,start-cpu-by-cpuid", P1275_INOUT(3, 0),
-		  cpuid, pc, arg);
+	unsigned long args[6];
+
+	args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid";
+	args[1] = 3;
+	args[2] = 0;
+	args[3] = (unsigned int) cpuid;
+	args[4] = pc;
+	args[5] = arg;
+	p1275_cmd_direct(args);
 }
 
 void prom_stopcpu_cpuid(int cpuid)
 {
-	p1275_cmd("SUNW,stop-cpu-by-cpuid", P1275_INOUT(1, 0),
-		  cpuid);
+	unsigned long args[4];
+
+	args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid";
+	args[1] = 1;
+	args[2] = 0;
+	args[3] = (unsigned int) cpuid;
+	p1275_cmd_direct(args);
 }
 
 void prom_stopself(void)
 {
-	p1275_cmd("SUNW,stop-self", P1275_INOUT(0, 0));
+	unsigned long args[3];
+
+	args[0] = (unsigned long) "SUNW,stop-self";
+	args[1] = 0;
+	args[2] = 0;
+	p1275_cmd_direct(args);
 }
 
 void prom_idleself(void)
 {
-	p1275_cmd("SUNW,idle-self", P1275_INOUT(0, 0));
+	unsigned long args[3];
+
+	args[0] = (unsigned long) "SUNW,idle-self";
+	args[1] = 0;
+	args[2] = 0;
+	p1275_cmd_direct(args);
 }
 
 void prom_resumecpu(int cpunode)
 {
-	p1275_cmd("SUNW,resume-cpu", P1275_INOUT(1, 0), cpunode);
+	unsigned long args[4];
+
+	args[0] = (unsigned long) "SUNW,resume-cpu";
+	args[1] = 1;
+	args[2] = 0;
+	args[3] = (unsigned int) cpunode;
+	p1275_cmd_direct(args);
 }
 #endif
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/prom/p1275.c linux-libre-2.6.34.15-gnu1/arch/sparc/prom/p1275.c
--- linux-libre-2.6.34-gnu1/arch/sparc/prom/p1275.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/prom/p1275.c	2014-02-10 17:31:40.000000000 -0500
@@ -22,13 +22,11 @@ struct {
 	long prom_callback;			/* 0x00 */
 	void (*prom_cif_handler)(long *);	/* 0x08 */
 	unsigned long prom_cif_stack;		/* 0x10 */
-	unsigned long prom_args [23];		/* 0x18 */
-	char prom_buffer [3000];
 } p1275buf;
 
 extern void prom_world(int);
 
-extern void prom_cif_interface(void);
+extern void prom_cif_direct(unsigned long *args);
 extern void prom_cif_callback(void);
 
 /*
@@ -36,114 +34,20 @@ extern void prom_cif_callback(void);
  */
 DEFINE_RAW_SPINLOCK(prom_entry_lock);
 
-long p1275_cmd(const char *service, long fmt, ...)
+void p1275_cmd_direct(unsigned long *args)
 {
-	char *p, *q;
 	unsigned long flags;
-	int nargs, nrets, i;
-	va_list list;
-	long attrs, x;
-	
-	p = p1275buf.prom_buffer;
 
 	raw_local_save_flags(flags);
 	raw_local_irq_restore(PIL_NMI);
 	raw_spin_lock(&prom_entry_lock);
 
-	p1275buf.prom_args[0] = (unsigned long)p;		/* service */
-	strcpy (p, service);
-	p = (char *)(((long)(strchr (p, 0) + 8)) & ~7);
-	p1275buf.prom_args[1] = nargs = (fmt & 0x0f);		/* nargs */
-	p1275buf.prom_args[2] = nrets = ((fmt & 0xf0) >> 4); 	/* nrets */
-	attrs = fmt >> 8;
-	va_start(list, fmt);
-	for (i = 0; i < nargs; i++, attrs >>= 3) {
-		switch (attrs & 0x7) {
-		case P1275_ARG_NUMBER:
-			p1275buf.prom_args[i + 3] =
-						(unsigned)va_arg(list, long);
-			break;
-		case P1275_ARG_IN_64B:
-			p1275buf.prom_args[i + 3] =
-				va_arg(list, unsigned long);
-			break;
-		case P1275_ARG_IN_STRING:
-			strcpy (p, va_arg(list, char *));
-			p1275buf.prom_args[i + 3] = (unsigned long)p;
-			p = (char *)(((long)(strchr (p, 0) + 8)) & ~7);
-			break;
-		case P1275_ARG_OUT_BUF:
-			(void) va_arg(list, char *);
-			p1275buf.prom_args[i + 3] = (unsigned long)p;
-			x = va_arg(list, long);
-			i++; attrs >>= 3;
-			p = (char *)(((long)(p + (int)x + 7)) & ~7);
-			p1275buf.prom_args[i + 3] = x;
-			break;
-		case P1275_ARG_IN_BUF:
-			q = va_arg(list, char *);
-			p1275buf.prom_args[i + 3] = (unsigned long)p;
-			x = va_arg(list, long);
-			i++; attrs >>= 3;
-			memcpy (p, q, (int)x);
-			p = (char *)(((long)(p + (int)x + 7)) & ~7);
-			p1275buf.prom_args[i + 3] = x;
-			break;
-		case P1275_ARG_OUT_32B:
-			(void) va_arg(list, char *);
-			p1275buf.prom_args[i + 3] = (unsigned long)p;
-			p += 32;
-			break;
-		case P1275_ARG_IN_FUNCTION:
-			p1275buf.prom_args[i + 3] =
-					(unsigned long)prom_cif_callback;
-			p1275buf.prom_callback = va_arg(list, long);
-			break;
-		}
-	}
-	va_end(list);
-
 	prom_world(1);
-	prom_cif_interface();
+	prom_cif_direct(args);
 	prom_world(0);
 
-	attrs = fmt >> 8;
-	va_start(list, fmt);
-	for (i = 0; i < nargs; i++, attrs >>= 3) {
-		switch (attrs & 0x7) {
-		case P1275_ARG_NUMBER:
-			(void) va_arg(list, long);
-			break;
-		case P1275_ARG_IN_STRING:
-			(void) va_arg(list, char *);
-			break;
-		case P1275_ARG_IN_FUNCTION:
-			(void) va_arg(list, long);
-			break;
-		case P1275_ARG_IN_BUF:
-			(void) va_arg(list, char *);
-			(void) va_arg(list, long);
-			i++; attrs >>= 3;
-			break;
-		case P1275_ARG_OUT_BUF:
-			p = va_arg(list, char *);
-			x = va_arg(list, long);
-			memcpy (p, (char *)(p1275buf.prom_args[i + 3]), (int)x);
-			i++; attrs >>= 3;
-			break;
-		case P1275_ARG_OUT_32B:
-			p = va_arg(list, char *);
-			memcpy (p, (char *)(p1275buf.prom_args[i + 3]), 32);
-			break;
-		}
-	}
-	va_end(list);
-	x = p1275buf.prom_args [nargs + 3];
-
 	raw_spin_unlock(&prom_entry_lock);
 	raw_local_irq_restore(flags);
-
-	return x;
 }
 
 void prom_cif_init(void *cif_handler, void *cif_stack)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/sparc/prom/tree_64.c linux-libre-2.6.34.15-gnu1/arch/sparc/prom/tree_64.c
--- linux-libre-2.6.34-gnu1/arch/sparc/prom/tree_64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/sparc/prom/tree_64.c	2014-02-10 17:31:40.000000000 -0500
@@ -16,22 +16,39 @@
 #include <asm/oplib.h>
 #include <asm/ldc.h>
 
+static int prom_node_to_node(const char *type, int node)
+{
+	unsigned long args[5];
+
+	args[0] = (unsigned long) type;
+	args[1] = 1;
+	args[2] = 1;
+	args[3] = (unsigned int) node;
+	args[4] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	return (int) args[4];
+}
+
 /* Return the child of node 'node' or zero if no this node has no
  * direct descendent.
  */
 inline int __prom_getchild(int node)
 {
-	return p1275_cmd ("child", P1275_INOUT(1, 1), node);
+	return prom_node_to_node("child", node);
 }
 
 inline int prom_getchild(int node)
 {
 	int cnode;
 
-	if(node == -1) return 0;
+	if (node == -1)
+		return 0;
 	cnode = __prom_getchild(node);
-	if(cnode == -1) return 0;
-	return (int)cnode;
+	if (cnode == -1)
+		return 0;
+	return cnode;
 }
 EXPORT_SYMBOL(prom_getchild);
 
@@ -39,10 +56,12 @@ inline int prom_getparent(int node)
 {
 	int cnode;
 
-	if(node == -1) return 0;
-	cnode = p1275_cmd ("parent", P1275_INOUT(1, 1), node);
-	if(cnode == -1) return 0;
-	return (int)cnode;
+	if (node == -1)
+		return 0;
+	cnode = prom_node_to_node("parent", node);
+	if (cnode == -1)
+		return 0;
+	return cnode;
 }
 
 /* Return the next sibling of node 'node' or zero if no more siblings
@@ -50,7 +69,7 @@ inline int prom_getparent(int node)
  */
 inline int __prom_getsibling(int node)
 {
-	return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node);
+	return prom_node_to_node(prom_peer_name, node);
 }
 
 inline int prom_getsibling(int node)
@@ -72,11 +91,21 @@ EXPORT_SYMBOL(prom_getsibling);
  */
 inline int prom_getproplen(int node, const char *prop)
 {
-	if((!node) || (!prop)) return -1;
-	return p1275_cmd ("getproplen", 
-			  P1275_ARG(1,P1275_ARG_IN_STRING)|
-			  P1275_INOUT(2, 1), 
-			  node, prop);
+	unsigned long args[6];
+
+	if (!node || !prop)
+		return -1;
+
+	args[0] = (unsigned long) "getproplen";
+	args[1] = 2;
+	args[2] = 1;
+	args[3] = (unsigned int) node;
+	args[4] = (unsigned long) prop;
+	args[5] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	return (int) args[5];
 }
 EXPORT_SYMBOL(prom_getproplen);
 
@@ -87,19 +116,25 @@ EXPORT_SYMBOL(prom_getproplen);
 inline int prom_getproperty(int node, const char *prop,
 			    char *buffer, int bufsize)
 {
+	unsigned long args[8];
 	int plen;
 
 	plen = prom_getproplen(node, prop);
-	if ((plen > bufsize) || (plen == 0) || (plen == -1)) {
+	if ((plen > bufsize) || (plen == 0) || (plen == -1))
 		return -1;
-	} else {
-		/* Ok, things seem all right. */
-		return p1275_cmd(prom_getprop_name, 
-				 P1275_ARG(1,P1275_ARG_IN_STRING)|
-				 P1275_ARG(2,P1275_ARG_OUT_BUF)|
-				 P1275_INOUT(4, 1), 
-				 node, prop, buffer, P1275_SIZE(plen));
-	}
+
+	args[0] = (unsigned long) prom_getprop_name;
+	args[1] = 4;
+	args[2] = 1;
+	args[3] = (unsigned int) node;
+	args[4] = (unsigned long) prop;
+	args[5] = (unsigned long) buffer;
+	args[6] = bufsize;
+	args[7] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	return (int) args[7];
 }
 EXPORT_SYMBOL(prom_getproperty);
 
@@ -110,7 +145,7 @@ inline int prom_getint(int node, const c
 {
 	int intprop;
 
-	if(prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
+	if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
 		return intprop;
 
 	return -1;
@@ -126,7 +161,8 @@ int prom_getintdefault(int node, const c
 	int retval;
 
 	retval = prom_getint(node, property);
-	if(retval == -1) return deflt;
+	if (retval == -1)
+		return deflt;
 
 	return retval;
 }
@@ -138,7 +174,8 @@ int prom_getbool(int node, const char *p
 	int retval;
 
 	retval = prom_getproplen(node, prop);
-	if(retval == -1) return 0;
+	if (retval == -1)
+		return 0;
 	return 1;
 }
 EXPORT_SYMBOL(prom_getbool);
@@ -152,7 +189,8 @@ void prom_getstring(int node, const char
 	int len;
 
 	len = prom_getproperty(node, prop, user_buf, ubuf_size);
-	if(len != -1) return;
+	if (len != -1)
+		return;
 	user_buf[0] = 0;
 }
 EXPORT_SYMBOL(prom_getstring);
@@ -164,7 +202,8 @@ int prom_nodematch(int node, const char
 {
 	char namebuf[128];
 	prom_getproperty(node, "name", namebuf, sizeof(namebuf));
-	if(strcmp(namebuf, name) == 0) return 1;
+	if (strcmp(namebuf, name) == 0)
+		return 1;
 	return 0;
 }
 
@@ -190,16 +229,29 @@ int prom_searchsiblings(int node_start,
 }
 EXPORT_SYMBOL(prom_searchsiblings);
 
+static const char *prom_nextprop_name = "nextprop";
+
 /* Return the first property type for node 'node'.
  * buffer should be at least 32B in length
  */
 inline char *prom_firstprop(int node, char *buffer)
 {
+	unsigned long args[7];
+
 	*buffer = 0;
-	if(node == -1) return buffer;
-	p1275_cmd ("nextprop", P1275_ARG(2,P1275_ARG_OUT_32B)|
-			       P1275_INOUT(3, 0), 
-			       node, (char *) 0x0, buffer);
+	if (node == -1)
+		return buffer;
+
+	args[0] = (unsigned long) prom_nextprop_name;
+	args[1] = 3;
+	args[2] = 1;
+	args[3] = (unsigned int) node;
+	args[4] = 0;
+	args[5] = (unsigned long) buffer;
+	args[6] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
 	return buffer;
 }
 EXPORT_SYMBOL(prom_firstprop);
@@ -210,9 +262,10 @@ EXPORT_SYMBOL(prom_firstprop);
  */
 inline char *prom_nextprop(int node, const char *oprop, char *buffer)
 {
+	unsigned long args[7];
 	char buf[32];
 
-	if(node == -1) {
+	if (node == -1) {
 		*buffer = 0;
 		return buffer;
 	}
@@ -220,10 +273,17 @@ inline char *prom_nextprop(int node, con
 		strcpy (buf, oprop);
 		oprop = buf;
 	}
-	p1275_cmd ("nextprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
-				    P1275_ARG(2,P1275_ARG_OUT_32B)|
-				    P1275_INOUT(3, 0), 
-				    node, oprop, buffer); 
+
+	args[0] = (unsigned long) prom_nextprop_name;
+	args[1] = 3;
+	args[2] = 1;
+	args[3] = (unsigned int) node;
+	args[4] = (unsigned long) oprop;
+	args[5] = (unsigned long) buffer;
+	args[6] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
 	return buffer;
 }
 EXPORT_SYMBOL(prom_nextprop);
@@ -231,12 +291,19 @@ EXPORT_SYMBOL(prom_nextprop);
 int
 prom_finddevice(const char *name)
 {
+	unsigned long args[5];
+
 	if (!name)
 		return 0;
-	return p1275_cmd(prom_finddev_name,
-			 P1275_ARG(0,P1275_ARG_IN_STRING)|
-			 P1275_INOUT(1, 1), 
-			 name);
+	args[0] = (unsigned long) "finddevice";
+	args[1] = 1;
+	args[2] = 1;
+	args[3] = (unsigned long) name;
+	args[4] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	return (int) args[4];
 }
 EXPORT_SYMBOL(prom_finddevice);
 
@@ -247,7 +314,7 @@ int prom_node_has_property(int node, con
 	*buf = 0;
 	do {
 		prom_nextprop(node, buf, buf);
-		if(!strcmp(buf, prop))
+		if (!strcmp(buf, prop))
 			return 1;
 	} while (*buf);
 	return 0;
@@ -260,6 +327,8 @@ EXPORT_SYMBOL(prom_node_has_property);
 int
 prom_setprop(int node, const char *pname, char *value, int size)
 {
+	unsigned long args[8];
+
 	if (size == 0)
 		return 0;
 	if ((pname == 0) || (value == 0))
@@ -271,19 +340,37 @@ prom_setprop(int node, const char *pname
 		return 0;
 	}
 #endif
-	return p1275_cmd ("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
-					  P1275_ARG(2,P1275_ARG_IN_BUF)|
-					  P1275_INOUT(4, 1), 
-					  node, pname, value, P1275_SIZE(size));
+	args[0] = (unsigned long) "setprop";
+	args[1] = 4;
+	args[2] = 1;
+	args[3] = (unsigned int) node;
+	args[4] = (unsigned long) pname;
+	args[5] = (unsigned long) value;
+	args[6] = size;
+	args[7] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	return (int) args[7];
 }
 EXPORT_SYMBOL(prom_setprop);
 
 inline int prom_inst2pkg(int inst)
 {
+	unsigned long args[5];
 	int node;
 	
-	node = p1275_cmd ("instance-to-package", P1275_INOUT(1, 1), inst);
-	if (node == -1) return 0;
+	args[0] = (unsigned long) "instance-to-package";
+	args[1] = 1;
+	args[2] = 1;
+	args[3] = (unsigned int) inst;
+	args[4] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	node = (int) args[4];
+	if (node == -1)
+		return 0;
 	return node;
 }
 
@@ -296,17 +383,28 @@ prom_pathtoinode(const char *path)
 	int node, inst;
 
 	inst = prom_devopen (path);
-	if (inst == 0) return 0;
-	node = prom_inst2pkg (inst);
-	prom_devclose (inst);
-	if (node == -1) return 0;
+	if (inst == 0)
+		return 0;
+	node = prom_inst2pkg(inst);
+	prom_devclose(inst);
+	if (node == -1)
+		return 0;
 	return node;
 }
 
 int prom_ihandle2path(int handle, char *buffer, int bufsize)
 {
-	return p1275_cmd("instance-to-path",
-			 P1275_ARG(1,P1275_ARG_OUT_BUF)|
-			 P1275_INOUT(3, 1),
-			 handle, buffer, P1275_SIZE(bufsize));
+	unsigned long args[7];
+
+	args[0] = (unsigned long) "instance-to-path";
+	args[1] = 3;
+	args[2] = 1;
+	args[3] = (unsigned int) handle;
+	args[4] = (unsigned long) buffer;
+	args[5] = bufsize;
+	args[6] = (unsigned long) -1;
+
+	p1275_cmd_direct(args);
+
+	return (int) args[6];
 }
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/um/drivers/line.c linux-libre-2.6.34.15-gnu1/arch/um/drivers/line.c
--- linux-libre-2.6.34-gnu1/arch/um/drivers/line.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/um/drivers/line.c	2014-02-10 17:31:40.000000000 -0500
@@ -728,6 +728,9 @@ struct winch {
 
 static void free_winch(struct winch *winch, int free_irq_ok)
 {
+	if (free_irq_ok)
+		free_irq(WINCH_IRQ, winch);
+
 	list_del(&winch->list);
 
 	if (winch->pid != -1)
@@ -736,8 +739,6 @@ static void free_winch(struct winch *win
 		os_close_file(winch->fd);
 	if (winch->stack != 0)
 		free_stack(winch->stack, 0);
-	if (free_irq_ok)
-		free_irq(WINCH_IRQ, winch);
 	kfree(winch);
 }
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/um/drivers/ubd_kern.c linux-libre-2.6.34.15-gnu1/arch/um/drivers/ubd_kern.c
--- linux-libre-2.6.34-gnu1/arch/um/drivers/ubd_kern.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/um/drivers/ubd_kern.c	2014-02-10 17:31:40.000000000 -0500
@@ -162,6 +162,7 @@ struct ubd {
 	struct scatterlist sg[MAX_SG];
 	struct request *request;
 	int start_sg, end_sg;
+	sector_t rq_pos;
 };
 
 #define DEFAULT_COW { \
@@ -186,6 +187,7 @@ struct ubd {
 	.request =		NULL, \
 	.start_sg =		0, \
 	.end_sg =		0, \
+	.rq_pos =		0, \
 }
 
 /* Protected by ubd_lock */
@@ -509,8 +511,37 @@ __uml_exitcall(kill_io_thread);
 static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
 {
 	char *file;
+	int fd;
+	int err;
 
-	file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
+	__u32 version;
+	__u32 align;
+	char *backing_file;
+	time_t mtime;
+	unsigned long long size;
+	int sector_size;
+	int bitmap_offset;
+
+	if (ubd_dev->file && ubd_dev->cow.file) {
+		file = ubd_dev->cow.file;
+
+		goto out;
+	}
+
+	fd = os_open_file(ubd_dev->file, global_openflags, 0);
+	if (fd < 0)
+		return fd;
+
+	err = read_cow_header(file_reader, &fd, &version, &backing_file, \
+		&mtime, &size, &sector_size, &align, &bitmap_offset);
+	os_close_file(fd);
+
+	if(err == -EINVAL)
+		file = ubd_dev->file;
+	else
+		file = backing_file;
+
+out:
 	return os_file_size(file, size_out);
 }
 
@@ -1223,7 +1254,6 @@ static void do_ubd_request(struct reques
 {
 	struct io_thread_req *io_req;
 	struct request *req;
-	sector_t sector;
 	int n;
 
 	while(1){
@@ -1234,12 +1264,12 @@ static void do_ubd_request(struct reques
 				return;
 
 			dev->request = req;
+			dev->rq_pos = blk_rq_pos(req);
 			dev->start_sg = 0;
 			dev->end_sg = blk_rq_map_sg(q, req, dev->sg);
 		}
 
 		req = dev->request;
-		sector = blk_rq_pos(req);
 		while(dev->start_sg < dev->end_sg){
 			struct scatterlist *sg = &dev->sg[dev->start_sg];
 
@@ -1251,10 +1281,9 @@ static void do_ubd_request(struct reques
 				return;
 			}
 			prepare_request(req, io_req,
-					(unsigned long long)sector << 9,
+					(unsigned long long)dev->rq_pos << 9,
 					sg->offset, sg->length, sg_page(sg));
 
-			sector += sg->length >> 9;
 			n = os_write_file(thread_fd, &io_req,
 					  sizeof(struct io_thread_req *));
 			if(n != sizeof(struct io_thread_req *)){
@@ -1267,6 +1296,7 @@ static void do_ubd_request(struct reques
 				return;
 			}
 
+			dev->rq_pos += sg->length >> 9;
 			dev->start_sg++;
 		}
 		dev->end_sg = 0;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/um/Kconfig.x86 linux-libre-2.6.34.15-gnu1/arch/um/Kconfig.x86
--- linux-libre-2.6.34-gnu1/arch/um/Kconfig.x86	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/um/Kconfig.x86	2014-02-10 17:31:40.000000000 -0500
@@ -20,10 +20,10 @@ config X86_32
 	select HAVE_AOUT
 
 config RWSEM_XCHGADD_ALGORITHM
-	def_bool X86_XADD
+	def_bool X86_XADD && 64BIT
 
 config RWSEM_GENERIC_SPINLOCK
-	def_bool !X86_XADD
+	def_bool !RWSEM_XCHGADD_ALGORITHM
 
 config 3_LEVEL_PGTABLES
 	bool "Three-level pagetables (EXPERIMENTAL)" if !64BIT
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/um/kernel/dyn.lds.S linux-libre-2.6.34.15-gnu1/arch/um/kernel/dyn.lds.S
--- linux-libre-2.6.34-gnu1/arch/um/kernel/dyn.lds.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/um/kernel/dyn.lds.S	2014-02-10 17:31:40.000000000 -0500
@@ -50,8 +50,18 @@ SECTIONS
   .rela.got       : { *(.rela.got) }
   .rel.bss        : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
   .rela.bss       : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
-  .rel.plt        : { *(.rel.plt) }
-  .rela.plt       : { *(.rela.plt) }
+  .rel.plt : {
+	*(.rel.plt)
+	PROVIDE_HIDDEN(__rel_iplt_start = .);
+	*(.rel.iplt)
+	PROVIDE_HIDDEN(__rel_iplt_end = .);
+  }
+  .rela.plt : {
+	*(.rela.plt)
+	PROVIDE_HIDDEN(__rela_iplt_start = .);
+	*(.rela.iplt)
+	PROVIDE_HIDDEN(__rela_iplt_end = .);
+  }
   .init           : {
     KEEP (*(.init))
   } =0x90909090
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/um/kernel/uml.lds.S linux-libre-2.6.34.15-gnu1/arch/um/kernel/uml.lds.S
--- linux-libre-2.6.34-gnu1/arch/um/kernel/uml.lds.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/um/kernel/uml.lds.S	2014-02-10 17:31:40.000000000 -0500
@@ -22,7 +22,7 @@ SECTIONS
   _text = .;
   _stext = .;
   __init_begin = .;
-  INIT_TEXT_SECTION(PAGE_SIZE)
+  INIT_TEXT_SECTION(0)
   . = ALIGN(PAGE_SIZE);
 
   .text      :
@@ -43,6 +43,23 @@ SECTIONS
 	__syscall_stub_end = .;
   }
 
+  /*
+   * These are needed even in a static link, even if they wind up being empty.
+   * Newer glibc needs these __rel{,a}_iplt_{start,end} symbols.
+   */
+  .rel.plt : {
+	*(.rel.plt)
+	PROVIDE_HIDDEN(__rel_iplt_start = .);
+	*(.rel.iplt)
+	PROVIDE_HIDDEN(__rel_iplt_end = .);
+  }
+  .rela.plt : {
+	*(.rela.plt)
+	PROVIDE_HIDDEN(__rela_iplt_start = .);
+	*(.rela.iplt)
+	PROVIDE_HIDDEN(__rela_iplt_end = .);
+  }
+
   #include "asm/common.lds.S"
 
   init.data : { INIT_DATA }
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/um/os-Linux/mem.c linux-libre-2.6.34.15-gnu1/arch/um/os-Linux/mem.c
--- linux-libre-2.6.34-gnu1/arch/um/os-Linux/mem.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/um/os-Linux/mem.c	2014-02-10 17:31:40.000000000 -0500
@@ -10,6 +10,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <string.h>
+#include <sys/stat.h>
 #include <sys/mman.h>
 #include <sys/param.h>
 #include "init.h"
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/um/os-Linux/time.c linux-libre-2.6.34.15-gnu1/arch/um/os-Linux/time.c
--- linux-libre-2.6.34-gnu1/arch/um/os-Linux/time.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/um/os-Linux/time.c	2014-02-10 17:31:40.000000000 -0500
@@ -60,7 +60,7 @@ static inline long long timeval_to_ns(co
 long long disable_timer(void)
 {
 	struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
-	int remain, max = UM_NSEC_PER_SEC / UM_HZ;
+	long long remain, max = UM_NSEC_PER_SEC / UM_HZ;
 
 	if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
 		printk(UM_KERN_ERR "disable_timer - setitimer failed, "
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/.gitignore linux-libre-2.6.34.15-gnu1/arch/x86/.gitignore
--- linux-libre-2.6.34-gnu1/arch/x86/.gitignore	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34.15-gnu1/arch/x86/.gitignore	2014-02-10 17:31:40.000000000 -0500
@@ -0,0 +1,3 @@
+boot/compressed/vmlinux
+tools/test_get_len
+
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/ia32/ia32entry.S linux-libre-2.6.34.15-gnu1/arch/x86/ia32/ia32entry.S
--- linux-libre-2.6.34-gnu1/arch/x86/ia32/ia32entry.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/ia32/ia32entry.S	2014-02-10 17:31:40.000000000 -0500
@@ -50,7 +50,12 @@
 	/*
 	 * Reload arg registers from stack in case ptrace changed them.
 	 * We don't reload %eax because syscall_trace_enter() returned
-	 * the value it wants us to use in the table lookup.
+	 * the %rax value we should see.  Instead, we just truncate that
+	 * value to 32 bits again as we did on entry from user mode.
+	 * If it's a new value set by user_regset during entry tracing,
+	 * this matches the normal truncation of the user-mode value.
+	 * If it's -1 to make us punt the syscall, then (u32)-1 is still
+	 * an appropriately invalid value.
 	 */
 	.macro LOAD_ARGS32 offset, _r9=0
 	.if \_r9
@@ -60,6 +65,7 @@
 	movl \offset+48(%rsp),%edx
 	movl \offset+56(%rsp),%esi
 	movl \offset+64(%rsp),%edi
+	movl %eax,%eax			/* zero extension */
 	.endm
 	
 	.macro CFI_STARTPROC32 simple
@@ -153,7 +159,7 @@ ENTRY(ia32_sysenter_target)
 	testl  $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
 	CFI_REMEMBER_STATE
 	jnz  sysenter_tracesys
-	cmpl	$(IA32_NR_syscalls-1),%eax
+	cmpq	$(IA32_NR_syscalls-1),%rax
 	ja	ia32_badsys
 sysenter_do_call:
 	IA32_ARG_FIXUP
@@ -195,7 +201,7 @@ sysexit_from_sys_call:
 	movl $AUDIT_ARCH_I386,%edi	/* 1st arg: audit arch */
 	call audit_syscall_entry
 	movl RAX-ARGOFFSET(%rsp),%eax	/* reload syscall number */
-	cmpl $(IA32_NR_syscalls-1),%eax
+	cmpq $(IA32_NR_syscalls-1),%rax
 	ja ia32_badsys
 	movl %ebx,%edi			/* reload 1st syscall arg */
 	movl RCX-ARGOFFSET(%rsp),%esi	/* reload 2nd syscall arg */
@@ -248,7 +254,7 @@ sysenter_tracesys:
 	call	syscall_trace_enter
 	LOAD_ARGS32 ARGOFFSET  /* reload args from stack in case ptrace changed it */
 	RESTORE_REST
-	cmpl	$(IA32_NR_syscalls-1),%eax
+	cmpq	$(IA32_NR_syscalls-1),%rax
 	ja	int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */
 	jmp	sysenter_do_call
 	CFI_ENDPROC
@@ -314,7 +320,7 @@ ENTRY(ia32_cstar_target)
 	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
 	CFI_REMEMBER_STATE
 	jnz   cstar_tracesys
-	cmpl $IA32_NR_syscalls-1,%eax
+	cmpq $IA32_NR_syscalls-1,%rax
 	ja  ia32_badsys
 cstar_do_call:
 	IA32_ARG_FIXUP 1
@@ -367,7 +373,7 @@ cstar_tracesys:
 	LOAD_ARGS32 ARGOFFSET, 1  /* reload args from stack in case ptrace changed it */
 	RESTORE_REST
 	xchgl %ebp,%r9d
-	cmpl $(IA32_NR_syscalls-1),%eax
+	cmpq $(IA32_NR_syscalls-1),%rax
 	ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */
 	jmp cstar_do_call
 END(ia32_cstar_target)
@@ -425,7 +431,7 @@ ENTRY(ia32_syscall)
 	orl   $TS_COMPAT,TI_status(%r10)
 	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
 	jnz ia32_tracesys
-	cmpl $(IA32_NR_syscalls-1),%eax
+	cmpq $(IA32_NR_syscalls-1),%rax
 	ja ia32_badsys
 ia32_do_call:
 	IA32_ARG_FIXUP
@@ -444,7 +450,7 @@ ia32_tracesys:
 	call syscall_trace_enter
 	LOAD_ARGS32 ARGOFFSET  /* reload args from stack in case ptrace changed it */
 	RESTORE_REST
-	cmpl $(IA32_NR_syscalls-1),%eax
+	cmpq $(IA32_NR_syscalls-1),%rax
 	ja  int_ret_from_sys_call	/* ia32_tracesys has set RAX(%rsp) */
 	jmp ia32_do_call
 END(ia32_syscall)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/acpi.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/acpi.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/acpi.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/acpi.h	2014-02-10 17:31:40.000000000 -0500
@@ -89,6 +89,7 @@ extern int acpi_ht;
 extern int acpi_pci_disabled;
 extern int acpi_skip_timer_override;
 extern int acpi_use_timer_override;
+extern int acpi_fix_pin2_polarity;
 
 extern u8 acpi_sci_flags;
 extern int acpi_sci_override_gsi;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/amd_iommu_proto.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/amd_iommu_proto.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/amd_iommu_proto.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/amd_iommu_proto.h	2014-02-10 17:31:40.000000000 -0500
@@ -38,4 +38,10 @@ static inline void amd_iommu_stats_init(
 
 #endif /* !CONFIG_AMD_IOMMU_STATS */
 
+static inline bool is_rd890_iommu(struct pci_dev *pdev)
+{
+	return (pdev->vendor == PCI_VENDOR_ID_ATI) &&
+	       (pdev->device == PCI_DEVICE_ID_RD890_IOMMU);
+}
+
 #endif /* _ASM_X86_AMD_IOMMU_PROTO_H  */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/amd_iommu_types.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/amd_iommu_types.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/amd_iommu_types.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/amd_iommu_types.h	2014-02-10 17:31:40.000000000 -0500
@@ -334,6 +334,9 @@ struct amd_iommu {
 	/* capabilities of that IOMMU read from ACPI */
 	u32 cap;
 
+	/* flags read from acpi table */
+	u8 acpi_flags;
+
 	/*
 	 * Capability pointer. There could be more than one IOMMU per PCI
 	 * device function if there are more than one AMD IOMMU capability
@@ -377,6 +380,15 @@ struct amd_iommu {
 
 	/* default dma_ops domain for that IOMMU */
 	struct dma_ops_domain *default_dom;
+
+	/*
+	 * This array is required to work around a potential BIOS bug.
+	 * The BIOS may miss to restore parts of the PCI configuration
+	 * space when the system resumes from S3. The result is that the
+	 * IOMMU does not execute commands anymore which leads to system
+	 * failure.
+	 */
+	u32 cache_cfg[4];
 };
 
 /*
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/apicdef.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/apicdef.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/apicdef.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/apicdef.h	2014-02-10 17:31:40.000000000 -0500
@@ -78,6 +78,7 @@
 #define		APIC_DEST_LOGICAL	0x00800
 #define		APIC_DEST_PHYSICAL	0x00000
 #define		APIC_DM_FIXED		0x00000
+#define		APIC_DM_FIXED_MASK	0x00700
 #define		APIC_DM_LOWEST		0x00100
 #define		APIC_DM_SMI		0x00200
 #define		APIC_DM_REMRD		0x00300
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/archrandom.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/archrandom.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/archrandom.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/archrandom.h	2014-02-10 17:31:40.000000000 -0500
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the Linux kernel.
+ *
+ * Copyright (c) 2011, Intel Corporation
+ * Authors: Fenghua Yu <fenghua.yu@intel.com>,
+ *          H. Peter Anvin <hpa@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef ASM_X86_ARCHRANDOM_H
+#define ASM_X86_ARCHRANDOM_H
+
+#include <asm/processor.h>
+#include <asm/cpufeature.h>
+#include <asm/alternative.h>
+#include <asm/nops.h>
+
+#define RDRAND_RETRY_LOOPS	10
+
+#define RDRAND_INT	".byte 0x0f,0xc7,0xf0"
+#ifdef CONFIG_X86_64
+# define RDRAND_LONG	".byte 0x48,0x0f,0xc7,0xf0"
+#else
+# define RDRAND_LONG	RDRAND_INT
+#endif
+
+#ifdef CONFIG_ARCH_RANDOM
+
+#define GET_RANDOM(name, type, rdrand, nop)			\
+static inline int name(type *v)					\
+{								\
+	int ok;							\
+	alternative_io("movl $0, %0\n\t"			\
+		       nop,					\
+		       "\n1: " rdrand "\n\t"			\
+		       "jc 2f\n\t"				\
+		       "decl %0\n\t"                            \
+		       "jnz 1b\n\t"                             \
+		       "2:",                                    \
+		       X86_FEATURE_RDRAND,                      \
+		       ASM_OUTPUT2("=r" (ok), "=a" (*v)),       \
+		       "0" (RDRAND_RETRY_LOOPS));		\
+	return ok;						\
+}
+
+#ifdef CONFIG_X86_64
+
+GET_RANDOM(arch_get_random_long, unsigned long, RDRAND_LONG, ASM_NOP5);
+GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP4);
+
+#else
+
+GET_RANDOM(arch_get_random_long, unsigned long, RDRAND_LONG, ASM_NOP3);
+GET_RANDOM(arch_get_random_int, unsigned int, RDRAND_INT, ASM_NOP3);
+
+#endif /* CONFIG_X86_64 */
+
+#endif  /* CONFIG_ARCH_RANDOM */
+
+#endif /* ASM_X86_ARCHRANDOM_H */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/cmpxchg_32.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/cmpxchg_32.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/cmpxchg_32.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/cmpxchg_32.h	2014-02-10 17:31:40.000000000 -0500
@@ -27,20 +27,20 @@ struct __xchg_dummy {
 	switch (size) {							\
 	case 1:								\
 		asm volatile("xchgb %b0,%1"				\
-			     : "=q" (__x)				\
-			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "=q" (__x), "+m" (*__xg(ptr))		\
+			     : "0" (__x)				\
 			     : "memory");				\
 		break;							\
 	case 2:								\
 		asm volatile("xchgw %w0,%1"				\
-			     : "=r" (__x)				\
-			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "=r" (__x), "+m" (*__xg(ptr))		\
+			     : "0" (__x)				\
 			     : "memory");				\
 		break;							\
 	case 4:								\
 		asm volatile("xchgl %0,%1"				\
-			     : "=r" (__x)				\
-			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "=r" (__x), "+m" (*__xg(ptr))		\
+			     : "0" (__x)				\
 			     : "memory");				\
 		break;							\
 	default:							\
@@ -53,60 +53,33 @@ struct __xchg_dummy {
 	__xchg((v), (ptr), sizeof(*ptr))
 
 /*
- * The semantics of XCHGCMP8B are a bit strange, this is why
- * there is a loop and the loading of %%eax and %%edx has to
- * be inside. This inlines well in most cases, the cached
- * cost is around ~38 cycles. (in the future we might want
- * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
- * might have an implicit FPU-save as a cost, so it's not
- * clear which path to go.)
+ * CMPXCHG8B only writes to the target if we had the previous
+ * value in registers, otherwise it acts as a read and gives us the
+ * "new previous" value.  That is why there is a loop.  Preloading
+ * EDX:EAX is a performance optimization: in the common case it means
+ * we need only one locked operation.
  *
- * cmpxchg8b must be used with the lock prefix here to allow
- * the instruction to be executed atomically, see page 3-102
- * of the instruction set reference 24319102.pdf. We need
- * the reader side to see the coherent 64bit value.
+ * A SIMD/3DNOW!/MMX/FPU 64-bit store here would require at the very
+ * least an FPU save and/or %cr0.ts manipulation.
+ *
+ * cmpxchg8b must be used with the lock prefix here to allow the
+ * instruction to be executed atomically.  We need to have the reader
+ * side to see the coherent 64bit value.
  */
-static inline void __set_64bit(unsigned long long *ptr,
-			       unsigned int low, unsigned int high)
+static inline void set_64bit(volatile u64 *ptr, u64 value)
 {
+	u32 low  = value;
+	u32 high = value >> 32;
+	u64 prev = *ptr;
+
 	asm volatile("\n1:\t"
-		     "movl (%0), %%eax\n\t"
-		     "movl 4(%0), %%edx\n\t"
-		     LOCK_PREFIX "cmpxchg8b (%0)\n\t"
+		     LOCK_PREFIX "cmpxchg8b %0\n\t"
 		     "jnz 1b"
-		     : /* no outputs */
-		     : "D"(ptr),
-		       "b"(low),
-		       "c"(high)
-		     : "ax", "dx", "memory");
-}
-
-static inline void __set_64bit_constant(unsigned long long *ptr,
-					unsigned long long value)
-{
-	__set_64bit(ptr, (unsigned int)value, (unsigned int)(value >> 32));
-}
-
-#define ll_low(x)	*(((unsigned int *)&(x)) + 0)
-#define ll_high(x)	*(((unsigned int *)&(x)) + 1)
-
-static inline void __set_64bit_var(unsigned long long *ptr,
-				   unsigned long long value)
-{
-	__set_64bit(ptr, ll_low(value), ll_high(value));
+		     : "=m" (*ptr), "+A" (prev)
+		     : "b" (low), "c" (high)
+		     : "memory");
 }
 
-#define set_64bit(ptr, value)			\
-	(__builtin_constant_p((value))		\
-	 ? __set_64bit_constant((ptr), (value))	\
-	 : __set_64bit_var((ptr), (value)))
-
-#define _set_64bit(ptr, value)						\
-	(__builtin_constant_p(value)					\
-	 ? __set_64bit(ptr, (unsigned int)(value),			\
-		       (unsigned int)((value) >> 32))			\
-	 : __set_64bit(ptr, ll_low((value)), ll_high((value))))
-
 extern void __cmpxchg_wrong_size(void);
 
 /*
@@ -121,21 +94,21 @@ extern void __cmpxchg_wrong_size(void);
 	__typeof__(*(ptr)) __new = (new);				\
 	switch (size) {							\
 	case 1:								\
-		asm volatile(lock "cmpxchgb %b1,%2"			\
-			     : "=a"(__ret)				\
-			     : "q"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+		asm volatile(lock "cmpxchgb %b2,%1"			\
+			     : "=a" (__ret), "+m" (*__xg(ptr))		\
+			     : "q" (__new), "0" (__old)			\
 			     : "memory");				\
 		break;							\
 	case 2:								\
-		asm volatile(lock "cmpxchgw %w1,%2"			\
-			     : "=a"(__ret)				\
-			     : "r"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+		asm volatile(lock "cmpxchgw %w2,%1"			\
+			     : "=a" (__ret), "+m" (*__xg(ptr))		\
+			     : "r" (__new), "0" (__old)			\
 			     : "memory");				\
 		break;							\
 	case 4:								\
-		asm volatile(lock "cmpxchgl %1,%2"			\
-			     : "=a"(__ret)				\
-			     : "r"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+		asm volatile(lock "cmpxchgl %2,%1"			\
+			     : "=a" (__ret), "+m" (*__xg(ptr))		\
+			     : "r" (__new), "0" (__old)			\
 			     : "memory");				\
 		break;							\
 	default:							\
@@ -180,12 +153,12 @@ static inline unsigned long long __cmpxc
 					     unsigned long long new)
 {
 	unsigned long long prev;
-	asm volatile(LOCK_PREFIX "cmpxchg8b %3"
-		     : "=A"(prev)
-		     : "b"((unsigned long)new),
-		       "c"((unsigned long)(new >> 32)),
-		       "m"(*__xg(ptr)),
-		       "0"(old)
+	asm volatile(LOCK_PREFIX "cmpxchg8b %1"
+		     : "=A" (prev),
+		       "+m" (*__xg(ptr))
+		     : "b" ((unsigned long)new),
+		       "c" ((unsigned long)(new >> 32)),
+		       "0" (old)
 		     : "memory");
 	return prev;
 }
@@ -195,12 +168,12 @@ static inline unsigned long long __cmpxc
 						   unsigned long long new)
 {
 	unsigned long long prev;
-	asm volatile("cmpxchg8b %3"
-		     : "=A"(prev)
-		     : "b"((unsigned long)new),
-		       "c"((unsigned long)(new >> 32)),
-		       "m"(*__xg(ptr)),
-		       "0"(old)
+	asm volatile("cmpxchg8b %1"
+		     : "=A" (prev),
+		       "+m" (*__xg(ptr))
+		     : "b" ((unsigned long)new),
+		       "c" ((unsigned long)(new >> 32)),
+		       "0" (old)
 		     : "memory");
 	return prev;
 }
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/cmpxchg_64.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/cmpxchg_64.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/cmpxchg_64.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/cmpxchg_64.h	2014-02-10 17:31:40.000000000 -0500
@@ -5,13 +5,11 @@
 
 #define __xg(x) ((volatile long *)(x))
 
-static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
+static inline void set_64bit(volatile u64 *ptr, u64 val)
 {
 	*ptr = val;
 }
 
-#define _set_64bit set_64bit
-
 extern void __xchg_wrong_size(void);
 extern void __cmpxchg_wrong_size(void);
 
@@ -26,26 +24,26 @@ extern void __cmpxchg_wrong_size(void);
 	switch (size) {							\
 	case 1:								\
 		asm volatile("xchgb %b0,%1"				\
-			     : "=q" (__x)				\
-			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "=q" (__x), "+m" (*__xg(ptr))		\
+			     : "0" (__x)				\
 			     : "memory");				\
 		break;							\
 	case 2:								\
 		asm volatile("xchgw %w0,%1"				\
-			     : "=r" (__x)				\
-			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "=r" (__x), "+m" (*__xg(ptr))		\
+			     : "0" (__x)				\
 			     : "memory");				\
 		break;							\
 	case 4:								\
 		asm volatile("xchgl %k0,%1"				\
-			     : "=r" (__x)				\
-			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "=r" (__x), "+m" (*__xg(ptr))		\
+			     : "0" (__x)				\
 			     : "memory");				\
 		break;							\
 	case 8:								\
 		asm volatile("xchgq %0,%1"				\
-			     : "=r" (__x)				\
-			     : "m" (*__xg(ptr)), "0" (__x)		\
+			     : "=r" (__x), "+m" (*__xg(ptr))		\
+			     : "0" (__x)				\
 			     : "memory");				\
 		break;							\
 	default:							\
@@ -71,27 +69,27 @@ extern void __cmpxchg_wrong_size(void);
 	__typeof__(*(ptr)) __new = (new);				\
 	switch (size) {							\
 	case 1:								\
-		asm volatile(lock "cmpxchgb %b1,%2"			\
-			     : "=a"(__ret)				\
-			     : "q"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+		asm volatile(lock "cmpxchgb %b2,%1"			\
+			     : "=a" (__ret), "+m" (*__xg(ptr))		\
+			     : "q" (__new), "0" (__old)			\
 			     : "memory");				\
 		break;							\
 	case 2:								\
-		asm volatile(lock "cmpxchgw %w1,%2"			\
-			     : "=a"(__ret)				\
-			     : "r"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+		asm volatile(lock "cmpxchgw %w2,%1"			\
+			     : "=a" (__ret), "+m" (*__xg(ptr))		\
+			     : "r" (__new), "0" (__old)			\
 			     : "memory");				\
 		break;							\
 	case 4:								\
-		asm volatile(lock "cmpxchgl %k1,%2"			\
-			     : "=a"(__ret)				\
-			     : "r"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+		asm volatile(lock "cmpxchgl %k2,%1"			\
+			     : "=a" (__ret), "+m" (*__xg(ptr))		\
+			     : "r" (__new), "0" (__old)			\
 			     : "memory");				\
 		break;							\
 	case 8:								\
-		asm volatile(lock "cmpxchgq %1,%2"			\
-			     : "=a"(__ret)				\
-			     : "r"(__new), "m"(*__xg(ptr)), "0"(__old)	\
+		asm volatile(lock "cmpxchgq %2,%1"			\
+			     : "=a" (__ret), "+m" (*__xg(ptr))		\
+			     : "r" (__new), "0" (__old)			\
 			     : "memory");				\
 		break;							\
 	default:							\
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/compat.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/compat.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/compat.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/compat.h	2014-02-10 17:31:40.000000000 -0500
@@ -205,7 +205,7 @@ static inline compat_uptr_t ptr_to_compa
 	return (u32)(unsigned long)uptr;
 }
 
-static inline void __user *compat_alloc_user_space(long len)
+static inline void __user *arch_compat_alloc_user_space(long len)
 {
 	struct pt_regs *regs = task_pt_regs(current);
 	return (void __user *)regs->sp - len;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/cpufeature.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/cpufeature.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/cpufeature.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/cpufeature.h	2014-02-10 17:31:40.000000000 -0500
@@ -124,6 +124,8 @@
 #define X86_FEATURE_XSAVE	(4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
 #define X86_FEATURE_OSXSAVE	(4*32+27) /* "" XSAVE enabled in the OS */
 #define X86_FEATURE_AVX		(4*32+28) /* Advanced Vector Extensions */
+#define X86_FEATURE_F16C	(4*32+29) /* 16-bit fp conversions */
+#define X86_FEATURE_RDRAND	(4*32+30) /* The RDRAND instruction */
 #define X86_FEATURE_HYPERVISOR	(4*32+31) /* Running on a hypervisor */
 
 /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
@@ -150,7 +152,7 @@
 #define X86_FEATURE_3DNOWPREFETCH (6*32+ 8) /* 3DNow prefetch instructions */
 #define X86_FEATURE_OSVW	(6*32+ 9) /* OS Visible Workaround */
 #define X86_FEATURE_IBS		(6*32+10) /* Instruction Based Sampling */
-#define X86_FEATURE_SSE5	(6*32+11) /* SSE-5 */
+#define X86_FEATURE_XOP		(6*32+11) /* extended AVX instructions */
 #define X86_FEATURE_SKINIT	(6*32+12) /* SKINIT/STGI instructions */
 #define X86_FEATURE_WDT		(6*32+13) /* Watchdog timer */
 #define X86_FEATURE_NODEID_MSR	(6*32+19) /* NodeId MSR */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/io.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/io.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/io.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/io.h	2014-02-10 17:31:40.000000000 -0500
@@ -206,6 +206,7 @@ static inline void __iomem *ioremap(reso
 
 extern void iounmap(volatile void __iomem *addr);
 
+extern void set_iounmap_nonlazy(void);
 
 #ifdef __KERNEL__
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/kvm_host.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/kvm_host.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/kvm_host.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/kvm_host.h	2014-02-10 17:31:40.000000000 -0500
@@ -180,6 +180,7 @@ union kvm_mmu_page_role {
 		unsigned invalid:1;
 		unsigned cr4_pge:1;
 		unsigned nxe:1;
+		unsigned cr0_wp:1;
 	};
 };
 
@@ -541,6 +542,8 @@ struct kvm_x86_ops {
 	int (*get_lpage_level)(void);
 	bool (*rdtscp_supported)(void);
 
+	void (*set_supported_cpuid)(u32 func, struct kvm_cpuid_entry2 *entry);
+
 	const struct trace_print_flags *exit_reasons_str;
 };
 
@@ -688,20 +691,6 @@ static inline struct kvm_mmu_page *page_
 	return (struct kvm_mmu_page *)page_private(page);
 }
 
-static inline u16 kvm_read_fs(void)
-{
-	u16 seg;
-	asm("mov %%fs, %0" : "=g"(seg));
-	return seg;
-}
-
-static inline u16 kvm_read_gs(void)
-{
-	u16 seg;
-	asm("mov %%gs, %0" : "=g"(seg));
-	return seg;
-}
-
 static inline u16 kvm_read_ldt(void)
 {
 	u16 ldt;
@@ -709,16 +698,6 @@ static inline u16 kvm_read_ldt(void)
 	return ldt;
 }
 
-static inline void kvm_load_fs(u16 sel)
-{
-	asm("mov %0, %%fs" : : "rm"(sel));
-}
-
-static inline void kvm_load_gs(u16 sel)
-{
-	asm("mov %0, %%gs" : : "rm"(sel));
-}
-
 static inline void kvm_load_ldt(u16 sel)
 {
 	asm("lldt %0" : : "rm"(sel));
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/linkage.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/linkage.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/linkage.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/linkage.h	2014-02-10 17:31:40.000000000 -0500
@@ -8,11 +8,6 @@
 
 #ifdef CONFIG_X86_32
 #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
-/*
- * For 32-bit UML - mark functions implemented in assembly that use
- * regparm input parameters:
- */
-#define asmregparm __attribute__((regparm(3)))
 
 /*
  * Make sure the compiler doesn't do anything stupid with the
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/mmu_context.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/mmu_context.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/mmu_context.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/mmu_context.h	2014-02-10 17:31:40.000000000 -0500
@@ -36,8 +36,6 @@ static inline void switch_mm(struct mm_s
 	unsigned cpu = smp_processor_id();
 
 	if (likely(prev != next)) {
-		/* stop flush ipis for the previous mm */
-		cpumask_clear_cpu(cpu, mm_cpumask(prev));
 #ifdef CONFIG_SMP
 		percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
 		percpu_write(cpu_tlbstate.active_mm, next);
@@ -47,6 +45,9 @@ static inline void switch_mm(struct mm_s
 		/* Re-load page tables */
 		load_cr3(next->pgd);
 
+		/* stop flush ipis for the previous mm */
+		cpumask_clear_cpu(cpu, mm_cpumask(prev));
+
 		/*
 		 * load the LDT, if the LDT is different:
 		 */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/msr-index.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/msr-index.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/msr-index.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/msr-index.h	2014-02-10 17:31:40.000000000 -0500
@@ -82,11 +82,15 @@
 #define MSR_IA32_MC0_ADDR		0x00000402
 #define MSR_IA32_MC0_MISC		0x00000403
 
+#define MSR_AMD64_MC0_MASK		0xc0010044
+
 #define MSR_IA32_MCx_CTL(x)		(MSR_IA32_MC0_CTL + 4*(x))
 #define MSR_IA32_MCx_STATUS(x)		(MSR_IA32_MC0_STATUS + 4*(x))
 #define MSR_IA32_MCx_ADDR(x)		(MSR_IA32_MC0_ADDR + 4*(x))
 #define MSR_IA32_MCx_MISC(x)		(MSR_IA32_MC0_MISC + 4*(x))
 
+#define MSR_AMD64_MCx_MASK(x)		(MSR_AMD64_MC0_MASK + (x))
+
 /* These are consecutive and not in the normal 4er MCE bank block */
 #define MSR_IA32_MC0_CTL2		0x00000280
 #define MSR_IA32_MCx_CTL2(x)		(MSR_IA32_MC0_CTL2 + (x))
@@ -107,6 +111,7 @@
 #define MSR_AMD64_PATCH_LOADER		0xc0010020
 #define MSR_AMD64_OSVW_ID_LENGTH	0xc0010140
 #define MSR_AMD64_OSVW_STATUS		0xc0010141
+#define MSR_AMD64_DC_CFG		0xc0011022
 #define MSR_AMD64_IBSFETCHCTL		0xc0011030
 #define MSR_AMD64_IBSFETCHLINAD		0xc0011031
 #define MSR_AMD64_IBSFETCHPHYSAD	0xc0011032
@@ -199,8 +204,9 @@
 #define MSR_IA32_EBL_CR_POWERON		0x0000002a
 #define MSR_IA32_FEATURE_CONTROL        0x0000003a
 
-#define FEATURE_CONTROL_LOCKED		(1<<0)
-#define FEATURE_CONTROL_VMXON_ENABLED	(1<<2)
+#define FEATURE_CONTROL_LOCKED				(1<<0)
+#define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX	(1<<1)
+#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX	(1<<2)
 
 #define MSR_IA32_APICBASE		0x0000001b
 #define MSR_IA32_APICBASE_BSP		(1<<8)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/mwait.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/mwait.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/mwait.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/mwait.h	2014-02-10 17:31:40.000000000 -0500
@@ -0,0 +1,15 @@
+#ifndef _ASM_X86_MWAIT_H
+#define _ASM_X86_MWAIT_H
+
+#define MWAIT_SUBSTATE_MASK		0xf
+#define MWAIT_CSTATE_MASK		0xf
+#define MWAIT_SUBSTATE_SIZE		4
+#define MWAIT_MAX_NUM_CSTATES		8
+
+#define CPUID_MWAIT_LEAF		5
+#define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1
+#define CPUID5_ECX_INTERRUPT_BREAK	0x2
+
+#define MWAIT_ECX_INTERRUPT_BREAK	0x1
+
+#endif /* _ASM_X86_MWAIT_H */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/pgtable_32.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/pgtable_32.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/pgtable_32.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/pgtable_32.h	2014-02-10 17:31:40.000000000 -0500
@@ -26,6 +26,7 @@ struct mm_struct;
 struct vm_area_struct;
 
 extern pgd_t swapper_pg_dir[1024];
+extern pgd_t trampoline_pg_dir[1024];
 
 static inline void pgtable_cache_init(void) { }
 static inline void check_pgt_cache(void) { }
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/pgtable-3level.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/pgtable-3level.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/pgtable-3level.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/pgtable-3level.h	2014-02-10 17:31:40.000000000 -0500
@@ -69,8 +69,6 @@ static inline void native_pmd_clear(pmd_
 
 static inline void pud_clear(pud_t *pudp)
 {
-	unsigned long pgd;
-
 	set_pud(pudp, __pud(0));
 
 	/*
@@ -79,13 +77,10 @@ static inline void pud_clear(pud_t *pudp
 	 * section 8.1: in PAE mode we explicitly have to flush the
 	 * TLB via cr3 if the top-level pgd is changed...
 	 *
-	 * Make sure the pud entry we're updating is within the
-	 * current pgd to avoid unnecessary TLB flushes.
+	 * Currently all places where pud_clear() is called either have
+	 * flush_tlb_mm() followed or don't need TLB flush (x86_64 code or
+	 * pud_clear_bad()), so we don't need TLB flush here.
 	 */
-	pgd = read_cr3();
-	if (__pa(pudp) >= pgd && __pa(pudp) <
-	    (pgd + sizeof(pgd_t)*PTRS_PER_PGD))
-		write_cr3(pgd);
 }
 
 #ifdef CONFIG_SMP
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/pgtable.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/pgtable.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/pgtable.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/pgtable.h	2014-02-10 17:31:40.000000000 -0500
@@ -132,6 +132,11 @@ static inline unsigned long pmd_pfn(pmd_
 	return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT;
 }
 
+static inline unsigned long pud_pfn(pud_t pud)
+{
+	return (pud_val(pud) & PTE_PFN_MASK) >> PAGE_SHIFT;
+}
+
 #define pte_page(pte)	pfn_to_page(pte_pfn(pte))
 
 static inline int pmd_large(pmd_t pte)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/processor.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/processor.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/processor.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/processor.h	2014-02-10 17:31:40.000000000 -0500
@@ -767,29 +767,6 @@ extern unsigned long		boot_option_idle_o
 extern unsigned long		idle_halt;
 extern unsigned long		idle_nomwait;
 
-/*
- * on systems with caches, caches must be flashed as the absolute
- * last instruction before going into a suspended halt.  Otherwise,
- * dirty data can linger in the cache and become stale on resume,
- * leading to strange errors.
- *
- * perform a variety of operations to guarantee that the compiler
- * will not reorder instructions.  wbinvd itself is serializing
- * so the processor will not reorder.
- *
- * Systems without cache can just go into halt.
- */
-static inline void wbinvd_halt(void)
-{
-	mb();
-	/* check for clflush to determine if wbinvd is legal */
-	if (cpu_has_clflush)
-		asm volatile("cli; wbinvd; 1: hlt; jmp 1b" : : : "memory");
-	else
-		while (1)
-			halt();
-}
-
 extern void enable_sep_cpu(void);
 extern int sysenter_setup(void);
 
@@ -1054,4 +1031,23 @@ unsigned long calc_aperfmperf_ratio(stru
 	return ratio;
 }
 
+/*
+ * AMD errata checking
+ */
+#ifdef CONFIG_CPU_SUP_AMD
+extern const int amd_erratum_400[];
+extern bool cpu_has_amd_erratum(const int *);
+
+#define AMD_LEGACY_ERRATUM(...)		{ -1, __VA_ARGS__, 0 }
+#define AMD_OSVW_ERRATUM(osvw_id, ...)	{ osvw_id, __VA_ARGS__, 0 }
+#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \
+	((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end))
+#define AMD_MODEL_RANGE_FAMILY(range)	(((range) >> 24) & 0xff)
+#define AMD_MODEL_RANGE_START(range)	(((range) >> 12) & 0xfff)
+#define AMD_MODEL_RANGE_END(range)	((range) & 0xfff)
+
+#else
+#define cpu_has_amd_erratum(x)	(false)
+#endif /* CONFIG_CPU_SUP_AMD */
+
 #endif /* _ASM_X86_PROCESSOR_H */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/pvclock.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/pvclock.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/pvclock.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/pvclock.h	2014-02-10 17:31:40.000000000 -0500
@@ -10,5 +10,44 @@ unsigned long pvclock_tsc_khz(struct pvc
 void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
 			    struct pvclock_vcpu_time_info *vcpu,
 			    struct timespec *ts);
+void pvclock_resume(void);
+
+/*
+ * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
+ * yielding a 64-bit result.
+ */
+static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift)
+{
+	u64 product;
+#ifdef __i386__
+	u32 tmp1, tmp2;
+#endif
+
+	if (shift < 0)
+		delta >>= -shift;
+	else
+		delta <<= shift;
+
+#ifdef __i386__
+	__asm__ (
+		"mul  %5       ; "
+		"mov  %4,%%eax ; "
+		"mov  %%edx,%4 ; "
+		"mul  %5       ; "
+		"xor  %5,%5    ; "
+		"add  %4,%%eax ; "
+		"adc  %5,%%edx ; "
+		: "=A" (product), "=r" (tmp1), "=r" (tmp2)
+		: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
+#elif defined(__x86_64__)
+	__asm__ (
+		"mul %%rdx ; shrd $32,%%rdx,%%rax"
+		: "=a" (product) : "0" (delta), "d" ((u64)mul_frac) );
+#else
+#error implement me!
+#endif
+
+	return product;
+}
 
 #endif /* _ASM_X86_PVCLOCK_H */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/rwsem.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/rwsem.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/rwsem.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/rwsem.h	2014-02-10 17:31:40.000000000 -0500
@@ -45,14 +45,10 @@
 
 struct rwsem_waiter;
 
-extern asmregparm struct rw_semaphore *
- rwsem_down_read_failed(struct rw_semaphore *sem);
-extern asmregparm struct rw_semaphore *
- rwsem_down_write_failed(struct rw_semaphore *sem);
-extern asmregparm struct rw_semaphore *
- rwsem_wake(struct rw_semaphore *);
-extern asmregparm struct rw_semaphore *
- rwsem_downgrade_wake(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *);
+extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
 
 /*
  * the semaphore definition
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/smpboot_hooks.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/smpboot_hooks.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/smpboot_hooks.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/smpboot_hooks.h	2014-02-10 17:31:40.000000000 -0500
@@ -34,7 +34,7 @@ static inline void smpboot_restore_warm_
 	 */
 	CMOS_WRITE(0, 0xf);
 
-	*((volatile long *)phys_to_virt(apic->trampoline_phys_low)) = 0;
+	*((volatile u32 *)phys_to_virt(apic->trampoline_phys_low)) = 0;
 }
 
 static inline void __init smpboot_setup_io_apic(void)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/smp.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/smp.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/smp.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/smp.h	2014-02-10 17:31:40.000000000 -0500
@@ -50,7 +50,7 @@ struct smp_ops {
 	void (*smp_prepare_cpus)(unsigned max_cpus);
 	void (*smp_cpus_done)(unsigned max_cpus);
 
-	void (*smp_send_stop)(void);
+	void (*stop_other_cpus)(int wait);
 	void (*smp_send_reschedule)(int cpu);
 
 	int (*cpu_up)(unsigned cpu);
@@ -73,7 +73,12 @@ extern struct smp_ops smp_ops;
 
 static inline void smp_send_stop(void)
 {
-	smp_ops.smp_send_stop();
+	smp_ops.stop_other_cpus(0);
+}
+
+static inline void stop_other_cpus(void)
+{
+	smp_ops.stop_other_cpus(1);
 }
 
 static inline void smp_prepare_boot_cpu(void)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/suspend_32.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/suspend_32.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/suspend_32.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/suspend_32.h	2014-02-10 17:31:40.000000000 -0500
@@ -15,6 +15,8 @@ static inline int arch_prepare_suspend(v
 struct saved_context {
 	u16 es, fs, gs, ss;
 	unsigned long cr0, cr2, cr3, cr4;
+	u64 misc_enable;
+	bool misc_enable_saved;
 	struct desc_ptr gdt;
 	struct desc_ptr idt;
 	u16 ldt;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/suspend_64.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/suspend_64.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/suspend_64.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/suspend_64.h	2014-02-10 17:31:40.000000000 -0500
@@ -27,6 +27,8 @@ struct saved_context {
 	u16 ds, es, fs, gs, ss;
 	unsigned long gs_base, gs_kernel_base, fs_base;
 	unsigned long cr0, cr2, cr3, cr4, cr8;
+	u64 misc_enable;
+	bool misc_enable_saved;
 	unsigned long efer;
 	u16 gdt_pad;
 	u16 gdt_limit;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/system.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/system.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/system.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/system.h	2014-02-10 17:31:40.000000000 -0500
@@ -451,7 +451,7 @@ void stop_this_cpu(void *dummy);
  *
  * (Could use an alternative three way for this if there was one.)
  */
-static inline void rdtsc_barrier(void)
+static __always_inline void rdtsc_barrier(void)
 {
 	alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);
 	alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/timer.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/timer.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/timer.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/timer.h	2014-02-10 17:31:40.000000000 -0500
@@ -38,6 +38,22 @@ extern int no_timer_check;
  *  (mathieu.desnoyers@polymtl.ca)
  *
  *			-johnstul@us.ibm.com "math is hard, lets go shopping!"
+ *
+ * In:
+ *
+ * ns = cycles * cyc2ns_scale / SC
+ *
+ * Although we may still have enough bits to store the value of ns,
+ * in some cases, we may not have enough bits to store cycles * cyc2ns_scale,
+ * leading to an incorrect result.
+ *
+ * To avoid this, we can decompose 'cycles' into quotient and remainder
+ * of division by SC.  Then,
+ *
+ * ns = (quot * SC + rem) * cyc2ns_scale / SC
+ *    = quot * cyc2ns_scale + (rem * cyc2ns_scale) / SC
+ *
+ *			- sqazi@google.com
  */
 
 DECLARE_PER_CPU(unsigned long, cyc2ns);
@@ -47,9 +63,14 @@ DECLARE_PER_CPU(unsigned long long, cyc2
 
 static inline unsigned long long __cycles_2_ns(unsigned long long cyc)
 {
+	unsigned long long quot;
+	unsigned long long rem;
 	int cpu = smp_processor_id();
 	unsigned long long ns = per_cpu(cyc2ns_offset, cpu);
-	ns += cyc * per_cpu(cyc2ns, cpu) >> CYC2NS_SCALE_FACTOR;
+	quot = (cyc >> CYC2NS_SCALE_FACTOR);
+	rem = cyc & ((1ULL << CYC2NS_SCALE_FACTOR) - 1);
+	ns += quot * per_cpu(cyc2ns, cpu) +
+		((rem * per_cpu(cyc2ns, cpu)) >> CYC2NS_SCALE_FACTOR);
 	return ns;
 }
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/trampoline.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/trampoline.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/trampoline.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/trampoline.h	2014-02-10 17:31:40.000000000 -0500
@@ -13,14 +13,17 @@ extern unsigned char *trampoline_base;
 
 extern unsigned long init_rsp;
 extern unsigned long initial_code;
+extern unsigned long initial_page_table;
 extern unsigned long initial_gs;
 
 #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
 
 extern unsigned long setup_trampoline(void);
+extern void __init setup_trampoline_page_table(void);
 extern void __init reserve_trampoline_memory(void);
 #else
-static inline void reserve_trampoline_memory(void) {};
+static inline void setup_trampoline_page_table(void) {}
+static inline void reserve_trampoline_memory(void) {}
 #endif /* CONFIG_X86_TRAMPOLINE */
 
 #endif /* __ASSEMBLY__ */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/tsc.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/tsc.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/tsc.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/tsc.h	2014-02-10 17:31:40.000000000 -0500
@@ -59,5 +59,7 @@ extern void check_tsc_sync_source(int cp
 extern void check_tsc_sync_target(void);
 
 extern int notsc_setup(char *);
+extern void save_sched_clock_state(void);
+extern void restore_sched_clock_state(void);
 
 #endif /* _ASM_X86_TSC_H */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/include/asm/uaccess.h linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/uaccess.h
--- linux-libre-2.6.34-gnu1/arch/x86/include/asm/uaccess.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/include/asm/uaccess.h	2014-02-10 17:31:40.000000000 -0500
@@ -42,7 +42,7 @@
  * Returns 0 if the range is valid, nonzero otherwise.
  *
  * This is equivalent to the following test:
- * (u33)addr + (u33)size >= (u33)current->addr_limit.seg (u65 for x86_64)
+ * (u33)addr + (u33)size > (u33)current->addr_limit.seg (u65 for x86_64)
  *
  * This needs 33-bit (65-bit for x86_64) arithmetic. We have a carry...
  */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/Kconfig linux-libre-2.6.34.15-gnu1/arch/x86/Kconfig
--- linux-libre-2.6.34-gnu1/arch/x86/Kconfig	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/Kconfig	2014-02-10 17:31:40.000000000 -0500
@@ -240,6 +240,11 @@ config X86_32_LAZY_GS
 
 config KTIME_SCALAR
 	def_bool X86_32
+
+config ARCH_CPU_PROBE_RELEASE
+	def_bool y
+	depends on HOTPLUG_CPU
+
 source "init/Kconfig"
 source "kernel/Kconfig.freezer"
 
@@ -1455,6 +1460,15 @@ config ARCH_USES_PG_UNCACHED
 	def_bool y
 	depends on X86_PAT
 
+config ARCH_RANDOM
+	def_bool y
+	prompt "x86 architectural random number generator" if EMBEDDED
+	---help---
+	  Enable the x86 architectural RDRAND instruction
+	  (Intel Bull Mountain technology) to generate random numbers.
+	  If supported, this is a high bandwidth, cryptographically
+	  secure hardware random number generator.
+
 config EFI
 	bool "EFI runtime service support"
 	depends on ACPI
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/acpi/boot.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/acpi/boot.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/acpi/boot.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/acpi/boot.c	2014-02-10 17:31:40.000000000 -0500
@@ -73,6 +73,7 @@ u8 acpi_sci_flags __initdata;
 int acpi_sci_override_gsi __initdata;
 int acpi_skip_timer_override __initdata;
 int acpi_use_timer_override __initdata;
+int acpi_fix_pin2_polarity __initdata;
 
 #ifdef CONFIG_X86_LOCAL_APIC
 static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
@@ -363,10 +364,15 @@ acpi_parse_int_src_ovr(struct acpi_subta
 		return 0;
 	}
 
-	if (acpi_skip_timer_override &&
-	    intsrc->source_irq == 0 && intsrc->global_irq == 2) {
-		printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n");
-		return 0;
+	if (intsrc->source_irq == 0 && intsrc->global_irq == 2) {
+		if (acpi_skip_timer_override) {
+			printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n");
+			return 0;
+		}
+		if (acpi_fix_pin2_polarity && (intsrc->inti_flags & ACPI_MADT_POLARITY_MASK)) {
+			intsrc->inti_flags &= ~ACPI_MADT_POLARITY_MASK;
+			printk(PREFIX "BIOS IRQ0 pin2 override: forcing polarity to high active.\n");
+		}
 	}
 
 	mp_override_legacy_irq(intsrc->source_irq,
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/acpi/cstate.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/acpi/cstate.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/acpi/cstate.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/acpi/cstate.c	2014-02-10 17:31:40.000000000 -0500
@@ -13,6 +13,7 @@
 
 #include <acpi/processor.h>
 #include <asm/acpi.h>
+#include <asm/mwait.h>
 
 /*
  * Initialize bm_flags based on the CPU cache properties
@@ -65,16 +66,6 @@ static struct cstate_entry *cpu_cstate_e
 
 static short mwait_supported[ACPI_PROCESSOR_MAX_POWER];
 
-#define MWAIT_SUBSTATE_MASK	(0xf)
-#define MWAIT_CSTATE_MASK	(0xf)
-#define MWAIT_SUBSTATE_SIZE	(4)
-
-#define CPUID_MWAIT_LEAF (5)
-#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1)
-#define CPUID5_ECX_INTERRUPT_BREAK	(0x2)
-
-#define MWAIT_ECX_INTERRUPT_BREAK	(0x1)
-
 #define NATIVE_CSTATE_BEYOND_HALT	(2)
 
 static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
@@ -145,6 +136,15 @@ int acpi_processor_ffh_cstate_probe(unsi
 		percpu_entry->states[cx->index].eax = cx->address;
 		percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK;
 	}
+
+	/*
+	 * For _CST FFH on Intel, if GAS.access_size bit 1 is cleared,
+	 * then we should skip checking BM_STS for this C-state.
+	 * ref: "Intel Processor Vendor-Specific ACPI Interface Specification"
+	 */
+	if ((c->x86_vendor == X86_VENDOR_INTEL) && !(reg->access_size & 0x2))
+		cx->bm_sts_skip = 1;
+
 	return retval;
 }
 EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/acpi/sleep.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/acpi/sleep.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/acpi/sleep.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/acpi/sleep.c	2014-02-10 17:31:40.000000000 -0500
@@ -162,8 +162,6 @@ static int __init acpi_sleep_setup(char
 #endif
 		if (strncmp(str, "old_ordering", 12) == 0)
 			acpi_old_suspend_ordering();
-		if (strncmp(str, "sci_force_enable", 16) == 0)
-			acpi_set_sci_en_on_resume();
 		str = strchr(str, ',');
 		if (str != NULL)
 			str += strspn(str, ", \t");
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/amd_iommu.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/amd_iommu.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/amd_iommu.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/amd_iommu.c	2014-02-10 17:31:40.000000000 -0500
@@ -1046,7 +1046,7 @@ static int alloc_new_range(struct dma_op
 		if (!pte || !IOMMU_PTE_PRESENT(*pte))
 			continue;
 
-		dma_ops_reserve_addresses(dma_dom, i << PAGE_SHIFT, 1);
+		dma_ops_reserve_addresses(dma_dom, i >> PAGE_SHIFT, 1);
 	}
 
 	update_domain(&dma_dom->domain);
@@ -1420,6 +1420,7 @@ static int __attach_device(struct device
 			   struct protection_domain *domain)
 {
 	struct iommu_dev_data *dev_data, *alias_data;
+	int ret;
 
 	dev_data   = get_dev_data(dev);
 	alias_data = get_dev_data(dev_data->alias);
@@ -1431,13 +1432,14 @@ static int __attach_device(struct device
 	spin_lock(&domain->lock);
 
 	/* Some sanity checks */
+	ret = -EBUSY;
 	if (alias_data->domain != NULL &&
 	    alias_data->domain != domain)
-		return -EBUSY;
+		goto out_unlock;
 
 	if (dev_data->domain != NULL &&
 	    dev_data->domain != domain)
-		return -EBUSY;
+		goto out_unlock;
 
 	/* Do real assignment */
 	if (dev_data->alias != dev) {
@@ -1453,10 +1455,14 @@ static int __attach_device(struct device
 
 	atomic_inc(&dev_data->bind);
 
+	ret = 0;
+
+out_unlock:
+
 	/* ready */
 	spin_unlock(&domain->lock);
 
-	return 0;
+	return ret;
 }
 
 /*
@@ -1880,6 +1886,7 @@ static void __unmap_single(struct dma_op
 			   size_t size,
 			   int dir)
 {
+	dma_addr_t flush_addr;
 	dma_addr_t i, start;
 	unsigned int pages;
 
@@ -1887,6 +1894,7 @@ static void __unmap_single(struct dma_op
 	    (dma_addr + size > dma_dom->aperture_size))
 		return;
 
+	flush_addr = dma_addr;
 	pages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
 	dma_addr &= PAGE_MASK;
 	start = dma_addr;
@@ -1901,7 +1909,7 @@ static void __unmap_single(struct dma_op
 	dma_ops_free_addresses(dma_dom, dma_addr, pages);
 
 	if (amd_iommu_unmap_flush || dma_dom->need_flush) {
-		iommu_flush_pages(&dma_dom->domain, dma_addr, size);
+		iommu_flush_pages(&dma_dom->domain, flush_addr, size);
 		dma_dom->need_flush = false;
 	}
 }
@@ -2257,10 +2265,6 @@ int __init amd_iommu_init_dma_ops(void)
 
 	iommu_detected = 1;
 	swiotlb = 0;
-#ifdef CONFIG_GART_IOMMU
-	gart_iommu_aperture_disabled = 1;
-	gart_iommu_aperture = 0;
-#endif
 
 	/* Make the driver finally visible to the drivers */
 	dma_ops = &amd_iommu_dma_ops;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/amd_iommu_init.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/amd_iommu_init.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/amd_iommu_init.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/amd_iommu_init.c	2014-02-10 17:31:40.000000000 -0500
@@ -286,8 +286,12 @@ static u8 * __init iommu_map_mmio_space(
 {
 	u8 *ret;
 
-	if (!request_mem_region(address, MMIO_REGION_LENGTH, "amd_iommu"))
+	if (!request_mem_region(address, MMIO_REGION_LENGTH, "amd_iommu")) {
+		pr_err("AMD-Vi: Can not reserve memory region %llx for mmio\n",
+			address);
+		pr_err("AMD-Vi: This is a BIOS bug. Please contact your hardware vendor\n");
 		return NULL;
+	}
 
 	ret = ioremap_nocache(address, MMIO_REGION_LENGTH);
 	if (ret != NULL)
@@ -627,6 +631,13 @@ static void __init init_iommu_from_pci(s
 	iommu->last_device = calc_devid(MMIO_GET_BUS(range),
 					MMIO_GET_LD(range));
 	iommu->evt_msi_num = MMIO_MSI_NUM(misc);
+
+	if (is_rd890_iommu(iommu->dev)) {
+		pci_read_config_dword(iommu->dev, 0xf0, &iommu->cache_cfg[0]);
+		pci_read_config_dword(iommu->dev, 0xf4, &iommu->cache_cfg[1]);
+		pci_read_config_dword(iommu->dev, 0xf8, &iommu->cache_cfg[2]);
+		pci_read_config_dword(iommu->dev, 0xfc, &iommu->cache_cfg[3]);
+	}
 }
 
 /*
@@ -638,35 +649,15 @@ static void __init init_iommu_from_acpi(
 {
 	u8 *p = (u8 *)h;
 	u8 *end = p, flags = 0;
-	u16 dev_i, devid = 0, devid_start = 0, devid_to = 0;
-	u32 ext_flags = 0;
+	u16 devid = 0, devid_start = 0, devid_to = 0;
+	u32 dev_i, ext_flags = 0;
 	bool alias = false;
 	struct ivhd_entry *e;
 
 	/*
-	 * First set the recommended feature enable bits from ACPI
-	 * into the IOMMU control registers
-	 */
-	h->flags & IVHD_FLAG_HT_TUN_EN_MASK ?
-		iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) :
-		iommu_feature_disable(iommu, CONTROL_HT_TUN_EN);
-
-	h->flags & IVHD_FLAG_PASSPW_EN_MASK ?
-		iommu_feature_enable(iommu, CONTROL_PASSPW_EN) :
-		iommu_feature_disable(iommu, CONTROL_PASSPW_EN);
-
-	h->flags & IVHD_FLAG_RESPASSPW_EN_MASK ?
-		iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) :
-		iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN);
-
-	h->flags & IVHD_FLAG_ISOC_EN_MASK ?
-		iommu_feature_enable(iommu, CONTROL_ISOC_EN) :
-		iommu_feature_disable(iommu, CONTROL_ISOC_EN);
-
-	/*
-	 * make IOMMU memory accesses cache coherent
+	 * First save the recommended feature enable bits from ACPI
 	 */
-	iommu_feature_enable(iommu, CONTROL_COHERENT_EN);
+	iommu->acpi_flags = h->flags;
 
 	/*
 	 * Done. Now parse the device entries
@@ -814,7 +805,7 @@ static void __init init_iommu_from_acpi(
 /* Initializes the device->iommu mapping for the driver */
 static int __init init_iommu_devices(struct amd_iommu *iommu)
 {
-	u16 i;
+	u32 i;
 
 	for (i = iommu->first_device; i <= iommu->last_device; ++i)
 		set_iommu_for_device(iommu, i);
@@ -1103,7 +1094,7 @@ static int __init init_memory_definition
  */
 static void init_device_table(void)
 {
-	u16 devid;
+	u32 devid;
 
 	for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) {
 		set_dev_entry_bit(devid, DEV_ENTRY_VALID);
@@ -1111,6 +1102,40 @@ static void init_device_table(void)
 	}
 }
 
+static void iommu_init_flags(struct amd_iommu *iommu)
+{
+	iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ?
+		iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) :
+		iommu_feature_disable(iommu, CONTROL_HT_TUN_EN);
+
+	iommu->acpi_flags & IVHD_FLAG_PASSPW_EN_MASK ?
+		iommu_feature_enable(iommu, CONTROL_PASSPW_EN) :
+		iommu_feature_disable(iommu, CONTROL_PASSPW_EN);
+
+	iommu->acpi_flags & IVHD_FLAG_RESPASSPW_EN_MASK ?
+		iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) :
+		iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN);
+
+	iommu->acpi_flags & IVHD_FLAG_ISOC_EN_MASK ?
+		iommu_feature_enable(iommu, CONTROL_ISOC_EN) :
+		iommu_feature_disable(iommu, CONTROL_ISOC_EN);
+
+	/*
+	 * make IOMMU memory accesses cache coherent
+	 */
+	iommu_feature_enable(iommu, CONTROL_COHERENT_EN);
+}
+
+static void iommu_apply_quirks(struct amd_iommu *iommu)
+{
+	if (is_rd890_iommu(iommu->dev)) {
+		pci_write_config_dword(iommu->dev, 0xf0, iommu->cache_cfg[0]);
+		pci_write_config_dword(iommu->dev, 0xf4, iommu->cache_cfg[1]);
+		pci_write_config_dword(iommu->dev, 0xf8, iommu->cache_cfg[2]);
+		pci_write_config_dword(iommu->dev, 0xfc, iommu->cache_cfg[3]);
+	}
+}
+
 /*
  * This function finally enables all IOMMUs found in the system after
  * they have been initialized
@@ -1121,6 +1146,8 @@ static void enable_iommus(void)
 
 	for_each_iommu(iommu) {
 		iommu_disable(iommu);
+		iommu_apply_quirks(iommu);
+		iommu_init_flags(iommu);
 		iommu_set_device_table(iommu);
 		iommu_enable_command_buffer(iommu);
 		iommu_enable_event_buffer(iommu);
@@ -1313,7 +1340,7 @@ static int __init amd_iommu_init(void)
 		ret = amd_iommu_init_dma_ops();
 
 	if (ret)
-		goto free;
+		goto free_disable;
 
 	amd_iommu_init_api();
 
@@ -1331,9 +1358,10 @@ static int __init amd_iommu_init(void)
 out:
 	return ret;
 
-free:
+free_disable:
 	disable_iommus();
 
+free:
 	amd_iommu_uninit_devices();
 
 	free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
@@ -1352,6 +1380,15 @@ free:
 
 	free_unity_maps();
 
+#ifdef CONFIG_GART_IOMMU
+	/*
+	 * We failed to initialize the AMD IOMMU - try fallback to GART
+	 * if possible.
+	 */
+	gart_iommu_init();
+
+#endif
+
 	goto out;
 }
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/apic.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/apic/apic.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/apic.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/apic/apic.c	2014-02-10 17:31:40.000000000 -0500
@@ -51,6 +51,7 @@
 #include <asm/smp.h>
 #include <asm/mce.h>
 #include <asm/kvm_para.h>
+#include <asm/tsc.h>
 
 unsigned int num_processors;
 
@@ -920,7 +921,7 @@ void disable_local_APIC(void)
 	unsigned int value;
 
 	/* APIC hasn't been mapped yet */
-	if (!apic_phys)
+	if (!x2apic_mode && !apic_phys)
 		return;
 
 	clear_local_APIC();
@@ -1151,8 +1152,13 @@ static void __cpuinit lapic_setup_esr(vo
  */
 void __cpuinit setup_local_APIC(void)
 {
-	unsigned int value;
-	int i, j;
+	unsigned int value, queued;
+	int i, j, acked = 0;
+	unsigned long long tsc = 0, ntsc;
+	long long max_loops = cpu_khz;
+
+	if (cpu_has_tsc)
+		rdtscll(tsc);
 
 	if (disable_apic) {
 		arch_disable_smp_support();
@@ -1204,13 +1210,32 @@ void __cpuinit setup_local_APIC(void)
 	 * the interrupt. Hence a vector might get locked. It was noticed
 	 * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
 	 */
-	for (i = APIC_ISR_NR - 1; i >= 0; i--) {
-		value = apic_read(APIC_ISR + i*0x10);
-		for (j = 31; j >= 0; j--) {
-			if (value & (1<<j))
-				ack_APIC_irq();
+	do {
+		queued = 0;
+		for (i = APIC_ISR_NR - 1; i >= 0; i--)
+			queued |= apic_read(APIC_IRR + i*0x10);
+
+		for (i = APIC_ISR_NR - 1; i >= 0; i--) {
+			value = apic_read(APIC_ISR + i*0x10);
+			for (j = 31; j >= 0; j--) {
+				if (value & (1<<j)) {
+					ack_APIC_irq();
+					acked++;
+				}
+			}
 		}
-	}
+		if (acked > 256) {
+			printk(KERN_ERR "LAPIC pending interrupts after %d EOI\n",
+			       acked);
+			break;
+		}
+		if (cpu_has_tsc) {
+			rdtscll(ntsc);
+			max_loops = (cpu_khz << 10) - (ntsc - tsc);
+		} else
+			max_loops--;
+	} while (queued && max_loops > 0);
+	WARN_ON(max_loops <= 0);
 
 	/*
 	 * Now that we are all set up, enable the APIC
@@ -1315,6 +1340,14 @@ void __cpuinit end_local_APIC_setup(void
 
 	setup_apic_nmi_watchdog(NULL);
 	apic_pm_activate();
+
+	/*
+	 * Now that local APIC setup is completed for BP, configure the fault
+	 * handling for interrupt remapping.
+	 */
+	if (!smp_processor_id() && intr_remapping_enabled)
+		enable_drhd_fault_handling();
+
 }
 
 #ifdef CONFIG_X86_X2APIC
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/io_apic.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/apic/io_apic.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/io_apic.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/apic/io_apic.c	2014-02-10 17:31:40.000000000 -0500
@@ -303,14 +303,19 @@ void arch_init_copy_chip_data(struct irq
 
 	old_cfg = old_desc->chip_data;
 
-	memcpy(cfg, old_cfg, sizeof(struct irq_cfg));
+	cfg->vector = old_cfg->vector;
+	cfg->move_in_progress = old_cfg->move_in_progress;
+	cpumask_copy(cfg->domain, old_cfg->domain);
+	cpumask_copy(cfg->old_domain, old_cfg->old_domain);
 
 	init_copy_irq_2_pin(old_cfg, cfg, node);
 }
 
-static void free_irq_cfg(struct irq_cfg *old_cfg)
+static void free_irq_cfg(struct irq_cfg *cfg)
 {
-	kfree(old_cfg);
+	free_cpumask_var(cfg->domain);
+	free_cpumask_var(cfg->old_domain);
+	kfree(cfg);
 }
 
 void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
@@ -1396,6 +1401,7 @@ int setup_ioapic_entry(int apic_id, int
 		irte.dlvry_mode = apic->irq_delivery_mode;
 		irte.vector = vector;
 		irte.dest_id = IRTE_DEST(destination);
+		irte.redir_hint = 1;
 
 		/* Set source-id of interrupt request */
 		set_ioapic_sid(&irte, apic_id);
@@ -1732,6 +1738,8 @@ __apicdebuginit(void) print_IO_APIC(void
 		struct irq_pin_list *entry;
 
 		cfg = desc->chip_data;
+		if (!cfg)
+			continue;
 		entry = cfg->irq_2_pin;
 		if (!entry)
 			continue;
@@ -3357,6 +3365,7 @@ static int msi_compose_msg(struct pci_de
 		irte.dlvry_mode = apic->irq_delivery_mode;
 		irte.vector = cfg->vector;
 		irte.dest_id = IRTE_DEST(dest);
+		irte.redir_hint = 1;
 
 		/* Set source-id of interrupt request */
 		if (pdev)
@@ -3413,7 +3422,7 @@ static int set_msi_irq_affinity(unsigned
 
 	cfg = desc->chip_data;
 
-	read_msi_msg_desc(desc, &msg);
+	get_cached_msi_msg_desc(desc, &msg);
 
 	msg.data &= ~MSI_DATA_VECTOR_MASK;
 	msg.data |= MSI_DATA_VECTOR(cfg->vector);
@@ -3633,6 +3642,7 @@ static int dmar_msi_set_affinity(unsigne
 	msg.data |= MSI_DATA_VECTOR(cfg->vector);
 	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
 	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+	msg.address_hi = MSI_ADDR_BASE_HI | MSI_ADDR_EXT_DEST_ID(dest);
 
 	dmar_msi_write(irq, &msg);
 
@@ -4284,6 +4294,7 @@ static int bad_ioapic(unsigned long addr
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 {
 	int idx = 0;
+	int entries;
 
 	if (bad_ioapic(address))
 		return;
@@ -4302,10 +4313,14 @@ void __init mp_register_ioapic(int id, u
 	 * Build basic GSI lookup table to facilitate gsi->io_apic lookups
 	 * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
 	 */
+	entries = io_apic_get_redir_entries(idx);
 	mp_gsi_routing[idx].gsi_base = gsi_base;
-	mp_gsi_routing[idx].gsi_end = gsi_base +
-	    io_apic_get_redir_entries(idx);
+	mp_gsi_routing[idx].gsi_end = gsi_base + entries;
 
+	/*
+	 * The number of IO-APIC IRQ registers (== #pins):
+	 */
+	nr_ioapic_registers[idx] = entries + 1;
 	printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
 	       "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
 	       mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/probe_64.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/apic/probe_64.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/probe_64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/apic/probe_64.c	2014-02-10 17:31:40.000000000 -0500
@@ -76,13 +76,6 @@ void __init default_setup_apic_routing(v
 		/* need to update phys_pkg_id */
 		apic->phys_pkg_id = apicid_phys_pkg_id;
 	}
-
-	/*
-	 * Now that apic routing model is selected, configure the
-	 * fault handling for intr remapping.
-	 */
-	if (intr_remapping_enabled)
-		enable_drhd_fault_handling();
 }
 
 /* Same for both flat and physical. */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c	2014-02-10 17:31:40.000000000 -0500
@@ -144,7 +144,6 @@ static int __cpuinit uv_wakeup_secondary
 	    ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) |
 	    APIC_DM_INIT;
 	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
-	mdelay(10);
 
 	val = (1UL << UVH_IPI_INT_SEND_SHFT) |
 	    (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) |
@@ -694,9 +693,11 @@ void __init uv_system_init(void)
 		for (j = 0; j < 64; j++) {
 			if (!test_bit(j, &present))
 				continue;
-			uv_blade_info[blade].pnode = (i * 64 + j);
+			pnode = (i * 64 + j);
+			uv_blade_info[blade].pnode = pnode;
 			uv_blade_info[blade].nr_possible_cpus = 0;
 			uv_blade_info[blade].nr_online_cpus = 0;
+			max_pnode = max(pnode, max_pnode);
 			blade++;
 		}
 	}
@@ -734,10 +735,6 @@ void __init uv_system_init(void)
 		uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid);
 		uv_node_to_blade[nid] = blade;
 		uv_cpu_to_blade[cpu] = blade;
-		max_pnode = max(pnode, max_pnode);
-
-		printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n",
-			cpu, apicid, pnode, nid, lcpu, blade);
 	}
 
 	/* Add blade/pnode info for nodes without cpus */
@@ -749,7 +746,6 @@ void __init uv_system_init(void)
 		pnode = (paddr >> m_val) & pnode_mask;
 		blade = boot_pnode_to_blade(pnode);
 		uv_node_to_blade[nid] = blade;
-		max_pnode = max(pnode, max_pnode);
 	}
 
 	map_gru_high(max_pnode);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/amd.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/amd.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/amd.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/amd.c	2014-02-10 17:31:40.000000000 -0500
@@ -565,6 +565,35 @@ static void __cpuinit init_amd(struct cp
 		}
 	}
 #endif
+
+	/*
+	 * Family 0x12 and above processors have APIC timer
+	 * running in deep C states.
+	 */
+	if (c->x86 > 0x11)
+		set_cpu_cap(c, X86_FEATURE_ARAT);
+
+	/*
+	 * Disable GART TLB Walk Errors on Fam10h. We do this here
+	 * because this is always needed when GART is enabled, even in a
+	 * kernel which has no MCE support built in.
+	 */
+	if (c->x86 == 0x10) {
+		/*
+		 * BIOS should disable GartTlbWlk Errors themself. If
+		 * it doesn't do it here as suggested by the BKDG.
+		 *
+		 * Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=33012
+		 */
+		u64 mask;
+		int err;
+
+		err = rdmsrl_safe(MSR_AMD64_MCx_MASK(4), &mask);
+		if (err == 0) {
+			mask |= (1 << 10);
+			checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask);
+		}
+	}
 }
 
 #ifdef CONFIG_X86_32
@@ -609,3 +638,68 @@ static const struct cpu_dev __cpuinitcon
 };
 
 cpu_dev_register(amd_cpu_dev);
+
+/*
+ * AMD errata checking
+ *
+ * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or
+ * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that
+ * have an OSVW id assigned, which it takes as first argument. Both take a
+ * variable number of family-specific model-stepping ranges created by
+ * AMD_MODEL_RANGE(). Each erratum also has to be declared as extern const
+ * int[] in arch/x86/include/asm/processor.h.
+ *
+ * Example:
+ *
+ * const int amd_erratum_319[] =
+ *	AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2),
+ *			   AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0),
+ *			   AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0));
+ */
+
+const int amd_erratum_400[] =
+	AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf),
+			    AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf));
+
+
+bool cpu_has_amd_erratum(const int *erratum)
+{
+	struct cpuinfo_x86 *cpu = &current_cpu_data;
+	int osvw_id = *erratum++;
+	u32 range;
+	u32 ms;
+
+	/*
+	 * If called early enough that current_cpu_data hasn't been initialized
+	 * yet, fall back to boot_cpu_data.
+	 */
+	if (cpu->x86 == 0)
+		cpu = &boot_cpu_data;
+
+	if (cpu->x86_vendor != X86_VENDOR_AMD)
+		return false;
+
+	if (osvw_id >= 0 && osvw_id < 65536 &&
+	    cpu_has(cpu, X86_FEATURE_OSVW)) {
+		u64 osvw_len;
+
+		rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len);
+		if (osvw_id < osvw_len) {
+			u64 osvw_bits;
+
+			rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6),
+			    osvw_bits);
+			return osvw_bits & (1ULL << (osvw_id & 0x3f));
+		}
+	}
+
+	/* OSVW unavailable or ID unknown, match family-model-stepping range */
+	ms = (cpu->x86_model << 4) | cpu->x86_mask;
+	while ((range = *erratum++))
+		if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) &&
+		    (ms >= AMD_MODEL_RANGE_START(range)) &&
+		    (ms <= AMD_MODEL_RANGE_END(range)))
+			return true;
+
+	return false;
+}
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/common.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/common.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/common.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/common.c	2014-02-10 17:31:40.000000000 -0500
@@ -537,7 +537,7 @@ void __cpuinit cpu_detect(struct cpuinfo
 	}
 }
 
-static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
+void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
 {
 	u32 tfms, xlvl;
 	u32 ebx;
@@ -576,6 +576,7 @@ static void __cpuinit get_cpu_cap(struct
 	if (c->extended_cpuid_level >= 0x80000007)
 		c->x86_power = cpuid_edx(0x80000007);
 
+	init_scattered_cpuid_features(c);
 }
 
 static void __cpuinit identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
@@ -731,7 +732,6 @@ static void __cpuinit generic_identify(s
 
 	get_model_name(c); /* Default name */
 
-	init_scattered_cpuid_features(c);
 	detect_nopl(c);
 }
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c	2014-02-10 17:31:40.000000000 -0500
@@ -744,6 +744,7 @@ static int acpi_cpufreq_cpu_exit(struct
 		per_cpu(acfreq_data, policy->cpu) = NULL;
 		acpi_processor_unregister_performance(data->acpi_data,
 						      policy->cpu);
+		kfree(data->freq_table);
 		kfree(data);
 	}
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpu.h linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/cpu.h
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/cpu.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/cpu.h	2014-02-10 17:31:40.000000000 -0500
@@ -33,5 +33,6 @@ extern const struct cpu_dev *const __x86
 			    *const __x86_cpu_dev_end[];
 
 extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c);
+extern void get_cpu_cap(struct cpuinfo_x86 *c);
 
 #endif
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/intel.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/intel.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/intel.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/intel.c	2014-02-10 17:31:40.000000000 -0500
@@ -40,6 +40,7 @@ static void __cpuinit early_init_intel(s
 			misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID;
 			wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
 			c->cpuid_level = cpuid_eax(0);
+			get_cpu_cap(c);
 		}
 	}
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/mce_amd.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/mcheck/mce_amd.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/mce_amd.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/mcheck/mce_amd.c	2014-02-10 17:31:40.000000000 -0500
@@ -141,6 +141,7 @@ void mce_amd_feature_init(struct cpuinfo
 				address = (low & MASK_BLKPTR_LO) >> 21;
 				if (!address)
 					break;
+
 				address += MCG_XBLK_ADDR;
 			} else
 				++address;
@@ -148,12 +149,8 @@ void mce_amd_feature_init(struct cpuinfo
 			if (rdmsr_safe(address, &low, &high))
 				break;
 
-			if (!(high & MASK_VALID_HI)) {
-				if (block)
-					continue;
-				else
-					break;
-			}
+			if (!(high & MASK_VALID_HI))
+				continue;
 
 			if (!(high & MASK_CNTP_HI)  ||
 			     (high & MASK_LOCKED_HI))
@@ -472,6 +469,7 @@ recurse:
 out_free:
 	if (b) {
 		kobject_put(&b->kobj);
+		list_del(&b->miscj);
 		kfree(b);
 	}
 	return err;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/mce.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/mcheck/mce.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/mce.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/mcheck/mce.c	2014-02-10 17:31:40.000000000 -0500
@@ -453,6 +453,13 @@ static inline void mce_get_rip(struct mc
 	if (regs && (m->mcgstatus & (MCG_STATUS_RIPV|MCG_STATUS_EIPV))) {
 		m->ip = regs->ip;
 		m->cs = regs->cs;
+		/*
+		 * When in VM86 mode make the cs look like ring 3
+		 * always. This is a lie, but it's better than passing
+		 * the additional vm86 bit around everywhere.
+		 */
+		if (v8086_mode(regs))
+			m->cs |= 3;
 	} else {
 		m->ip = 0;
 		m->cs = 0;
@@ -990,6 +997,7 @@ void do_machine_check(struct pt_regs *re
 		 */
 		add_taint(TAINT_MACHINE_CHECK);
 
+		mce_get_rip(&m, regs);
 		severity = mce_severity(&m, tolerant, NULL);
 
 		/*
@@ -1028,7 +1036,6 @@ void do_machine_check(struct pt_regs *re
 		if (severity == MCE_AO_SEVERITY && mce_usable_address(&m))
 			mce_ring_add(m.addr >> PAGE_SHIFT);
 
-		mce_get_rip(&m, regs);
 		mce_log(&m);
 
 		if (severity > worst) {
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/therm_throt.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/mcheck/therm_throt.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mcheck/therm_throt.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/mcheck/therm_throt.c	2014-02-10 17:31:40.000000000 -0500
@@ -293,18 +293,20 @@ void intel_init_thermal(struct cpuinfo_x
 	 */
 	rdmsr(MSR_IA32_MISC_ENABLE, l, h);
 
+	h = lvtthmr_init;
 	/*
 	 * The initial value of thermal LVT entries on all APs always reads
 	 * 0x10000 because APs are woken up by BSP issuing INIT-SIPI-SIPI
 	 * sequence to them and LVT registers are reset to 0s except for
 	 * the mask bits which are set to 1s when APs receive INIT IPI.
-	 * Always restore the value that BIOS has programmed on AP based on
-	 * BSP's info we saved since BIOS is always setting the same value
-	 * for all threads/cores
+	 * If BIOS takes over the thermal interrupt and sets its interrupt
+	 * delivery mode to SMI (not fixed), it restores the value that the
+	 * BIOS has programmed on AP based on BSP's info we saved since BIOS
+	 * is always setting the same value for all threads/cores.
 	 */
-	apic_write(APIC_LVTTHMR, lvtthmr_init);
+	if ((h & APIC_DM_FIXED_MASK) != APIC_DM_FIXED)
+		apic_write(APIC_LVTTHMR, lvtthmr_init);
 
-	h = lvtthmr_init;
 
 	if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
 		printk(KERN_DEBUG
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/mtrr/cleanup.c	2014-02-10 17:31:40.000000000 -0500
@@ -827,7 +827,7 @@ int __init amd_special_default_mtrr(void
 
 	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
 		return 0;
-	if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11)
+	if (boot_cpu_data.x86 < 0xf)
 		return 0;
 	/* In case some hypervisor doesn't pass SYSCFG through: */
 	if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/main.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/mtrr/main.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/mtrr/main.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/mtrr/main.c	2014-02-10 17:31:40.000000000 -0500
@@ -263,14 +263,24 @@ set_mtrr(unsigned int reg, unsigned long
 
 	/*
 	 * HACK!
-	 * We use this same function to initialize the mtrrs on boot.
-	 * The state of the boot cpu's mtrrs has been saved, and we want
-	 * to replicate across all the APs.
-	 * If we're doing that @reg is set to something special...
+	 *
+	 * We use this same function to initialize the mtrrs during boot,
+	 * resume, runtime cpu online and on an explicit request to set a
+	 * specific MTRR.
+	 *
+	 * During boot or suspend, the state of the boot cpu's mtrrs has been
+	 * saved, and we want to replicate that across all the cpus that come
+	 * online (either at the end of boot or resume or during a runtime cpu
+	 * online). If we're doing that, @reg is set to something special and on
+	 * this cpu we still do mtrr_if->set_all(). During boot/resume, this
+	 * is unnecessary if at this point we are still on the cpu that started
+	 * the boot/resume sequence. But there is no guarantee that we are still
+	 * on the same cpu. So we do mtrr_if->set_all() on this cpu aswell to be
+	 * sure that we are in sync with everyone else.
 	 */
 	if (reg != ~0U)
 		mtrr_if->set(reg, base, size, type);
-	else if (!mtrr_aps_delayed_init)
+	else
 		mtrr_if->set_all();
 
 	/* Wait for the others */
@@ -763,13 +773,21 @@ void set_mtrr_aps_delayed_init(void)
 }
 
 /*
- * MTRR initialization for all AP's
+ * Delayed MTRR initialization for all AP's
  */
 void mtrr_aps_init(void)
 {
 	if (!use_intel())
 		return;
 
+	/*
+	 * Check if someone has requested the delay of AP MTRR initialization,
+	 * by doing set_mtrr_aps_delayed_init(), prior to this point. If not,
+	 * then we are done.
+	 */
+	if (!mtrr_aps_delayed_init)
+		return;
+
 	set_mtrr(~0U, 0, 0, 0);
 	mtrr_aps_delayed_init = false;
 }
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event_amd.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/perf_event_amd.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event_amd.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/perf_event_amd.c	2014-02-10 17:31:40.000000000 -0500
@@ -102,8 +102,8 @@ static const u64 amd_perfmon_event_map[]
   [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
   [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0080,
   [PERF_COUNT_HW_CACHE_MISSES]		= 0x0081,
-  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
-  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c2,
+  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c3,
 };
 
 static u64 amd_pmu_event_map(int hw_event)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/perf_event.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/perf_event.c	2014-02-10 17:31:40.000000000 -0500
@@ -460,8 +460,11 @@ static int __hw_perf_event_init(struct p
 		if (atomic_read(&active_events) == 0) {
 			if (!reserve_pmc_hardware())
 				err = -EBUSY;
-			else
+			else {
 				err = reserve_bts_hardware();
+				if (err)
+					release_pmc_hardware();
+			}
 		}
 		if (!err)
 			atomic_inc(&active_events);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event_intel.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/perf_event_intel.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/perf_event_intel.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/perf_event_intel.c	2014-02-10 17:31:40.000000000 -0500
@@ -72,6 +72,7 @@ static struct event_constraint intel_wes
 	INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
 	INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */
 	INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
+	INTEL_EVENT_CONSTRAINT(0xb3, 0x1), /* SNOOPQ_REQUEST_OUTSTANDING */
 	EVENT_CONSTRAINT_END
 };
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/vmware.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/vmware.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/cpu/vmware.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/cpu/vmware.c	2014-02-10 17:31:40.000000000 -0500
@@ -23,6 +23,7 @@
 
 #include <linux/dmi.h>
 #include <linux/module.h>
+#include <linux/jiffies.h>
 #include <asm/div64.h>
 #include <asm/vmware.h>
 #include <asm/x86_init.h>
@@ -51,7 +52,7 @@ static inline int __vmware_platform(void
 
 static unsigned long vmware_get_tsc_khz(void)
 {
-	uint64_t tsc_hz;
+	uint64_t tsc_hz, lpj;
 	uint32_t eax, ebx, ecx, edx;
 
 	VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
@@ -62,6 +63,13 @@ static unsigned long vmware_get_tsc_khz(
 	printk(KERN_INFO "TSC freq read from hypervisor : %lu.%03lu MHz\n",
 			 (unsigned long) tsc_hz / 1000,
 			 (unsigned long) tsc_hz % 1000);
+
+	if (!preset_lpj) {
+		lpj = ((u64)tsc_hz * 1000);
+		do_div(lpj, HZ);
+		preset_lpj = lpj;
+	}
+
 	return tsc_hz;
 }
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/crash_dump_64.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/crash_dump_64.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/crash_dump_64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/crash_dump_64.c	2014-02-10 17:31:40.000000000 -0500
@@ -34,7 +34,7 @@ ssize_t copy_oldmem_page(unsigned long p
 	if (!csize)
 		return 0;
 
-	vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
+	vaddr = ioremap_cache(pfn << PAGE_SHIFT, PAGE_SIZE);
 	if (!vaddr)
 		return -ENOMEM;
 
@@ -46,6 +46,7 @@ ssize_t copy_oldmem_page(unsigned long p
 	} else
 		memcpy(buf, vaddr + offset, csize);
 
+	set_iounmap_nonlazy();
 	iounmap(vaddr);
 	return csize;
 }
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/e820.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/e820.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/e820.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/e820.c	2014-02-10 17:31:40.000000000 -0500
@@ -980,15 +980,21 @@ static int __init parse_memopt(char *p)
 	if (!p)
 		return -EINVAL;
 
-#ifdef CONFIG_X86_32
 	if (!strcmp(p, "nopentium")) {
+#ifdef CONFIG_X86_32
 		setup_clear_cpu_cap(X86_FEATURE_PSE);
 		return 0;
-	}
+#else
+		printk(KERN_WARNING "mem=nopentium ignored! (only supported on x86_32)\n");
+		return -EINVAL;
 #endif
+	}
 
 	userdef = 1;
 	mem_size = memparse(p, &p);
+	/* don't remove all of memory when handling "mem={invalid}" param */
+	if (mem_size == 0)
+		return -EINVAL;
 	e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
 
 	return 0;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/early-quirks.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/early-quirks.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/early-quirks.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/early-quirks.c	2014-02-10 17:31:40.000000000 -0500
@@ -145,15 +145,10 @@ static void __init ati_bugs(int num, int
 
 static u32 __init ati_sbx00_rev(int num, int slot, int func)
 {
-	u32 old, d;
+	u32 d;
 
-	d = read_pci_config(num, slot, func, 0x70);
-	old = d;
-	d &= ~(1<<8);
-	write_pci_config(num, slot, func, 0x70, d);
 	d = read_pci_config(num, slot, func, 0x8);
 	d &= 0xff;
-	write_pci_config(num, slot, func, 0x70, old);
 
 	return d;
 }
@@ -162,11 +157,19 @@ static void __init ati_bugs_contd(int nu
 {
 	u32 d, rev;
 
-	if (acpi_use_timer_override)
+	rev = ati_sbx00_rev(num, slot, func);
+	if (rev >= 0x40)
+		acpi_fix_pin2_polarity = 1;
+
+	/*
+	 * SB600: revisions 0x11, 0x12, 0x13, 0x14, ...
+	 * SB700: revisions 0x39, 0x3a, ...
+	 * SB800: revisions 0x40, 0x41, ...
+	 */
+	if (rev >= 0x39)
 		return;
 
-	rev = ati_sbx00_rev(num, slot, func);
-	if (rev > 0x13)
+	if (acpi_use_timer_override)
 		return;
 
 	/* check for IRQ0 interrupt swap */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/efi.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/efi.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/efi.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/efi.c	2014-02-10 17:31:40.000000000 -0500
@@ -459,9 +459,6 @@ void __init efi_init(void)
 	x86_platform.set_wallclock = efi_set_rtc_mmss;
 #endif
 
-	/* Setup for EFI runtime service */
-	reboot_type = BOOT_EFI;
-
 #if EFI_DEBUG
 	print_efi_memmap();
 #endif
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/entry_64.S linux-libre-2.6.34.15-gnu1/arch/x86/kernel/entry_64.S
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/entry_64.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/entry_64.S	2014-02-10 17:31:40.000000000 -0500
@@ -1268,7 +1268,7 @@ ENTRY(xen_do_hypervisor_callback)   # do
 	decl PER_CPU_VAR(irq_count)
 	jmp  error_exit
 	CFI_ENDPROC
-END(do_hypervisor_callback)
+END(xen_do_hypervisor_callback)
 
 /*
  * Hypervisor uses this for application faults while it executes.
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/head_32.S linux-libre-2.6.34.15-gnu1/arch/x86/kernel/head_32.S
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/head_32.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/head_32.S	2014-02-10 17:31:40.000000000 -0500
@@ -328,7 +328,7 @@ ENTRY(startup_32_smp)
 /*
  * Enable paging
  */
-	movl $pa(swapper_pg_dir),%eax
+	movl pa(initial_page_table), %eax
 	movl %eax,%cr3		/* set the page table pointer.. */
 	movl %cr0,%eax
 	orl  $X86_CR0_PG,%eax
@@ -608,6 +608,8 @@ ignore_int:
 .align 4
 ENTRY(initial_code)
 	.long i386_start_kernel
+ENTRY(initial_page_table)
+	.long pa(swapper_pg_dir)
 
 /*
  * BSS section
@@ -623,6 +625,10 @@ ENTRY(swapper_pg_dir)
 #endif
 swapper_pg_fixmap:
 	.fill 1024,4,0
+#ifdef CONFIG_X86_TRAMPOLINE
+ENTRY(trampoline_pg_dir)
+	.fill 1024,4,0
+#endif
 ENTRY(empty_zero_page)
 	.fill 4096,1,0
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/hpet.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/hpet.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/hpet.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/hpet.c	2014-02-10 17:31:40.000000000 -0500
@@ -28,6 +28,9 @@
 #define HPET_DEV_FSB_CAP		0x1000
 #define HPET_DEV_PERI_CAP		0x2000
 
+#define HPET_MIN_CYCLES			128
+#define HPET_MIN_PROG_DELTA		(HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1))
+
 #define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt)
 
 /*
@@ -300,8 +303,9 @@ static void hpet_legacy_clockevent_regis
 	/* Calculate the min / max delta */
 	hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
 							   &hpet_clockevent);
-	/* 5 usec minimum reprogramming delta. */
-	hpet_clockevent.min_delta_ns = 5000;
+	/* Setup minimum reprogramming delta. */
+	hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA,
+							   &hpet_clockevent);
 
 	/*
 	 * Start hpet with the boot cpu mask and make it
@@ -381,36 +385,37 @@ static int hpet_next_event(unsigned long
 			   struct clock_event_device *evt, int timer)
 {
 	u32 cnt;
+	s32 res;
 
 	cnt = hpet_readl(HPET_COUNTER);
 	cnt += (u32) delta;
 	hpet_writel(cnt, HPET_Tn_CMP(timer));
 
 	/*
-	 * We need to read back the CMP register on certain HPET
-	 * implementations (ATI chipsets) which seem to delay the
-	 * transfer of the compare register into the internal compare
-	 * logic. With small deltas this might actually be too late as
-	 * the counter could already be higher than the compare value
-	 * at that point and we would wait for the next hpet interrupt
-	 * forever. We found out that reading the CMP register back
-	 * forces the transfer so we can rely on the comparison with
-	 * the counter register below. If the read back from the
-	 * compare register does not match the value we programmed
-	 * then we might have a real hardware problem. We can not do
-	 * much about it here, but at least alert the user/admin with
-	 * a prominent warning.
-	 * An erratum on some chipsets (ICH9,..), results in comparator read
-	 * immediately following a write returning old value. Workaround
-	 * for this is to read this value second time, when first
-	 * read returns old value.
+	 * HPETs are a complete disaster. The compare register is
+	 * based on a equal comparison and neither provides a less
+	 * than or equal functionality (which would require to take
+	 * the wraparound into account) nor a simple count down event
+	 * mode. Further the write to the comparator register is
+	 * delayed internally up to two HPET clock cycles in certain
+	 * chipsets (ATI, ICH9,10). Some newer AMD chipsets have even
+	 * longer delays. We worked around that by reading back the
+	 * compare register, but that required another workaround for
+	 * ICH9,10 chips where the first readout after write can
+	 * return the old stale value. We already had a minimum
+	 * programming delta of 5us enforced, but a NMI or SMI hitting
+	 * between the counter readout and the comparator write can
+	 * move us behind that point easily. Now instead of reading
+	 * the compare register back several times, we make the ETIME
+	 * decision based on the following: Return ETIME if the
+	 * counter value after the write is less than HPET_MIN_CYCLES
+	 * away from the event or if the counter is already ahead of
+	 * the event. The minimum programming delta for the generic
+	 * clockevents code is set to 1.5 * HPET_MIN_CYCLES.
 	 */
-	if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) {
-		WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt,
-		  KERN_WARNING "hpet: compare register read back failed.\n");
-	}
+	res = (s32)(cnt - hpet_readl(HPET_COUNTER));
 
-	return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
+	return res < HPET_MIN_CYCLES ? -ETIME : 0;
 }
 
 static void hpet_legacy_set_mode(enum clock_event_mode mode,
@@ -499,7 +504,7 @@ static int hpet_assign_irq(struct hpet_d
 {
 	unsigned int irq;
 
-	irq = create_irq();
+	irq = create_irq_nr(0, -1);
 	if (!irq)
 		return -EINVAL;
 
@@ -959,7 +964,7 @@ fs_initcall(hpet_late_init);
 
 void hpet_disable(void)
 {
-	if (is_hpet_capable()) {
+	if (is_hpet_capable() && hpet_virt_address) {
 		unsigned int cfg = hpet_readl(HPET_CFG);
 
 		if (hpet_legacy_int_enabled) {
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/i8259.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/i8259.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/i8259.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/i8259.c	2014-02-10 17:31:40.000000000 -0500
@@ -276,16 +276,6 @@ static struct sys_device device_i8259A =
 	.cls	= &i8259_sysdev_class,
 };
 
-static int __init i8259A_init_sysfs(void)
-{
-	int error = sysdev_class_register(&i8259_sysdev_class);
-	if (!error)
-		error = sysdev_register(&device_i8259A);
-	return error;
-}
-
-device_initcall(i8259A_init_sysfs);
-
 static void mask_8259A(void)
 {
 	unsigned long flags;
@@ -407,3 +397,18 @@ struct legacy_pic default_legacy_pic = {
 };
 
 struct legacy_pic *legacy_pic = &default_legacy_pic;
+
+static int __init i8259A_init_sysfs(void)
+{
+	int error;
+
+	if (legacy_pic != &default_legacy_pic)
+		return 0;
+
+	error = sysdev_class_register(&i8259_sysdev_class);
+	if (!error)
+		error = sysdev_register(&device_i8259A);
+	return error;
+}
+
+device_initcall(i8259A_init_sysfs);
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/kprobes.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/kprobes.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/kprobes.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/kprobes.c	2014-02-10 17:31:40.000000000 -0500
@@ -75,8 +75,10 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kpr
 	/*
 	 * Undefined/reserved opcodes, conditional jump, Opcode Extension
 	 * Groups, and some special opcodes can not boost.
+	 * This is non-const to keep gcc from statically optimizing it out, as
+	 * variable_test_bit makes gcc think only *(unsigned long*) is used.
 	 */
-static const u32 twobyte_is_boostable[256 / 32] = {
+static u32 twobyte_is_boostable[256 / 32] = {
 	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f          */
 	/*      ----------------------------------------------          */
 	W(0x00, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0) | /* 00 */
@@ -632,8 +634,8 @@ static int __kprobes kprobe_handler(stru
 	/* Skip cs, ip, orig_ax and gs. */	\
 	"	subl $16, %esp\n"	\
 	"	pushl %fs\n"		\
-	"	pushl %ds\n"		\
 	"	pushl %es\n"		\
+	"	pushl %ds\n"		\
 	"	pushl %eax\n"		\
 	"	pushl %ebp\n"		\
 	"	pushl %edi\n"		\
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/Makefile linux-libre-2.6.34.15-gnu1/arch/x86/kernel/Makefile
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/Makefile	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/Makefile	2014-02-10 17:31:40.000000000 -0500
@@ -11,6 +11,8 @@ ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_tsc.o = -pg
 CFLAGS_REMOVE_rtc.o = -pg
 CFLAGS_REMOVE_paravirt-spinlocks.o = -pg
+CFLAGS_REMOVE_pvclock.o = -pg
+CFLAGS_REMOVE_kvmclock.o = -pg
 CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_early_printk.o = -pg
 endif
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/microcode_amd.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/microcode_amd.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/microcode_amd.c	2013-05-03 09:43:44.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/microcode_amd.c	2014-02-11 14:50:03.000000000 -0500
@@ -66,7 +66,6 @@ struct microcode_amd {
 	unsigned int			mpb[0];
 };
 
-#define UCODE_MAX_SIZE			2048
 #define UCODE_CONTAINER_SECTION_HDR	8
 #define UCODE_CONTAINER_HEADER_SIZE	12
 
@@ -155,6 +154,37 @@ static int apply_microcode_amd(int cpu)
 	return 0;
 }
 
+static unsigned int verify_ucode_size(int cpu, const u8 *buf, unsigned int size)
+{
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
+	unsigned int max_size, actual_size;
+
+#define F1XH_MPB_MAX_SIZE 2048
+#define F14H_MPB_MAX_SIZE 1824
+#define F15H_MPB_MAX_SIZE 4096
+
+	switch (c->x86) {
+	case 0x14:
+		max_size = F14H_MPB_MAX_SIZE;
+		break;
+	case 0x15:
+		max_size = F15H_MPB_MAX_SIZE;
+		break;
+	default:
+		max_size = F1XH_MPB_MAX_SIZE;
+		break;
+	}
+
+	actual_size = buf[4] + (buf[5] << 8);
+
+	if (actual_size > size || actual_size > max_size) {
+		pr_err("section size mismatch\n");
+		return 0;
+	}
+
+	return actual_size;
+}
+
 static int get_ucode_data(void *to, const u8 *from, size_t n)
 {
 	memcpy(to, from, n);
@@ -162,37 +192,29 @@ static int get_ucode_data(void *to, cons
 }
 
 static void *
-get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size)
+get_next_ucode(int cpu, const u8 *buf, unsigned int size, unsigned int *mc_size)
 {
-	unsigned int total_size;
-	u8 section_hdr[UCODE_CONTAINER_SECTION_HDR];
-	void *mc;
-
-	if (get_ucode_data(section_hdr, buf, UCODE_CONTAINER_SECTION_HDR))
-		return NULL;
+	void *mc = NULL;
+	unsigned int actual_size = 0;
 
-	if (section_hdr[0] != UCODE_UCODE_TYPE) {
+	if (buf[0] != UCODE_UCODE_TYPE) {
 		pr_err("error: invalid type field in container file section header\n");
-		return NULL;
+		goto out;
 	}
 
-	total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));
+	actual_size = verify_ucode_size(cpu, buf, size);
+	if (!actual_size)
+		goto out;
 
-	if (total_size > size || total_size > UCODE_MAX_SIZE) {
-		pr_err("error: size mismatch\n");
-		return NULL;
-	}
+	mc = vmalloc(actual_size);
+	if (!mc)
+		goto out;
 
-	mc = vmalloc(UCODE_MAX_SIZE);
-	if (mc) {
-		memset(mc, 0, UCODE_MAX_SIZE);
-		if (get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR,
-				   total_size)) {
-			vfree(mc);
-			mc = NULL;
-		} else
-			*mc_size = total_size + UCODE_CONTAINER_SECTION_HDR;
-	}
+	memset(mc, 0, actual_size);
+	get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR, actual_size);
+	*mc_size = actual_size + UCODE_CONTAINER_SECTION_HDR;
+
+out:
 	return mc;
 }
 
@@ -258,7 +280,7 @@ generic_load_microcode(int cpu, const u8
 		unsigned int uninitialized_var(mc_size);
 		struct microcode_header_amd *mc_header;
 
-		mc = get_next_ucode(ucode_ptr, leftover, &mc_size);
+		mc = get_next_ucode(cpu, ucode_ptr, leftover, &mc_size);
 		if (!mc)
 			break;
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/mpparse.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/mpparse.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/mpparse.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/mpparse.c	2014-02-10 17:31:40.000000000 -0500
@@ -94,8 +94,8 @@ static void __init MP_bus_info(struct mp
 	}
 #endif
 
+	set_bit(m->busid, mp_bus_not_pci);
 	if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA) - 1) == 0) {
-		set_bit(m->busid, mp_bus_not_pci);
 #if defined(CONFIG_EISA) || defined(CONFIG_MCA)
 		mp_bus_id_to_type[m->busid] = MP_BUS_ISA;
 #endif
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/msr.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/msr.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/msr.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/msr.c	2014-02-10 17:31:40.000000000 -0500
@@ -176,6 +176,9 @@ static int msr_open(struct inode *inode,
 	unsigned int cpu;
 	struct cpuinfo_x86 *c;
 
+	if (!capable(CAP_SYS_RAWIO))
+		return -EPERM;
+
 	cpu = iminor(file->f_path.dentry->d_inode);
 	if (cpu >= nr_cpu_ids || !cpu_online(cpu))
 		return -ENXIO;	/* No such CPU */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/olpc.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/olpc.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/olpc.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/olpc.c	2014-02-10 17:31:40.000000000 -0500
@@ -117,6 +117,7 @@ int olpc_ec_cmd(unsigned char cmd, unsig
 	unsigned long flags;
 	int ret = -EIO;
 	int i;
+	int restarts = 0;
 
 	spin_lock_irqsave(&ec_lock, flags);
 
@@ -173,7 +174,9 @@ restart:
 			if (wait_on_obf(0x6c, 1)) {
 				printk(KERN_ERR "olpc-ec:  timeout waiting for"
 						" EC to provide data!\n");
-				goto restart;
+				if (restarts++ < 10)
+					goto restart;
+				goto err;
 			}
 			outbuf[i] = inb(0x68);
 			printk(KERN_DEBUG "olpc-ec:  received 0x%x\n",
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/pci-calgary_64.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/pci-calgary_64.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/pci-calgary_64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/pci-calgary_64.c	2014-02-10 17:31:40.000000000 -0500
@@ -103,11 +103,16 @@ int use_calgary __read_mostly = 0;
 #define PMR_SOFTSTOPFAULT	0x40000000
 #define PMR_HARDSTOP		0x20000000
 
-#define MAX_NUM_OF_PHBS		8 /* how many PHBs in total? */
-#define MAX_NUM_CHASSIS		8 /* max number of chassis */
-/* MAX_PHB_BUS_NUM is the maximal possible dev->bus->number */
-#define MAX_PHB_BUS_NUM		(MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2)
-#define PHBS_PER_CALGARY	4
+/*
+ * The maximum PHB bus number.
+ * x3950M2 (rare): 8 chassis, 48 PHBs per chassis = 384
+ * x3950M2: 4 chassis, 48 PHBs per chassis        = 192
+ * x3950 (PCIE): 8 chassis, 32 PHBs per chassis   = 256
+ * x3950 (PCIX): 8 chassis, 16 PHBs per chassis   = 128
+ */
+#define MAX_PHB_BUS_NUM		256
+
+#define PHBS_PER_CALGARY	  4
 
 /* register offsets in Calgary's internal register space */
 static const unsigned long tar_offsets[] = {
@@ -1051,8 +1056,6 @@ static int __init calgary_init_one(struc
 	struct iommu_table *tbl;
 	int ret;
 
-	BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM);
-
 	bbar = busno_to_bbar(dev->bus->number);
 	ret = calgary_setup_tar(dev, bbar);
 	if (ret)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/process_32.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/process_32.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/process_32.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/process_32.c	2014-02-10 17:31:40.000000000 -0500
@@ -253,7 +253,6 @@ start_thread(struct pt_regs *regs, unsig
 {
 	set_user_gs(regs, 0);
 	regs->fs		= 0;
-	set_fs(USER_DS);
 	regs->ds		= __USER_DS;
 	regs->es		= __USER_DS;
 	regs->ss		= __USER_DS;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/process_64.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/process_64.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/process_64.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/process_64.c	2014-02-10 17:31:40.000000000 -0500
@@ -345,7 +345,6 @@ start_thread_common(struct pt_regs *regs
 	regs->cs		= _cs;
 	regs->ss		= _ss;
 	regs->flags		= X86_EFLAGS_IF;
-	set_fs(USER_DS);
 	/*
 	 * Free the old FP and other extended state
 	 */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/process.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/process.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/process.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/process.c	2014-02-10 17:31:40.000000000 -0500
@@ -525,42 +525,6 @@ static int __cpuinit mwait_usable(const
 	return (edx & MWAIT_EDX_C1);
 }
 
-/*
- * Check for AMD CPUs, where APIC timer interrupt does not wake up CPU from C1e.
- * For more information see
- * - Erratum #400 for NPT family 0xf and family 0x10 CPUs
- * - Erratum #365 for family 0x11 (not affected because C1e not in use)
- */
-static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
-{
-	u64 val;
-	if (c->x86_vendor != X86_VENDOR_AMD)
-		goto no_c1e_idle;
-
-	/* Family 0x0f models < rev F do not have C1E */
-	if (c->x86 == 0x0F && c->x86_model >= 0x40)
-		return 1;
-
-	if (c->x86 == 0x10) {
-		/*
-		 * check OSVW bit for CPUs that are not affected
-		 * by erratum #400
-		 */
-		if (cpu_has(c, X86_FEATURE_OSVW)) {
-			rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val);
-			if (val >= 2) {
-				rdmsrl(MSR_AMD64_OSVW_STATUS, val);
-				if (!(val & BIT(1)))
-					goto no_c1e_idle;
-			}
-		}
-		return 1;
-	}
-
-no_c1e_idle:
-	return 0;
-}
-
 static cpumask_var_t c1e_mask;
 static int c1e_detected;
 
@@ -638,7 +602,8 @@ void __cpuinit select_idle_routine(const
 		 */
 		printk(KERN_INFO "using mwait in idle threads.\n");
 		pm_idle = mwait_idle;
-	} else if (check_c1e_idle(c)) {
+	} else if (cpu_has_amd_erratum(amd_erratum_400)) {
+		/* E400: APIC timer interrupt does not wake up CPU from C1e */
 		printk(KERN_INFO "using C1E aware idle routine\n");
 		pm_idle = c1e_idle;
 	} else
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/ptrace.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/ptrace.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/ptrace.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/ptrace.c	2014-02-10 17:31:40.000000000 -0500
@@ -1730,7 +1730,7 @@ void send_sigtrap(struct task_struct *ts
  * We must return the syscall number to actually look up in the table.
  * This can be -1L to skip running any syscall at all.
  */
-asmregparm long syscall_trace_enter(struct pt_regs *regs)
+long syscall_trace_enter(struct pt_regs *regs)
 {
 	long ret = 0;
 
@@ -1775,7 +1775,7 @@ asmregparm long syscall_trace_enter(stru
 	return ret ?: regs->orig_ax;
 }
 
-asmregparm void syscall_trace_leave(struct pt_regs *regs)
+void syscall_trace_leave(struct pt_regs *regs)
 {
 	bool step;
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/pvclock.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/pvclock.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/pvclock.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/pvclock.c	2014-02-10 17:31:40.000000000 -0500
@@ -74,7 +74,8 @@ static inline u64 scale_delta(u64 delta,
 static u64 pvclock_get_nsec_offset(struct pvclock_shadow_time *shadow)
 {
 	u64 delta = native_read_tsc() - shadow->tsc_timestamp;
-	return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift);
+	return pvclock_scale_delta(delta, shadow->tsc_to_nsec_mul,
+				   shadow->tsc_shift);
 }
 
 /*
@@ -109,11 +110,19 @@ unsigned long pvclock_tsc_khz(struct pvc
 	return pv_tsc_khz;
 }
 
+static atomic64_t last_value = ATOMIC64_INIT(0);
+
+void pvclock_resume(void)
+{
+	atomic64_set(&last_value, 0);
+}
+
 cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
 {
 	struct pvclock_shadow_time shadow;
 	unsigned version;
 	cycle_t ret, offset;
+	u64 last;
 
 	do {
 		version = pvclock_get_time_values(&shadow, src);
@@ -123,6 +132,27 @@ cycle_t pvclock_clocksource_read(struct
 		barrier();
 	} while (version != src->version);
 
+	/*
+	 * Assumption here is that last_value, a global accumulator, always goes
+	 * forward. If we are less than that, we should not be much smaller.
+	 * We assume there is an error marging we're inside, and then the correction
+	 * does not sacrifice accuracy.
+	 *
+	 * For reads: global may have changed between test and return,
+	 * but this means someone else updated poked the clock at a later time.
+	 * We just need to make sure we are not seeing a backwards event.
+	 *
+	 * For updates: last_value = ret is not enough, since two vcpus could be
+	 * updating at the same time, and one of them could be slightly behind,
+	 * making the assumption that last_value always go forward fail to hold.
+	 */
+	last = atomic64_read(&last_value);
+	do {
+		if (ret < last)
+			return last;
+		last = atomic64_cmpxchg(&last_value, last, ret);
+	} while (unlikely(last != ret));
+
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/reboot.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/reboot.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/reboot.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/reboot.c	2014-02-10 17:31:40.000000000 -0500
@@ -469,6 +469,14 @@ static struct dmi_system_id __initdata p
 			DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"),
 		},
 	},
+	{	/* Handle problems with rebooting on the Latitude E5420. */
+		.callback = set_pci_reboot,
+		.ident = "Dell Latitude E5420",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5420"),
+		},
+	},
 	{ }
 };
 
@@ -633,7 +641,7 @@ void native_machine_shutdown(void)
 	/* O.K Now that I'm on the appropriate processor,
 	 * stop all of the others.
 	 */
-	smp_send_stop();
+	stop_other_cpus();
 #endif
 
 	lapic_shutdown();
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/relocate_kernel_32.S linux-libre-2.6.34.15-gnu1/arch/x86/kernel/relocate_kernel_32.S
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/relocate_kernel_32.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/relocate_kernel_32.S	2014-02-10 17:31:40.000000000 -0500
@@ -97,6 +97,8 @@ relocate_kernel:
 	ret
 
 identity_mapped:
+	/* set return address to 0 if not preserving context */
+	pushl	$0
 	/* store the start address on the stack */
 	pushl   %edx
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/relocate_kernel_64.S linux-libre-2.6.34.15-gnu1/arch/x86/kernel/relocate_kernel_64.S
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/relocate_kernel_64.S	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/relocate_kernel_64.S	2014-02-10 17:31:40.000000000 -0500
@@ -100,6 +100,8 @@ relocate_kernel:
 	ret
 
 identity_mapped:
+	/* set return address to 0 if not preserving context */
+	pushq	$0
 	/* store the start address on the stack */
 	pushq   %rdx
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/setup.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/setup.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/setup.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/setup.c	2014-02-10 17:31:40.000000000 -0500
@@ -676,6 +676,17 @@ static struct dmi_system_id __initdata b
 			DMI_MATCH(DMI_BOARD_NAME, "DG45FC"),
 		},
 	},
+	/*
+	 * The Dell Inspiron Mini 1012 has DMI_BIOS_VENDOR = "Dell Inc.", so
+	 * match on the product name.
+	 */
+	{
+		.callback = dmi_low_memory_corruption,
+		.ident = "Phoenix BIOS",
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
+		},
+	},
 #endif
 	{}
 };
@@ -996,6 +1007,8 @@ void __init setup_arch(char **cmdline_p)
 	paging_init();
 	x86_init.paging.pagetable_setup_done(swapper_pg_dir);
 
+	setup_trampoline_page_table();
+
 	tboot_probe();
 
 #ifdef CONFIG_X86_64
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/smpboot.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/smpboot.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/smpboot.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/smpboot.c	2014-02-10 17:31:40.000000000 -0500
@@ -62,6 +62,7 @@
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/mtrr.h>
+#include <asm/mwait.h>
 #include <asm/vmi.h>
 #include <asm/apic.h>
 #include <asm/setup.h>
@@ -73,7 +74,6 @@
 
 #ifdef CONFIG_X86_32
 u8 apicid_2_node[MAX_APICID];
-static int low_mappings;
 #endif
 
 /* State of each CPU */
@@ -91,6 +91,25 @@ DEFINE_PER_CPU(int, cpu_state) = { 0 };
 static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
 #define get_idle_for_cpu(x)      (per_cpu(idle_thread_array, x))
 #define set_idle_for_cpu(x, p)   (per_cpu(idle_thread_array, x) = (p))
+
+/*
+ * We need this for trampoline_base protection from concurrent accesses when
+ * off- and onlining cores wildly.
+ */
+static DEFINE_MUTEX(x86_cpu_hotplug_driver_mutex);
+
+void cpu_hotplug_driver_lock()
+{
+        mutex_lock(&x86_cpu_hotplug_driver_mutex);
+}
+
+void cpu_hotplug_driver_unlock()
+{
+        mutex_unlock(&x86_cpu_hotplug_driver_mutex);
+}
+
+ssize_t arch_cpu_probe(const char *buf, size_t count) { return -1; }
+ssize_t arch_cpu_release(const char *buf, size_t count) { return -1; }
 #else
 static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
 #define get_idle_for_cpu(x)      (idle_thread_array[(x)])
@@ -281,6 +300,18 @@ notrace static void __cpuinit start_seco
 	 * fragile that we want to limit the things done here to the
 	 * most necessary things.
 	 */
+
+#ifdef CONFIG_X86_32
+	/*
+	 * Switch away from the trampoline page-table
+	 *
+	 * Do this before cpu_init() because it needs to access per-cpu
+	 * data which may not be mapped in the trampoline page-table.
+	 */
+	load_cr3(swapper_pg_dir);
+	__flush_tlb_all();
+#endif
+
 	vmi_bringup();
 	cpu_init();
 	preempt_disable();
@@ -299,12 +330,6 @@ notrace static void __cpuinit start_seco
 		legacy_pic->chip->unmask(0);
 	}
 
-#ifdef CONFIG_X86_32
-	while (low_mappings)
-		cpu_relax();
-	__flush_tlb_all();
-#endif
-
 	/* This must be done before setting cpu_online_mask */
 	set_cpu_sibling_map(raw_smp_processor_id());
 	wmb();
@@ -754,6 +779,7 @@ do_rest:
 #ifdef CONFIG_X86_32
 	/* Stack for startup_32 can be just as for start_secondary onwards */
 	irq_ctx_init(cpu);
+	initial_page_table = __pa(&trampoline_pg_dir);
 #else
 	clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
 	initial_gs = per_cpu_offset(cpu);
@@ -894,20 +920,8 @@ int __cpuinit native_cpu_up(unsigned int
 
 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 
-#ifdef CONFIG_X86_32
-	/* init low mem mapping */
-	clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
-		min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
-	flush_tlb_all();
-	low_mappings = 1;
-
 	err = do_boot_cpu(apicid, cpu);
 
-	zap_low_mappings(false);
-	low_mappings = 0;
-#else
-	err = do_boot_cpu(apicid, cpu);
-#endif
 	if (err) {
 		pr_debug("do_boot_cpu failed %d\n", err);
 		return -EIO;
@@ -1347,11 +1361,88 @@ void play_dead_common(void)
 	local_irq_disable();
 }
 
+/*
+ * We need to flush the caches before going to sleep, lest we have
+ * dirty data in our caches when we come back up.
+ */
+static inline void mwait_play_dead(void)
+{
+	unsigned int eax, ebx, ecx, edx;
+	unsigned int highest_cstate = 0;
+	unsigned int highest_subcstate = 0;
+	int i;
+	void *mwait_ptr;
+
+	if (!cpu_has(&current_cpu_data, X86_FEATURE_MWAIT))
+		return;
+	if (!cpu_has(&current_cpu_data, X86_FEATURE_CLFLSH))
+		return;
+	if (current_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
+		return;
+
+	eax = CPUID_MWAIT_LEAF;
+	ecx = 0;
+	native_cpuid(&eax, &ebx, &ecx, &edx);
+
+	/*
+	 * eax will be 0 if EDX enumeration is not valid.
+	 * Initialized below to cstate, sub_cstate value when EDX is valid.
+	 */
+	if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED)) {
+		eax = 0;
+	} else {
+		edx >>= MWAIT_SUBSTATE_SIZE;
+		for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) {
+			if (edx & MWAIT_SUBSTATE_MASK) {
+				highest_cstate = i;
+				highest_subcstate = edx & MWAIT_SUBSTATE_MASK;
+			}
+		}
+		eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
+			(highest_subcstate - 1);
+	}
+
+	/*
+	 * This should be a memory location in a cache line which is
+	 * unlikely to be touched by other processors.  The actual
+	 * content is immaterial as it is not actually modified in any way.
+	 */
+	mwait_ptr = &current_thread_info()->flags;
+
+	wbinvd();
+
+	while (1) {
+		/*
+		 * The CLFLUSH is a workaround for erratum AAI65 for
+		 * the Xeon 7400 series.  It's not clear it is actually
+		 * needed, but it should be harmless in either case.
+		 * The WBINVD is insufficient due to the spurious-wakeup
+		 * case where we return around the loop.
+		 */
+		clflush(mwait_ptr);
+		__monitor(mwait_ptr, 0, 0);
+		mb();
+		__mwait(eax, 0);
+	}
+}
+
+static inline void hlt_play_dead(void)
+{
+	if (current_cpu_data.x86 >= 4)
+		wbinvd();
+
+	while (1) {
+		native_halt();
+	}
+}
+
 void native_play_dead(void)
 {
 	play_dead_common();
 	tboot_shutdown(TB_SHUTDOWN_WFS);
-	wbinvd_halt();
+
+	mwait_play_dead();	/* Only returns on failure */
+	hlt_play_dead();
 }
 
 #else /* ... !CONFIG_HOTPLUG_CPU */
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/smp.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/smp.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/smp.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/smp.c	2014-02-10 17:31:40.000000000 -0500
@@ -159,10 +159,10 @@ asmlinkage void smp_reboot_interrupt(voi
 	irq_exit();
 }
 
-static void native_smp_send_stop(void)
+static void native_stop_other_cpus(int wait)
 {
 	unsigned long flags;
-	unsigned long wait;
+	unsigned long timeout;
 
 	if (reboot_force)
 		return;
@@ -179,9 +179,12 @@ static void native_smp_send_stop(void)
 	if (num_online_cpus() > 1) {
 		apic->send_IPI_allbutself(REBOOT_VECTOR);
 
-		/* Don't wait longer than a second */
-		wait = USEC_PER_SEC;
-		while (num_online_cpus() > 1 && wait--)
+		/*
+		 * Don't wait longer than a second if the caller
+		 * didn't ask us to wait.
+		 */
+		timeout = USEC_PER_SEC;
+		while (num_online_cpus() > 1 && (wait || timeout--))
 			udelay(1);
 	}
 
@@ -227,7 +230,7 @@ struct smp_ops smp_ops = {
 	.smp_prepare_cpus	= native_smp_prepare_cpus,
 	.smp_cpus_done		= native_smp_cpus_done,
 
-	.smp_send_stop		= native_smp_send_stop,
+	.stop_other_cpus	= native_stop_other_cpus,
 	.smp_send_reschedule	= native_smp_send_reschedule,
 
 	.cpu_up			= native_cpu_up,
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/tboot.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/tboot.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/tboot.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/tboot.c	2014-02-10 17:31:40.000000000 -0500
@@ -46,6 +46,7 @@
 
 /* Global pointer to shared data; NULL means no measured launch. */
 struct tboot *tboot __read_mostly;
+EXPORT_SYMBOL(tboot);
 
 /* timeout for APs (in secs) to enter wait-for-SIPI state during shutdown */
 #define AP_WAIT_TIMEOUT		1
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/tls.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/tls.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/tls.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/tls.c	2014-02-10 17:31:40.000000000 -0500
@@ -163,7 +163,7 @@ int regset_tls_get(struct task_struct *t
 {
 	const struct desc_struct *tls;
 
-	if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) ||
+	if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) ||
 	    (pos % sizeof(struct user_desc)) != 0 ||
 	    (count % sizeof(struct user_desc)) != 0)
 		return -EINVAL;
@@ -198,7 +198,7 @@ int regset_tls_set(struct task_struct *t
 	struct user_desc infobuf[GDT_ENTRY_TLS_ENTRIES];
 	const struct user_desc *info;
 
-	if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) ||
+	if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) ||
 	    (pos % sizeof(struct user_desc)) != 0 ||
 	    (count % sizeof(struct user_desc)) != 0)
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/trampoline.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/trampoline.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/trampoline.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/trampoline.c	2014-02-10 17:31:40.000000000 -0500
@@ -1,6 +1,7 @@
 #include <linux/io.h>
 
 #include <asm/trampoline.h>
+#include <asm/pgtable.h>
 #include <asm/e820.h>
 
 #if defined(CONFIG_X86_64) && defined(CONFIG_ACPI_SLEEP)
@@ -37,3 +38,19 @@ unsigned long __trampinit setup_trampoli
 	memcpy(trampoline_base, trampoline_data, TRAMPOLINE_SIZE);
 	return virt_to_phys(trampoline_base);
 }
+
+void __init setup_trampoline_page_table(void)
+{
+#ifdef CONFIG_X86_32
+	/* Copy kernel address range */
+	clone_pgd_range(trampoline_pg_dir + KERNEL_PGD_BOUNDARY,
+			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
+			KERNEL_PGD_PTRS);
+
+	/* Initialize low mappings */
+	clone_pgd_range(trampoline_pg_dir,
+			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
+			min_t(unsigned long, KERNEL_PGD_PTRS,
+			      KERNEL_PGD_BOUNDARY));
+#endif
+}
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/traps.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/traps.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/traps.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/traps.c	2014-02-10 17:31:40.000000000 -0500
@@ -529,6 +529,7 @@ asmlinkage __kprobes struct pt_regs *syn
 dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
 {
 	struct task_struct *tsk = current;
+	int user_icebp = 0;
 	unsigned long dr6;
 	int si_code;
 
@@ -537,6 +538,14 @@ dotraplinkage void __kprobes do_debug(st
 	/* Filter out all the reserved bits which are preset to 1 */
 	dr6 &= ~DR6_RESERVED;
 
+	/*
+	 * If dr6 has no reason to give us about the origin of this trap,
+	 * then it's very likely the result of an icebp/int01 trap.
+	 * User wants a sigtrap for that.
+	 */
+	if (!dr6 && user_mode(regs))
+		user_icebp = 1;
+
 	/* Catch kmemcheck conditions first of all! */
 	if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
 		return;
@@ -578,7 +587,7 @@ dotraplinkage void __kprobes do_debug(st
 		regs->flags &= ~X86_EFLAGS_TF;
 	}
 	si_code = get_si_code(tsk->thread.debugreg6);
-	if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS))
+	if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp)
 		send_sigtrap(tsk, regs, error_code, si_code);
 	preempt_conditional_cli(regs);
 
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kernel/tsc.c linux-libre-2.6.34.15-gnu1/arch/x86/kernel/tsc.c
--- linux-libre-2.6.34-gnu1/arch/x86/kernel/tsc.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kernel/tsc.c	2014-02-10 17:31:40.000000000 -0500
@@ -626,6 +626,44 @@ static void set_cyc2ns_scale(unsigned lo
 	local_irq_restore(flags);
 }
 
+static unsigned long long cyc2ns_suspend;
+
+void save_sched_clock_state(void)
+{
+	if (!sched_clock_stable)
+		return;
+
+	cyc2ns_suspend = sched_clock();
+}
+
+/*
+ * Even on processors with invariant TSC, TSC gets reset in some the
+ * ACPI system sleep states. And in some systems BIOS seem to reinit TSC to
+ * arbitrary value (still sync'd across cpu's) during resume from such sleep
+ * states. To cope up with this, recompute the cyc2ns_offset for each cpu so
+ * that sched_clock() continues from the point where it was left off during
+ * suspend.
+ */
+void restore_sched_clock_state(void)
+{
+	unsigned long long offset;
+	unsigned long flags;
+	int cpu;
+
+	if (!sched_clock_stable)
+		return;
+
+	local_irq_save(flags);
+
+	__get_cpu_var(cyc2ns_offset) = 0;
+	offset = cyc2ns_suspend - sched_clock();
+
+	for_each_possible_cpu(cpu)
+		per_cpu(cyc2ns_offset, cpu) = offset;
+
+	local_irq_restore(flags);
+}
+
 #ifdef CONFIG_CPU_FREQ
 
 /* Frequency scaling support. Adjust the TSC based timer when the cpu frequency
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kvm/i8254.c linux-libre-2.6.34.15-gnu1/arch/x86/kvm/i8254.c
--- linux-libre-2.6.34-gnu1/arch/x86/kvm/i8254.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kvm/i8254.c	2014-02-10 17:31:40.000000000 -0500
@@ -280,11 +280,15 @@ static struct kvm_timer_ops kpit_ops = {
 	.is_periodic = kpit_is_periodic,
 };
 
-static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period)
+static void create_pit_timer(struct kvm *kvm, u32 val, int is_period)
 {
+	struct kvm_kpit_state *ps = &kvm->arch.vpit->pit_state;
 	struct kvm_timer *pt = &ps->pit_timer;
 	s64 interval;
 
+	if (!irqchip_in_kernel(kvm))
+		return;
+
 	interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ);
 
 	pr_debug("create pit timer, interval is %llu nsec\n", interval);
@@ -336,13 +340,13 @@ static void pit_load_count(struct kvm *k
         /* FIXME: enhance mode 4 precision */
 	case 4:
 		if (!(ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)) {
-			create_pit_timer(ps, val, 0);
+			create_pit_timer(kvm, val, 0);
 		}
 		break;
 	case 2:
 	case 3:
 		if (!(ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)){
-			create_pit_timer(ps, val, 1);
+			create_pit_timer(kvm, val, 1);
 		}
 		break;
 	default:
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kvm/mmu.c linux-libre-2.6.34.15-gnu1/arch/x86/kvm/mmu.c
--- linux-libre-2.6.34-gnu1/arch/x86/kvm/mmu.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kvm/mmu.c	2014-02-10 17:31:40.000000000 -0500
@@ -223,7 +223,7 @@ void kvm_mmu_set_mask_ptes(u64 user_mask
 }
 EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes);
 
-static int is_write_protection(struct kvm_vcpu *vcpu)
+static bool is_write_protection(struct kvm_vcpu *vcpu)
 {
 	return kvm_read_cr0_bits(vcpu, X86_CR0_WP);
 }
@@ -1837,6 +1837,9 @@ static int set_spte(struct kvm_vcpu *vcp
 
 		spte |= PT_WRITABLE_MASK;
 
+		if (!tdp_enabled && !(pte_access & ACC_WRITE_MASK))
+			spte &= ~PT_USER_MASK;
+
 		/*
 		 * Optimization: for pte sync, if spte was writable the hash
 		 * lookup is unnecessary (and expensive). Write protection
@@ -1892,10 +1895,14 @@ static void mmu_set_spte(struct kvm_vcpu
 
 			child = page_header(pte & PT64_BASE_ADDR_MASK);
 			mmu_page_remove_parent_pte(child, sptep);
+			__set_spte(sptep, shadow_trap_nonpresent_pte);
+			kvm_flush_remote_tlbs(vcpu->kvm);
 		} else if (pfn != spte_to_pfn(*sptep)) {
 			pgprintk("hfn old %lx new %lx\n",
 				 spte_to_pfn(*sptep), pfn);
 			rmap_remove(vcpu->kvm, sptep);
+			__set_spte(sptep, shadow_trap_nonpresent_pte);
+			kvm_flush_remote_tlbs(vcpu->kvm);
 		} else
 			was_rmapped = 1;
 	}
@@ -2085,11 +2092,13 @@ static int mmu_alloc_roots(struct kvm_vc
 			direct = 1;
 		if (mmu_check_root(vcpu, root_gfn))
 			return 1;
+		spin_lock(&vcpu->kvm->mmu_lock);
 		sp = kvm_mmu_get_page(vcpu, root_gfn, 0,
 				      PT64_ROOT_LEVEL, direct,
 				      ACC_ALL, NULL);
 		root = __pa(sp->spt);
 		++sp->root_count;
+		spin_unlock(&vcpu->kvm->mmu_lock);
 		vcpu->arch.mmu.root_hpa = root;
 		return 0;
 	}
@@ -2111,11 +2120,14 @@ static int mmu_alloc_roots(struct kvm_vc
 			root_gfn = 0;
 		if (mmu_check_root(vcpu, root_gfn))
 			return 1;
+		spin_lock(&vcpu->kvm->mmu_lock);
 		sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30,
 				      PT32_ROOT_LEVEL, direct,
 				      ACC_ALL, NULL);
 		root = __pa(sp->spt);
 		++sp->root_count;
+		spin_unlock(&vcpu->kvm->mmu_lock);
+
 		vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK;
 	}
 	vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root);
@@ -2439,6 +2451,7 @@ static int init_kvm_softmmu(struct kvm_v
 		r = paging32_init_context(vcpu);
 
 	vcpu->arch.mmu.base_role.glevels = vcpu->arch.mmu.root_level;
+	vcpu->arch.mmu.base_role.cr0_wp = is_write_protection(vcpu);
 
 	return r;
 }
@@ -2478,7 +2491,9 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu)
 		goto out;
 	spin_lock(&vcpu->kvm->mmu_lock);
 	kvm_mmu_free_some_pages(vcpu);
+	spin_unlock(&vcpu->kvm->mmu_lock);
 	r = mmu_alloc_roots(vcpu);
+	spin_lock(&vcpu->kvm->mmu_lock);
 	mmu_sync_roots(vcpu);
 	spin_unlock(&vcpu->kvm->mmu_lock);
 	if (r)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kvm/paging_tmpl.h linux-libre-2.6.34.15-gnu1/arch/x86/kvm/paging_tmpl.h
--- linux-libre-2.6.34-gnu1/arch/x86/kvm/paging_tmpl.h	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kvm/paging_tmpl.h	2014-02-10 17:31:40.000000000 -0500
@@ -318,8 +318,32 @@ static u64 *FNAME(fetch)(struct kvm_vcpu
 			break;
 		}
 
-		if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep))
-			continue;
+		if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep)) {
+			struct kvm_mmu_page *child;
+			unsigned direct_access;
+
+			if (level != gw->level)
+				continue;
+
+			/*
+			 * For the direct sp, if the guest pte's dirty bit
+			 * changed form clean to dirty, it will corrupt the
+			 * sp's access: allow writable in the read-only sp,
+			 * so we should update the spte at this point to get
+			 * a new sp with the correct access.
+			 */
+			direct_access = gw->pt_access & gw->pte_access;
+			if (!is_dirty_gpte(gw->ptes[gw->level - 1]))
+				direct_access &= ~ACC_WRITE_MASK;
+
+			child = page_header(*sptep & PT64_BASE_ADDR_MASK);
+			if (child->role.access == direct_access)
+				continue;
+
+			mmu_page_remove_parent_pte(child, sptep);
+			__set_spte(sptep, shadow_trap_nonpresent_pte);
+			kvm_flush_remote_tlbs(vcpu->kvm);
+		}
 
 		if (is_large_pte(*sptep)) {
 			rmap_remove(vcpu->kvm, sptep);
@@ -332,6 +356,8 @@ static u64 *FNAME(fetch)(struct kvm_vcpu
 			direct = 1;
 			if (!is_dirty_gpte(gw->ptes[level - delta]))
 				access &= ~ACC_WRITE_MASK;
+			access &= gw->pte_access;
+
 			table_gfn = gpte_to_gfn(gw->ptes[level - delta]);
 			/* advance table_gfn when emulating 1gb pages with 4k */
 			if (delta == 0)
diff -druNp --no-dereference linux-libre-2.6.34-gnu1/arch/x86/kvm/svm.c linux-libre-2.6.34.15-gnu1/arch/x86/kvm/svm.c
--- linux-libre-2.6.34-gnu1/arch/x86/kvm/svm.c	2010-05-16 17:17:36.000000000 -0400
+++ linux-libre-2.6.34.15-gnu1/arch/x86/kvm/svm.c	2014-02-10 17:31:40.000000000 -0500
@@ -28,6 +28,7 @@
 #include <linux/ftrace_event.h>
 #include <linux/slab.h>
 
+#include <asm/tlbflush.h>
 #include <asm/desc.h>
 
 #include <asm/virtext.h>
@@ -55,6 +56,8 @@ MODULE_LICENSE("GPL");
 
 #define DEBUGCTL_RESERVED_BITS (~(0x3fULL))
 
+static bool erratum_383_found __read_mostly;
+
 static const u32 host_save_user_msrs[] = {
 #ifdef CONFIG_X86_64
 	MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE,
@@ -129,6 +132,7 @@ static void svm_flush_tlb(struct kvm_vcp
 static void svm_complete_interrupts(struct vcpu_svm *svm);
 
 static int nested_svm_exit_handled(struct vcpu_svm *svm);
+static int nested_svm_intercept(struct vcpu_svm *svm);
 static int nested_svm_vmexit(struct vcpu_svm *svm);
 static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
 				      bool has_error_code, u32 error_code);
@@ -297,6 +301,31 @@ static void skip_emulated_instruction(st
 	svm_set_interrupt_shadow(vcpu, 0);
 }
 
+static void svm_init_erratum_383(void)
+{
+	u32 low, high;
+	int err;
+	u64 val;
+
+	/* Only Fam10h is affected */
+	if (boot_cpu_data.x86 != 0x10)
+		return;
+
+	/* Use _safe variants to not break nested virtualization */
+	val = native_read_msr_safe(MSR_AMD64_DC_CFG, &err);
+	if (err)
+		return;
+
+	val |= (1ULL << 47);
+
+	low  = lower_32_bits(val);
+	high = upper_32_bits(val);
+
+	native_write_msr_safe(MSR_AMD64_DC_CFG, low, high);
+
+	erratum_383_found = true;
+}
+
 static int has_svm(void)
 {
 	const char *msg;
@@ -352,6 +381,8 @@ static int svm_hardware_enable(void *gar
 
 	wrmsrl(MSR_VM_HSAVE_PA, page_to_pfn(sd->save_area) << PAGE_SHIFT);
 
+	svm_init_erratum_383();
+
 	return 0;
 }
 
@@ -601,7 +632,6 @@ static void init_vmcb(struct vcpu_svm *s
 
 	control->iopm_base_pa = iopm_base;
 	control->msrpm_base_pa = __pa(svm->msrpm);
-	control->tsc_offset = 0;
 	control->int_ctl = V_INTR_MASKING_MASK;
 
 	init_seg(&save->es);
@@ -735,6 +765,7 @@ static struct kvm_vcpu *svm_create_vcpu(
 	svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT;
 	svm->asid_generation = 0;
 	init_vmcb(svm);
+	svm->vmcb->control.tsc_offset = 0-native_read_tsc();
 
 	fx_init(&svm->vcpu);
 	svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
@@ -1279,8 +1310,59 @@ static int nm_interception(struct vcpu_s
 	return 1;
 }
 
-static int mc_interception(struct vcpu_svm *svm)
+static bool is_erratum_383(void)
+{
+	int err, i;
+	u64 value;
+
+	if (!erratum_383_found)
+		return false;
+
+	value = native_read_msr_safe(MSR_IA32_MC0_STATUS, &err);
+	if (err)
+		return false;
+
+	/* Bit 62 may or may not be set for this mce */
+	value &= ~(1ULL << 62);
+
+	if (value != 0xb600000000010015ULL)
+		return false;
+
+	/* Clear MCi_STATUS registers */
+	for (i = 0; i < 6; ++i)
+		native_write_msr_safe(MSR_IA32_MCx_STATUS(i), 0, 0);
+
+	value = native_read_msr_safe(MSR_IA32_MCG_STATUS, &err);
+	if (!err) {
+		u32 low, high;
+
+		value &= ~(1ULL << 2);
+		low    = lower_32_bits(value);
+		high   = upper_32_bits(value);
+
+		native_write_msr_safe(MSR_IA32_MCG_STATUS, low, high);
+	}
+
+	/* Flush tlb to evict multi-match entries */
+	__flush_tlb_all();
+
+	return true;
+}
+
+static void svm_handle_mce(struct vcpu_svm *svm)
 {
+	if (is_erratum_383()) {
+		/*
+		 * Erratum 383 triggered. Guest state is corrupt so kill the
+		 * guest.
+		 */
+		pr_err("KVM: Guest triggered AMD Erratum 383\n");
+
+		set_bit(KVM_REQ_TRIPLE_FAULT, &svm->vcpu.requests);
+
+		return;
+	}
+
 	/*
 	 * On an #MC intercept the MCE handler is not called automatically in
 	 * the host. So do it by hand here.
@@ -1289,6 +1371,11 @@ static int mc_interception(struct vcpu_s
 		"int $0x12\n");
 	/* not sure if we ever come back to this point */
 
+	return;
+}
+
+static int mc_interception(struct vcpu_svm *svm)
+{
 	return 1;
 }
 
@@ -1384,6 +1471,8 @@ static int nested_svm_check_permissions(
 static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
 				      bool has_error_code, u32 error_code)
 {
+	int vmexit;
+
 	if (!is_nested(svm))
 		return 0;
 
@@ -1392,19 +1481,24 @@ static int nested_svm_check_exception(st
 	svm->vmcb->control.exit_info_1 = error_code;
 	svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2;
 
-	return nested_svm_exit_handled(svm);
+	vmexit = nested_svm_intercept(svm);
+	if (vmexit == NESTED_EXIT_DONE)
+		svm->nested.exit_required = true;
+
+	return vmexit;
 }
 
-static inline int nested_svm_intr(struct vcpu_svm *svm)
+/* This function returns true if it is save to enable the irq window */
+static inline bool nested_svm_intr(struct vcpu_svm *svm)
 {
 	if (!is_nested(svm))
-		return 0;
+		return true;
 
 	if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
-		return 0;
+		return true;
 
 	if (!(svm->vcpu.arch.hflags & HF_HIF_MASK))
-		return 0;
+		return false;
 
 	svm->vmcb->control.exit_code = SVM_EXIT_INTR;
 
@@ -1417,13 +1511,13 @@ static inline int nested_svm_intr(struct
 		 */
 		svm->nested.exit_required = true;
 		trace_kvm_nested_intr_vmexit(svm->vmcb->save.rip);
-		return 1;
+		return false;
 	}
 
-	return 0;
+	return true;
 }
 
-static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, enum km_type idx)
+static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page)
 {
 	struct page *page;
 
@@ -1431,7 +1525,9 @@ static void *nested_svm_map(struct vcpu_
 	if (is_error_page(page))
 		goto error;
 
-	return kmap_atomic(page, idx);
+	*_page = page;
+
+	return kmap(page);
 
 error:
 	kvm_release_page_clean(page);
@@ -1440,16 +1536,9 @@ error:
 	return NULL;
 }
 
-static void nested_svm_unmap(void *addr, enum km_type idx)
+static void nested_svm_unmap(struct page *page)
 {
-	struct page *page;
-
-	if (!addr)
-		return;
-
-	page = kmap_atomic_to_page(addr);
-
-	kunmap_atomic(addr, idx);
+	kunmap(page);
 	kvm_release_page_dirty(page);
 }
 
@@ -1459,16 +1548,11 @@ static bool nested_svm_exit_handled_msr(
 	u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX];
 	bool ret = false;
 	u32 t0, t1;
-	u8 *msrpm;
+	u8 val;
 
 	if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT)))
 		return false;
 
-	msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0);
-
-	if (!msrpm)
-		goto out;
-
 	switch (msr) {
 	case 0 ... 0x1fff:
 		t0 = (msr * 2) % 8;
@@ -1489,11 +1573,10 @@ static bool nested_svm_exit_handled_msr(
 		goto out;
 	}
 
-	ret = msrpm[t1] & ((1 << param) << t0);
+	if (!kvm_read_guest(svm->vcpu.kvm, svm->nested.vmcb_msrpm + t1, &val, 1))
+		ret = val & ((1 << param) << t0);
 
 out:
-	nested_svm_unmap(msrpm, KM_USER0);
-
 	return ret;
 }
 
@@ -1525,7 +1608,7 @@ static int nested_svm_exit_special(struc
 /*
  * If this function returns true, this #vmexit was already handled
  */
-static int nested_svm_exit_handled(struct vcpu_svm *svm)
+static int nested_svm_intercept(struct vcpu_svm *svm)
 {
 	u32 exit_code = svm->vmcb->control.exit_code;
 	int vmexit = NESTED_EXIT_HOST;
@@ -1571,9 +1654,17 @@ static int nested_svm_exit_handled(struc
 	}
 	}
 
-	if (vmexit == NESTED_EXIT_DONE) {
+	return vmexit;
+}
+
+static int nested_svm_exit_handled(struct vcpu_svm *svm)
+{
+	int vmexit;
+
+	vmexit = nested_svm_intercept(svm);
+
+	if (vmexit == NESTED_EXIT_DONE)
 		nested_svm_vmexit(svm);
-	}
 
 	return vmexit;
 }
@@ -1615,6 +1706,7 @@ static int nested_svm_vmexit(struct vcpu
 	struct vmcb *nested_vmcb;
 	struct vmcb *hsave = svm->nested.hsave;
 	struct vmcb *vmcb = svm->vmcb;
+	struct page *page;
 
 	trace_kvm_nested_vmexit_inject(vmcb->control.exit_code,
 				       vmcb->control.exit_info_1,
@@ -1622,7 +1714,7 @@ static int nested_svm_vmexit(struct vcpu
 				       vmcb->control.exit_int_info,
 				       vmcb->control.exit_int_info_err);
 
-	nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, KM_USER0);
+	nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, &page);
 	if (!nested_vmcb)
 		return 1;
 
@@ -1635,9 +1727,13 @@ static int nested_svm_vmexit(struct vcpu
 	nested_vmcb->save.ds     = vmcb->save.ds;
 	nested_vmcb->save.gdtr   = vmcb->save.gdtr;
 	nested_vmcb->save.idtr   = vmcb->save.idtr;
+	nested_vmcb->save.cr0    = kvm_read_cr0(&svm->vcpu);
 	if (npt_enabled)
 		nested_vmcb->save.cr3    = vmcb->save.cr3;
+	else
+		nested_vmcb->save.cr3    = svm->vcpu.arch.cr3;
 	nested_vmcb->save.cr2    = vmcb->save.cr2;
+	nested_vmcb->save.cr4    = svm->vcpu.arch.cr4;
 	nested_vmcb->save.rflags = vmcb->save.rflags;
 	nested_vmcb->save.rip    = vmcb->save.rip;
 	nested_vmcb->save.rsp    = vmcb->save.rsp;
@@ -1712,7 +1808,7 @@ static int nested_svm_vmexit(struct vcpu
 	/* Exit nested SVM mode */
 	svm->nested.vmcb = 0;
 
-	nested_svm_unmap(nested_vmcb, KM_USER0);
+	nested_svm_unmap(page);
 
 	kvm_mmu_reset_context(&svm->vcpu);
 	kvm_mmu_load(&svm->vcpu);
@@ -1723,9 +1819,10 @@ static int nested_svm_vmexit(struct vcpu
 static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
 {
 	u32 *nested_msrpm;
+	struct page *page;
 	int i;
 
-	nested_msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0);
+	nested_msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, &page);
 	if (!nested_msrpm)
 		return false;
 
@@ -1734,7 +1831,7 @@ static bool nested_svm_vmrun_msrpm(struc
 
 	svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm);
 
-	nested_svm_unmap(nested_msrpm, KM_USER0);
+	nested_svm_unmap(page);
 
 	return true;
 }
@@ -1744,8 +1841,9 @@ static bool nested_svm_vmrun(struct vcpu
 	struct vmcb *nested_vmcb;
 	struct vmcb *hsave = svm->nested.hsave;
 	struct vmcb *vmcb = svm->vmcb;
+	struct page *page;
 
-	nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0);
+	nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page);
 	if (!nested_vmcb)
 		return false;
 
@@ -1819,21 +1917,6 @@ static bool nested_svm_vmrun(struct vcpu
 	svm->vmcb->save.dr6 = nested_vmcb->save.dr6;
 	svm->vmcb->save.cpl = nested_vmcb->save.cpl;
 
-	/* We don't want a nested guest to be more powerful than the guest,
-	   so all intercepts are ORed */
-	svm->vmcb->control.intercept_cr_read |=
-		nested_vmcb->control.intercept_cr_read;
-	svm->vmcb->control.intercept_cr_write |=
-		nested_vmcb->control.intercept_cr_write;
-	svm->vmcb->control.intercept_dr_read |=
-		nested_vmcb->control.intercept_dr_read;
-	svm->vmcb->control.intercept_dr_write |=
-		nested_vmcb->control.intercept_dr_write;
-	svm->vmcb->control.intercept_exceptions |=
-		nested_vmcb->control.intercept_exceptions;
-
-	svm->vmcb->control.intercept |= nested_vmcb->control.intercept;
-
 	svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa;
 
 	/* cache intercepts */
@@ -1851,13 +1934,38 @@ static bool nested_svm_vmrun(struct vcpu
 	else
 		svm->vcpu.arch.hflags &= ~HF_VINTR_MASK;
 
+	if (svm->vcpu.arch.hflags & HF_VINTR_MASK) {
+		/* We only want the cr8 intercept bits of the guest */
+		svm->vmcb->control.intercept_cr_read &= ~INTERCEPT_CR8_MASK;
+		svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK;
+	}
+
+	/* We don't want to see VMMCALLs from a nested guest */
+	svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMMCALL);
+
+	/* We don't want a nested guest to be more powerful than the guest,
+	   so all intercepts are ORed */
+	svm->vmcb->control.intercept_cr_read |=
+		nested_vmcb->control.intercept_cr_read;
+	svm->vmcb->control.intercept_cr_write |=
+		nested_vmcb->control.intercept_cr_write;
+	svm->vmcb->control.intercept_dr_read |=
+		nested_vmcb->control.intercept_dr_read;
+	svm->vmcb->control.intercept_dr_write |=
+		nested_vmcb->control.intercept_dr_write;
+	svm->vmcb->control.intercept_exceptions |=
+		nested_vmcb->control.intercept_exceptions;
+
+	svm->vmcb->control.intercept |= nested_vmcb->control.intercept;
+
+	svm->vmcb->control.lbr_ctl = nested_vmcb->control.lbr_ctl;
 	svm->vmcb->control.int_vector = nested_vmcb->control.int_vector;
 	svm->vmcb->control.int_state = nested_vmcb->control.int_state;
 	svm->vmcb->control.tsc_offset += nested_vmcb->control.tsc_offset;
 	svm->vmcb->control.event_inj = nested_vmcb->control.event_inj;
 	svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err;
 
-	nested_svm_unmap(nested_vmcb, KM_USER0);
+	nested_svm_unmap(page);
 
 	enable_gif(svm);
 
@@ -1883,6 +1991,7 @@ static void nested_svm_vmloadsave(struct
 static int vmload_interception(struct vcpu_svm *svm)
 {
 	struct vmcb *nested_vmcb;
+	struct page *page;
 
 	if (nested_svm_check_permissions(svm))
 		return 1;
@@ -1890,12 +1999,12 @@ static int vmload_interception(struct vc
 	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
 	skip_emulated_instruction(&svm->vcpu);
 
-	nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0);
+	nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page);
 	if (!nested_vmcb)
 		return 1;
 
 	nested_svm_vmloadsave(nested_vmcb, svm->vmcb);
-	nested_svm_unmap(nested_vmcb, KM_USER0);
+	nested_svm_unmap(page);
 
 	return 1;
 }
@@ -1903,6 +2012,7 @@ static int vmload_interception(struct vc
 static int vmsave_interception(struct vcpu_svm *svm)
 {
 	struct vmcb *nested_vmcb;
+	struct page *page;
 
 	if (nested_svm_check_permissions(svm))
 		return 1;
@@ -1910,12 +2020,12 @@ static int vmsave_interception(struct vc
 	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
 	skip_emulated_instruction(&svm->vcpu);
 
-	nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0);
+	nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page);
 	if (!nested_vmcb)
 		return 1;
 
 	nested_svm_vmloadsave(svm->vmcb, nested_vmcb);
-	nested_svm_unmap(nested_vmcb, KM_USER0);
+	nested_svm_unmap(page);
 
 	return 1;
 }
@@ -2511,6 +2621,9 @@ static void update_cr8_intercept(struct
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
+	if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK))
+		return;
+
 	if (irr == -1)
 		return;
 
@@ -2568,13 +2681,11 @@ static void enable_irq_window(struct kvm
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
-	nested_svm_intr(svm);
-
 	/* In case GIF=0 we can't rely on the CPU to tell us when
 	 * GIF becomes 1, because that's a separate STGI/VMRUN intercept.
 	 * The next time we get that intercept, this function will be
 	 * called again though and we'll get the vintr intercept. */
-	if (gif_set(svm)) {
+	if (gif_set(svm) && nested_svm_intr(svm)) {
 		svm_set_vintr(svm);
 		svm_inject_irq(svm, 0x0);
 	}
@@ -2614,6 +2725,9 @@ static inline void sync_cr8_to_lapic(str
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
+	if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK))
+		return;
+
 	if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR8_MASK)) {
 		int cr8 = svm->vmcb->control.int_ctl & V_TPR_MASK;
 		kvm_set_cr8(vcpu, cr8);
@@ -2625,6 +2739,9 @@ static inline void sync_lapic_to_cr8(str
 	struct vcpu_svm *svm = to_svm(vcpu);
 	u64 cr8;
 
+	if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK))
+		return;
+
 	cr8 = kvm_get_cr8(vcpu);
 	svm->vmcb->control.int_ctl &= ~V_TPR_MASK;
 	svm->vmcb->control.int_ctl |= cr8 & V_TPR_MASK;
@@ -2704,8 +2821,8 @@ static void svm_vcpu_run(struct kvm_vcpu
 	sync_lapic_to_cr8(vcpu);
 
 	save_host_msrs(vcpu);
-	fs_selector = kvm_read_fs();
-	gs_selector = kvm_read_gs();
+	savesegment(fs, fs_selector);
+	savesegment(gs, gs_selector);
 	ldt_selector = kvm_read_ldt();
 	svm->vmcb->save.cr2 = vcpu->arch.cr2;
 	/* required for live migration with NPT */
@@ -2792,10 +2909,15 @@ static void svm_vcpu_run(struct kvm_vcpu
 	vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
 	vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
 
-	kvm_load_fs(fs_selector);
-	kvm_load_gs(gs_selector);
-	kvm_load_ldt(ldt_selector);
 	load_host_msrs(vcpu);
+	loadsegment(fs, fs_selector);
+#ifdef CONFIG_X86_64
+	load_gs_index(gs_selector);
+	wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs);
+#else
+	loadsegment(gs, gs_selector);
+#endif
+	kvm_load_ldt(ldt_selector);
 
 	reload_tss(vcpu);
 
@@ -2811,6 +2933,14 @@ static void svm_vcpu_run(struct kvm_vcpu
 		vcpu->arch.regs_avail &= ~(1 << VCPU_EXREG_PDPTR);
 		vcpu->arch.regs_dirty &= ~(1 << VCPU_EXREG_PDPTR);
 	}
+
+	/*
+	 * We need to handle MC intercepts here before the vcpu has a chance to
+	 * change the physical cpu
+	 */
+	if (unlikely(svm->vmcb->control.exit_code ==
+		     SVM_EXIT_EXCP_BASE + MC_VECTOR))
+		svm_handle_mce(svm);
 }
 
 #undef R
@@ -2879,6 +3009,20 @@ static void svm_cpuid_update(struct kvm_
 {
 }
 
+static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
+{
+	switch (func) {
+	case 0x8000000A:
+		entry->eax = 1; /* SVM revision 1 */
+		entry->ebx = 8; /* Lets support 8 ASIDs in case we add proper
+				   ASID emulation to nested SVM */
+		entry->ecx = 0; /* Reserved */
+		entry->edx = 0; /* Do not support any additional features */
+
+		break;
+	}
+}
+
 static const struct trace_print_flags svm_exit_reasons_str[] = {
 	{ SVM_EXIT_READ_CR0,           		"read_cr0" },
 	{ SVM_EXIT_READ_CR3,	      		"read_cr3" },
@@ -3023,6 +3167,8 @@ static struct kvm_x86_ops svm_x86_ops =
 	.cpuid_update = svm_cpuid_update,
 
 	.rdtscp_supported = svm_rdtscp_supported,