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 via email to