diff -druN linux-2.6.27.59-libre5/arch/alpha/kernel/osf_sys.c linux-2.6.27.61-libre5/arch/alpha/kernel/osf_sys.c
--- linux-2.6.27.59-libre5/arch/alpha/kernel/osf_sys.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/alpha/kernel/osf_sys.c	2012-02-12 15:40:04.000000000 -0500
@@ -451,7 +451,7 @@
 		return -EFAULT;
 
 	len = namelen;
-	if (namelen > 32)
+	if (len > 32)
 		len = 32;
 
 	down_read(&uts_sem);
@@ -639,7 +639,7 @@
 	down_read(&uts_sem);
 	res = sysinfo_table[offset];
 	len = strlen(res)+1;
-	if (len > count)
+	if ((unsigned long)len > (unsigned long)count)
 		len = count;
 	if (copy_to_user(buf, res, len))
 		err = -EFAULT;
@@ -695,7 +695,7 @@
 		return 1;
 
 	case GSI_GET_HWRPB:
-		if (nbytes < sizeof(*hwrpb))
+		if (nbytes > sizeof(*hwrpb))
 			return -EINVAL;
 		if (copy_to_user(buffer, hwrpb, nbytes) != 0)
 			return -EFAULT;
@@ -1061,6 +1061,7 @@
 {
 	struct rusage r;
 	long ret, err;
+	unsigned int status = 0;
 	mm_segment_t old_fs;
 
 	if (!ur)
@@ -1069,13 +1070,15 @@
 	old_fs = get_fs();
 		
 	set_fs (KERNEL_DS);
-	ret = sys_wait4(pid, ustatus, options, (struct rusage __user *) &r);
+	ret = sys_wait4(pid, (unsigned int __user *) &status, options,
+			(struct rusage __user *) &r);
 	set_fs (old_fs);
 
 	if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
 		return -EFAULT;
 
 	err = 0;
+	err |= put_user(status, ustatus);
 	err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
 	err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
 	err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
diff -druN linux-2.6.27.59-libre5/arch/arm/kernel/sys_oabi-compat.c linux-2.6.27.61-libre5/arch/arm/kernel/sys_oabi-compat.c
--- linux-2.6.27.59-libre5/arch/arm/kernel/sys_oabi-compat.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/arm/kernel/sys_oabi-compat.c	2012-02-12 15:40:04.000000000 -0500
@@ -319,7 +319,7 @@
 	long err;
 	int i;
 
-	if (nsops < 1)
+	if (nsops < 1 || nsops > SEMOPM)
 		return -EINVAL;
 	sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
 	if (!sops)
diff -druN linux-2.6.27.59-libre5/arch/parisc/mm/init.c linux-2.6.27.61-libre5/arch/parisc/mm/init.c
--- linux-2.6.27.59-libre5/arch/parisc/mm/init.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/parisc/mm/init.c	2012-02-12 15:40:04.000000000 -0500
@@ -265,8 +265,10 @@
 	}
 	memset(pfnnid_map, 0xff, sizeof(pfnnid_map));
 
-	for (i = 0; i < npmem_ranges; i++)
+	for (i = 0; i < npmem_ranges; i++) {
+		node_set_state(i, N_NORMAL_MEMORY);
 		node_set_online(i);
+	}
 #endif
 
 	/*
diff -druN linux-2.6.27.59-libre5/arch/powerpc/kernel/crash.c linux-2.6.27.61-libre5/arch/powerpc/kernel/crash.c
--- linux-2.6.27.59-libre5/arch/powerpc/kernel/crash.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/powerpc/kernel/crash.c	2012-02-12 15:40:04.000000000 -0500
@@ -176,12 +176,8 @@
 
 		while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) {
 			barrier();
-			if (!cpu_possible(i)) {
-				break;
-			}
-			if (!cpu_online(i)) {
+			if (!cpu_possible(i) || !cpu_online(i) || (msecs <= 0))
 				break;
-			}
 			msecs--;
 			mdelay(1);
 		}
diff -druN linux-2.6.27.59-libre5/arch/powerpc/kernel/prom_init.c linux-2.6.27.61-libre5/arch/powerpc/kernel/prom_init.c
--- linux-2.6.27.59-libre5/arch/powerpc/kernel/prom_init.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/powerpc/kernel/prom_init.c	2012-02-12 15:40:04.000000000 -0500
@@ -880,7 +880,7 @@
 	}
 	if (addr == 0)
 		return 0;
-	RELOC(alloc_bottom) = addr;
+	RELOC(alloc_bottom) = addr + size;
 
 	prom_debug(" -> %x\n", addr);
 	prom_debug("  alloc_bottom : %x\n", RELOC(alloc_bottom));
@@ -1680,7 +1680,7 @@
 		chunk = alloc_up(room, 0);
 		if (chunk == 0)
 			prom_panic("No memory for flatten_device_tree (claim failed)");
-		*mem_end = RELOC(alloc_top);
+		*mem_end = chunk + room;
 	}
 
 	ret = (void *)*mem_start;
@@ -1899,7 +1899,7 @@
 	mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
 	if (mem_start == 0)
 		prom_panic("Can't allocate initial device-tree chunk\n");
-	mem_end = RELOC(alloc_top);
+	mem_end = mem_start + room;
 
 	/* Get root of tree */
 	root = call_prom("peer", 1, 1, (phandle)0);
diff -druN linux-2.6.27.59-libre5/arch/powerpc/oprofile/op_model_power4.c linux-2.6.27.61-libre5/arch/powerpc/oprofile/op_model_power4.c
--- linux-2.6.27.59-libre5/arch/powerpc/oprofile/op_model_power4.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/powerpc/oprofile/op_model_power4.c	2012-02-12 15:40:04.000000000 -0500
@@ -254,6 +254,28 @@
 	return is_kernel;
 }
 
+static bool pmc_overflow(unsigned long val)
+{
+	if ((int)val < 0)
+		return true;
+
+	/*
+	 * Events on POWER7 can roll back if a speculative event doesn't
+	 * eventually complete. Unfortunately in some rare cases they will
+	 * raise a performance monitor exception. We need to catch this to
+	 * ensure we reset the PMC. In all cases the PMC will be 256 or less
+	 * cycles from overflow.
+	 *
+	 * We only do this if the first pass fails to find any overflowing
+	 * PMCs because a user might set a period of less than 256 and we
+	 * don't want to mistakenly reset them.
+	 */
+	if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256))
+		return true;
+
+	return false;
+}
+
 static void power4_handle_interrupt(struct pt_regs *regs,
 				    struct op_counter_config *ctr)
 {
@@ -274,7 +296,7 @@
 
 	for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {
 		val = classic_ctr_read(i);
-		if (val < 0) {
+		if (pmc_overflow(val)) {
 			if (oprofile_running && ctr[i].enabled) {
 				oprofile_add_ext_sample(pc, regs, i, is_kernel);
 				classic_ctr_write(i, reset_value[i]);
diff -druN linux-2.6.27.59-libre5/arch/powerpc/platforms/pseries/hvconsole.c linux-2.6.27.61-libre5/arch/powerpc/platforms/pseries/hvconsole.c
--- linux-2.6.27.59-libre5/arch/powerpc/platforms/pseries/hvconsole.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/powerpc/platforms/pseries/hvconsole.c	2012-02-12 15:40:04.000000000 -0500
@@ -73,7 +73,7 @@
 	if (ret == H_SUCCESS)
 		return count;
 	if (ret == H_BUSY)
-		return 0;
+		return -EAGAIN;
 	return -EIO;
 }
 
diff -druN linux-2.6.27.59-libre5/arch/powerpc/platforms/pseries/lpar.c linux-2.6.27.61-libre5/arch/powerpc/platforms/pseries/lpar.c
--- linux-2.6.27.59-libre5/arch/powerpc/platforms/pseries/lpar.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/powerpc/platforms/pseries/lpar.c	2012-02-12 15:40:04.000000000 -0500
@@ -371,7 +371,7 @@
 		unsigned long ptel;
 	} ptes[4];
 	long lpar_rc;
-	int i, j;
+	unsigned long i, j;
 
 	/* Read in batches of 4,
 	 * invalidate only valid entries not in the VRMA
diff -druN linux-2.6.27.59-libre5/arch/s390/kvm/kvm-s390.c linux-2.6.27.61-libre5/arch/s390/kvm/kvm-s390.c
--- linux-2.6.27.59-libre5/arch/s390/kvm/kvm-s390.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/s390/kvm/kvm-s390.c	2012-02-12 15:40:04.000000000 -0500
@@ -274,11 +274,17 @@
 struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
 				      unsigned int id)
 {
-	struct kvm_vcpu *vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
-	int rc = -ENOMEM;
+	struct kvm_vcpu *vcpu;
+	int rc = -EINVAL;
+
+	if (id >= KVM_MAX_VCPUS)
+		goto out;
 
+	rc = -ENOMEM;
+
+	vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
 	if (!vcpu)
-		goto out_nomem;
+		goto out;
 
 	vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
 					get_zeroed_page(GFP_KERNEL);
@@ -313,7 +319,7 @@
 	return vcpu;
 out_free_cpu:
 	kfree(vcpu);
-out_nomem:
+out:
 	return ERR_PTR(rc);
 }
 
diff -druN linux-2.6.27.59-libre5/arch/um/drivers/ubd_kern.c linux-2.6.27.61-libre5/arch/um/drivers/ubd_kern.c
--- linux-2.6.27.59-libre5/arch/um/drivers/ubd_kern.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/um/drivers/ubd_kern.c	2012-02-12 15:40:04.000000000 -0500
@@ -529,8 +529,37 @@
 static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
 {
 	char *file;
+	int fd;
+	int err;
 
-	file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
+	__u32 version;
+	__u32 align;
+	char *backing_file;
+	time_t mtime;
+	unsigned long long size;
+	int sector_size;
+	int bitmap_offset;
+
+	if (ubd_dev->file && ubd_dev->cow.file) {
+		file = ubd_dev->cow.file;
+
+		goto out;
+	}
+
+	fd = os_open_file(ubd_dev->file, global_openflags, 0);
+	if (fd < 0)
+		return fd;
+
+	err = read_cow_header(file_reader, &fd, &version, &backing_file, \
+		&mtime, &size, &sector_size, &align, &bitmap_offset);
+	os_close_file(fd);
+
+	if(err == -EINVAL)
+		file = ubd_dev->file;
+	else
+		file = backing_file;
+
+out:
 	return os_file_size(file, size_out);
 }
 
diff -druN linux-2.6.27.59-libre5/arch/x86/kernel/amd_iommu_init.c linux-2.6.27.61-libre5/arch/x86/kernel/amd_iommu_init.c
--- linux-2.6.27.59-libre5/arch/x86/kernel/amd_iommu_init.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/x86/kernel/amd_iommu_init.c	2012-02-12 15:40:04.000000000 -0500
@@ -538,8 +538,8 @@
 {
 	u8 *p = (u8 *)h;
 	u8 *end = p, flags = 0;
-	u16 dev_i, devid = 0, devid_start = 0, devid_to = 0;
-	u32 ext_flags = 0;
+	u16 devid = 0, devid_start = 0, devid_to = 0;
+	u32 dev_i, ext_flags = 0;
 	bool alias = false;
 	struct ivhd_entry *e;
 
@@ -638,7 +638,7 @@
 /* Initializes the device->iommu mapping for the driver */
 static int __init init_iommu_devices(struct amd_iommu *iommu)
 {
-	u16 i;
+	u32 i;
 
 	for (i = iommu->first_device; i <= iommu->last_device; ++i)
 		set_iommu_for_device(iommu, i);
@@ -833,7 +833,7 @@
  */
 static void init_device_table(void)
 {
-	u16 devid;
+	u32 devid;
 
 	for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) {
 		set_dev_entry_bit(devid, DEV_ENTRY_VALID);
diff -druN linux-2.6.27.59-libre5/arch/x86/lib/copy_user_64.S linux-2.6.27.61-libre5/arch/x86/lib/copy_user_64.S
--- linux-2.6.27.59-libre5/arch/x86/lib/copy_user_64.S	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/x86/lib/copy_user_64.S	2012-02-12 15:40:04.000000000 -0500
@@ -72,7 +72,7 @@
 	addq %rdx,%rcx
 	jc bad_to_user
 	cmpq TI_addr_limit(%rax),%rcx
-	jae bad_to_user
+	ja bad_to_user
 	ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
 	CFI_ENDPROC
 
@@ -84,7 +84,7 @@
 	addq %rdx,%rcx
 	jc bad_from_user
 	cmpq TI_addr_limit(%rax),%rcx
-	jae bad_from_user
+	ja bad_from_user
 	ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
 	CFI_ENDPROC
 ENDPROC(copy_from_user)
diff -druN linux-2.6.27.59-libre5/arch/x86/mm/gup.c linux-2.6.27.61-libre5/arch/x86/mm/gup.c
--- linux-2.6.27.59-libre5/arch/x86/mm/gup.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/x86/mm/gup.c	2012-02-12 15:40:04.000000000 -0500
@@ -219,6 +219,62 @@
 	return 1;
 }
 
+/*
+ * Like get_user_pages_fast() except its IRQ-safe in that it won't fall
+ * back to the regular GUP.
+ */
+int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
+			  struct page **pages)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long addr, len, end;
+	unsigned long next;
+	unsigned long flags;
+	pgd_t *pgdp;
+	int nr = 0;
+
+	start &= PAGE_MASK;
+	addr = start;
+	len = (unsigned long) nr_pages << PAGE_SHIFT;
+	end = start + len;
+	if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
+					(void __user *)start, len)))
+		return 0;
+
+	/*
+	 * XXX: batch / limit 'nr', to avoid large irq off latency
+	 * needs some instrumenting to determine the common sizes used by
+	 * important workloads (eg. DB2), and whether limiting the batch size
+	 * will decrease performance.
+	 *
+	 * It seems like we're in the clear for the moment. Direct-IO is
+	 * the main guy that batches up lots of get_user_pages, and even
+	 * they are limited to 64-at-a-time which is not so many.
+	 */
+	/*
+	 * This doesn't prevent pagetable teardown, but does prevent
+	 * the pagetables and pages from being freed on x86.
+	 *
+	 * So long as we atomically load page table pointers versus teardown
+	 * (which we do on x86, with the above PAE exception), we can follow the
+	 * address down to the the page and take a ref on it.
+	 */
+	local_irq_save(flags);
+	pgdp = pgd_offset(mm, addr);
+	do {
+		pgd_t pgd = *pgdp;
+
+		next = pgd_addr_end(addr, end);
+		if (pgd_none(pgd))
+			break;
+		if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
+			break;
+	} while (pgdp++, addr = next, addr != end);
+	local_irq_restore(flags);
+
+	return nr;
+}
+
 int get_user_pages_fast(unsigned long start, int nr_pages, int write,
 			struct page **pages)
 {
diff -druN linux-2.6.27.59-libre5/arch/x86/mm/mmap.c linux-2.6.27.61-libre5/arch/x86/mm/mmap.c
--- linux-2.6.27.59-libre5/arch/x86/mm/mmap.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/x86/mm/mmap.c	2012-02-12 15:40:04.000000000 -0500
@@ -87,9 +87,9 @@
 	*/
 	if (current->flags & PF_RANDOMIZE) {
 		if (mmap_is_ia32())
-			rnd = (long)get_random_int() % (1<<8);
+			rnd = get_random_int() % (1<<8);
 		else
-			rnd = (long)(get_random_int() % (1<<28));
+			rnd = get_random_int() % (1<<28);
 	}
 	return rnd << PAGE_SHIFT;
 }
diff -druN linux-2.6.27.59-libre5/arch/x86/oprofile/backtrace.c linux-2.6.27.61-libre5/arch/x86/oprofile/backtrace.c
--- linux-2.6.27.59-libre5/arch/x86/oprofile/backtrace.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/x86/oprofile/backtrace.c	2012-02-12 15:40:04.000000000 -0500
@@ -11,6 +11,8 @@
 #include <linux/oprofile.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/highmem.h>
+
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
 #include <asm/stacktrace.h>
@@ -47,6 +49,42 @@
 	.address = backtrace_address,
 };
 
+/* from arch/x86/kernel/cpu/perf_event.c: */
+
+/*
+ * best effort, GUP based copy_from_user() that assumes IRQ or NMI context
+ */
+static unsigned long
+copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
+{
+	unsigned long offset, addr = (unsigned long)from;
+	unsigned long size, len = 0;
+	struct page *page;
+	void *map;
+	int ret;
+
+	do {
+		ret = __get_user_pages_fast(addr, 1, 0, &page);
+		if (!ret)
+			break;
+
+		offset = addr & (PAGE_SIZE - 1);
+		size = min(PAGE_SIZE - offset, n - len);
+
+		map = kmap_atomic(page, KM_USER0);
+		memcpy(to, map+offset, size);
+		kunmap_atomic(map, KM_USER0);
+		put_page(page);
+
+		len  += size;
+		to   += size;
+		addr += size;
+
+	} while (len < n);
+
+	return len;
+}
+
 struct frame_head {
 	struct frame_head *bp;
 	unsigned long ret;
@@ -55,12 +93,12 @@
 static struct frame_head *
 dump_user_backtrace(struct frame_head * head)
 {
+	/* Also check accessibility of one struct frame_head beyond: */
 	struct frame_head bufhead[2];
+	unsigned long bytes;
 
-	/* Also check accessibility of one struct frame_head beyond */
-	if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
-		return NULL;
-	if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
+	bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead));
+	if (bytes != sizeof(bufhead))
 		return NULL;
 
 	oprofile_add_trace(bufhead[0].ret);
diff -druN linux-2.6.27.59-libre5/arch/x86/oprofile/init.c linux-2.6.27.61-libre5/arch/x86/oprofile/init.c
--- linux-2.6.27.59-libre5/arch/x86/oprofile/init.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/arch/x86/oprofile/init.c	2012-02-12 15:40:04.000000000 -0500
@@ -21,6 +21,7 @@
 extern void op_nmi_exit(void);
 extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth);
 
+static int nmi_timer;
 
 int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
@@ -31,8 +32,9 @@
 #ifdef CONFIG_X86_LOCAL_APIC
 	ret = op_nmi_init(ops);
 #endif
+	nmi_timer = (ret != 0);
 #ifdef CONFIG_X86_IO_APIC
-	if (ret < 0)
+	if (nmi_timer)
 		ret = op_nmi_timer_init(ops);
 #endif
 	ops->backtrace = x86_backtrace;
@@ -44,6 +46,7 @@
 void oprofile_arch_exit(void)
 {
 #ifdef CONFIG_X86_LOCAL_APIC
-	op_nmi_exit();
+	if (!nmi_timer)
+		op_nmi_exit();
 #endif
 }
diff -druN linux-2.6.27.59-libre5/block/cfq-iosched.c linux-2.6.27.61-libre5/block/cfq-iosched.c
--- linux-2.6.27.59-libre5/block/cfq-iosched.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/block/cfq-iosched.c	2012-02-12 15:40:04.000000000 -0500
@@ -1286,8 +1286,14 @@
 	cic->dead_key = (unsigned long) cic->key;
 	cic->key = NULL;
 
-	if (ioc->ioc_data == cic)
+	rcu_read_lock();
+	if (rcu_dereference(ioc->ioc_data) == cic) {
+		rcu_read_unlock();
+		spin_lock(&ioc->lock);
 		rcu_assign_pointer(ioc->ioc_data, NULL);
+		spin_unlock(&ioc->lock);
+	} else
+		rcu_read_unlock();
 
 	if (cic->cfqq[ASYNC]) {
 		cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]);
diff -druN linux-2.6.27.59-libre5/block/elevator.c linux-2.6.27.61-libre5/block/elevator.c
--- linux-2.6.27.59-libre5/block/elevator.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/block/elevator.c	2012-02-12 15:40:04.000000000 -0500
@@ -729,7 +729,8 @@
 				return rq;
 		}
 
-		if (!q->elevator->ops->elevator_dispatch_fn(q, 0))
+		if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags) ||
+		    !q->elevator->ops->elevator_dispatch_fn(q, 0))
 			return NULL;
 	}
 }
diff -druN linux-2.6.27.59-libre5/block/scsi_ioctl.c linux-2.6.27.61-libre5/block/scsi_ioctl.c
--- linux-2.6.27.59-libre5/block/scsi_ioctl.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/block/scsi_ioctl.c	2012-02-12 15:40:04.000000000 -0500
@@ -653,3 +653,57 @@
 }
 
 EXPORT_SYMBOL(scsi_cmd_ioctl);
+
+int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd)
+{
+	if (bd && bd == bd->bd_contains)
+		return 0;
+
+	/* Actually none of these is particularly useful on a partition,
+	 * but they are safe.
+	 */
+	switch (cmd) {
+	case SCSI_IOCTL_GET_IDLUN:
+	case SCSI_IOCTL_GET_BUS_NUMBER:
+	case SCSI_IOCTL_GET_PCI:
+	case SCSI_IOCTL_PROBE_HOST:
+	case SG_GET_VERSION_NUM:
+	case SG_SET_TIMEOUT:
+	case SG_GET_TIMEOUT:
+	case SG_GET_RESERVED_SIZE:
+	case SG_SET_RESERVED_SIZE:
+	case SG_EMULATED_HOST:
+		return 0;
+	case CDROM_GET_CAPABILITY:
+		/* Keep this until we remove the printk below.  udev sends it
+		 * and we do not want to spam dmesg about it.   CD-ROMs do
+		 * not have partitions, so we get here only for disks.
+		 */
+		return -ENOTTY;
+	default:
+		break;
+	}
+
+	/* In particular, rule out all resets and host-specific ioctls.  */
+	if (printk_ratelimit())
+		printk(KERN_WARNING
+			   "%s: sending ioctl %x to a partition!\n", current->comm, cmd);
+
+	return capable(CAP_SYS_RAWIO) ? 0 : -ENOTTY;
+}
+EXPORT_SYMBOL(scsi_verify_blk_ioctl);
+
+
+int scsi_cmd_blk_ioctl(struct file *file, struct block_device *bd,
+                       unsigned int cmd, void __user *arg)
+{
+	int ret;
+
+	ret = scsi_verify_blk_ioctl(bd, cmd);
+	if (ret < 0)
+		return ret;
+
+	return scsi_cmd_ioctl(file, bd->bd_disk->queue, bd->bd_disk, cmd, arg);
+}
+EXPORT_SYMBOL(scsi_cmd_blk_ioctl);
+
diff -druN linux-2.6.27.59-libre5/Documentation/kbuild/makefiles.txt linux-2.6.27.61-libre5/Documentation/kbuild/makefiles.txt
--- linux-2.6.27.59-libre5/Documentation/kbuild/makefiles.txt	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/Documentation/kbuild/makefiles.txt	2012-02-12 15:40:04.000000000 -0500
@@ -471,6 +471,18 @@
 	gcc >= 3.00. For gcc < 3.00, -malign-functions=4 is used.
 	Note: cc-option-align uses KBUILD_CFLAGS for $(CC) options
 
+    cc-disable-warning
+	cc-disable-warning checks if gcc supports a given warning and returns
+	the commandline switch to disable it. This special function is needed,
+	because gcc 4.4 and later accept any unknown -Wno-* option and only
+	warn about it if there is another warning in the source file.
+
+	Example:
+		KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
+
+	In the above example, -Wno-unused-but-set-variable will be added to
+	KBUILD_CFLAGS only if gcc really accepts it.
+
     cc-version
 	cc-version returns a numerical version of the $(CC) compiler version.
 	The format is <major><minor> where both are two digits. So for example
diff -druN linux-2.6.27.59-libre5/drivers/ata/libata-scsi.c linux-2.6.27.61-libre5/drivers/ata/libata-scsi.c
--- linux-2.6.27.59-libre5/drivers/ata/libata-scsi.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/ata/libata-scsi.c	2012-02-12 15:40:04.000000000 -0500
@@ -957,13 +957,13 @@
 	/* configure max sectors */
 	blk_queue_max_sectors(sdev->request_queue, dev->max_sectors);
 
+	sdev->sector_size = ATA_SECT_SIZE;
+
 	if (dev->class == ATA_DEV_ATAPI) {
 		struct request_queue *q = sdev->request_queue;
 		void *buf;
 
-		/* set the min alignment and padding */
-		blk_queue_update_dma_alignment(sdev->request_queue,
-					       ATA_DMA_PAD_SZ - 1);
+		/* set DMA padding */
 		blk_queue_update_dma_pad(sdev->request_queue,
 					 ATA_DMA_PAD_SZ - 1);
 
@@ -977,12 +977,24 @@
 
 		blk_queue_dma_drain(q, atapi_drain_needed, buf, ATAPI_MAX_DRAIN);
 	} else {
-		/* ATA devices must be sector aligned */
-		blk_queue_update_dma_alignment(sdev->request_queue,
-					       ATA_SECT_SIZE - 1);
 		sdev->manage_start_stop = 1;
 	}
 
+	/*
+	 * ata_pio_sectors() expects buffer for each sector to not cross
+	 * page boundary.  Enforce it by requiring buffers to be sector
+	 * aligned, which works iff sector_size is not larger than
+	 * PAGE_SIZE.  ATAPI devices also need the alignment as
+	 * IDENTIFY_PACKET is executed as ATA_PROT_PIO.
+	 */
+	if (sdev->sector_size > PAGE_SIZE)
+		ata_dev_printk(dev, KERN_WARNING,
+			"sector_size=%u > PAGE_SIZE, PIO may malfunction\n",
+			sdev->sector_size);
+
+	blk_queue_update_dma_alignment(sdev->request_queue,
+				       sdev->sector_size - 1);
+
 	if (dev->flags & ATA_DFLAG_AN)
 		set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events);
 
diff -druN linux-2.6.27.59-libre5/drivers/ata/sata_via.c linux-2.6.27.61-libre5/drivers/ata/sata_via.c
--- linux-2.6.27.59-libre5/drivers/ata/sata_via.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/ata/sata_via.c	2012-02-12 15:40:04.000000000 -0500
@@ -40,6 +40,8 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 
@@ -72,6 +74,7 @@
 static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
 static void svia_noop_freeze(struct ata_port *ap);
 static int vt6420_prereset(struct ata_link *link, unsigned long deadline);
+static void vt6420_bmdma_start(struct ata_queued_cmd *qc);
 static int vt6421_pata_cable_detect(struct ata_port *ap);
 static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev);
 static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev);
@@ -107,6 +110,7 @@
 	.inherits		= &ata_bmdma_port_ops,
 	.freeze			= svia_noop_freeze,
 	.prereset		= vt6420_prereset,
+	.bmdma_start		= vt6420_bmdma_start,
 };
 
 static struct ata_port_operations vt6421_pata_ops = {
@@ -247,6 +251,17 @@
 	return 0;
 }
 
+static void vt6420_bmdma_start(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	if ((qc->tf.command == ATA_CMD_PACKET) &&
+	    (qc->scsicmd->sc_data_direction == DMA_TO_DEVICE)) {
+		/* Prevents corruption on some ATAPI burners */
+		ata_sff_pause(ap);
+	}
+	ata_bmdma_start(qc);
+}
+
 static int vt6421_pata_cable_detect(struct ata_port *ap)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
diff -druN linux-2.6.27.59-libre5/drivers/block/cciss.c linux-2.6.27.61-libre5/drivers/block/cciss.c
--- linux-2.6.27.59-libre5/drivers/block/cciss.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/block/cciss.c	2012-02-12 15:40:04.000000000 -0500
@@ -1225,7 +1225,7 @@
 			return status;
 		}
 
-	/* scsi_cmd_ioctl handles these, below, though some are not */
+	/* scsi_cmd_blk_ioctl handles these, below, though some are not */
 	/* very meaningful for cciss.  SG_IO is the main one people want. */
 
 	case SG_GET_VERSION_NUM:
@@ -1236,9 +1236,9 @@
 	case SG_EMULATED_HOST:
 	case SG_IO:
 	case SCSI_IOCTL_SEND_COMMAND:
-		return scsi_cmd_ioctl(filep, disk->queue, disk, cmd, argp);
+		return scsi_cmd_blk_ioctl(filep, bdev, cmd, argp);
 
-	/* scsi_cmd_ioctl would normally handle these, below, but */
+	/* scsi_cmd_blk_ioctl would normally handle these, below, but */
 	/* they aren't a good fit for cciss, as CD-ROMs are */
 	/* not supported, and we don't have any bus/target/lun */
 	/* which we present to the kernel. */
diff -druN linux-2.6.27.59-libre5/drivers/block/ub.c linux-2.6.27.61-libre5/drivers/block/ub.c
--- linux-2.6.27.59-libre5/drivers/block/ub.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/block/ub.c	2012-02-12 15:40:04.000000000 -0500
@@ -1729,10 +1729,9 @@
 static int ub_bd_ioctl(struct inode *inode, struct file *filp,
     unsigned int cmd, unsigned long arg)
 {
-	struct gendisk *disk = inode->i_bdev->bd_disk;
 	void __user *usermem = (void __user *) arg;
 
-	return scsi_cmd_ioctl(filp, disk->queue, disk, cmd, usermem);
+	return scsi_cmd_blk_ioctl(filp, inode->i_bdev, cmd, usermem);
 }
 
 /*
diff -druN linux-2.6.27.59-libre5/drivers/block/virtio_blk.c linux-2.6.27.61-libre5/drivers/block/virtio_blk.c
--- linux-2.6.27.59-libre5/drivers/block/virtio_blk.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/block/virtio_blk.c	2012-02-12 15:40:04.000000000 -0500
@@ -149,8 +149,7 @@
 static int virtblk_ioctl(struct inode *inode, struct file *filp,
 			 unsigned cmd, unsigned long data)
 {
-	return scsi_cmd_ioctl(filp, inode->i_bdev->bd_disk->queue,
-			      inode->i_bdev->bd_disk, cmd,
+	return scsi_cmd_blk_ioctl(filp, inode->i_bdev, cmd,
 			      (void __user *)data);
 }
 
diff -druN linux-2.6.27.59-libre5/drivers/cdrom/cdrom.c linux-2.6.27.61-libre5/drivers/cdrom/cdrom.c
--- linux-2.6.27.59-libre5/drivers/cdrom/cdrom.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/cdrom/cdrom.c	2012-02-12 15:40:04.000000000 -0500
@@ -2667,12 +2667,11 @@
 {
 	void __user *argp = (void __user *)arg;
 	int ret;
-	struct gendisk *disk = ip->i_bdev->bd_disk;
 
 	/*
 	 * Try the generic SCSI command ioctl's first.
 	 */
-	ret = scsi_cmd_ioctl(file, disk->queue, disk, cmd, argp);
+	ret = scsi_cmd_blk_ioctl(file, ip->i_bdev, cmd, argp);
 	if (ret != -ENOTTY)
 		return ret;
 
diff -druN linux-2.6.27.59-libre5/drivers/char/agp/generic.c linux-2.6.27.61-libre5/drivers/char/agp/generic.c
--- linux-2.6.27.59-libre5/drivers/char/agp/generic.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/char/agp/generic.c	2012-02-12 15:40:04.000000000 -0500
@@ -123,6 +123,9 @@
 	struct agp_memory *new;
 	unsigned long alloc_size = num_agp_pages*sizeof(struct page *);
 
+	if (INT_MAX/sizeof(struct page *) < num_agp_pages)
+		return NULL;
+
 	new = kzalloc(sizeof(struct agp_memory), GFP_KERNEL);
 	if (new == NULL)
 		return NULL;
@@ -236,11 +239,14 @@
 	int scratch_pages;
 	struct agp_memory *new;
 	size_t i;
+	int cur_memory;
 
 	if (!bridge)
 		return NULL;
 
-	if ((atomic_read(&bridge->current_memory_agp) + page_count) > bridge->max_memory_agp)
+	cur_memory = atomic_read(&bridge->current_memory_agp);
+	if ((cur_memory + page_count > bridge->max_memory_agp) ||
+	    (cur_memory + page_count < page_count))
 		return NULL;
 
 	if (type >= AGP_USER_TYPES) {
@@ -1099,8 +1105,8 @@
 		return -EINVAL;
 	}
 
-	/* AK: could wrap */
-	if ((pg_start + mem->page_count) > num_entries)
+	if (((pg_start + mem->page_count) > num_entries) ||
+	    ((pg_start + mem->page_count) < pg_start))
 		return -EINVAL;
 
 	j = pg_start;
@@ -1132,7 +1138,7 @@
 {
 	size_t i;
 	struct agp_bridge_data *bridge;
-	int mask_type;
+	int mask_type, num_entries;
 
 	bridge = mem->bridge;
 	if (!bridge)
@@ -1144,6 +1150,11 @@
 	if (type != mem->type)
 		return -EINVAL;
 
+	num_entries = agp_num_entries();
+	if (((pg_start + mem->page_count) > num_entries) ||
+	    ((pg_start + mem->page_count) < pg_start))
+		return -EINVAL;
+
 	mask_type = bridge->driver->agp_type_to_mask_type(bridge, type);
 	if (mask_type != 0) {
 		/* The generic routines know nothing of memory types */
diff -druN linux-2.6.27.59-libre5/drivers/char/i8k.c linux-2.6.27.61-libre5/drivers/char/i8k.c
--- linux-2.6.27.59-libre5/drivers/char/i8k.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/char/i8k.c	2012-02-12 15:40:04.000000000 -0500
@@ -119,7 +119,7 @@
 	int eax = regs->eax;
 
 #if defined(CONFIG_X86_64)
-	asm("pushq %%rax\n\t"
+	asm volatile("pushq %%rax\n\t"
 		"movl 0(%%rax),%%edx\n\t"
 		"pushq %%rdx\n\t"
 		"movl 4(%%rax),%%ebx\n\t"
@@ -138,14 +138,14 @@
 		"movl %%edi,20(%%rax)\n\t"
 		"popq %%rdx\n\t"
 		"movl %%edx,0(%%rax)\n\t"
-		"lahf\n\t"
-		"shrl $8,%%eax\n\t"
+		"pushfq\n\t"
+		"popq %%rax\n\t"
 		"andl $1,%%eax\n"
 		:"=a"(rc)
 		:    "a"(regs)
 		:    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
 #else
-	asm("pushl %%eax\n\t"
+	asm volatile("pushl %%eax\n\t"
 	    "movl 0(%%eax),%%edx\n\t"
 	    "push %%edx\n\t"
 	    "movl 4(%%eax),%%ebx\n\t"
@@ -166,7 +166,8 @@
 	    "movl %%edx,0(%%eax)\n\t"
 	    "lahf\n\t"
 	    "shrl $8,%%eax\n\t"
-	    "andl $1,%%eax\n":"=a"(rc)
+	    "andl $1,%%eax\n"
+	    :"=a"(rc)
 	    :    "a"(regs)
 	    :    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
 #endif
diff -druN linux-2.6.27.59-libre5/drivers/char/tpm/tpm.c linux-2.6.27.61-libre5/drivers/char/tpm/tpm.c
--- linux-2.6.27.59-libre5/drivers/char/tpm/tpm.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/char/tpm/tpm.c	2012-02-12 15:40:04.000000000 -0500
@@ -375,6 +375,9 @@
 	u32 count, ordinal;
 	unsigned long stop;
 
+	if (bufsiz > TPM_BUFSIZE)
+		bufsiz = TPM_BUFSIZE;
+
 	count = be32_to_cpu(*((__be32 *) (buf + 2)));
 	ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
 	if (count == 0)
@@ -1066,6 +1069,7 @@
 {
 	struct tpm_chip *chip = file->private_data;
 	ssize_t ret_size;
+	int rc;
 
 	del_singleshot_timer_sync(&chip->user_read_timer);
 	flush_scheduled_work();
@@ -1076,8 +1080,11 @@
 			ret_size = size;
 
 		mutex_lock(&chip->buffer_mutex);
-		if (copy_to_user(buf, chip->data_buffer, ret_size))
+		rc = copy_to_user(buf, chip->data_buffer, ret_size);
+		memset(chip->data_buffer, 0, ret_size);
+		if (rc)
 			ret_size = -EFAULT;
+
 		mutex_unlock(&chip->buffer_mutex);
 	}
 
diff -druN linux-2.6.27.59-libre5/drivers/ide/ide-floppy.c linux-2.6.27.61-libre5/drivers/ide/ide-floppy.c
--- linux-2.6.27.59-libre5/drivers/ide/ide-floppy.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/ide/ide-floppy.c	2012-02-12 15:40:04.000000000 -0500
@@ -1337,8 +1337,7 @@
 	 * and CDROM_SEND_PACKET (legacy) ioctls
 	 */
 	if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND)
-		err = scsi_cmd_ioctl(file, bdev->bd_disk->queue,
-					bdev->bd_disk, cmd, argp);
+		err = scsi_cmd_blk_ioctl(file, bdev, cmd, argp);
 	else
 		err = -ENOTTY;
 
diff -druN linux-2.6.27.59-libre5/drivers/md/dm-linear.c linux-2.6.27.61-libre5/drivers/md/dm-linear.c
--- linux-2.6.27.59-libre5/drivers/md/dm-linear.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/md/dm-linear.c	2012-02-12 15:40:04.000000000 -0500
@@ -118,12 +118,20 @@
 	struct block_device *bdev = lc->dev->bdev;
 	struct file fake_file = {};
 	struct dentry fake_dentry = {};
+	int r = 0;
 
 	fake_file.f_mode = lc->dev->mode;
 	fake_file.f_path.dentry = &fake_dentry;
 	fake_dentry.d_inode = bdev->bd_inode;
 
-	return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg);
+	/*
+	 * Only pass ioctls through if the device sizes match exactly.
+	 */
+	if (lc->start ||
+	    ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT)
+		r = scsi_verify_blk_ioctl(NULL, cmd);
+
+	return r ? : blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg);
 }
 
 static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
diff -druN linux-2.6.27.59-libre5/drivers/md/dm-mpath.c linux-2.6.27.61-libre5/drivers/md/dm-mpath.c
--- linux-2.6.27.59-libre5/drivers/md/dm-mpath.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/md/dm-mpath.c	2012-02-12 15:40:04.000000000 -0500
@@ -1421,6 +1421,12 @@
 
 	spin_unlock_irqrestore(&m->lock, flags);
 
+	/*
+	 * Only pass ioctls through if the device sizes match exactly.
+	 */
+	if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT)
+		r = scsi_verify_blk_ioctl(NULL, cmd);
+
 	return r ? : blkdev_driver_ioctl(bdev->bd_inode, &fake_file,
 					 bdev->bd_disk, cmd, arg);
 }
diff -druN linux-2.6.27.59-libre5/drivers/md/md.c linux-2.6.27.61-libre5/drivers/md/md.c
--- linux-2.6.27.59-libre5/drivers/md/md.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/md/md.c	2012-02-12 15:40:04.000000000 -0500
@@ -2002,7 +2002,7 @@
 		if (rdev->raid_disk == -1)
 			return -EEXIST;
 		/* personality does all needed checks */
-		if (rdev->mddev->pers->hot_add_disk == NULL)
+		if (rdev->mddev->pers->hot_remove_disk == NULL)
 			return -EINVAL;
 		err = rdev->mddev->pers->
 			hot_remove_disk(rdev->mddev, rdev->raid_disk);
diff -druN linux-2.6.27.59-libre5/drivers/media/video/uvc/uvc_queue.c linux-2.6.27.61-libre5/drivers/media/video/uvc/uvc_queue.c
--- linux-2.6.27.59-libre5/drivers/media/video/uvc/uvc_queue.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/media/video/uvc/uvc_queue.c	2012-02-12 15:40:04.000000000 -0500
@@ -165,6 +165,8 @@
 	}
 
 	if (queue->count) {
+		uvc_queue_cancel(queue, 0);
+		INIT_LIST_HEAD(&queue->mainqueue);
 		vfree(queue->mem);
 		queue->count = 0;
 	}
diff -druN linux-2.6.27.59-libre5/drivers/mmc/host/sdhci.c linux-2.6.27.61-libre5/drivers/mmc/host/sdhci.c
--- linux-2.6.27.59-libre5/drivers/mmc/host/sdhci.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/mmc/host/sdhci.c	2012-02-12 15:40:04.000000000 -0500
@@ -1165,6 +1165,13 @@
 
 	host = (struct sdhci_host*)param;
 
+        /*
+         * If this tasklet gets rescheduled while running, it will
+         * be run again afterwards but without any active request.
+         */
+	if (!host->mrq)
+		return;
+
 	spin_lock_irqsave(&host->lock, flags);
 
 	del_timer(&host->timer);
@@ -1176,7 +1183,7 @@
 	 * upon error conditions.
 	 */
 	if (!(host->flags & SDHCI_DEVICE_DEAD) &&
-		(mrq->cmd->error ||
+	    ((mrq->cmd && mrq->cmd->error) ||
 		 (mrq->data && (mrq->data->error ||
 		  (mrq->data->stop && mrq->data->stop->error))) ||
 		   (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) {
diff -druN linux-2.6.27.59-libre5/drivers/mmc/host/sdhci-pci.c linux-2.6.27.61-libre5/drivers/mmc/host/sdhci-pci.c
--- linux-2.6.27.59-libre5/drivers/mmc/host/sdhci-pci.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/mmc/host/sdhci-pci.c	2012-02-12 15:40:04.000000000 -0500
@@ -547,6 +547,7 @@
 	host->ioaddr = ioremap_nocache(addr, pci_resource_len(pdev, bar));
 	if (!host->ioaddr) {
 		dev_err(&pdev->dev, "failed to remap registers\n");
+		ret = -ENOMEM;
 		goto release;
 	}
 
diff -druN linux-2.6.27.59-libre5/drivers/mtd/ubi/cdev.c linux-2.6.27.61-libre5/drivers/mtd/ubi/cdev.c
--- linux-2.6.27.59-libre5/drivers/mtd/ubi/cdev.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/mtd/ubi/cdev.c	2012-02-12 15:40:04.000000000 -0500
@@ -569,6 +569,9 @@
 	if (req->alignment != 1 && n)
 		goto bad;
 
+	if (!req->name[0] || !req->name_len)
+		goto bad;
+
 	if (req->name_len > UBI_VOL_NAME_MAX) {
 		err = -ENAMETOOLONG;
 		goto bad;
diff -druN linux-2.6.27.59-libre5/drivers/net/bonding/bond_3ad.c linux-2.6.27.61-libre5/drivers/net/bonding/bond_3ad.c
--- linux-2.6.27.59-libre5/drivers/net/bonding/bond_3ad.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/net/bonding/bond_3ad.c	2012-02-12 15:40:04.000000000 -0500
@@ -2436,6 +2436,13 @@
 	if (!(dev->flags & IFF_MASTER))
 		goto out;
 
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (!skb)
+		goto out;
+
+	if (!pskb_may_pull(skb, sizeof(struct lacpdu)))
+		goto out;
+
 	read_lock(&bond->lock);
 	slave = bond_get_slave_by_dev((struct bonding *)dev->priv, orig_dev);
 	if (!slave)
diff -druN linux-2.6.27.59-libre5/drivers/net/bonding/bond_alb.c linux-2.6.27.61-libre5/drivers/net/bonding/bond_alb.c
--- linux-2.6.27.59-libre5/drivers/net/bonding/bond_alb.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/net/bonding/bond_alb.c	2012-02-12 15:40:04.000000000 -0500
@@ -359,6 +359,13 @@
 		goto out;
 	}
 
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (!skb)
+		goto out;
+
+	if (!pskb_may_pull(skb, arp_hdr_len(bond_dev)))
+		goto out;
+
 	if (skb->len < sizeof(struct arp_pkt)) {
 		dprintk("Packet is too small to be an ARP\n");
 		goto out;
diff -druN linux-2.6.27.59-libre5/drivers/net/bonding/bond_main.c linux-2.6.27.61-libre5/drivers/net/bonding/bond_main.c
--- linux-2.6.27.59-libre5/drivers/net/bonding/bond_main.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/net/bonding/bond_main.c	2012-02-12 15:40:04.000000000 -0500
@@ -2699,6 +2699,10 @@
 	if (!slave || !slave_do_arp_validate(bond, slave))
 		goto out_unlock;
 
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (!skb)
+		goto out_unlock;
+
 	if (!pskb_may_pull(skb, arp_hdr_len(dev)))
 		goto out_unlock;
 
diff -druN linux-2.6.27.59-libre5/drivers/net/rionet.c linux-2.6.27.61-libre5/drivers/net/rionet.c
--- linux-2.6.27.59-libre5/drivers/net/rionet.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/net/rionet.c	2012-02-12 15:40:04.000000000 -0500
@@ -87,8 +87,8 @@
 #define dev_rionet_capable(dev) \
 	is_rionet_capable(dev->pef, dev->src_ops, dev->dst_ops)
 
-#define RIONET_MAC_MATCH(x)	(*(u32 *)x == 0x00010001)
-#define RIONET_GET_DESTID(x)	(*(u16 *)(x + 4))
+#define RIONET_MAC_MATCH(x)	(!memcmp((x), "\00\01\00\01", 4))
+#define RIONET_GET_DESTID(x)	((*((u8 *)x + 4) << 8) | *((u8 *)x + 5))
 
 static int rionet_rx_clean(struct net_device *ndev)
 {
diff -druN linux-2.6.27.59-libre5/drivers/net/wireless/libertas/cmd.c linux-2.6.27.61-libre5/drivers/net/wireless/libertas/cmd.c
--- linux-2.6.27.59-libre5/drivers/net/wireless/libertas/cmd.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/net/wireless/libertas/cmd.c	2012-02-12 15:40:04.000000000 -0500
@@ -1751,8 +1751,8 @@
 				    cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
 					lbs_deb_host(
 					       "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
-					list_del(&cmdnode->list);
 					spin_lock_irqsave(&priv->driver_lock, flags);
+					list_del(&cmdnode->list);
 					lbs_complete_command(priv, cmdnode, 0);
 					spin_unlock_irqrestore(&priv->driver_lock, flags);
 
@@ -1764,8 +1764,8 @@
 				    (priv->psstate == PS_STATE_PRE_SLEEP)) {
 					lbs_deb_host(
 					       "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
-					list_del(&cmdnode->list);
 					spin_lock_irqsave(&priv->driver_lock, flags);
+					list_del(&cmdnode->list);
 					lbs_complete_command(priv, cmdnode, 0);
 					spin_unlock_irqrestore(&priv->driver_lock, flags);
 					priv->needtowakeup = 1;
@@ -1778,7 +1778,9 @@
 				       "EXEC_NEXT_CMD: sending EXIT_PS\n");
 			}
 		}
+		spin_lock_irqsave(&priv->driver_lock, flags);
 		list_del(&cmdnode->list);
+		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
 			    le16_to_cpu(cmd->command));
 		lbs_submit_command(priv, cmdnode);
diff -druN linux-2.6.27.59-libre5/drivers/scsi/aacraid/commsup.c linux-2.6.27.61-libre5/drivers/scsi/aacraid/commsup.c
--- linux-2.6.27.59-libre5/drivers/scsi/aacraid/commsup.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/scsi/aacraid/commsup.c	2012-02-12 15:40:04.000000000 -0500
@@ -1202,6 +1202,8 @@
 	kfree(aac->queues);
 	aac->queues = NULL;
 	free_irq(aac->pdev->irq, aac);
+	if (aac->msi)
+		pci_disable_msi(aac->pdev);
 	kfree(aac->fsa_dev);
 	aac->fsa_dev = NULL;
 	quirks = aac_get_driver_ident(index)->quirks;
diff -druN linux-2.6.27.59-libre5/drivers/scsi/device_handler/scsi_dh.c linux-2.6.27.61-libre5/drivers/scsi/device_handler/scsi_dh.c
--- linux-2.6.27.59-libre5/drivers/scsi/device_handler/scsi_dh.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/scsi/device_handler/scsi_dh.c	2012-02-12 15:40:04.000000000 -0500
@@ -423,7 +423,12 @@
 
 	spin_lock_irqsave(q->queue_lock, flags);
 	sdev = q->queuedata;
-	if (sdev && sdev->scsi_dh_data)
+	if (!sdev) {
+		spin_unlock_irqrestore(q->queue_lock, flags);
+		return SCSI_DH_NOSYS;
+	}
+
+	if (sdev->scsi_dh_data)
 		scsi_dh = sdev->scsi_dh_data->scsi_dh;
 	if (!scsi_dh || !get_device(&sdev->sdev_gendev))
 		err = SCSI_DH_NOSYS;
diff -druN linux-2.6.27.59-libre5/drivers/scsi/hosts.c linux-2.6.27.61-libre5/drivers/scsi/hosts.c
--- linux-2.6.27.59-libre5/drivers/scsi/hosts.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/scsi/hosts.c	2012-02-12 15:40:04.000000000 -0500
@@ -269,14 +269,17 @@
 {
 	struct Scsi_Host *shost = dev_to_shost(dev);
 	struct device *parent = dev->parent;
+	struct request_queue *q;
 
 	if (shost->ehandler)
 		kthread_stop(shost->ehandler);
 	if (shost->work_q)
 		destroy_workqueue(shost->work_q);
-	if (shost->uspace_req_q) {
-		kfree(shost->uspace_req_q->queuedata);
-		scsi_free_queue(shost->uspace_req_q);
+	q = shost->uspace_req_q;
+	if (q) {
+		kfree(q->queuedata);
+		q->queuedata = NULL;
+		scsi_free_queue(q);
 	}
 
 	scsi_destroy_command_freelist(shost);
diff -druN linux-2.6.27.59-libre5/drivers/scsi/libsas/sas_expander.c linux-2.6.27.61-libre5/drivers/scsi/libsas/sas_expander.c
--- linux-2.6.27.59-libre5/drivers/scsi/libsas/sas_expander.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/scsi/libsas/sas_expander.c	2012-02-12 15:40:04.000000000 -0500
@@ -839,6 +839,9 @@
 
 	res = sas_discover_expander(child);
 	if (res) {
+		spin_lock_irq(&parent->port->dev_list_lock);
+		list_del(&child->dev_list_node);
+		spin_unlock_irq(&parent->port->dev_list_lock);
 		kfree(child);
 		return NULL;
 	}
@@ -1719,10 +1722,12 @@
 	}
 	sas_disable_routing(parent, phy->attached_sas_addr);
 	memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
-	sas_port_delete_phy(phy->port, phy->phy);
-	if (phy->port->num_phys == 0)
-		sas_port_delete(phy->port);
-	phy->port = NULL;
+	if (phy->port) {
+		sas_port_delete_phy(phy->port, phy->phy);
+		if (phy->port->num_phys == 0)
+			sas_port_delete(phy->port);
+		phy->port = NULL;
+	}
 }
 
 static int sas_discover_bfs_by_root_level(struct domain_device *root,
diff -druN linux-2.6.27.59-libre5/drivers/scsi/scsi_lib.c linux-2.6.27.61-libre5/drivers/scsi/scsi_lib.c
--- linux-2.6.27.59-libre5/drivers/scsi/scsi_lib.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/scsi/scsi_lib.c	2012-02-12 15:40:04.000000000 -0500
@@ -1389,8 +1389,8 @@
 static void scsi_kill_request(struct request *req, struct request_queue *q)
 {
 	struct scsi_cmnd *cmd = req->special;
-	struct scsi_device *sdev = cmd->device;
-	struct Scsi_Host *shost = sdev->host;
+	struct scsi_device *sdev;
+	struct Scsi_Host *shost;
 
 	blkdev_dequeue_request(req);
 
@@ -1400,6 +1400,10 @@
 		BUG();
 	}
 
+	scmd_printk(KERN_INFO, cmd, "killing request\n");
+
+	sdev = cmd->device;
+	shost = sdev->host;
 	scsi_init_cmd_errh(cmd);
 	cmd->result = DID_NO_CONNECT << 16;
 	atomic_inc(&cmd->device->iorequest_cnt);
@@ -1473,7 +1477,6 @@
 	struct request *req;
 
 	if (!sdev) {
-		printk("scsi: killing requests for dead queue\n");
 		while ((req = elv_next_request(q)) != NULL)
 			scsi_kill_request(req, q);
 		return;
@@ -1680,6 +1683,15 @@
 
 void scsi_free_queue(struct request_queue *q)
 {
+	unsigned long flags;
+
+	WARN_ON(q->queuedata);
+
+	/* cause scsi_request_fn() to kill all non-finished requests */
+	spin_lock_irqsave(q->queue_lock, flags);
+	q->request_fn(q);
+	spin_unlock_irqrestore(q->queue_lock, flags);
+
 	blk_cleanup_queue(q);
 }
 
diff -druN linux-2.6.27.59-libre5/drivers/scsi/scsi_sysfs.c linux-2.6.27.61-libre5/drivers/scsi/scsi_sysfs.c
--- linux-2.6.27.59-libre5/drivers/scsi/scsi_sysfs.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/scsi/scsi_sysfs.c	2012-02-12 15:40:04.000000000 -0500
@@ -317,14 +317,8 @@
 		kfree(evt);
 	}
 
-	if (sdev->request_queue) {
-		sdev->request_queue->queuedata = NULL;
-		/* user context needed to free queue */
-		scsi_free_queue(sdev->request_queue);
-		/* temporary expedient, try to catch use of queue lock
-		 * after free of sdev */
-		sdev->request_queue = NULL;
-	}
+	/* NULL queue means the device can't be used */
+	sdev->request_queue = NULL;
 
 	scsi_target_reap(scsi_target(sdev));
 
@@ -950,6 +944,12 @@
 	if (sdev->host->hostt->slave_destroy)
 		sdev->host->hostt->slave_destroy(sdev);
 	transport_destroy_device(dev);
+
+	/* cause the request function to reject all I/O requests */
+	sdev->request_queue->queuedata = NULL;
+
+	/* Freeing the queue signals to block that we're done */
+	scsi_free_queue(sdev->request_queue);
 	put_device(dev);
 }
 
diff -druN linux-2.6.27.59-libre5/drivers/scsi/sd.c linux-2.6.27.61-libre5/drivers/scsi/sd.c
--- linux-2.6.27.59-libre5/drivers/scsi/sd.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/scsi/sd.c	2012-02-12 15:40:04.000000000 -0500
@@ -749,6 +749,10 @@
 	SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n",
 						disk->disk_name, cmd));
 
+	error = scsi_verify_blk_ioctl(bdev, cmd);
+	if (error < 0)
+		return error;
+
 	/*
 	 * If we are in the middle of error recovery, don't let anyone
 	 * else try and use this device.  Also, if error recovery fails, it
@@ -769,7 +773,7 @@
 		case SCSI_IOCTL_GET_BUS_NUMBER:
 			return scsi_ioctl(sdp, cmd, p);
 		default:
-			error = scsi_cmd_ioctl(filp, disk->queue, disk, cmd, p);
+			error = scsi_cmd_blk_ioctl(filp, bdev, cmd, p);
 			if (error != -ENOTTY)
 				return error;
 	}
@@ -927,6 +931,11 @@
 	struct block_device *bdev = file->f_path.dentry->d_inode->i_bdev;
 	struct gendisk *disk = bdev->bd_disk;
 	struct scsi_device *sdev = scsi_disk(disk)->device;
+	int ret;
+
+	ret = scsi_verify_blk_ioctl(bdev, cmd);
+	if (ret < 0)
+		return -ENOIOCTLCMD;
 
 	/*
 	 * If we are in the middle of error recovery, don't let anyone
@@ -938,8 +947,6 @@
 		return -ENODEV;
 	       
 	if (sdev->host->hostt->compat_ioctl) {
-		int ret;
-
 		ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
 
 		return ret;
diff -druN linux-2.6.27.59-libre5/drivers/scsi/sym53c8xx_2/sym_glue.c linux-2.6.27.61-libre5/drivers/scsi/sym53c8xx_2/sym_glue.c
--- linux-2.6.27.59-libre5/drivers/scsi/sym53c8xx_2/sym_glue.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/scsi/sym53c8xx_2/sym_glue.c	2012-02-12 15:40:04.000000000 -0500
@@ -821,6 +821,10 @@
 	struct sym_hcb *np = sym_get_hcb(sdev->host);
 	struct sym_lcb *lp = sym_lp(&np->target[sdev->id], sdev->lun);
 
+	/* if slave_alloc returned before allocating a sym_lcb, return */
+	if (!lp)
+		return;
+
 	if (lp->itlq_tbl)
 		sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK * 4, "ITLQ_TBL");
 	kfree(lp->cb_tags);
diff -druN linux-2.6.27.59-libre5/drivers/usb/musb/musb_core.c linux-2.6.27.61-libre5/drivers/usb/musb/musb_core.c
--- linux-2.6.27.59-libre5/drivers/usb/musb/musb_core.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/usb/musb/musb_core.c	2012-02-12 15:40:04.000000000 -0500
@@ -1792,6 +1792,7 @@
 	INIT_LIST_HEAD(&musb->out_bulk);
 
 	hcd->uses_new_polling = 1;
+	hcd->has_tt = 1;
 
 	musb->vbuserr_retry = VBUSERR_RETRY_COUNT;
 #else
diff -druN linux-2.6.27.59-libre5/drivers/usb/serial/ftdi_sio.c linux-2.6.27.61-libre5/drivers/usb/serial/ftdi_sio.c
--- linux-2.6.27.59-libre5/drivers/usb/serial/ftdi_sio.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/usb/serial/ftdi_sio.c	2012-02-12 15:40:04.000000000 -0500
@@ -2109,13 +2109,19 @@
 
 	cflag = termios->c_cflag;
 
-	/* FIXME -For this cut I don't care if the line is really changing or
-	   not  - so just do the change regardless  - should be able to
-	   compare old_termios and tty->termios */
+	if (old_termios->c_cflag == termios->c_cflag
+	    && old_termios->c_ispeed == termios->c_ispeed
+	    && old_termios->c_ospeed == termios->c_ospeed)
+		goto no_c_cflag_changes;
+
 	/* NOTE These routines can get interrupted by
 	   ftdi_sio_read_bulk_callback  - need to examine what this means -
 	   don't see any problems yet */
 
+	if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) ==
+	    (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)))
+		goto no_data_parity_stop_changes;
+
 	/* Set number of data bits, parity, stop bits */
 
 	termios->c_cflag &= ~CMSPAR;
@@ -2151,6 +2157,7 @@
 	}
 
 	/* Now do the baudrate */
+no_data_parity_stop_changes:
 	if ((cflag & CBAUD) == B0) {
 		/* Disable flow control */
 		if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
@@ -2173,6 +2180,7 @@
 
 	/* Set flow control */
 	/* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */
+no_c_cflag_changes:
 	if (cflag & CRTSCTS) {
 		dbg("%s Setting to CRTSCTS flow control", __func__);
 		if (usb_control_msg(dev,
diff -druN linux-2.6.27.59-libre5/drivers/usb/storage/usb.c linux-2.6.27.61-libre5/drivers/usb/storage/usb.c
--- linux-2.6.27.59-libre5/drivers/usb/storage/usb.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/usb/storage/usb.c	2012-02-12 15:40:04.000000000 -0500
@@ -1065,6 +1065,7 @@
 	.post_reset =	storage_post_reset,
 	.id_table =	storage_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 static int __init usb_stor_init(void)
diff -druN linux-2.6.27.59-libre5/drivers/video/carminefb.c linux-2.6.27.61-libre5/drivers/video/carminefb.c
--- linux-2.6.27.59-libre5/drivers/video/carminefb.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/video/carminefb.c	2012-02-12 15:40:04.000000000 -0500
@@ -31,11 +31,11 @@
 #define CARMINEFB_DEFAULT_VIDEO_MODE	1
 
 static unsigned int fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE;
-module_param(fb_mode, uint, 444);
+module_param(fb_mode, uint, 0444);
 MODULE_PARM_DESC(fb_mode, "Initial video mode as integer.");
 
 static char *fb_mode_str;
-module_param(fb_mode_str, charp, 444);
+module_param(fb_mode_str, charp, 0444);
 MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters.");
 
 /*
@@ -45,7 +45,7 @@
  * 0b010 Display 1
  */
 static int fb_displays = CARMINE_USE_DISPLAY0 | CARMINE_USE_DISPLAY1;
-module_param(fb_displays, int, 444);
+module_param(fb_displays, int, 0444);
 MODULE_PARM_DESC(fb_displays, "Bit mode, which displays are used");
 
 struct carmine_hw {
diff -druN linux-2.6.27.59-libre5/drivers/video/offb.c linux-2.6.27.61-libre5/drivers/video/offb.c
--- linux-2.6.27.59-libre5/drivers/video/offb.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/drivers/video/offb.c	2012-02-12 15:40:04.000000000 -0500
@@ -100,36 +100,32 @@
 			  u_int transp, struct fb_info *info)
 {
 	struct offb_par *par = (struct offb_par *) info->par;
-	int i, depth;
-	u32 *pal = info->pseudo_palette;
 
-	depth = info->var.bits_per_pixel;
-	if (depth == 16)
-		depth = (info->var.green.length == 5) ? 15 : 16;
+	if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
+		u32 *pal = info->pseudo_palette;
+		u32 cr = red >> (16 - info->var.red.length);
+		u32 cg = green >> (16 - info->var.green.length);
+		u32 cb = blue >> (16 - info->var.blue.length);
+		u32 value;
 
-	if (regno > 255 ||
-	    (depth == 16 && regno > 63) ||
-	    (depth == 15 && regno > 31))
-		return 1;
+		if (regno >= 16)
+			return -EINVAL;
 
-	if (regno < 16) {
-		switch (depth) {
-		case 15:
-			pal[regno] = (regno << 10) | (regno << 5) | regno;
-			break;
-		case 16:
-			pal[regno] = (regno << 11) | (regno << 5) | regno;
-			break;
-		case 24:
-			pal[regno] = (regno << 16) | (regno << 8) | regno;
-			break;
-		case 32:
-			i = (regno << 8) | regno;
-			pal[regno] = (i << 16) | i;
-			break;
+		value = (cr << info->var.red.offset) |
+			(cg << info->var.green.offset) |
+			(cb << info->var.blue.offset);
+		if (info->var.transp.length > 0) {
+			u32 mask = (1 << info->var.transp.length) - 1;
+			mask <<= info->var.transp.offset;
+			value |= mask;
 		}
+		pal[regno] = value;
+		return 0;
 	}
 
+	if (regno > 255)
+		return -EINVAL;
+
 	red >>= 8;
 	green >>= 8;
 	blue >>= 8;
@@ -372,7 +368,7 @@
 				int pitch, unsigned long address,
 				int foreign_endian, struct device_node *dp)
 {
-	unsigned long res_size = pitch * height * (depth + 7) / 8;
+	unsigned long res_size = pitch * height;
 	struct offb_par *par = &default_par;
 	unsigned long res_start = address;
 	struct fb_fix_screeninfo *fix;
diff -druN linux-2.6.27.59-libre5/fs/cifs/cifssmb.c linux-2.6.27.61-libre5/fs/cifs/cifssmb.c
--- linux-2.6.27.59-libre5/fs/cifs/cifssmb.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/cifs/cifssmb.c	2012-02-12 15:40:04.000000000 -0500
@@ -3649,7 +3649,8 @@
 	T2_FNEXT_RSP_PARMS *parms;
 	char *response_data;
 	int rc = 0;
-	int bytes_returned, name_len;
+	int bytes_returned;
+	unsigned int name_len;
 	__u16 params, byte_count;
 
 	cFYI(1, ("In FindNext"));
diff -druN linux-2.6.27.59-libre5/fs/ext3/namei.c linux-2.6.27.61-libre5/fs/ext3/namei.c
--- linux-2.6.27.59-libre5/fs/ext3/namei.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/ext3/namei.c	2012-02-12 15:40:04.000000000 -0500
@@ -1430,10 +1430,19 @@
 	frame->at = entries;
 	frame->bh = bh;
 	bh = bh2;
+	/*
+	 * Mark buffers dirty here so that if do_split() fails we write a
+	 * consistent set of buffers to disk.
+	 */
+	ext3_journal_dirty_metadata(handle, frame->bh);
+	ext3_journal_dirty_metadata(handle, bh);
 	de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
-	dx_release (frames);
-	if (!(de))
+	if (!de) {
+		ext3_mark_inode_dirty(handle, dir);
+		dx_release(frames);
 		return retval;
+	}
+	dx_release(frames);
 
 	return add_dirent_to_buf(handle, dentry, inode, de, bh);
 }
diff -druN linux-2.6.27.59-libre5/fs/ext3/xattr.c linux-2.6.27.61-libre5/fs/ext3/xattr.c
--- linux-2.6.27.59-libre5/fs/ext3/xattr.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/ext3/xattr.c	2012-02-12 15:40:04.000000000 -0500
@@ -801,8 +801,16 @@
 			/* We need to allocate a new block */
 			ext3_fsblk_t goal = ext3_group_first_block_no(sb,
 						EXT3_I(inode)->i_block_group);
-			ext3_fsblk_t block = ext3_new_block(handle, inode,
-							goal, &error);
+			ext3_fsblk_t block;
+
+			/*
+			 * Protect us agaist concurrent allocations to the
+			 * same inode from ext3_..._writepage(). Reservation
+			 * code does not expect racing allocations.
+			 */
+			mutex_lock(&EXT3_I(inode)->truncate_mutex);
+			block = ext3_new_block(handle, inode, goal, &error);
+			mutex_unlock(&EXT3_I(inode)->truncate_mutex);
 			if (error)
 				goto cleanup;
 			ea_idebug(inode, "creating block %d", block);
diff -druN linux-2.6.27.59-libre5/fs/ext4/extents.c linux-2.6.27.61-libre5/fs/ext4/extents.c
--- linux-2.6.27.59-libre5/fs/ext4/extents.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/ext4/extents.c	2012-02-12 15:40:04.000000000 -0500
@@ -2327,6 +2327,7 @@
 		ex1 = ex;
 		ex1->ee_len = cpu_to_le16(iblock - ee_block);
 		ext4_ext_mark_uninitialized(ex1);
+		ext4_ext_dirty(handle, inode, path + depth);
 		ex2 = &newex;
 	}
 	/*
diff -druN linux-2.6.27.59-libre5/fs/ext4/inode.c linux-2.6.27.61-libre5/fs/ext4/inode.c
--- linux-2.6.27.59-libre5/fs/ext4/inode.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/ext4/inode.c	2012-02-12 15:40:04.000000000 -0500
@@ -2816,7 +2816,7 @@
 	 */
 
 	new_i_size = pos + copied;
-	if (new_i_size > EXT4_I(inode)->i_disksize) {
+	if (copied && new_i_size > EXT4_I(inode)->i_disksize) {
 		if (ext4_da_should_update_i_disksize(page, end)) {
 			down_write(&EXT4_I(inode)->i_data_sem);
 			if (new_i_size > EXT4_I(inode)->i_disksize) {
diff -druN linux-2.6.27.59-libre5/fs/hfs/btree.c linux-2.6.27.61-libre5/fs/hfs/btree.c
--- linux-2.6.27.59-libre5/fs/hfs/btree.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/hfs/btree.c	2012-02-12 15:40:04.000000000 -0500
@@ -45,11 +45,26 @@
 	case HFS_EXT_CNID:
 		hfs_inode_read_fork(tree->inode, mdb->drXTExtRec, mdb->drXTFlSize,
 				    mdb->drXTFlSize, be32_to_cpu(mdb->drXTClpSiz));
+		if (HFS_I(tree->inode)->alloc_blocks >
+					HFS_I(tree->inode)->first_blocks) {
+			printk(KERN_ERR "hfs: invalid btree extent records\n");
+			unlock_new_inode(tree->inode);
+			goto free_inode;
+		}
+
 		tree->inode->i_mapping->a_ops = &hfs_btree_aops;
 		break;
 	case HFS_CAT_CNID:
 		hfs_inode_read_fork(tree->inode, mdb->drCTExtRec, mdb->drCTFlSize,
 				    mdb->drCTFlSize, be32_to_cpu(mdb->drCTClpSiz));
+
+		if (!HFS_I(tree->inode)->first_blocks) {
+			printk(KERN_ERR "hfs: invalid btree extent records "
+								"(0 size).\n");
+			unlock_new_inode(tree->inode);
+			goto free_inode;
+		}
+
 		tree->inode->i_mapping->a_ops = &hfs_btree_aops;
 		break;
 	default:
diff -druN linux-2.6.27.59-libre5/fs/hfs/trans.c linux-2.6.27.61-libre5/fs/hfs/trans.c
--- linux-2.6.27.59-libre5/fs/hfs/trans.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/hfs/trans.c	2012-02-12 15:40:04.000000000 -0500
@@ -40,6 +40,8 @@
 
 	src = in->name;
 	srclen = in->len;
+	if (srclen > HFS_NAMELEN)
+		srclen = HFS_NAMELEN;
 	dst = out;
 	dstlen = HFS_MAX_NAMELEN;
 	if (nls_io) {
diff -druN linux-2.6.27.59-libre5/fs/jbd/journal.c linux-2.6.27.61-libre5/fs/jbd/journal.c
--- linux-2.6.27.59-libre5/fs/jbd/journal.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/jbd/journal.c	2012-02-12 15:40:04.000000000 -0500
@@ -1030,6 +1030,14 @@
 		goto out;
 	}
 
+	if (be32_to_cpu(sb->s_first) == 0 ||
+	    be32_to_cpu(sb->s_first) >= journal->j_maxlen) {
+		printk(KERN_WARNING
+			"JBD: Invalid start block of journal: %u\n",
+			be32_to_cpu(sb->s_first));
+		goto out;
+	}
+
 	return 0;
 
 out:
diff -druN linux-2.6.27.59-libre5/fs/jbd2/journal.c linux-2.6.27.61-libre5/fs/jbd2/journal.c
--- linux-2.6.27.59-libre5/fs/jbd2/journal.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/jbd2/journal.c	2012-02-12 15:40:04.000000000 -0500
@@ -1369,6 +1369,14 @@
 		goto out;
 	}
 
+	if (be32_to_cpu(sb->s_first) == 0 ||
+	    be32_to_cpu(sb->s_first) >= journal->j_maxlen) {
+		printk(KERN_WARNING
+			"JBD2: Invalid start block of journal: %u\n",
+			be32_to_cpu(sb->s_first));
+		goto out;
+	}
+
 	return 0;
 
 out:
diff -druN linux-2.6.27.59-libre5/fs/lockd/clntproc.c linux-2.6.27.61-libre5/fs/lockd/clntproc.c
--- linux-2.6.27.59-libre5/fs/lockd/clntproc.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/lockd/clntproc.c	2012-02-12 15:40:04.000000000 -0500
@@ -709,7 +709,13 @@
 
 	if (task->tk_status < 0) {
 		dprintk("lockd: unlock failed (err = %d)\n", -task->tk_status);
-		goto retry_rebind;
+		switch (task->tk_status) {
+		case -EACCES:
+		case -EIO:
+			goto die;
+		default:
+			goto retry_rebind;
+		}
 	}
 	if (status == NLM_LCK_DENIED_GRACE_PERIOD) {
 		rpc_delay(task, NLMCLNT_GRACE_WAIT);
diff -druN linux-2.6.27.59-libre5/fs/nfsd/export.c linux-2.6.27.61-libre5/fs/nfsd/export.c
--- linux-2.6.27.59-libre5/fs/nfsd/export.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/nfsd/export.c	2012-02-12 15:40:04.000000000 -0500
@@ -101,7 +101,7 @@
 	struct svc_expkey key;
 	struct svc_expkey *ek;
 
-	if (mesg[mlen-1] != '\n')
+	if (mlen < 1 || mesg[mlen-1] != '\n')
 		return -EINVAL;
 	mesg[mlen-1] = 0;
 
diff -druN linux-2.6.27.59-libre5/fs/nfsd/vfs.c linux-2.6.27.61-libre5/fs/nfsd/vfs.c
--- linux-2.6.27.59-libre5/fs/nfsd/vfs.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/nfsd/vfs.c	2012-02-12 15:40:04.000000000 -0500
@@ -1334,7 +1334,7 @@
 		goto out;
 	if (!(iap->ia_valid & ATTR_MODE))
 		iap->ia_mode = 0;
-	err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE);
+	err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_EXEC);
 	if (err)
 		goto out;
 
@@ -1356,6 +1356,13 @@
 	if (IS_ERR(dchild))
 		goto out_nfserr;
 
+	/* If file doesn't exist, check for permissions to create one */
+	if (!dchild->d_inode) {
+		err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE);
+		if (err)
+			goto out;
+	}
+
 	err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
 	if (err)
 		goto out;
diff -druN linux-2.6.27.59-libre5/fs/partitions/efi.c linux-2.6.27.61-libre5/fs/partitions/efi.c
--- linux-2.6.27.59-libre5/fs/partitions/efi.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/partitions/efi.c	2012-02-12 15:40:04.000000000 -0500
@@ -343,6 +343,12 @@
 		goto fail;
 	}
 
+	/* Check that sizeof_partition_entry has the correct value */
+	if (le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) {
+		pr_debug("GUID Partitition Entry Size check failed.\n");
+		goto fail;
+	}
+
 	if (!(*ptes = alloc_read_gpt_entries(bdev, *gpt)))
 		goto fail;
 
diff -druN linux-2.6.27.59-libre5/fs/partitions/ldm.c linux-2.6.27.61-libre5/fs/partitions/ldm.c
--- linux-2.6.27.59-libre5/fs/partitions/ldm.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/partitions/ldm.c	2012-02-12 15:40:04.000000000 -0500
@@ -1299,6 +1299,11 @@
 
 	BUG_ON (!data || !frags);
 
+	if (size < 2 * VBLK_SIZE_HEAD) {
+		ldm_error("Value of size is to small.");
+		return false;
+	}
+
 	group = get_unaligned_be32(data + 0x08);
 	rec   = get_unaligned_be16(data + 0x0C);
 	num   = get_unaligned_be16(data + 0x0E);
@@ -1306,6 +1311,10 @@
 		ldm_error ("A VBLK claims to have %d parts.", num);
 		return false;
 	}
+	if (rec >= num) {
+		ldm_error("REC value (%d) exceeds NUM value (%d)", rec, num);
+		return false;
+	}
 
 	list_for_each (item, frags) {
 		f = list_entry (item, struct frag, list);
@@ -1326,6 +1335,11 @@
 
 	list_add_tail (&f->list, frags);
 found:
+	if (rec >= f->num) {
+		ldm_error("REC value (%d) exceeds NUM value (%d)", rec, f->num);
+		return false;
+	}
+
 	if (f->map & (1 << rec)) {
 		ldm_error ("Duplicate VBLK, part %d.", rec);
 		f->map &= 0x7F;			/* Mark the group as broken */
@@ -1334,10 +1348,9 @@
 
 	f->map |= (1 << rec);
 
-	if (num > 0) {
-		data += VBLK_SIZE_HEAD;
-		size -= VBLK_SIZE_HEAD;
-	}
+	data += VBLK_SIZE_HEAD;
+	size -= VBLK_SIZE_HEAD;
+
 	memcpy (f->data+rec*(size-VBLK_SIZE_HEAD)+VBLK_SIZE_HEAD, data, size);
 
 	return true;
diff -druN linux-2.6.27.59-libre5/fs/partitions/osf.c linux-2.6.27.61-libre5/fs/partitions/osf.c
--- linux-2.6.27.59-libre5/fs/partitions/osf.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/partitions/osf.c	2012-02-12 15:40:04.000000000 -0500
@@ -10,10 +10,13 @@
 #include "check.h"
 #include "osf.h"
 
+#define MAX_OSF_PARTITIONS 8
+
 int osf_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
 	int i;
 	int slot = 1;
+	unsigned int npartitions;
 	Sector sect;
 	unsigned char *data;
 	struct disklabel {
@@ -45,7 +48,7 @@
 			u8  p_fstype;
 			u8  p_frag;
 			__le16 p_cpg;
-		} d_partitions[8];
+		} d_partitions[MAX_OSF_PARTITIONS];
 	} * label;
 	struct d_partition * partition;
 
@@ -63,7 +66,12 @@
 		put_dev_sector(sect);
 		return 0;
 	}
-	for (i = 0 ; i < le16_to_cpu(label->d_npartitions); i++, partition++) {
+	npartitions = le16_to_cpu(label->d_npartitions);
+	if (npartitions > MAX_OSF_PARTITIONS) {
+		put_dev_sector(sect);
+		return 0;
+	}
+	for (i = 0 ; i < npartitions; i++, partition++) {
 		if (slot == state->limit)
 		        break;
 		if (le32_to_cpu(partition->p_size))
diff -druN linux-2.6.27.59-libre5/fs/ubifs/recovery.c linux-2.6.27.61-libre5/fs/ubifs/recovery.c
--- linux-2.6.27.59-libre5/fs/ubifs/recovery.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/fs/ubifs/recovery.c	2012-02-12 15:40:04.000000000 -0500
@@ -280,6 +280,32 @@
 			goto out_free;
 		}
 		memcpy(c->rcvrd_mst_node, c->mst_node, UBIFS_MST_NODE_SZ);
+
+		/*
+		 * We had to recover the master node, which means there was an
+		 * unclean reboot. However, it is possible that the master node
+		 * is clean at this point, i.e., %UBIFS_MST_DIRTY is not set.
+		 * E.g., consider the following chain of events:
+		 *
+		 * 1. UBIFS was cleanly unmounted, so the master node is clean
+		 * 2. UBIFS is being mounted R/W and starts changing the master
+		 *    node in the first (%UBIFS_MST_LNUM). A power cut happens,
+		 *    so this LEB ends up with some amount of garbage at the
+		 *    end.
+		 * 3. UBIFS is being mounted R/O. We reach this place and
+		 *    recover the master node from the second LEB
+		 *    (%UBIFS_MST_LNUM + 1). But we cannot update the media
+		 *    because we are being mounted R/O. We have to defer the
+		 *    operation.
+		 * 4. However, this master node (@c->mst_node) is marked as
+		 *    clean (since the step 1). And if we just return, the
+		 *    mount code will be confused and won't recover the master
+		 *    node when it is re-mounter R/W later.
+		 *
+		 *    Thus, to force the recovery by marking the master node as
+		 *    dirty.
+		 */
+		c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY);
 	} else {
 		/* Write the recovered master node */
 		c->max_sqnum = le64_to_cpu(mst->ch.sqnum) - 1;
diff -druN linux-2.6.27.59-libre5/include/asm-x86/uaccess.h linux-2.6.27.61-libre5/include/asm-x86/uaccess.h
--- linux-2.6.27.59-libre5/include/asm-x86/uaccess.h	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/include/asm-x86/uaccess.h	2012-02-12 15:40:04.000000000 -0500
@@ -42,7 +42,7 @@
  * Returns 0 if the range is valid, nonzero otherwise.
  *
  * This is equivalent to the following test:
- * (u33)addr + (u33)size >= (u33)current->addr_limit.seg (u65 for x86_64)
+ * (u33)addr + (u33)size > (u33)current->addr_limit.seg (u65 for x86_64)
  *
  * This needs 33-bit (65-bit for x86_64) arithmetic. We have a carry...
  */
diff -druN linux-2.6.27.59-libre5/include/linux/blkdev.h linux-2.6.27.61-libre5/include/linux/blkdev.h
--- linux-2.6.27.59-libre5/include/linux/blkdev.h	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/include/linux/blkdev.h	2012-02-12 15:40:04.000000000 -0500
@@ -669,8 +669,11 @@
 extern void blk_plug_device_unlocked(struct request_queue *);
 extern int blk_remove_plug(struct request_queue *);
 extern void blk_recount_segments(struct request_queue *, struct bio *);
+extern int scsi_verify_blk_ioctl(struct block_device *, unsigned int);
 extern int scsi_cmd_ioctl(struct file *, struct request_queue *,
 			  struct gendisk *, unsigned int, void __user *);
+extern int scsi_cmd_blk_ioctl(struct file *, struct block_device *,
+                              unsigned int, void __user *);
 extern int sg_scsi_ioctl(struct file *, struct request_queue *,
 		struct gendisk *, struct scsi_ioctl_command __user *);
 
diff -druN linux-2.6.27.59-libre5/include/linux/if_packet.h linux-2.6.27.61-libre5/include/linux/if_packet.h
--- linux-2.6.27.59-libre5/include/linux/if_packet.h	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/include/linux/if_packet.h	2012-02-12 15:40:04.000000000 -0500
@@ -61,6 +61,7 @@
 	__u16		tp_mac;
 	__u16		tp_net;
 	__u16		tp_vlan_tci;
+	__u16		tp_padding;
 };
 
 struct tpacket_hdr
@@ -93,6 +94,7 @@
 	__u32		tp_sec;
 	__u32		tp_nsec;
 	__u16		tp_vlan_tci;
+	__u16		tp_padding;
 };
 
 #define TPACKET2_HDRLEN		(TPACKET_ALIGN(sizeof(struct tpacket2_hdr)) + sizeof(struct sockaddr_ll))
diff -druN linux-2.6.27.59-libre5/include/linux/mm.h linux-2.6.27.61-libre5/include/linux/mm.h
--- linux-2.6.27.59-libre5/include/linux/mm.h	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/include/linux/mm.h	2012-02-12 15:40:04.000000000 -0500
@@ -850,6 +850,12 @@
 			struct page **pages);
 
 /*
+ * doesn't attempt to fault and will return short.
+ */
+int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
+			  struct page **pages);
+
+/*
  * A callback you can register to apply pressure to ageable caches.
  *
  * 'shrink' is passed a count 'nr_to_scan' and a 'gfpmask'.  It should
diff -druN linux-2.6.27.59-libre5/include/linux/seqlock.h linux-2.6.27.61-libre5/include/linux/seqlock.h
--- linux-2.6.27.59-libre5/include/linux/seqlock.h	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/include/linux/seqlock.h	2012-02-12 15:40:04.000000000 -0500
@@ -88,12 +88,12 @@
 	unsigned ret;
 
 repeat:
-	ret = sl->sequence;
-	smp_rmb();
+	ret = ACCESS_ONCE(sl->sequence);
 	if (unlikely(ret & 1)) {
 		cpu_relax();
 		goto repeat;
 	}
+	smp_rmb();
 
 	return ret;
 }
diff -druN linux-2.6.27.59-libre5/include/linux/sunrpc/sched.h linux-2.6.27.61-libre5/include/linux/sunrpc/sched.h
--- linux-2.6.27.59-libre5/include/linux/sunrpc/sched.h	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/include/linux/sunrpc/sched.h	2012-02-12 15:40:04.000000000 -0500
@@ -84,8 +84,8 @@
 	long			tk_rtt;		/* round-trip time (jiffies) */
 
 	pid_t			tk_owner;	/* Process id for batching tasks */
-	unsigned char		tk_priority : 2;/* Task priority */
-
+	unsigned char		tk_priority : 2,/* Task priority */
+				tk_rebind_retry : 2;
 #ifdef RPC_DEBUG
 	unsigned short		tk_pid;		/* debugging aid */
 #endif
diff -druN linux-2.6.27.59-libre5/kernel/taskstats.c linux-2.6.27.61-libre5/kernel/taskstats.c
--- linux-2.6.27.59-libre5/kernel/taskstats.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/kernel/taskstats.c	2012-02-12 15:40:04.000000000 -0500
@@ -574,6 +574,7 @@
 	.cmd		= TASKSTATS_CMD_GET,
 	.doit		= taskstats_user_cmd,
 	.policy		= taskstats_cmd_get_policy,
+	.flags		= GENL_ADMIN_PERM,
 };
 
 static struct genl_ops cgroupstats_ops = {
diff -druN linux-2.6.27.59-libre5/kernel/time/timekeeping.c linux-2.6.27.61-libre5/kernel/time/timekeeping.c
--- linux-2.6.27.59-libre5/kernel/time/timekeeping.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/kernel/time/timekeeping.c	2012-02-12 15:40:04.000000000 -0500
@@ -52,8 +52,15 @@
 static struct timespec xtime_cache __attribute__ ((aligned (16)));
 void update_xtime_cache(u64 nsec)
 {
-	xtime_cache = xtime;
-	timespec_add_ns(&xtime_cache, nsec);
+	/*
+	 * Use temporary variable so get_seconds() cannot catch
+	 * an intermediate xtime_cache.tv_sec value.
+	 * The ACCESS_ONCE() keeps the compiler from optimizing
+	 * out the intermediate value.
+	 */
+	struct timespec ts = xtime;
+	timespec_add_ns(&ts, nsec);
+	ACCESS_ONCE(xtime_cache) = ts;
 }
 
 struct clocksource *clock;
diff -druN linux-2.6.27.59-libre5/MAINTAINERS linux-2.6.27.61-libre5/MAINTAINERS
--- linux-2.6.27.59-libre5/MAINTAINERS	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/MAINTAINERS	2012-02-12 15:40:04.000000000 -0500
@@ -3857,7 +3857,7 @@
 STABLE BRANCH:
 P:	Greg Kroah-Hartman
 M:	greg@kroah.com
-L:	stable@kernel.org
+L:	stable@vger.kernel.org
 S:	Maintained
 
 SHARP LH SUPPORT (LH7952X & LH7A40X)
diff -druN linux-2.6.27.59-libre5/Makefile linux-2.6.27.61-libre5/Makefile
--- linux-2.6.27.59-libre5/Makefile	2011-05-02 15:23:37.000000000 -0400
+++ linux-2.6.27.61-libre5/Makefile	2012-02-13 09:31:32.000000000 -0500
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 27
-EXTRAVERSION = .59-libre5
+EXTRAVERSION = .61-libre5
 NAME = Trembling Tortoise
 
 # *DOCUMENTATION*
@@ -530,6 +530,9 @@
 # Arch Makefiles may override this setting
 KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
 
+# This warning generated too much noise in a regular build.
+KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
+
 ifdef CONFIG_FRAME_POINTER
 KBUILD_CFLAGS	+= -fno-omit-frame-pointer -fno-optimize-sibling-calls
 else
@@ -558,7 +561,7 @@
 KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
 
 # disable pointer signed / unsigned warnings in gcc 4.0
-KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
+KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign)
 
 # disable invalid "can't wrap" optimzations for signed / pointers
 KBUILD_CFLAGS	+= $(call cc-option,-fno-strict-overflow)
diff -druN linux-2.6.27.59-libre5/mm/util.c linux-2.6.27.61-libre5/mm/util.c
--- linux-2.6.27.59-libre5/mm/util.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/mm/util.c	2012-02-12 15:40:04.000000000 -0500
@@ -101,6 +101,19 @@
 }
 EXPORT_SYMBOL(__krealloc);
 
+/*
+ * Like get_user_pages_fast() except its IRQ-safe in that it won't fall
+ * back to the regular GUP.
+ * If the architecture not support this fucntion, simply return with no
+ * page pinned
+ */
+int __attribute__((weak)) __get_user_pages_fast(unsigned long start,
+				 int nr_pages, int write, struct page **pages)
+{
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__get_user_pages_fast);
+
 /**
  * krealloc - reallocate memory. The contents will remain unchanged.
  * @p: object to reallocate memory for.
diff -druN linux-2.6.27.59-libre5/net/bluetooth/l2cap.c linux-2.6.27.61-libre5/net/bluetooth/l2cap.c
--- linux-2.6.27.59-libre5/net/bluetooth/l2cap.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/net/bluetooth/l2cap.c	2012-02-12 15:40:04.000000000 -0500
@@ -1737,7 +1737,7 @@
 
 	/* Reject if config buffer is too small. */
 	len = cmd_len - sizeof(*req);
-	if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
+	if (len < 0 || l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
 		l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
 				l2cap_build_conf_rsp(sk, rsp,
 					L2CAP_CONF_REJECT, flags), rsp);
diff -druN linux-2.6.27.59-libre5/net/ipv4/af_inet.c linux-2.6.27.61-libre5/net/ipv4/af_inet.c
--- linux-2.6.27.59-libre5/net/ipv4/af_inet.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/net/ipv4/af_inet.c	2012-02-12 15:40:04.000000000 -0500
@@ -458,6 +458,9 @@
 	if (addr_len < sizeof(struct sockaddr_in))
 		goto out;
 
+	if (addr->sin_family != AF_INET)
+		goto out;
+
 	chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
 
 	/* Not specified by any standard per-se, however it breaks too
diff -druN linux-2.6.27.59-libre5/net/packet/af_packet.c linux-2.6.27.61-libre5/net/packet/af_packet.c
--- linux-2.6.27.59-libre5/net/packet/af_packet.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/net/packet/af_packet.c	2012-02-12 15:40:04.000000000 -0500
@@ -708,6 +708,7 @@
 		h.h2->tp_sec = ts.tv_sec;
 		h.h2->tp_nsec = ts.tv_nsec;
 		h.h2->tp_vlan_tci = skb->vlan_tci;
+		h.h2->tp_padding = 0;
 		hdrlen = sizeof(*h.h2);
 		break;
 	default:
@@ -1181,6 +1182,7 @@
 		aux.tp_net = skb_network_offset(skb);
 		aux.tp_vlan_tci = skb->vlan_tci;
 
+		aux.tp_padding = 0;
 		put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux);
 	}
 
diff -druN linux-2.6.27.59-libre5/net/sched/sch_api.c linux-2.6.27.61-libre5/net/sched/sch_api.c
--- linux-2.6.27.59-libre5/net/sched/sch_api.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/net/sched/sch_api.c	2012-02-12 15:40:04.000000000 -0500
@@ -1193,6 +1193,11 @@
 	return -1;
 }
 
+static bool tc_qdisc_dump_ignore(struct Qdisc *q)
+{
+	return (q->flags & TCQ_F_BUILTIN) ? true : false;
+}
+
 static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n,
 			u32 clid, struct Qdisc *old, struct Qdisc *new)
 {
@@ -1203,11 +1208,11 @@
 	if (!skb)
 		return -ENOBUFS;
 
-	if (old && old->handle) {
+	if (old && !tc_qdisc_dump_ignore(old)) {
 		if (tc_fill_qdisc(skb, old, clid, pid, n->nlmsg_seq, 0, RTM_DELQDISC) < 0)
 			goto err_out;
 	}
-	if (new) {
+	if (new && !tc_qdisc_dump_ignore(new)) {
 		if (tc_fill_qdisc(skb, new, clid, pid, n->nlmsg_seq, old ? NLM_F_REPLACE : 0, RTM_NEWQDISC) < 0)
 			goto err_out;
 	}
@@ -1220,11 +1225,6 @@
 	return -EINVAL;
 }
 
-static bool tc_qdisc_dump_ignore(struct Qdisc *q)
-{
-	return (q->flags & TCQ_F_BUILTIN) ? true : false;
-}
-
 static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
 			      struct netlink_callback *cb,
 			      int *q_idx_p, int s_q_idx)
diff -druN linux-2.6.27.59-libre5/net/sunrpc/clnt.c linux-2.6.27.61-libre5/net/sunrpc/clnt.c
--- linux-2.6.27.59-libre5/net/sunrpc/clnt.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/net/sunrpc/clnt.c	2012-02-12 15:40:04.000000000 -0500
@@ -955,6 +955,9 @@
 			status = -EOPNOTSUPP;
 			break;
 		}
+		if (task->tk_rebind_retry == 0)
+			break;
+		task->tk_rebind_retry--;
 		rpc_delay(task, 3*HZ);
 		goto retry_timeout;
 	case -ETIMEDOUT:
diff -druN linux-2.6.27.59-libre5/net/sunrpc/rpcb_clnt.c linux-2.6.27.61-libre5/net/sunrpc/rpcb_clnt.c
--- linux-2.6.27.59-libre5/net/sunrpc/rpcb_clnt.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/net/sunrpc/rpcb_clnt.c	2012-02-12 15:40:04.000000000 -0500
@@ -505,7 +505,7 @@
 	u32 bind_version;
 	struct rpc_xprt *xprt;
 	struct rpc_clnt	*rpcb_clnt;
-	static struct rpcbind_args *map;
+	struct rpcbind_args *map;
 	struct rpc_task	*child;
 	struct sockaddr_storage addr;
 	struct sockaddr *sap = (struct sockaddr *)&addr;
diff -druN linux-2.6.27.59-libre5/net/sunrpc/sched.c linux-2.6.27.61-libre5/net/sunrpc/sched.c
--- linux-2.6.27.59-libre5/net/sunrpc/sched.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/net/sunrpc/sched.c	2012-02-12 15:40:04.000000000 -0500
@@ -786,6 +786,7 @@
 	/* Initialize retry counters */
 	task->tk_garb_retry = 2;
 	task->tk_cred_retry = 2;
+	task->tk_rebind_retry = 2;
 
 	task->tk_priority = task_setup_data->priority - RPC_PRIORITY_LOW;
 	task->tk_owner = current->tgid;
diff -druN linux-2.6.27.59-libre5/net/sunrpc/svc.c linux-2.6.27.61-libre5/net/sunrpc/svc.c
--- linux-2.6.27.59-libre5/net/sunrpc/svc.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/net/sunrpc/svc.c	2012-02-12 15:40:04.000000000 -0500
@@ -163,6 +163,7 @@
 
 fail_free:
 	kfree(m->to_pool);
+	m->to_pool = NULL;
 fail:
 	return -ENOMEM;
 }
@@ -283,7 +284,9 @@
 	if (!--m->count) {
 		m->mode = SVC_POOL_DEFAULT;
 		kfree(m->to_pool);
+		m->to_pool = NULL;
 		kfree(m->pool_to);
+		m->pool_to = NULL;
 		m->npools = 0;
 	}
 
diff -druN linux-2.6.27.59-libre5/net/sunrpc/svc_xprt.c linux-2.6.27.61-libre5/net/sunrpc/svc_xprt.c
--- linux-2.6.27.59-libre5/net/sunrpc/svc_xprt.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/net/sunrpc/svc_xprt.c	2012-02-12 15:40:04.000000000 -0500
@@ -830,12 +830,13 @@
 	if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags))
 		list_del_init(&xprt->xpt_list);
 	/*
-	 * We used to delete the transport from whichever list
-	 * it's sk_xprt.xpt_ready node was on, but we don't actually
-	 * need to.  This is because the only time we're called
-	 * while still attached to a queue, the queue itself
-	 * is about to be destroyed (in svc_destroy).
+	 * The only time we're called while xpt_ready is still on a list
+	 * is while the list itself is about to be destroyed (in
+	 * svc_destroy).  BUT svc_xprt_enqueue could still be attempting
+	 * to add new entries to the sp_sockets list, so we can't leave
+	 * a freed xprt on it.
 	 */
+	list_del_init(&xprt->xpt_ready);
 	if (test_bit(XPT_TEMP, &xprt->xpt_flags))
 		serv->sv_tmpcnt--;
 
diff -druN linux-2.6.27.59-libre5/net/sunrpc/xprtsock.c linux-2.6.27.61-libre5/net/sunrpc/xprtsock.c
--- linux-2.6.27.59-libre5/net/sunrpc/xprtsock.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/net/sunrpc/xprtsock.c	2012-02-12 15:40:04.000000000 -0500
@@ -1126,10 +1126,11 @@
 	if (!(xprt = xprt_from_sock(sk)))
 		goto out;
 	dprintk("RPC:       xs_tcp_state_change client %p...\n", xprt);
-	dprintk("RPC:       state %x conn %d dead %d zapped %d\n",
+	dprintk("RPC:       state %x conn %d dead %d zapped %d sk_shutdown %d\n",
 			sk->sk_state, xprt_connected(xprt),
 			sock_flag(sk, SOCK_DEAD),
-			sock_flag(sk, SOCK_ZAPPED));
+			sock_flag(sk, SOCK_ZAPPED),
+			sk->sk_shutdown);
 
 	switch (sk->sk_state) {
 	case TCP_ESTABLISHED:
@@ -1594,10 +1595,25 @@
 {
 	unsigned int state = transport->inet->sk_state;
 
-	if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED)
-		return;
-	if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT))
-		return;
+	if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED) {
+		/* we don't need to abort the connection if the socket
+		 * hasn't undergone a shutdown
+		 */
+		if (transport->inet->sk_shutdown == 0)
+			return;
+		dprintk("RPC:       %s: TCP_CLOSEd and sk_shutdown set to %d\n",
+				__func__, transport->inet->sk_shutdown);
+	}
+	if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT)) {
+		/* we don't need to abort the connection if the socket
+		 * hasn't undergone a shutdown
+		 */
+		if (transport->inet->sk_shutdown == 0)
+			return;
+		dprintk("RPC:       %s: ESTABLISHED/SYN_SENT "
+				"sk_shutdown set to %d\n",
+				__func__, transport->inet->sk_shutdown);
+	}
 	xs_abort_connection(xprt, transport);
 }
 
diff -druN linux-2.6.27.59-libre5/net/unix/af_unix.c linux-2.6.27.61-libre5/net/unix/af_unix.c
--- linux-2.6.27.59-libre5/net/unix/af_unix.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/net/unix/af_unix.c	2012-02-12 15:40:04.000000000 -0500
@@ -501,6 +501,8 @@
 			      int, int);
 static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
 				  struct msghdr *, size_t);
+static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *,
+				  struct msghdr *, size_t, int);
 
 static const struct proto_ops unix_stream_ops = {
 	.family =	PF_UNIX,
@@ -560,7 +562,7 @@
 	.setsockopt =	sock_no_setsockopt,
 	.getsockopt =	sock_no_getsockopt,
 	.sendmsg =	unix_seqpacket_sendmsg,
-	.recvmsg =	unix_dgram_recvmsg,
+	.recvmsg =	unix_seqpacket_recvmsg,
 	.mmap =		sock_no_mmap,
 	.sendpage =	sock_no_sendpage,
 };
@@ -1617,6 +1619,18 @@
 	return unix_dgram_sendmsg(kiocb, sock, msg, len);
 }
 
+static int unix_seqpacket_recvmsg(struct kiocb *iocb, struct socket *sock,
+			      struct msghdr *msg, size_t size,
+			      int flags)
+{
+	struct sock *sk = sock->sk;
+
+	if (sk->sk_state != TCP_ESTABLISHED)
+		return -ENOTCONN;
+
+	return unix_dgram_recvmsg(iocb, sock, msg, size, flags);
+}
+
 static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
 {
 	struct unix_sock *u = unix_sk(sk);
diff -druN linux-2.6.27.59-libre5/scripts/Kbuild.include linux-2.6.27.61-libre5/scripts/Kbuild.include
--- linux-2.6.27.59-libre5/scripts/Kbuild.include	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/scripts/Kbuild.include	2012-02-12 15:40:04.000000000 -0500
@@ -117,6 +117,11 @@
 cc-option-align = $(subst -functions=0,,\
 	$(call cc-option,-falign-functions=0,-malign-functions=0))
 
+# 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-version
 # Usage gcc-ver := $(call cc-version)
 cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC))
diff -druN linux-2.6.27.59-libre5/sound/core/timer.c linux-2.6.27.61-libre5/sound/core/timer.c
--- linux-2.6.27.59-libre5/sound/core/timer.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/sound/core/timer.c	2012-02-12 15:40:04.000000000 -0500
@@ -527,6 +527,8 @@
 	if (err < 0)
 		return err;
 	timer = timeri->timer;
+	if (!timer)
+		return -EINVAL;
 	spin_lock_irqsave(&timer->lock, flags);
 	timeri->cticks = timeri->ticks;
 	timeri->pticks = 0;
diff -druN linux-2.6.27.59-libre5/sound/pci/ice1712/amp.c linux-2.6.27.61-libre5/sound/pci/ice1712/amp.c
--- linux-2.6.27.59-libre5/sound/pci/ice1712/amp.c	2011-04-30 10:53:51.000000000 -0400
+++ linux-2.6.27.61-libre5/sound/pci/ice1712/amp.c	2012-02-12 15:40:04.000000000 -0500
@@ -67,8 +67,11 @@
 
 static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)
 {
-	/* we use pins 39 and 41 of the VT1616 for left and right read outputs */
-	snd_ac97_write_cache(ice->ac97, 0x5a, snd_ac97_read(ice->ac97, 0x5a) & ~0x8000);
+	if (ice->ac97)
+		/* we use pins 39 and 41 of the VT1616 for left and right
+		read outputs */
+		snd_ac97_write_cache(ice->ac97, 0x5a,
+			snd_ac97_read(ice->ac97, 0x5a) & ~0x8000);
 	return 0;
 }
 
