public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Alice Ferrazzi" <alicef@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:4.9 commit in: /
Date: Sat, 17 Feb 2018 15:02:05 +0000 (UTC)	[thread overview]
Message-ID: <1518879709.afbda2ef9bf2c33e80dd8b21c3e0b7a91a182983.alicef@gentoo> (raw)

commit:     afbda2ef9bf2c33e80dd8b21c3e0b7a91a182983
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Sat Feb 17 15:01:49 2018 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Sat Feb 17 15:01:49 2018 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=afbda2ef

linux kernel 4.9.82

 0000_README             |    4 +
 1081_linux-4.9.82.patch | 4130 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 4134 insertions(+)

diff --git a/0000_README b/0000_README
index a2405f2..363e368 100644
--- a/0000_README
+++ b/0000_README
@@ -367,6 +367,10 @@ Patch:  1080_linux-4.9.81.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.9.81
 
+Patch:  1081_linux-4.9.82.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.9.82
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1081_linux-4.9.82.patch b/1081_linux-4.9.82.patch
new file mode 100644
index 0000000..a60b06b
--- /dev/null
+++ b/1081_linux-4.9.82.patch
@@ -0,0 +1,4130 @@
+diff --git a/Makefile b/Makefile
+index 4d5753f1c37b..d338530540e0 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 9
+-SUBLEVEL = 81
++SUBLEVEL = 82
+ EXTRAVERSION =
+ NAME = Roaring Lionus
+ 
+diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h
+index 2b0ac429f5eb..412bb3c24f36 100644
+--- a/arch/alpha/kernel/pci_impl.h
++++ b/arch/alpha/kernel/pci_impl.h
+@@ -143,7 +143,8 @@ struct pci_iommu_arena
+ };
+ 
+ #if defined(CONFIG_ALPHA_SRM) && \
+-    (defined(CONFIG_ALPHA_CIA) || defined(CONFIG_ALPHA_LCA))
++    (defined(CONFIG_ALPHA_CIA) || defined(CONFIG_ALPHA_LCA) || \
++     defined(CONFIG_ALPHA_AVANTI))
+ # define NEED_SRM_SAVE_RESTORE
+ #else
+ # undef NEED_SRM_SAVE_RESTORE
+diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
+index b483156698d5..60c17b9bf04d 100644
+--- a/arch/alpha/kernel/process.c
++++ b/arch/alpha/kernel/process.c
+@@ -265,12 +265,13 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
+ 	   application calling fork.  */
+ 	if (clone_flags & CLONE_SETTLS)
+ 		childti->pcb.unique = regs->r20;
++	else
++		regs->r20 = 0;	/* OSF/1 has some strange fork() semantics.  */
+ 	childti->pcb.usp = usp ?: rdusp();
+ 	*childregs = *regs;
+ 	childregs->r0 = 0;
+ 	childregs->r19 = 0;
+ 	childregs->r20 = 1;	/* OSF/1 has some strange fork() semantics.  */
+-	regs->r20 = 0;
+ 	stack = ((struct switch_stack *) regs) - 1;
+ 	*childstack = *stack;
+ 	childstack->r26 = (unsigned long) ret_from_fork;
+diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
+index 74aceead06e9..32ba92cdf5f6 100644
+--- a/arch/alpha/kernel/traps.c
++++ b/arch/alpha/kernel/traps.c
+@@ -158,11 +158,16 @@ void show_stack(struct task_struct *task, unsigned long *sp)
+ 	for(i=0; i < kstack_depth_to_print; i++) {
+ 		if (((long) stack & (THREAD_SIZE-1)) == 0)
+ 			break;
+-		if (i && ((i % 4) == 0))
+-			printk("\n       ");
+-		printk("%016lx ", *stack++);
++		if ((i % 4) == 0) {
++			if (i)
++				pr_cont("\n");
++			printk("       ");
++		} else {
++			pr_cont(" ");
++		}
++		pr_cont("%016lx", *stack++);
+ 	}
+-	printk("\n");
++	pr_cont("\n");
+ 	dik_show_trace(sp);
+ }
+ 
+diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
+index 19b5f5c1c0ff..c38bfbeec306 100644
+--- a/arch/arm/kvm/arm.c
++++ b/arch/arm/kvm/arm.c
+@@ -1165,6 +1165,7 @@ static int hyp_init_cpu_pm_notifier(struct notifier_block *self,
+ 			cpu_hyp_reset();
+ 
+ 		return NOTIFY_OK;
++	case CPU_PM_ENTER_FAILED:
+ 	case CPU_PM_EXIT:
+ 		if (__this_cpu_read(kvm_arm_hardware_enabled))
+ 			/* The hardware was enabled before suspend. */
+diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c
+index 42f5daf715d0..4e57ebca6e69 100644
+--- a/arch/arm/kvm/handle_exit.c
++++ b/arch/arm/kvm/handle_exit.c
+@@ -38,7 +38,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
+ 
+ 	ret = kvm_psci_call(vcpu);
+ 	if (ret < 0) {
+-		kvm_inject_undefined(vcpu);
++		vcpu_set_reg(vcpu, 0, ~0UL);
+ 		return 1;
+ 	}
+ 
+@@ -47,7 +47,16 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
+ 
+ static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
+ {
+-	kvm_inject_undefined(vcpu);
++	/*
++	 * "If an SMC instruction executed at Non-secure EL1 is
++	 * trapped to EL2 because HCR_EL2.TSC is 1, the exception is a
++	 * Trap exception, not a Secure Monitor Call exception [...]"
++	 *
++	 * We need to advance the PC after the trap, as it would
++	 * otherwise return to the same address...
++	 */
++	vcpu_set_reg(vcpu, 0, ~0UL);
++	kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+ 	return 1;
+ }
+ 
+diff --git a/arch/mn10300/mm/misalignment.c b/arch/mn10300/mm/misalignment.c
+index b9920b1edd5a..70cef54dc40f 100644
+--- a/arch/mn10300/mm/misalignment.c
++++ b/arch/mn10300/mm/misalignment.c
+@@ -437,7 +437,7 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code)
+ 
+ 	info.si_signo	= SIGSEGV;
+ 	info.si_errno	= 0;
+-	info.si_code	= 0;
++	info.si_code	= SEGV_MAPERR;
+ 	info.si_addr	= (void *) regs->pc;
+ 	force_sig_info(SIGSEGV, &info, current);
+ 	return;
+diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
+index 3d3f6062f49c..605a284922fb 100644
+--- a/arch/openrisc/kernel/traps.c
++++ b/arch/openrisc/kernel/traps.c
+@@ -302,12 +302,12 @@ asmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address)
+ 	siginfo_t info;
+ 
+ 	if (user_mode(regs)) {
+-		/* Send a SIGSEGV */
+-		info.si_signo = SIGSEGV;
++		/* Send a SIGBUS */
++		info.si_signo = SIGBUS;
+ 		info.si_errno = 0;
+-		/* info.si_code has been set above */
+-		info.si_addr = (void *)address;
+-		force_sig_info(SIGSEGV, &info, current);
++		info.si_code = BUS_ADRALN;
++		info.si_addr = (void __user *)address;
++		force_sig_info(SIGBUS, &info, current);
+ 	} else {
+ 		printk("KERNEL: Unaligned Access 0x%.8lx\n", address);
+ 		show_registers(regs);
+diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
+index 0e12cb2437d1..dc0996b9d75d 100644
+--- a/arch/powerpc/include/asm/hvcall.h
++++ b/arch/powerpc/include/asm/hvcall.h
+@@ -319,6 +319,7 @@
+ #define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR	(1ull << 61) // IBM bit 2
+ 
+ #ifndef __ASSEMBLY__
++#include <linux/types.h>
+ 
+ /**
+  * plpar_hcall_norets: - Make a pseries hypervisor call with no return arguments
+diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
+index ff639342a8be..c5b997757988 100644
+--- a/arch/sh/kernel/traps_32.c
++++ b/arch/sh/kernel/traps_32.c
+@@ -607,7 +607,8 @@ asmlinkage void do_divide_error(unsigned long r4)
+ 		break;
+ 	}
+ 
+-	force_sig_info(SIGFPE, &info, current);
++	info.si_signo = SIGFPE;
++	force_sig_info(info.si_signo, &info, current);
+ }
+ #endif
+ 
+diff --git a/arch/x86/crypto/poly1305_glue.c b/arch/x86/crypto/poly1305_glue.c
+index e32142bc071d..28c372003e44 100644
+--- a/arch/x86/crypto/poly1305_glue.c
++++ b/arch/x86/crypto/poly1305_glue.c
+@@ -164,7 +164,6 @@ static struct shash_alg alg = {
+ 	.init		= poly1305_simd_init,
+ 	.update		= poly1305_simd_update,
+ 	.final		= crypto_poly1305_final,
+-	.setkey		= crypto_poly1305_setkey,
+ 	.descsize	= sizeof(struct poly1305_simd_desc_ctx),
+ 	.base		= {
+ 		.cra_name		= "poly1305",
+diff --git a/arch/x86/crypto/sha512-mb/sha512_mb_mgr_init_avx2.c b/arch/x86/crypto/sha512-mb/sha512_mb_mgr_init_avx2.c
+index 36870b26067a..d08805032f01 100644
+--- a/arch/x86/crypto/sha512-mb/sha512_mb_mgr_init_avx2.c
++++ b/arch/x86/crypto/sha512-mb/sha512_mb_mgr_init_avx2.c
+@@ -57,10 +57,12 @@ void sha512_mb_mgr_init_avx2(struct sha512_mb_mgr *state)
+ {
+ 	unsigned int j;
+ 
+-	state->lens[0] = 0;
+-	state->lens[1] = 1;
+-	state->lens[2] = 2;
+-	state->lens[3] = 3;
++	/* initially all lanes are unused */
++	state->lens[0] = 0xFFFFFFFF00000000;
++	state->lens[1] = 0xFFFFFFFF00000001;
++	state->lens[2] = 0xFFFFFFFF00000002;
++	state->lens[3] = 0xFFFFFFFF00000003;
++
+ 	state->unused_lanes = 0xFF03020100;
+ 	for (j = 0; j < 4; j++)
+ 		state->ldata[j].job_in_lane = NULL;
+diff --git a/arch/x86/include/asm/vsyscall.h b/arch/x86/include/asm/vsyscall.h
+index 9ee85066f407..62210da19a92 100644
+--- a/arch/x86/include/asm/vsyscall.h
++++ b/arch/x86/include/asm/vsyscall.h
+@@ -13,7 +13,6 @@ extern void map_vsyscall(void);
+  */
+ extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address);
+ extern bool vsyscall_enabled(void);
+-extern unsigned long vsyscall_pgprot;
+ #else
+ static inline void map_vsyscall(void) {}
+ static inline bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
+@@ -22,5 +21,6 @@ static inline bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
+ }
+ static inline bool vsyscall_enabled(void) { return false; }
+ #endif
++extern unsigned long vsyscall_pgprot;
+ 
+ #endif /* _ASM_X86_VSYSCALL_H */
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index d49da86e3099..d66224e695cf 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -4967,14 +4967,15 @@ static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu,
+ 
+ 	if (is_guest_mode(vcpu) &&
+ 	    vector == vmx->nested.posted_intr_nv) {
+-		/* the PIR and ON have been set by L1. */
+-		kvm_vcpu_trigger_posted_interrupt(vcpu);
+ 		/*
+ 		 * If a posted intr is not recognized by hardware,
+ 		 * we will accomplish it in the next vmentry.
+ 		 */
+ 		vmx->nested.pi_pending = true;
+ 		kvm_make_request(KVM_REQ_EVENT, vcpu);
++		/* the PIR and ON have been set by L1. */
++		if (!kvm_vcpu_trigger_posted_interrupt(vcpu))
++			kvm_vcpu_kick(vcpu);
+ 		return 0;
+ 	}
+ 	return -1;
+diff --git a/arch/xtensa/include/asm/futex.h b/arch/xtensa/include/asm/futex.h
+index b39531babec0..72bfc1cbc2b5 100644
+--- a/arch/xtensa/include/asm/futex.h
++++ b/arch/xtensa/include/asm/futex.h
+@@ -109,7 +109,6 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ 			      u32 oldval, u32 newval)
+ {
+ 	int ret = 0;
+-	u32 prev;
+ 
+ 	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+ 		return -EFAULT;
+@@ -120,26 +119,24 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ 
+ 	__asm__ __volatile__ (
+ 	"	# futex_atomic_cmpxchg_inatomic\n"
+-	"1:	l32i	%1, %3, 0\n"
+-	"	mov	%0, %5\n"
+-	"	wsr	%1, scompare1\n"
+-	"2:	s32c1i	%0, %3, 0\n"
+-	"3:\n"
++	"	wsr	%5, scompare1\n"
++	"1:	s32c1i	%1, %4, 0\n"
++	"	s32i	%1, %6, 0\n"
++	"2:\n"
+ 	"	.section .fixup,\"ax\"\n"
+ 	"	.align 4\n"
+-	"4:	.long	3b\n"
+-	"5:	l32r	%1, 4b\n"
+-	"	movi	%0, %6\n"
++	"3:	.long	2b\n"
++	"4:	l32r	%1, 3b\n"
++	"	movi	%0, %7\n"
+ 	"	jx	%1\n"
+ 	"	.previous\n"
+ 	"	.section __ex_table,\"a\"\n"
+-	"	.long 1b,5b,2b,5b\n"
++	"	.long 1b,4b\n"
+ 	"	.previous\n"
+-	: "+r" (ret), "=&r" (prev), "+m" (*uaddr)
+-	: "r" (uaddr), "r" (oldval), "r" (newval), "I" (-EFAULT)
++	: "+r" (ret), "+r" (newval), "+m" (*uaddr), "+m" (*uval)
++	: "r" (uaddr), "r" (oldval), "r" (uval), "I" (-EFAULT)
+ 	: "memory");
+ 
+-	*uval = prev;
+ 	return ret;
+ }
+ 
+diff --git a/crypto/ahash.c b/crypto/ahash.c
+index cce0268a13fe..f3fa104de479 100644
+--- a/crypto/ahash.c
++++ b/crypto/ahash.c
+@@ -625,5 +625,16 @@ struct hash_alg_common *ahash_attr_alg(struct rtattr *rta, u32 type, u32 mask)
+ }
+ EXPORT_SYMBOL_GPL(ahash_attr_alg);
+ 
++bool crypto_hash_alg_has_setkey(struct hash_alg_common *halg)
++{
++	struct crypto_alg *alg = &halg->base;
++
++	if (alg->cra_type != &crypto_ahash_type)
++		return crypto_shash_alg_has_setkey(__crypto_shash_alg(alg));
++
++	return __crypto_ahash_alg(alg)->setkey != NULL;
++}
++EXPORT_SYMBOL_GPL(crypto_hash_alg_has_setkey);
++
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION("Asynchronous cryptographic hash type");
+diff --git a/crypto/cryptd.c b/crypto/cryptd.c
+index 0c654e59f215..af9ad45d1909 100644
+--- a/crypto/cryptd.c
++++ b/crypto/cryptd.c
+@@ -691,7 +691,8 @@ static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb,
+ 	inst->alg.finup  = cryptd_hash_finup_enqueue;
+ 	inst->alg.export = cryptd_hash_export;
+ 	inst->alg.import = cryptd_hash_import;
+-	inst->alg.setkey = cryptd_hash_setkey;
++	if (crypto_shash_alg_has_setkey(salg))
++		inst->alg.setkey = cryptd_hash_setkey;
+ 	inst->alg.digest = cryptd_hash_digest_enqueue;
+ 
+ 	err = ahash_register_instance(tmpl, inst);
+diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c
+index a14100e74754..6e9389c8bfbd 100644
+--- a/crypto/mcryptd.c
++++ b/crypto/mcryptd.c
+@@ -534,7 +534,8 @@ static int mcryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb,
+ 	inst->alg.finup  = mcryptd_hash_finup_enqueue;
+ 	inst->alg.export = mcryptd_hash_export;
+ 	inst->alg.import = mcryptd_hash_import;
+-	inst->alg.setkey = mcryptd_hash_setkey;
++	if (crypto_hash_alg_has_setkey(halg))
++		inst->alg.setkey = mcryptd_hash_setkey;
+ 	inst->alg.digest = mcryptd_hash_digest_enqueue;
+ 
+ 	err = ahash_register_instance(tmpl, inst);
+diff --git a/crypto/poly1305_generic.c b/crypto/poly1305_generic.c
+index 2df9835dfbc0..bca99238948f 100644
+--- a/crypto/poly1305_generic.c
++++ b/crypto/poly1305_generic.c
+@@ -51,17 +51,6 @@ int crypto_poly1305_init(struct shash_desc *desc)
+ }
+ EXPORT_SYMBOL_GPL(crypto_poly1305_init);
+ 
+-int crypto_poly1305_setkey(struct crypto_shash *tfm,
+-			   const u8 *key, unsigned int keylen)
+-{
+-	/* Poly1305 requires a unique key for each tag, which implies that
+-	 * we can't set it on the tfm that gets accessed by multiple users
+-	 * simultaneously. Instead we expect the key as the first 32 bytes in
+-	 * the update() call. */
+-	return -ENOTSUPP;
+-}
+-EXPORT_SYMBOL_GPL(crypto_poly1305_setkey);
+-
+ static void poly1305_setrkey(struct poly1305_desc_ctx *dctx, const u8 *key)
+ {
+ 	/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
+@@ -80,6 +69,11 @@ static void poly1305_setskey(struct poly1305_desc_ctx *dctx, const u8 *key)
+ 	dctx->s[3] = le32_to_cpuvp(key + 12);
+ }
+ 
++/*
++ * Poly1305 requires a unique key for each tag, which implies that we can't set
++ * it on the tfm that gets accessed by multiple users simultaneously. Instead we
++ * expect the key as the first 32 bytes in the update() call.
++ */
+ unsigned int crypto_poly1305_setdesckey(struct poly1305_desc_ctx *dctx,
+ 					const u8 *src, unsigned int srclen)
+ {
+@@ -285,7 +279,6 @@ static struct shash_alg poly1305_alg = {
+ 	.init		= crypto_poly1305_init,
+ 	.update		= crypto_poly1305_update,
+ 	.final		= crypto_poly1305_final,
+-	.setkey		= crypto_poly1305_setkey,
+ 	.descsize	= sizeof(struct poly1305_desc_ctx),
+ 	.base		= {
+ 		.cra_name		= "poly1305",
+diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
+index fe03d00de22b..b1815b20a99c 100644
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -1535,6 +1535,9 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
+ 		struct kernfs_node *nfit_kernfs;
+ 
+ 		nvdimm = nfit_mem->nvdimm;
++		if (!nvdimm)
++			continue;
++
+ 		nfit_kernfs = sysfs_get_dirent(nvdimm_kobj(nvdimm)->sd, "nfit");
+ 		if (nfit_kernfs)
+ 			nfit_mem->flags_attr = sysfs_get_dirent(nfit_kernfs,
+diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
+index 2fa8304171e0..7a3431018e0a 100644
+--- a/drivers/acpi/sbshc.c
++++ b/drivers/acpi/sbshc.c
+@@ -275,8 +275,8 @@ static int acpi_smbus_hc_add(struct acpi_device *device)
+ 	device->driver_data = hc;
+ 
+ 	acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
+-	printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n",
+-		hc->ec, hc->offset, hc->query_bit);
++	dev_info(&device->dev, "SBS HC: offset = 0x%0x, query_bit = 0x%0x\n",
++		 hc->offset, hc->query_bit);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index c94038206c3a..9b46ef4c851e 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -265,9 +265,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
+ 	{ PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */
+-	{ PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH AHCI */
++	{ PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH M AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
+-	{ PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */
++	{ PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH M RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */
+@@ -290,9 +290,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
+ 	{ PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
+-	{ PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */
++	{ PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT M AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
+-	{ PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */
++	{ PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT M RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */
+@@ -301,20 +301,20 @@ static const struct pci_device_id ahci_pci_tbl[] = {
+ 	{ PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */
+-	{ PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point AHCI */
++	{ PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point M AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
+-	{ PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */
++	{ PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point M RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */
+-	{ PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point AHCI */
++	{ PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point M AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */
+-	{ PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point RAID */
++	{ PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point M RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */
+-	{ PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */
++	{ PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point M RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
+-	{ PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */
++	{ PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point M RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */
+@@ -355,21 +355,21 @@ static const struct pci_device_id ahci_pci_tbl[] = {
+ 	{ PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */
+-	{ PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series AHCI */
++	{ PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series M AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */
+-	{ PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series RAID */
++	{ PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series M RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */
+-	{ PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */
++	{ PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series M RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
+-	{ PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */
++	{ PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series M RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */
+ 	{ PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */
+-	{ PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */
++	{ PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H M AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
+ 	{ PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */
+-	{ PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
++	{ PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H M RAID */
+ 	{ PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
+ 	{ PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/
+@@ -383,6 +383,11 @@ static const struct pci_device_id ahci_pci_tbl[] = {
+ 	{ PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
+ 	{ PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
+ 	{ PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
++	{ PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */
++	{ PCI_VDEVICE(INTEL, 0x0f22), board_ahci }, /* Bay Trail AHCI */
++	{ PCI_VDEVICE(INTEL, 0x0f23), board_ahci }, /* Bay Trail AHCI */
++	{ PCI_VDEVICE(INTEL, 0x22a3), board_ahci }, /* Cherry Trail AHCI */
++	{ PCI_VDEVICE(INTEL, 0x5ae3), board_ahci }, /* Apollo Lake AHCI */
+ 
+ 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
+ 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
+index 90fa4ac149db..7e4ef0502796 100644
+--- a/drivers/block/pktcdvd.c
++++ b/drivers/block/pktcdvd.c
+@@ -2779,7 +2779,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
+ 	pd->pkt_dev = MKDEV(pktdev_major, idx);
+ 	ret = pkt_new_dev(pd, dev);
+ 	if (ret)
+-		goto out_new_dev;
++		goto out_mem2;
+ 
+ 	/* inherit events of the host device */
+ 	disk->events = pd->bdev->bd_disk->events;
+@@ -2797,8 +2797,6 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
+ 	mutex_unlock(&ctl_mutex);
+ 	return 0;
+ 
+-out_new_dev:
+-	blk_cleanup_queue(disk->queue);
+ out_mem2:
+ 	put_disk(disk);
+ out_mem:
+diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c
+index 1cb958e199eb..94e914a33a99 100644
+--- a/drivers/bluetooth/btsdio.c
++++ b/drivers/bluetooth/btsdio.c
+@@ -31,6 +31,7 @@
+ #include <linux/errno.h>
+ #include <linux/skbuff.h>
+ 
++#include <linux/mmc/host.h>
+ #include <linux/mmc/sdio_ids.h>
+ #include <linux/mmc/sdio_func.h>
+ 
+@@ -291,6 +292,14 @@ static int btsdio_probe(struct sdio_func *func,
+ 		tuple = tuple->next;
+ 	}
+ 
++	/* BCM43341 devices soldered onto the PCB (non-removable) use an
++	 * uart connection for bluetooth, ignore the BT SDIO interface.
++	 */
++	if (func->vendor == SDIO_VENDOR_ID_BROADCOM &&
++	    func->device == SDIO_DEVICE_ID_BROADCOM_43341 &&
++	    !mmc_card_is_removable(func->card->host))
++		return -ENODEV;
++
+ 	data = devm_kzalloc(&func->dev, sizeof(*data), GFP_KERNEL);
+ 	if (!data)
+ 		return -ENOMEM;
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 693028659ccc..3257647d4f74 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -23,6 +23,7 @@
+ 
+ #include <linux/module.h>
+ #include <linux/usb.h>
++#include <linux/usb/quirks.h>
+ #include <linux/firmware.h>
+ #include <asm/unaligned.h>
+ 
+@@ -369,8 +370,8 @@ static const struct usb_device_id blacklist_table[] = {
+ #define BTUSB_FIRMWARE_LOADED	7
+ #define BTUSB_FIRMWARE_FAILED	8
+ #define BTUSB_BOOTING		9
+-#define BTUSB_RESET_RESUME	10
+-#define BTUSB_DIAG_RUNNING	11
++#define BTUSB_DIAG_RUNNING	10
++#define BTUSB_OOB_WAKE_ENABLED	11
+ 
+ struct btusb_data {
+ 	struct hci_dev       *hdev;
+@@ -2928,9 +2929,9 @@ static int btusb_probe(struct usb_interface *intf,
+ 
+ 		/* QCA Rome devices lose their updated firmware over suspend,
+ 		 * but the USB hub doesn't notice any status change.
+-		 * Explicitly request a device reset on resume.
++		 * explicitly request a device reset on resume.
+ 		 */
+-		set_bit(BTUSB_RESET_RESUME, &data->flags);
++		interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME;
+ 	}
+ 
+ #ifdef CONFIG_BT_HCIBTUSB_RTL
+@@ -2941,7 +2942,7 @@ static int btusb_probe(struct usb_interface *intf,
+ 		 * but the USB hub doesn't notice any status change.
+ 		 * Explicitly request a device reset on resume.
+ 		 */
+-		set_bit(BTUSB_RESET_RESUME, &data->flags);
++		interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME;
+ 	}
+ #endif
+ 
+@@ -3098,14 +3099,6 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
+ 	btusb_stop_traffic(data);
+ 	usb_kill_anchored_urbs(&data->tx_anchor);
+ 
+-	/* Optionally request a device reset on resume, but only when
+-	 * wakeups are disabled. If wakeups are enabled we assume the
+-	 * device will stay powered up throughout suspend.
+-	 */
+-	if (test_bit(BTUSB_RESET_RESUME, &data->flags) &&
+-	    !device_may_wakeup(&data->udev->dev))
+-		data->udev->reset_resume = 1;
+-
+ 	return 0;
+ }
+ 
+diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c
+index 1b2574c4fb97..b167cc634fae 100644
+--- a/drivers/clocksource/timer-stm32.c
++++ b/drivers/clocksource/timer-stm32.c
+@@ -16,6 +16,7 @@
+ #include <linux/of_irq.h>
+ #include <linux/clk.h>
+ #include <linux/reset.h>
++#include <linux/slab.h>
+ 
+ #define TIM_CR1		0x00
+ #define TIM_DIER	0x0c
+@@ -106,6 +107,10 @@ static int __init stm32_clockevent_init(struct device_node *np)
+ 	unsigned long rate, max_delta;
+ 	int irq, ret, bits, prescaler = 1;
+ 
++	data = kmemdup(&clock_event_ddata, sizeof(*data), GFP_KERNEL);
++	if (!data)
++		return -ENOMEM;
++
+ 	clk = of_clk_get(np, 0);
+ 	if (IS_ERR(clk)) {
+ 		ret = PTR_ERR(clk);
+@@ -156,8 +161,8 @@ static int __init stm32_clockevent_init(struct device_node *np)
+ 
+ 	writel_relaxed(prescaler - 1, data->base + TIM_PSC);
+ 	writel_relaxed(TIM_EGR_UG, data->base + TIM_EGR);
+-	writel_relaxed(TIM_DIER_UIE, data->base + TIM_DIER);
+ 	writel_relaxed(0, data->base + TIM_SR);
++	writel_relaxed(TIM_DIER_UIE, data->base + TIM_DIER);
+ 
+ 	data->periodic_top = DIV_ROUND_CLOSEST(rate, prescaler * HZ);
+ 
+@@ -184,6 +189,7 @@ static int __init stm32_clockevent_init(struct device_node *np)
+ err_clk_enable:
+ 	clk_put(clk);
+ err_clk_get:
++	kfree(data);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
+index 98468b96c32f..2ca101ac0c17 100644
+--- a/drivers/crypto/caam/ctrl.c
++++ b/drivers/crypto/caam/ctrl.c
+@@ -228,12 +228,16 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
+ 		 * without any error (HW optimizations for later
+ 		 * CAAM eras), then try again.
+ 		 */
++		if (ret)
++			break;
++
+ 		rdsta_val = rd_reg32(&ctrl->r4tst[0].rdsta) & RDSTA_IFMASK;
+ 		if ((status && status != JRSTA_SSRC_JUMP_HALT_CC) ||
+-		    !(rdsta_val & (1 << sh_idx)))
++		    !(rdsta_val & (1 << sh_idx))) {
+ 			ret = -EAGAIN;
+-		if (ret)
+ 			break;
++		}
++
+ 		dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx);
+ 		/* Clear the contents before recreating the descriptor */
+ 		memset(desc, 0x00, CAAM_CMD_SZ * 7);
+diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
+index e0bd578a253a..ebe72a466587 100644
+--- a/drivers/dma/dmatest.c
++++ b/drivers/dma/dmatest.c
+@@ -339,7 +339,7 @@ static void dmatest_callback(void *arg)
+ {
+ 	struct dmatest_done *done = arg;
+ 	struct dmatest_thread *thread =
+-		container_of(arg, struct dmatest_thread, done_wait);
++		container_of(done, struct dmatest_thread, test_done);
+ 	if (!thread->done) {
+ 		done->done = true;
+ 		wake_up_all(done->wait);
+diff --git a/drivers/edac/octeon_edac-lmc.c b/drivers/edac/octeon_edac-lmc.c
+index cda6dab5067a..6b65a102b49d 100644
+--- a/drivers/edac/octeon_edac-lmc.c
++++ b/drivers/edac/octeon_edac-lmc.c
+@@ -79,6 +79,7 @@ static void octeon_lmc_edac_poll_o2(struct mem_ctl_info *mci)
+ 	if (!pvt->inject)
+ 		int_reg.u64 = cvmx_read_csr(CVMX_LMCX_INT(mci->mc_idx));
+ 	else {
++		int_reg.u64 = 0;
+ 		if (pvt->error_type == 1)
+ 			int_reg.s.sec_err = 1;
+ 		if (pvt->error_type == 2)
+diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
+index 7fdc42e5aac8..74163a928cba 100644
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -5063,6 +5063,12 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
+ 	 */
+ 	final->t8 = 1;
+ 	final->t9 = 1;
++
++	/*
++	 * HW has only a 100msec granularity for t11_t12 so round it up
++	 * accordingly.
++	 */
++	final->t11_t12 = roundup(final->t11_t12, 100 * 10);
+ }
+ 
+ static void
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index e32862ca5223..03cac5731afc 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -2365,7 +2365,6 @@ static const struct hid_device_id hid_ignore_list[] = {
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) },
+ 	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, 0x0400) },
+-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, 0x0401) },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) },
+@@ -2635,6 +2634,17 @@ bool hid_ignore(struct hid_device *hdev)
+ 			strncmp(hdev->name, "www.masterkit.ru MA901", 22) == 0)
+ 			return true;
+ 		break;
++	case USB_VENDOR_ID_ELAN:
++		/*
++		 * Many Elan devices have a product id of 0x0401 and are handled
++		 * by the elan_i2c input driver. But the ACPI HID ELAN0800 dev
++		 * is not (and cannot be) handled by that driver ->
++		 * Ignore all 0x0401 devs except for the ELAN0800 dev.
++		 */
++		if (hdev->product == 0x0401 &&
++		    strncmp(hdev->name, "ELAN0800", 8) != 0)
++			return true;
++		break;
+ 	}
+ 
+ 	if (hdev->type == HID_TYPE_USBMOUSE &&
+diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c
+index ad304eed656d..c61227cfff25 100644
+--- a/drivers/media/dvb-frontends/ascot2e.c
++++ b/drivers/media/dvb-frontends/ascot2e.c
+@@ -155,7 +155,9 @@ static int ascot2e_write_regs(struct ascot2e_priv *priv,
+ 
+ static int ascot2e_write_reg(struct ascot2e_priv *priv, u8 reg, u8 val)
+ {
+-	return ascot2e_write_regs(priv, reg, &val, 1);
++	u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++	return ascot2e_write_regs(priv, reg, &tmp, 1);
+ }
+ 
+ static int ascot2e_read_regs(struct ascot2e_priv *priv,
+diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
+index fd0f25ee251f..b97647cd7dc6 100644
+--- a/drivers/media/dvb-frontends/cxd2841er.c
++++ b/drivers/media/dvb-frontends/cxd2841er.c
+@@ -261,7 +261,9 @@ static int cxd2841er_write_regs(struct cxd2841er_priv *priv,
+ static int cxd2841er_write_reg(struct cxd2841er_priv *priv,
+ 			       u8 addr, u8 reg, u8 val)
+ {
+-	return cxd2841er_write_regs(priv, addr, reg, &val, 1);
++	u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++	return cxd2841er_write_regs(priv, addr, reg, &tmp, 1);
+ }
+ 
+ static int cxd2841er_read_regs(struct cxd2841er_priv *priv,
+diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c
+index dc43c5f6d0ea..e06bcd4b3ddc 100644
+--- a/drivers/media/dvb-frontends/helene.c
++++ b/drivers/media/dvb-frontends/helene.c
+@@ -331,7 +331,9 @@ static int helene_write_regs(struct helene_priv *priv,
+ 
+ static int helene_write_reg(struct helene_priv *priv, u8 reg, u8 val)
+ {
+-	return helene_write_regs(priv, reg, &val, 1);
++	u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++	return helene_write_regs(priv, reg, &tmp, 1);
+ }
+ 
+ static int helene_read_regs(struct helene_priv *priv,
+diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c
+index 0c089b5986a1..4ebddc895137 100644
+--- a/drivers/media/dvb-frontends/horus3a.c
++++ b/drivers/media/dvb-frontends/horus3a.c
+@@ -89,7 +89,9 @@ static int horus3a_write_regs(struct horus3a_priv *priv,
+ 
+ static int horus3a_write_reg(struct horus3a_priv *priv, u8 reg, u8 val)
+ {
+-	return horus3a_write_regs(priv, reg, &val, 1);
++	u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++	return horus3a_write_regs(priv, reg, &tmp, 1);
+ }
+ 
+ static int horus3a_enter_power_save(struct horus3a_priv *priv)
+diff --git a/drivers/media/dvb-frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c
+index cadcae4cff89..ac9d2591bb6f 100644
+--- a/drivers/media/dvb-frontends/itd1000.c
++++ b/drivers/media/dvb-frontends/itd1000.c
+@@ -99,8 +99,9 @@ static int itd1000_read_reg(struct itd1000_state *state, u8 reg)
+ 
+ static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v)
+ {
+-	int ret = itd1000_write_regs(state, r, &v, 1);
+-	state->shadow[r] = v;
++	u8 tmp = v; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++	int ret = itd1000_write_regs(state, r, &tmp, 1);
++	state->shadow[r] = tmp;
+ 	return ret;
+ }
+ 
+diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c
+index fc08429c99b7..7824926a3744 100644
+--- a/drivers/media/dvb-frontends/mt312.c
++++ b/drivers/media/dvb-frontends/mt312.c
+@@ -142,7 +142,10 @@ static inline int mt312_readreg(struct mt312_state *state,
+ static inline int mt312_writereg(struct mt312_state *state,
+ 				 const enum mt312_reg_addr reg, const u8 val)
+ {
+-	return mt312_write(state, reg, &val, 1);
++	u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++
++	return mt312_write(state, reg, &tmp, 1);
+ }
+ 
+ static inline u32 mt312_div(u32 a, u32 b)
+diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c
+index 3d171b0e00c2..3deddbcaa8b7 100644
+--- a/drivers/media/dvb-frontends/stb0899_drv.c
++++ b/drivers/media/dvb-frontends/stb0899_drv.c
+@@ -552,7 +552,8 @@ int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data,
+ 
+ int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data)
+ {
+-	return stb0899_write_regs(state, reg, &data, 1);
++	u8 tmp = data;
++	return stb0899_write_regs(state, reg, &tmp, 1);
+ }
+ 
+ /*
+diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c
+index 5add1182c3ca..4746b1e0d637 100644
+--- a/drivers/media/dvb-frontends/stb6100.c
++++ b/drivers/media/dvb-frontends/stb6100.c
+@@ -226,12 +226,14 @@ static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int st
+ 
+ static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
+ {
++	u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
+ 	if (unlikely(reg >= STB6100_NUMREGS)) {
+ 		dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
+ 		return -EREMOTEIO;
+ 	}
+-	data = (data & stb6100_template[reg].mask) | stb6100_template[reg].set;
+-	return stb6100_write_reg_range(state, &data, reg, 1);
++	tmp = (tmp & stb6100_template[reg].mask) | stb6100_template[reg].set;
++	return stb6100_write_reg_range(state, &tmp, reg, 1);
+ }
+ 
+ 
+diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
+index abc379aea713..94cec81d0a5c 100644
+--- a/drivers/media/dvb-frontends/stv0367.c
++++ b/drivers/media/dvb-frontends/stv0367.c
+@@ -804,7 +804,9 @@ int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
+ 
+ static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
+ {
+-	return stv0367_writeregs(state, reg, &data, 1);
++	u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++	return stv0367_writeregs(state, reg, &tmp, 1);
+ }
+ 
+ static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
+diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c
+index 25bdf6e0f963..f0377e2b341b 100644
+--- a/drivers/media/dvb-frontends/stv090x.c
++++ b/drivers/media/dvb-frontends/stv090x.c
+@@ -761,7 +761,9 @@ static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8
+ 
+ static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data)
+ {
+-	return stv090x_write_regs(state, reg, &data, 1);
++	u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++	return stv090x_write_regs(state, reg, &tmp, 1);
+ }
+ 
+ static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
+diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c
+index c611ad210b5c..924f16fee1fb 100644
+--- a/drivers/media/dvb-frontends/stv6110x.c
++++ b/drivers/media/dvb-frontends/stv6110x.c
+@@ -97,7 +97,9 @@ static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 da
+ 
+ static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
+ {
+-	return stv6110x_write_regs(stv6110x, reg, &data, 1);
++	u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++	return stv6110x_write_regs(stv6110x, reg, &tmp, 1);
+ }
+ 
+ static int stv6110x_init(struct dvb_frontend *fe)
+diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c
+index a9f6bbea6df3..103b9c824f1f 100644
+--- a/drivers/media/dvb-frontends/ts2020.c
++++ b/drivers/media/dvb-frontends/ts2020.c
+@@ -369,7 +369,7 @@ static int ts2020_read_tuner_gain(struct dvb_frontend *fe, unsigned v_agc,
+ 		gain2 = clamp_t(long, gain2, 0, 13);
+ 		v_agc = clamp_t(long, v_agc, 400, 1100);
+ 
+-		*_gain = -(gain1 * 2330 +
++		*_gain = -((__s64)gain1 * 2330 +
+ 			   gain2 * 3500 +
+ 			   v_agc * 24 / 10 * 10 +
+ 			   10000);
+@@ -387,7 +387,7 @@ static int ts2020_read_tuner_gain(struct dvb_frontend *fe, unsigned v_agc,
+ 		gain3 = clamp_t(long, gain3, 0, 6);
+ 		v_agc = clamp_t(long, v_agc, 600, 1600);
+ 
+-		*_gain = -(gain1 * 2650 +
++		*_gain = -((__s64)gain1 * 2650 +
+ 			   gain2 * 3380 +
+ 			   gain3 * 2850 +
+ 			   v_agc * 176 / 100 * 10 -
+diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c
+index f8c271be196c..0d2bef62ff05 100644
+--- a/drivers/media/dvb-frontends/zl10039.c
++++ b/drivers/media/dvb-frontends/zl10039.c
+@@ -138,7 +138,9 @@ static inline int zl10039_writereg(struct zl10039_state *state,
+ 				const enum zl10039_reg_addr reg,
+ 				const u8 val)
+ {
+-	return zl10039_write(state, reg, &val, 1);
++	const u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++	return zl10039_write(state, reg, &tmp, 1);
+ }
+ 
+ static int zl10039_init(struct dvb_frontend *fe)
+diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
+index 0e8fb89896c4..5c4aa247d650 100644
+--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
++++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
+@@ -504,18 +504,23 @@ static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
+ 
+ static int lme2510_return_status(struct dvb_usb_device *d)
+ {
+-	int ret = 0;
++	int ret;
+ 	u8 *data;
+ 
+-	data = kzalloc(10, GFP_KERNEL);
++	data = kzalloc(6, GFP_KERNEL);
+ 	if (!data)
+ 		return -ENOMEM;
+ 
+-	ret |= usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
+-			0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
+-	info("Firmware Status: %x (%x)", ret , data[2]);
++	ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
++			      0x06, 0x80, 0x0302, 0x00,
++			      data, 0x6, 200);
++	if (ret != 6)
++		ret = -EINVAL;
++	else
++		ret = data[2];
++
++	info("Firmware Status: %6ph", data);
+ 
+-	ret = (ret < 0) ? -ENODEV : data[2];
+ 	kfree(data);
+ 	return ret;
+ }
+@@ -1079,8 +1084,6 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
+ 
+ 		if (adap->fe[0]) {
+ 			info("FE Found M88RS2000");
+-			dvb_attach(ts2020_attach, adap->fe[0], &ts2020_config,
+-					&d->i2c_adap);
+ 			st->i2c_tuner_gate_w = 5;
+ 			st->i2c_tuner_gate_r = 5;
+ 			st->i2c_tuner_addr = 0x60;
+@@ -1146,17 +1149,18 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
+ 			ret = st->tuner_config;
+ 		break;
+ 	case TUNER_RS2000:
+-		ret = st->tuner_config;
++		if (dvb_attach(ts2020_attach, adap->fe[0],
++			       &ts2020_config, &d->i2c_adap))
++			ret = st->tuner_config;
+ 		break;
+ 	default:
+ 		break;
+ 	}
+ 
+-	if (ret)
++	if (ret) {
+ 		info("TUN Found %s tuner", tun_msg[ret]);
+-	else {
+-		info("TUN No tuner found --- resetting device");
+-		lme_coldreset(d);
++	} else {
++		info("TUN No tuner found");
+ 		return -ENODEV;
+ 	}
+ 
+@@ -1200,6 +1204,7 @@ static int lme2510_get_adapter_count(struct dvb_usb_device *d)
+ static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
+ {
+ 	struct lme2510_state *st = d->priv;
++	int status;
+ 
+ 	usb_reset_configuration(d->udev);
+ 
+@@ -1208,12 +1213,16 @@ static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
+ 
+ 	st->dvb_usb_lme2510_firmware = dvb_usb_lme2510_firmware;
+ 
+-	if (lme2510_return_status(d) == 0x44) {
++	status = lme2510_return_status(d);
++	if (status == 0x44) {
+ 		*name = lme_firmware_switch(d, 0);
+ 		return COLD;
+ 	}
+ 
+-	return 0;
++	if (status != 0x47)
++		return -EINVAL;
++
++	return WARM;
+ }
+ 
+ static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
+diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
+index 9fd43a37154c..b20f03d86e00 100644
+--- a/drivers/media/usb/dvb-usb/cxusb.c
++++ b/drivers/media/usb/dvb-usb/cxusb.c
+@@ -820,6 +820,8 @@ static int dvico_bluebird_xc2028_callback(void *ptr, int component,
+ 	case XC2028_RESET_CLK:
+ 		deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
+ 		break;
++	case XC2028_I2C_FLUSH:
++		break;
+ 	default:
+ 		deb_info("%s: unknown command %d, arg %d\n", __func__,
+ 			 command, arg);
+diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
+index caa55402052e..2868766893c8 100644
+--- a/drivers/media/usb/dvb-usb/dib0700_devices.c
++++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
+@@ -431,6 +431,7 @@ static int stk7700ph_xc3028_callback(void *ptr, int component,
+ 		state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+ 		break;
+ 	case XC2028_RESET_CLK:
++	case XC2028_I2C_FLUSH:
+ 		break;
+ 	default:
+ 		err("%s: unknown command %d, arg %d\n", __func__,
+diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c
+index a61d8fd63c12..a20b60ac66ca 100644
+--- a/drivers/media/usb/hdpvr/hdpvr-core.c
++++ b/drivers/media/usb/hdpvr/hdpvr-core.c
+@@ -295,7 +295,7 @@ static int hdpvr_probe(struct usb_interface *interface,
+ 	/* register v4l2_device early so it can be used for printks */
+ 	if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
+ 		dev_err(&interface->dev, "v4l2_device_register failed\n");
+-		goto error;
++		goto error_free_dev;
+ 	}
+ 
+ 	mutex_init(&dev->io_mutex);
+@@ -304,7 +304,7 @@ static int hdpvr_probe(struct usb_interface *interface,
+ 	dev->usbc_buf = kmalloc(64, GFP_KERNEL);
+ 	if (!dev->usbc_buf) {
+ 		v4l2_err(&dev->v4l2_dev, "Out of memory\n");
+-		goto error;
++		goto error_v4l2_unregister;
+ 	}
+ 
+ 	init_waitqueue_head(&dev->wait_buffer);
+@@ -342,13 +342,13 @@ static int hdpvr_probe(struct usb_interface *interface,
+ 	}
+ 	if (!dev->bulk_in_endpointAddr) {
+ 		v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n");
+-		goto error;
++		goto error_put_usb;
+ 	}
+ 
+ 	/* init the device */
+ 	if (hdpvr_device_init(dev)) {
+ 		v4l2_err(&dev->v4l2_dev, "device init failed\n");
+-		goto error;
++		goto error_put_usb;
+ 	}
+ 
+ 	mutex_lock(&dev->io_mutex);
+@@ -356,7 +356,7 @@ static int hdpvr_probe(struct usb_interface *interface,
+ 		mutex_unlock(&dev->io_mutex);
+ 		v4l2_err(&dev->v4l2_dev,
+ 			 "allocating transfer buffers failed\n");
+-		goto error;
++		goto error_put_usb;
+ 	}
+ 	mutex_unlock(&dev->io_mutex);
+ 
+@@ -364,7 +364,7 @@ static int hdpvr_probe(struct usb_interface *interface,
+ 	retval = hdpvr_register_i2c_adapter(dev);
+ 	if (retval < 0) {
+ 		v4l2_err(&dev->v4l2_dev, "i2c adapter register failed\n");
+-		goto error;
++		goto error_free_buffers;
+ 	}
+ 
+ 	client = hdpvr_register_ir_rx_i2c(dev);
+@@ -397,13 +397,17 @@ static int hdpvr_probe(struct usb_interface *interface,
+ reg_fail:
+ #if IS_ENABLED(CONFIG_I2C)
+ 	i2c_del_adapter(&dev->i2c_adapter);
++error_free_buffers:
+ #endif
++	hdpvr_free_buffers(dev);
++error_put_usb:
++	usb_put_dev(dev->udev);
++	kfree(dev->usbc_buf);
++error_v4l2_unregister:
++	v4l2_device_unregister(&dev->v4l2_dev);
++error_free_dev:
++	kfree(dev);
+ error:
+-	if (dev) {
+-		flush_work(&dev->worker);
+-		/* this frees allocated memory */
+-		hdpvr_delete(dev);
+-	}
+ 	return retval;
+ }
+ 
+diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+index dc51dd86377d..48a39222fdf9 100644
+--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
++++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+@@ -18,8 +18,18 @@
+ #include <linux/videodev2.h>
+ #include <linux/v4l2-subdev.h>
+ #include <media/v4l2-dev.h>
++#include <media/v4l2-fh.h>
++#include <media/v4l2-ctrls.h>
+ #include <media/v4l2-ioctl.h>
+ 
++/* Use the same argument order as copy_in_user */
++#define assign_in_user(to, from)					\
++({									\
++	typeof(*from) __assign_tmp;					\
++									\
++	get_user(__assign_tmp, from) || put_user(__assign_tmp, to);	\
++})
++
+ static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ {
+ 	long ret = -ENOIOCTLCMD;
+@@ -33,131 +43,88 @@ static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ 
+ struct v4l2_clip32 {
+ 	struct v4l2_rect        c;
+-	compat_caddr_t 		next;
++	compat_caddr_t		next;
+ };
+ 
+ struct v4l2_window32 {
+ 	struct v4l2_rect        w;
+-	__u32		  	field;	/* enum v4l2_field */
++	__u32			field;	/* enum v4l2_field */
+ 	__u32			chromakey;
+ 	compat_caddr_t		clips; /* actually struct v4l2_clip32 * */
+ 	__u32			clipcount;
+ 	compat_caddr_t		bitmap;
++	__u8                    global_alpha;
+ };
+ 
+-static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
+-{
+-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_window32)) ||
+-		copy_from_user(&kp->w, &up->w, sizeof(up->w)) ||
+-		get_user(kp->field, &up->field) ||
+-		get_user(kp->chromakey, &up->chromakey) ||
+-		get_user(kp->clipcount, &up->clipcount))
+-			return -EFAULT;
+-	if (kp->clipcount > 2048)
+-		return -EINVAL;
+-	if (kp->clipcount) {
+-		struct v4l2_clip32 __user *uclips;
+-		struct v4l2_clip __user *kclips;
+-		int n = kp->clipcount;
+-		compat_caddr_t p;
+-
+-		if (get_user(p, &up->clips))
+-			return -EFAULT;
+-		uclips = compat_ptr(p);
+-		kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
+-		kp->clips = kclips;
+-		while (--n >= 0) {
+-			if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
+-				return -EFAULT;
+-			if (put_user(n ? kclips + 1 : NULL, &kclips->next))
+-				return -EFAULT;
+-			uclips += 1;
+-			kclips += 1;
+-		}
+-	} else
+-		kp->clips = NULL;
+-	return 0;
+-}
+-
+-static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
+-{
+-	if (copy_to_user(&up->w, &kp->w, sizeof(kp->w)) ||
+-		put_user(kp->field, &up->field) ||
+-		put_user(kp->chromakey, &up->chromakey) ||
+-		put_user(kp->clipcount, &up->clipcount))
+-			return -EFAULT;
+-	return 0;
+-}
+-
+-static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
+-{
+-	if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
+-		return -EFAULT;
+-	return 0;
+-}
+-
+-static inline int get_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
+-				struct v4l2_pix_format_mplane __user *up)
+-{
+-	if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format_mplane)))
+-		return -EFAULT;
+-	return 0;
+-}
+-
+-static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
+-{
+-	if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
+-		return -EFAULT;
+-	return 0;
+-}
+-
+-static inline int put_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
+-				struct v4l2_pix_format_mplane __user *up)
++static int get_v4l2_window32(struct v4l2_window __user *kp,
++			     struct v4l2_window32 __user *up,
++			     void __user *aux_buf, u32 aux_space)
+ {
+-	if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format_mplane)))
++	struct v4l2_clip32 __user *uclips;
++	struct v4l2_clip __user *kclips;
++	compat_caddr_t p;
++	u32 clipcount;
++
++	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
++	    copy_in_user(&kp->w, &up->w, sizeof(up->w)) ||
++	    assign_in_user(&kp->field, &up->field) ||
++	    assign_in_user(&kp->chromakey, &up->chromakey) ||
++	    assign_in_user(&kp->global_alpha, &up->global_alpha) ||
++	    get_user(clipcount, &up->clipcount) ||
++	    put_user(clipcount, &kp->clipcount))
+ 		return -EFAULT;
+-	return 0;
+-}
++	if (clipcount > 2048)
++		return -EINVAL;
++	if (!clipcount)
++		return put_user(NULL, &kp->clips);
+ 
+-static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
+-{
+-	if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
++	if (get_user(p, &up->clips))
+ 		return -EFAULT;
+-	return 0;
+-}
+-
+-static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
+-{
+-	if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
++	uclips = compat_ptr(p);
++	if (aux_space < clipcount * sizeof(*kclips))
+ 		return -EFAULT;
+-	return 0;
+-}
+-
+-static inline int get_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up)
+-{
+-	if (copy_from_user(kp, up, sizeof(struct v4l2_sliced_vbi_format)))
++	kclips = aux_buf;
++	if (put_user(kclips, &kp->clips))
+ 		return -EFAULT;
+-	return 0;
+-}
+ 
+-static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up)
+-{
+-	if (copy_to_user(up, kp, sizeof(struct v4l2_sliced_vbi_format)))
+-		return -EFAULT;
++	while (clipcount--) {
++		if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
++			return -EFAULT;
++		if (put_user(clipcount ? kclips + 1 : NULL, &kclips->next))
++			return -EFAULT;
++		uclips++;
++		kclips++;
++	}
+ 	return 0;
+ }
+ 
+-static inline int get_v4l2_sdr_format(struct v4l2_sdr_format *kp, struct v4l2_sdr_format __user *up)
++static int put_v4l2_window32(struct v4l2_window __user *kp,
++			     struct v4l2_window32 __user *up)
+ {
+-	if (copy_from_user(kp, up, sizeof(struct v4l2_sdr_format)))
++	struct v4l2_clip __user *kclips = kp->clips;
++	struct v4l2_clip32 __user *uclips;
++	compat_caddr_t p;
++	u32 clipcount;
++
++	if (copy_in_user(&up->w, &kp->w, sizeof(kp->w)) ||
++	    assign_in_user(&up->field, &kp->field) ||
++	    assign_in_user(&up->chromakey, &kp->chromakey) ||
++	    assign_in_user(&up->global_alpha, &kp->global_alpha) ||
++	    get_user(clipcount, &kp->clipcount) ||
++	    put_user(clipcount, &up->clipcount))
+ 		return -EFAULT;
+-	return 0;
+-}
++	if (!clipcount)
++		return 0;
+ 
+-static inline int put_v4l2_sdr_format(struct v4l2_sdr_format *kp, struct v4l2_sdr_format __user *up)
+-{
+-	if (copy_to_user(up, kp, sizeof(struct v4l2_sdr_format)))
++	if (get_user(p, &up->clips))
+ 		return -EFAULT;
++	uclips = compat_ptr(p);
++	while (clipcount--) {
++		if (copy_in_user(&uclips->c, &kclips->c, sizeof(uclips->c)))
++			return -EFAULT;
++		uclips++;
++		kclips++;
++	}
+ 	return 0;
+ }
+ 
+@@ -191,97 +158,158 @@ struct v4l2_create_buffers32 {
+ 	__u32			reserved[8];
+ };
+ 
+-static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
++static int __bufsize_v4l2_format(struct v4l2_format32 __user *up, u32 *size)
++{
++	u32 type;
++
++	if (get_user(type, &up->type))
++		return -EFAULT;
++
++	switch (type) {
++	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
++	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
++		u32 clipcount;
++
++		if (get_user(clipcount, &up->fmt.win.clipcount))
++			return -EFAULT;
++		if (clipcount > 2048)
++			return -EINVAL;
++		*size = clipcount * sizeof(struct v4l2_clip);
++		return 0;
++	}
++	default:
++		*size = 0;
++		return 0;
++	}
++}
++
++static int bufsize_v4l2_format(struct v4l2_format32 __user *up, u32 *size)
+ {
+-	if (get_user(kp->type, &up->type))
++	if (!access_ok(VERIFY_READ, up, sizeof(*up)))
+ 		return -EFAULT;
++	return __bufsize_v4l2_format(up, size);
++}
+ 
+-	switch (kp->type) {
++static int __get_v4l2_format32(struct v4l2_format __user *kp,
++			       struct v4l2_format32 __user *up,
++			       void __user *aux_buf, u32 aux_space)
++{
++	u32 type;
++
++	if (get_user(type, &up->type) || put_user(type, &kp->type))
++		return -EFAULT;
++
++	switch (type) {
+ 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+-		return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
++		return copy_in_user(&kp->fmt.pix, &up->fmt.pix,
++				    sizeof(kp->fmt.pix)) ? -EFAULT : 0;
+ 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+-		return get_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
+-						  &up->fmt.pix_mp);
++		return copy_in_user(&kp->fmt.pix_mp, &up->fmt.pix_mp,
++				    sizeof(kp->fmt.pix_mp)) ? -EFAULT : 0;
+ 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+-		return get_v4l2_window32(&kp->fmt.win, &up->fmt.win);
++		return get_v4l2_window32(&kp->fmt.win, &up->fmt.win,
++					 aux_buf, aux_space);
+ 	case V4L2_BUF_TYPE_VBI_CAPTURE:
+ 	case V4L2_BUF_TYPE_VBI_OUTPUT:
+-		return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
++		return copy_in_user(&kp->fmt.vbi, &up->fmt.vbi,
++				    sizeof(kp->fmt.vbi)) ? -EFAULT : 0;
+ 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+-		return get_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
++		return copy_in_user(&kp->fmt.sliced, &up->fmt.sliced,
++				    sizeof(kp->fmt.sliced)) ? -EFAULT : 0;
+ 	case V4L2_BUF_TYPE_SDR_CAPTURE:
+ 	case V4L2_BUF_TYPE_SDR_OUTPUT:
+-		return get_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr);
++		return copy_in_user(&kp->fmt.sdr, &up->fmt.sdr,
++				    sizeof(kp->fmt.sdr)) ? -EFAULT : 0;
+ 	default:
+-		pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
+-								kp->type);
+ 		return -EINVAL;
+ 	}
+ }
+ 
+-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
++static int get_v4l2_format32(struct v4l2_format __user *kp,
++			     struct v4l2_format32 __user *up,
++			     void __user *aux_buf, u32 aux_space)
+ {
+-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)))
++	if (!access_ok(VERIFY_READ, up, sizeof(*up)))
+ 		return -EFAULT;
+-	return __get_v4l2_format32(kp, up);
++	return __get_v4l2_format32(kp, up, aux_buf, aux_space);
+ }
+ 
+-static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
++static int bufsize_v4l2_create(struct v4l2_create_buffers32 __user *up,
++			       u32 *size)
+ {
+-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
+-	    copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format)))
++	if (!access_ok(VERIFY_READ, up, sizeof(*up)))
+ 		return -EFAULT;
+-	return __get_v4l2_format32(&kp->format, &up->format);
++	return __bufsize_v4l2_format(&up->format, size);
+ }
+ 
+-static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
++static int get_v4l2_create32(struct v4l2_create_buffers __user *kp,
++			     struct v4l2_create_buffers32 __user *up,
++			     void __user *aux_buf, u32 aux_space)
+ {
+-	if (put_user(kp->type, &up->type))
++	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
++	    copy_in_user(kp, up,
++			 offsetof(struct v4l2_create_buffers32, format)))
+ 		return -EFAULT;
++	return __get_v4l2_format32(&kp->format, &up->format,
++				   aux_buf, aux_space);
++}
++
++static int __put_v4l2_format32(struct v4l2_format __user *kp,
++			       struct v4l2_format32 __user *up)
++{
++	u32 type;
+ 
+-	switch (kp->type) {
++	if (get_user(type, &kp->type))
++		return -EFAULT;
++
++	switch (type) {
+ 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+-		return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
++		return copy_in_user(&up->fmt.pix, &kp->fmt.pix,
++				    sizeof(kp->fmt.pix)) ? -EFAULT : 0;
+ 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+-		return put_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
+-						  &up->fmt.pix_mp);
++		return copy_in_user(&up->fmt.pix_mp, &kp->fmt.pix_mp,
++				    sizeof(kp->fmt.pix_mp)) ? -EFAULT : 0;
+ 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+ 		return put_v4l2_window32(&kp->fmt.win, &up->fmt.win);
+ 	case V4L2_BUF_TYPE_VBI_CAPTURE:
+ 	case V4L2_BUF_TYPE_VBI_OUTPUT:
+-		return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
++		return copy_in_user(&up->fmt.vbi, &kp->fmt.vbi,
++				    sizeof(kp->fmt.vbi)) ? -EFAULT : 0;
+ 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+-		return put_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
++		return copy_in_user(&up->fmt.sliced, &kp->fmt.sliced,
++				    sizeof(kp->fmt.sliced)) ? -EFAULT : 0;
+ 	case V4L2_BUF_TYPE_SDR_CAPTURE:
+ 	case V4L2_BUF_TYPE_SDR_OUTPUT:
+-		return put_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr);
++		return copy_in_user(&up->fmt.sdr, &kp->fmt.sdr,
++				    sizeof(kp->fmt.sdr)) ? -EFAULT : 0;
+ 	default:
+-		pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
+-								kp->type);
+ 		return -EINVAL;
+ 	}
+ }
+ 
+-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
++static int put_v4l2_format32(struct v4l2_format __user *kp,
++			     struct v4l2_format32 __user *up)
+ {
+-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)))
++	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)))
+ 		return -EFAULT;
+ 	return __put_v4l2_format32(kp, up);
+ }
+ 
+-static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
++static int put_v4l2_create32(struct v4l2_create_buffers __user *kp,
++			     struct v4l2_create_buffers32 __user *up)
+ {
+-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
+-	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format)) ||
+-	    copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
++	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
++	    copy_in_user(up, kp,
++			 offsetof(struct v4l2_create_buffers32, format)) ||
++	    copy_in_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
+ 		return -EFAULT;
+ 	return __put_v4l2_format32(&kp->format, &up->format);
+ }
+@@ -295,25 +323,28 @@ struct v4l2_standard32 {
+ 	__u32		     reserved[4];
+ };
+ 
+-static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
++static int get_v4l2_standard32(struct v4l2_standard __user *kp,
++			       struct v4l2_standard32 __user *up)
+ {
+ 	/* other fields are not set by the user, nor used by the driver */
+-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard32)) ||
+-		get_user(kp->index, &up->index))
++	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
++	    assign_in_user(&kp->index, &up->index))
+ 		return -EFAULT;
+ 	return 0;
+ }
+ 
+-static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
++static int put_v4l2_standard32(struct v4l2_standard __user *kp,
++			       struct v4l2_standard32 __user *up)
+ {
+-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
+-		put_user(kp->index, &up->index) ||
+-		put_user(kp->id, &up->id) ||
+-		copy_to_user(up->name, kp->name, 24) ||
+-		copy_to_user(&up->frameperiod, &kp->frameperiod, sizeof(kp->frameperiod)) ||
+-		put_user(kp->framelines, &up->framelines) ||
+-		copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32)))
+-			return -EFAULT;
++	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
++	    assign_in_user(&up->index, &kp->index) ||
++	    assign_in_user(&up->id, &kp->id) ||
++	    copy_in_user(up->name, kp->name, sizeof(up->name)) ||
++	    copy_in_user(&up->frameperiod, &kp->frameperiod,
++			 sizeof(up->frameperiod)) ||
++	    assign_in_user(&up->framelines, &kp->framelines) ||
++	    copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
++		return -EFAULT;
+ 	return 0;
+ }
+ 
+@@ -352,134 +383,186 @@ struct v4l2_buffer32 {
+ 	__u32			reserved;
+ };
+ 
+-static int get_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __user *up32,
+-				enum v4l2_memory memory)
++static int get_v4l2_plane32(struct v4l2_plane __user *up,
++			    struct v4l2_plane32 __user *up32,
++			    enum v4l2_memory memory)
+ {
+-	void __user *up_pln;
+-	compat_long_t p;
++	compat_ulong_t p;
+ 
+ 	if (copy_in_user(up, up32, 2 * sizeof(__u32)) ||
+-		copy_in_user(&up->data_offset, &up32->data_offset,
+-				sizeof(__u32)))
++	    copy_in_user(&up->data_offset, &up32->data_offset,
++			 sizeof(up->data_offset)))
+ 		return -EFAULT;
+ 
+-	if (memory == V4L2_MEMORY_USERPTR) {
+-		if (get_user(p, &up32->m.userptr))
+-			return -EFAULT;
+-		up_pln = compat_ptr(p);
+-		if (put_user((unsigned long)up_pln, &up->m.userptr))
++	switch (memory) {
++	case V4L2_MEMORY_MMAP:
++	case V4L2_MEMORY_OVERLAY:
++		if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
++				 sizeof(up32->m.mem_offset)))
+ 			return -EFAULT;
+-	} else if (memory == V4L2_MEMORY_DMABUF) {
+-		if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(int)))
++		break;
++	case V4L2_MEMORY_USERPTR:
++		if (get_user(p, &up32->m.userptr) ||
++		    put_user((unsigned long)compat_ptr(p), &up->m.userptr))
+ 			return -EFAULT;
+-	} else {
+-		if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
+-					sizeof(__u32)))
++		break;
++	case V4L2_MEMORY_DMABUF:
++		if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(up32->m.fd)))
+ 			return -EFAULT;
++		break;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-static int put_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __user *up32,
+-				enum v4l2_memory memory)
++static int put_v4l2_plane32(struct v4l2_plane __user *up,
++			    struct v4l2_plane32 __user *up32,
++			    enum v4l2_memory memory)
+ {
++	unsigned long p;
++
+ 	if (copy_in_user(up32, up, 2 * sizeof(__u32)) ||
+-		copy_in_user(&up32->data_offset, &up->data_offset,
+-				sizeof(__u32)))
++	    copy_in_user(&up32->data_offset, &up->data_offset,
++			 sizeof(up->data_offset)))
+ 		return -EFAULT;
+ 
+-	/* For MMAP, driver might've set up the offset, so copy it back.
+-	 * USERPTR stays the same (was userspace-provided), so no copying. */
+-	if (memory == V4L2_MEMORY_MMAP)
++	switch (memory) {
++	case V4L2_MEMORY_MMAP:
++	case V4L2_MEMORY_OVERLAY:
+ 		if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset,
+-					sizeof(__u32)))
++				 sizeof(up->m.mem_offset)))
+ 			return -EFAULT;
+-	/* For DMABUF, driver might've set up the fd, so copy it back. */
+-	if (memory == V4L2_MEMORY_DMABUF)
+-		if (copy_in_user(&up32->m.fd, &up->m.fd,
+-					sizeof(int)))
++		break;
++	case V4L2_MEMORY_USERPTR:
++		if (get_user(p, &up->m.userptr) ||
++		    put_user((compat_ulong_t)ptr_to_compat((__force void *)p),
++			     &up32->m.userptr))
++			return -EFAULT;
++		break;
++	case V4L2_MEMORY_DMABUF:
++		if (copy_in_user(&up32->m.fd, &up->m.fd, sizeof(up->m.fd)))
+ 			return -EFAULT;
++		break;
++	}
+ 
+ 	return 0;
+ }
+ 
+-static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
++static int bufsize_v4l2_buffer(struct v4l2_buffer32 __user *up, u32 *size)
+ {
++	u32 type;
++	u32 length;
++
++	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
++	    get_user(type, &up->type) ||
++	    get_user(length, &up->length))
++		return -EFAULT;
++
++	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
++		if (length > VIDEO_MAX_PLANES)
++			return -EINVAL;
++
++		/*
++		 * We don't really care if userspace decides to kill itself
++		 * by passing a very big length value
++		 */
++		*size = length * sizeof(struct v4l2_plane);
++	} else {
++		*size = 0;
++	}
++	return 0;
++}
++
++static int get_v4l2_buffer32(struct v4l2_buffer __user *kp,
++			     struct v4l2_buffer32 __user *up,
++			     void __user *aux_buf, u32 aux_space)
++{
++	u32 type;
++	u32 length;
++	enum v4l2_memory memory;
+ 	struct v4l2_plane32 __user *uplane32;
+ 	struct v4l2_plane __user *uplane;
+ 	compat_caddr_t p;
+-	int num_planes;
+ 	int ret;
+ 
+-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) ||
+-		get_user(kp->index, &up->index) ||
+-		get_user(kp->type, &up->type) ||
+-		get_user(kp->flags, &up->flags) ||
+-		get_user(kp->memory, &up->memory) ||
+-		get_user(kp->length, &up->length))
+-			return -EFAULT;
++	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
++	    assign_in_user(&kp->index, &up->index) ||
++	    get_user(type, &up->type) ||
++	    put_user(type, &kp->type) ||
++	    assign_in_user(&kp->flags, &up->flags) ||
++	    get_user(memory, &up->memory) ||
++	    put_user(memory, &kp->memory) ||
++	    get_user(length, &up->length) ||
++	    put_user(length, &kp->length))
++		return -EFAULT;
+ 
+-	if (V4L2_TYPE_IS_OUTPUT(kp->type))
+-		if (get_user(kp->bytesused, &up->bytesused) ||
+-			get_user(kp->field, &up->field) ||
+-			get_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
+-			get_user(kp->timestamp.tv_usec,
+-					&up->timestamp.tv_usec))
++	if (V4L2_TYPE_IS_OUTPUT(type))
++		if (assign_in_user(&kp->bytesused, &up->bytesused) ||
++		    assign_in_user(&kp->field, &up->field) ||
++		    assign_in_user(&kp->timestamp.tv_sec,
++				   &up->timestamp.tv_sec) ||
++		    assign_in_user(&kp->timestamp.tv_usec,
++				   &up->timestamp.tv_usec))
+ 			return -EFAULT;
+ 
+-	if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
+-		num_planes = kp->length;
++	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
++		u32 num_planes = length;
++
+ 		if (num_planes == 0) {
+-			kp->m.planes = NULL;
+-			/* num_planes == 0 is legal, e.g. when userspace doesn't
+-			 * need planes array on DQBUF*/
+-			return 0;
++			/*
++			 * num_planes == 0 is legal, e.g. when userspace doesn't
++			 * need planes array on DQBUF
++			 */
++			return put_user(NULL, &kp->m.planes);
+ 		}
++		if (num_planes > VIDEO_MAX_PLANES)
++			return -EINVAL;
+ 
+ 		if (get_user(p, &up->m.planes))
+ 			return -EFAULT;
+ 
+ 		uplane32 = compat_ptr(p);
+ 		if (!access_ok(VERIFY_READ, uplane32,
+-				num_planes * sizeof(struct v4l2_plane32)))
++			       num_planes * sizeof(*uplane32)))
+ 			return -EFAULT;
+ 
+-		/* We don't really care if userspace decides to kill itself
+-		 * by passing a very big num_planes value */
+-		uplane = compat_alloc_user_space(num_planes *
+-						sizeof(struct v4l2_plane));
+-		kp->m.planes = (__force struct v4l2_plane *)uplane;
++		/*
++		 * We don't really care if userspace decides to kill itself
++		 * by passing a very big num_planes value
++		 */
++		if (aux_space < num_planes * sizeof(*uplane))
++			return -EFAULT;
++
++		uplane = aux_buf;
++		if (put_user((__force struct v4l2_plane *)uplane,
++			     &kp->m.planes))
++			return -EFAULT;
+ 
+-		while (--num_planes >= 0) {
+-			ret = get_v4l2_plane32(uplane, uplane32, kp->memory);
++		while (num_planes--) {
++			ret = get_v4l2_plane32(uplane, uplane32, memory);
+ 			if (ret)
+ 				return ret;
+-			++uplane;
+-			++uplane32;
++			uplane++;
++			uplane32++;
+ 		}
+ 	} else {
+-		switch (kp->memory) {
++		switch (memory) {
+ 		case V4L2_MEMORY_MMAP:
+-			if (get_user(kp->m.offset, &up->m.offset))
++		case V4L2_MEMORY_OVERLAY:
++			if (assign_in_user(&kp->m.offset, &up->m.offset))
+ 				return -EFAULT;
+ 			break;
+-		case V4L2_MEMORY_USERPTR:
+-			{
+-			compat_long_t tmp;
++		case V4L2_MEMORY_USERPTR: {
++			compat_ulong_t userptr;
+ 
+-			if (get_user(tmp, &up->m.userptr))
+-				return -EFAULT;
+-
+-			kp->m.userptr = (unsigned long)compat_ptr(tmp);
+-			}
+-			break;
+-		case V4L2_MEMORY_OVERLAY:
+-			if (get_user(kp->m.offset, &up->m.offset))
++			if (get_user(userptr, &up->m.userptr) ||
++			    put_user((unsigned long)compat_ptr(userptr),
++				     &kp->m.userptr))
+ 				return -EFAULT;
+ 			break;
++		}
+ 		case V4L2_MEMORY_DMABUF:
+-			if (get_user(kp->m.fd, &up->m.fd))
++			if (assign_in_user(&kp->m.fd, &up->m.fd))
+ 				return -EFAULT;
+ 			break;
+ 		}
+@@ -488,65 +571,70 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
+ 	return 0;
+ }
+ 
+-static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
++static int put_v4l2_buffer32(struct v4l2_buffer __user *kp,
++			     struct v4l2_buffer32 __user *up)
+ {
++	u32 type;
++	u32 length;
++	enum v4l2_memory memory;
+ 	struct v4l2_plane32 __user *uplane32;
+ 	struct v4l2_plane __user *uplane;
+ 	compat_caddr_t p;
+-	int num_planes;
+ 	int ret;
+ 
+-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) ||
+-		put_user(kp->index, &up->index) ||
+-		put_user(kp->type, &up->type) ||
+-		put_user(kp->flags, &up->flags) ||
+-		put_user(kp->memory, &up->memory))
+-			return -EFAULT;
++	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
++	    assign_in_user(&up->index, &kp->index) ||
++	    get_user(type, &kp->type) ||
++	    put_user(type, &up->type) ||
++	    assign_in_user(&up->flags, &kp->flags) ||
++	    get_user(memory, &kp->memory) ||
++	    put_user(memory, &up->memory))
++		return -EFAULT;
+ 
+-	if (put_user(kp->bytesused, &up->bytesused) ||
+-		put_user(kp->field, &up->field) ||
+-		put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
+-		put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec) ||
+-		copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) ||
+-		put_user(kp->sequence, &up->sequence) ||
+-		put_user(kp->reserved2, &up->reserved2) ||
+-		put_user(kp->reserved, &up->reserved) ||
+-		put_user(kp->length, &up->length))
+-			return -EFAULT;
++	if (assign_in_user(&up->bytesused, &kp->bytesused) ||
++	    assign_in_user(&up->field, &kp->field) ||
++	    assign_in_user(&up->timestamp.tv_sec, &kp->timestamp.tv_sec) ||
++	    assign_in_user(&up->timestamp.tv_usec, &kp->timestamp.tv_usec) ||
++	    copy_in_user(&up->timecode, &kp->timecode, sizeof(kp->timecode)) ||
++	    assign_in_user(&up->sequence, &kp->sequence) ||
++	    assign_in_user(&up->reserved2, &kp->reserved2) ||
++	    assign_in_user(&up->reserved, &kp->reserved) ||
++	    get_user(length, &kp->length) ||
++	    put_user(length, &up->length))
++		return -EFAULT;
++
++	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
++		u32 num_planes = length;
+ 
+-	if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
+-		num_planes = kp->length;
+ 		if (num_planes == 0)
+ 			return 0;
+ 
+-		uplane = (__force struct v4l2_plane __user *)kp->m.planes;
++		if (get_user(uplane, ((__force struct v4l2_plane __user **)&kp->m.planes)))
++			return -EFAULT;
+ 		if (get_user(p, &up->m.planes))
+ 			return -EFAULT;
+ 		uplane32 = compat_ptr(p);
+ 
+-		while (--num_planes >= 0) {
+-			ret = put_v4l2_plane32(uplane, uplane32, kp->memory);
++		while (num_planes--) {
++			ret = put_v4l2_plane32(uplane, uplane32, memory);
+ 			if (ret)
+ 				return ret;
+ 			++uplane;
+ 			++uplane32;
+ 		}
+ 	} else {
+-		switch (kp->memory) {
++		switch (memory) {
+ 		case V4L2_MEMORY_MMAP:
+-			if (put_user(kp->m.offset, &up->m.offset))
++		case V4L2_MEMORY_OVERLAY:
++			if (assign_in_user(&up->m.offset, &kp->m.offset))
+ 				return -EFAULT;
+ 			break;
+ 		case V4L2_MEMORY_USERPTR:
+-			if (put_user(kp->m.userptr, &up->m.userptr))
+-				return -EFAULT;
+-			break;
+-		case V4L2_MEMORY_OVERLAY:
+-			if (put_user(kp->m.offset, &up->m.offset))
++			if (assign_in_user(&up->m.userptr, &kp->m.userptr))
+ 				return -EFAULT;
+ 			break;
+ 		case V4L2_MEMORY_DMABUF:
+-			if (put_user(kp->m.fd, &up->m.fd))
++			if (assign_in_user(&up->m.fd, &kp->m.fd))
+ 				return -EFAULT;
+ 			break;
+ 		}
+@@ -558,7 +646,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
+ struct v4l2_framebuffer32 {
+ 	__u32			capability;
+ 	__u32			flags;
+-	compat_caddr_t 		base;
++	compat_caddr_t		base;
+ 	struct {
+ 		__u32		width;
+ 		__u32		height;
+@@ -571,30 +659,33 @@ struct v4l2_framebuffer32 {
+ 	} fmt;
+ };
+ 
+-static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
++static int get_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp,
++				  struct v4l2_framebuffer32 __user *up)
+ {
+-	u32 tmp;
+-
+-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_framebuffer32)) ||
+-		get_user(tmp, &up->base) ||
+-		get_user(kp->capability, &up->capability) ||
+-		get_user(kp->flags, &up->flags) ||
+-		copy_from_user(&kp->fmt, &up->fmt, sizeof(up->fmt)))
+-			return -EFAULT;
+-	kp->base = (__force void *)compat_ptr(tmp);
++	compat_caddr_t tmp;
++
++	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
++	    get_user(tmp, &up->base) ||
++	    put_user((__force void *)compat_ptr(tmp), &kp->base) ||
++	    assign_in_user(&kp->capability, &up->capability) ||
++	    assign_in_user(&kp->flags, &up->flags) ||
++	    copy_in_user(&kp->fmt, &up->fmt, sizeof(kp->fmt)))
++		return -EFAULT;
+ 	return 0;
+ }
+ 
+-static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
++static int put_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp,
++				  struct v4l2_framebuffer32 __user *up)
+ {
+-	u32 tmp = (u32)((unsigned long)kp->base);
+-
+-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) ||
+-		put_user(tmp, &up->base) ||
+-		put_user(kp->capability, &up->capability) ||
+-		put_user(kp->flags, &up->flags) ||
+-		copy_to_user(&up->fmt, &kp->fmt, sizeof(up->fmt)))
+-			return -EFAULT;
++	void *base;
++
++	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
++	    get_user(base, &kp->base) ||
++	    put_user(ptr_to_compat(base), &up->base) ||
++	    assign_in_user(&up->capability, &kp->capability) ||
++	    assign_in_user(&up->flags, &kp->flags) ||
++	    copy_in_user(&up->fmt, &kp->fmt, sizeof(kp->fmt)))
++		return -EFAULT;
+ 	return 0;
+ }
+ 
+@@ -606,21 +697,26 @@ struct v4l2_input32 {
+ 	__u32        tuner;             /*  Associated tuner */
+ 	compat_u64   std;
+ 	__u32	     status;
+-	__u32	     reserved[4];
++	__u32	     capabilities;
++	__u32	     reserved[3];
+ };
+ 
+-/* The 64-bit v4l2_input struct has extra padding at the end of the struct.
+-   Otherwise it is identical to the 32-bit version. */
+-static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
++/*
++ * The 64-bit v4l2_input struct has extra padding at the end of the struct.
++ * Otherwise it is identical to the 32-bit version.
++ */
++static inline int get_v4l2_input32(struct v4l2_input __user *kp,
++				   struct v4l2_input32 __user *up)
+ {
+-	if (copy_from_user(kp, up, sizeof(struct v4l2_input32)))
++	if (copy_in_user(kp, up, sizeof(*up)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+ 
+-static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
++static inline int put_v4l2_input32(struct v4l2_input __user *kp,
++				   struct v4l2_input32 __user *up)
+ {
+-	if (copy_to_user(up, kp, sizeof(struct v4l2_input32)))
++	if (copy_in_user(up, kp, sizeof(*up)))
+ 		return -EFAULT;
+ 	return 0;
+ }
+@@ -644,58 +740,95 @@ struct v4l2_ext_control32 {
+ 	};
+ } __attribute__ ((packed));
+ 
+-/* The following function really belong in v4l2-common, but that causes
+-   a circular dependency between modules. We need to think about this, but
+-   for now this will do. */
+-
+-/* Return non-zero if this control is a pointer type. Currently only
+-   type STRING is a pointer type. */
+-static inline int ctrl_is_pointer(u32 id)
++/* Return true if this control is a pointer type. */
++static inline bool ctrl_is_pointer(struct file *file, u32 id)
+ {
+-	switch (id) {
+-	case V4L2_CID_RDS_TX_PS_NAME:
+-	case V4L2_CID_RDS_TX_RADIO_TEXT:
+-		return 1;
+-	default:
+-		return 0;
++	struct video_device *vdev = video_devdata(file);
++	struct v4l2_fh *fh = NULL;
++	struct v4l2_ctrl_handler *hdl = NULL;
++	struct v4l2_query_ext_ctrl qec = { id };
++	const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
++
++	if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags))
++		fh = file->private_data;
++
++	if (fh && fh->ctrl_handler)
++		hdl = fh->ctrl_handler;
++	else if (vdev->ctrl_handler)
++		hdl = vdev->ctrl_handler;
++
++	if (hdl) {
++		struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, id);
++
++		return ctrl && ctrl->is_ptr;
+ 	}
++
++	if (!ops || !ops->vidioc_query_ext_ctrl)
++		return false;
++
++	return !ops->vidioc_query_ext_ctrl(file, fh, &qec) &&
++		(qec.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD);
++}
++
++static int bufsize_v4l2_ext_controls(struct v4l2_ext_controls32 __user *up,
++				     u32 *size)
++{
++	u32 count;
++
++	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
++	    get_user(count, &up->count))
++		return -EFAULT;
++	if (count > V4L2_CID_MAX_CTRLS)
++		return -EINVAL;
++	*size = count * sizeof(struct v4l2_ext_control);
++	return 0;
+ }
+ 
+-static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
++static int get_v4l2_ext_controls32(struct file *file,
++				   struct v4l2_ext_controls __user *kp,
++				   struct v4l2_ext_controls32 __user *up,
++				   void __user *aux_buf, u32 aux_space)
+ {
+ 	struct v4l2_ext_control32 __user *ucontrols;
+ 	struct v4l2_ext_control __user *kcontrols;
+-	int n;
++	u32 count;
++	u32 n;
+ 	compat_caddr_t p;
+ 
+-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_ext_controls32)) ||
+-		get_user(kp->which, &up->which) ||
+-		get_user(kp->count, &up->count) ||
+-		get_user(kp->error_idx, &up->error_idx) ||
+-		copy_from_user(kp->reserved, up->reserved,
+-			       sizeof(kp->reserved)))
+-			return -EFAULT;
+-	n = kp->count;
+-	if (n == 0) {
+-		kp->controls = NULL;
+-		return 0;
+-	}
++	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
++	    assign_in_user(&kp->which, &up->which) ||
++	    get_user(count, &up->count) ||
++	    put_user(count, &kp->count) ||
++	    assign_in_user(&kp->error_idx, &up->error_idx) ||
++	    copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
++		return -EFAULT;
++
++	if (count == 0)
++		return put_user(NULL, &kp->controls);
++	if (count > V4L2_CID_MAX_CTRLS)
++		return -EINVAL;
+ 	if (get_user(p, &up->controls))
+ 		return -EFAULT;
+ 	ucontrols = compat_ptr(p);
+-	if (!access_ok(VERIFY_READ, ucontrols,
+-			n * sizeof(struct v4l2_ext_control32)))
++	if (!access_ok(VERIFY_READ, ucontrols, count * sizeof(*ucontrols)))
++		return -EFAULT;
++	if (aux_space < count * sizeof(*kcontrols))
+ 		return -EFAULT;
+-	kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control));
+-	kp->controls = (__force struct v4l2_ext_control *)kcontrols;
+-	while (--n >= 0) {
++	kcontrols = aux_buf;
++	if (put_user((__force struct v4l2_ext_control *)kcontrols,
++		     &kp->controls))
++		return -EFAULT;
++
++	for (n = 0; n < count; n++) {
+ 		u32 id;
+ 
+ 		if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols)))
+ 			return -EFAULT;
++
+ 		if (get_user(id, &kcontrols->id))
+ 			return -EFAULT;
+-		if (ctrl_is_pointer(id)) {
++
++		if (ctrl_is_pointer(file, id)) {
+ 			void __user *s;
+ 
+ 			if (get_user(p, &ucontrols->string))
+@@ -710,43 +843,55 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
+ 	return 0;
+ }
+ 
+-static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
++static int put_v4l2_ext_controls32(struct file *file,
++				   struct v4l2_ext_controls __user *kp,
++				   struct v4l2_ext_controls32 __user *up)
+ {
+ 	struct v4l2_ext_control32 __user *ucontrols;
+-	struct v4l2_ext_control __user *kcontrols =
+-		(__force struct v4l2_ext_control __user *)kp->controls;
+-	int n = kp->count;
++	struct v4l2_ext_control __user *kcontrols;
++	u32 count;
++	u32 n;
+ 	compat_caddr_t p;
+ 
+-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_ext_controls32)) ||
+-		put_user(kp->which, &up->which) ||
+-		put_user(kp->count, &up->count) ||
+-		put_user(kp->error_idx, &up->error_idx) ||
+-		copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved)))
+-			return -EFAULT;
+-	if (!kp->count)
+-		return 0;
++	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
++	    assign_in_user(&up->which, &kp->which) ||
++	    get_user(count, &kp->count) ||
++	    put_user(count, &up->count) ||
++	    assign_in_user(&up->error_idx, &kp->error_idx) ||
++	    copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)) ||
++	    get_user(kcontrols, &kp->controls))
++		return -EFAULT;
+ 
++	if (!count)
++		return 0;
+ 	if (get_user(p, &up->controls))
+ 		return -EFAULT;
+ 	ucontrols = compat_ptr(p);
+-	if (!access_ok(VERIFY_WRITE, ucontrols,
+-			n * sizeof(struct v4l2_ext_control32)))
++	if (!access_ok(VERIFY_WRITE, ucontrols, count * sizeof(*ucontrols)))
+ 		return -EFAULT;
+ 
+-	while (--n >= 0) {
+-		unsigned size = sizeof(*ucontrols);
++	for (n = 0; n < count; n++) {
++		unsigned int size = sizeof(*ucontrols);
+ 		u32 id;
+ 
+-		if (get_user(id, &kcontrols->id))
++		if (get_user(id, &kcontrols->id) ||
++		    put_user(id, &ucontrols->id) ||
++		    assign_in_user(&ucontrols->size, &kcontrols->size) ||
++		    copy_in_user(&ucontrols->reserved2, &kcontrols->reserved2,
++				 sizeof(ucontrols->reserved2)))
+ 			return -EFAULT;
+-		/* Do not modify the pointer when copying a pointer control.
+-		   The contents of the pointer was changed, not the pointer
+-		   itself. */
+-		if (ctrl_is_pointer(id))
++
++		/*
++		 * Do not modify the pointer when copying a pointer control.
++		 * The contents of the pointer was changed, not the pointer
++		 * itself.
++		 */
++		if (ctrl_is_pointer(file, id))
+ 			size -= sizeof(ucontrols->value64);
++
+ 		if (copy_in_user(ucontrols, kcontrols, size))
+ 			return -EFAULT;
++
+ 		ucontrols++;
+ 		kcontrols++;
+ 	}
+@@ -766,18 +911,19 @@ struct v4l2_event32 {
+ 	__u32				reserved[8];
+ };
+ 
+-static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *up)
++static int put_v4l2_event32(struct v4l2_event __user *kp,
++			    struct v4l2_event32 __user *up)
+ {
+-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_event32)) ||
+-		put_user(kp->type, &up->type) ||
+-		copy_to_user(&up->u, &kp->u, sizeof(kp->u)) ||
+-		put_user(kp->pending, &up->pending) ||
+-		put_user(kp->sequence, &up->sequence) ||
+-		put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
+-		put_user(kp->timestamp.tv_nsec, &up->timestamp.tv_nsec) ||
+-		put_user(kp->id, &up->id) ||
+-		copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32)))
+-			return -EFAULT;
++	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
++	    assign_in_user(&up->type, &kp->type) ||
++	    copy_in_user(&up->u, &kp->u, sizeof(kp->u)) ||
++	    assign_in_user(&up->pending, &kp->pending) ||
++	    assign_in_user(&up->sequence, &kp->sequence) ||
++	    assign_in_user(&up->timestamp.tv_sec, &kp->timestamp.tv_sec) ||
++	    assign_in_user(&up->timestamp.tv_nsec, &kp->timestamp.tv_nsec) ||
++	    assign_in_user(&up->id, &kp->id) ||
++	    copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
++		return -EFAULT;
+ 	return 0;
+ }
+ 
+@@ -789,32 +935,35 @@ struct v4l2_edid32 {
+ 	compat_caddr_t edid;
+ };
+ 
+-static int get_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
++static int get_v4l2_edid32(struct v4l2_edid __user *kp,
++			   struct v4l2_edid32 __user *up)
+ {
+-	u32 tmp;
+-
+-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_edid32)) ||
+-		get_user(kp->pad, &up->pad) ||
+-		get_user(kp->start_block, &up->start_block) ||
+-		get_user(kp->blocks, &up->blocks) ||
+-		get_user(tmp, &up->edid) ||
+-		copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
+-			return -EFAULT;
+-	kp->edid = (__force u8 *)compat_ptr(tmp);
++	compat_uptr_t tmp;
++
++	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
++	    assign_in_user(&kp->pad, &up->pad) ||
++	    assign_in_user(&kp->start_block, &up->start_block) ||
++	    assign_in_user(&kp->blocks, &up->blocks) ||
++	    get_user(tmp, &up->edid) ||
++	    put_user(compat_ptr(tmp), &kp->edid) ||
++	    copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
++		return -EFAULT;
+ 	return 0;
+ }
+ 
+-static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
++static int put_v4l2_edid32(struct v4l2_edid __user *kp,
++			   struct v4l2_edid32 __user *up)
+ {
+-	u32 tmp = (u32)((unsigned long)kp->edid);
+-
+-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_edid32)) ||
+-		put_user(kp->pad, &up->pad) ||
+-		put_user(kp->start_block, &up->start_block) ||
+-		put_user(kp->blocks, &up->blocks) ||
+-		put_user(tmp, &up->edid) ||
+-		copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved)))
+-			return -EFAULT;
++	void *edid;
++
++	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
++	    assign_in_user(&up->pad, &kp->pad) ||
++	    assign_in_user(&up->start_block, &kp->start_block) ||
++	    assign_in_user(&up->blocks, &kp->blocks) ||
++	    get_user(edid, &kp->edid) ||
++	    put_user(ptr_to_compat(edid), &up->edid) ||
++	    copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
++		return -EFAULT;
+ 	return 0;
+ }
+ 
+@@ -830,7 +979,7 @@ static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
+ #define VIDIOC_ENUMINPUT32	_IOWR('V', 26, struct v4l2_input32)
+ #define VIDIOC_G_EDID32		_IOWR('V', 40, struct v4l2_edid32)
+ #define VIDIOC_S_EDID32		_IOWR('V', 41, struct v4l2_edid32)
+-#define VIDIOC_TRY_FMT32      	_IOWR('V', 64, struct v4l2_format32)
++#define VIDIOC_TRY_FMT32	_IOWR('V', 64, struct v4l2_format32)
+ #define VIDIOC_G_EXT_CTRLS32    _IOWR('V', 71, struct v4l2_ext_controls32)
+ #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
+ #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
+@@ -846,22 +995,23 @@ static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
+ #define VIDIOC_G_OUTPUT32	_IOR ('V', 46, s32)
+ #define VIDIOC_S_OUTPUT32	_IOWR('V', 47, s32)
+ 
++static int alloc_userspace(unsigned int size, u32 aux_space,
++			   void __user **up_native)
++{
++	*up_native = compat_alloc_user_space(size + aux_space);
++	if (!*up_native)
++		return -ENOMEM;
++	if (clear_user(*up_native, size))
++		return -EFAULT;
++	return 0;
++}
++
+ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ {
+-	union {
+-		struct v4l2_format v2f;
+-		struct v4l2_buffer v2b;
+-		struct v4l2_framebuffer v2fb;
+-		struct v4l2_input v2i;
+-		struct v4l2_standard v2s;
+-		struct v4l2_ext_controls v2ecs;
+-		struct v4l2_event v2ev;
+-		struct v4l2_create_buffers v2crt;
+-		struct v4l2_edid v2edid;
+-		unsigned long vx;
+-		int vi;
+-	} karg;
+ 	void __user *up = compat_ptr(arg);
++	void __user *up_native = NULL;
++	void __user *aux_buf;
++	u32 aux_space;
+ 	int compatible_arg = 1;
+ 	long err = 0;
+ 
+@@ -900,30 +1050,52 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
+ 	case VIDIOC_STREAMOFF:
+ 	case VIDIOC_S_INPUT:
+ 	case VIDIOC_S_OUTPUT:
+-		err = get_user(karg.vi, (s32 __user *)up);
++		err = alloc_userspace(sizeof(unsigned int), 0, &up_native);
++		if (!err && assign_in_user((unsigned int __user *)up_native,
++					   (compat_uint_t __user *)up))
++			err = -EFAULT;
+ 		compatible_arg = 0;
+ 		break;
+ 
+ 	case VIDIOC_G_INPUT:
+ 	case VIDIOC_G_OUTPUT:
++		err = alloc_userspace(sizeof(unsigned int), 0, &up_native);
+ 		compatible_arg = 0;
+ 		break;
+ 
+ 	case VIDIOC_G_EDID:
+ 	case VIDIOC_S_EDID:
+-		err = get_v4l2_edid32(&karg.v2edid, up);
++		err = alloc_userspace(sizeof(struct v4l2_edid), 0, &up_native);
++		if (!err)
++			err = get_v4l2_edid32(up_native, up);
+ 		compatible_arg = 0;
+ 		break;
+ 
+ 	case VIDIOC_G_FMT:
+ 	case VIDIOC_S_FMT:
+ 	case VIDIOC_TRY_FMT:
+-		err = get_v4l2_format32(&karg.v2f, up);
++		err = bufsize_v4l2_format(up, &aux_space);
++		if (!err)
++			err = alloc_userspace(sizeof(struct v4l2_format),
++					      aux_space, &up_native);
++		if (!err) {
++			aux_buf = up_native + sizeof(struct v4l2_format);
++			err = get_v4l2_format32(up_native, up,
++						aux_buf, aux_space);
++		}
+ 		compatible_arg = 0;
+ 		break;
+ 
+ 	case VIDIOC_CREATE_BUFS:
+-		err = get_v4l2_create32(&karg.v2crt, up);
++		err = bufsize_v4l2_create(up, &aux_space);
++		if (!err)
++			err = alloc_userspace(sizeof(struct v4l2_create_buffers),
++					      aux_space, &up_native);
++		if (!err) {
++			aux_buf = up_native + sizeof(struct v4l2_create_buffers);
++			err = get_v4l2_create32(up_native, up,
++						aux_buf, aux_space);
++		}
+ 		compatible_arg = 0;
+ 		break;
+ 
+@@ -931,36 +1103,63 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
+ 	case VIDIOC_QUERYBUF:
+ 	case VIDIOC_QBUF:
+ 	case VIDIOC_DQBUF:
+-		err = get_v4l2_buffer32(&karg.v2b, up);
++		err = bufsize_v4l2_buffer(up, &aux_space);
++		if (!err)
++			err = alloc_userspace(sizeof(struct v4l2_buffer),
++					      aux_space, &up_native);
++		if (!err) {
++			aux_buf = up_native + sizeof(struct v4l2_buffer);
++			err = get_v4l2_buffer32(up_native, up,
++						aux_buf, aux_space);
++		}
+ 		compatible_arg = 0;
+ 		break;
+ 
+ 	case VIDIOC_S_FBUF:
+-		err = get_v4l2_framebuffer32(&karg.v2fb, up);
++		err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
++				      &up_native);
++		if (!err)
++			err = get_v4l2_framebuffer32(up_native, up);
+ 		compatible_arg = 0;
+ 		break;
+ 
+ 	case VIDIOC_G_FBUF:
++		err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
++				      &up_native);
+ 		compatible_arg = 0;
+ 		break;
+ 
+ 	case VIDIOC_ENUMSTD:
+-		err = get_v4l2_standard32(&karg.v2s, up);
++		err = alloc_userspace(sizeof(struct v4l2_standard), 0,
++				      &up_native);
++		if (!err)
++			err = get_v4l2_standard32(up_native, up);
+ 		compatible_arg = 0;
+ 		break;
+ 
+ 	case VIDIOC_ENUMINPUT:
+-		err = get_v4l2_input32(&karg.v2i, up);
++		err = alloc_userspace(sizeof(struct v4l2_input), 0, &up_native);
++		if (!err)
++			err = get_v4l2_input32(up_native, up);
+ 		compatible_arg = 0;
+ 		break;
+ 
+ 	case VIDIOC_G_EXT_CTRLS:
+ 	case VIDIOC_S_EXT_CTRLS:
+ 	case VIDIOC_TRY_EXT_CTRLS:
+-		err = get_v4l2_ext_controls32(&karg.v2ecs, up);
++		err = bufsize_v4l2_ext_controls(up, &aux_space);
++		if (!err)
++			err = alloc_userspace(sizeof(struct v4l2_ext_controls),
++					      aux_space, &up_native);
++		if (!err) {
++			aux_buf = up_native + sizeof(struct v4l2_ext_controls);
++			err = get_v4l2_ext_controls32(file, up_native, up,
++						      aux_buf, aux_space);
++		}
+ 		compatible_arg = 0;
+ 		break;
+ 	case VIDIOC_DQEVENT:
++		err = alloc_userspace(sizeof(struct v4l2_event), 0, &up_native);
+ 		compatible_arg = 0;
+ 		break;
+ 	}
+@@ -969,22 +1168,26 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
+ 
+ 	if (compatible_arg)
+ 		err = native_ioctl(file, cmd, (unsigned long)up);
+-	else {
+-		mm_segment_t old_fs = get_fs();
++	else
++		err = native_ioctl(file, cmd, (unsigned long)up_native);
+ 
+-		set_fs(KERNEL_DS);
+-		err = native_ioctl(file, cmd, (unsigned long)&karg);
+-		set_fs(old_fs);
+-	}
++	if (err == -ENOTTY)
++		return err;
+ 
+-	/* Special case: even after an error we need to put the
+-	   results back for these ioctls since the error_idx will
+-	   contain information on which control failed. */
++	/*
++	 * Special case: even after an error we need to put the
++	 * results back for these ioctls since the error_idx will
++	 * contain information on which control failed.
++	 */
+ 	switch (cmd) {
+ 	case VIDIOC_G_EXT_CTRLS:
+ 	case VIDIOC_S_EXT_CTRLS:
+ 	case VIDIOC_TRY_EXT_CTRLS:
+-		if (put_v4l2_ext_controls32(&karg.v2ecs, up))
++		if (put_v4l2_ext_controls32(file, up_native, up))
++			err = -EFAULT;
++		break;
++	case VIDIOC_S_EDID:
++		if (put_v4l2_edid32(up_native, up))
+ 			err = -EFAULT;
+ 		break;
+ 	}
+@@ -996,44 +1199,46 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
+ 	case VIDIOC_S_OUTPUT:
+ 	case VIDIOC_G_INPUT:
+ 	case VIDIOC_G_OUTPUT:
+-		err = put_user(((s32)karg.vi), (s32 __user *)up);
++		if (assign_in_user((compat_uint_t __user *)up,
++				   ((unsigned int __user *)up_native)))
++			err = -EFAULT;
+ 		break;
+ 
+ 	case VIDIOC_G_FBUF:
+-		err = put_v4l2_framebuffer32(&karg.v2fb, up);
++		err = put_v4l2_framebuffer32(up_native, up);
+ 		break;
+ 
+ 	case VIDIOC_DQEVENT:
+-		err = put_v4l2_event32(&karg.v2ev, up);
++		err = put_v4l2_event32(up_native, up);
+ 		break;
+ 
+ 	case VIDIOC_G_EDID:
+-	case VIDIOC_S_EDID:
+-		err = put_v4l2_edid32(&karg.v2edid, up);
++		err = put_v4l2_edid32(up_native, up);
+ 		break;
+ 
+ 	case VIDIOC_G_FMT:
+ 	case VIDIOC_S_FMT:
+ 	case VIDIOC_TRY_FMT:
+-		err = put_v4l2_format32(&karg.v2f, up);
++		err = put_v4l2_format32(up_native, up);
+ 		break;
+ 
+ 	case VIDIOC_CREATE_BUFS:
+-		err = put_v4l2_create32(&karg.v2crt, up);
++		err = put_v4l2_create32(up_native, up);
+ 		break;
+ 
++	case VIDIOC_PREPARE_BUF:
+ 	case VIDIOC_QUERYBUF:
+ 	case VIDIOC_QBUF:
+ 	case VIDIOC_DQBUF:
+-		err = put_v4l2_buffer32(&karg.v2b, up);
++		err = put_v4l2_buffer32(up_native, up);
+ 		break;
+ 
+ 	case VIDIOC_ENUMSTD:
+-		err = put_v4l2_standard32(&karg.v2s, up);
++		err = put_v4l2_standard32(up_native, up);
+ 		break;
+ 
+ 	case VIDIOC_ENUMINPUT:
+-		err = put_v4l2_input32(&karg.v2i, up);
++		err = put_v4l2_input32(up_native, up);
+ 		break;
+ 	}
+ 	return err;
+diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
+index c52d94c018bb..4510e8a37244 100644
+--- a/drivers/media/v4l2-core/v4l2-ioctl.c
++++ b/drivers/media/v4l2-core/v4l2-ioctl.c
+@@ -2862,8 +2862,11 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
+ 
+ 	/* Handles IOCTL */
+ 	err = func(file, cmd, parg);
+-	if (err == -ENOIOCTLCMD)
++	if (err == -ENOTTY || err == -ENOIOCTLCMD) {
+ 		err = -ENOTTY;
++		goto out;
++	}
++
+ 	if (err == 0) {
+ 		if (cmd == VIDIOC_DQBUF)
+ 			trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
+diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
+index d9fab2222eb3..1a4a790054e4 100644
+--- a/drivers/mtd/nand/brcmnand/brcmnand.c
++++ b/drivers/mtd/nand/brcmnand/brcmnand.c
+@@ -2193,16 +2193,9 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
+ 	if (ctrl->nand_version >= 0x0702)
+ 		tmp |= ACC_CONTROL_RD_ERASED;
+ 	tmp &= ~ACC_CONTROL_FAST_PGM_RDIN;
+-	if (ctrl->features & BRCMNAND_HAS_PREFETCH) {
+-		/*
+-		 * FIXME: Flash DMA + prefetch may see spurious erased-page ECC
+-		 * errors
+-		 */
+-		if (has_flash_dma(ctrl))
+-			tmp &= ~ACC_CONTROL_PREFETCH;
+-		else
+-			tmp |= ACC_CONTROL_PREFETCH;
+-	}
++	if (ctrl->features & BRCMNAND_HAS_PREFETCH)
++		tmp &= ~ACC_CONTROL_PREFETCH;
++
+ 	nand_writereg(ctrl, offs, tmp);
+ 
+ 	return 0;
+diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
+index a77cfd74a92e..21c03086bb7f 100644
+--- a/drivers/mtd/nand/nand_base.c
++++ b/drivers/mtd/nand/nand_base.c
+@@ -2320,6 +2320,7 @@ EXPORT_SYMBOL(nand_write_oob_syndrome);
+ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
+ 			    struct mtd_oob_ops *ops)
+ {
++	unsigned int max_bitflips = 0;
+ 	int page, realpage, chipnr;
+ 	struct nand_chip *chip = mtd_to_nand(mtd);
+ 	struct mtd_ecc_stats stats;
+@@ -2377,6 +2378,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
+ 				nand_wait_ready(mtd);
+ 		}
+ 
++		max_bitflips = max_t(unsigned int, max_bitflips, ret);
++
+ 		readlen -= len;
+ 		if (!readlen)
+ 			break;
+@@ -2402,7 +2405,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
+ 	if (mtd->ecc_stats.failed - stats.failed)
+ 		return -EBADMSG;
+ 
+-	return  mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
++	return max_bitflips;
+ }
+ 
+ /**
+diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
+index f9b2a771096b..e26c4f880df6 100644
+--- a/drivers/mtd/nand/sunxi_nand.c
++++ b/drivers/mtd/nand/sunxi_nand.c
+@@ -1835,8 +1835,14 @@ static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
+ 
+ 	/* Add ECC info retrieval from DT */
+ 	for (i = 0; i < ARRAY_SIZE(strengths); i++) {
+-		if (ecc->strength <= strengths[i])
++		if (ecc->strength <= strengths[i]) {
++			/*
++			 * Update ecc->strength value with the actual strength
++			 * that will be used by the ECC engine.
++			 */
++			ecc->strength = strengths[i];
+ 			break;
++		}
+ 	}
+ 
+ 	if (i >= ARRAY_SIZE(strengths)) {
+diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
+index d1e6931c132f..46913ef25bc0 100644
+--- a/drivers/mtd/ubi/block.c
++++ b/drivers/mtd/ubi/block.c
+@@ -99,6 +99,8 @@ struct ubiblock {
+ 
+ /* Linked list of all ubiblock instances */
+ static LIST_HEAD(ubiblock_devices);
++static DEFINE_IDR(ubiblock_minor_idr);
++/* Protects ubiblock_devices and ubiblock_minor_idr */
+ static DEFINE_MUTEX(devices_mutex);
+ static int ubiblock_major;
+ 
+@@ -353,8 +355,6 @@ static struct blk_mq_ops ubiblock_mq_ops = {
+ 	.init_request	= ubiblock_init_request,
+ };
+ 
+-static DEFINE_IDR(ubiblock_minor_idr);
+-
+ int ubiblock_create(struct ubi_volume_info *vi)
+ {
+ 	struct ubiblock *dev;
+@@ -367,14 +367,15 @@ int ubiblock_create(struct ubi_volume_info *vi)
+ 	/* Check that the volume isn't already handled */
+ 	mutex_lock(&devices_mutex);
+ 	if (find_dev_nolock(vi->ubi_num, vi->vol_id)) {
+-		mutex_unlock(&devices_mutex);
+-		return -EEXIST;
++		ret = -EEXIST;
++		goto out_unlock;
+ 	}
+-	mutex_unlock(&devices_mutex);
+ 
+ 	dev = kzalloc(sizeof(struct ubiblock), GFP_KERNEL);
+-	if (!dev)
+-		return -ENOMEM;
++	if (!dev) {
++		ret = -ENOMEM;
++		goto out_unlock;
++	}
+ 
+ 	mutex_init(&dev->dev_mutex);
+ 
+@@ -439,14 +440,13 @@ int ubiblock_create(struct ubi_volume_info *vi)
+ 		goto out_free_queue;
+ 	}
+ 
+-	mutex_lock(&devices_mutex);
+ 	list_add_tail(&dev->list, &ubiblock_devices);
+-	mutex_unlock(&devices_mutex);
+ 
+ 	/* Must be the last step: anyone can call file ops from now on */
+ 	add_disk(dev->gd);
+ 	dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)",
+ 		 dev->ubi_num, dev->vol_id, vi->name);
++	mutex_unlock(&devices_mutex);
+ 	return 0;
+ 
+ out_free_queue:
+@@ -459,6 +459,8 @@ int ubiblock_create(struct ubi_volume_info *vi)
+ 	put_disk(dev->gd);
+ out_free_dev:
+ 	kfree(dev);
++out_unlock:
++	mutex_unlock(&devices_mutex);
+ 
+ 	return ret;
+ }
+@@ -480,30 +482,36 @@ static void ubiblock_cleanup(struct ubiblock *dev)
+ int ubiblock_remove(struct ubi_volume_info *vi)
+ {
+ 	struct ubiblock *dev;
++	int ret;
+ 
+ 	mutex_lock(&devices_mutex);
+ 	dev = find_dev_nolock(vi->ubi_num, vi->vol_id);
+ 	if (!dev) {
+-		mutex_unlock(&devices_mutex);
+-		return -ENODEV;
++		ret = -ENODEV;
++		goto out_unlock;
+ 	}
+ 
+ 	/* Found a device, let's lock it so we can check if it's busy */
+ 	mutex_lock(&dev->dev_mutex);
+ 	if (dev->refcnt > 0) {
+-		mutex_unlock(&dev->dev_mutex);
+-		mutex_unlock(&devices_mutex);
+-		return -EBUSY;
++		ret = -EBUSY;
++		goto out_unlock_dev;
+ 	}
+ 
+ 	/* Remove from device list */
+ 	list_del(&dev->list);
+-	mutex_unlock(&devices_mutex);
+-
+ 	ubiblock_cleanup(dev);
+ 	mutex_unlock(&dev->dev_mutex);
++	mutex_unlock(&devices_mutex);
++
+ 	kfree(dev);
+ 	return 0;
++
++out_unlock_dev:
++	mutex_unlock(&dev->dev_mutex);
++out_unlock:
++	mutex_unlock(&devices_mutex);
++	return ret;
+ }
+ 
+ static int ubiblock_resize(struct ubi_volume_info *vi)
+@@ -632,6 +640,7 @@ static void ubiblock_remove_all(void)
+ 	struct ubiblock *next;
+ 	struct ubiblock *dev;
+ 
++	mutex_lock(&devices_mutex);
+ 	list_for_each_entry_safe(dev, next, &ubiblock_devices, list) {
+ 		/* The module is being forcefully removed */
+ 		WARN_ON(dev->desc);
+@@ -640,6 +649,7 @@ static void ubiblock_remove_all(void)
+ 		ubiblock_cleanup(dev);
+ 		kfree(dev);
+ 	}
++	mutex_unlock(&devices_mutex);
+ }
+ 
+ int __init ubiblock_init(void)
+diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
+index b5b8cd6f481c..668b46202507 100644
+--- a/drivers/mtd/ubi/wl.c
++++ b/drivers/mtd/ubi/wl.c
+@@ -1528,6 +1528,46 @@ static void shutdown_work(struct ubi_device *ubi)
+ 	}
+ }
+ 
++/**
++ * erase_aeb - erase a PEB given in UBI attach info PEB
++ * @ubi: UBI device description object
++ * @aeb: UBI attach info PEB
++ * @sync: If true, erase synchronously. Otherwise schedule for erasure
++ */
++static int erase_aeb(struct ubi_device *ubi, struct ubi_ainf_peb *aeb, bool sync)
++{
++	struct ubi_wl_entry *e;
++	int err;
++
++	e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
++	if (!e)
++		return -ENOMEM;
++
++	e->pnum = aeb->pnum;
++	e->ec = aeb->ec;
++	ubi->lookuptbl[e->pnum] = e;
++
++	if (sync) {
++		err = sync_erase(ubi, e, false);
++		if (err)
++			goto out_free;
++
++		wl_tree_add(e, &ubi->free);
++		ubi->free_count++;
++	} else {
++		err = schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false);
++		if (err)
++			goto out_free;
++	}
++
++	return 0;
++
++out_free:
++	wl_entry_destroy(ubi, e);
++
++	return err;
++}
++
+ /**
+  * ubi_wl_init - initialize the WL sub-system using attaching information.
+  * @ubi: UBI device description object
+@@ -1566,18 +1606,10 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
+ 	list_for_each_entry_safe(aeb, tmp, &ai->erase, u.list) {
+ 		cond_resched();
+ 
+-		e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
+-		if (!e)
++		err = erase_aeb(ubi, aeb, false);
++		if (err)
+ 			goto out_free;
+ 
+-		e->pnum = aeb->pnum;
+-		e->ec = aeb->ec;
+-		ubi->lookuptbl[e->pnum] = e;
+-		if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) {
+-			wl_entry_destroy(ubi, e);
+-			goto out_free;
+-		}
+-
+ 		found_pebs++;
+ 	}
+ 
+@@ -1635,6 +1667,8 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
+ 			ubi_assert(!ubi->lookuptbl[e->pnum]);
+ 			ubi->lookuptbl[e->pnum] = e;
+ 		} else {
++			bool sync = false;
++
+ 			/*
+ 			 * Usually old Fastmap PEBs are scheduled for erasure
+ 			 * and we don't have to care about them but if we face
+@@ -1644,18 +1678,21 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
+ 			if (ubi->lookuptbl[aeb->pnum])
+ 				continue;
+ 
+-			e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
+-			if (!e)
+-				goto out_free;
++			/*
++			 * The fastmap update code might not find a free PEB for
++			 * writing the fastmap anchor to and then reuses the
++			 * current fastmap anchor PEB. When this PEB gets erased
++			 * and a power cut happens before it is written again we
++			 * must make sure that the fastmap attach code doesn't
++			 * find any outdated fastmap anchors, hence we erase the
++			 * outdated fastmap anchor PEBs synchronously here.
++			 */
++			if (aeb->vol_id == UBI_FM_SB_VOLUME_ID)
++				sync = true;
+ 
+-			e->pnum = aeb->pnum;
+-			e->ec = aeb->ec;
+-			ubi_assert(!ubi->lookuptbl[e->pnum]);
+-			ubi->lookuptbl[e->pnum] = e;
+-			if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0, false)) {
+-				wl_entry_destroy(ubi, e);
++			err = erase_aeb(ubi, aeb, sync);
++			if (err)
+ 				goto out_free;
+-			}
+ 		}
+ 
+ 		found_pebs++;
+diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
+index b40a074822cf..df63b7d997e8 100644
+--- a/drivers/pinctrl/intel/pinctrl-intel.c
++++ b/drivers/pinctrl/intel/pinctrl-intel.c
+@@ -368,6 +368,18 @@ static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input)
+ 	writel(value, padcfg0);
+ }
+ 
++static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
++{
++	u32 value;
++
++	/* Put the pad into GPIO mode */
++	value = readl(padcfg0) & ~PADCFG0_PMODE_MASK;
++	/* Disable SCI/SMI/NMI generation */
++	value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI);
++	value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI);
++	writel(value, padcfg0);
++}
++
+ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
+ 				     struct pinctrl_gpio_range *range,
+ 				     unsigned pin)
+@@ -375,7 +387,6 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
+ 	struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ 	void __iomem *padcfg0;
+ 	unsigned long flags;
+-	u32 value;
+ 
+ 	raw_spin_lock_irqsave(&pctrl->lock, flags);
+ 
+@@ -385,13 +396,7 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
+ 	}
+ 
+ 	padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
+-	/* Put the pad into GPIO mode */
+-	value = readl(padcfg0) & ~PADCFG0_PMODE_MASK;
+-	/* Disable SCI/SMI/NMI generation */
+-	value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI);
+-	value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI);
+-	writel(value, padcfg0);
+-
++	intel_gpio_set_gpio_mode(padcfg0);
+ 	/* Disable TX buffer and enable RX (this will be input) */
+ 	__intel_gpio_set_direction(padcfg0, true);
+ 
+@@ -770,6 +775,8 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type)
+ 
+ 	raw_spin_lock_irqsave(&pctrl->lock, flags);
+ 
++	intel_gpio_set_gpio_mode(reg);
++
+ 	value = readl(reg);
+ 
+ 	value &= ~(PADCFG0_RXEVCFG_MASK | PADCFG0_RXINV);
+diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c
+index 31125a4a2658..d7dcd39fe12c 100644
+--- a/drivers/usb/gadget/function/uvc_configfs.c
++++ b/drivers/usb/gadget/function/uvc_configfs.c
+@@ -2140,7 +2140,7 @@ static struct configfs_item_operations uvc_item_ops = {
+ 	.release		= uvc_attr_release,
+ };
+ 
+-#define UVCG_OPTS_ATTR(cname, conv, str2u, uxx, vnoc, limit)		\
++#define UVCG_OPTS_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit)	\
+ static ssize_t f_uvc_opts_##cname##_show(				\
+ 	struct config_item *item, char *page)				\
+ {									\
+@@ -2183,16 +2183,16 @@ end:									\
+ 	return ret;							\
+ }									\
+ 									\
+-UVC_ATTR(f_uvc_opts_, cname, aname)
++UVC_ATTR(f_uvc_opts_, cname, cname)
+ 
+ #define identity_conv(x) (x)
+ 
+-UVCG_OPTS_ATTR(streaming_interval, identity_conv, kstrtou8, u8, identity_conv,
+-	       16);
+-UVCG_OPTS_ATTR(streaming_maxpacket, le16_to_cpu, kstrtou16, u16, le16_to_cpu,
+-	       3072);
+-UVCG_OPTS_ATTR(streaming_maxburst, identity_conv, kstrtou8, u8, identity_conv,
+-	       15);
++UVCG_OPTS_ATTR(streaming_interval, streaming_interval, identity_conv,
++	       kstrtou8, u8, identity_conv, 16);
++UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, le16_to_cpu,
++	       kstrtou16, u16, le16_to_cpu, 3072);
++UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, identity_conv,
++	       kstrtou8, u8, identity_conv, 15);
+ 
+ #undef identity_conv
+ 
+diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
+index 4874b0f18650..518dfa1047cb 100644
+--- a/drivers/watchdog/imx2_wdt.c
++++ b/drivers/watchdog/imx2_wdt.c
+@@ -169,15 +169,21 @@ static int imx2_wdt_ping(struct watchdog_device *wdog)
+ 	return 0;
+ }
+ 
+-static int imx2_wdt_set_timeout(struct watchdog_device *wdog,
+-				unsigned int new_timeout)
++static void __imx2_wdt_set_timeout(struct watchdog_device *wdog,
++				   unsigned int new_timeout)
+ {
+ 	struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
+ 
+-	wdog->timeout = new_timeout;
+-
+ 	regmap_update_bits(wdev->regmap, IMX2_WDT_WCR, IMX2_WDT_WCR_WT,
+ 			   WDOG_SEC_TO_COUNT(new_timeout));
++}
++
++static int imx2_wdt_set_timeout(struct watchdog_device *wdog,
++				unsigned int new_timeout)
++{
++	__imx2_wdt_set_timeout(wdog, new_timeout);
++
++	wdog->timeout = new_timeout;
+ 	return 0;
+ }
+ 
+@@ -371,7 +377,11 @@ static int imx2_wdt_suspend(struct device *dev)
+ 
+ 	/* The watchdog IP block is running */
+ 	if (imx2_wdt_is_running(wdev)) {
+-		imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME);
++		/*
++		 * Don't update wdog->timeout, we'll restore the current value
++		 * during resume.
++		 */
++		__imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME);
+ 		imx2_wdt_ping(wdog);
+ 	}
+ 
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 894d56361ea9..a8a1fb40e258 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -2063,8 +2063,15 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
+ 		goto out;
+ 	 }
+ 
+-	btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state,
+-				  0);
++	ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
++					&cached_state, 0);
++	if (ret) {
++		mapping_set_error(page->mapping, ret);
++		end_extent_writepage(page, ret, page_start, page_end);
++		ClearPageChecked(page);
++		goto out;
++	}
++
+ 	ClearPageChecked(page);
+ 	set_page_dirty(page);
+ out:
+diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
+index 5eb04129f938..73360df52ce9 100644
+--- a/fs/cifs/cifsencrypt.c
++++ b/fs/cifs/cifsencrypt.c
+@@ -318,9 +318,8 @@ int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
+ {
+ 	int i;
+ 	int rc;
+-	char password_with_pad[CIFS_ENCPWD_SIZE];
++	char password_with_pad[CIFS_ENCPWD_SIZE] = {0};
+ 
+-	memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
+ 	if (password)
+ 		strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE);
+ 
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 580b3a4ca53a..441d434a48c1 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -1667,7 +1667,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
+ 			tmp_end++;
+ 			if (!(tmp_end < end && tmp_end[1] == delim)) {
+ 				/* No it is not. Set the password to NULL */
+-				kfree(vol->password);
++				kzfree(vol->password);
+ 				vol->password = NULL;
+ 				break;
+ 			}
+@@ -1705,7 +1705,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
+ 					options = end;
+ 			}
+ 
+-			kfree(vol->password);
++			kzfree(vol->password);
+ 			/* Now build new password string */
+ 			temp_len = strlen(value);
+ 			vol->password = kzalloc(temp_len+1, GFP_KERNEL);
+@@ -4159,7 +4159,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
+ 		reset_cifs_unix_caps(0, tcon, NULL, vol_info);
+ out:
+ 	kfree(vol_info->username);
+-	kfree(vol_info->password);
++	kzfree(vol_info->password);
+ 	kfree(vol_info);
+ 
+ 	return tcon;
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index cf192f9ce254..02e403af9518 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -3285,20 +3285,18 @@ static const struct vm_operations_struct cifs_file_vm_ops = {
+ 
+ int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)
+ {
+-	int rc, xid;
++	int xid, rc = 0;
+ 	struct inode *inode = file_inode(file);
+ 
+ 	xid = get_xid();
+ 
+-	if (!CIFS_CACHE_READ(CIFS_I(inode))) {
++	if (!CIFS_CACHE_READ(CIFS_I(inode)))
+ 		rc = cifs_zap_mapping(inode);
+-		if (rc)
+-			return rc;
+-	}
+-
+-	rc = generic_file_mmap(file, vma);
+-	if (rc == 0)
++	if (!rc)
++		rc = generic_file_mmap(file, vma);
++	if (!rc)
+ 		vma->vm_ops = &cifs_file_vm_ops;
++
+ 	free_xid(xid);
+ 	return rc;
+ }
+@@ -3308,16 +3306,16 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
+ 	int rc, xid;
+ 
+ 	xid = get_xid();
++
+ 	rc = cifs_revalidate_file(file);
+-	if (rc) {
++	if (rc)
+ 		cifs_dbg(FYI, "Validation prior to mmap failed, error=%d\n",
+ 			 rc);
+-		free_xid(xid);
+-		return rc;
+-	}
+-	rc = generic_file_mmap(file, vma);
+-	if (rc == 0)
++	if (!rc)
++		rc = generic_file_mmap(file, vma);
++	if (!rc)
+ 		vma->vm_ops = &cifs_file_vm_ops;
++
+ 	free_xid(xid);
+ 	return rc;
+ }
+diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
+index 5419afea0a36..323d8e34abde 100644
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -99,14 +99,11 @@ sesInfoFree(struct cifs_ses *buf_to_free)
+ 	kfree(buf_to_free->serverOS);
+ 	kfree(buf_to_free->serverDomain);
+ 	kfree(buf_to_free->serverNOS);
+-	if (buf_to_free->password) {
+-		memset(buf_to_free->password, 0, strlen(buf_to_free->password));
+-		kfree(buf_to_free->password);
+-	}
++	kzfree(buf_to_free->password);
+ 	kfree(buf_to_free->user_name);
+ 	kfree(buf_to_free->domainName);
+-	kfree(buf_to_free->auth_key.response);
+-	kfree(buf_to_free);
++	kzfree(buf_to_free->auth_key.response);
++	kzfree(buf_to_free);
+ }
+ 
+ struct cifs_tcon *
+@@ -137,10 +134,7 @@ tconInfoFree(struct cifs_tcon *buf_to_free)
+ 	}
+ 	atomic_dec(&tconInfoAllocCount);
+ 	kfree(buf_to_free->nativeFileSystem);
+-	if (buf_to_free->password) {
+-		memset(buf_to_free->password, 0, strlen(buf_to_free->password));
+-		kfree(buf_to_free->password);
+-	}
++	kzfree(buf_to_free->password);
+ 	kfree(buf_to_free);
+ }
+ 
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 69b610ad3fdc..94c4c1901222 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -585,8 +585,7 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
+ 	}
+ 
+ 	/* check validate negotiate info response matches what we got earlier */
+-	if (pneg_rsp->Dialect !=
+-			cpu_to_le16(tcon->ses->server->vals->protocol_id))
++	if (pneg_rsp->Dialect != cpu_to_le16(tcon->ses->server->dialect))
+ 		goto vneg_out;
+ 
+ 	if (pneg_rsp->SecurityMode != cpu_to_le16(tcon->ses->server->sec_mode))
+diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
+index 78219d5644e9..d6512cd9ba02 100644
+--- a/fs/kernfs/file.c
++++ b/fs/kernfs/file.c
+@@ -275,7 +275,7 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf,
+ {
+ 	struct kernfs_open_file *of = kernfs_of(file);
+ 	const struct kernfs_ops *ops;
+-	size_t len;
++	ssize_t len;
+ 	char *buf;
+ 
+ 	if (of->atomic_write_len) {
+diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
+index bd81bcf3ffcf..1ac1593aded3 100644
+--- a/fs/nfs/direct.c
++++ b/fs/nfs/direct.c
+@@ -787,10 +787,8 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
+ 
+ 	spin_lock(&dreq->lock);
+ 
+-	if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) {
+-		dreq->flags = 0;
++	if (test_bit(NFS_IOHDR_ERROR, &hdr->flags))
+ 		dreq->error = hdr->error;
+-	}
+ 	if (dreq->error == 0) {
+ 		nfs_direct_good_bytes(dreq, hdr);
+ 		if (nfs_write_need_commit(hdr)) {
+diff --git a/fs/nfs/io.c b/fs/nfs/io.c
+index 1fc5d1ce327e..d18ccc1ce0b5 100644
+--- a/fs/nfs/io.c
++++ b/fs/nfs/io.c
+@@ -98,7 +98,7 @@ static void nfs_block_buffered(struct nfs_inode *nfsi, struct inode *inode)
+ {
+ 	if (!test_bit(NFS_INO_ODIRECT, &nfsi->flags)) {
+ 		set_bit(NFS_INO_ODIRECT, &nfsi->flags);
+-		nfs_wb_all(inode);
++		nfs_sync_mapping(inode->i_mapping);
+ 	}
+ }
+ 
+diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c
+index c444285bb1b1..f1160cdd4682 100644
+--- a/fs/nfs/nfs4idmap.c
++++ b/fs/nfs/nfs4idmap.c
+@@ -567,9 +567,13 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
+ 	struct idmap_msg *im;
+ 	struct idmap *idmap = (struct idmap *)aux;
+ 	struct key *key = cons->key;
+-	int ret = -ENOMEM;
++	int ret = -ENOKEY;
++
++	if (!aux)
++		goto out1;
+ 
+ 	/* msg and im are freed in idmap_pipe_destroy_msg */
++	ret = -ENOMEM;
+ 	data = kzalloc(sizeof(*data), GFP_KERNEL);
+ 	if (!data)
+ 		goto out1;
+diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
+index b7a07ba8783a..b8e44746f761 100644
+--- a/fs/nfs/pnfs.c
++++ b/fs/nfs/pnfs.c
+@@ -2145,7 +2145,7 @@ pnfs_write_through_mds(struct nfs_pageio_descriptor *desc,
+ 		nfs_pageio_reset_write_mds(desc);
+ 		mirror->pg_recoalesce = 1;
+ 	}
+-	hdr->release(hdr);
++	hdr->completion_ops->completion(hdr);
+ }
+ 
+ static enum pnfs_try_status
+@@ -2256,7 +2256,7 @@ pnfs_read_through_mds(struct nfs_pageio_descriptor *desc,
+ 		nfs_pageio_reset_read_mds(desc);
+ 		mirror->pg_recoalesce = 1;
+ 	}
+-	hdr->release(hdr);
++	hdr->completion_ops->completion(hdr);
+ }
+ 
+ /*
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c
+index 9905735463a4..9a3b3820306d 100644
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -1806,6 +1806,8 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data)
+ 		set_bit(NFS_CONTEXT_RESEND_WRITES, &req->wb_context->flags);
+ 	next:
+ 		nfs_unlock_and_release_request(req);
++		/* Latency breaker */
++		cond_resched();
+ 	}
+ 	nfss = NFS_SERVER(data->inode);
+ 	if (atomic_long_read(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
+diff --git a/fs/nsfs.c b/fs/nsfs.c
+index 8718af895eab..80fdfad7c215 100644
+--- a/fs/nsfs.c
++++ b/fs/nsfs.c
+@@ -90,6 +90,7 @@ static void *__ns_get_path(struct path *path, struct ns_common *ns)
+ 		return ERR_PTR(-ENOMEM);
+ 	}
+ 	d_instantiate(dentry, inode);
++	dentry->d_flags |= DCACHE_RCUACCESS;
+ 	dentry->d_fsdata = (void *)ns->ops;
+ 	d = atomic_long_cmpxchg(&ns->stashed, 0, (unsigned long)dentry);
+ 	if (d) {
+diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
+index f241b4ee3d8a..a1be6baabca3 100644
+--- a/fs/overlayfs/readdir.c
++++ b/fs/overlayfs/readdir.c
+@@ -434,10 +434,14 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end,
+ 	struct dentry *dentry = file->f_path.dentry;
+ 	struct file *realfile = od->realfile;
+ 
++	/* Nothing to sync for lower */
++	if (!OVL_TYPE_UPPER(ovl_path_type(dentry)))
++		return 0;
++
+ 	/*
+ 	 * Need to check if we started out being a lower dir, but got copied up
+ 	 */
+-	if (!od->is_upper && OVL_TYPE_UPPER(ovl_path_type(dentry))) {
++	if (!od->is_upper) {
+ 		struct inode *inode = file_inode(file);
+ 
+ 		realfile = lockless_dereference(od->upperfile);
+diff --git a/fs/pipe.c b/fs/pipe.c
+index 9faecf1b4a27..34345535f63d 100644
+--- a/fs/pipe.c
++++ b/fs/pipe.c
+@@ -609,12 +609,17 @@ static unsigned long account_pipe_buffers(struct user_struct *user,
+ 
+ static bool too_many_pipe_buffers_soft(unsigned long user_bufs)
+ {
+-	return pipe_user_pages_soft && user_bufs >= pipe_user_pages_soft;
++	return pipe_user_pages_soft && user_bufs > pipe_user_pages_soft;
+ }
+ 
+ static bool too_many_pipe_buffers_hard(unsigned long user_bufs)
+ {
+-	return pipe_user_pages_hard && user_bufs >= pipe_user_pages_hard;
++	return pipe_user_pages_hard && user_bufs > pipe_user_pages_hard;
++}
++
++static bool is_unprivileged_user(void)
++{
++	return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
+ }
+ 
+ struct pipe_inode_info *alloc_pipe_info(void)
+@@ -633,12 +638,12 @@ struct pipe_inode_info *alloc_pipe_info(void)
+ 
+ 	user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
+ 
+-	if (too_many_pipe_buffers_soft(user_bufs)) {
++	if (too_many_pipe_buffers_soft(user_bufs) && is_unprivileged_user()) {
+ 		user_bufs = account_pipe_buffers(user, pipe_bufs, 1);
+ 		pipe_bufs = 1;
+ 	}
+ 
+-	if (too_many_pipe_buffers_hard(user_bufs))
++	if (too_many_pipe_buffers_hard(user_bufs) && is_unprivileged_user())
+ 		goto out_revert_acct;
+ 
+ 	pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer),
+@@ -1069,7 +1074,7 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
+ 	if (nr_pages > pipe->buffers &&
+ 			(too_many_pipe_buffers_hard(user_bufs) ||
+ 			 too_many_pipe_buffers_soft(user_bufs)) &&
+-			!capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) {
++			is_unprivileged_user()) {
+ 		ret = -EPERM;
+ 		goto out_revert_acct;
+ 	}
+diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
+index 5c89a07e3d7f..df7e07986ead 100644
+--- a/fs/proc/kcore.c
++++ b/fs/proc/kcore.c
+@@ -507,23 +507,15 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
+ 				return -EFAULT;
+ 		} else {
+ 			if (kern_addr_valid(start)) {
+-				unsigned long n;
+-
+ 				/*
+ 				 * Using bounce buffer to bypass the
+ 				 * hardened user copy kernel text checks.
+ 				 */
+-				memcpy(buf, (char *) start, tsz);
+-				n = copy_to_user(buffer, buf, tsz);
+-				/*
+-				 * We cannot distinguish between fault on source
+-				 * and fault on destination. When this happens
+-				 * we clear too and hope it will trigger the
+-				 * EFAULT again.
+-				 */
+-				if (n) { 
+-					if (clear_user(buffer + tsz - n,
+-								n))
++				if (probe_kernel_read(buf, (void *) start, tsz)) {
++					if (clear_user(buffer, tsz))
++						return -EFAULT;
++				} else {
++					if (copy_to_user(buffer, buf, tsz))
+ 						return -EFAULT;
+ 				}
+ 			} else {
+diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
+index d9f9615bfd71..3979d767a0cb 100644
+--- a/fs/ubifs/xattr.c
++++ b/fs/ubifs/xattr.c
+@@ -270,7 +270,8 @@ static struct inode *iget_xattr(struct ubifs_info *c, ino_t inum)
+ }
+ 
+ static int __ubifs_setxattr(struct inode *host, const char *name,
+-			    const void *value, size_t size, int flags)
++			    const void *value, size_t size, int flags,
++			    bool check_lock)
+ {
+ 	struct inode *inode;
+ 	struct ubifs_info *c = host->i_sb->s_fs_info;
+@@ -279,7 +280,8 @@ static int __ubifs_setxattr(struct inode *host, const char *name,
+ 	union ubifs_key key;
+ 	int err;
+ 
+-	ubifs_assert(inode_is_locked(host));
++	if (check_lock)
++		ubifs_assert(inode_is_locked(host));
+ 
+ 	if (size > UBIFS_MAX_INO_DATA)
+ 		return -ERANGE;
+@@ -548,7 +550,8 @@ static int init_xattrs(struct inode *inode, const struct xattr *xattr_array,
+ 		}
+ 		strcpy(name, XATTR_SECURITY_PREFIX);
+ 		strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
+-		err = __ubifs_setxattr(inode, name, xattr->value, xattr->value_len, 0);
++		err = __ubifs_setxattr(inode, name, xattr->value,
++				       xattr->value_len, 0, false);
+ 		kfree(name);
+ 		if (err < 0)
+ 			break;
+@@ -594,7 +597,8 @@ static int ubifs_xattr_set(const struct xattr_handler *handler,
+ 	name = xattr_full_name(handler, name);
+ 
+ 	if (value)
+-		return __ubifs_setxattr(inode, name, value, size, flags);
++		return __ubifs_setxattr(inode, name, value, size, flags,
++					true);
+ 	else
+ 		return __ubifs_removexattr(inode, name);
+ }
+diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h
+index cac57358f7af..5203560f992e 100644
+--- a/include/crypto/internal/hash.h
++++ b/include/crypto/internal/hash.h
+@@ -88,6 +88,8 @@ static inline bool crypto_shash_alg_has_setkey(struct shash_alg *alg)
+ 	return alg->setkey != shash_no_setkey;
+ }
+ 
++bool crypto_hash_alg_has_setkey(struct hash_alg_common *halg);
++
+ int crypto_init_ahash_spawn(struct crypto_ahash_spawn *spawn,
+ 			    struct hash_alg_common *alg,
+ 			    struct crypto_instance *inst);
+diff --git a/include/crypto/poly1305.h b/include/crypto/poly1305.h
+index 894df59b74e4..d586f741cab5 100644
+--- a/include/crypto/poly1305.h
++++ b/include/crypto/poly1305.h
+@@ -30,8 +30,6 @@ struct poly1305_desc_ctx {
+ };
+ 
+ int crypto_poly1305_init(struct shash_desc *desc);
+-int crypto_poly1305_setkey(struct crypto_shash *tfm,
+-			   const u8 *key, unsigned int keylen);
+ unsigned int crypto_poly1305_setdesckey(struct poly1305_desc_ctx *dctx,
+ 					const u8 *src, unsigned int srclen);
+ int crypto_poly1305_update(struct shash_desc *desc,
+diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
+index 3aa56e3104bb..b5b43f94f311 100644
+--- a/include/linux/mtd/map.h
++++ b/include/linux/mtd/map.h
+@@ -270,75 +270,67 @@ void map_destroy(struct mtd_info *mtd);
+ #define INVALIDATE_CACHED_RANGE(map, from, size) \
+ 	do { if (map->inval_cache) map->inval_cache(map, from, size); } while (0)
+ 
+-
+-static inline int map_word_equal(struct map_info *map, map_word val1, map_word val2)
+-{
+-	int i;
+-
+-	for (i = 0; i < map_words(map); i++) {
+-		if (val1.x[i] != val2.x[i])
+-			return 0;
+-	}
+-
+-	return 1;
+-}
+-
+-static inline map_word map_word_and(struct map_info *map, map_word val1, map_word val2)
+-{
+-	map_word r;
+-	int i;
+-
+-	for (i = 0; i < map_words(map); i++)
+-		r.x[i] = val1.x[i] & val2.x[i];
+-
+-	return r;
+-}
+-
+-static inline map_word map_word_clr(struct map_info *map, map_word val1, map_word val2)
+-{
+-	map_word r;
+-	int i;
+-
+-	for (i = 0; i < map_words(map); i++)
+-		r.x[i] = val1.x[i] & ~val2.x[i];
+-
+-	return r;
+-}
+-
+-static inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2)
+-{
+-	map_word r;
+-	int i;
+-
+-	for (i = 0; i < map_words(map); i++)
+-		r.x[i] = val1.x[i] | val2.x[i];
+-
+-	return r;
+-}
+-
+-static inline int map_word_andequal(struct map_info *map, map_word val1, map_word val2, map_word val3)
+-{
+-	int i;
+-
+-	for (i = 0; i < map_words(map); i++) {
+-		if ((val1.x[i] & val2.x[i]) != val3.x[i])
+-			return 0;
+-	}
+-
+-	return 1;
+-}
+-
+-static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
+-{
+-	int i;
+-
+-	for (i = 0; i < map_words(map); i++) {
+-		if (val1.x[i] & val2.x[i])
+-			return 1;
+-	}
+-
+-	return 0;
+-}
++#define map_word_equal(map, val1, val2)					\
++({									\
++	int i, ret = 1;							\
++	for (i = 0; i < map_words(map); i++)				\
++		if ((val1).x[i] != (val2).x[i]) {			\
++			ret = 0;					\
++			break;						\
++		}							\
++	ret;								\
++})
++
++#define map_word_and(map, val1, val2)					\
++({									\
++	map_word r;							\
++	int i;								\
++	for (i = 0; i < map_words(map); i++)				\
++		r.x[i] = (val1).x[i] & (val2).x[i];			\
++	r;								\
++})
++
++#define map_word_clr(map, val1, val2)					\
++({									\
++	map_word r;							\
++	int i;								\
++	for (i = 0; i < map_words(map); i++)				\
++		r.x[i] = (val1).x[i] & ~(val2).x[i];			\
++	r;								\
++})
++
++#define map_word_or(map, val1, val2)					\
++({									\
++	map_word r;							\
++	int i;								\
++	for (i = 0; i < map_words(map); i++)				\
++		r.x[i] = (val1).x[i] | (val2).x[i];			\
++	r;								\
++})
++
++#define map_word_andequal(map, val1, val2, val3)			\
++({									\
++	int i, ret = 1;							\
++	for (i = 0; i < map_words(map); i++) {				\
++		if (((val1).x[i] & (val2).x[i]) != (val2).x[i]) {	\
++			ret = 0;					\
++			break;						\
++		}							\
++	}								\
++	ret;								\
++})
++
++#define map_word_bitsset(map, val1, val2)				\
++({									\
++	int i, ret = 0;							\
++	for (i = 0; i < map_words(map); i++) {				\
++		if ((val1).x[i] & (val2).x[i]) {			\
++			ret = 1;					\
++			break;						\
++		}							\
++	}								\
++	ret;								\
++})
+ 
+ static inline map_word map_word_load(struct map_info *map, const void *ptr)
+ {
+diff --git a/kernel/async.c b/kernel/async.c
+index d2edd6efec56..d84d4860992e 100644
+--- a/kernel/async.c
++++ b/kernel/async.c
+@@ -84,20 +84,24 @@ static atomic_t entry_count;
+ 
+ static async_cookie_t lowest_in_progress(struct async_domain *domain)
+ {
+-	struct list_head *pending;
++	struct async_entry *first = NULL;
+ 	async_cookie_t ret = ASYNC_COOKIE_MAX;
+ 	unsigned long flags;
+ 
+ 	spin_lock_irqsave(&async_lock, flags);
+ 
+-	if (domain)
+-		pending = &domain->pending;
+-	else
+-		pending = &async_global_pending;
++	if (domain) {
++		if (!list_empty(&domain->pending))
++			first = list_first_entry(&domain->pending,
++					struct async_entry, domain_list);
++	} else {
++		if (!list_empty(&async_global_pending))
++			first = list_first_entry(&async_global_pending,
++					struct async_entry, global_list);
++	}
+ 
+-	if (!list_empty(pending))
+-		ret = list_first_entry(pending, struct async_entry,
+-				       domain_list)->cookie;
++	if (first)
++		ret = first->cookie;
+ 
+ 	spin_unlock_irqrestore(&async_lock, flags);
+ 	return ret;
+diff --git a/kernel/relay.c b/kernel/relay.c
+index 8f18d314a96a..2603e04f55f9 100644
+--- a/kernel/relay.c
++++ b/kernel/relay.c
+@@ -611,7 +611,6 @@ struct rchan *relay_open(const char *base_filename,
+ 
+ 	kref_put(&chan->kref, relay_destroy_channel);
+ 	mutex_unlock(&relay_channels_mutex);
+-	kfree(chan);
+ 	return NULL;
+ }
+ EXPORT_SYMBOL_GPL(relay_open);
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index e5066955cc3a..bce3a7ad4253 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -5864,6 +5864,19 @@ static void rq_attach_root(struct rq *rq, struct root_domain *rd)
+ 		call_rcu_sched(&old_rd->rcu, free_rootdomain);
+ }
+ 
++void sched_get_rd(struct root_domain *rd)
++{
++	atomic_inc(&rd->refcount);
++}
++
++void sched_put_rd(struct root_domain *rd)
++{
++	if (!atomic_dec_and_test(&rd->refcount))
++		return;
++
++	call_rcu_sched(&rd->rcu, free_rootdomain);
++}
++
+ static int init_rootdomain(struct root_domain *rd)
+ {
+ 	memset(rd, 0, sizeof(*rd));
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
+index 7a360d6f6798..f6d68ddfa2f3 100644
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -1895,9 +1895,8 @@ static void push_rt_tasks(struct rq *rq)
+  * the rt_loop_next will cause the iterator to perform another scan.
+  *
+  */
+-static int rto_next_cpu(struct rq *rq)
++static int rto_next_cpu(struct root_domain *rd)
+ {
+-	struct root_domain *rd = rq->rd;
+ 	int next;
+ 	int cpu;
+ 
+@@ -1973,19 +1972,24 @@ static void tell_cpu_to_push(struct rq *rq)
+ 	 * Otherwise it is finishing up and an ipi needs to be sent.
+ 	 */
+ 	if (rq->rd->rto_cpu < 0)
+-		cpu = rto_next_cpu(rq);
++		cpu = rto_next_cpu(rq->rd);
+ 
+ 	raw_spin_unlock(&rq->rd->rto_lock);
+ 
+ 	rto_start_unlock(&rq->rd->rto_loop_start);
+ 
+-	if (cpu >= 0)
++	if (cpu >= 0) {
++		/* Make sure the rd does not get freed while pushing */
++		sched_get_rd(rq->rd);
+ 		irq_work_queue_on(&rq->rd->rto_push_work, cpu);
++	}
+ }
+ 
+ /* Called from hardirq context */
+ void rto_push_irq_work_func(struct irq_work *work)
+ {
++	struct root_domain *rd =
++		container_of(work, struct root_domain, rto_push_work);
+ 	struct rq *rq;
+ 	int cpu;
+ 
+@@ -2001,18 +2005,20 @@ void rto_push_irq_work_func(struct irq_work *work)
+ 		raw_spin_unlock(&rq->lock);
+ 	}
+ 
+-	raw_spin_lock(&rq->rd->rto_lock);
++	raw_spin_lock(&rd->rto_lock);
+ 
+ 	/* Pass the IPI to the next rt overloaded queue */
+-	cpu = rto_next_cpu(rq);
++	cpu = rto_next_cpu(rd);
+ 
+-	raw_spin_unlock(&rq->rd->rto_lock);
++	raw_spin_unlock(&rd->rto_lock);
+ 
+-	if (cpu < 0)
++	if (cpu < 0) {
++		sched_put_rd(rd);
+ 		return;
++	}
+ 
+ 	/* Try the next RT overloaded CPU */
+-	irq_work_queue_on(&rq->rd->rto_push_work, cpu);
++	irq_work_queue_on(&rd->rto_push_work, cpu);
+ }
+ #endif /* HAVE_RT_PUSH_IPI */
+ 
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index cff985feb6e7..f564a1d2c9d5 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -590,6 +590,8 @@ struct root_domain {
+ };
+ 
+ extern struct root_domain def_root_domain;
++extern void sched_get_rd(struct root_domain *rd);
++extern void sched_put_rd(struct root_domain *rd);
+ 
+ #ifdef HAVE_RT_PUSH_IPI
+ extern void rto_push_irq_work_func(struct irq_work *work);
+diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
+index f2826c35e918..fc7c37ad90a0 100644
+--- a/kernel/time/posix-timers.c
++++ b/kernel/time/posix-timers.c
+@@ -507,17 +507,22 @@ static struct pid *good_sigevent(sigevent_t * event)
+ {
+ 	struct task_struct *rtn = current->group_leader;
+ 
+-	if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
+-		(!(rtn = find_task_by_vpid(event->sigev_notify_thread_id)) ||
+-		 !same_thread_group(rtn, current) ||
+-		 (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
++	switch (event->sigev_notify) {
++	case SIGEV_SIGNAL | SIGEV_THREAD_ID:
++		rtn = find_task_by_vpid(event->sigev_notify_thread_id);
++		if (!rtn || !same_thread_group(rtn, current))
++			return NULL;
++		/* FALLTHRU */
++	case SIGEV_SIGNAL:
++	case SIGEV_THREAD:
++		if (event->sigev_signo <= 0 || event->sigev_signo > SIGRTMAX)
++			return NULL;
++		/* FALLTHRU */
++	case SIGEV_NONE:
++		return task_pid(rtn);
++	default:
+ 		return NULL;
+-
+-	if (((event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) &&
+-	    ((event->sigev_signo <= 0) || (event->sigev_signo > SIGRTMAX)))
+-		return NULL;
+-
+-	return task_pid(rtn);
++	}
+ }
+ 
+ void posix_timers_register_clock(const clockid_t clock_id,
+@@ -745,8 +750,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
+ 	/* interval timer ? */
+ 	if (iv.tv64)
+ 		cur_setting->it_interval = ktime_to_timespec(iv);
+-	else if (!hrtimer_active(timer) &&
+-		 (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
++	else if (!hrtimer_active(timer) && timr->it_sigev_notify != SIGEV_NONE)
+ 		return;
+ 
+ 	now = timer->base->get_time();
+@@ -757,7 +761,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
+ 	 * expiry is > now.
+ 	 */
+ 	if (iv.tv64 && (timr->it_requeue_pending & REQUEUE_PENDING ||
+-	    (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
++			timr->it_sigev_notify == SIGEV_NONE))
+ 		timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
+ 
+ 	remaining = __hrtimer_expires_remaining_adjusted(timer, now);
+@@ -767,7 +771,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
+ 		 * A single shot SIGEV_NONE timer must return 0, when
+ 		 * it is expired !
+ 		 */
+-		if ((timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
++		if (timr->it_sigev_notify != SIGEV_NONE)
+ 			cur_setting->it_value.tv_nsec = 1;
+ 	} else
+ 		cur_setting->it_value = ktime_to_timespec(remaining);
+@@ -865,7 +869,7 @@ common_timer_set(struct k_itimer *timr, int flags,
+ 	timr->it.real.interval = timespec_to_ktime(new_setting->it_interval);
+ 
+ 	/* SIGEV_NONE timers are not queued ! See common_timer_get */
+-	if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
++	if (timr->it_sigev_notify == SIGEV_NONE) {
+ 		/* Setup correct expiry time for relative timers */
+ 		if (mode == HRTIMER_MODE_REL) {
+ 			hrtimer_add_expires(timer, timer->base->get_time());
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 5b8d7189e147..2884fe01cb54 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -3911,7 +3911,6 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
+ 		func_g.type = filter_parse_regex(glob, strlen(glob),
+ 						 &func_g.search, &not);
+ 		func_g.len = strlen(func_g.search);
+-		func_g.search = glob;
+ 
+ 		/* we do not support '!' for function probes */
+ 		if (WARN_ON(not))
+diff --git a/lib/ubsan.c b/lib/ubsan.c
+index fb0409df1bcf..50d1d5c25deb 100644
+--- a/lib/ubsan.c
++++ b/lib/ubsan.c
+@@ -265,14 +265,14 @@ void __ubsan_handle_divrem_overflow(struct overflow_data *data,
+ }
+ EXPORT_SYMBOL(__ubsan_handle_divrem_overflow);
+ 
+-static void handle_null_ptr_deref(struct type_mismatch_data *data)
++static void handle_null_ptr_deref(struct type_mismatch_data_common *data)
+ {
+ 	unsigned long flags;
+ 
+-	if (suppress_report(&data->location))
++	if (suppress_report(data->location))
+ 		return;
+ 
+-	ubsan_prologue(&data->location, &flags);
++	ubsan_prologue(data->location, &flags);
+ 
+ 	pr_err("%s null pointer of type %s\n",
+ 		type_check_kinds[data->type_check_kind],
+@@ -281,15 +281,15 @@ static void handle_null_ptr_deref(struct type_mismatch_data *data)
+ 	ubsan_epilogue(&flags);
+ }
+ 
+-static void handle_missaligned_access(struct type_mismatch_data *data,
++static void handle_misaligned_access(struct type_mismatch_data_common *data,
+ 				unsigned long ptr)
+ {
+ 	unsigned long flags;
+ 
+-	if (suppress_report(&data->location))
++	if (suppress_report(data->location))
+ 		return;
+ 
+-	ubsan_prologue(&data->location, &flags);
++	ubsan_prologue(data->location, &flags);
+ 
+ 	pr_err("%s misaligned address %p for type %s\n",
+ 		type_check_kinds[data->type_check_kind],
+@@ -299,15 +299,15 @@ static void handle_missaligned_access(struct type_mismatch_data *data,
+ 	ubsan_epilogue(&flags);
+ }
+ 
+-static void handle_object_size_mismatch(struct type_mismatch_data *data,
++static void handle_object_size_mismatch(struct type_mismatch_data_common *data,
+ 					unsigned long ptr)
+ {
+ 	unsigned long flags;
+ 
+-	if (suppress_report(&data->location))
++	if (suppress_report(data->location))
+ 		return;
+ 
+-	ubsan_prologue(&data->location, &flags);
++	ubsan_prologue(data->location, &flags);
+ 	pr_err("%s address %p with insufficient space\n",
+ 		type_check_kinds[data->type_check_kind],
+ 		(void *) ptr);
+@@ -315,19 +315,47 @@ static void handle_object_size_mismatch(struct type_mismatch_data *data,
+ 	ubsan_epilogue(&flags);
+ }
+ 
+-void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
++static void ubsan_type_mismatch_common(struct type_mismatch_data_common *data,
+ 				unsigned long ptr)
+ {
+ 
+ 	if (!ptr)
+ 		handle_null_ptr_deref(data);
+ 	else if (data->alignment && !IS_ALIGNED(ptr, data->alignment))
+-		handle_missaligned_access(data, ptr);
++		handle_misaligned_access(data, ptr);
+ 	else
+ 		handle_object_size_mismatch(data, ptr);
+ }
++
++void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
++				unsigned long ptr)
++{
++	struct type_mismatch_data_common common_data = {
++		.location = &data->location,
++		.type = data->type,
++		.alignment = data->alignment,
++		.type_check_kind = data->type_check_kind
++	};
++
++	ubsan_type_mismatch_common(&common_data, ptr);
++}
+ EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
+ 
++void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data,
++				unsigned long ptr)
++{
++
++	struct type_mismatch_data_common common_data = {
++		.location = &data->location,
++		.type = data->type,
++		.alignment = 1UL << data->log_alignment,
++		.type_check_kind = data->type_check_kind
++	};
++
++	ubsan_type_mismatch_common(&common_data, ptr);
++}
++EXPORT_SYMBOL(__ubsan_handle_type_mismatch_v1);
++
+ void __ubsan_handle_nonnull_return(struct nonnull_return_data *data)
+ {
+ 	unsigned long flags;
+diff --git a/lib/ubsan.h b/lib/ubsan.h
+index b2d18d4a53f5..d8b8085e5dac 100644
+--- a/lib/ubsan.h
++++ b/lib/ubsan.h
+@@ -36,6 +36,20 @@ struct type_mismatch_data {
+ 	unsigned char type_check_kind;
+ };
+ 
++struct type_mismatch_data_v1 {
++	struct source_location location;
++	struct type_descriptor *type;
++	unsigned char log_alignment;
++	unsigned char type_check_kind;
++};
++
++struct type_mismatch_data_common {
++	struct source_location *location;
++	struct type_descriptor *type;
++	unsigned long alignment;
++	unsigned char type_check_kind;
++};
++
+ struct nonnull_arg_data {
+ 	struct source_location location;
+ 	struct source_location attr_location;
+diff --git a/net/dccp/proto.c b/net/dccp/proto.c
+index b68168fcc06a..9d43c1f40274 100644
+--- a/net/dccp/proto.c
++++ b/net/dccp/proto.c
+@@ -259,6 +259,7 @@ int dccp_disconnect(struct sock *sk, int flags)
+ {
+ 	struct inet_connection_sock *icsk = inet_csk(sk);
+ 	struct inet_sock *inet = inet_sk(sk);
++	struct dccp_sock *dp = dccp_sk(sk);
+ 	int err = 0;
+ 	const int old_state = sk->sk_state;
+ 
+@@ -278,6 +279,10 @@ int dccp_disconnect(struct sock *sk, int flags)
+ 		sk->sk_err = ECONNRESET;
+ 
+ 	dccp_clear_xmit_timers(sk);
++	ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
++	ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
++	dp->dccps_hc_rx_ccid = NULL;
++	dp->dccps_hc_tx_ccid = NULL;
+ 
+ 	__skb_queue_purge(&sk->sk_receive_queue);
+ 	__skb_queue_purge(&sk->sk_write_queue);
+diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
+index 3f8e6f0b7eb5..dcf03691ebc8 100644
+--- a/sound/soc/intel/skylake/skl-nhlt.c
++++ b/sound/soc/intel/skylake/skl-nhlt.c
+@@ -41,7 +41,8 @@ struct nhlt_acpi_table *skl_nhlt_init(struct device *dev)
+ 	obj = acpi_evaluate_dsm(handle, OSC_UUID, 1, 1, NULL);
+ 	if (obj && obj->type == ACPI_TYPE_BUFFER) {
+ 		nhlt_ptr = (struct nhlt_resource_desc  *)obj->buffer.pointer;
+-		nhlt_table = (struct nhlt_acpi_table *)
++		if (nhlt_ptr->length)
++			nhlt_table = (struct nhlt_acpi_table *)
+ 				memremap(nhlt_ptr->min_addr, nhlt_ptr->length,
+ 				MEMREMAP_WB);
+ 		ACPI_FREE(obj);
+diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
+index 974915cb4c4f..08bfee447a36 100644
+--- a/sound/soc/rockchip/rockchip_i2s.c
++++ b/sound/soc/rockchip/rockchip_i2s.c
+@@ -476,6 +476,7 @@ static bool rockchip_i2s_rd_reg(struct device *dev, unsigned int reg)
+ 	case I2S_INTCR:
+ 	case I2S_XFER:
+ 	case I2S_CLR:
++	case I2S_TXDR:
+ 	case I2S_RXDR:
+ 	case I2S_FIFOLR:
+ 	case I2S_INTSR:
+@@ -490,6 +491,9 @@ static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg)
+ 	switch (reg) {
+ 	case I2S_INTSR:
+ 	case I2S_CLR:
++	case I2S_FIFOLR:
++	case I2S_TXDR:
++	case I2S_RXDR:
+ 		return true;
+ 	default:
+ 		return false;
+@@ -499,6 +503,8 @@ static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg)
+ static bool rockchip_i2s_precious_reg(struct device *dev, unsigned int reg)
+ {
+ 	switch (reg) {
++	case I2S_RXDR:
++		return true;
+ 	default:
+ 		return false;
+ 	}


             reply	other threads:[~2018-02-17 15:02 UTC|newest]

Thread overview: 393+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-17 15:02 Alice Ferrazzi [this message]
  -- strict thread matches above, loose matches on Subject: below --
2023-01-07 11:37 [gentoo-commits] proj/linux-patches:4.9 commit in: / Mike Pagano
2022-12-14 12:24 Mike Pagano
2022-12-08 13:09 Alice Ferrazzi
2022-11-25 17:02 Mike Pagano
2022-11-10 15:14 Mike Pagano
2022-11-03 15:09 Mike Pagano
2022-10-26 11:43 Mike Pagano
2022-09-28  9:19 Mike Pagano
2022-09-20 12:04 Mike Pagano
2022-09-15 11:10 Mike Pagano
2022-09-05 12:08 Mike Pagano
2022-08-25 10:37 Mike Pagano
2022-07-29 15:25 Mike Pagano
2022-07-21 20:14 Mike Pagano
2022-07-12 16:03 Mike Pagano
2022-07-07 16:20 Mike Pagano
2022-07-02 16:04 Mike Pagano
2022-06-25 10:24 Mike Pagano
2022-06-16 11:42 Mike Pagano
2022-06-14 15:49 Mike Pagano
2022-06-06 11:07 Mike Pagano
2022-05-27 12:41 Mike Pagano
2022-05-25 11:57 Mike Pagano
2022-05-18  9:52 Mike Pagano
2022-05-15 22:14 Mike Pagano
2022-05-12 11:32 Mike Pagano
2022-04-27 11:38 Mike Pagano
2022-04-20 12:12 Mike Pagano
2022-03-28 11:01 Mike Pagano
2022-03-23 11:59 Mike Pagano
2022-03-16 13:22 Mike Pagano
2022-03-11 10:57 Mike Pagano
2022-03-08 18:28 Mike Pagano
2022-03-02 13:09 Mike Pagano
2022-02-26 23:38 Mike Pagano
2022-02-23 12:40 Mike Pagano
2022-02-16 12:49 Mike Pagano
2022-02-11 12:38 Mike Pagano
2022-02-08 18:03 Mike Pagano
2022-01-29 17:46 Mike Pagano
2022-01-27 11:41 Mike Pagano
2022-01-11 12:59 Mike Pagano
2022-01-05 12:57 Mike Pagano
2021-12-29 13:13 Mike Pagano
2021-12-22 14:08 Mike Pagano
2021-12-14 10:37 Mike Pagano
2021-12-08 12:57 Mike Pagano
2021-11-26 12:01 Mike Pagano
2021-11-12 13:38 Mike Pagano
2021-11-02 17:06 Mike Pagano
2021-10-27 12:00 Mike Pagano
2021-10-17 13:14 Mike Pagano
2021-10-09 21:35 Mike Pagano
2021-10-06 11:32 Mike Pagano
2021-09-26 14:15 Mike Pagano
2021-09-22 11:42 Mike Pagano
2021-09-20 22:06 Mike Pagano
2021-09-03 11:24 Mike Pagano
2021-08-26 14:03 Mike Pagano
2021-08-25 23:14 Mike Pagano
2021-08-25 23:13 Mike Pagano
2021-08-15 20:10 Mike Pagano
2021-08-08 13:41 Mike Pagano
2021-08-04 11:55 Mike Pagano
2021-08-03 12:49 Mike Pagano
2021-07-28 12:39 Mike Pagano
2021-07-20 15:29 Alice Ferrazzi
2021-07-11 14:47 Mike Pagano
2021-06-30 14:28 Mike Pagano
2021-06-17 14:23 Alice Ferrazzi
2021-06-17 11:08 Alice Ferrazzi
2021-06-10 11:10 Mike Pagano
2021-06-03 10:41 Alice Ferrazzi
2021-05-26 12:03 Mike Pagano
2021-05-22 10:01 Mike Pagano
2021-04-28 11:03 Alice Ferrazzi
2021-04-16 11:19 Alice Ferrazzi
2021-04-10 13:22 Mike Pagano
2021-04-07 12:14 Mike Pagano
2021-03-30 14:14 Mike Pagano
2021-03-24 12:07 Mike Pagano
2021-03-17 15:58 Mike Pagano
2021-03-11 14:04 Mike Pagano
2021-03-07 15:13 Mike Pagano
2021-03-03 17:24 Alice Ferrazzi
2021-02-23 13:38 Alice Ferrazzi
2021-02-10 10:15 Alice Ferrazzi
2021-02-05 14:53 Alice Ferrazzi
2021-02-03 23:25 Mike Pagano
2021-01-30 13:18 Alice Ferrazzi
2021-01-23 16:34 Mike Pagano
2021-01-17 16:22 Mike Pagano
2021-01-12 20:08 Mike Pagano
2021-01-09 12:54 Mike Pagano
2020-12-29 14:18 Mike Pagano
2020-12-11 12:54 Mike Pagano
2020-12-02 12:48 Mike Pagano
2020-11-24 13:39 Mike Pagano
2020-11-22 19:12 Mike Pagano
2020-11-18 19:23 Mike Pagano
2020-11-11 15:32 Mike Pagano
2020-11-10 13:54 Mike Pagano
2020-10-29 11:17 Mike Pagano
2020-10-17 10:14 Mike Pagano
2020-10-14 20:34 Mike Pagano
2020-10-01 19:03 Mike Pagano
2020-10-01 18:59 Mike Pagano
2020-09-24 16:02 Mike Pagano
2020-09-23 11:59 Mike Pagano
2020-09-23 11:57 Mike Pagano
2020-09-12 17:31 Mike Pagano
2020-09-03 11:34 Mike Pagano
2020-08-26 11:13 Mike Pagano
2020-08-21 11:23 Alice Ferrazzi
2020-08-21 11:02 Alice Ferrazzi
2020-07-31 16:13 Mike Pagano
2020-07-22 12:30 Mike Pagano
2020-07-09 12:07 Mike Pagano
2020-07-01 12:10 Mike Pagano
2020-06-22 14:44 Mike Pagano
2020-06-11 11:28 Mike Pagano
2020-06-03 11:37 Mike Pagano
2020-05-27 15:26 Mike Pagano
2020-05-20 11:24 Mike Pagano
2020-05-13 12:50 Mike Pagano
2020-05-11 22:52 Mike Pagano
2020-05-05 17:39 Mike Pagano
2020-05-02 19:22 Mike Pagano
2020-04-24 12:01 Mike Pagano
2020-04-15 17:55 Mike Pagano
2020-04-13 11:15 Mike Pagano
2020-04-02 18:55 Mike Pagano
2020-03-20 11:54 Mike Pagano
2020-03-11 10:15 Mike Pagano
2020-02-28 15:29 Mike Pagano
2020-02-14 23:36 Mike Pagano
2020-02-05 14:48 Mike Pagano
2020-01-29 12:36 Mike Pagano
2020-01-23 11:02 Mike Pagano
2020-01-14 22:26 Mike Pagano
2020-01-12 14:52 Mike Pagano
2020-01-04 16:48 Mike Pagano
2019-12-21 14:54 Mike Pagano
2019-12-05 15:17 Alice Ferrazzi
2019-11-29 21:39 Thomas Deutschmann
2019-11-28 23:51 Mike Pagano
2019-11-25 12:08 Mike Pagano
2019-11-16 10:54 Mike Pagano
2019-11-12 20:58 Mike Pagano
2019-11-10 16:15 Mike Pagano
2019-11-06 14:24 Mike Pagano
2019-10-29 11:16 Mike Pagano
2019-10-17 22:21 Mike Pagano
2019-10-07 17:37 Mike Pagano
2019-10-05 11:39 Mike Pagano
2019-09-21 15:57 Mike Pagano
2019-09-19 23:16 Mike Pagano
2019-09-16 12:22 Mike Pagano
2019-09-10 11:10 Mike Pagano
2019-09-06 17:18 Mike Pagano
2019-08-25 17:34 Mike Pagano
2019-08-11 10:59 Mike Pagano
2019-08-06 19:16 Mike Pagano
2019-08-04 16:05 Mike Pagano
2019-07-21 14:38 Mike Pagano
2019-07-10 11:03 Mike Pagano
2019-06-27 11:10 Mike Pagano
2019-06-22 19:04 Mike Pagano
2019-06-17 19:19 Mike Pagano
2019-06-11 17:40 Mike Pagano
2019-06-11 12:39 Mike Pagano
2019-05-31 16:42 Mike Pagano
2019-05-26 17:12 Mike Pagano
2019-05-21 17:14 Mike Pagano
2019-05-16 22:59 Mike Pagano
2019-05-14 20:08 Mike Pagano
2019-05-10 19:38 Mike Pagano
2019-05-08 10:03 Mike Pagano
2019-05-04 18:26 Mike Pagano
2019-05-02 10:16 Mike Pagano
2019-04-27 17:29 Mike Pagano
2019-04-20 11:06 Mike Pagano
2019-04-19 19:54 Mike Pagano
2019-04-05 21:42 Mike Pagano
2019-04-03 10:48 Mike Pagano
2019-03-27 10:20 Mike Pagano
2019-03-23 14:57 Mike Pagano
2019-03-23 14:18 Mike Pagano
2019-03-19 16:56 Mike Pagano
2019-03-13 22:05 Mike Pagano
2019-03-06 19:12 Mike Pagano
2019-03-05 17:59 Mike Pagano
2019-02-27 11:20 Mike Pagano
2019-02-23 14:42 Mike Pagano
2019-02-20 11:16 Mike Pagano
2019-02-15 12:46 Mike Pagano
2019-02-12 20:51 Mike Pagano
2019-02-06 20:14 Mike Pagano
2019-01-31 11:22 Mike Pagano
2019-01-26 15:03 Mike Pagano
2019-01-23 11:29 Mike Pagano
2019-01-16 23:29 Mike Pagano
2019-01-13 19:26 Mike Pagano
2019-01-09 18:09 Mike Pagano
2019-01-09 17:52 Mike Pagano
2018-12-29 22:53 Mike Pagano
2018-12-29 18:51 Mike Pagano
2018-12-21 14:44 Mike Pagano
2018-12-17 11:39 Mike Pagano
2018-12-13 11:36 Mike Pagano
2018-12-08 13:25 Mike Pagano
2018-12-05 19:44 Mike Pagano
2018-12-01 18:00 Mike Pagano
2018-12-01 15:04 Mike Pagano
2018-11-27 16:22 Mike Pagano
2018-11-23 12:48 Mike Pagano
2018-11-23 12:45 Mike Pagano
2018-11-21 12:20 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-14 14:37 Mike Pagano
2018-11-13 21:20 Mike Pagano
2018-11-11  1:44 Mike Pagano
2018-11-11  1:31 Mike Pagano
2018-11-10 21:30 Mike Pagano
2018-10-20 12:43 Mike Pagano
2018-10-18 10:25 Mike Pagano
2018-10-13 16:34 Mike Pagano
2018-10-10 11:19 Mike Pagano
2018-10-04 10:40 Mike Pagano
2018-09-29 13:33 Mike Pagano
2018-09-26 10:42 Mike Pagano
2018-09-19 22:38 Mike Pagano
2018-09-15 10:10 Mike Pagano
2018-09-09 23:27 Mike Pagano
2018-09-05 15:27 Mike Pagano
2018-08-24 11:43 Mike Pagano
2018-08-22 10:06 Alice Ferrazzi
2018-08-18 18:07 Mike Pagano
2018-08-17 19:32 Mike Pagano
2018-08-17 19:25 Mike Pagano
2018-08-16 11:51 Mike Pagano
2018-08-15 16:46 Mike Pagano
2018-08-09 10:52 Mike Pagano
2018-08-07 18:12 Mike Pagano
2018-08-03 12:25 Mike Pagano
2018-07-28 10:38 Mike Pagano
2018-07-25 10:26 Mike Pagano
2018-07-22 15:14 Mike Pagano
2018-07-17 10:25 Mike Pagano
2018-07-12 15:42 Alice Ferrazzi
2018-07-03 13:16 Mike Pagano
2018-06-26 16:34 Alice Ferrazzi
2018-06-16 15:42 Mike Pagano
2018-06-13 15:03 Mike Pagano
2018-06-06 18:04 Mike Pagano
2018-06-05 11:21 Mike Pagano
2018-05-30 22:34 Mike Pagano
2018-05-30 11:39 Mike Pagano
2018-05-25 14:54 Mike Pagano
2018-05-22 17:28 Mike Pagano
2018-05-20 22:20 Mike Pagano
2018-05-16 10:23 Mike Pagano
2018-05-09 10:54 Mike Pagano
2018-05-02 16:13 Mike Pagano
2018-04-30 10:29 Mike Pagano
2018-04-24 11:30 Mike Pagano
2018-04-20 11:12 Mike Pagano
2018-04-13 22:21 Mike Pagano
2018-04-08 14:26 Mike Pagano
2018-03-31 22:17 Mike Pagano
2018-03-28 17:42 Mike Pagano
2018-03-25 14:31 Mike Pagano
2018-03-25 13:39 Mike Pagano
2018-03-22 12:58 Mike Pagano
2018-03-18 22:15 Mike Pagano
2018-03-11 18:26 Mike Pagano
2018-03-05  2:38 Alice Ferrazzi
2018-02-28 18:46 Alice Ferrazzi
2018-02-28 15:02 Alice Ferrazzi
2018-02-25 15:47 Mike Pagano
2018-02-22 23:22 Mike Pagano
2018-02-13 13:25 Alice Ferrazzi
2018-02-03 21:22 Mike Pagano
2018-01-31 13:31 Alice Ferrazzi
2018-01-23 21:17 Mike Pagano
2018-01-17 10:18 Alice Ferrazzi
2018-01-17 10:18 Alice Ferrazzi
2018-01-17  9:16 Alice Ferrazzi
2018-01-15 14:57 Alice Ferrazzi
2018-01-10 12:21 Alice Ferrazzi
2018-01-10 11:47 Mike Pagano
2018-01-05 15:54 Alice Ferrazzi
2018-01-05 15:04 Alice Ferrazzi
2018-01-02 20:13 Mike Pagano
2017-12-29 17:20 Alice Ferrazzi
2017-12-25 14:36 Alice Ferrazzi
2017-12-20 12:44 Mike Pagano
2017-12-16 17:42 Alice Ferrazzi
2017-12-14  8:58 Alice Ferrazzi
2017-12-09 23:29 Mike Pagano
2017-12-05 11:38 Mike Pagano
2017-11-30 12:19 Alice Ferrazzi
2017-11-24  9:44 Alice Ferrazzi
2017-11-21  9:18 Alice Ferrazzi
2017-11-18 18:24 Mike Pagano
2017-11-15 15:44 Mike Pagano
2017-11-08 13:49 Mike Pagano
2017-11-02 10:03 Mike Pagano
2017-10-27 10:29 Mike Pagano
2017-10-21 20:15 Mike Pagano
2017-10-18 13:46 Mike Pagano
2017-10-12 22:26 Mike Pagano
2017-10-12 12:37 Mike Pagano
2017-10-08 14:23 Mike Pagano
2017-10-08 14:21 Mike Pagano
2017-10-08 14:13 Mike Pagano
2017-10-05 11:38 Mike Pagano
2017-09-27 16:38 Mike Pagano
2017-09-20 10:11 Mike Pagano
2017-09-14 11:39 Mike Pagano
2017-09-13 22:28 Mike Pagano
2017-09-13 16:25 Mike Pagano
2017-09-10 14:38 Mike Pagano
2017-09-07 22:43 Mike Pagano
2017-09-02 17:45 Mike Pagano
2017-08-30 10:06 Mike Pagano
2017-08-25 10:59 Mike Pagano
2017-08-16 22:29 Mike Pagano
2017-08-13 16:51 Mike Pagano
2017-08-11 17:41 Mike Pagano
2017-08-07 10:26 Mike Pagano
2017-05-14 13:31 Mike Pagano
2017-05-08 10:43 Mike Pagano
2017-05-03 17:45 Mike Pagano
2017-04-27  9:05 Alice Ferrazzi
2017-04-22 17:01 Mike Pagano
2017-04-18 10:23 Mike Pagano
2017-04-12 18:01 Mike Pagano
2017-04-08 13:53 Mike Pagano
2017-03-31 10:44 Mike Pagano
2017-03-30 18:15 Mike Pagano
2017-03-26 11:54 Mike Pagano
2017-03-23 18:38 Mike Pagano
2017-03-22 12:42 Mike Pagano
2017-03-18 14:34 Mike Pagano
2017-03-15 19:21 Mike Pagano
2017-03-12 12:22 Mike Pagano
2017-03-02 16:23 Mike Pagano
2017-02-26 20:38 Mike Pagano
2017-02-26 20:36 Mike Pagano
2017-02-23 20:34 Mike Pagano
2017-02-23 20:11 Mike Pagano
2017-02-18 20:37 Mike Pagano
2017-02-18 16:13 Alice Ferrazzi
2017-02-15 16:02 Alice Ferrazzi
2017-02-14 23:08 Mike Pagano
2017-02-09 11:11 Alice Ferrazzi
2017-02-04 11:34 Alice Ferrazzi
2017-02-01 13:07 Alice Ferrazzi
2017-01-29 23:08 Alice Ferrazzi
2017-01-26  8:51 Alice Ferrazzi
2017-01-20 11:33 Alice Ferrazzi
2017-01-15 22:59 Mike Pagano
2017-01-12 22:53 Mike Pagano
2017-01-09 12:41 Mike Pagano
2017-01-07  0:55 Mike Pagano
2017-01-06 23:09 Mike Pagano
2016-12-31 19:39 Mike Pagano
2016-12-11 23:20 Mike Pagano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1518879709.afbda2ef9bf2c33e80dd8b21c3e0b7a91a182983.alicef@gentoo \
    --to=alicef@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox