diff -druN linux-libre-3.5.6-gnu/arch/alpha/kernel/process.c linux-libre-3.5.7-gnu/arch/alpha/kernel/process.c
--- linux-libre-3.5.6-gnu/arch/alpha/kernel/process.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/alpha/kernel/process.c	2012-10-12 16:48:25.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/slab.h>
+#include <linux/rcupdate.h>
 
 #include <asm/reg.h>
 #include <asm/uaccess.h>
@@ -54,8 +55,10 @@
 		/* FIXME -- EV6 and LCA45 know how to power down
 		   the CPU.  */
 
+		rcu_idle_enter();
 		while (!need_resched())
 			cpu_relax();
+		rcu_idle_exit();
 		schedule();
 	}
 }
diff -druN linux-libre-3.5.6-gnu/arch/arm/include/asm/syscall.h linux-libre-3.5.7-gnu/arch/arm/include/asm/syscall.h
--- linux-libre-3.5.6-gnu/arch/arm/include/asm/syscall.h	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/arm/include/asm/syscall.h	2012-10-12 16:48:25.000000000 -0400
@@ -8,6 +8,7 @@
 #define _ASM_ARM_SYSCALL_H
 
 #include <linux/err.h>
+#include <linux/sched.h>
 
 extern const unsigned long sys_call_table[];
 
diff -druN linux-libre-3.5.6-gnu/arch/cris/kernel/process.c linux-libre-3.5.7-gnu/arch/cris/kernel/process.c
--- linux-libre-3.5.6-gnu/arch/cris/kernel/process.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/cris/kernel/process.c	2012-10-12 16:48:25.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/elfcore.h>
 #include <linux/mqueue.h>
 #include <linux/reboot.h>
+#include <linux/rcupdate.h>
 
 //#define DEBUG
 
@@ -74,6 +75,7 @@
 {
 	/* endless idle loop with no priority at all */
 	while (1) {
+		rcu_idle_enter();
 		while (!need_resched()) {
 			void (*idle)(void);
 			/*
@@ -86,6 +88,7 @@
 				idle = default_idle;
 			idle();
 		}
+		rcu_idle_exit();
 		schedule_preempt_disabled();
 	}
 }
diff -druN linux-libre-3.5.6-gnu/arch/frv/kernel/process.c linux-libre-3.5.7-gnu/arch/frv/kernel/process.c
--- linux-libre-3.5.6-gnu/arch/frv/kernel/process.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/frv/kernel/process.c	2012-10-12 16:48:25.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/reboot.h>
 #include <linux/interrupt.h>
 #include <linux/pagemap.h>
+#include <linux/rcupdate.h>
 
 #include <asm/asm-offsets.h>
 #include <asm/uaccess.h>
@@ -69,12 +70,14 @@
 {
 	/* endless idle loop with no priority at all */
 	while (1) {
+		rcu_idle_enter();
 		while (!need_resched()) {
 			check_pgt_cache();
 
 			if (!frv_dma_inprogress && idle)
 				idle();
 		}
+		rcu_idle_exit();
 
 		schedule_preempt_disabled();
 	}
diff -druN linux-libre-3.5.6-gnu/arch/h8300/kernel/process.c linux-libre-3.5.7-gnu/arch/h8300/kernel/process.c
--- linux-libre-3.5.6-gnu/arch/h8300/kernel/process.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/h8300/kernel/process.c	2012-10-12 16:48:25.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/reboot.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
+#include <linux/rcupdate.h>
 
 #include <asm/uaccess.h>
 #include <asm/traps.h>
@@ -78,8 +79,10 @@
 void cpu_idle(void)
 {
 	while (1) {
+		rcu_idle_enter();
 		while (!need_resched())
 			idle();
+		rcu_idle_exit();
 		schedule_preempt_disabled();
 	}
 }
diff -druN linux-libre-3.5.6-gnu/arch/ia64/kernel/process.c linux-libre-3.5.7-gnu/arch/ia64/kernel/process.c
--- linux-libre-3.5.6-gnu/arch/ia64/kernel/process.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/ia64/kernel/process.c	2012-10-12 16:48:25.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/kdebug.h>
 #include <linux/utsname.h>
 #include <linux/tracehook.h>
+#include <linux/rcupdate.h>
 
 #include <asm/cpu.h>
 #include <asm/delay.h>
@@ -279,6 +280,7 @@
 
 	/* endless idle loop with no priority at all */
 	while (1) {
+		rcu_idle_enter();
 		if (can_do_pal_halt) {
 			current_thread_info()->status &= ~TS_POLLING;
 			/*
@@ -309,6 +311,7 @@
 			normal_xtp();
 #endif
 		}
+		rcu_idle_exit();
 		schedule_preempt_disabled();
 		check_pgt_cache();
 		if (cpu_is_offline(cpu))
diff -druN linux-libre-3.5.6-gnu/arch/m32r/kernel/process.c linux-libre-3.5.7-gnu/arch/m32r/kernel/process.c
--- linux-libre-3.5.6-gnu/arch/m32r/kernel/process.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/m32r/kernel/process.c	2012-10-12 16:48:25.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/hardirq.h>
+#include <linux/rcupdate.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -82,6 +83,7 @@
 {
 	/* endless idle loop with no priority at all */
 	while (1) {
+		rcu_idle_enter();
 		while (!need_resched()) {
 			void (*idle)(void) = pm_idle;
 
@@ -90,6 +92,7 @@
 
 			idle();
 		}
+		rcu_idle_exit();
 		schedule_preempt_disabled();
 	}
 }
diff -druN linux-libre-3.5.6-gnu/arch/m68k/kernel/process.c linux-libre-3.5.7-gnu/arch/m68k/kernel/process.c
--- linux-libre-3.5.6-gnu/arch/m68k/kernel/process.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/m68k/kernel/process.c	2012-10-12 16:48:25.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/reboot.h>
 #include <linux/init_task.h>
 #include <linux/mqueue.h>
+#include <linux/rcupdate.h>
 
 #include <asm/uaccess.h>
 #include <asm/traps.h>
@@ -75,8 +76,10 @@
 {
 	/* endless idle loop with no priority at all */
 	while (1) {
+		rcu_idle_enter();
 		while (!need_resched())
 			idle();
+		rcu_idle_exit();
 		schedule_preempt_disabled();
 	}
 }
diff -druN linux-libre-3.5.6-gnu/arch/mips/ath79/clock.c linux-libre-3.5.7-gnu/arch/mips/ath79/clock.c
--- linux-libre-3.5.6-gnu/arch/mips/ath79/clock.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/mips/ath79/clock.c	2012-10-12 16:48:25.000000000 -0400
@@ -189,7 +189,7 @@
 	       AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
 
 	cpu_pll = nint * ath79_ref_clk.rate / ref_div;
-	cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 6));
+	cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 6));
 	cpu_pll /= (1 << out_div);
 
 	pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG);
@@ -203,7 +203,7 @@
 	       AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
 
 	ddr_pll = nint * ath79_ref_clk.rate / ref_div;
-	ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 10));
+	ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 10));
 	ddr_pll /= (1 << out_div);
 
 	clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
diff -druN linux-libre-3.5.6-gnu/arch/mips/kernel/Makefile linux-libre-3.5.7-gnu/arch/mips/kernel/Makefile
--- linux-libre-3.5.6-gnu/arch/mips/kernel/Makefile	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/mips/kernel/Makefile	2012-10-12 16:48:25.000000000 -0400
@@ -104,7 +104,7 @@
 
 obj-$(CONFIG_OF)		+= prom.o
 
-CFLAGS_cpu-bugs64.o	= $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
+CFLAGS_cpu-bugs64.o	= $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -x c /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
 
 obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT)	+= 8250-platform.o
 
diff -druN linux-libre-3.5.6-gnu/arch/mips/Makefile linux-libre-3.5.7-gnu/arch/mips/Makefile
--- linux-libre-3.5.6-gnu/arch/mips/Makefile	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/mips/Makefile	2012-10-12 16:48:25.000000000 -0400
@@ -225,7 +225,7 @@
 LDFLAGS			+= -m $(ld-emul)
 
 ifdef CONFIG_MIPS
-CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -xc /dev/null | \
+CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \
 	egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \
 	sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/")
 ifdef CONFIG_64BIT
diff -druN linux-libre-3.5.6-gnu/arch/mn10300/kernel/process.c linux-libre-3.5.7-gnu/arch/mn10300/kernel/process.c
--- linux-libre-3.5.6-gnu/arch/mn10300/kernel/process.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/mn10300/kernel/process.c	2012-10-12 16:48:25.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/err.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
+#include <linux/rcupdate.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
@@ -107,6 +108,7 @@
 {
 	/* endless idle loop with no priority at all */
 	for (;;) {
+		rcu_idle_enter();
 		while (!need_resched()) {
 			void (*idle)(void);
 
@@ -121,6 +123,7 @@
 			}
 			idle();
 		}
+		rcu_idle_exit();
 
 		schedule_preempt_disabled();
 	}
diff -druN linux-libre-3.5.6-gnu/arch/mn10300/Makefile linux-libre-3.5.7-gnu/arch/mn10300/Makefile
--- linux-libre-3.5.6-gnu/arch/mn10300/Makefile	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/mn10300/Makefile	2012-10-12 16:48:25.000000000 -0400
@@ -26,7 +26,7 @@
 PROCESSOR	:= unset
 UNIT		:= unset
 
-KBUILD_CFLAGS	+= -mam33 -mmem-funcs -DCPU=AM33
+KBUILD_CFLAGS	+= -mam33 -DCPU=AM33 $(call cc-option,-mmem-funcs,)
 KBUILD_AFLAGS	+= -mam33 -DCPU=AM33
 
 ifeq ($(CONFIG_MN10300_CURRENT_IN_E2),y)
diff -druN linux-libre-3.5.6-gnu/arch/parisc/kernel/process.c linux-libre-3.5.7-gnu/arch/parisc/kernel/process.c
--- linux-libre-3.5.6-gnu/arch/parisc/kernel/process.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/parisc/kernel/process.c	2012-10-12 16:48:25.000000000 -0400
@@ -48,6 +48,7 @@
 #include <linux/unistd.h>
 #include <linux/kallsyms.h>
 #include <linux/uaccess.h>
+#include <linux/rcupdate.h>
 
 #include <asm/io.h>
 #include <asm/asm-offsets.h>
@@ -69,8 +70,10 @@
 
 	/* endless idle loop with no priority at all */
 	while (1) {
+		rcu_idle_enter();
 		while (!need_resched())
 			barrier();
+		rcu_idle_exit();
 		schedule_preempt_disabled();
 		check_pgt_cache();
 	}
diff -druN linux-libre-3.5.6-gnu/arch/powerpc/include/asm/pci-bridge.h linux-libre-3.5.7-gnu/arch/powerpc/include/asm/pci-bridge.h
--- linux-libre-3.5.6-gnu/arch/powerpc/include/asm/pci-bridge.h	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/powerpc/include/asm/pci-bridge.h	2012-10-12 16:48:25.000000000 -0400
@@ -181,6 +181,14 @@
 #if defined(CONFIG_EEH)
 static inline struct eeh_dev *of_node_to_eeh_dev(struct device_node *dn)
 {
+	/*
+	 * For those OF nodes whose parent isn't PCI bridge, they
+	 * don't have PCI_DN actually. So we have to skip them for
+	 * any EEH operations.
+	 */
+	if (!dn || !PCI_DN(dn))
+		return NULL;
+
 	return PCI_DN(dn)->edev;
 }
 #endif
diff -druN linux-libre-3.5.6-gnu/arch/powerpc/platforms/pseries/eeh.c linux-libre-3.5.7-gnu/arch/powerpc/platforms/pseries/eeh.c
--- linux-libre-3.5.6-gnu/arch/powerpc/platforms/pseries/eeh.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/powerpc/platforms/pseries/eeh.c	2012-10-12 16:48:25.000000000 -0400
@@ -1029,7 +1029,7 @@
 {
 	struct pci_controller *phb;
 
-	if (!dn || !of_node_to_eeh_dev(dn))
+	if (!of_node_to_eeh_dev(dn))
 		return;
 	phb = of_node_to_eeh_dev(dn)->phb;
 
diff -druN linux-libre-3.5.6-gnu/arch/score/kernel/process.c linux-libre-3.5.7-gnu/arch/score/kernel/process.c
--- linux-libre-3.5.6-gnu/arch/score/kernel/process.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/score/kernel/process.c	2012-10-12 16:48:25.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/reboot.h>
 #include <linux/elfcore.h>
 #include <linux/pm.h>
+#include <linux/rcupdate.h>
 
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
@@ -50,9 +51,10 @@
 {
 	/* endless idle loop with no priority at all */
 	while (1) {
+		rcu_idle_enter();
 		while (!need_resched())
 			barrier();
-
+		rcu_idle_exit();
 		schedule_preempt_disabled();
 	}
 }
diff -druN linux-libre-3.5.6-gnu/arch/x86/boot/compressed/Makefile linux-libre-3.5.7-gnu/arch/x86/boot/compressed/Makefile
--- linux-libre-3.5.6-gnu/arch/x86/boot/compressed/Makefile	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/x86/boot/compressed/Makefile	2012-10-12 16:48:25.000000000 -0400
@@ -28,6 +28,9 @@
 	$(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o \
 	$(obj)/piggy.o
 
+$(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone
+$(obj)/efi_stub_$(BITS).o: KBUILD_CLFAGS += -fshort-wchar -mno-red-zone
+
 ifeq ($(CONFIG_EFI_STUB), y)
 	VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o
 endif
diff -druN linux-libre-3.5.6-gnu/arch/x86/include/asm/pgtable.h linux-libre-3.5.7-gnu/arch/x86/include/asm/pgtable.h
--- linux-libre-3.5.6-gnu/arch/x86/include/asm/pgtable.h	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/x86/include/asm/pgtable.h	2012-10-12 16:48:25.000000000 -0400
@@ -146,8 +146,7 @@
 
 static inline int pmd_large(pmd_t pte)
 {
-	return (pmd_flags(pte) & (_PAGE_PSE | _PAGE_PRESENT)) ==
-		(_PAGE_PSE | _PAGE_PRESENT);
+	return pmd_flags(pte) & _PAGE_PSE;
 }
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -415,7 +414,13 @@
 
 static inline int pmd_present(pmd_t pmd)
 {
-	return pmd_flags(pmd) & _PAGE_PRESENT;
+	/*
+	 * Checking for _PAGE_PSE is needed too because
+	 * split_huge_page will temporarily clear the present bit (but
+	 * the _PAGE_PSE flag will remain set at all times while the
+	 * _PAGE_PRESENT bit is clear).
+	 */
+	return pmd_flags(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_PSE);
 }
 
 static inline int pmd_none(pmd_t pmd)
diff -druN linux-libre-3.5.6-gnu/arch/x86/kvm/vmx.c linux-libre-3.5.7-gnu/arch/x86/kvm/vmx.c
--- linux-libre-3.5.6-gnu/arch/x86/kvm/vmx.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/x86/kvm/vmx.c	2012-10-12 16:48:25.000000000 -0400
@@ -615,10 +615,6 @@
 static void kvm_cpu_vmxoff(void);
 static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3);
 static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr);
-static void vmx_set_segment(struct kvm_vcpu *vcpu,
-			    struct kvm_segment *var, int seg);
-static void vmx_get_segment(struct kvm_vcpu *vcpu,
-			    struct kvm_segment *var, int seg);
 
 static DEFINE_PER_CPU(struct vmcs *, vmxarea);
 static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
@@ -2767,7 +2763,6 @@
 {
 	unsigned long flags;
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
-	struct kvm_segment var;
 
 	if (enable_unrestricted_guest)
 		return;
@@ -2811,23 +2806,20 @@
 	if (emulate_invalid_guest_state)
 		goto continue_rmode;
 
-	vmx_get_segment(vcpu, &var, VCPU_SREG_SS);
-	vmx_set_segment(vcpu, &var, VCPU_SREG_SS);
-
-	vmx_get_segment(vcpu, &var, VCPU_SREG_CS);
-	vmx_set_segment(vcpu, &var, VCPU_SREG_CS);
-
-	vmx_get_segment(vcpu, &var, VCPU_SREG_ES);
-	vmx_set_segment(vcpu, &var, VCPU_SREG_ES);
-
-	vmx_get_segment(vcpu, &var, VCPU_SREG_DS);
-	vmx_set_segment(vcpu, &var, VCPU_SREG_DS);
+	vmcs_write16(GUEST_SS_SELECTOR, vmcs_readl(GUEST_SS_BASE) >> 4);
+	vmcs_write32(GUEST_SS_LIMIT, 0xffff);
+	vmcs_write32(GUEST_SS_AR_BYTES, 0xf3);
 
-	vmx_get_segment(vcpu, &var, VCPU_SREG_GS);
-	vmx_set_segment(vcpu, &var, VCPU_SREG_GS);
+	vmcs_write32(GUEST_CS_AR_BYTES, 0xf3);
+	vmcs_write32(GUEST_CS_LIMIT, 0xffff);
+	if (vmcs_readl(GUEST_CS_BASE) == 0xffff0000)
+		vmcs_writel(GUEST_CS_BASE, 0xf0000);
+	vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4);
 
-	vmx_get_segment(vcpu, &var, VCPU_SREG_FS);
-	vmx_set_segment(vcpu, &var, VCPU_SREG_FS);
+	fix_rmode_seg(VCPU_SREG_ES, &vmx->rmode.es);
+	fix_rmode_seg(VCPU_SREG_DS, &vmx->rmode.ds);
+	fix_rmode_seg(VCPU_SREG_GS, &vmx->rmode.gs);
+	fix_rmode_seg(VCPU_SREG_FS, &vmx->rmode.fs);
 
 continue_rmode:
 	kvm_mmu_reset_context(vcpu);
@@ -3230,44 +3222,6 @@
 
 	vmcs_write32(sf->ar_bytes, ar);
 	__clear_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail);
-
-	/*
-	 * Fix segments for real mode guest in hosts that don't have
-	 * "unrestricted_mode" or it was disabled.
-	 * This is done to allow migration of the guests from hosts with
-	 * unrestricted guest like Westmere to older host that don't have
-	 * unrestricted guest like Nehelem.
-	 */
-	if (!enable_unrestricted_guest && vmx->rmode.vm86_active) {
-		switch (seg) {
-		case VCPU_SREG_CS:
-			vmcs_write32(GUEST_CS_AR_BYTES, 0xf3);
-			vmcs_write32(GUEST_CS_LIMIT, 0xffff);
-			if (vmcs_readl(GUEST_CS_BASE) == 0xffff0000)
-				vmcs_writel(GUEST_CS_BASE, 0xf0000);
-			vmcs_write16(GUEST_CS_SELECTOR,
-				     vmcs_readl(GUEST_CS_BASE) >> 4);
-			break;
-		case VCPU_SREG_ES:
-			fix_rmode_seg(VCPU_SREG_ES, &vmx->rmode.es);
-			break;
-		case VCPU_SREG_DS:
-			fix_rmode_seg(VCPU_SREG_DS, &vmx->rmode.ds);
-			break;
-		case VCPU_SREG_GS:
-			fix_rmode_seg(VCPU_SREG_GS, &vmx->rmode.gs);
-			break;
-		case VCPU_SREG_FS:
-			fix_rmode_seg(VCPU_SREG_FS, &vmx->rmode.fs);
-			break;
-		case VCPU_SREG_SS:
-			vmcs_write16(GUEST_SS_SELECTOR,
-				     vmcs_readl(GUEST_SS_BASE) >> 4);
-			vmcs_write32(GUEST_SS_LIMIT, 0xffff);
-			vmcs_write32(GUEST_SS_AR_BYTES, 0xf3);
-			break;
-		}
-	}
 }
 
 static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
diff -druN linux-libre-3.5.6-gnu/arch/x86/Makefile linux-libre-3.5.7-gnu/arch/x86/Makefile
--- linux-libre-3.5.6-gnu/arch/x86/Makefile	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/x86/Makefile	2012-10-12 16:48:25.000000000 -0400
@@ -85,7 +85,7 @@
 ifdef CONFIG_X86_X32
 	x32_ld_ok := $(call try-run,\
 			/bin/echo -e '1: .quad 1b' | \
-			$(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" - && \
+			$(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" - && \
 			$(OBJCOPY) -O elf32-x86-64 "$$TMP" "$$TMPO" && \
 			$(LD) -m elf32_x86_64 "$$TMPO" -o "$$TMP",y,n)
         ifeq ($(x32_ld_ok),y)
diff -druN linux-libre-3.5.6-gnu/arch/x86/platform/efi/efi.c linux-libre-3.5.7-gnu/arch/x86/platform/efi/efi.c
--- linux-libre-3.5.6-gnu/arch/x86/platform/efi/efi.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/x86/platform/efi/efi.c	2012-10-12 16:48:25.000000000 -0400
@@ -890,6 +890,7 @@
 	 *
 	 * Call EFI services through wrapper functions.
 	 */
+	efi.runtime_version = efi_systab.fw_revision;
 	efi.get_time = virt_efi_get_time;
 	efi.set_time = virt_efi_set_time;
 	efi.get_wakeup_time = virt_efi_get_wakeup_time;
diff -druN linux-libre-3.5.6-gnu/arch/xtensa/kernel/process.c linux-libre-3.5.7-gnu/arch/xtensa/kernel/process.c
--- linux-libre-3.5.6-gnu/arch/xtensa/kernel/process.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/arch/xtensa/kernel/process.c	2012-10-12 16:48:25.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/mqueue.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
+#include <linux/rcupdate.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -110,8 +111,10 @@
 
 	/* endless idle loop with no priority at all */
 	while (1) {
+		rcu_idle_enter();
 		while (!need_resched())
 			platform_idle();
+		rcu_idle_exit();
 		schedule_preempt_disabled();
 	}
 }
diff -druN linux-libre-3.5.6-gnu/drivers/acpi/bus.c linux-libre-3.5.7-gnu/drivers/acpi/bus.c
--- linux-libre-3.5.6-gnu/drivers/acpi/bus.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/acpi/bus.c	2012-10-12 16:48:25.000000000 -0400
@@ -990,8 +990,6 @@
 	status = acpi_ec_ecdt_probe();
 	/* Ignore result. Not having an ECDT is not fatal. */
 
-	acpi_bus_osc_support();
-
 	status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
 	if (ACPI_FAILURE(status)) {
 		printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
@@ -999,6 +997,12 @@
 	}
 
 	/*
+	 * _OSC method may exist in module level code,
+	 * so it must be run after ACPI_FULL_INITIALIZATION
+	 */
+	acpi_bus_osc_support();
+
+	/*
 	 * _PDC control method may load dynamic SSDT tables,
 	 * and we need to install the table handler before that.
 	 */
diff -druN linux-libre-3.5.6-gnu/drivers/base/core.c linux-libre-3.5.7-gnu/drivers/base/core.c
--- linux-libre-3.5.6-gnu/drivers/base/core.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/base/core.c	2012-10-12 16:48:25.000000000 -0400
@@ -1895,8 +1895,8 @@
 				    "DEVICE=+%s:%s", subsys, dev_name(dev));
 	}
 skip:
-	if (level[2])
-		level_extra = &level[2]; /* skip past KERN_SOH "L" */
+	if (level[3])
+		level_extra = &level[3]; /* skip past "<L>" */
 
 	return printk_emit(0, level[1] - '0',
 			   dictlen ? dict : NULL, dictlen,
diff -druN linux-libre-3.5.6-gnu/drivers/base/power/main.c linux-libre-3.5.7-gnu/drivers/base/power/main.c
--- linux-libre-3.5.6-gnu/drivers/base/power/main.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/base/power/main.c	2012-10-12 16:48:25.000000000 -0400
@@ -994,7 +994,7 @@
 
 	error = dpm_suspend_noirq(state);
 	if (error) {
-		dpm_resume_early(state);
+		dpm_resume_early(resume_event(state));
 		return error;
 	}
 
diff -druN linux-libre-3.5.6-gnu/drivers/block/aoe/aoecmd.c linux-libre-3.5.7-gnu/drivers/block/aoe/aoecmd.c
--- linux-libre-3.5.6-gnu/drivers/block/aoe/aoecmd.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/block/aoe/aoecmd.c	2012-10-12 16:48:25.000000000 -0400
@@ -35,6 +35,7 @@
 		skb_reset_mac_header(skb);
 		skb_reset_network_header(skb);
 		skb->protocol = __constant_htons(ETH_P_AOE);
+		skb_checksum_none_assert(skb);
 	}
 	return skb;
 }
diff -druN linux-libre-3.5.6-gnu/drivers/gpu/drm/drm_crtc.c linux-libre-3.5.7-gnu/drivers/gpu/drm/drm_crtc.c
--- linux-libre-3.5.6-gnu/drivers/gpu/drm/drm_crtc.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/gpu/drm/drm_crtc.c	2012-10-12 16:48:25.000000000 -0400
@@ -1034,15 +1034,15 @@
 		fb->funcs->destroy(fb);
 	}
 
-	list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
-		crtc->funcs->destroy(crtc);
-	}
-
 	list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
 				 head) {
 		plane->funcs->destroy(plane);
 	}
 
+	list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
+		crtc->funcs->destroy(crtc);
+	}
+
 	idr_remove_all(&dev->mode_config.crtc_idr);
 	idr_destroy(&dev->mode_config.crtc_idr);
 }
diff -druN linux-libre-3.5.6-gnu/drivers/gpu/drm/i915/i915_irq.c linux-libre-3.5.7-gnu/drivers/gpu/drm/i915/i915_irq.c
--- linux-libre-3.5.6-gnu/drivers/gpu/drm/i915/i915_irq.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/gpu/drm/i915/i915_irq.c	2012-10-12 16:48:25.000000000 -0400
@@ -605,12 +605,12 @@
 			intel_opregion_gse_intr(dev);
 
 		for (i = 0; i < 3; i++) {
+			if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i)))
+				drm_handle_vblank(dev, i);
 			if (de_iir & (DE_PLANEA_FLIP_DONE_IVB << (5 * i))) {
 				intel_prepare_page_flip(dev, i);
 				intel_finish_page_flip_plane(dev, i);
 			}
-			if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i)))
-				drm_handle_vblank(dev, i);
 		}
 
 		/* check event from PCH */
@@ -692,6 +692,12 @@
 	if (de_iir & DE_GSE)
 		intel_opregion_gse_intr(dev);
 
+	if (de_iir & DE_PIPEA_VBLANK)
+		drm_handle_vblank(dev, 0);
+
+	if (de_iir & DE_PIPEB_VBLANK)
+		drm_handle_vblank(dev, 1);
+
 	if (de_iir & DE_PLANEA_FLIP_DONE) {
 		intel_prepare_page_flip(dev, 0);
 		intel_finish_page_flip_plane(dev, 0);
@@ -702,12 +708,6 @@
 		intel_finish_page_flip_plane(dev, 1);
 	}
 
-	if (de_iir & DE_PIPEA_VBLANK)
-		drm_handle_vblank(dev, 0);
-
-	if (de_iir & DE_PIPEB_VBLANK)
-		drm_handle_vblank(dev, 1);
-
 	/* check event from PCH */
 	if (de_iir & DE_PCH_EVENT) {
 		if (pch_iir & hotplug_mask)
diff -druN linux-libre-3.5.6-gnu/drivers/gpu/drm/i915/i915_reg.h linux-libre-3.5.7-gnu/drivers/gpu/drm/i915/i915_reg.h
--- linux-libre-3.5.6-gnu/drivers/gpu/drm/i915/i915_reg.h	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/gpu/drm/i915/i915_reg.h	2012-10-12 16:48:25.000000000 -0400
@@ -514,6 +514,9 @@
 # define VS_TIMER_DISPATCH				(1 << 6)
 # define MI_FLUSH_ENABLE				(1 << 12)
 
+#define GEN6_GT_MODE	0x20d0
+#define   GEN6_GT_MODE_HI	(1 << 9)
+
 #define GFX_MODE	0x02520
 #define GFX_MODE_GEN7	0x0229c
 #define RING_MODE_GEN7(ring)	((ring)->mmio_base+0x29c)
diff -druN linux-libre-3.5.6-gnu/drivers/gpu/drm/i915/intel_display.c linux-libre-3.5.7-gnu/drivers/gpu/drm/i915/intel_display.c
--- linux-libre-3.5.6-gnu/drivers/gpu/drm/i915/intel_display.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/gpu/drm/i915/intel_display.c	2012-10-12 16:48:25.000000000 -0400
@@ -2641,13 +2641,34 @@
 	udelay(100);
 }
 
+static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+	bool pending;
+
+	if (atomic_read(&dev_priv->mm.wedged))
+		return false;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	pending = to_intel_crtc(crtc)->unpin_work != NULL;
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	return pending;
+}
+
 static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	if (crtc->fb == NULL)
 		return;
 
+	wait_event(dev_priv->pending_flip_queue,
+		   !intel_crtc_has_pending_flip(crtc));
+
 	mutex_lock(&dev->struct_mutex);
 	intel_finish_fb(crtc->fb);
 	mutex_unlock(&dev->struct_mutex);
@@ -5916,9 +5937,8 @@
 
 	atomic_clear_mask(1 << intel_crtc->plane,
 			  &obj->pending_flip.counter);
-	if (atomic_read(&obj->pending_flip) == 0)
-		wake_up(&dev_priv->pending_flip_queue);
 
+	wake_up(&dev_priv->pending_flip_queue);
 	schedule_work(&work->work);
 
 	trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj);
@@ -6167,7 +6187,7 @@
 	default:
 		WARN_ONCE(1, "unknown plane in flip command\n");
 		ret = -ENODEV;
-		goto err;
+		goto err_unpin;
 	}
 
 	ret = intel_ring_begin(ring, 4);
diff -druN linux-libre-3.5.6-gnu/drivers/gpu/drm/i915/intel_pm.c linux-libre-3.5.7-gnu/drivers/gpu/drm/i915/intel_pm.c
--- linux-libre-3.5.6-gnu/drivers/gpu/drm/i915/intel_pm.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/gpu/drm/i915/intel_pm.c	2012-10-12 16:48:25.000000000 -0400
@@ -3363,6 +3363,11 @@
 			   DISPPLANE_TRICKLE_FEED_DISABLE);
 		intel_flush_display_plane(dev_priv, pipe);
 	}
+
+	/* The default value should be 0x200 according to docs, but the two
+	 * platforms I checked have a 0 for this. (Maybe BIOS overrides?) */
+	I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_DISABLE(0xffff));
+	I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_ENABLE(GEN6_GT_MODE_HI));
 }
 
 static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv)
diff -druN linux-libre-3.5.6-gnu/drivers/gpu/drm/i915/intel_ringbuffer.c linux-libre-3.5.7-gnu/drivers/gpu/drm/i915/intel_ringbuffer.c
--- linux-libre-3.5.6-gnu/drivers/gpu/drm/i915/intel_ringbuffer.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/gpu/drm/i915/intel_ringbuffer.c	2012-10-12 16:48:25.000000000 -0400
@@ -280,6 +280,8 @@
 	I915_WRITE_HEAD(ring, 0);
 	ring->write_tail(ring, 0);
 
+	/* Initialize the ring. */
+	I915_WRITE_START(ring, obj->gtt_offset);
 	head = I915_READ_HEAD(ring) & HEAD_ADDR;
 
 	/* G45 ring initialization fails to reset head to zero */
@@ -305,11 +307,6 @@
 		}
 	}
 
-	/* Initialize the ring. This must happen _after_ we've cleared the ring
-	 * registers with the above sequence (the readback of the HEAD registers
-	 * also enforces ordering), otherwise the hw might lose the new ring
-	 * register values. */
-	I915_WRITE_START(ring, obj->gtt_offset);
 	I915_WRITE_CTL(ring,
 			((ring->size - PAGE_SIZE) & RING_NR_PAGES)
 			| RING_VALID);
diff -druN linux-libre-3.5.6-gnu/drivers/gpu/drm/nouveau/nvc0_fence.c linux-libre-3.5.7-gnu/drivers/gpu/drm/nouveau/nvc0_fence.c
--- linux-libre-3.5.6-gnu/drivers/gpu/drm/nouveau/nvc0_fence.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/gpu/drm/nouveau/nvc0_fence.c	2012-10-12 16:48:25.000000000 -0400
@@ -32,6 +32,7 @@
 struct nvc0_fence_priv {
 	struct nouveau_fence_priv base;
 	struct nouveau_bo *bo;
+	u32 *suspend;
 };
 
 struct nvc0_fence_chan {
@@ -125,12 +126,36 @@
 static int
 nvc0_fence_fini(struct drm_device *dev, int engine, bool suspend)
 {
+	struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
+	struct nvc0_fence_priv *priv = nv_engine(dev, engine);
+	int i;
+
+	if (suspend) {
+		priv->suspend = vmalloc(pfifo->channels * sizeof(u32));
+		if (!priv->suspend)
+			return -ENOMEM;
+
+		for (i = 0; i < pfifo->channels; i++)
+			priv->suspend[i] = nouveau_bo_rd32(priv->bo, i);
+	}
+
 	return 0;
 }
 
 static int
 nvc0_fence_init(struct drm_device *dev, int engine)
 {
+	struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
+	struct nvc0_fence_priv *priv = nv_engine(dev, engine);
+	int i;
+
+	if (priv->suspend) {
+		for (i = 0; i < pfifo->channels; i++)
+			nouveau_bo_wr32(priv->bo, i, priv->suspend[i]);
+		vfree(priv->suspend);
+		priv->suspend = NULL;
+	}
+
 	return 0;
 }
 
diff -druN linux-libre-3.5.6-gnu/drivers/gpu/drm/radeon/radeon_irq_kms.c linux-libre-3.5.7-gnu/drivers/gpu/drm/radeon/radeon_irq_kms.c
--- linux-libre-3.5.6-gnu/drivers/gpu/drm/radeon/radeon_irq_kms.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/gpu/drm/radeon/radeon_irq_kms.c	2012-10-12 16:48:25.000000000 -0400
@@ -149,6 +149,16 @@
 	    (rdev->pdev->subsystem_device == 0x01fd))
 		return true;
 
+	/* Gateway RS690 only seems to work with MSIs. */
+	if ((rdev->pdev->device == 0x791f) &&
+	    (rdev->pdev->subsystem_vendor == 0x107b) &&
+	    (rdev->pdev->subsystem_device == 0x0185))
+		return true;
+
+	/* try and enable MSIs by default on all RS690s */
+	if (rdev->family == CHIP_RS690)
+		return true;
+
 	/* RV515 seems to have MSI issues where it loses
 	 * MSI rearms occasionally. This leads to lockups and freezes.
 	 * disable it by default.
diff -druN linux-libre-3.5.6-gnu/drivers/gpu/drm/radeon/radeon_pm.c linux-libre-3.5.7-gnu/drivers/gpu/drm/radeon/radeon_pm.c
--- linux-libre-3.5.6-gnu/drivers/gpu/drm/radeon/radeon_pm.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/gpu/drm/radeon/radeon_pm.c	2012-10-12 16:48:25.000000000 -0400
@@ -555,7 +555,9 @@
 void radeon_pm_resume(struct radeon_device *rdev)
 {
 	/* set up the default clocks if the MC ucode is loaded */
-	if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) {
+	if ((rdev->family >= CHIP_BARTS) &&
+	    (rdev->family <= CHIP_CAYMAN) &&
+	    rdev->mc_fw) {
 		if (rdev->pm.default_vddc)
 			radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
 						SET_VOLTAGE_TYPE_ASIC_VDDC);
@@ -610,7 +612,9 @@
 		radeon_pm_print_states(rdev);
 		radeon_pm_init_profile(rdev);
 		/* set up the default clocks if the MC ucode is loaded */
-		if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) {
+		if ((rdev->family >= CHIP_BARTS) &&
+		    (rdev->family <= CHIP_CAYMAN) &&
+		    rdev->mc_fw) {
 			if (rdev->pm.default_vddc)
 				radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
 							SET_VOLTAGE_TYPE_ASIC_VDDC);
diff -druN linux-libre-3.5.6-gnu/drivers/gpu/drm/savage/savage_bci.c linux-libre-3.5.7-gnu/drivers/gpu/drm/savage/savage_bci.c
--- linux-libre-3.5.6-gnu/drivers/gpu/drm/savage/savage_bci.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/gpu/drm/savage/savage_bci.c	2012-10-12 16:48:25.000000000 -0400
@@ -547,6 +547,8 @@
 
 	dev_priv->chipset = (enum savage_family)chipset;
 
+	pci_set_master(dev->pdev);
+
 	return 0;
 }
 
diff -druN linux-libre-3.5.6-gnu/drivers/iommu/intel-iommu.c linux-libre-3.5.7-gnu/drivers/iommu/intel-iommu.c
--- linux-libre-3.5.6-gnu/drivers/iommu/intel-iommu.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/iommu/intel-iommu.c	2012-10-12 16:48:25.000000000 -0400
@@ -589,7 +589,9 @@
 {
 	int i;
 
-	domain->iommu_coherency = 1;
+	i = find_first_bit(domain->iommu_bmp, g_num_of_iommus);
+
+	domain->iommu_coherency = i < g_num_of_iommus ? 1 : 0;
 
 	for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) {
 		if (!ecap_coherent(g_iommus[i]->ecap)) {
diff -druN linux-libre-3.5.6-gnu/drivers/media/rc/ite-cir.c linux-libre-3.5.7-gnu/drivers/media/rc/ite-cir.c
--- linux-libre-3.5.6-gnu/drivers/media/rc/ite-cir.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/media/rc/ite-cir.c	2012-10-12 16:48:25.000000000 -0400
@@ -1473,6 +1473,7 @@
 	rdev = rc_allocate_device();
 	if (!rdev)
 		goto failure;
+	itdev->rdev = rdev;
 
 	ret = -ENODEV;
 
@@ -1604,7 +1605,6 @@
 	if (ret)
 		goto failure3;
 
-	itdev->rdev = rdev;
 	ite_pr(KERN_NOTICE, "driver has been successfully loaded\n");
 
 	return 0;
diff -druN linux-libre-3.5.6-gnu/drivers/media/video/em28xx/em28xx-cards.c linux-libre-3.5.7-gnu/drivers/media/video/em28xx/em28xx-cards.c
--- linux-libre-3.5.6-gnu/drivers/media/video/em28xx/em28xx-cards.c	2012-10-07 22:17:04.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/media/video/em28xx/em28xx-cards.c	2012-10-13 14:07:01.000000000 -0400
@@ -2880,12 +2880,20 @@
 }
 
 
-#if defined(CONFIG_MODULES) && defined(MODULE)
 static void request_module_async(struct work_struct *work)
 {
 	struct em28xx *dev = container_of(work,
 			     struct em28xx, request_module_wk);
 
+	/*
+	 * The em28xx extensions can be modules or builtin. If the
+	 * modules are already loaded or are built in, those extensions
+	 * can be initialised right now. Otherwise, the module init
+	 * code will do it.
+	 */
+	em28xx_init_extension(dev);
+
+#if defined(CONFIG_MODULES) && defined(MODULE)
 	if (dev->has_audio_class)
 		request_module("snd-usb-audio");
 	else if (dev->has_alsa_audio)
@@ -2895,6 +2903,7 @@
 		request_module("em28xx-dvb");
 	if (dev->board.ir_codes && !disable_ir)
 		request_module("em28xx-rc");
+#endif /* CONFIG_MODULES */
 }
 
 static void request_modules(struct em28xx *dev)
@@ -2907,10 +2916,6 @@
 {
 	flush_work_sync(&dev->request_module_wk);
 }
-#else
-#define request_modules(dev)
-#define flush_request_modules(dev)
-#endif /* CONFIG_MODULES */
 
 /*
  * em28xx_release_resources()
@@ -3329,13 +3334,6 @@
 	 */
 	mutex_unlock(&dev->lock);
 
-	/*
-	 * These extensions can be modules. If the modules are already
-	 * loaded then we can initialise the device now, otherwise we
-	 * will initialise it when the modules load instead.
-	 */
-	em28xx_init_extension(dev);
-
 	return 0;
 
 unlock_and_free:
diff -druN linux-libre-3.5.6-gnu/drivers/media/video/gspca/pac7302.c linux-libre-3.5.7-gnu/drivers/media/video/gspca/pac7302.c
--- linux-libre-3.5.6-gnu/drivers/media/video/gspca/pac7302.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/media/video/gspca/pac7302.c	2012-10-12 16:48:25.000000000 -0400
@@ -978,6 +978,7 @@
 	{USB_DEVICE(0x093a, 0x262a)},
 	{USB_DEVICE(0x093a, 0x262c)},
 	{USB_DEVICE(0x145f, 0x013c)},
+	{USB_DEVICE(0x1ae7, 0x2001)}, /* SpeedLink Snappy Mic SL-6825-SBK */
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
diff -druN linux-libre-3.5.6-gnu/drivers/mfd/max8925-core.c linux-libre-3.5.7-gnu/drivers/mfd/max8925-core.c
--- linux-libre-3.5.6-gnu/drivers/mfd/max8925-core.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/mfd/max8925-core.c	2012-10-12 16:48:25.000000000 -0400
@@ -18,12 +18,19 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/max8925.h>
 
+static struct resource io_parent = {
+	.start = 0,
+	.end   = 0xffffffff,
+	.flags = IORESOURCE_IO,
+};
+
 static struct resource backlight_resources[] = {
 	{
 		.name	= "max8925-backlight",
 		.start	= MAX8925_WLED_MODE_CNTL,
 		.end	= MAX8925_WLED_CNTL,
 		.flags	= IORESOURCE_IO,
+		.parent = &io_parent,
 	},
 };
 
@@ -42,6 +49,7 @@
 		.start	= MAX8925_TSC_IRQ,
 		.end	= MAX8925_ADC_RES_END,
 		.flags	= IORESOURCE_IO,
+		.parent = &io_parent,
 	},
 };
 
@@ -60,6 +68,7 @@
 		.start	= MAX8925_CHG_IRQ1,
 		.end	= MAX8925_CHG_IRQ1_MASK,
 		.flags	= IORESOURCE_IO,
+		.parent = &io_parent,
 	},
 };
 
@@ -118,6 +127,7 @@
 	.start	= MAX8925_##_start,		\
 	.end	= MAX8925_##_end,		\
 	.flags	= IORESOURCE_IO,		\
+	.parent = &io_parent,			\
 }
 
 static struct resource regulator_resources[] = {
diff -druN linux-libre-3.5.6-gnu/drivers/mmc/host/omap_hsmmc.c linux-libre-3.5.7-gnu/drivers/mmc/host/omap_hsmmc.c
--- linux-libre-3.5.6-gnu/drivers/mmc/host/omap_hsmmc.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/mmc/host/omap_hsmmc.c	2012-10-12 16:48:25.000000000 -0400
@@ -2102,8 +2102,7 @@
 	if (ret) {
 		host->suspended = 0;
 		if (host->pdata->resume) {
-			ret = host->pdata->resume(dev, host->slot_id);
-			if (ret)
+			if (host->pdata->resume(dev, host->slot_id))
 				dev_dbg(dev, "Unmask interrupt failed\n");
 		}
 		goto err;
diff -druN linux-libre-3.5.6-gnu/drivers/mmc/host/sh_mmcif.c linux-libre-3.5.7-gnu/drivers/mmc/host/sh_mmcif.c
--- linux-libre-3.5.6-gnu/drivers/mmc/host/sh_mmcif.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/mmc/host/sh_mmcif.c	2012-10-12 16:48:25.000000000 -0400
@@ -1191,6 +1191,10 @@
 		host->sd_error = true;
 		dev_dbg(&host->pd->dev, "int err state = %08x\n", state);
 	}
+	if (host->state == STATE_IDLE) {
+		dev_info(&host->pd->dev, "Spurious IRQ status 0x%x", state);
+		return IRQ_HANDLED;
+	}
 	if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) {
 		if (!host->dma_active)
 			return IRQ_WAKE_THREAD;
diff -druN linux-libre-3.5.6-gnu/drivers/mtd/maps/autcpu12-nvram.c linux-libre-3.5.7-gnu/drivers/mtd/maps/autcpu12-nvram.c
--- linux-libre-3.5.6-gnu/drivers/mtd/maps/autcpu12-nvram.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/mtd/maps/autcpu12-nvram.c	2012-10-12 16:48:25.000000000 -0400
@@ -43,7 +43,8 @@
 
 static int __init init_autcpu12_sram (void)
 {
-	int err, save0, save1;
+	map_word tmp, save0, save1;
+	int err;
 
 	autcpu12_sram_map.virt = ioremap(0x12000000, SZ_128K);
 	if (!autcpu12_sram_map.virt) {
@@ -51,7 +52,7 @@
 		err = -EIO;
 		goto out;
 	}
-	simple_map_init(&autcpu_sram_map);
+	simple_map_init(&autcpu12_sram_map);
 
 	/*
 	 * Check for 32K/128K
@@ -61,20 +62,22 @@
 	 * Read	and check result on ofs 0x0
 	 * Restore contents
 	 */
-	save0 = map_read32(&autcpu12_sram_map,0);
-	save1 = map_read32(&autcpu12_sram_map,0x10000);
-	map_write32(&autcpu12_sram_map,~save0,0x10000);
+	save0 = map_read(&autcpu12_sram_map, 0);
+	save1 = map_read(&autcpu12_sram_map, 0x10000);
+	tmp.x[0] = ~save0.x[0];
+	map_write(&autcpu12_sram_map, tmp, 0x10000);
 	/* if we find this pattern on 0x0, we have 32K size
 	 * restore contents and exit
 	 */
-	if ( map_read32(&autcpu12_sram_map,0) != save0) {
-		map_write32(&autcpu12_sram_map,save0,0x0);
+	tmp = map_read(&autcpu12_sram_map, 0);
+	if (!map_word_equal(&autcpu12_sram_map, tmp, save0)) {
+		map_write(&autcpu12_sram_map, save0, 0x0);
 		goto map;
 	}
 	/* We have a 128K found, restore 0x10000 and set size
 	 * to 128K
 	 */
-	map_write32(&autcpu12_sram_map,save1,0x10000);
+	map_write(&autcpu12_sram_map, save1, 0x10000);
 	autcpu12_sram_map.size = SZ_128K;
 
 map:
diff -druN linux-libre-3.5.6-gnu/drivers/mtd/mtdpart.c linux-libre-3.5.7-gnu/drivers/mtd/mtdpart.c
--- linux-libre-3.5.6-gnu/drivers/mtd/mtdpart.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/mtd/mtdpart.c	2012-10-12 16:48:25.000000000 -0400
@@ -711,6 +711,8 @@
  * partition parsers, specified in @types. However, if @types is %NULL, then
  * the default list of parsers is used. The default list contains only the
  * "cmdlinepart" and "ofpart" parsers ATM.
+ * Note: If there are more then one parser in @types, the kernel only takes the
+ * partitions parsed out by the first parser.
  *
  * This function may return:
  * o a negative error code in case of failure
@@ -735,11 +737,12 @@
 		if (!parser)
 			continue;
 		ret = (*parser->parse_fn)(master, pparts, data);
+		put_partition_parser(parser);
 		if (ret > 0) {
 			printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
 			       ret, parser->name, master->name);
+			break;
 		}
-		put_partition_parser(parser);
 	}
 	return ret;
 }
diff -druN linux-libre-3.5.6-gnu/drivers/mtd/nand/nand_bbt.c linux-libre-3.5.7-gnu/drivers/mtd/nand/nand_bbt.c
--- linux-libre-3.5.6-gnu/drivers/mtd/nand/nand_bbt.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/mtd/nand/nand_bbt.c	2012-10-12 16:48:25.000000000 -0400
@@ -390,7 +390,7 @@
 	/* Read the mirror version, if available */
 	if (md && (md->options & NAND_BBT_VERSION)) {
 		scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
-			      mtd->writesize, td);
+			      mtd->writesize, md);
 		md->version[0] = buf[bbt_get_ver_offs(mtd, md)];
 		pr_info("Bad block table at page %d, version 0x%02X\n",
 			 md->pages[0], md->version[0]);
diff -druN linux-libre-3.5.6-gnu/drivers/mtd/nand/nandsim.c linux-libre-3.5.7-gnu/drivers/mtd/nand/nandsim.c
--- linux-libre-3.5.6-gnu/drivers/mtd/nand/nandsim.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/mtd/nand/nandsim.c	2012-10-12 16:48:25.000000000 -0400
@@ -2333,6 +2333,7 @@
 		uint64_t new_size = (uint64_t)nsmtd->erasesize << overridesize;
 		if (new_size >> overridesize != nsmtd->erasesize) {
 			NS_ERR("overridesize is too big\n");
+			retval = -EINVAL;
 			goto err_exit;
 		}
 		/* N.B. This relies on nand_scan not doing anything with the size before we change it */
diff -druN linux-libre-3.5.6-gnu/drivers/mtd/nand/omap2.c linux-libre-3.5.7-gnu/drivers/mtd/nand/omap2.c
--- linux-libre-3.5.6-gnu/drivers/mtd/nand/omap2.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/mtd/nand/omap2.c	2012-10-12 16:48:25.000000000 -0400
@@ -1382,7 +1382,8 @@
 	/* Release NAND device, its internal structures and partitions */
 	nand_release(&info->mtd);
 	iounmap(info->nand.IO_ADDR_R);
-	kfree(&info->mtd);
+	release_mem_region(info->phys_base, NAND_IO_SIZE);
+	kfree(info);
 	return 0;
 }
 
diff -druN linux-libre-3.5.6-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c linux-libre-3.5.7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
--- linux-libre-3.5.6-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c	2012-10-07 22:20:40.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c	2012-10-13 14:10:38.000000000 -0400
@@ -620,14 +620,16 @@
 static void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe,
 				struct bnx2x_fastpath *fp)
 {
-	/* Do nothing if no IP/L4 csum validation was done */
-
+	/* Do nothing if no L4 csum validation was done.
+	 * We do not check whether IP csum was validated. For IPv4 we assume
+	 * that if the card got as far as validating the L4 csum, it also
+	 * validated the IP csum. IPv6 has no IP csum.
+	 */
 	if (cqe->fast_path_cqe.status_flags &
-	    (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG |
-	     ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG))
+	    ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG)
 		return;
 
-	/* If both IP/L4 validation were done, check if an error was found. */
+	/* If L4 validation was done, check if an error was found. */
 
 	if (cqe->fast_path_cqe.type_error_flags &
 	    (ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG |
diff -druN linux-libre-3.5.6-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c linux-libre-3.5.7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
--- linux-libre-3.5.6-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c	2012-10-12 16:48:25.000000000 -0400
@@ -2723,10 +2723,7 @@
 			(1 << HWTSTAMP_FILTER_NONE) |
 			(1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
 			(1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
-			(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
-			(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
-			(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
-			(1 << HWTSTAMP_FILTER_SOME);
+			(1 << HWTSTAMP_FILTER_PTP_V2_EVENT);
 		break;
 #endif /* CONFIG_IXGBE_PTP */
 	default:
diff -druN linux-libre-3.5.6-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c linux-libre-3.5.7-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
--- linux-libre-3.5.6-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c	2012-10-07 22:21:19.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c	2012-10-13 14:11:16.000000000 -0400
@@ -1378,6 +1378,10 @@
 	struct pci_dev *root = pdev->bus->self;
 	u32 aer_pos;
 
+	/* root bus? */
+	if (!root)
+		return;
+
 	if (adapter->ahw.board_type != NETXEN_BRDTYPE_P3_4_GB_MM &&
 		adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP)
 		return;
diff -druN linux-libre-3.5.6-gnu/drivers/net/ethernet/ti/davinci_cpdma.c linux-libre-3.5.7-gnu/drivers/net/ethernet/ti/davinci_cpdma.c
--- linux-libre-3.5.6-gnu/drivers/net/ethernet/ti/davinci_cpdma.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/net/ethernet/ti/davinci_cpdma.c	2012-10-12 16:48:25.000000000 -0400
@@ -862,6 +862,7 @@
 
 		next_dma = desc_read(desc, hw_next);
 		chan->head = desc_from_phys(pool, next_dma);
+		chan->count--;
 		chan->stats.teardown_dequeue++;
 
 		/* issue callback without locks held */
diff -druN linux-libre-3.5.6-gnu/drivers/net/ppp/pppoe.c linux-libre-3.5.7-gnu/drivers/net/ppp/pppoe.c
--- linux-libre-3.5.6-gnu/drivers/net/ppp/pppoe.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/net/ppp/pppoe.c	2012-10-12 16:48:25.000000000 -0400
@@ -570,7 +570,7 @@
 
 	po = pppox_sk(sk);
 
-	if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+	if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
 		dev_put(po->pppoe_dev);
 		po->pppoe_dev = NULL;
 	}
diff -druN linux-libre-3.5.6-gnu/drivers/net/rionet.c linux-libre-3.5.7-gnu/drivers/net/rionet.c
--- linux-libre-3.5.6-gnu/drivers/net/rionet.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/net/rionet.c	2012-10-12 16:48:25.000000000 -0400
@@ -79,6 +79,7 @@
  * on system trade-offs.
  */
 static struct rio_dev **rionet_active;
+static int nact;	/* total number of active rionet peers */
 
 #define is_rionet_capable(src_ops, dst_ops)			\
 			((src_ops & RIO_SRC_OPS_DATA_MSG) &&	\
@@ -175,6 +176,7 @@
 	struct ethhdr *eth = (struct ethhdr *)skb->data;
 	u16 destid;
 	unsigned long flags;
+	int add_num = 1;
 
 	local_irq_save(flags);
 	if (!spin_trylock(&rnet->tx_lock)) {
@@ -182,7 +184,10 @@
 		return NETDEV_TX_LOCKED;
 	}
 
-	if ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) {
+	if (is_multicast_ether_addr(eth->h_dest))
+		add_num = nact;
+
+	if ((rnet->tx_cnt + add_num) > RIONET_TX_RING_SIZE) {
 		netif_stop_queue(ndev);
 		spin_unlock_irqrestore(&rnet->tx_lock, flags);
 		printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
@@ -191,11 +196,16 @@
 	}
 
 	if (is_multicast_ether_addr(eth->h_dest)) {
+		int count = 0;
 		for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size);
 				i++)
-			if (rionet_active[i])
+			if (rionet_active[i]) {
 				rionet_queue_tx_msg(skb, ndev,
 						    rionet_active[i]);
+				if (count)
+					atomic_inc(&skb->users);
+				count++;
+			}
 	} else if (RIONET_MAC_MATCH(eth->h_dest)) {
 		destid = RIONET_GET_DESTID(eth->h_dest);
 		if (rionet_active[destid])
@@ -220,14 +230,17 @@
 	if (info == RIONET_DOORBELL_JOIN) {
 		if (!rionet_active[sid]) {
 			list_for_each_entry(peer, &rionet_peers, node) {
-				if (peer->rdev->destid == sid)
+				if (peer->rdev->destid == sid) {
 					rionet_active[sid] = peer->rdev;
+					nact++;
+				}
 			}
 			rio_mport_send_doorbell(mport, sid,
 						RIONET_DOORBELL_JOIN);
 		}
 	} else if (info == RIONET_DOORBELL_LEAVE) {
 		rionet_active[sid] = NULL;
+		nact--;
 	} else {
 		if (netif_msg_intr(rnet))
 			printk(KERN_WARNING "%s: unhandled doorbell\n",
@@ -523,6 +536,7 @@
 
 		rc = rionet_setup_netdev(rdev->net->hport, ndev);
 		rionet_check = 1;
+		nact = 0;
 	}
 
 	/*
diff -druN linux-libre-3.5.6-gnu/drivers/net/usb/sierra_net.c linux-libre-3.5.7-gnu/drivers/net/usb/sierra_net.c
--- linux-libre-3.5.6-gnu/drivers/net/usb/sierra_net.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/net/usb/sierra_net.c	2012-10-12 16:48:25.000000000 -0400
@@ -678,7 +678,7 @@
 		return -EIO;
 	}
 
-	*datap = *attrdata;
+	*datap = le16_to_cpu(*attrdata);
 
 	kfree(attrdata);
 	return result;
diff -druN linux-libre-3.5.6-gnu/drivers/net/wan/ixp4xx_hss.c linux-libre-3.5.7-gnu/drivers/net/wan/ixp4xx_hss.c
--- linux-libre-3.5.6-gnu/drivers/net/wan/ixp4xx_hss.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/net/wan/ixp4xx_hss.c	2012-10-12 16:48:25.000000000 -0400
@@ -10,6 +10,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/cdev.h>
 #include <linux/dma-mapping.h>
diff -druN linux-libre-3.5.6-gnu/drivers/pci/hotplug/acpiphp_glue.c linux-libre-3.5.7-gnu/drivers/pci/hotplug/acpiphp_glue.c
--- linux-libre-3.5.6-gnu/drivers/pci/hotplug/acpiphp_glue.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/pci/hotplug/acpiphp_glue.c	2012-10-12 16:48:25.000000000 -0400
@@ -132,6 +132,15 @@
 	if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle))
 		return AE_OK;
 
+	status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
+	if (ACPI_FAILURE(status)) {
+		warn("can't evaluate _ADR (%#x)\n", status);
+		return AE_OK;
+	}
+
+	device = (adr >> 16) & 0xffff;
+	function = adr & 0xffff;
+
 	pdev = pbus->self;
 	if (pdev && pci_is_pcie(pdev)) {
 		tmp = acpi_find_root_bridge_handle(pdev);
@@ -144,10 +153,6 @@
 		}
 	}
 
-	acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
-	device = (adr >> 16) & 0xffff;
-	function = adr & 0xffff;
-
 	newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
 	if (!newfunc)
 		return AE_NO_MEMORY;
diff -druN linux-libre-3.5.6-gnu/drivers/pci/probe.c linux-libre-3.5.7-gnu/drivers/pci/probe.c
--- linux-libre-3.5.6-gnu/drivers/pci/probe.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/pci/probe.c	2012-10-12 16:48:25.000000000 -0400
@@ -684,8 +684,10 @@
 
 	/* Check if setup is sensible at all */
 	if (!pass &&
-	    (primary != bus->number || secondary <= bus->number)) {
-		dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n");
+	    (primary != bus->number || secondary <= bus->number ||
+	     secondary > subordinate)) {
+		dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n",
+			 secondary, subordinate);
 		broken = 1;
 	}
 
diff -druN linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_aux.c linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_aux.c
--- linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_aux.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_aux.c	2012-10-12 16:48:25.000000000 -0400
@@ -519,6 +519,7 @@
 
 	rwlock_init(&port->unit_list_lock);
 	INIT_LIST_HEAD(&port->unit_list);
+	atomic_set(&port->units, 0);
 
 	INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
 	INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
diff -druN linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_ccw.c linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_ccw.c
--- linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_ccw.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_ccw.c	2012-10-12 16:48:25.000000000 -0400
@@ -39,17 +39,23 @@
 	spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
 }
 
-static int zfcp_ccw_activate(struct ccw_device *cdev)
-
+/**
+ * zfcp_ccw_activate - activate adapter and wait for it to finish
+ * @cdev: pointer to belonging ccw device
+ * @clear: Status flags to clear.
+ * @tag: s390dbf trace record tag
+ */
+static int zfcp_ccw_activate(struct ccw_device *cdev, int clear, char *tag)
 {
 	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 
 	if (!adapter)
 		return 0;
 
+	zfcp_erp_clear_adapter_status(adapter, clear);
 	zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
 	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
-				"ccresu2");
+				tag);
 	zfcp_erp_wait(adapter);
 	flush_work(&adapter->scan_work);
 
@@ -164,26 +170,29 @@
 	BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
 	adapter->req_no = 0;
 
-	zfcp_ccw_activate(cdev);
+	zfcp_ccw_activate(cdev, 0, "ccsonl1");
 	zfcp_ccw_adapter_put(adapter);
 	return 0;
 }
 
 /**
- * zfcp_ccw_set_offline - set_offline function of zfcp driver
+ * zfcp_ccw_offline_sync - shut down adapter and wait for it to finish
  * @cdev: pointer to belonging ccw device
+ * @set: Status flags to set.
+ * @tag: s390dbf trace record tag
  *
  * This function gets called by the common i/o layer and sets an adapter
  * into state offline.
  */
-static int zfcp_ccw_set_offline(struct ccw_device *cdev)
+static int zfcp_ccw_offline_sync(struct ccw_device *cdev, int set, char *tag)
 {
 	struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
 
 	if (!adapter)
 		return 0;
 
-	zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1");
+	zfcp_erp_set_adapter_status(adapter, set);
+	zfcp_erp_adapter_shutdown(adapter, 0, tag);
 	zfcp_erp_wait(adapter);
 
 	zfcp_ccw_adapter_put(adapter);
@@ -191,6 +200,18 @@
 }
 
 /**
+ * zfcp_ccw_set_offline - set_offline function of zfcp driver
+ * @cdev: pointer to belonging ccw device
+ *
+ * This function gets called by the common i/o layer and sets an adapter
+ * into state offline.
+ */
+static int zfcp_ccw_set_offline(struct ccw_device *cdev)
+{
+	return zfcp_ccw_offline_sync(cdev, 0, "ccsoff1");
+}
+
+/**
  * zfcp_ccw_notify - ccw notify function
  * @cdev: pointer to belonging ccw device
  * @event: indicates if adapter was detached or attached
@@ -207,6 +228,11 @@
 
 	switch (event) {
 	case CIO_GONE:
+		if (atomic_read(&adapter->status) &
+		    ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
+			zfcp_dbf_hba_basic("ccnigo1", adapter);
+			break;
+		}
 		dev_warn(&cdev->dev, "The FCP device has been detached\n");
 		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
 		break;
@@ -216,6 +242,11 @@
 		zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
 		break;
 	case CIO_OPER:
+		if (atomic_read(&adapter->status) &
+		    ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
+			zfcp_dbf_hba_basic("ccniop1", adapter);
+			break;
+		}
 		dev_info(&cdev->dev, "The FCP device is operational again\n");
 		zfcp_erp_set_adapter_status(adapter,
 					    ZFCP_STATUS_COMMON_RUNNING);
@@ -251,6 +282,28 @@
 	zfcp_ccw_adapter_put(adapter);
 }
 
+static int zfcp_ccw_suspend(struct ccw_device *cdev)
+{
+	zfcp_ccw_offline_sync(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccsusp1");
+	return 0;
+}
+
+static int zfcp_ccw_thaw(struct ccw_device *cdev)
+{
+	/* trace records for thaw and final shutdown during suspend
+	   can only be found in system dump until the end of suspend
+	   but not after resume because it's based on the memory image
+	   right after the very first suspend (freeze) callback */
+	zfcp_ccw_activate(cdev, 0, "ccthaw1");
+	return 0;
+}
+
+static int zfcp_ccw_resume(struct ccw_device *cdev)
+{
+	zfcp_ccw_activate(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccresu1");
+	return 0;
+}
+
 struct ccw_driver zfcp_ccw_driver = {
 	.driver = {
 		.owner	= THIS_MODULE,
@@ -263,7 +316,7 @@
 	.set_offline = zfcp_ccw_set_offline,
 	.notify      = zfcp_ccw_notify,
 	.shutdown    = zfcp_ccw_shutdown,
-	.freeze      = zfcp_ccw_set_offline,
-	.thaw	     = zfcp_ccw_activate,
-	.restore     = zfcp_ccw_activate,
+	.freeze      = zfcp_ccw_suspend,
+	.thaw	     = zfcp_ccw_thaw,
+	.restore     = zfcp_ccw_resume,
 };
diff -druN linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_cfdc.c linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_cfdc.c
--- linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_cfdc.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_cfdc.c	2012-10-12 16:48:25.000000000 -0400
@@ -293,7 +293,7 @@
 	}
 	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 
-	shost_for_each_device(sdev, port->adapter->scsi_host) {
+	shost_for_each_device(sdev, adapter->scsi_host) {
 		zfcp_sdev = sdev_to_zfcp(sdev);
 		status = atomic_read(&zfcp_sdev->status);
 		if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) ||
diff -druN linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_dbf.c linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_dbf.c
--- linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_dbf.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_dbf.c	2012-10-12 16:48:25.000000000 -0400
@@ -191,7 +191,7 @@
 	length = min((u16)sizeof(struct qdio_buffer),
 		     (u16)ZFCP_DBF_PAY_MAX_REC);
 
-	while ((char *)pl[payload->counter] && payload->counter < scount) {
+	while (payload->counter < scount && (char *)pl[payload->counter]) {
 		memcpy(payload->data, (char *)pl[payload->counter], length);
 		debug_event(dbf->pay, 1, payload, zfcp_dbf_plen(length));
 		payload->counter++;
@@ -200,6 +200,26 @@
 	spin_unlock_irqrestore(&dbf->pay_lock, flags);
 }
 
+/**
+ * zfcp_dbf_hba_basic - trace event for basic adapter events
+ * @adapter: pointer to struct zfcp_adapter
+ */
+void zfcp_dbf_hba_basic(char *tag, struct zfcp_adapter *adapter)
+{
+	struct zfcp_dbf *dbf = adapter->dbf;
+	struct zfcp_dbf_hba *rec = &dbf->hba_buf;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dbf->hba_lock, flags);
+	memset(rec, 0, sizeof(*rec));
+
+	memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
+	rec->id = ZFCP_DBF_HBA_BASIC;
+
+	debug_event(dbf->hba, 1, rec, sizeof(*rec));
+	spin_unlock_irqrestore(&dbf->hba_lock, flags);
+}
+
 static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec,
 				struct zfcp_adapter *adapter,
 				struct zfcp_port *port,
diff -druN linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_dbf.h linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_dbf.h
--- linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_dbf.h	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_dbf.h	2012-10-12 16:48:25.000000000 -0400
@@ -154,6 +154,7 @@
 	ZFCP_DBF_HBA_RES	= 1,
 	ZFCP_DBF_HBA_USS	= 2,
 	ZFCP_DBF_HBA_BIT	= 3,
+	ZFCP_DBF_HBA_BASIC	= 4,
 };
 
 /**
diff -druN linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_def.h linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_def.h
--- linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_def.h	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_def.h	2012-10-12 16:48:25.000000000 -0400
@@ -77,6 +77,7 @@
 #define ZFCP_STATUS_ADAPTER_SIOSL_ISSUED	0x00000004
 #define ZFCP_STATUS_ADAPTER_XCONFIG_OK		0x00000008
 #define ZFCP_STATUS_ADAPTER_HOST_CON_INIT	0x00000010
+#define ZFCP_STATUS_ADAPTER_SUSPENDED		0x00000040
 #define ZFCP_STATUS_ADAPTER_ERP_PENDING		0x00000100
 #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED	0x00000200
 #define ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED	0x00000400
@@ -204,6 +205,7 @@
 	struct zfcp_adapter    *adapter;       /* adapter used to access port */
 	struct list_head	unit_list;	/* head of logical unit list */
 	rwlock_t		unit_list_lock; /* unit list lock */
+	atomic_t		units;	       /* zfcp_unit count */
 	atomic_t	       status;	       /* status of this remote port */
 	u64		       wwnn;	       /* WWNN if known */
 	u64		       wwpn;	       /* WWPN */
diff -druN linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_ext.h linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_ext.h
--- linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_ext.h	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_ext.h	2012-10-12 16:48:25.000000000 -0400
@@ -54,6 +54,7 @@
 extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *);
 extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *);
 extern void zfcp_dbf_hba_def_err(struct zfcp_adapter *, u64, u16, void **);
+extern void zfcp_dbf_hba_basic(char *, struct zfcp_adapter *);
 extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32);
 extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *);
 extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *);
@@ -158,6 +159,7 @@
 extern struct attribute_group zfcp_sysfs_unit_attrs;
 extern struct attribute_group zfcp_sysfs_adapter_attrs;
 extern struct attribute_group zfcp_sysfs_port_attrs;
+extern struct mutex zfcp_sysfs_port_units_mutex;
 extern struct device_attribute *zfcp_sysfs_sdev_attrs[];
 extern struct device_attribute *zfcp_sysfs_shost_attrs[];
 
diff -druN linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_fsf.c linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_fsf.c
--- linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_fsf.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_fsf.c	2012-10-12 16:48:25.000000000 -0400
@@ -219,7 +219,7 @@
 		return;
 	}
 
-	zfcp_dbf_hba_fsf_uss("fssrh_2", req);
+	zfcp_dbf_hba_fsf_uss("fssrh_4", req);
 
 	switch (sr_buf->status_type) {
 	case FSF_STATUS_READ_PORT_CLOSED:
@@ -437,6 +437,34 @@
 	}
 }
 
+#define ZFCP_FSF_PORTSPEED_1GBIT	(1 <<  0)
+#define ZFCP_FSF_PORTSPEED_2GBIT	(1 <<  1)
+#define ZFCP_FSF_PORTSPEED_4GBIT	(1 <<  2)
+#define ZFCP_FSF_PORTSPEED_10GBIT	(1 <<  3)
+#define ZFCP_FSF_PORTSPEED_8GBIT	(1 <<  4)
+#define ZFCP_FSF_PORTSPEED_16GBIT	(1 <<  5)
+#define ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED (1 << 15)
+
+static u32 zfcp_fsf_convert_portspeed(u32 fsf_speed)
+{
+	u32 fdmi_speed = 0;
+	if (fsf_speed & ZFCP_FSF_PORTSPEED_1GBIT)
+		fdmi_speed |= FC_PORTSPEED_1GBIT;
+	if (fsf_speed & ZFCP_FSF_PORTSPEED_2GBIT)
+		fdmi_speed |= FC_PORTSPEED_2GBIT;
+	if (fsf_speed & ZFCP_FSF_PORTSPEED_4GBIT)
+		fdmi_speed |= FC_PORTSPEED_4GBIT;
+	if (fsf_speed & ZFCP_FSF_PORTSPEED_10GBIT)
+		fdmi_speed |= FC_PORTSPEED_10GBIT;
+	if (fsf_speed & ZFCP_FSF_PORTSPEED_8GBIT)
+		fdmi_speed |= FC_PORTSPEED_8GBIT;
+	if (fsf_speed & ZFCP_FSF_PORTSPEED_16GBIT)
+		fdmi_speed |= FC_PORTSPEED_16GBIT;
+	if (fsf_speed & ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED)
+		fdmi_speed |= FC_PORTSPEED_NOT_NEGOTIATED;
+	return fdmi_speed;
+}
+
 static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
 {
 	struct fsf_qtcb_bottom_config *bottom = &req->qtcb->bottom.config;
@@ -456,7 +484,8 @@
 	fc_host_port_name(shost) = nsp->fl_wwpn;
 	fc_host_node_name(shost) = nsp->fl_wwnn;
 	fc_host_port_id(shost) = ntoh24(bottom->s_id);
-	fc_host_speed(shost) = bottom->fc_link_speed;
+	fc_host_speed(shost) =
+		zfcp_fsf_convert_portspeed(bottom->fc_link_speed);
 	fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
 
 	adapter->hydra_version = bottom->adapter_type;
@@ -580,7 +609,8 @@
 	} else
 		fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
 	fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
-	fc_host_supported_speeds(shost) = bottom->supported_speed;
+	fc_host_supported_speeds(shost) =
+		zfcp_fsf_convert_portspeed(bottom->supported_speed);
 	memcpy(fc_host_supported_fc4s(shost), bottom->supported_fc4_types,
 	       FC_FC4_LIST_SIZE);
 	memcpy(fc_host_active_fc4s(shost), bottom->active_fc4_types,
@@ -771,12 +801,14 @@
 static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
 {
 	struct scsi_device *sdev = req->data;
-	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
+	struct zfcp_scsi_dev *zfcp_sdev;
 	union fsf_status_qual *fsq = &req->qtcb->header.fsf_status_qual;
 
 	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
 		return;
 
+	zfcp_sdev = sdev_to_zfcp(sdev);
+
 	switch (req->qtcb->header.fsf_status) {
 	case FSF_PORT_HANDLE_NOT_VALID:
 		if (fsq->word[0] == fsq->word[1]) {
@@ -885,7 +917,7 @@
 
 	switch (header->fsf_status) {
         case FSF_GOOD:
-		zfcp_dbf_san_res("fsscth1", req);
+		zfcp_dbf_san_res("fsscth2", req);
 		ct->status = 0;
 		break;
         case FSF_SERVICE_CLASS_NOT_SUPPORTED:
@@ -1739,13 +1771,15 @@
 {
 	struct zfcp_adapter *adapter = req->adapter;
 	struct scsi_device *sdev = req->data;
-	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
+	struct zfcp_scsi_dev *zfcp_sdev;
 	struct fsf_qtcb_header *header = &req->qtcb->header;
 	struct fsf_qtcb_bottom_support *bottom = &req->qtcb->bottom.support;
 
 	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
 		return;
 
+	zfcp_sdev = sdev_to_zfcp(sdev);
+
 	atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
 			  ZFCP_STATUS_COMMON_ACCESS_BOXED |
 			  ZFCP_STATUS_LUN_SHARED |
@@ -1856,11 +1890,13 @@
 static void zfcp_fsf_close_lun_handler(struct zfcp_fsf_req *req)
 {
 	struct scsi_device *sdev = req->data;
-	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
+	struct zfcp_scsi_dev *zfcp_sdev;
 
 	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
 		return;
 
+	zfcp_sdev = sdev_to_zfcp(sdev);
+
 	switch (req->qtcb->header.fsf_status) {
 	case FSF_PORT_HANDLE_NOT_VALID:
 		zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fscuh_1");
@@ -1950,7 +1986,7 @@
 {
 	struct fsf_qual_latency_info *lat_in;
 	struct latency_cont *lat = NULL;
-	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scsi->device);
+	struct zfcp_scsi_dev *zfcp_sdev;
 	struct zfcp_blk_drv_data blktrc;
 	int ticks = req->adapter->timer_ticks;
 
@@ -1965,6 +2001,7 @@
 
 	if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA &&
 	    !(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
+		zfcp_sdev = sdev_to_zfcp(scsi->device);
 		blktrc.flags |= ZFCP_BLK_LAT_VALID;
 		blktrc.channel_lat = lat_in->channel_lat * ticks;
 		blktrc.fabric_lat = lat_in->fabric_lat * ticks;
@@ -2002,12 +2039,14 @@
 {
 	struct scsi_cmnd *scmnd = req->data;
 	struct scsi_device *sdev = scmnd->device;
-	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
+	struct zfcp_scsi_dev *zfcp_sdev;
 	struct fsf_qtcb_header *header = &req->qtcb->header;
 
 	if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR))
 		return;
 
+	zfcp_sdev = sdev_to_zfcp(sdev);
+
 	switch (header->fsf_status) {
 	case FSF_HANDLE_MISMATCH:
 	case FSF_PORT_HANDLE_NOT_VALID:
diff -druN linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_qdio.c linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_qdio.c
--- linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_qdio.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_qdio.c	2012-10-12 16:48:25.000000000 -0400
@@ -102,18 +102,22 @@
 {
 	struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm;
 	struct zfcp_adapter *adapter = qdio->adapter;
-	struct qdio_buffer_element *sbale;
 	int sbal_no, sbal_idx;
-	void *pl[ZFCP_QDIO_MAX_SBALS_PER_REQ + 1];
-	u64 req_id;
-	u8 scount;
 
 	if (unlikely(qdio_err)) {
-		memset(pl, 0, ZFCP_QDIO_MAX_SBALS_PER_REQ * sizeof(void *));
 		if (zfcp_adapter_multi_buffer_active(adapter)) {
+			void *pl[ZFCP_QDIO_MAX_SBALS_PER_REQ + 1];
+			struct qdio_buffer_element *sbale;
+			u64 req_id;
+			u8 scount;
+
+			memset(pl, 0,
+			       ZFCP_QDIO_MAX_SBALS_PER_REQ * sizeof(void *));
 			sbale = qdio->res_q[idx]->element;
 			req_id = (u64) sbale->addr;
-			scount = sbale->scount + 1; /* incl. signaling SBAL */
+			scount = min(sbale->scount + 1,
+				     ZFCP_QDIO_MAX_SBALS_PER_REQ + 1);
+				     /* incl. signaling SBAL */
 
 			for (sbal_no = 0; sbal_no < scount; sbal_no++) {
 				sbal_idx = (idx + sbal_no) %
diff -druN linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_sysfs.c linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_sysfs.c
--- linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_sysfs.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_sysfs.c	2012-10-12 16:48:25.000000000 -0400
@@ -227,6 +227,8 @@
 static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
 		     zfcp_sysfs_port_rescan_store);
 
+DEFINE_MUTEX(zfcp_sysfs_port_units_mutex);
+
 static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
 					    struct device_attribute *attr,
 					    const char *buf, size_t count)
@@ -249,6 +251,16 @@
 	else
 		retval = 0;
 
+	mutex_lock(&zfcp_sysfs_port_units_mutex);
+	if (atomic_read(&port->units) > 0) {
+		retval = -EBUSY;
+		mutex_unlock(&zfcp_sysfs_port_units_mutex);
+		goto out;
+	}
+	/* port is about to be removed, so no more unit_add */
+	atomic_set(&port->units, -1);
+	mutex_unlock(&zfcp_sysfs_port_units_mutex);
+
 	write_lock_irq(&adapter->port_list_lock);
 	list_del(&port->list);
 	write_unlock_irq(&adapter->port_list_lock);
@@ -289,12 +301,14 @@
 {
 	struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
 	u64 fcp_lun;
+	int retval;
 
 	if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun))
 		return -EINVAL;
 
-	if (zfcp_unit_add(port, fcp_lun))
-		return -EINVAL;
+	retval = zfcp_unit_add(port, fcp_lun);
+	if (retval)
+		return retval;
 
 	return count;
 }
diff -druN linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_unit.c linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_unit.c
--- linux-libre-3.5.6-gnu/drivers/s390/scsi/zfcp_unit.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/s390/scsi/zfcp_unit.c	2012-10-12 16:48:25.000000000 -0400
@@ -104,7 +104,7 @@
 {
 	struct zfcp_unit *unit = container_of(dev, struct zfcp_unit, dev);
 
-	put_device(&unit->port->dev);
+	atomic_dec(&unit->port->units);
 	kfree(unit);
 }
 
@@ -119,16 +119,27 @@
 int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun)
 {
 	struct zfcp_unit *unit;
+	int retval = 0;
+
+	mutex_lock(&zfcp_sysfs_port_units_mutex);
+	if (atomic_read(&port->units) == -1) {
+		/* port is already gone */
+		retval = -ENODEV;
+		goto out;
+	}
 
 	unit = zfcp_unit_find(port, fcp_lun);
 	if (unit) {
 		put_device(&unit->dev);
-		return -EEXIST;
+		retval = -EEXIST;
+		goto out;
 	}
 
 	unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
-	if (!unit)
-		return -ENOMEM;
+	if (!unit) {
+		retval = -ENOMEM;
+		goto out;
+	}
 
 	unit->port = port;
 	unit->fcp_lun = fcp_lun;
@@ -139,28 +150,33 @@
 	if (dev_set_name(&unit->dev, "0x%016llx",
 			 (unsigned long long) fcp_lun)) {
 		kfree(unit);
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto out;
 	}
 
-	get_device(&port->dev);
-
 	if (device_register(&unit->dev)) {
 		put_device(&unit->dev);
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto out;
 	}
 
 	if (sysfs_create_group(&unit->dev.kobj, &zfcp_sysfs_unit_attrs)) {
 		device_unregister(&unit->dev);
-		return -EINVAL;
+		retval = -EINVAL;
+		goto out;
 	}
 
+	atomic_inc(&port->units); /* under zfcp_sysfs_port_units_mutex ! */
+
 	write_lock_irq(&port->unit_list_lock);
 	list_add_tail(&unit->list, &port->unit_list);
 	write_unlock_irq(&port->unit_list_lock);
 
 	zfcp_unit_scsi_scan(unit);
 
-	return 0;
+out:
+	mutex_unlock(&zfcp_sysfs_port_units_mutex);
+	return retval;
 }
 
 /**
diff -druN linux-libre-3.5.6-gnu/drivers/scsi/atp870u.c linux-libre-3.5.7-gnu/drivers/scsi/atp870u.c
--- linux-libre-3.5.6-gnu/drivers/scsi/atp870u.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/drivers/scsi/atp870u.c	2012-10-12 16:48:25.000000000 -0400
@@ -1173,7 +1173,16 @@
 	outw(val, tmport);
 	outb(2, 0x80);
 TCM_SYNC:
-	udelay(0x800);
+	/*
+	 * The funny division into multiple delays is to accomodate
+	 * arches like ARM where udelay() multiplies its argument by
+	 * a large number to initialize a loop counter.  To avoid
+	 * overflow, the maximum supported udelay is 2000 microseconds.
+	 *
+	 * XXX it would be more polite to find a way to use msleep()
+	 */
+	mdelay(2);
+	udelay(48);
 	if ((inb(tmport) & 0x80) == 0x00) {	/* bsy ? */
 		outw(0, tmport--);
 		outb(0, tmport);
diff -druN linux-libre-3.5.6-gnu/fs/cifs/cifs_unicode.c linux-libre-3.5.7-gnu/fs/cifs/cifs_unicode.c
--- linux-libre-3.5.6-gnu/fs/cifs/cifs_unicode.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/fs/cifs/cifs_unicode.c	2012-10-12 16:48:25.000000000 -0400
@@ -203,6 +203,27 @@
 	int i;
 	wchar_t wchar_to; /* needed to quiet sparse */
 
+	/* special case for utf8 to handle no plane0 chars */
+	if (!strcmp(codepage->charset, "utf8")) {
+		/*
+		 * convert utf8 -> utf16, we assume we have enough space
+		 * as caller should have assumed conversion does not overflow
+		 * in destination len is length in wchar_t units (16bits)
+		 */
+		i  = utf8s_to_utf16s(from, len, UTF16_LITTLE_ENDIAN,
+				       (wchar_t *) to, len);
+
+		/* if success terminate and exit */
+		if (i >= 0)
+			goto success;
+		/*
+		 * if fails fall back to UCS encoding as this
+		 * function should not return negative values
+		 * currently can fail only if source contains
+		 * invalid encoded characters
+		 */
+	}
+
 	for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
 		charlen = codepage->char2uni(from, len, &wchar_to);
 		if (charlen < 1) {
@@ -215,6 +236,7 @@
 		put_unaligned_le16(wchar_to, &to[i]);
 	}
 
+success:
 	put_unaligned_le16(0, &to[i]);
 	return i;
 }
diff -druN linux-libre-3.5.6-gnu/fs/cifs/connect.c linux-libre-3.5.7-gnu/fs/cifs/connect.c
--- linux-libre-3.5.6-gnu/fs/cifs/connect.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/fs/cifs/connect.c	2012-10-12 16:48:25.000000000 -0400
@@ -70,6 +70,7 @@
 	/* Mount options that take no arguments */
 	Opt_user_xattr, Opt_nouser_xattr,
 	Opt_forceuid, Opt_noforceuid,
+	Opt_forcegid, Opt_noforcegid,
 	Opt_noblocksend, Opt_noautotune,
 	Opt_hard, Opt_soft, Opt_perm, Opt_noperm,
 	Opt_mapchars, Opt_nomapchars, Opt_sfu,
@@ -121,6 +122,8 @@
 	{ Opt_nouser_xattr, "nouser_xattr" },
 	{ Opt_forceuid, "forceuid" },
 	{ Opt_noforceuid, "noforceuid" },
+	{ Opt_forcegid, "forcegid" },
+	{ Opt_noforcegid, "noforcegid" },
 	{ Opt_noblocksend, "noblocksend" },
 	{ Opt_noautotune, "noautotune" },
 	{ Opt_hard, "hard" },
@@ -1345,6 +1348,12 @@
 		case Opt_noforceuid:
 			override_uid = 0;
 			break;
+		case Opt_forcegid:
+			override_gid = 1;
+			break;
+		case Opt_noforcegid:
+			override_gid = 0;
+			break;
 		case Opt_noblocksend:
 			vol->noblocksnd = 1;
 			break;
diff -druN linux-libre-3.5.6-gnu/fs/ext4/inode.c linux-libre-3.5.7-gnu/fs/ext4/inode.c
--- linux-libre-3.5.6-gnu/fs/ext4/inode.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/fs/ext4/inode.c	2012-10-12 16:48:25.000000000 -0400
@@ -2453,6 +2453,16 @@
 	free_blocks  = EXT4_C2B(sbi,
 		percpu_counter_read_positive(&sbi->s_freeclusters_counter));
 	dirty_blocks = percpu_counter_read_positive(&sbi->s_dirtyclusters_counter);
+	/*
+	 * Start pushing delalloc when 1/2 of free blocks are dirty.
+	 */
+	if (dirty_blocks && (free_blocks < 2 * dirty_blocks) &&
+	    !writeback_in_progress(sb->s_bdi) &&
+	    down_read_trylock(&sb->s_umount)) {
+		writeback_inodes_sb(sb, WB_REASON_FS_FREE_SPACE);
+		up_read(&sb->s_umount);
+	}
+
 	if (2 * free_blocks < 3 * dirty_blocks ||
 		free_blocks < (dirty_blocks + EXT4_FREECLUSTERS_WATERMARK)) {
 		/*
@@ -2461,13 +2471,6 @@
 		 */
 		return 1;
 	}
-	/*
-	 * Even if we don't switch but are nearing capacity,
-	 * start pushing delalloc when 1/2 of free blocks are dirty.
-	 */
-	if (free_blocks < 2 * dirty_blocks)
-		writeback_inodes_sb_if_idle(sb, WB_REASON_FS_FREE_SPACE);
-
 	return 0;
 }
 
@@ -3985,6 +3988,7 @@
 	struct ext4_inode_info *ei = EXT4_I(inode);
 	struct buffer_head *bh = iloc->bh;
 	int err = 0, rc, block;
+	int need_datasync = 0;
 	uid_t i_uid;
 	gid_t i_gid;
 
@@ -4035,7 +4039,10 @@
 		raw_inode->i_file_acl_high =
 			cpu_to_le16(ei->i_file_acl >> 32);
 	raw_inode->i_file_acl_lo = cpu_to_le32(ei->i_file_acl);
-	ext4_isize_set(raw_inode, ei->i_disksize);
+	if (ei->i_disksize != ext4_isize(raw_inode)) {
+		ext4_isize_set(raw_inode, ei->i_disksize);
+		need_datasync = 1;
+	}
 	if (ei->i_disksize > 0x7fffffffULL) {
 		struct super_block *sb = inode->i_sb;
 		if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
@@ -4088,7 +4095,7 @@
 		err = rc;
 	ext4_clear_inode_state(inode, EXT4_STATE_NEW);
 
-	ext4_update_inode_fsync_trans(handle, inode, 0);
+	ext4_update_inode_fsync_trans(handle, inode, need_datasync);
 out_brelse:
 	brelse(bh);
 	ext4_std_error(inode->i_sb, err);
diff -druN linux-libre-3.5.6-gnu/fs/ext4/move_extent.c linux-libre-3.5.7-gnu/fs/ext4/move_extent.c
--- linux-libre-3.5.6-gnu/fs/ext4/move_extent.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/fs/ext4/move_extent.c	2012-10-12 16:48:25.000000000 -0400
@@ -141,55 +141,21 @@
 }
 
 /**
- * mext_check_null_inode - NULL check for two inodes
- *
- * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
- */
-static int
-mext_check_null_inode(struct inode *inode1, struct inode *inode2,
-		      const char *function, unsigned int line)
-{
-	int ret = 0;
-
-	if (inode1 == NULL) {
-		__ext4_error(inode2->i_sb, function, line,
-			"Both inodes should not be NULL: "
-			"inode1 NULL inode2 %lu", inode2->i_ino);
-		ret = -EIO;
-	} else if (inode2 == NULL) {
-		__ext4_error(inode1->i_sb, function, line,
-			"Both inodes should not be NULL: "
-			"inode1 %lu inode2 NULL", inode1->i_ino);
-		ret = -EIO;
-	}
-	return ret;
-}
-
-/**
  * double_down_write_data_sem - Acquire two inodes' write lock of i_data_sem
  *
- * @orig_inode:		original inode structure
- * @donor_inode:	donor inode structure
- * Acquire write lock of i_data_sem of the two inodes (orig and donor) by
- * i_ino order.
+ * Acquire write lock of i_data_sem of the two inodes
  */
 static void
-double_down_write_data_sem(struct inode *orig_inode, struct inode *donor_inode)
+double_down_write_data_sem(struct inode *first, struct inode *second)
 {
-	struct inode *first = orig_inode, *second = donor_inode;
+	if (first < second) {
+		down_write(&EXT4_I(first)->i_data_sem);
+		down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
+	} else {
+		down_write(&EXT4_I(second)->i_data_sem);
+		down_write_nested(&EXT4_I(first)->i_data_sem, SINGLE_DEPTH_NESTING);
 
-	/*
-	 * Use the inode number to provide the stable locking order instead
-	 * of its address, because the C language doesn't guarantee you can
-	 * compare pointers that don't come from the same array.
-	 */
-	if (donor_inode->i_ino < orig_inode->i_ino) {
-		first = donor_inode;
-		second = orig_inode;
 	}
-
-	down_write(&EXT4_I(first)->i_data_sem);
-	down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
 }
 
 /**
@@ -969,14 +935,6 @@
 		return -EINVAL;
 	}
 
-	/* Files should be in the same ext4 FS */
-	if (orig_inode->i_sb != donor_inode->i_sb) {
-		ext4_debug("ext4 move extent: The argument files "
-			"should be in same FS [ino:orig %lu, donor %lu]\n",
-			orig_inode->i_ino, donor_inode->i_ino);
-		return -EINVAL;
-	}
-
 	/* Ext4 move extent supports only extent based file */
 	if (!(ext4_test_inode_flag(orig_inode, EXT4_INODE_EXTENTS))) {
 		ext4_debug("ext4 move extent: orig file is not extents "
@@ -1072,35 +1030,19 @@
  * @inode1:	the inode structure
  * @inode2:	the inode structure
  *
- * Lock two inodes' i_mutex by i_ino order.
- * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
+ * Lock two inodes' i_mutex
  */
-static int
+static void
 mext_inode_double_lock(struct inode *inode1, struct inode *inode2)
 {
-	int ret = 0;
-
-	BUG_ON(inode1 == NULL && inode2 == NULL);
-
-	ret = mext_check_null_inode(inode1, inode2, __func__, __LINE__);
-	if (ret < 0)
-		goto out;
-
-	if (inode1 == inode2) {
-		mutex_lock(&inode1->i_mutex);
-		goto out;
-	}
-
-	if (inode1->i_ino < inode2->i_ino) {
+	BUG_ON(inode1 == inode2);
+	if (inode1 < inode2) {
 		mutex_lock_nested(&inode1->i_mutex, I_MUTEX_PARENT);
 		mutex_lock_nested(&inode2->i_mutex, I_MUTEX_CHILD);
 	} else {
 		mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT);
 		mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD);
 	}
-
-out:
-	return ret;
 }
 
 /**
@@ -1109,28 +1051,13 @@
  * @inode1:     the inode that is released first
  * @inode2:     the inode that is released second
  *
- * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
  */
 
-static int
+static void
 mext_inode_double_unlock(struct inode *inode1, struct inode *inode2)
 {
-	int ret = 0;
-
-	BUG_ON(inode1 == NULL && inode2 == NULL);
-
-	ret = mext_check_null_inode(inode1, inode2, __func__, __LINE__);
-	if (ret < 0)
-		goto out;
-
-	if (inode1)
-		mutex_unlock(&inode1->i_mutex);
-
-	if (inode2 && inode2 != inode1)
-		mutex_unlock(&inode2->i_mutex);
-
-out:
-	return ret;
+	mutex_unlock(&inode1->i_mutex);
+	mutex_unlock(&inode2->i_mutex);
 }
 
 /**
@@ -1187,16 +1114,23 @@
 	ext4_lblk_t block_end, seq_start, add_blocks, file_end, seq_blocks = 0;
 	ext4_lblk_t rest_blocks;
 	pgoff_t orig_page_offset = 0, seq_end_page;
-	int ret1, ret2, depth, last_extent = 0;
+	int ret, depth, last_extent = 0;
 	int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
 	int data_offset_in_page;
 	int block_len_in_page;
 	int uninit;
 
-	/* orig and donor should be different file */
-	if (orig_inode->i_ino == donor_inode->i_ino) {
+	if (orig_inode->i_sb != donor_inode->i_sb) {
+		ext4_debug("ext4 move extent: The argument files "
+			"should be in same FS [ino:orig %lu, donor %lu]\n",
+			orig_inode->i_ino, donor_inode->i_ino);
+		return -EINVAL;
+	}
+
+	/* orig and donor should be different inodes */
+	if (orig_inode == donor_inode) {
 		ext4_debug("ext4 move extent: The argument files should not "
-			"be same file [ino:orig %lu, donor %lu]\n",
+			"be same inode [ino:orig %lu, donor %lu]\n",
 			orig_inode->i_ino, donor_inode->i_ino);
 		return -EINVAL;
 	}
@@ -1208,18 +1142,21 @@
 			orig_inode->i_ino, donor_inode->i_ino);
 		return -EINVAL;
 	}
-
+	/* TODO: This is non obvious task to swap blocks for inodes with full
+	   jornaling enabled */
+	if (ext4_should_journal_data(orig_inode) ||
+	    ext4_should_journal_data(donor_inode)) {
+		return -EINVAL;
+	}
 	/* Protect orig and donor inodes against a truncate */
-	ret1 = mext_inode_double_lock(orig_inode, donor_inode);
-	if (ret1 < 0)
-		return ret1;
+	mext_inode_double_lock(orig_inode, donor_inode);
 
 	/* Protect extent tree against block allocations via delalloc */
 	double_down_write_data_sem(orig_inode, donor_inode);
 	/* Check the filesystem environment whether move_extent can be done */
-	ret1 = mext_check_arguments(orig_inode, donor_inode, orig_start,
+	ret = mext_check_arguments(orig_inode, donor_inode, orig_start,
 				    donor_start, &len);
-	if (ret1)
+	if (ret)
 		goto out;
 
 	file_end = (i_size_read(orig_inode) - 1) >> orig_inode->i_blkbits;
@@ -1227,13 +1164,13 @@
 	if (file_end < block_end)
 		len -= block_end - file_end;
 
-	ret1 = get_ext_path(orig_inode, block_start, &orig_path);
-	if (ret1)
+	ret = get_ext_path(orig_inode, block_start, &orig_path);
+	if (ret)
 		goto out;
 
 	/* Get path structure to check the hole */
-	ret1 = get_ext_path(orig_inode, block_start, &holecheck_path);
-	if (ret1)
+	ret = get_ext_path(orig_inode, block_start, &holecheck_path);
+	if (ret)
 		goto out;
 
 	depth = ext_depth(orig_inode);
@@ -1252,13 +1189,13 @@
 		last_extent = mext_next_extent(orig_inode,
 					holecheck_path, &ext_cur);
 		if (last_extent < 0) {
-			ret1 = last_extent;
+			ret = last_extent;
 			goto out;
 		}
 		last_extent = mext_next_extent(orig_inode, orig_path,
 							&ext_dummy);
 		if (last_extent < 0) {
-			ret1 = last_extent;
+			ret = last_extent;
 			goto out;
 		}
 		seq_start = le32_to_cpu(ext_cur->ee_block);
@@ -1272,7 +1209,7 @@
 	if (le32_to_cpu(ext_cur->ee_block) > block_end) {
 		ext4_debug("ext4 move extent: The specified range of file "
 							"may be the hole\n");
-		ret1 = -EINVAL;
+		ret = -EINVAL;
 		goto out;
 	}
 
@@ -1292,7 +1229,7 @@
 		last_extent = mext_next_extent(orig_inode, holecheck_path,
 						&ext_cur);
 		if (last_extent < 0) {
-			ret1 = last_extent;
+			ret = last_extent;
 			break;
 		}
 		add_blocks = ext4_ext_get_actual_len(ext_cur);
@@ -1349,18 +1286,18 @@
 						orig_page_offset,
 						data_offset_in_page,
 						block_len_in_page, uninit,
-						&ret1);
+						&ret);
 
 			/* Count how many blocks we have exchanged */
 			*moved_len += block_len_in_page;
-			if (ret1 < 0)
+			if (ret < 0)
 				break;
 			if (*moved_len > len) {
 				EXT4_ERROR_INODE(orig_inode,
 					"We replaced blocks too much! "
 					"sum of replaced: %llu requested: %llu",
 					*moved_len, len);
-				ret1 = -EIO;
+				ret = -EIO;
 				break;
 			}
 
@@ -1374,22 +1311,22 @@
 		}
 
 		double_down_write_data_sem(orig_inode, donor_inode);
-		if (ret1 < 0)
+		if (ret < 0)
 			break;
 
 		/* Decrease buffer counter */
 		if (holecheck_path)
 			ext4_ext_drop_refs(holecheck_path);
-		ret1 = get_ext_path(orig_inode, seq_start, &holecheck_path);
-		if (ret1)
+		ret = get_ext_path(orig_inode, seq_start, &holecheck_path);
+		if (ret)
 			break;
 		depth = holecheck_path->p_depth;
 
 		/* Decrease buffer counter */
 		if (orig_path)
 			ext4_ext_drop_refs(orig_path);
-		ret1 = get_ext_path(orig_inode, seq_start, &orig_path);
-		if (ret1)
+		ret = get_ext_path(orig_inode, seq_start, &orig_path);
+		if (ret)
 			break;
 
 		ext_cur = holecheck_path[depth].p_ext;
@@ -1412,12 +1349,7 @@
 		kfree(holecheck_path);
 	}
 	double_up_write_data_sem(orig_inode, donor_inode);
-	ret2 = mext_inode_double_unlock(orig_inode, donor_inode);
-
-	if (ret1)
-		return ret1;
-	else if (ret2)
-		return ret2;
+	mext_inode_double_unlock(orig_inode, donor_inode);
 
-	return 0;
+	return ret;
 }
diff -druN linux-libre-3.5.6-gnu/fs/ext4/namei.c linux-libre-3.5.7-gnu/fs/ext4/namei.c
--- linux-libre-3.5.6-gnu/fs/ext4/namei.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/fs/ext4/namei.c	2012-10-12 16:48:25.000000000 -0400
@@ -2149,9 +2149,7 @@
 	err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
 		init_special_inode(inode, inode->i_mode, rdev);
-#ifdef CONFIG_EXT4_FS_XATTR
 		inode->i_op = &ext4_special_inode_operations;
-#endif
 		err = ext4_add_nondir(handle, dentry, inode);
 	}
 	ext4_journal_stop(handle);
diff -druN linux-libre-3.5.6-gnu/fs/ext4/resize.c linux-libre-3.5.7-gnu/fs/ext4/resize.c
--- linux-libre-3.5.6-gnu/fs/ext4/resize.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/fs/ext4/resize.c	2012-10-12 16:48:25.000000000 -0400
@@ -200,8 +200,11 @@
  * be a partial of a flex group.
  *
  * @sb: super block of fs to which the groups belongs
+ *
+ * Returns 0 on a successful allocation of the metadata blocks in the
+ * block group.
  */
-static void ext4_alloc_group_tables(struct super_block *sb,
+static int ext4_alloc_group_tables(struct super_block *sb,
 				struct ext4_new_flex_group_data *flex_gd,
 				int flexbg_size)
 {
@@ -226,6 +229,8 @@
 	       (last_group & ~(flexbg_size - 1))));
 next_group:
 	group = group_data[0].group;
+	if (src_group >= group_data[0].group + flex_gd->count)
+		return -ENOSPC;
 	start_blk = ext4_group_first_block_no(sb, src_group);
 	last_blk = start_blk + group_data[src_group - group].blocks_count;
 
@@ -235,7 +240,6 @@
 
 	start_blk += overhead;
 
-	BUG_ON(src_group >= group_data[0].group + flex_gd->count);
 	/* We collect contiguous blocks as much as possible. */
 	src_group++;
 	for (; src_group <= last_group; src_group++)
@@ -300,6 +304,7 @@
 			       group_data[i].free_blocks_count);
 		}
 	}
+	return 0;
 }
 
 static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
@@ -451,6 +456,9 @@
 		gdblocks = ext4_bg_num_gdb(sb, group);
 		start = ext4_group_first_block_no(sb, group);
 
+		if (!ext4_bg_has_super(sb, group))
+			goto handle_itb;
+
 		/* Copy all of the GDT blocks into the backup in this group */
 		for (j = 0, block = start + 1; j < gdblocks; j++, block++) {
 			struct buffer_head *gdb;
@@ -493,6 +501,7 @@
 				goto out;
 		}
 
+handle_itb:
 		/* Initialize group tables of the grop @group */
 		if (!(bg_flags[i] & EXT4_BG_INODE_ZEROED))
 			goto handle_bb;
@@ -1349,13 +1358,15 @@
 		err = err2;
 
 	if (!err) {
-		int i;
+		int gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
+		int gdb_num_end = ((group + flex_gd->count - 1) /
+				   EXT4_DESC_PER_BLOCK(sb));
+
 		update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
 			       sizeof(struct ext4_super_block));
-		for (i = 0; i < flex_gd->count; i++, group++) {
+		for (; gdb_num <= gdb_num_end; gdb_num++) {
 			struct buffer_head *gdb_bh;
-			int gdb_num;
-			gdb_num = group / EXT4_BLOCKS_PER_GROUP(sb);
+
 			gdb_bh = sbi->s_group_desc[gdb_num];
 			update_backups(sb, gdb_bh->b_blocknr, gdb_bh->b_data,
 				       gdb_bh->b_size);
@@ -1729,7 +1740,8 @@
 	 */
 	while (ext4_setup_next_flex_gd(sb, flex_gd, n_blocks_count,
 					      flexbg_size)) {
-		ext4_alloc_group_tables(sb, flex_gd, flexbg_size);
+		if (ext4_alloc_group_tables(sb, flex_gd, flexbg_size) != 0)
+			break;
 		err = ext4_flex_group_add(sb, resize_inode, flex_gd);
 		if (unlikely(err))
 			break;
diff -druN linux-libre-3.5.6-gnu/fs/ext4/super.c linux-libre-3.5.7-gnu/fs/ext4/super.c
--- linux-libre-3.5.6-gnu/fs/ext4/super.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/fs/ext4/super.c	2012-10-12 16:48:25.000000000 -0400
@@ -1748,7 +1748,7 @@
 
 static const char *token2str(int token)
 {
-	static const struct match_token *t;
+	const struct match_token *t;
 
 	for (t = tokens; t->token != Opt_err; t++)
 		if (t->token == token && !strchr(t->pattern, '='))
diff -druN linux-libre-3.5.6-gnu/fs/fs-writeback.c linux-libre-3.5.7-gnu/fs/fs-writeback.c
--- linux-libre-3.5.6-gnu/fs/fs-writeback.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/fs/fs-writeback.c	2012-10-12 16:48:25.000000000 -0400
@@ -68,6 +68,7 @@
 {
 	return test_bit(BDI_writeback_running, &bdi->state);
 }
+EXPORT_SYMBOL(writeback_in_progress);
 
 static inline struct backing_dev_info *inode_to_bdi(struct inode *inode)
 {
diff -druN linux-libre-3.5.6-gnu/fs/jbd2/journal.c linux-libre-3.5.7-gnu/fs/jbd2/journal.c
--- linux-libre-3.5.6-gnu/fs/jbd2/journal.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/fs/jbd2/journal.c	2012-10-12 16:48:25.000000000 -0400
@@ -1354,6 +1354,11 @@
 
 	BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex));
 	read_lock(&journal->j_state_lock);
+	/* Is it already empty? */
+	if (sb->s_start == 0) {
+		read_unlock(&journal->j_state_lock);
+		return;
+	}
 	jbd_debug(1, "JBD2: Marking journal as empty (seq %d)\n",
 		  journal->j_tail_sequence);
 
diff -druN linux-libre-3.5.6-gnu/fs/jffs2/super.c linux-libre-3.5.7-gnu/fs/jffs2/super.c
--- linux-libre-3.5.6-gnu/fs/jffs2/super.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/fs/jffs2/super.c	2012-10-12 16:48:25.000000000 -0400
@@ -100,6 +100,10 @@
 {
 	struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
 
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
+	cancel_delayed_work_sync(&c->wbuf_dwork);
+#endif
+
 	mutex_lock(&c->alloc_sem);
 	jffs2_flush_wbuf_pad(c);
 	mutex_unlock(&c->alloc_sem);
diff -druN linux-libre-3.5.6-gnu/fs/jffs2/wbuf.c linux-libre-3.5.7-gnu/fs/jffs2/wbuf.c
--- linux-libre-3.5.6-gnu/fs/jffs2/wbuf.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/fs/jffs2/wbuf.c	2012-10-12 16:48:25.000000000 -0400
@@ -1044,10 +1044,10 @@
 	ops.datbuf = NULL;
 
 	ret = mtd_read_oob(c->mtd, jeb->offset, &ops);
-	if (ret || ops.oobretlen != ops.ooblen) {
+	if ((ret && !mtd_is_bitflip(ret)) || ops.oobretlen != ops.ooblen) {
 		pr_err("cannot read OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n",
 		       jeb->offset, ops.ooblen, ops.oobretlen, ret);
-		if (!ret)
+		if (!ret || mtd_is_bitflip(ret))
 			ret = -EIO;
 		return ret;
 	}
@@ -1086,10 +1086,10 @@
 	ops.datbuf = NULL;
 
 	ret = mtd_read_oob(c->mtd, jeb->offset, &ops);
-	if (ret || ops.oobretlen != ops.ooblen) {
+	if ((ret && !mtd_is_bitflip(ret)) || ops.oobretlen != ops.ooblen) {
 		pr_err("cannot read OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n",
 		       jeb->offset, ops.ooblen, ops.oobretlen, ret);
-		if (!ret)
+		if (!ret || mtd_is_bitflip(ret))
 			ret = -EIO;
 		return ret;
 	}
diff -druN linux-libre-3.5.6-gnu/fs/proc/page.c linux-libre-3.5.7-gnu/fs/proc/page.c
--- linux-libre-3.5.6-gnu/fs/proc/page.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/fs/proc/page.c	2012-10-12 16:48:25.000000000 -0400
@@ -115,7 +115,13 @@
 		u |= 1 << KPF_COMPOUND_TAIL;
 	if (PageHuge(page))
 		u |= 1 << KPF_HUGE;
-	else if (PageTransCompound(page))
+	/*
+	 * PageTransCompound can be true for non-huge compound pages (slab
+	 * pages or pages allocated by drivers with __GFP_COMP) because it
+	 * just checks PG_head/PG_tail, so we need to check PageLRU to make
+	 * sure a given page is a thp, not a non-huge compound page.
+	 */
+	else if (PageTransCompound(page) && PageLRU(compound_trans_head(page)))
 		u |= 1 << KPF_THP;
 
 	/*
diff -druN linux-libre-3.5.6-gnu/include/linux/mempolicy.h linux-libre-3.5.7-gnu/include/linux/mempolicy.h
--- linux-libre-3.5.6-gnu/include/linux/mempolicy.h	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/include/linux/mempolicy.h	2012-10-12 16:48:25.000000000 -0400
@@ -188,7 +188,7 @@
 
 struct shared_policy {
 	struct rb_root root;
-	spinlock_t lock;
+	struct mutex mutex;
 };
 
 void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol);
diff -druN linux-libre-3.5.6-gnu/include/linux/xfrm.h linux-libre-3.5.7-gnu/include/linux/xfrm.h
--- linux-libre-3.5.6-gnu/include/linux/xfrm.h	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/include/linux/xfrm.h	2012-10-12 16:48:25.000000000 -0400
@@ -84,6 +84,8 @@
 	__u32	bitmap;
 };
 
+#define XFRMA_REPLAY_ESN_MAX	4096
+
 struct xfrm_replay_state_esn {
 	unsigned int	bmp_len;
 	__u32		oseq;
diff -druN linux-libre-3.5.6-gnu/include/net/xfrm.h linux-libre-3.5.7-gnu/include/net/xfrm.h
--- linux-libre-3.5.6-gnu/include/net/xfrm.h	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/include/net/xfrm.h	2012-10-12 16:48:25.000000000 -0400
@@ -269,6 +269,9 @@
 	int	(*check)(struct xfrm_state *x,
 			 struct sk_buff *skb,
 			 __be32 net_seq);
+	int	(*recheck)(struct xfrm_state *x,
+			   struct sk_buff *skb,
+			   __be32 net_seq);
 	void	(*notify)(struct xfrm_state *x, int event);
 	int	(*overflow)(struct xfrm_state *x, struct sk_buff *skb);
 };
diff -druN linux-libre-3.5.6-gnu/kernel/cpuset.c linux-libre-3.5.7-gnu/kernel/cpuset.c
--- linux-libre-3.5.6-gnu/kernel/cpuset.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/kernel/cpuset.c	2012-10-12 16:48:25.000000000 -0400
@@ -2054,6 +2054,9 @@
  * (of no affect) on systems that are actively using CPU hotplug
  * but making no active use of cpusets.
  *
+ * The only exception to this is suspend/resume, where we don't
+ * modify cpusets at all.
+ *
  * This routine ensures that top_cpuset.cpus_allowed tracks
  * cpu_active_mask on each CPU hotplug (cpuhp) event.
  *
diff -druN linux-libre-3.5.6-gnu/kernel/rcutree.c linux-libre-3.5.7-gnu/kernel/rcutree.c
--- linux-libre-3.5.6-gnu/kernel/rcutree.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/kernel/rcutree.c	2012-10-12 16:48:25.000000000 -0400
@@ -304,7 +304,9 @@
 static int
 cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp)
 {
-	return *rdp->nxttail[RCU_DONE_TAIL] && !rcu_gp_in_progress(rsp);
+	return *rdp->nxttail[RCU_DONE_TAIL +
+			     ACCESS_ONCE(rsp->completed) != rdp->completed] &&
+	       !rcu_gp_in_progress(rsp);
 }
 
 /*
diff -druN linux-libre-3.5.6-gnu/kernel/sched/core.c linux-libre-3.5.7-gnu/kernel/sched/core.c
--- linux-libre-3.5.6-gnu/kernel/sched/core.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/kernel/sched/core.c	2012-10-12 16:48:25.000000000 -0400
@@ -7103,34 +7103,66 @@
 	mutex_unlock(&sched_domains_mutex);
 }
 
+static int num_cpus_frozen;	/* used to mark begin/end of suspend/resume */
+
 /*
  * Update cpusets according to cpu_active mask.  If cpusets are
  * disabled, cpuset_update_active_cpus() becomes a simple wrapper
  * around partition_sched_domains().
+ *
+ * If we come here as part of a suspend/resume, don't touch cpusets because we
+ * want to restore it back to its original state upon resume anyway.
  */
 static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,
 			     void *hcpu)
 {
-	switch (action & ~CPU_TASKS_FROZEN) {
+	switch (action) {
+	case CPU_ONLINE_FROZEN:
+	case CPU_DOWN_FAILED_FROZEN:
+
+		/*
+		 * num_cpus_frozen tracks how many CPUs are involved in suspend
+		 * resume sequence. As long as this is not the last online
+		 * operation in the resume sequence, just build a single sched
+		 * domain, ignoring cpusets.
+		 */
+		num_cpus_frozen--;
+		if (likely(num_cpus_frozen)) {
+			partition_sched_domains(1, NULL, NULL);
+			break;
+		}
+
+		/*
+		 * This is the last CPU online operation. So fall through and
+		 * restore the original sched domains by considering the
+		 * cpuset configurations.
+		 */
+
 	case CPU_ONLINE:
 	case CPU_DOWN_FAILED:
 		cpuset_update_active_cpus();
-		return NOTIFY_OK;
+		break;
 	default:
 		return NOTIFY_DONE;
 	}
+	return NOTIFY_OK;
 }
 
 static int cpuset_cpu_inactive(struct notifier_block *nfb, unsigned long action,
 			       void *hcpu)
 {
-	switch (action & ~CPU_TASKS_FROZEN) {
+	switch (action) {
 	case CPU_DOWN_PREPARE:
 		cpuset_update_active_cpus();
-		return NOTIFY_OK;
+		break;
+	case CPU_DOWN_PREPARE_FROZEN:
+		num_cpus_frozen++;
+		partition_sched_domains(1, NULL, NULL);
+		break;
 	default:
 		return NOTIFY_DONE;
 	}
+	return NOTIFY_OK;
 }
 
 void __init sched_init_smp(void)
diff -druN linux-libre-3.5.6-gnu/kernel/sys.c linux-libre-3.5.7-gnu/kernel/sys.c
--- linux-libre-3.5.6-gnu/kernel/sys.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/kernel/sys.c	2012-10-12 16:48:25.000000000 -0400
@@ -368,6 +368,7 @@
 void kernel_restart(char *cmd)
 {
 	kernel_restart_prepare(cmd);
+	disable_nonboot_cpus();
 	if (!cmd)
 		printk(KERN_EMERG "Restarting system.\n");
 	else
diff -druN linux-libre-3.5.6-gnu/kernel/workqueue.c linux-libre-3.5.7-gnu/kernel/workqueue.c
--- linux-libre-3.5.6-gnu/kernel/workqueue.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/kernel/workqueue.c	2012-10-12 16:48:25.000000000 -0400
@@ -1869,7 +1869,9 @@
 
 	spin_unlock_irq(&gcwq->lock);
 
+	smp_wmb();	/* paired with test_and_set_bit(PENDING) */
 	work_clear_pending(work);
+
 	lock_map_acquire_read(&cwq->wq->lockdep_map);
 	lock_map_acquire(&lockdep_map);
 	trace_workqueue_execute_start(work);
diff -druN linux-libre-3.5.6-gnu/lib/gcd.c linux-libre-3.5.7-gnu/lib/gcd.c
--- linux-libre-3.5.6-gnu/lib/gcd.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/lib/gcd.c	2012-10-12 16:48:25.000000000 -0400
@@ -9,6 +9,9 @@
 
 	if (a < b)
 		swap(a, b);
+
+	if (!b)
+		return a;
 	while ((r = a % b) != 0) {
 		a = b;
 		b = r;
diff -druN linux-libre-3.5.6-gnu/Makefile linux-libre-3.5.7-gnu/Makefile
--- linux-libre-3.5.6-gnu/Makefile	2012-10-07 22:15:12.000000000 -0400
+++ linux-libre-3.5.7-gnu/Makefile	2012-10-13 14:05:32.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 5
-SUBLEVEL = 6
+SUBLEVEL = 7
 EXTRAVERSION =-gnu
 NAME = Saber-toothed Squirrel
 
diff -druN linux-libre-3.5.6-gnu/mm/hugetlb.c linux-libre-3.5.7-gnu/mm/hugetlb.c
--- linux-libre-3.5.6-gnu/mm/hugetlb.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/mm/hugetlb.c	2012-10-12 16:48:25.000000000 -0400
@@ -2432,7 +2432,8 @@
 	 * from page cache lookup which is in HPAGE_SIZE units.
 	 */
 	address = address & huge_page_mask(h);
-	pgoff = vma_hugecache_offset(h, vma, address);
+	pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) +
+			vma->vm_pgoff;
 	mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
 
 	/*
diff -druN linux-libre-3.5.6-gnu/mm/mempolicy.c linux-libre-3.5.7-gnu/mm/mempolicy.c
--- linux-libre-3.5.6-gnu/mm/mempolicy.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/mm/mempolicy.c	2012-10-12 16:48:25.000000000 -0400
@@ -607,6 +607,42 @@
 	return first;
 }
 
+/*
+ * Apply policy to a single VMA
+ * This must be called with the mmap_sem held for writing.
+ */
+static int vma_replace_policy(struct vm_area_struct *vma,
+						struct mempolicy *pol)
+{
+	int err;
+	struct mempolicy *old;
+	struct mempolicy *new;
+
+	pr_debug("vma %lx-%lx/%lx vm_ops %p vm_file %p set_policy %p\n",
+		 vma->vm_start, vma->vm_end, vma->vm_pgoff,
+		 vma->vm_ops, vma->vm_file,
+		 vma->vm_ops ? vma->vm_ops->set_policy : NULL);
+
+	new = mpol_dup(pol);
+	if (IS_ERR(new))
+		return PTR_ERR(new);
+
+	if (vma->vm_ops && vma->vm_ops->set_policy) {
+		err = vma->vm_ops->set_policy(vma, new);
+		if (err)
+			goto err_out;
+	}
+
+	old = vma->vm_policy;
+	vma->vm_policy = new; /* protected by mmap_sem */
+	mpol_put(old);
+
+	return 0;
+ err_out:
+	mpol_put(new);
+	return err;
+}
+
 /* Step 2: apply policy to a range and do splits. */
 static int mbind_range(struct mm_struct *mm, unsigned long start,
 		       unsigned long end, struct mempolicy *new_pol)
@@ -655,23 +691,9 @@
 			if (err)
 				goto out;
 		}
-
-		/*
-		 * Apply policy to a single VMA. The reference counting of
-		 * policy for vma_policy linkages has already been handled by
-		 * vma_merge and split_vma as necessary. If this is a shared
-		 * policy then ->set_policy will increment the reference count
-		 * for an sp node.
-		 */
-		pr_debug("vma %lx-%lx/%lx vm_ops %p vm_file %p set_policy %p\n",
-			vma->vm_start, vma->vm_end, vma->vm_pgoff,
-			vma->vm_ops, vma->vm_file,
-			vma->vm_ops ? vma->vm_ops->set_policy : NULL);
-		if (vma->vm_ops && vma->vm_ops->set_policy) {
-			err = vma->vm_ops->set_policy(vma, new_pol);
-			if (err)
-				goto out;
-		}
+		err = vma_replace_policy(vma, new_pol);
+		if (err)
+			goto out;
 	}
 
  out:
@@ -1530,8 +1552,18 @@
 									addr);
 			if (vpol)
 				pol = vpol;
-		} else if (vma->vm_policy)
+		} else if (vma->vm_policy) {
 			pol = vma->vm_policy;
+
+			/*
+			 * shmem_alloc_page() passes MPOL_F_SHARED policy with
+			 * a pseudo vma whose vma->vm_ops=NULL. Take a reference
+			 * count on these policies which will be dropped by
+			 * mpol_cond_put() later
+			 */
+			if (mpol_needs_cond_ref(pol))
+				mpol_get(pol);
+		}
 	}
 	if (!pol)
 		pol = &default_policy;
@@ -2055,7 +2087,7 @@
  */
 
 /* lookup first element intersecting start-end */
-/* Caller holds sp->lock */
+/* Caller holds sp->mutex */
 static struct sp_node *
 sp_lookup(struct shared_policy *sp, unsigned long start, unsigned long end)
 {
@@ -2119,36 +2151,50 @@
 
 	if (!sp->root.rb_node)
 		return NULL;
-	spin_lock(&sp->lock);
+	mutex_lock(&sp->mutex);
 	sn = sp_lookup(sp, idx, idx+1);
 	if (sn) {
 		mpol_get(sn->policy);
 		pol = sn->policy;
 	}
-	spin_unlock(&sp->lock);
+	mutex_unlock(&sp->mutex);
 	return pol;
 }
 
+static void sp_free(struct sp_node *n)
+{
+	mpol_put(n->policy);
+	kmem_cache_free(sn_cache, n);
+}
+
 static void sp_delete(struct shared_policy *sp, struct sp_node *n)
 {
 	pr_debug("deleting %lx-l%lx\n", n->start, n->end);
 	rb_erase(&n->nd, &sp->root);
-	mpol_put(n->policy);
-	kmem_cache_free(sn_cache, n);
+	sp_free(n);
 }
 
 static struct sp_node *sp_alloc(unsigned long start, unsigned long end,
 				struct mempolicy *pol)
 {
-	struct sp_node *n = kmem_cache_alloc(sn_cache, GFP_KERNEL);
+	struct sp_node *n;
+	struct mempolicy *newpol;
 
+	n = kmem_cache_alloc(sn_cache, GFP_KERNEL);
 	if (!n)
 		return NULL;
+
+	newpol = mpol_dup(pol);
+	if (IS_ERR(newpol)) {
+		kmem_cache_free(sn_cache, n);
+		return NULL;
+	}
+	newpol->flags |= MPOL_F_SHARED;
+
 	n->start = start;
 	n->end = end;
-	mpol_get(pol);
-	pol->flags |= MPOL_F_SHARED;	/* for unref */
-	n->policy = pol;
+	n->policy = newpol;
+
 	return n;
 }
 
@@ -2156,10 +2202,10 @@
 static int shared_policy_replace(struct shared_policy *sp, unsigned long start,
 				 unsigned long end, struct sp_node *new)
 {
-	struct sp_node *n, *new2 = NULL;
+	struct sp_node *n;
+	int ret = 0;
 
-restart:
-	spin_lock(&sp->lock);
+	mutex_lock(&sp->mutex);
 	n = sp_lookup(sp, start, end);
 	/* Take care of old policies in the same range. */
 	while (n && n->start < end) {
@@ -2172,16 +2218,14 @@
 		} else {
 			/* Old policy spanning whole new range. */
 			if (n->end > end) {
+				struct sp_node *new2;
+				new2 = sp_alloc(end, n->end, n->policy);
 				if (!new2) {
-					spin_unlock(&sp->lock);
-					new2 = sp_alloc(end, n->end, n->policy);
-					if (!new2)
-						return -ENOMEM;
-					goto restart;
+					ret = -ENOMEM;
+					goto out;
 				}
 				n->end = start;
 				sp_insert(sp, new2);
-				new2 = NULL;
 				break;
 			} else
 				n->end = start;
@@ -2192,12 +2236,9 @@
 	}
 	if (new)
 		sp_insert(sp, new);
-	spin_unlock(&sp->lock);
-	if (new2) {
-		mpol_put(new2->policy);
-		kmem_cache_free(sn_cache, new2);
-	}
-	return 0;
+out:
+	mutex_unlock(&sp->mutex);
+	return ret;
 }
 
 /**
@@ -2215,7 +2256,7 @@
 	int ret;
 
 	sp->root = RB_ROOT;		/* empty tree == default mempolicy */
-	spin_lock_init(&sp->lock);
+	mutex_init(&sp->mutex);
 
 	if (mpol) {
 		struct vm_area_struct pvma;
@@ -2269,7 +2310,7 @@
 	}
 	err = shared_policy_replace(info, vma->vm_pgoff, vma->vm_pgoff+sz, new);
 	if (err && new)
-		kmem_cache_free(sn_cache, new);
+		sp_free(new);
 	return err;
 }
 
@@ -2281,16 +2322,14 @@
 
 	if (!p->root.rb_node)
 		return;
-	spin_lock(&p->lock);
+	mutex_lock(&p->mutex);
 	next = rb_first(&p->root);
 	while (next) {
 		n = rb_entry(next, struct sp_node, nd);
 		next = rb_next(&n->nd);
-		rb_erase(&n->nd, &p->root);
-		mpol_put(n->policy);
-		kmem_cache_free(sn_cache, n);
+		sp_delete(p, n);
 	}
-	spin_unlock(&p->lock);
+	mutex_unlock(&p->mutex);
 }
 
 /* assumes fs == KERNEL_DS */
diff -druN linux-libre-3.5.6-gnu/mm/slab.c linux-libre-3.5.7-gnu/mm/slab.c
--- linux-libre-3.5.6-gnu/mm/slab.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/mm/slab.c	2012-10-12 16:48:25.000000000 -0400
@@ -1685,9 +1685,6 @@
 
 	g_cpucache_up = LATE;
 
-	/* Annotate slab for lockdep -- annotate the malloc caches */
-	init_lock_keys();
-
 	/* 6) resize the head arrays to their final sizes */
 	mutex_lock(&cache_chain_mutex);
 	list_for_each_entry(cachep, &cache_chain, next)
@@ -1695,6 +1692,9 @@
 			BUG();
 	mutex_unlock(&cache_chain_mutex);
 
+	/* Annotate slab for lockdep -- annotate the malloc caches */
+	init_lock_keys();
+
 	/* Done! */
 	g_cpucache_up = FULL;
 
diff -druN linux-libre-3.5.6-gnu/mm/truncate.c linux-libre-3.5.7-gnu/mm/truncate.c
--- linux-libre-3.5.6-gnu/mm/truncate.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/mm/truncate.c	2012-10-12 16:48:25.000000000 -0400
@@ -394,11 +394,12 @@
 	if (page_has_private(page) && !try_to_release_page(page, GFP_KERNEL))
 		return 0;
 
+	clear_page_mlock(page);
+
 	spin_lock_irq(&mapping->tree_lock);
 	if (PageDirty(page))
 		goto failed;
 
-	clear_page_mlock(page);
 	BUG_ON(page_has_private(page));
 	__delete_from_page_cache(page);
 	spin_unlock_irq(&mapping->tree_lock);
diff -druN linux-libre-3.5.6-gnu/net/8021q/vlan_core.c linux-libre-3.5.7-gnu/net/8021q/vlan_core.c
--- linux-libre-3.5.6-gnu/net/8021q/vlan_core.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/8021q/vlan_core.c	2012-10-12 16:48:25.000000000 -0400
@@ -105,7 +105,6 @@
 		return NULL;
 	memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN);
 	skb->mac_header += VLAN_HLEN;
-	skb_reset_mac_len(skb);
 	return skb;
 }
 
@@ -139,6 +138,8 @@
 
 	skb_reset_network_header(skb);
 	skb_reset_transport_header(skb);
+	skb_reset_mac_len(skb);
+
 	return skb;
 
 err_free:
diff -druN linux-libre-3.5.6-gnu/net/batman-adv/bitarray.h linux-libre-3.5.7-gnu/net/batman-adv/bitarray.h
--- linux-libre-3.5.6-gnu/net/batman-adv/bitarray.h	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/batman-adv/bitarray.h	2012-10-12 16:48:25.000000000 -0400
@@ -22,8 +22,9 @@
 #ifndef _NET_BATMAN_ADV_BITARRAY_H_
 #define _NET_BATMAN_ADV_BITARRAY_H_
 
-/* returns true if the corresponding bit in the given seq_bits indicates true
- * and curr_seqno is within range of last_seqno */
+/* Returns 1 if the corresponding bit in the given seq_bits indicates true
+ * and curr_seqno is within range of last_seqno. Otherwise returns 0.
+ */
 static inline int bat_test_bit(const unsigned long *seq_bits,
 			       uint32_t last_seqno, uint32_t curr_seqno)
 {
@@ -33,7 +34,7 @@
 	if (diff < 0 || diff >= TQ_LOCAL_WINDOW_SIZE)
 		return 0;
 	else
-		return  test_bit(diff, seq_bits);
+		return test_bit(diff, seq_bits) != 0;
 }
 
 /* turn corresponding bit on, so we can remember that we got the packet */
diff -druN linux-libre-3.5.6-gnu/net/core/dev.c linux-libre-3.5.7-gnu/net/core/dev.c
--- linux-libre-3.5.6-gnu/net/core/dev.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/core/dev.c	2012-10-12 16:48:25.000000000 -0400
@@ -2119,7 +2119,8 @@
 static netdev_features_t harmonize_features(struct sk_buff *skb,
 	__be16 protocol, netdev_features_t features)
 {
-	if (!can_checksum_protocol(features, protocol)) {
+	if (skb->ip_summed != CHECKSUM_NONE &&
+	    !can_checksum_protocol(features, protocol)) {
 		features &= ~NETIF_F_ALL_CSUM;
 		features &= ~NETIF_F_SG;
 	} else if (illegal_highdma(skb->dev, skb)) {
@@ -2615,15 +2616,16 @@
 	if (!skb_flow_dissect(skb, &keys))
 		return;
 
-	if (keys.ports) {
-		if ((__force u16)keys.port16[1] < (__force u16)keys.port16[0])
-			swap(keys.port16[0], keys.port16[1]);
+	if (keys.ports)
 		skb->l4_rxhash = 1;
-	}
 
 	/* get a consistent hash (same value on both flow directions) */
-	if ((__force u32)keys.dst < (__force u32)keys.src)
+	if (((__force u32)keys.dst < (__force u32)keys.src) ||
+	    (((__force u32)keys.dst == (__force u32)keys.src) &&
+	     ((__force u16)keys.port16[1] < (__force u16)keys.port16[0]))) {
 		swap(keys.dst, keys.src);
+		swap(keys.port16[0], keys.port16[1]);
+	}
 
 	hash = jhash_3words((__force u32)keys.dst,
 			    (__force u32)keys.src,
diff -druN linux-libre-3.5.6-gnu/net/core/sock.c linux-libre-3.5.7-gnu/net/core/sock.c
--- linux-libre-3.5.6-gnu/net/core/sock.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/core/sock.c	2012-10-12 16:48:25.000000000 -0400
@@ -636,7 +636,8 @@
 
 	case SO_KEEPALIVE:
 #ifdef CONFIG_INET
-		if (sk->sk_protocol == IPPROTO_TCP)
+		if (sk->sk_protocol == IPPROTO_TCP &&
+		    sk->sk_type == SOCK_STREAM)
 			tcp_set_keepalive(sk, valbool);
 #endif
 		sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool);
diff -druN linux-libre-3.5.6-gnu/net/ipv4/raw.c linux-libre-3.5.7-gnu/net/ipv4/raw.c
--- linux-libre-3.5.6-gnu/net/ipv4/raw.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/ipv4/raw.c	2012-10-12 16:48:25.000000000 -0400
@@ -131,18 +131,20 @@
  *	0 - deliver
  *	1 - block
  */
-static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb)
+static int icmp_filter(const struct sock *sk, const struct sk_buff *skb)
 {
-	int type;
+	struct icmphdr _hdr;
+	const struct icmphdr *hdr;
 
-	if (!pskb_may_pull(skb, sizeof(struct icmphdr)))
+	hdr = skb_header_pointer(skb, skb_transport_offset(skb),
+				 sizeof(_hdr), &_hdr);
+	if (!hdr)
 		return 1;
 
-	type = icmp_hdr(skb)->type;
-	if (type < 32) {
+	if (hdr->type < 32) {
 		__u32 data = raw_sk(sk)->filter.data;
 
-		return ((1 << type) & data) != 0;
+		return ((1U << hdr->type) & data) != 0;
 	}
 
 	/* Do not block unknown ICMP types */
diff -druN linux-libre-3.5.6-gnu/net/ipv4/tcp.c linux-libre-3.5.7-gnu/net/ipv4/tcp.c
--- linux-libre-3.5.6-gnu/net/ipv4/tcp.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/ipv4/tcp.c	2012-10-12 16:48:25.000000000 -0400
@@ -1706,8 +1706,14 @@
 		}
 
 #ifdef CONFIG_NET_DMA
-		if (tp->ucopy.dma_chan)
-			dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+		if (tp->ucopy.dma_chan) {
+			if (tp->rcv_wnd == 0 &&
+			    !skb_queue_empty(&sk->sk_async_wait_queue)) {
+				tcp_service_net_dma(sk, true);
+				tcp_cleanup_rbuf(sk, copied);
+			} else
+				dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+		}
 #endif
 		if (copied >= target) {
 			/* Do not sleep, just process backlog. */
diff -druN linux-libre-3.5.6-gnu/net/ipv4/tcp_input.c linux-libre-3.5.7-gnu/net/ipv4/tcp_input.c
--- linux-libre-3.5.6-gnu/net/ipv4/tcp_input.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/ipv4/tcp_input.c	2012-10-12 16:48:25.000000000 -0400
@@ -4818,7 +4818,7 @@
 
 		if (eaten > 0)
 			kfree_skb_partial(skb, fragstolen);
-		else if (!sock_flag(sk, SOCK_DEAD))
+		if (!sock_flag(sk, SOCK_DEAD))
 			sk->sk_data_ready(sk, 0);
 		return;
 	}
@@ -5680,8 +5680,7 @@
 #endif
 			if (eaten)
 				kfree_skb_partial(skb, fragstolen);
-			else
-				sk->sk_data_ready(sk, 0);
+			sk->sk_data_ready(sk, 0);
 			return 0;
 		}
 	}
diff -druN linux-libre-3.5.6-gnu/net/ipv6/addrconf.c linux-libre-3.5.7-gnu/net/ipv6/addrconf.c
--- linux-libre-3.5.6-gnu/net/ipv6/addrconf.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/ipv6/addrconf.c	2012-10-12 16:48:25.000000000 -0400
@@ -793,10 +793,16 @@
 		struct in6_addr prefix;
 		struct rt6_info *rt;
 		struct net *net = dev_net(ifp->idev->dev);
+		struct flowi6 fl6 = {};
+
 		ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len);
-		rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1);
+		fl6.flowi6_oif = ifp->idev->dev->ifindex;
+		fl6.daddr = prefix;
+		rt = (struct rt6_info *)ip6_route_lookup(net, &fl6,
+							 RT6_LOOKUP_F_IFACE);
 
-		if (rt && addrconf_is_prefix_route(rt)) {
+		if (rt != net->ipv6.ip6_null_entry &&
+		    addrconf_is_prefix_route(rt)) {
 			if (onlink == 0) {
 				ip6_del_rt(rt);
 				rt = NULL;
diff -druN linux-libre-3.5.6-gnu/net/ipv6/ip6_fib.c linux-libre-3.5.7-gnu/net/ipv6/ip6_fib.c
--- linux-libre-3.5.6-gnu/net/ipv6/ip6_fib.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/ipv6/ip6_fib.c	2012-10-12 16:48:25.000000000 -0400
@@ -818,6 +818,10 @@
 					offsetof(struct rt6_info, rt6i_src),
 					allow_create, replace_required);
 
+			if (IS_ERR(sn)) {
+				err = PTR_ERR(sn);
+				sn = NULL;
+			}
 			if (!sn) {
 				/* If it is failed, discard just allocated
 				   root, and then (in st_failure) stale node
diff -druN linux-libre-3.5.6-gnu/net/ipv6/mip6.c linux-libre-3.5.7-gnu/net/ipv6/mip6.c
--- linux-libre-3.5.6-gnu/net/ipv6/mip6.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/ipv6/mip6.c	2012-10-12 16:48:25.000000000 -0400
@@ -86,28 +86,30 @@
 
 static int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
 {
-	struct ip6_mh *mh;
+	struct ip6_mh _hdr;
+	const struct ip6_mh *mh;
 
-	if (!pskb_may_pull(skb, (skb_transport_offset(skb)) + 8) ||
-	    !pskb_may_pull(skb, (skb_transport_offset(skb) +
-				 ((skb_transport_header(skb)[1] + 1) << 3))))
+	mh = skb_header_pointer(skb, skb_transport_offset(skb),
+				sizeof(_hdr), &_hdr);
+	if (!mh)
 		return -1;
 
-	mh = (struct ip6_mh *)skb_transport_header(skb);
+	if (((mh->ip6mh_hdrlen + 1) << 3) > skb->len)
+		return -1;
 
 	if (mh->ip6mh_hdrlen < mip6_mh_len(mh->ip6mh_type)) {
 		LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH message too short: %d vs >=%d\n",
 			       mh->ip6mh_hdrlen, mip6_mh_len(mh->ip6mh_type));
-		mip6_param_prob(skb, 0, ((&mh->ip6mh_hdrlen) -
-					 skb_network_header(skb)));
+		mip6_param_prob(skb, 0, offsetof(struct ip6_mh, ip6mh_hdrlen) +
+				skb_network_header_len(skb));
 		return -1;
 	}
 
 	if (mh->ip6mh_proto != IPPROTO_NONE) {
 		LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n",
 			       mh->ip6mh_proto);
-		mip6_param_prob(skb, 0, ((&mh->ip6mh_proto) -
-					 skb_network_header(skb)));
+		mip6_param_prob(skb, 0, offsetof(struct ip6_mh, ip6mh_proto) +
+				skb_network_header_len(skb));
 		return -1;
 	}
 
diff -druN linux-libre-3.5.6-gnu/net/ipv6/raw.c linux-libre-3.5.7-gnu/net/ipv6/raw.c
--- linux-libre-3.5.6-gnu/net/ipv6/raw.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/ipv6/raw.c	2012-10-12 16:48:25.000000000 -0400
@@ -107,21 +107,20 @@
  *	0 - deliver
  *	1 - block
  */
-static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb)
+static int icmpv6_filter(const struct sock *sk, const struct sk_buff *skb)
 {
-	struct icmp6hdr *icmph;
-	struct raw6_sock *rp = raw6_sk(sk);
-
-	if (pskb_may_pull(skb, sizeof(struct icmp6hdr))) {
-		__u32 *data = &rp->filter.data[0];
-		int bit_nr;
+	struct icmp6hdr *_hdr;
+	const struct icmp6hdr *hdr;
 
-		icmph = (struct icmp6hdr *) skb->data;
-		bit_nr = icmph->icmp6_type;
+	hdr = skb_header_pointer(skb, skb_transport_offset(skb),
+				 sizeof(_hdr), &_hdr);
+	if (hdr) {
+		const __u32 *data = &raw6_sk(sk)->filter.data[0];
+		unsigned int type = hdr->icmp6_type;
 
-		return (data[bit_nr >> 5] & (1 << (bit_nr & 31))) != 0;
+		return (data[type >> 5] & (1U << (type & 31))) != 0;
 	}
-	return 0;
+	return 1;
 }
 
 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
diff -druN linux-libre-3.5.6-gnu/net/ipv6/route.c linux-libre-3.5.7-gnu/net/ipv6/route.c
--- linux-libre-3.5.6-gnu/net/ipv6/route.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/ipv6/route.c	2012-10-12 16:48:25.000000000 -0400
@@ -1485,17 +1485,18 @@
 	struct fib6_table *table;
 	struct net *net = dev_net(rt->dst.dev);
 
-	if (rt == net->ipv6.ip6_null_entry)
-		return -ENOENT;
+	if (rt == net->ipv6.ip6_null_entry) {
+		err = -ENOENT;
+		goto out;
+	}
 
 	table = rt->rt6i_table;
 	write_lock_bh(&table->tb6_lock);
-
 	err = fib6_del(rt, info);
-	dst_release(&rt->dst);
-
 	write_unlock_bh(&table->tb6_lock);
 
+out:
+	dst_release(&rt->dst);
 	return err;
 }
 
diff -druN linux-libre-3.5.6-gnu/net/l2tp/l2tp_eth.c linux-libre-3.5.7-gnu/net/l2tp/l2tp_eth.c
--- linux-libre-3.5.6-gnu/net/l2tp/l2tp_eth.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/l2tp/l2tp_eth.c	2012-10-12 16:48:25.000000000 -0400
@@ -148,7 +148,7 @@
 		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, length);
 	}
 
-	if (!pskb_may_pull(skb, sizeof(ETH_HLEN)))
+	if (!pskb_may_pull(skb, ETH_HLEN))
 		goto error;
 
 	secpath_reset(skb);
diff -druN linux-libre-3.5.6-gnu/net/netrom/af_netrom.c linux-libre-3.5.7-gnu/net/netrom/af_netrom.c
--- linux-libre-3.5.6-gnu/net/netrom/af_netrom.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/netrom/af_netrom.c	2012-10-12 16:48:25.000000000 -0400
@@ -1169,7 +1169,12 @@
 		msg->msg_flags |= MSG_TRUNC;
 	}
 
-	skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+	er = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+	if (er < 0) {
+		skb_free_datagram(sk, skb);
+		release_sock(sk);
+		return er;
+	}
 
 	if (sax != NULL) {
 		sax->sax25_family = AF_NETROM;
diff -druN linux-libre-3.5.6-gnu/net/sched/sch_cbq.c linux-libre-3.5.7-gnu/net/sched/sch_cbq.c
--- linux-libre-3.5.6-gnu/net/sched/sch_cbq.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/sched/sch_cbq.c	2012-10-12 16:48:25.000000000 -0400
@@ -250,10 +250,11 @@
 			else if ((cl = defmap[res.classid & TC_PRIO_MAX]) == NULL)
 				cl = defmap[TC_PRIO_BESTEFFORT];
 
-			if (cl == NULL || cl->level >= head->level)
+			if (cl == NULL)
 				goto fallback;
 		}
-
+		if (cl->level >= head->level)
+			goto fallback;
 #ifdef CONFIG_NET_CLS_ACT
 		switch (result) {
 		case TC_ACT_QUEUED:
diff -druN linux-libre-3.5.6-gnu/net/sched/sch_qfq.c linux-libre-3.5.7-gnu/net/sched/sch_qfq.c
--- linux-libre-3.5.6-gnu/net/sched/sch_qfq.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/sched/sch_qfq.c	2012-10-12 16:48:25.000000000 -0400
@@ -831,7 +831,10 @@
 		if (mask) {
 			struct qfq_group *next = qfq_ffs(q, mask);
 			if (qfq_gt(roundedF, next->F)) {
-				cl->S = next->F;
+				if (qfq_gt(limit, next->F))
+					cl->S = next->F;
+				else /* preserve timestamp correctness */
+					cl->S = limit;
 				return;
 			}
 		}
diff -druN linux-libre-3.5.6-gnu/net/sctp/output.c linux-libre-3.5.7-gnu/net/sctp/output.c
--- linux-libre-3.5.6-gnu/net/sctp/output.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/sctp/output.c	2012-10-12 16:48:25.000000000 -0400
@@ -339,6 +339,25 @@
 	return retval;
 }
 
+static void sctp_packet_release_owner(struct sk_buff *skb)
+{
+	sk_free(skb->sk);
+}
+
+static void sctp_packet_set_owner_w(struct sk_buff *skb, struct sock *sk)
+{
+	skb_orphan(skb);
+	skb->sk = sk;
+	skb->destructor = sctp_packet_release_owner;
+
+	/*
+	 * The data chunks have already been accounted for in sctp_sendmsg(),
+	 * therefore only reserve a single byte to keep socket around until
+	 * the packet has been transmitted.
+	 */
+	atomic_inc(&sk->sk_wmem_alloc);
+}
+
 /* All packets are sent to the network through this function from
  * sctp_outq_tail().
  *
@@ -380,7 +399,7 @@
 	/* Set the owning socket so that we know where to get the
 	 * destination IP address.
 	 */
-	skb_set_owner_w(nskb, sk);
+	sctp_packet_set_owner_w(nskb, sk);
 
 	if (!sctp_transport_dst_check(tp)) {
 		sctp_transport_route(tp, NULL, sctp_sk(sk));
diff -druN linux-libre-3.5.6-gnu/net/xfrm/xfrm_input.c linux-libre-3.5.7-gnu/net/xfrm/xfrm_input.c
--- linux-libre-3.5.6-gnu/net/xfrm/xfrm_input.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/xfrm/xfrm_input.c	2012-10-12 16:48:25.000000000 -0400
@@ -212,7 +212,7 @@
 		/* only the first xfrm gets the encap type */
 		encap_type = 0;
 
-		if (async && x->repl->check(x, skb, seq)) {
+		if (async && x->repl->recheck(x, skb, seq)) {
 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
 			goto drop_unlock;
 		}
diff -druN linux-libre-3.5.6-gnu/net/xfrm/xfrm_policy.c linux-libre-3.5.7-gnu/net/xfrm/xfrm_policy.c
--- linux-libre-3.5.6-gnu/net/xfrm/xfrm_policy.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/xfrm/xfrm_policy.c	2012-10-12 16:48:25.000000000 -0400
@@ -1763,7 +1763,7 @@
 
 	if (!afinfo) {
 		dst_release(dst_orig);
-		ret = ERR_PTR(-EINVAL);
+		return ERR_PTR(-EINVAL);
 	} else {
 		ret = afinfo->blackhole_route(net, dst_orig);
 	}
diff -druN linux-libre-3.5.6-gnu/net/xfrm/xfrm_replay.c linux-libre-3.5.7-gnu/net/xfrm/xfrm_replay.c
--- linux-libre-3.5.6-gnu/net/xfrm/xfrm_replay.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/xfrm/xfrm_replay.c	2012-10-12 16:48:25.000000000 -0400
@@ -420,6 +420,18 @@
 	return -EINVAL;
 }
 
+static int xfrm_replay_recheck_esn(struct xfrm_state *x,
+				   struct sk_buff *skb, __be32 net_seq)
+{
+	if (unlikely(XFRM_SKB_CB(skb)->seq.input.hi !=
+		     htonl(xfrm_replay_seqhi(x, net_seq)))) {
+			x->stats.replay_window++;
+			return -EINVAL;
+	}
+
+	return xfrm_replay_check_esn(x, skb, net_seq);
+}
+
 static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)
 {
 	unsigned int bitnr, nr, i;
@@ -479,6 +491,7 @@
 static struct xfrm_replay xfrm_replay_legacy = {
 	.advance	= xfrm_replay_advance,
 	.check		= xfrm_replay_check,
+	.recheck	= xfrm_replay_check,
 	.notify		= xfrm_replay_notify,
 	.overflow	= xfrm_replay_overflow,
 };
@@ -486,6 +499,7 @@
 static struct xfrm_replay xfrm_replay_bmp = {
 	.advance	= xfrm_replay_advance_bmp,
 	.check		= xfrm_replay_check_bmp,
+	.recheck	= xfrm_replay_check_bmp,
 	.notify		= xfrm_replay_notify_bmp,
 	.overflow	= xfrm_replay_overflow_bmp,
 };
@@ -493,6 +507,7 @@
 static struct xfrm_replay xfrm_replay_esn = {
 	.advance	= xfrm_replay_advance_esn,
 	.check		= xfrm_replay_check_esn,
+	.recheck	= xfrm_replay_recheck_esn,
 	.notify		= xfrm_replay_notify_bmp,
 	.overflow	= xfrm_replay_overflow_esn,
 };
diff -druN linux-libre-3.5.6-gnu/net/xfrm/xfrm_user.c linux-libre-3.5.7-gnu/net/xfrm/xfrm_user.c
--- linux-libre-3.5.6-gnu/net/xfrm/xfrm_user.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/net/xfrm/xfrm_user.c	2012-10-12 16:48:25.000000000 -0400
@@ -123,9 +123,21 @@
 				struct nlattr **attrs)
 {
 	struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL];
+	struct xfrm_replay_state_esn *rs;
 
-	if ((p->flags & XFRM_STATE_ESN) && !rt)
-		return -EINVAL;
+	if (p->flags & XFRM_STATE_ESN) {
+		if (!rt)
+			return -EINVAL;
+
+		rs = nla_data(rt);
+
+		if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8)
+			return -EINVAL;
+
+		if (nla_len(rt) < xfrm_replay_state_esn_len(rs) &&
+		    nla_len(rt) != sizeof(*rs))
+			return -EINVAL;
+	}
 
 	if (!rt)
 		return 0;
@@ -370,14 +382,15 @@
 					 struct nlattr *rp)
 {
 	struct xfrm_replay_state_esn *up;
+	int ulen;
 
 	if (!replay_esn || !rp)
 		return 0;
 
 	up = nla_data(rp);
+	ulen = xfrm_replay_state_esn_len(up);
 
-	if (xfrm_replay_state_esn_len(replay_esn) !=
-			xfrm_replay_state_esn_len(up))
+	if (nla_len(rp) < ulen || xfrm_replay_state_esn_len(replay_esn) != ulen)
 		return -EINVAL;
 
 	return 0;
@@ -388,22 +401,28 @@
 				       struct nlattr *rta)
 {
 	struct xfrm_replay_state_esn *p, *pp, *up;
+	int klen, ulen;
 
 	if (!rta)
 		return 0;
 
 	up = nla_data(rta);
+	klen = xfrm_replay_state_esn_len(up);
+	ulen = nla_len(rta) >= klen ? klen : sizeof(*up);
 
-	p = kmemdup(up, xfrm_replay_state_esn_len(up), GFP_KERNEL);
+	p = kzalloc(klen, GFP_KERNEL);
 	if (!p)
 		return -ENOMEM;
 
-	pp = kmemdup(up, xfrm_replay_state_esn_len(up), GFP_KERNEL);
+	pp = kzalloc(klen, GFP_KERNEL);
 	if (!pp) {
 		kfree(p);
 		return -ENOMEM;
 	}
 
+	memcpy(p, up, ulen);
+	memcpy(pp, up, ulen);
+
 	*replay_esn = p;
 	*preplay_esn = pp;
 
@@ -442,10 +461,11 @@
  * somehow made shareable and move it to xfrm_state.c - JHS
  *
 */
-static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs)
+static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs,
+				  int update_esn)
 {
 	struct nlattr *rp = attrs[XFRMA_REPLAY_VAL];
-	struct nlattr *re = attrs[XFRMA_REPLAY_ESN_VAL];
+	struct nlattr *re = update_esn ? attrs[XFRMA_REPLAY_ESN_VAL] : NULL;
 	struct nlattr *lt = attrs[XFRMA_LTIME_VAL];
 	struct nlattr *et = attrs[XFRMA_ETIMER_THRESH];
 	struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH];
@@ -555,7 +575,7 @@
 		goto error;
 
 	/* override default values from above */
-	xfrm_update_ae_params(x, attrs);
+	xfrm_update_ae_params(x, attrs, 0);
 
 	return x;
 
@@ -689,6 +709,7 @@
 
 static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
 {
+	memset(p, 0, sizeof(*p));
 	memcpy(&p->id, &x->id, sizeof(p->id));
 	memcpy(&p->sel, &x->sel, sizeof(p->sel));
 	memcpy(&p->lft, &x->lft, sizeof(p->lft));
@@ -742,7 +763,7 @@
 		return -EMSGSIZE;
 
 	algo = nla_data(nla);
-	strcpy(algo->alg_name, auth->alg_name);
+	strncpy(algo->alg_name, auth->alg_name, sizeof(algo->alg_name));
 	memcpy(algo->alg_key, auth->alg_key, (auth->alg_key_len + 7) / 8);
 	algo->alg_key_len = auth->alg_key_len;
 
@@ -872,6 +893,7 @@
 {
 	struct xfrm_dump_info info;
 	struct sk_buff *skb;
+	int err;
 
 	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
 	if (!skb)
@@ -882,9 +904,10 @@
 	info.nlmsg_seq = seq;
 	info.nlmsg_flags = 0;
 
-	if (dump_one_state(x, 0, &info)) {
+	err = dump_one_state(x, 0, &info);
+	if (err) {
 		kfree_skb(skb);
-		return NULL;
+		return ERR_PTR(err);
 	}
 
 	return skb;
@@ -1309,6 +1332,7 @@
 
 static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_info *p, int dir)
 {
+	memset(p, 0, sizeof(*p));
 	memcpy(&p->sel, &xp->selector, sizeof(p->sel));
 	memcpy(&p->lft, &xp->lft, sizeof(p->lft));
 	memcpy(&p->curlft, &xp->curlft, sizeof(p->curlft));
@@ -1413,6 +1437,7 @@
 		struct xfrm_user_tmpl *up = &vec[i];
 		struct xfrm_tmpl *kp = &xp->xfrm_vec[i];
 
+		memset(up, 0, sizeof(*up));
 		memcpy(&up->id, &kp->id, sizeof(up->id));
 		up->family = kp->encap_family;
 		memcpy(&up->saddr, &kp->saddr, sizeof(up->saddr));
@@ -1541,6 +1566,7 @@
 {
 	struct xfrm_dump_info info;
 	struct sk_buff *skb;
+	int err;
 
 	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (!skb)
@@ -1551,9 +1577,10 @@
 	info.nlmsg_seq = seq;
 	info.nlmsg_flags = 0;
 
-	if (dump_one_policy(xp, dir, 0, &info) < 0) {
+	err = dump_one_policy(xp, dir, 0, &info);
+	if (err) {
 		kfree_skb(skb);
-		return NULL;
+		return ERR_PTR(err);
 	}
 
 	return skb;
@@ -1812,7 +1839,7 @@
 		goto out;
 
 	spin_lock_bh(&x->lock);
-	xfrm_update_ae_params(x, attrs);
+	xfrm_update_ae_params(x, attrs, 1);
 	spin_unlock_bh(&x->lock);
 
 	c.event = nlh->nlmsg_type;
diff -druN linux-libre-3.5.6-gnu/scripts/gcc-version.sh linux-libre-3.5.7-gnu/scripts/gcc-version.sh
--- linux-libre-3.5.6-gnu/scripts/gcc-version.sh	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/scripts/gcc-version.sh	2012-10-12 16:48:25.000000000 -0400
@@ -22,10 +22,10 @@
 	exit 1
 fi
 
-MAJOR=$(echo __GNUC__ | $compiler -E -xc - | tail -n 1)
-MINOR=$(echo __GNUC_MINOR__ | $compiler -E -xc - | tail -n 1)
+MAJOR=$(echo __GNUC__ | $compiler -E -x c - | tail -n 1)
+MINOR=$(echo __GNUC_MINOR__ | $compiler -E -x c - | tail -n 1)
 if [ "x$with_patchlevel" != "x" ] ; then
-	PATCHLEVEL=$(echo __GNUC_PATCHLEVEL__ | $compiler -E -xc - | tail -n 1)
+	PATCHLEVEL=$(echo __GNUC_PATCHLEVEL__ | $compiler -E -x c - | tail -n 1)
 	printf "%02d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL
 else
 	printf "%02d%02d\\n" $MAJOR $MINOR
diff -druN linux-libre-3.5.6-gnu/scripts/gcc-x86_32-has-stack-protector.sh linux-libre-3.5.7-gnu/scripts/gcc-x86_32-has-stack-protector.sh
--- linux-libre-3.5.6-gnu/scripts/gcc-x86_32-has-stack-protector.sh	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/scripts/gcc-x86_32-has-stack-protector.sh	2012-10-12 16:48:25.000000000 -0400
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-echo "int foo(void) { char X[200]; return 3; }" | $* -S -xc -c -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
+echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
 if [ "$?" -eq "0" ] ; then
 	echo y
 else
diff -druN linux-libre-3.5.6-gnu/scripts/gcc-x86_64-has-stack-protector.sh linux-libre-3.5.7-gnu/scripts/gcc-x86_64-has-stack-protector.sh
--- linux-libre-3.5.6-gnu/scripts/gcc-x86_64-has-stack-protector.sh	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/scripts/gcc-x86_64-has-stack-protector.sh	2012-10-12 16:48:25.000000000 -0400
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-echo "int foo(void) { char X[200]; return 3; }" | $* -S -xc -c -O0 -mcmodel=kernel -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
+echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
 if [ "$?" -eq "0" ] ; then
 	echo y
 else
diff -druN linux-libre-3.5.6-gnu/scripts/Kbuild.include linux-libre-3.5.7-gnu/scripts/Kbuild.include
--- linux-libre-3.5.6-gnu/scripts/Kbuild.include	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/scripts/Kbuild.include	2012-10-12 16:48:25.000000000 -0400
@@ -98,24 +98,24 @@
 # Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,)
 
 as-option = $(call try-run,\
-	$(CC) $(KBUILD_CFLAGS) $(1) -c -xassembler /dev/null -o "$$TMP",$(1),$(2))
+	$(CC) $(KBUILD_CFLAGS) $(1) -c -x assembler /dev/null -o "$$TMP",$(1),$(2))
 
 # as-instr
 # Usage: cflags-y += $(call as-instr,instr,option1,option2)
 
 as-instr = $(call try-run,\
-	printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3))
+	printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3))
 
 # cc-option
 # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
 
 cc-option = $(call try-run,\
-	$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",$(1),$(2))
+	$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))
 
 # cc-option-yn
 # Usage: flag := $(call cc-option-yn,-march=winchip-c6)
 cc-option-yn = $(call try-run,\
-	$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",y,n)
+	$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)
 
 # cc-option-align
 # Prefix align with either -falign or -malign
@@ -125,7 +125,7 @@
 # cc-disable-warning
 # Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable)
 cc-disable-warning = $(call try-run,\
-	$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -xc /dev/null -o "$$TMP",-Wno-$(strip $(1)))
+	$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
 
 # cc-version
 # Usage gcc-ver := $(call cc-version)
@@ -143,7 +143,7 @@
 # cc-ldoption
 # Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both)
 cc-ldoption = $(call try-run,\
-	$(CC) $(1) -nostdlib -xc /dev/null -o "$$TMP",$(1),$(2))
+	$(CC) $(1) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2))
 
 # ld-option
 # Usage: LDFLAGS += $(call ld-option, -X)
@@ -209,7 +209,7 @@
 # >$< substitution to preserve $ when reloading .cmd file
 # note: when using inline perl scripts [perl -e '...$$t=1;...']
 # in $(cmd_xxx) double $$ your perl vars
-make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1)))))
+make-cmd = $(subst \\,\\\\,$(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))))
 
 # Find any prerequisites that is newer than target or that does not exist.
 # PHONY targets skipped in both cases.
diff -druN linux-libre-3.5.6-gnu/scripts/kconfig/check.sh linux-libre-3.5.7-gnu/scripts/kconfig/check.sh
--- linux-libre-3.5.6-gnu/scripts/kconfig/check.sh	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/scripts/kconfig/check.sh	2012-10-12 16:48:25.000000000 -0400
@@ -1,6 +1,6 @@
 #!/bin/sh
 # Needed for systems without gettext
-$* -xc -o /dev/null - > /dev/null 2>&1 << EOF
+$* -x c -o /dev/null - > /dev/null 2>&1 << EOF
 #include <libintl.h>
 int main()
 {
diff -druN linux-libre-3.5.6-gnu/scripts/kconfig/lxdialog/check-lxdialog.sh linux-libre-3.5.7-gnu/scripts/kconfig/lxdialog/check-lxdialog.sh
--- linux-libre-3.5.6-gnu/scripts/kconfig/lxdialog/check-lxdialog.sh	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/scripts/kconfig/lxdialog/check-lxdialog.sh	2012-10-12 16:48:25.000000000 -0400
@@ -38,7 +38,7 @@
 
 # Check if we can link to ncurses
 check() {
-        $cc -xc - -o $tmp 2>/dev/null <<'EOF'
+        $cc -x c - -o $tmp 2>/dev/null <<'EOF'
 #include CURSES_LOC
 main() {}
 EOF
diff -druN linux-libre-3.5.6-gnu/scripts/kconfig/streamline_config.pl linux-libre-3.5.7-gnu/scripts/kconfig/streamline_config.pl
--- linux-libre-3.5.6-gnu/scripts/kconfig/streamline_config.pl	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/scripts/kconfig/streamline_config.pl	2012-10-12 16:48:25.000000000 -0400
@@ -463,6 +463,8 @@
 	if (defined($configs{$1})) {
 	    if ($localyesconfig) {
 	        $setconfigs{$1} = 'y';
+		print "$1=y\n";
+		next;
 	    } else {
 	        $setconfigs{$1} = $2;
 	    }
diff -druN linux-libre-3.5.6-gnu/sound/drivers/aloop.c linux-libre-3.5.7-gnu/sound/drivers/aloop.c
--- linux-libre-3.5.6-gnu/sound/drivers/aloop.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/sound/drivers/aloop.c	2012-10-12 16:48:25.000000000 -0400
@@ -120,6 +120,7 @@
 	unsigned int last_drift;
 	unsigned long last_jiffies;
 	struct timer_list timer;
+	spinlock_t timer_lock;
 };
 
 static struct platform_device *devices[SNDRV_CARDS];
@@ -170,6 +171,7 @@
 	unsigned long tick;
 	unsigned int rate_shift = get_rate_shift(dpcm);
 
+	spin_lock(&dpcm->timer_lock);
 	if (rate_shift != dpcm->pcm_rate_shift) {
 		dpcm->pcm_rate_shift = rate_shift;
 		dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size);
@@ -182,12 +184,15 @@
 	tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
 	dpcm->timer.expires = jiffies + tick;
 	add_timer(&dpcm->timer);
+	spin_unlock(&dpcm->timer_lock);
 }
 
 static inline void loopback_timer_stop(struct loopback_pcm *dpcm)
 {
+	spin_lock(&dpcm->timer_lock);
 	del_timer(&dpcm->timer);
 	dpcm->timer.expires = 0;
+	spin_unlock(&dpcm->timer_lock);
 }
 
 #define CABLE_VALID_PLAYBACK	(1 << SNDRV_PCM_STREAM_PLAYBACK)
@@ -667,6 +672,7 @@
 	dpcm->substream = substream;
 	setup_timer(&dpcm->timer, loopback_timer_function,
 		    (unsigned long)dpcm);
+	spin_lock_init(&dpcm->timer_lock);
 
 	cable = loopback->cables[substream->number][dev];
 	if (!cable) {
diff -druN linux-libre-3.5.6-gnu/sound/pci/hda/patch_conexant.c linux-libre-3.5.7-gnu/sound/pci/hda/patch_conexant.c
--- linux-libre-3.5.6-gnu/sound/pci/hda/patch_conexant.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/sound/pci/hda/patch_conexant.c	2012-10-12 16:48:25.000000000 -0400
@@ -4467,6 +4467,7 @@
 	SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
+	SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
 	{}
 };
diff -druN linux-libre-3.5.6-gnu/sound/pci/hda/patch_realtek.c linux-libre-3.5.7-gnu/sound/pci/hda/patch_realtek.c
--- linux-libre-3.5.6-gnu/sound/pci/hda/patch_realtek.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/sound/pci/hda/patch_realtek.c	2012-10-12 16:48:25.000000000 -0400
@@ -6145,6 +6145,12 @@
 
 	spec = codec->spec;
 
+	alc_pick_fixup(codec, alc269_fixup_models,
+		       alc269_fixup_tbl, alc269_fixups);
+	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
+
+	alc_auto_parse_customize_define(codec);
+
 	if (codec->vendor_id == 0x10ec0269) {
 		spec->codec_variant = ALC269_TYPE_ALC269VA;
 		switch (alc_get_coef0(codec) & 0x00f0) {
@@ -6172,12 +6178,6 @@
 		alc269_fill_coef(codec);
 	}
 
-	alc_pick_fixup(codec, alc269_fixup_models,
-		       alc269_fixup_tbl, alc269_fixups);
-	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-
-	alc_auto_parse_customize_define(codec);
-
 	/* automatic parse from the BIOS config */
 	err = alc269_parse_auto_config(codec);
 	if (err < 0)
diff -druN linux-libre-3.5.6-gnu/sound/pci/hda/patch_via.c linux-libre-3.5.7-gnu/sound/pci/hda/patch_via.c
--- linux-libre-3.5.6-gnu/sound/pci/hda/patch_via.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/sound/pci/hda/patch_via.c	2012-10-12 16:48:25.000000000 -0400
@@ -3661,6 +3661,32 @@
 		update_power_state(codec, 0x21, AC_PWRST_D3);
 }
 
+/*
+ * pin fix-up
+ */
+enum {
+	VIA_FIXUP_INTMIC_BOOST,
+};
+
+static void via_fixup_intmic_boost(struct hda_codec *codec,
+				  const struct hda_fixup *fix, int action)
+{
+	if (action == HDA_FIXUP_ACT_PRE_PROBE)
+		override_mic_boost(codec, 0x30, 0, 2, 40);
+}
+
+static const struct hda_fixup via_fixups[] = {
+	[VIA_FIXUP_INTMIC_BOOST] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = via_fixup_intmic_boost,
+	},
+};
+
+static const struct snd_pci_quirk vt2002p_fixups[] = {
+	SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST),
+	{}
+};
+
 /* patch for vt2002P */
 static int patch_vt2002P(struct hda_codec *codec)
 {
@@ -3677,6 +3703,9 @@
 	override_mic_boost(codec, 0x29, 0, 3, 40);
 	add_secret_dac_path(codec);
 
+	snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups);
+	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
+
 	/* automatic parse from the BIOS config */
 	err = via_parse_auto_config(codec);
 	if (err < 0) {
diff -druN linux-libre-3.5.6-gnu/sound/soc/codecs/wm9712.c linux-libre-3.5.7-gnu/sound/soc/codecs/wm9712.c
--- linux-libre-3.5.6-gnu/sound/soc/codecs/wm9712.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/sound/soc/codecs/wm9712.c	2012-10-12 16:48:25.000000000 -0400
@@ -146,7 +146,7 @@
 SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 15, 1),
 SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1),
 
-SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1),
+SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1),
 SOC_ENUM("Capture Volume Steps", wm9712_enum[6]),
 SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1),
 SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
diff -druN linux-libre-3.5.6-gnu/sound/soc/codecs/wm_hubs.c linux-libre-3.5.7-gnu/sound/soc/codecs/wm_hubs.c
--- linux-libre-3.5.6-gnu/sound/soc/codecs/wm_hubs.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/sound/soc/codecs/wm_hubs.c	2012-10-12 16:48:25.000000000 -0400
@@ -634,6 +634,11 @@
 
 	snd_soc_update_bits(codec, WM8993_CLASS_W_0,
 			    WM8993_CP_DYN_V | WM8993_CP_DYN_FREQ, enable);
+
+	snd_soc_write(codec, WM8993_LEFT_OUTPUT_VOLUME,
+		      snd_soc_read(codec, WM8993_LEFT_OUTPUT_VOLUME));
+	snd_soc_write(codec, WM8993_RIGHT_OUTPUT_VOLUME,
+		      snd_soc_read(codec, WM8993_RIGHT_OUTPUT_VOLUME));
 }
 EXPORT_SYMBOL_GPL(wm_hubs_update_class_w);
 
diff -druN linux-libre-3.5.6-gnu/sound/usb/mixer.c linux-libre-3.5.7-gnu/sound/usb/mixer.c
--- linux-libre-3.5.6-gnu/sound/usb/mixer.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/sound/usb/mixer.c	2012-10-12 16:48:25.000000000 -0400
@@ -1267,6 +1267,13 @@
 		/* disable non-functional volume control */
 		master_bits &= ~UAC_CONTROL_BIT(UAC_FU_VOLUME);
 		break;
+	case USB_ID(0x1130, 0xf211):
+		snd_printk(KERN_INFO
+			   "usbmixer: volume control quirk for Tenx TP6911 Audio Headset\n");
+		/* disable non-functional volume control */
+		channels = 0;
+		break;
+
 	}
 	if (channels > 0)
 		first_ch_bits = snd_usb_combine_bytes(bmaControls + csize, csize);
diff -druN linux-libre-3.5.6-gnu/sound/usb/quirks-table.h linux-libre-3.5.7-gnu/sound/usb/quirks-table.h
--- linux-libre-3.5.6-gnu/sound/usb/quirks-table.h	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/sound/usb/quirks-table.h	2012-10-12 16:48:25.000000000 -0400
@@ -2781,6 +2781,59 @@
 	}
 },
 
+/* Microsoft XboxLive Headset/Xbox Communicator */
+{
+	USB_DEVICE(0x045e, 0x0283),
+	.bInterfaceClass = USB_CLASS_PER_INTERFACE,
+	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+		.vendor_name = "Microsoft",
+		.product_name = "XboxLive Headset/Xbox Communicator",
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = &(const struct snd_usb_audio_quirk[]) {
+			{
+				/* playback */
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S16_LE,
+					.channels = 1,
+					.iface = 0,
+					.altsetting = 0,
+					.altset_idx = 0,
+					.attributes = 0,
+					.endpoint = 0x04,
+					.ep_attr = 0x05,
+					.rates = SNDRV_PCM_RATE_CONTINUOUS,
+					.rate_min = 22050,
+					.rate_max = 22050
+				}
+			},
+			{
+				/* capture */
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S16_LE,
+					.channels = 1,
+					.iface = 1,
+					.altsetting = 0,
+					.altset_idx = 0,
+					.attributes = 0,
+					.endpoint = 0x85,
+					.ep_attr = 0x05,
+					.rates = SNDRV_PCM_RATE_CONTINUOUS,
+					.rate_min = 16000,
+					.rate_max = 16000
+				}
+			},
+			{
+				.ifnum = -1
+			}
+		}
+	}
+},
+
 {
 	/*
 	 * Some USB MIDI devices don't have an audio control interface,
diff -druN linux-libre-3.5.6-gnu/tools/lguest/lguest.c linux-libre-3.5.7-gnu/tools/lguest/lguest.c
--- linux-libre-3.5.6-gnu/tools/lguest/lguest.c	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/tools/lguest/lguest.c	2012-10-12 16:48:25.000000000 -0400
@@ -1299,6 +1299,7 @@
 	dev->feature_len = 0;
 	dev->num_vq = 0;
 	dev->running = false;
+	dev->next = NULL;
 
 	/*
 	 * Append to device list.  Prepending to a single-linked list is
diff -druN linux-libre-3.5.6-gnu/tools/perf/Makefile linux-libre-3.5.7-gnu/tools/perf/Makefile
--- linux-libre-3.5.6-gnu/tools/perf/Makefile	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/tools/perf/Makefile	2012-10-12 16:48:25.000000000 -0400
@@ -62,7 +62,7 @@
 	ARCH := x86
 	IS_X86_64 := 0
 	ifeq (, $(findstring m32,$(EXTRA_CFLAGS)))
-		IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1)
+		IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
 	endif
 	ifeq (${IS_X86_64}, 1)
 		RAW_ARCH := x86_64
diff -druN linux-libre-3.5.6-gnu/tools/power/cpupower/Makefile linux-libre-3.5.7-gnu/tools/power/cpupower/Makefile
--- linux-libre-3.5.6-gnu/tools/power/cpupower/Makefile	2012-10-07 11:36:20.000000000 -0400
+++ linux-libre-3.5.7-gnu/tools/power/cpupower/Makefile	2012-10-12 16:48:25.000000000 -0400
@@ -111,7 +111,7 @@
 export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS
 
 # check if compiler option is supported
-cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;}
+cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -x c /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;}
 
 # use '-Os' optimization if available, else use -O2
 OPTIMIZATION := $(call cc-supports,-Os,-O2)
