diff options
Diffstat (limited to '4.8.7/1004_linux-4.8.5.patch')
-rw-r--r-- | 4.8.7/1004_linux-4.8.5.patch | 5397 |
1 files changed, 5397 insertions, 0 deletions
diff --git a/4.8.7/1004_linux-4.8.5.patch b/4.8.7/1004_linux-4.8.5.patch new file mode 100644 index 0000000..b4a1ae0 --- /dev/null +++ b/4.8.7/1004_linux-4.8.5.patch @@ -0,0 +1,5397 @@ +diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl +index 4ba0a2a..640f65e 100644 +--- a/Documentation/ABI/testing/sysfs-class-cxl ++++ b/Documentation/ABI/testing/sysfs-class-cxl +@@ -220,8 +220,11 @@ What: /sys/class/cxl/<card>/reset + Date: October 2014 + Contact: linuxppc-dev@lists.ozlabs.org + Description: write only +- Writing 1 will issue a PERST to card which may cause the card +- to reload the FPGA depending on load_image_on_perst. ++ Writing 1 will issue a PERST to card provided there are no ++ contexts active on any one of the card AFUs. This may cause ++ the card to reload the FPGA depending on load_image_on_perst. ++ Writing -1 will do a force PERST irrespective of any active ++ contexts on the card AFUs. + Users: https://github.com/ibm-capi/libcxl + + What: /sys/class/cxl/<card>/perst_reloads_same_image (not in a guest) +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index a4f4d69..46726d4 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -1457,7 +1457,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX + controllers + i8042.notimeout [HW] Ignore timeout condition signalled by controller +- i8042.reset [HW] Reset the controller during init and cleanup ++ i8042.reset [HW] Reset the controller during init, cleanup and ++ suspend-to-ram transitions, only during s2r ++ transitions, or never reset ++ Format: { 1 | Y | y | 0 | N | n } ++ 1, Y, y: always reset controller ++ 0, N, n: don't ever reset controller ++ Default: only on s2r transitions on x86; most other ++ architectures force reset to be always executed + i8042.unlock [HW] Unlock (ignore) the keylock + i8042.kbdreset [HW] Reset device connected to KBD port + +diff --git a/Makefile b/Makefile +index 82a36ab..daa3a01 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 8 +-SUBLEVEL = 4 ++SUBLEVEL = 5 + EXTRAVERSION = + NAME = Psychotic Stoned Sheep + +diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c +index 6cb3736..d347bbc 100644 +--- a/arch/arc/kernel/signal.c ++++ b/arch/arc/kernel/signal.c +@@ -107,13 +107,13 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf) + struct user_regs_struct uregs; + + err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); +- if (!err) +- set_current_blocked(&set); +- + err |= __copy_from_user(&uregs.scratch, + &(sf->uc.uc_mcontext.regs.scratch), + sizeof(sf->uc.uc_mcontext.regs.scratch)); ++ if (err) ++ return err; + ++ set_current_blocked(&set); + regs->bta = uregs.scratch.bta; + regs->lp_start = uregs.scratch.lp_start; + regs->lp_end = uregs.scratch.lp_end; +@@ -138,7 +138,7 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf) + regs->r0 = uregs.scratch.r0; + regs->sp = uregs.scratch.sp; + +- return err; ++ return 0; + } + + static inline int is_do_ss_needed(unsigned int magic) +diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h +index 4cdeae3..948a9a8 100644 +--- a/arch/arm64/include/asm/kvm_emulate.h ++++ b/arch/arm64/include/asm/kvm_emulate.h +@@ -167,11 +167,6 @@ static inline bool kvm_vcpu_dabt_isvalid(const struct kvm_vcpu *vcpu) + return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_ISV); + } + +-static inline bool kvm_vcpu_dabt_iswrite(const struct kvm_vcpu *vcpu) +-{ +- return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_WNR); +-} +- + static inline bool kvm_vcpu_dabt_issext(const struct kvm_vcpu *vcpu) + { + return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SSE); +@@ -192,6 +187,12 @@ static inline bool kvm_vcpu_dabt_iss1tw(const struct kvm_vcpu *vcpu) + return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_S1PTW); + } + ++static inline bool kvm_vcpu_dabt_iswrite(const struct kvm_vcpu *vcpu) ++{ ++ return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_WNR) || ++ kvm_vcpu_dabt_iss1tw(vcpu); /* AF/DBM update */ ++} ++ + static inline bool kvm_vcpu_dabt_is_cm(const struct kvm_vcpu *vcpu) + { + return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_CM); +diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h +index e12af67..06ff7fd 100644 +--- a/arch/arm64/include/asm/module.h ++++ b/arch/arm64/include/asm/module.h +@@ -17,6 +17,7 @@ + #define __ASM_MODULE_H + + #include <asm-generic/module.h> ++#include <asm/memory.h> + + #define MODULE_ARCH_VERMAGIC "aarch64" + +@@ -32,6 +33,10 @@ u64 module_emit_plt_entry(struct module *mod, const Elf64_Rela *rela, + Elf64_Sym *sym); + + #ifdef CONFIG_RANDOMIZE_BASE ++#ifdef CONFIG_MODVERSIONS ++#define ARCH_RELOCATES_KCRCTAB ++#define reloc_start (kimage_vaddr - KIMAGE_VADDR) ++#endif + extern u64 module_alloc_base; + #else + #define module_alloc_base ((u64)_etext - MODULES_VSIZE) +diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h +index 2fee2f5..5394c84 100644 +--- a/arch/arm64/include/asm/percpu.h ++++ b/arch/arm64/include/asm/percpu.h +@@ -44,48 +44,44 @@ static inline unsigned long __percpu_##op(void *ptr, \ + \ + switch (size) { \ + case 1: \ +- do { \ +- asm ("//__per_cpu_" #op "_1\n" \ +- "ldxrb %w[ret], %[ptr]\n" \ ++ asm ("//__per_cpu_" #op "_1\n" \ ++ "1: ldxrb %w[ret], %[ptr]\n" \ + #asm_op " %w[ret], %w[ret], %w[val]\n" \ +- "stxrb %w[loop], %w[ret], %[ptr]\n" \ +- : [loop] "=&r" (loop), [ret] "=&r" (ret), \ +- [ptr] "+Q"(*(u8 *)ptr) \ +- : [val] "Ir" (val)); \ +- } while (loop); \ ++ " stxrb %w[loop], %w[ret], %[ptr]\n" \ ++ " cbnz %w[loop], 1b" \ ++ : [loop] "=&r" (loop), [ret] "=&r" (ret), \ ++ [ptr] "+Q"(*(u8 *)ptr) \ ++ : [val] "Ir" (val)); \ + break; \ + case 2: \ +- do { \ +- asm ("//__per_cpu_" #op "_2\n" \ +- "ldxrh %w[ret], %[ptr]\n" \ ++ asm ("//__per_cpu_" #op "_2\n" \ ++ "1: ldxrh %w[ret], %[ptr]\n" \ + #asm_op " %w[ret], %w[ret], %w[val]\n" \ +- "stxrh %w[loop], %w[ret], %[ptr]\n" \ +- : [loop] "=&r" (loop), [ret] "=&r" (ret), \ +- [ptr] "+Q"(*(u16 *)ptr) \ +- : [val] "Ir" (val)); \ +- } while (loop); \ ++ " stxrh %w[loop], %w[ret], %[ptr]\n" \ ++ " cbnz %w[loop], 1b" \ ++ : [loop] "=&r" (loop), [ret] "=&r" (ret), \ ++ [ptr] "+Q"(*(u16 *)ptr) \ ++ : [val] "Ir" (val)); \ + break; \ + case 4: \ +- do { \ +- asm ("//__per_cpu_" #op "_4\n" \ +- "ldxr %w[ret], %[ptr]\n" \ ++ asm ("//__per_cpu_" #op "_4\n" \ ++ "1: ldxr %w[ret], %[ptr]\n" \ + #asm_op " %w[ret], %w[ret], %w[val]\n" \ +- "stxr %w[loop], %w[ret], %[ptr]\n" \ +- : [loop] "=&r" (loop), [ret] "=&r" (ret), \ +- [ptr] "+Q"(*(u32 *)ptr) \ +- : [val] "Ir" (val)); \ +- } while (loop); \ ++ " stxr %w[loop], %w[ret], %[ptr]\n" \ ++ " cbnz %w[loop], 1b" \ ++ : [loop] "=&r" (loop), [ret] "=&r" (ret), \ ++ [ptr] "+Q"(*(u32 *)ptr) \ ++ : [val] "Ir" (val)); \ + break; \ + case 8: \ +- do { \ +- asm ("//__per_cpu_" #op "_8\n" \ +- "ldxr %[ret], %[ptr]\n" \ ++ asm ("//__per_cpu_" #op "_8\n" \ ++ "1: ldxr %[ret], %[ptr]\n" \ + #asm_op " %[ret], %[ret], %[val]\n" \ +- "stxr %w[loop], %[ret], %[ptr]\n" \ +- : [loop] "=&r" (loop), [ret] "=&r" (ret), \ +- [ptr] "+Q"(*(u64 *)ptr) \ +- : [val] "Ir" (val)); \ +- } while (loop); \ ++ " stxr %w[loop], %[ret], %[ptr]\n" \ ++ " cbnz %w[loop], 1b" \ ++ : [loop] "=&r" (loop), [ret] "=&r" (ret), \ ++ [ptr] "+Q"(*(u64 *)ptr) \ ++ : [val] "Ir" (val)); \ + break; \ + default: \ + BUILD_BUG(); \ +@@ -150,44 +146,40 @@ static inline unsigned long __percpu_xchg(void *ptr, unsigned long val, + + switch (size) { + case 1: +- do { +- asm ("//__percpu_xchg_1\n" +- "ldxrb %w[ret], %[ptr]\n" +- "stxrb %w[loop], %w[val], %[ptr]\n" +- : [loop] "=&r"(loop), [ret] "=&r"(ret), +- [ptr] "+Q"(*(u8 *)ptr) +- : [val] "r" (val)); +- } while (loop); ++ asm ("//__percpu_xchg_1\n" ++ "1: ldxrb %w[ret], %[ptr]\n" ++ " stxrb %w[loop], %w[val], %[ptr]\n" ++ " cbnz %w[loop], 1b" ++ : [loop] "=&r"(loop), [ret] "=&r"(ret), ++ [ptr] "+Q"(*(u8 *)ptr) ++ : [val] "r" (val)); + break; + case 2: +- do { +- asm ("//__percpu_xchg_2\n" +- "ldxrh %w[ret], %[ptr]\n" +- "stxrh %w[loop], %w[val], %[ptr]\n" +- : [loop] "=&r"(loop), [ret] "=&r"(ret), +- [ptr] "+Q"(*(u16 *)ptr) +- : [val] "r" (val)); +- } while (loop); ++ asm ("//__percpu_xchg_2\n" ++ "1: ldxrh %w[ret], %[ptr]\n" ++ " stxrh %w[loop], %w[val], %[ptr]\n" ++ " cbnz %w[loop], 1b" ++ : [loop] "=&r"(loop), [ret] "=&r"(ret), ++ [ptr] "+Q"(*(u16 *)ptr) ++ : [val] "r" (val)); + break; + case 4: +- do { +- asm ("//__percpu_xchg_4\n" +- "ldxr %w[ret], %[ptr]\n" +- "stxr %w[loop], %w[val], %[ptr]\n" +- : [loop] "=&r"(loop), [ret] "=&r"(ret), +- [ptr] "+Q"(*(u32 *)ptr) +- : [val] "r" (val)); +- } while (loop); ++ asm ("//__percpu_xchg_4\n" ++ "1: ldxr %w[ret], %[ptr]\n" ++ " stxr %w[loop], %w[val], %[ptr]\n" ++ " cbnz %w[loop], 1b" ++ : [loop] "=&r"(loop), [ret] "=&r"(ret), ++ [ptr] "+Q"(*(u32 *)ptr) ++ : [val] "r" (val)); + break; + case 8: +- do { +- asm ("//__percpu_xchg_8\n" +- "ldxr %[ret], %[ptr]\n" +- "stxr %w[loop], %[val], %[ptr]\n" +- : [loop] "=&r"(loop), [ret] "=&r"(ret), +- [ptr] "+Q"(*(u64 *)ptr) +- : [val] "r" (val)); +- } while (loop); ++ asm ("//__percpu_xchg_8\n" ++ "1: ldxr %[ret], %[ptr]\n" ++ " stxr %w[loop], %[val], %[ptr]\n" ++ " cbnz %w[loop], 1b" ++ : [loop] "=&r"(loop), [ret] "=&r"(ret), ++ [ptr] "+Q"(*(u64 *)ptr) ++ : [val] "r" (val)); + break; + default: + BUILD_BUG(); +diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h +index c47257c..db84983 100644 +--- a/arch/arm64/include/asm/uaccess.h ++++ b/arch/arm64/include/asm/uaccess.h +@@ -21,6 +21,7 @@ + /* + * User space memory access functions + */ ++#include <linux/bitops.h> + #include <linux/kasan-checks.h> + #include <linux/string.h> + #include <linux/thread_info.h> +@@ -102,6 +103,13 @@ static inline void set_fs(mm_segment_t fs) + flag; \ + }) + ++/* ++ * When dealing with data aborts or instruction traps we may end up with ++ * a tagged userland pointer. Clear the tag to get a sane pointer to pass ++ * on to access_ok(), for instance. ++ */ ++#define untagged_addr(addr) sign_extend64(addr, 55) ++ + #define access_ok(type, addr, size) __range_ok(addr, size) + #define user_addr_max get_fs + +diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c +index 42ffdb5..b0988bb 100644 +--- a/arch/arm64/kernel/armv8_deprecated.c ++++ b/arch/arm64/kernel/armv8_deprecated.c +@@ -280,35 +280,43 @@ static void __init register_insn_emulation_sysctl(struct ctl_table *table) + /* + * Error-checking SWP macros implemented using ldxr{b}/stxr{b} + */ +-#define __user_swpX_asm(data, addr, res, temp, B) \ ++ ++/* Arbitrary constant to ensure forward-progress of the LL/SC loop */ ++#define __SWP_LL_SC_LOOPS 4 ++ ++#define __user_swpX_asm(data, addr, res, temp, temp2, B) \ + __asm__ __volatile__( \ ++ " mov %w3, %w7\n" \ + ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, \ + CONFIG_ARM64_PAN) \ +- "0: ldxr"B" %w2, [%3]\n" \ +- "1: stxr"B" %w0, %w1, [%3]\n" \ ++ "0: ldxr"B" %w2, [%4]\n" \ ++ "1: stxr"B" %w0, %w1, [%4]\n" \ + " cbz %w0, 2f\n" \ +- " mov %w0, %w4\n" \ ++ " sub %w3, %w3, #1\n" \ ++ " cbnz %w3, 0b\n" \ ++ " mov %w0, %w5\n" \ + " b 3f\n" \ + "2:\n" \ + " mov %w1, %w2\n" \ + "3:\n" \ + " .pushsection .fixup,\"ax\"\n" \ + " .align 2\n" \ +- "4: mov %w0, %w5\n" \ ++ "4: mov %w0, %w6\n" \ + " b 3b\n" \ + " .popsection" \ + _ASM_EXTABLE(0b, 4b) \ + _ASM_EXTABLE(1b, 4b) \ + ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, \ + CONFIG_ARM64_PAN) \ +- : "=&r" (res), "+r" (data), "=&r" (temp) \ +- : "r" (addr), "i" (-EAGAIN), "i" (-EFAULT) \ ++ : "=&r" (res), "+r" (data), "=&r" (temp), "=&r" (temp2) \ ++ : "r" (addr), "i" (-EAGAIN), "i" (-EFAULT), \ ++ "i" (__SWP_LL_SC_LOOPS) \ + : "memory") + +-#define __user_swp_asm(data, addr, res, temp) \ +- __user_swpX_asm(data, addr, res, temp, "") +-#define __user_swpb_asm(data, addr, res, temp) \ +- __user_swpX_asm(data, addr, res, temp, "b") ++#define __user_swp_asm(data, addr, res, temp, temp2) \ ++ __user_swpX_asm(data, addr, res, temp, temp2, "") ++#define __user_swpb_asm(data, addr, res, temp, temp2) \ ++ __user_swpX_asm(data, addr, res, temp, temp2, "b") + + /* + * Bit 22 of the instruction encoding distinguishes between +@@ -328,12 +336,12 @@ static int emulate_swpX(unsigned int address, unsigned int *data, + } + + while (1) { +- unsigned long temp; ++ unsigned long temp, temp2; + + if (type == TYPE_SWPB) +- __user_swpb_asm(*data, address, res, temp); ++ __user_swpb_asm(*data, address, res, temp, temp2); + else +- __user_swp_asm(*data, address, res, temp); ++ __user_swp_asm(*data, address, res, temp, temp2); + + if (likely(res != -EAGAIN) || signal_pending(current)) + break; +diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S +index 3e7b050..4d19508 100644 +--- a/arch/arm64/kernel/head.S ++++ b/arch/arm64/kernel/head.S +@@ -578,8 +578,9 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems + b.lt 4f // Skip if no PMU present + mrs x0, pmcr_el0 // Disable debug access traps + ubfx x0, x0, #11, #5 // to EL2 and allow access to +- msr mdcr_el2, x0 // all PMU counters from EL1 + 4: ++ csel x0, xzr, x0, lt // all PMU counters from EL1 ++ msr mdcr_el2, x0 // (if they exist) + + /* Stage-2 translation */ + msr vttbr_el2, xzr +diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c +index df06750..771a01a7f 100644 +--- a/arch/arm64/kernel/traps.c ++++ b/arch/arm64/kernel/traps.c +@@ -434,18 +434,21 @@ void cpu_enable_cache_maint_trap(void *__unused) + } + + #define __user_cache_maint(insn, address, res) \ +- asm volatile ( \ +- "1: " insn ", %1\n" \ +- " mov %w0, #0\n" \ +- "2:\n" \ +- " .pushsection .fixup,\"ax\"\n" \ +- " .align 2\n" \ +- "3: mov %w0, %w2\n" \ +- " b 2b\n" \ +- " .popsection\n" \ +- _ASM_EXTABLE(1b, 3b) \ +- : "=r" (res) \ +- : "r" (address), "i" (-EFAULT) ) ++ if (untagged_addr(address) >= user_addr_max()) \ ++ res = -EFAULT; \ ++ else \ ++ asm volatile ( \ ++ "1: " insn ", %1\n" \ ++ " mov %w0, #0\n" \ ++ "2:\n" \ ++ " .pushsection .fixup,\"ax\"\n" \ ++ " .align 2\n" \ ++ "3: mov %w0, %w2\n" \ ++ " b 2b\n" \ ++ " .popsection\n" \ ++ _ASM_EXTABLE(1b, 3b) \ ++ : "=r" (res) \ ++ : "r" (address), "i" (-EFAULT) ) + + asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs) + { +diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S +index ce9e5e5..eaf08d3 100644 +--- a/arch/arm64/kvm/hyp/entry.S ++++ b/arch/arm64/kvm/hyp/entry.S +@@ -98,6 +98,8 @@ ENTRY(__guest_exit) + // x4-x29,lr: vcpu regs + // vcpu x0-x3 on the stack + ++ ALTERNATIVE(nop, SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN) ++ + add x2, x0, #VCPU_CONTEXT + + stp x4, x5, [x2, #CPU_XREG_OFFSET(4)] +diff --git a/arch/metag/include/asm/atomic.h b/arch/metag/include/asm/atomic.h +index 470e365..8ff0a70 100644 +--- a/arch/metag/include/asm/atomic.h ++++ b/arch/metag/include/asm/atomic.h +@@ -39,11 +39,10 @@ + #define atomic_dec(v) atomic_sub(1, (v)) + + #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) ++#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v) + + #endif + +-#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v) +- + #include <asm-generic/atomic64.h> + + #endif /* __ASM_METAG_ATOMIC_H */ +diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h +index f6fc6aa..b657861 100644 +--- a/arch/mips/include/asm/ptrace.h ++++ b/arch/mips/include/asm/ptrace.h +@@ -152,7 +152,7 @@ static inline int is_syscall_success(struct pt_regs *regs) + + static inline long regs_return_value(struct pt_regs *regs) + { +- if (is_syscall_success(regs)) ++ if (is_syscall_success(regs) || !user_mode(regs)) + return regs->regs[2]; + else + return -regs->regs[2]; +diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile +index 3b4538e..de9e8836 100644 +--- a/arch/mips/vdso/Makefile ++++ b/arch/mips/vdso/Makefile +@@ -82,7 +82,7 @@ obj-vdso := $(obj-vdso-y:%.o=$(obj)/%.o) + $(obj-vdso): KBUILD_CFLAGS := $(cflags-vdso) $(native-abi) + $(obj-vdso): KBUILD_AFLAGS := $(aflags-vdso) $(native-abi) + +-$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(native-abi) ++$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) $(native-abi) + + $(obj)/vdso.so.dbg.raw: $(obj)/vdso.lds $(obj-vdso) FORCE + $(call if_changed,vdsold) +diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h +index 291cee2..c2c43f7 100644 +--- a/arch/parisc/include/asm/pgtable.h ++++ b/arch/parisc/include/asm/pgtable.h +@@ -83,10 +83,10 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr) + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e)) + + /* This is the size of the initially mapped kernel memory */ +-#ifdef CONFIG_64BIT +-#define KERNEL_INITIAL_ORDER 25 /* 1<<25 = 32MB */ ++#if defined(CONFIG_64BIT) ++#define KERNEL_INITIAL_ORDER 26 /* 1<<26 = 64MB */ + #else +-#define KERNEL_INITIAL_ORDER 24 /* 1<<24 = 16MB */ ++#define KERNEL_INITIAL_ORDER 25 /* 1<<25 = 32MB */ + #endif + #define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER) + +diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c +index f7ea626..81d6f63 100644 +--- a/arch/parisc/kernel/setup.c ++++ b/arch/parisc/kernel/setup.c +@@ -38,6 +38,7 @@ + #include <linux/export.h> + + #include <asm/processor.h> ++#include <asm/sections.h> + #include <asm/pdc.h> + #include <asm/led.h> + #include <asm/machdep.h> /* for pa7300lc_init() proto */ +@@ -140,6 +141,13 @@ void __init setup_arch(char **cmdline_p) + #endif + printk(KERN_CONT ".\n"); + ++ /* ++ * Check if initial kernel page mappings are sufficient. ++ * panic early if not, else we may access kernel functions ++ * and variables which can't be reached. ++ */ ++ if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE) ++ panic("KERNEL_INITIAL_ORDER too small!"); + + pdc_console_init(); + +diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c +index 4b0b963..9b63b87 100644 +--- a/arch/parisc/kernel/time.c ++++ b/arch/parisc/kernel/time.c +@@ -226,12 +226,6 @@ void __init start_cpu_itimer(void) + unsigned int cpu = smp_processor_id(); + unsigned long next_tick = mfctl(16) + clocktick; + +-#if defined(CONFIG_HAVE_UNSTABLE_SCHED_CLOCK) && defined(CONFIG_64BIT) +- /* With multiple 64bit CPUs online, the cr16's are not syncronized. */ +- if (cpu != 0) +- clear_sched_clock_stable(); +-#endif +- + mtctl(next_tick, 16); /* kick off Interval Timer (CR16) */ + + per_cpu(cpu_data, cpu).it_value = next_tick; +diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S +index f3ead0b..75304af 100644 +--- a/arch/parisc/kernel/vmlinux.lds.S ++++ b/arch/parisc/kernel/vmlinux.lds.S +@@ -89,8 +89,9 @@ SECTIONS + /* Start of data section */ + _sdata = .; + +- RO_DATA_SECTION(8) +- ++ /* Architecturally we need to keep __gp below 0x1000000 and thus ++ * in front of RO_DATA_SECTION() which stores lots of tracepoint ++ * and ftrace symbols. */ + #ifdef CONFIG_64BIT + . = ALIGN(16); + /* Linkage tables */ +@@ -105,6 +106,8 @@ SECTIONS + } + #endif + ++ RO_DATA_SECTION(8) ++ + /* unwind info */ + .PARISC.unwind : { + __start___unwind = .; +diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig +index 927d2ab..792cb17 100644 +--- a/arch/powerpc/Kconfig ++++ b/arch/powerpc/Kconfig +@@ -637,7 +637,7 @@ config FORCE_MAX_ZONEORDER + int "Maximum zone order" + range 8 9 if PPC64 && PPC_64K_PAGES + default "9" if PPC64 && PPC_64K_PAGES +- range 9 13 if PPC64 && !PPC_64K_PAGES ++ range 13 13 if PPC64 && !PPC_64K_PAGES + default "13" if PPC64 && !PPC_64K_PAGES + range 9 64 if PPC32 && PPC_16K_PAGES + default "9" if PPC32 && PPC_16K_PAGES +diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c +index 5f36e8a..29aa8d1 100644 +--- a/arch/powerpc/kernel/eeh_driver.c ++++ b/arch/powerpc/kernel/eeh_driver.c +@@ -994,6 +994,14 @@ static void eeh_handle_special_event(void) + /* Notify all devices to be down */ + eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); + bus = eeh_pe_bus_get(phb_pe); ++ if (!bus) { ++ pr_err("%s: Cannot find PCI bus for " ++ "PHB#%d-PE#%x\n", ++ __func__, ++ pe->phb->global_number, ++ pe->addr); ++ break; ++ } + eeh_pe_dev_traverse(pe, + eeh_report_failure, NULL); + pci_hp_remove_devices(bus); +diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S +index 184a6ba..abf17fe 100644 +--- a/arch/powerpc/kernel/vdso64/datapage.S ++++ b/arch/powerpc/kernel/vdso64/datapage.S +@@ -59,7 +59,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map) + bl V_LOCAL_FUNC(__get_datapage) + mtlr r12 + addi r3,r3,CFG_SYSCALL_MAP64 +- cmpli cr0,r4,0 ++ cmpldi cr0,r4,0 + crclr cr0*4+so + beqlr + li r0,NR_syscalls +diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S +index a76b4af..3820213 100644 +--- a/arch/powerpc/kernel/vdso64/gettimeofday.S ++++ b/arch/powerpc/kernel/vdso64/gettimeofday.S +@@ -145,7 +145,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres) + bne cr0,99f + + li r3,0 +- cmpli cr0,r4,0 ++ cmpldi cr0,r4,0 + crclr cr0*4+so + beqlr + lis r5,CLOCK_REALTIME_RES@h +diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S +index f09899e..7b22624 100644 +--- a/arch/powerpc/lib/copyuser_64.S ++++ b/arch/powerpc/lib/copyuser_64.S +@@ -359,6 +359,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) + addi r3,r3,8 + 171: + 177: ++179: + addi r3,r3,8 + 370: + 372: +@@ -373,7 +374,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) + 173: + 174: + 175: +-179: + 181: + 184: + 186: +diff --git a/arch/powerpc/mm/copro_fault.c b/arch/powerpc/mm/copro_fault.c +index bb03542..362954f 100644 +--- a/arch/powerpc/mm/copro_fault.c ++++ b/arch/powerpc/mm/copro_fault.c +@@ -106,6 +106,8 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb) + switch (REGION_ID(ea)) { + case USER_REGION_ID: + pr_devel("%s: 0x%llx -- USER_REGION_ID\n", __func__, ea); ++ if (mm == NULL) ++ return 1; + psize = get_slice_psize(mm, ea); + ssize = user_segment_size(ea); + vsid = get_vsid(mm->context.id, ea, ssize); +diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c +index 0821556..28923b2 100644 +--- a/arch/powerpc/mm/hash_utils_64.c ++++ b/arch/powerpc/mm/hash_utils_64.c +@@ -526,7 +526,7 @@ static bool might_have_hea(void) + */ + #ifdef CONFIG_IBMEBUS + return !cpu_has_feature(CPU_FTR_ARCH_207S) && +- !firmware_has_feature(FW_FEATURE_SPLPAR); ++ firmware_has_feature(FW_FEATURE_SPLPAR); + #else + return false; + #endif +diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c +index 86544ea..ba17fdd 100644 +--- a/arch/powerpc/platforms/powernv/eeh-powernv.c ++++ b/arch/powerpc/platforms/powernv/eeh-powernv.c +@@ -1091,6 +1091,11 @@ static int pnv_eeh_reset(struct eeh_pe *pe, int option) + } + + bus = eeh_pe_bus_get(pe); ++ if (!bus) { ++ pr_err("%s: Cannot find PCI bus for PHB#%d-PE#%x\n", ++ __func__, pe->phb->global_number, pe->addr); ++ return -EIO; ++ } + if (pe->type & EEH_PE_VF) + return pnv_eeh_reset_vf_pe(pe, option); + +@@ -1306,7 +1311,7 @@ static void pnv_eeh_get_and_dump_hub_diag(struct pci_controller *hose) + return; + } + +- switch (data->type) { ++ switch (be16_to_cpu(data->type)) { + case OPAL_P7IOC_DIAG_TYPE_RGC: + pr_info("P7IOC diag-data for RGC\n\n"); + pnv_eeh_dump_hub_diag_common(data); +@@ -1538,7 +1543,7 @@ static int pnv_eeh_next_error(struct eeh_pe **pe) + + /* Try best to clear it */ + opal_pci_eeh_freeze_clear(phb->opal_id, +- frozen_pe_no, ++ be64_to_cpu(frozen_pe_no), + OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); + ret = EEH_NEXT_ERR_NONE; + } else if ((*pe)->state & EEH_PE_ISOLATED || +diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c +index a21d831..0fe3520 100644 +--- a/arch/powerpc/platforms/powernv/pci.c ++++ b/arch/powerpc/platforms/powernv/pci.c +@@ -309,8 +309,8 @@ static void pnv_pci_dump_p7ioc_diag_data(struct pci_controller *hose, + be64_to_cpu(data->dma1ErrorLog1)); + + for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) { +- if ((data->pestA[i] >> 63) == 0 && +- (data->pestB[i] >> 63) == 0) ++ if ((be64_to_cpu(data->pestA[i]) >> 63) == 0 && ++ (be64_to_cpu(data->pestB[i]) >> 63) == 0) + continue; + + pr_info("PE[%3d] A/B: %016llx %016llx\n", +diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c +index 86707e6..aa35245 100644 +--- a/arch/powerpc/platforms/pseries/lpar.c ++++ b/arch/powerpc/platforms/pseries/lpar.c +@@ -393,7 +393,7 @@ static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot, + unsigned long *vpn, int count, + int psize, int ssize) + { +- unsigned long param[8]; ++ unsigned long param[PLPAR_HCALL9_BUFSIZE]; + int i = 0, pix = 0, rc; + unsigned long flags = 0; + int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); +@@ -522,7 +522,7 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local) + unsigned long flags = 0; + struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); + int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); +- unsigned long param[9]; ++ unsigned long param[PLPAR_HCALL9_BUFSIZE]; + unsigned long hash, index, shift, hidx, slot; + real_pte_t pte; + int psize, ssize; +diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c +index 81d4947..82e8e2b 100644 +--- a/arch/powerpc/sysdev/cpm1.c ++++ b/arch/powerpc/sysdev/cpm1.c +@@ -233,8 +233,6 @@ void __init cpm_reset(void) + else + out_be32(&siu_conf->sc_sdcr, 1); + immr_unmap(siu_conf); +- +- cpm_muram_init(); + } + + static DEFINE_SPINLOCK(cmd_lock); +diff --git a/arch/powerpc/sysdev/cpm2.c b/arch/powerpc/sysdev/cpm2.c +index 8dc1e24..f78ff84 100644 +--- a/arch/powerpc/sysdev/cpm2.c ++++ b/arch/powerpc/sysdev/cpm2.c +@@ -66,10 +66,6 @@ void __init cpm2_reset(void) + cpm2_immr = ioremap(get_immrbase(), CPM_MAP_SIZE); + #endif + +- /* Reclaim the DP memory for our use. +- */ +- cpm_muram_init(); +- + /* Tell everyone where the comm processor resides. + */ + cpmp = &cpm2_immr->im_cpm; +diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c +index 947f420..51bf749 100644 +--- a/arch/powerpc/sysdev/cpm_common.c ++++ b/arch/powerpc/sysdev/cpm_common.c +@@ -37,6 +37,21 @@ + #include <linux/of_gpio.h> + #endif + ++static int __init cpm_init(void) ++{ ++ struct device_node *np; ++ ++ np = of_find_compatible_node(NULL, NULL, "fsl,cpm1"); ++ if (!np) ++ np = of_find_compatible_node(NULL, NULL, "fsl,cpm2"); ++ if (!np) ++ return -ENODEV; ++ cpm_muram_init(); ++ of_node_put(np); ++ return 0; ++} ++subsys_initcall(cpm_init); ++ + #ifdef CONFIG_PPC_EARLY_DEBUG_CPM + static u32 __iomem *cpm_udbg_txdesc; + static u8 __iomem *cpm_udbg_txbuf; +diff --git a/arch/powerpc/xmon/spr_access.S b/arch/powerpc/xmon/spr_access.S +index 84ad742..7d8b0e8 100644 +--- a/arch/powerpc/xmon/spr_access.S ++++ b/arch/powerpc/xmon/spr_access.S +@@ -2,12 +2,12 @@ + + /* unsigned long xmon_mfspr(sprn, default_value) */ + _GLOBAL(xmon_mfspr) +- ld r5, .Lmfspr_table@got(r2) ++ PPC_LL r5, .Lmfspr_table@got(r2) + b xmon_mxspr + + /* void xmon_mtspr(sprn, new_value) */ + _GLOBAL(xmon_mtspr) +- ld r5, .Lmtspr_table@got(r2) ++ PPC_LL r5, .Lmtspr_table@got(r2) + b xmon_mxspr + + /* +diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c +index dfd0ca2..9746b78 100644 +--- a/arch/s390/kvm/intercept.c ++++ b/arch/s390/kvm/intercept.c +@@ -118,8 +118,13 @@ static int handle_validity(struct kvm_vcpu *vcpu) + + vcpu->stat.exit_validity++; + trace_kvm_s390_intercept_validity(vcpu, viwhy); +- WARN_ONCE(true, "kvm: unhandled validity intercept 0x%x\n", viwhy); +- return -EOPNOTSUPP; ++ KVM_EVENT(3, "validity intercept 0x%x for pid %u (kvm 0x%pK)", viwhy, ++ current->pid, vcpu->kvm); ++ ++ /* do not warn on invalid runtime instrumentation mode */ ++ WARN_ONCE(viwhy != 0x44, "kvm: unhandled validity intercept 0x%x\n", ++ viwhy); ++ return -EINVAL; + } + + static int handle_instruction(struct kvm_vcpu *vcpu) +diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c +index 8a90f15..625eb69 100644 +--- a/arch/x86/kernel/e820.c ++++ b/arch/x86/kernel/e820.c +@@ -348,7 +348,7 @@ int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, + * continue building up new bios map based on this + * information + */ +- if (current_type != last_type) { ++ if (current_type != last_type || current_type == E820_PRAM) { + if (last_type != 0) { + new_bios[new_bios_entry].size = + change_point[chgidx]->addr - last_addr; +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index 82b1737..9e152cd 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -1408,15 +1408,17 @@ __init void prefill_possible_map(void) + + /* No boot processor was found in mptable or ACPI MADT */ + if (!num_processors) { +- int apicid = boot_cpu_physical_apicid; +- int cpu = hard_smp_processor_id(); ++ if (boot_cpu_has(X86_FEATURE_APIC)) { ++ int apicid = boot_cpu_physical_apicid; ++ int cpu = hard_smp_processor_id(); + +- pr_warn("Boot CPU (id %d) not listed by BIOS\n", cpu); ++ pr_warn("Boot CPU (id %d) not listed by BIOS\n", cpu); + +- /* Make sure boot cpu is enumerated */ +- if (apic->cpu_present_to_apicid(0) == BAD_APICID && +- apic->apic_id_valid(apicid)) +- generic_processor_info(apicid, boot_cpu_apic_version); ++ /* Make sure boot cpu is enumerated */ ++ if (apic->cpu_present_to_apicid(0) == BAD_APICID && ++ apic->apic_id_valid(apicid)) ++ generic_processor_info(apicid, boot_cpu_apic_version); ++ } + + if (!num_processors) + num_processors = 1; +diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c +index c7220ba..1a22de7 100644 +--- a/arch/x86/kvm/ioapic.c ++++ b/arch/x86/kvm/ioapic.c +@@ -594,7 +594,7 @@ static void kvm_ioapic_reset(struct kvm_ioapic *ioapic) + ioapic->irr = 0; + ioapic->irr_delivered = 0; + ioapic->id = 0; +- memset(ioapic->irq_eoi, 0x00, IOAPIC_NUM_PINS); ++ memset(ioapic->irq_eoi, 0x00, sizeof(ioapic->irq_eoi)); + rtc_irq_eoi_tracking_reset(ioapic); + } + +diff --git a/arch/x86/platform/uv/bios_uv.c b/arch/x86/platform/uv/bios_uv.c +index 23f2f3e..58e152b 100644 +--- a/arch/x86/platform/uv/bios_uv.c ++++ b/arch/x86/platform/uv/bios_uv.c +@@ -40,7 +40,15 @@ s64 uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5) + */ + return BIOS_STATUS_UNIMPLEMENTED; + +- ret = efi_call_virt_pointer(tab, function, (u64)which, a1, a2, a3, a4, a5); ++ /* ++ * If EFI_OLD_MEMMAP is set, we need to fall back to using our old EFI ++ * callback method, which uses efi_call() directly, with the kernel page tables: ++ */ ++ if (unlikely(test_bit(EFI_OLD_MEMMAP, &efi.flags))) ++ ret = efi_call((void *)__va(tab->function), (u64)which, a1, a2, a3, a4, a5); ++ else ++ ret = efi_call_virt_pointer(tab, function, (u64)which, a1, a2, a3, a4, a5); ++ + return ret; + } + EXPORT_SYMBOL_GPL(uv_bios_call); +diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c +index dd38e5c..b08ccbb 100644 +--- a/block/blk-cgroup.c ++++ b/block/blk-cgroup.c +@@ -1340,10 +1340,8 @@ int blkcg_policy_register(struct blkcg_policy *pol) + struct blkcg_policy_data *cpd; + + cpd = pol->cpd_alloc_fn(GFP_KERNEL); +- if (!cpd) { +- mutex_unlock(&blkcg_pol_mutex); ++ if (!cpd) + goto err_free_cpds; +- } + + blkcg->cpd[pol->plid] = cpd; + cpd->blkcg = blkcg; +diff --git a/drivers/base/platform.c b/drivers/base/platform.c +index 6482d47..d557229 100644 +--- a/drivers/base/platform.c ++++ b/drivers/base/platform.c +@@ -97,7 +97,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num) + int ret; + + ret = of_irq_get(dev->dev.of_node, num); +- if (ret >= 0 || ret == -EPROBE_DEFER) ++ if (ret > 0 || ret == -EPROBE_DEFER) + return ret; + } + +@@ -175,7 +175,7 @@ int platform_get_irq_byname(struct platform_device *dev, const char *name) + int ret; + + ret = of_irq_get_byname(dev->dev.of_node, name); +- if (ret >= 0 || ret == -EPROBE_DEFER) ++ if (ret > 0 || ret == -EPROBE_DEFER) + return ret; + } + +diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c +index ba1c1ae..ce8ea10 100644 +--- a/drivers/clk/imx/clk-imx6q.c ++++ b/drivers/clk/imx/clk-imx6q.c +@@ -318,11 +318,16 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) + clk[IMX6QDL_CLK_IPG_PER_SEL] = imx_clk_mux("ipg_per_sel", base + 0x1c, 6, 1, ipg_per_sels, ARRAY_SIZE(ipg_per_sels)); + clk[IMX6QDL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); + clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels_2, ARRAY_SIZE(gpu2d_core_sels_2)); ++ } else if (clk_on_imx6dl()) { ++ clk[IMX6QDL_CLK_MLB_SEL] = imx_clk_mux("mlb_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels)); + } else { + clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels)); + } + clk[IMX6QDL_CLK_GPU3D_CORE_SEL] = imx_clk_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels)); +- clk[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); ++ if (clk_on_imx6dl()) ++ clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); ++ else ++ clk[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); + clk[IMX6QDL_CLK_IPU1_SEL] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); + clk[IMX6QDL_CLK_IPU2_SEL] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); + clk[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); +@@ -400,9 +405,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) + clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); + clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); + } +- clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3); ++ if (clk_on_imx6dl()) ++ clk[IMX6QDL_CLK_MLB_PODF] = imx_clk_divider("mlb_podf", "mlb_sel", base + 0x18, 23, 3); ++ else ++ clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3); + clk[IMX6QDL_CLK_GPU3D_CORE_PODF] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3); +- clk[IMX6QDL_CLK_GPU3D_SHADER] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3); ++ if (clk_on_imx6dl()) ++ clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 29, 3); ++ else ++ clk[IMX6QDL_CLK_GPU3D_SHADER] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3); + clk[IMX6QDL_CLK_IPU1_PODF] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); + clk[IMX6QDL_CLK_IPU2_PODF] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); + clk[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0); +@@ -473,14 +484,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) + clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); + clk[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20); + clk[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22); +- if (clk_on_imx6dl()) +- /* +- * The multiplexer and divider of imx6q clock gpu3d_shader get +- * redefined/reused as gpu2d_core_sel and gpu2d_core_podf on imx6dl. +- */ +- clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu3d_shader", base + 0x6c, 24); +- else +- clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24); ++ clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24); + clk[IMX6QDL_CLK_GPU3D_CORE] = imx_clk_gate2("gpu3d_core", "gpu3d_core_podf", base + 0x6c, 26); + clk[IMX6QDL_CLK_HDMI_IAHB] = imx_clk_gate2("hdmi_iahb", "ahb", base + 0x70, 0); + clk[IMX6QDL_CLK_HDMI_ISFR] = imx_clk_gate2("hdmi_isfr", "video_27m", base + 0x70, 4); +@@ -511,7 +515,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) + * The multiplexer and divider of the imx6q clock gpu2d get + * redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl. + */ +- clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "gpu2d_core_podf", base + 0x74, 18); ++ clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "mlb_podf", base + 0x74, 18); + else + clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "axi", base + 0x74, 18); + clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20); +@@ -629,6 +633,24 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) + if (IS_ENABLED(CONFIG_PCI_IMX6)) + clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]); + ++ /* ++ * Initialize the GPU clock muxes, so that the maximum specified clock ++ * rates for the respective SoC are not exceeded. ++ */ ++ if (clk_on_imx6dl()) { ++ clk_set_parent(clk[IMX6QDL_CLK_GPU3D_CORE_SEL], ++ clk[IMX6QDL_CLK_PLL2_PFD1_594M]); ++ clk_set_parent(clk[IMX6QDL_CLK_GPU2D_CORE_SEL], ++ clk[IMX6QDL_CLK_PLL2_PFD1_594M]); ++ } else if (clk_on_imx6q()) { ++ clk_set_parent(clk[IMX6QDL_CLK_GPU3D_CORE_SEL], ++ clk[IMX6QDL_CLK_MMDC_CH0_AXI]); ++ clk_set_parent(clk[IMX6QDL_CLK_GPU3D_SHADER_SEL], ++ clk[IMX6QDL_CLK_PLL2_PFD1_594M]); ++ clk_set_parent(clk[IMX6QDL_CLK_GPU2D_CORE_SEL], ++ clk[IMX6QDL_CLK_PLL3_USB_OTG]); ++ } ++ + imx_register_uart_clocks(uart_clks); + } + CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init); +diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c +index 2ee40fd..e1aa531 100644 +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -68,6 +68,8 @@ static const struct of_device_id machines[] __initconst = { + + { .compatible = "sigma,tango4" }, + ++ { .compatible = "ti,am33xx", }, ++ { .compatible = "ti,dra7", }, + { .compatible = "ti,omap2", }, + { .compatible = "ti,omap3", }, + { .compatible = "ti,omap4", }, +diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c +index 18da4f8..1347589 100644 +--- a/drivers/cpufreq/cpufreq_conservative.c ++++ b/drivers/cpufreq/cpufreq_conservative.c +@@ -17,6 +17,7 @@ + struct cs_policy_dbs_info { + struct policy_dbs_info policy_dbs; + unsigned int down_skip; ++ unsigned int requested_freq; + }; + + static inline struct cs_policy_dbs_info *to_dbs_info(struct policy_dbs_info *policy_dbs) +@@ -61,6 +62,7 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy) + { + struct policy_dbs_info *policy_dbs = policy->governor_data; + struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs); ++ unsigned int requested_freq = dbs_info->requested_freq; + struct dbs_data *dbs_data = policy_dbs->dbs_data; + struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; + unsigned int load = dbs_update(policy); +@@ -72,10 +74,16 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy) + if (cs_tuners->freq_step == 0) + goto out; + ++ /* ++ * If requested_freq is out of range, it is likely that the limits ++ * changed in the meantime, so fall back to current frequency in that ++ * case. ++ */ ++ if (requested_freq > policy->max || requested_freq < policy->min) ++ requested_freq = policy->cur; ++ + /* Check for frequency increase */ + if (load > dbs_data->up_threshold) { +- unsigned int requested_freq = policy->cur; +- + dbs_info->down_skip = 0; + + /* if we are already at full speed then break out early */ +@@ -83,8 +91,11 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy) + goto out; + + requested_freq += get_freq_target(cs_tuners, policy); ++ if (requested_freq > policy->max) ++ requested_freq = policy->max; + + __cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_H); ++ dbs_info->requested_freq = requested_freq; + goto out; + } + +@@ -95,7 +106,7 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy) + + /* Check for frequency decrease */ + if (load < cs_tuners->down_threshold) { +- unsigned int freq_target, requested_freq = policy->cur; ++ unsigned int freq_target; + /* + * if we cannot reduce the frequency anymore, break out early + */ +@@ -109,6 +120,7 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy) + requested_freq = policy->min; + + __cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_L); ++ dbs_info->requested_freq = requested_freq; + } + + out: +@@ -287,6 +299,7 @@ static void cs_start(struct cpufreq_policy *policy) + struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy->governor_data); + + dbs_info->down_skip = 0; ++ dbs_info->requested_freq = policy->cur; + } + + static struct dbs_governor cs_governor = { +diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c +index be9eade..b46547e 100644 +--- a/drivers/cpufreq/intel_pstate.c ++++ b/drivers/cpufreq/intel_pstate.c +@@ -556,12 +556,12 @@ static void intel_pstate_hwp_set(const struct cpumask *cpumask) + int min, hw_min, max, hw_max, cpu, range, adj_range; + u64 value, cap; + +- rdmsrl(MSR_HWP_CAPABILITIES, cap); +- hw_min = HWP_LOWEST_PERF(cap); +- hw_max = HWP_HIGHEST_PERF(cap); +- range = hw_max - hw_min; +- + for_each_cpu(cpu, cpumask) { ++ rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap); ++ hw_min = HWP_LOWEST_PERF(cap); ++ hw_max = HWP_HIGHEST_PERF(cap); ++ range = hw_max - hw_min; ++ + rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value); + adj_range = limits->min_perf_pct * range / 100; + min = hw_min + adj_range; +diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c +index 425501c..793518a 100644 +--- a/drivers/gpio/gpio-mpc8xxx.c ++++ b/drivers/gpio/gpio-mpc8xxx.c +@@ -239,7 +239,7 @@ static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int irq, + irq_hw_number_t hwirq) + { + irq_set_chip_data(irq, h->host_data); +- irq_set_chip_and_handler(irq, &mpc8xxx_irq_chip, handle_level_irq); ++ irq_set_chip_and_handler(irq, &mpc8xxx_irq_chip, handle_edge_irq); + + return 0; + } +diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c +index f2b776e..5f88ccd 100644 +--- a/drivers/infiniband/core/verbs.c ++++ b/drivers/infiniband/core/verbs.c +@@ -821,7 +821,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, + if (ret) { + pr_err("failed to init MR pool ret= %d\n", ret); + ib_destroy_qp(qp); +- qp = ERR_PTR(ret); ++ return ERR_PTR(ret); + } + } + +diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c +index 3322ed7..6b07d4b 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -1400,7 +1400,9 @@ static int srp_map_sg_entry(struct srp_map_state *state, + + while (dma_len) { + unsigned offset = dma_addr & ~dev->mr_page_mask; +- if (state->npages == dev->max_pages_per_mr || offset != 0) { ++ ++ if (state->npages == dev->max_pages_per_mr || ++ (state->npages > 0 && offset != 0)) { + ret = srp_map_finish_fmr(state, ch); + if (ret) + return ret; +@@ -1417,12 +1419,12 @@ static int srp_map_sg_entry(struct srp_map_state *state, + } + + /* +- * If the last entry of the MR wasn't a full page, then we need to ++ * If the end of the MR is not on a page boundary then we need to + * close it out and start a new one -- we can only merge at page + * boundaries. + */ + ret = 0; +- if (len != dev->mr_page_size) ++ if ((dma_addr & ~dev->mr_page_mask) != 0) + ret = srp_map_finish_fmr(state, ch); + return ret; + } +diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c +index 08e252a..ff8c107 100644 +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1159,6 +1159,13 @@ static const struct dmi_system_id elantech_dmi_has_middle_button[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"), + }, + }, ++ { ++ /* Fujitsu H760 also has a middle button */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H760"), ++ }, ++ }, + #endif + { } + }; +@@ -1503,10 +1510,10 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = { + }, + }, + { +- /* Fujitsu LIFEBOOK E554 does not work with crc_enabled == 0 */ ++ /* Fujitsu H760 does not work with crc_enabled == 0 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +- DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E554"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H760"), + }, + }, + { +@@ -1517,6 +1524,20 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = { + }, + }, + { ++ /* Fujitsu LIFEBOOK E554 does not work with crc_enabled == 0 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E554"), ++ }, ++ }, ++ { ++ /* Fujitsu LIFEBOOK E556 does not work with crc_enabled == 0 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E556"), ++ }, ++ }, ++ { + /* Fujitsu LIFEBOOK U745 does not work with crc_enabled == 0 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h +index a5eed2a..34da81c 100644 +--- a/drivers/input/serio/i8042-io.h ++++ b/drivers/input/serio/i8042-io.h +@@ -81,7 +81,7 @@ static inline int i8042_platform_init(void) + return -EBUSY; + #endif + +- i8042_reset = 1; ++ i8042_reset = I8042_RESET_ALWAYS; + return 0; + } + +diff --git a/drivers/input/serio/i8042-ip22io.h b/drivers/input/serio/i8042-ip22io.h +index ee1ad27..08a1c10 100644 +--- a/drivers/input/serio/i8042-ip22io.h ++++ b/drivers/input/serio/i8042-ip22io.h +@@ -61,7 +61,7 @@ static inline int i8042_platform_init(void) + return -EBUSY; + #endif + +- i8042_reset = 1; ++ i8042_reset = I8042_RESET_ALWAYS; + + return 0; + } +diff --git a/drivers/input/serio/i8042-ppcio.h b/drivers/input/serio/i8042-ppcio.h +index f708c75..1aabea4 100644 +--- a/drivers/input/serio/i8042-ppcio.h ++++ b/drivers/input/serio/i8042-ppcio.h +@@ -44,7 +44,7 @@ static inline void i8042_write_command(int val) + + static inline int i8042_platform_init(void) + { +- i8042_reset = 1; ++ i8042_reset = I8042_RESET_ALWAYS; + return 0; + } + +diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h +index afcd1c1..6231d63 100644 +--- a/drivers/input/serio/i8042-sparcio.h ++++ b/drivers/input/serio/i8042-sparcio.h +@@ -130,7 +130,7 @@ static int __init i8042_platform_init(void) + } + } + +- i8042_reset = 1; ++ i8042_reset = I8042_RESET_ALWAYS; + + return 0; + } +diff --git a/drivers/input/serio/i8042-unicore32io.h b/drivers/input/serio/i8042-unicore32io.h +index 73f5cc1..4557475 100644 +--- a/drivers/input/serio/i8042-unicore32io.h ++++ b/drivers/input/serio/i8042-unicore32io.h +@@ -61,7 +61,7 @@ static inline int i8042_platform_init(void) + if (!request_mem_region(I8042_REGION_START, I8042_REGION_SIZE, "i8042")) + return -EBUSY; + +- i8042_reset = 1; ++ i8042_reset = I8042_RESET_ALWAYS; + return 0; + } + +diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h +index 68f5f4a..f4bfb4b 100644 +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -510,6 +510,90 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { + { } + }; + ++/* ++ * On some Asus laptops, just running self tests cause problems. ++ */ ++static const struct dmi_system_id i8042_dmi_noselftest_table[] = { ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "A455LD"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "K401LB"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "K501LB"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "K501LX"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "R409L"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "V502LX"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X302LA"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X450LD"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X455LAB"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X455LDB"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X455LF"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Z450LA"), ++ }, ++ }, ++ { } ++}; + static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { + { + /* MSI Wind U-100 */ +@@ -1072,12 +1156,18 @@ static int __init i8042_platform_init(void) + return retval; + + #if defined(__ia64__) +- i8042_reset = true; ++ i8042_reset = I8042_RESET_ALWAYS; + #endif + + #ifdef CONFIG_X86 +- if (dmi_check_system(i8042_dmi_reset_table)) +- i8042_reset = true; ++ /* Honor module parameter when value is not default */ ++ if (i8042_reset == I8042_RESET_DEFAULT) { ++ if (dmi_check_system(i8042_dmi_reset_table)) ++ i8042_reset = I8042_RESET_ALWAYS; ++ ++ if (dmi_check_system(i8042_dmi_noselftest_table)) ++ i8042_reset = I8042_RESET_NEVER; ++ } + + if (dmi_check_system(i8042_dmi_noloop_table)) + i8042_noloop = true; +diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c +index 405252a..89abfdb 100644 +--- a/drivers/input/serio/i8042.c ++++ b/drivers/input/serio/i8042.c +@@ -48,9 +48,39 @@ static bool i8042_unlock; + module_param_named(unlock, i8042_unlock, bool, 0); + MODULE_PARM_DESC(unlock, "Ignore keyboard lock."); + +-static bool i8042_reset; +-module_param_named(reset, i8042_reset, bool, 0); +-MODULE_PARM_DESC(reset, "Reset controller during init and cleanup."); ++enum i8042_controller_reset_mode { ++ I8042_RESET_NEVER, ++ I8042_RESET_ALWAYS, ++ I8042_RESET_ON_S2RAM, ++#define I8042_RESET_DEFAULT I8042_RESET_ON_S2RAM ++}; ++static enum i8042_controller_reset_mode i8042_reset = I8042_RESET_DEFAULT; ++static int i8042_set_reset(const char *val, const struct kernel_param *kp) ++{ ++ enum i8042_controller_reset_mode *arg = kp->arg; ++ int error; ++ bool reset; ++ ++ if (val) { ++ error = kstrtobool(val, &reset); ++ if (error) ++ return error; ++ } else { ++ reset = true; ++ } ++ ++ *arg = reset ? I8042_RESET_ALWAYS : I8042_RESET_NEVER; ++ return 0; ++} ++ ++static const struct kernel_param_ops param_ops_reset_param = { ++ .flags = KERNEL_PARAM_OPS_FL_NOARG, ++ .set = i8042_set_reset, ++}; ++#define param_check_reset_param(name, p) \ ++ __param_check(name, p, enum i8042_controller_reset_mode) ++module_param_named(reset, i8042_reset, reset_param, 0); ++MODULE_PARM_DESC(reset, "Reset controller on resume, cleanup or both"); + + static bool i8042_direct; + module_param_named(direct, i8042_direct, bool, 0); +@@ -1019,7 +1049,7 @@ static int i8042_controller_init(void) + * Reset the controller and reset CRT to the original value set by BIOS. + */ + +-static void i8042_controller_reset(bool force_reset) ++static void i8042_controller_reset(bool s2r_wants_reset) + { + i8042_flush(); + +@@ -1044,8 +1074,10 @@ static void i8042_controller_reset(bool force_reset) + * Reset the controller if requested. + */ + +- if (i8042_reset || force_reset) ++ if (i8042_reset == I8042_RESET_ALWAYS || ++ (i8042_reset == I8042_RESET_ON_S2RAM && s2r_wants_reset)) { + i8042_controller_selftest(); ++ } + + /* + * Restore the original control register setting. +@@ -1110,7 +1142,7 @@ static void i8042_dritek_enable(void) + * before suspending. + */ + +-static int i8042_controller_resume(bool force_reset) ++static int i8042_controller_resume(bool s2r_wants_reset) + { + int error; + +@@ -1118,7 +1150,8 @@ static int i8042_controller_resume(bool force_reset) + if (error) + return error; + +- if (i8042_reset || force_reset) { ++ if (i8042_reset == I8042_RESET_ALWAYS || ++ (i8042_reset == I8042_RESET_ON_S2RAM && s2r_wants_reset)) { + error = i8042_controller_selftest(); + if (error) + return error; +@@ -1195,7 +1228,7 @@ static int i8042_pm_resume_noirq(struct device *dev) + + static int i8042_pm_resume(struct device *dev) + { +- bool force_reset; ++ bool want_reset; + int i; + + for (i = 0; i < I8042_NUM_PORTS; i++) { +@@ -1218,9 +1251,9 @@ static int i8042_pm_resume(struct device *dev) + * off control to the platform firmware, otherwise we can simply restore + * the mode. + */ +- force_reset = pm_resume_via_firmware(); ++ want_reset = pm_resume_via_firmware(); + +- return i8042_controller_resume(force_reset); ++ return i8042_controller_resume(want_reset); + } + + static int i8042_pm_thaw(struct device *dev) +@@ -1482,7 +1515,7 @@ static int __init i8042_probe(struct platform_device *dev) + + i8042_platform_device = dev; + +- if (i8042_reset) { ++ if (i8042_reset == I8042_RESET_ALWAYS) { + error = i8042_controller_selftest(); + if (error) + return error; +diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c +index efbf0e4..ebc2b0b 100644 +--- a/drivers/irqchip/irq-eznps.c ++++ b/drivers/irqchip/irq-eznps.c +@@ -85,7 +85,7 @@ static void nps400_irq_eoi_global(struct irq_data *irqd) + nps_ack_gic(); + } + +-static void nps400_irq_eoi(struct irq_data *irqd) ++static void nps400_irq_ack(struct irq_data *irqd) + { + unsigned int __maybe_unused irq = irqd_to_hwirq(irqd); + +@@ -103,7 +103,7 @@ static struct irq_chip nps400_irq_chip_percpu = { + .name = "NPS400 IC", + .irq_mask = nps400_irq_mask, + .irq_unmask = nps400_irq_unmask, +- .irq_eoi = nps400_irq_eoi, ++ .irq_ack = nps400_irq_ack, + }; + + static int nps400_irq_map(struct irq_domain *d, unsigned int virq, +diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c +index da6c0ba..708a260 100644 +--- a/drivers/irqchip/irq-gic-v3.c ++++ b/drivers/irqchip/irq-gic-v3.c +@@ -153,7 +153,7 @@ static void gic_enable_redist(bool enable) + return; /* No PM support in this redistributor */ + } + +- while (count--) { ++ while (--count) { + val = readl_relaxed(rbase + GICR_WAKER); + if (enable ^ (bool)(val & GICR_WAKER_ChildrenAsleep)) + break; +diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c +index 8742957..6fc8923 100644 +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -113,8 +113,7 @@ struct iv_tcw_private { + * and encrypts / decrypts at the same time. + */ + enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID, +- DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD, +- DM_CRYPT_EXIT_THREAD}; ++ DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD }; + + /* + * The fields in here must be read only after initialization. +@@ -1207,18 +1206,20 @@ static int dmcrypt_write(void *data) + if (!RB_EMPTY_ROOT(&cc->write_tree)) + goto pop_from_list; + +- if (unlikely(test_bit(DM_CRYPT_EXIT_THREAD, &cc->flags))) { +- spin_unlock_irq(&cc->write_thread_wait.lock); +- break; +- } +- +- __set_current_state(TASK_INTERRUPTIBLE); ++ set_current_state(TASK_INTERRUPTIBLE); + __add_wait_queue(&cc->write_thread_wait, &wait); + + spin_unlock_irq(&cc->write_thread_wait.lock); + ++ if (unlikely(kthread_should_stop())) { ++ set_task_state(current, TASK_RUNNING); ++ remove_wait_queue(&cc->write_thread_wait, &wait); ++ break; ++ } ++ + schedule(); + ++ set_task_state(current, TASK_RUNNING); + spin_lock_irq(&cc->write_thread_wait.lock); + __remove_wait_queue(&cc->write_thread_wait, &wait); + goto continue_locked; +@@ -1533,13 +1534,8 @@ static void crypt_dtr(struct dm_target *ti) + if (!cc) + return; + +- if (cc->write_thread) { +- spin_lock_irq(&cc->write_thread_wait.lock); +- set_bit(DM_CRYPT_EXIT_THREAD, &cc->flags); +- wake_up_locked(&cc->write_thread_wait); +- spin_unlock_irq(&cc->write_thread_wait.lock); ++ if (cc->write_thread) + kthread_stop(cc->write_thread); +- } + + if (cc->io_queue) + destroy_workqueue(cc->io_queue); +diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c +index ac734e5..15db5e9 100644 +--- a/drivers/md/dm-mpath.c ++++ b/drivers/md/dm-mpath.c +@@ -1521,10 +1521,10 @@ static void activate_path(struct work_struct *work) + { + struct pgpath *pgpath = + container_of(work, struct pgpath, activate_path.work); ++ struct request_queue *q = bdev_get_queue(pgpath->path.dev->bdev); + +- if (pgpath->is_active) +- scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev), +- pg_init_done, pgpath); ++ if (pgpath->is_active && !blk_queue_dying(q)) ++ scsi_dh_activate(q, pg_init_done, pgpath); + else + pg_init_done(pgpath, SCSI_DH_DEV_OFFLINED); + } +diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c +index 1ca7463..5da86c8 100644 +--- a/drivers/md/dm-rq.c ++++ b/drivers/md/dm-rq.c +@@ -73,15 +73,24 @@ static void dm_old_start_queue(struct request_queue *q) + spin_unlock_irqrestore(q->queue_lock, flags); + } + ++static void dm_mq_start_queue(struct request_queue *q) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(q->queue_lock, flags); ++ queue_flag_clear(QUEUE_FLAG_STOPPED, q); ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ ++ blk_mq_start_stopped_hw_queues(q, true); ++ blk_mq_kick_requeue_list(q); ++} ++ + void dm_start_queue(struct request_queue *q) + { + if (!q->mq_ops) + dm_old_start_queue(q); +- else { +- queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, q); +- blk_mq_start_stopped_hw_queues(q, true); +- blk_mq_kick_requeue_list(q); +- } ++ else ++ dm_mq_start_queue(q); + } + + static void dm_old_stop_queue(struct request_queue *q) +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index fa9b1cb..0f2928b 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -1873,6 +1873,7 @@ EXPORT_SYMBOL_GPL(dm_device_name); + + static void __dm_destroy(struct mapped_device *md, bool wait) + { ++ struct request_queue *q = dm_get_md_queue(md); + struct dm_table *map; + int srcu_idx; + +@@ -1883,6 +1884,10 @@ static void __dm_destroy(struct mapped_device *md, bool wait) + set_bit(DMF_FREEING, &md->flags); + spin_unlock(&_minor_lock); + ++ spin_lock_irq(q->queue_lock); ++ queue_flag_set(QUEUE_FLAG_DYING, q); ++ spin_unlock_irq(q->queue_lock); ++ + if (dm_request_based(md) && md->kworker_task) + flush_kthread_worker(&md->kworker); + +@@ -2249,10 +2254,11 @@ static int __dm_resume(struct mapped_device *md, struct dm_table *map) + + int dm_resume(struct mapped_device *md) + { +- int r = -EINVAL; ++ int r; + struct dm_table *map = NULL; + + retry: ++ r = -EINVAL; + mutex_lock_nested(&md->suspend_lock, SINGLE_DEPTH_NESTING); + + if (!dm_suspended_md(md)) +@@ -2276,8 +2282,6 @@ int dm_resume(struct mapped_device *md) + goto out; + + clear_bit(DMF_SUSPENDED, &md->flags); +- +- r = 0; + out: + mutex_unlock(&md->suspend_lock); + +diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c +index 4132532..fe79358 100644 +--- a/drivers/media/dvb-frontends/mb86a20s.c ++++ b/drivers/media/dvb-frontends/mb86a20s.c +@@ -71,25 +71,27 @@ static struct regdata mb86a20s_init1[] = { + }; + + static struct regdata mb86a20s_init2[] = { +- { 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 }, ++ { 0x50, 0xd1 }, { 0x51, 0x22 }, ++ { 0x39, 0x01 }, ++ { 0x71, 0x00 }, + { 0x3b, 0x21 }, +- { 0x3c, 0x38 }, ++ { 0x3c, 0x3a }, + { 0x01, 0x0d }, +- { 0x04, 0x08 }, { 0x05, 0x03 }, ++ { 0x04, 0x08 }, { 0x05, 0x05 }, + { 0x04, 0x0e }, { 0x05, 0x00 }, +- { 0x04, 0x0f }, { 0x05, 0x37 }, +- { 0x04, 0x0b }, { 0x05, 0x78 }, ++ { 0x04, 0x0f }, { 0x05, 0x14 }, ++ { 0x04, 0x0b }, { 0x05, 0x8c }, + { 0x04, 0x00 }, { 0x05, 0x00 }, +- { 0x04, 0x01 }, { 0x05, 0x1e }, +- { 0x04, 0x02 }, { 0x05, 0x07 }, +- { 0x04, 0x03 }, { 0x05, 0xd0 }, ++ { 0x04, 0x01 }, { 0x05, 0x07 }, ++ { 0x04, 0x02 }, { 0x05, 0x0f }, ++ { 0x04, 0x03 }, { 0x05, 0xa0 }, + { 0x04, 0x09 }, { 0x05, 0x00 }, + { 0x04, 0x0a }, { 0x05, 0xff }, +- { 0x04, 0x27 }, { 0x05, 0x00 }, ++ { 0x04, 0x27 }, { 0x05, 0x64 }, + { 0x04, 0x28 }, { 0x05, 0x00 }, +- { 0x04, 0x1e }, { 0x05, 0x00 }, +- { 0x04, 0x29 }, { 0x05, 0x64 }, +- { 0x04, 0x32 }, { 0x05, 0x02 }, ++ { 0x04, 0x1e }, { 0x05, 0xff }, ++ { 0x04, 0x29 }, { 0x05, 0x0a }, ++ { 0x04, 0x32 }, { 0x05, 0x0a }, + { 0x04, 0x14 }, { 0x05, 0x02 }, + { 0x04, 0x04 }, { 0x05, 0x00 }, + { 0x04, 0x05 }, { 0x05, 0x22 }, +@@ -97,8 +99,6 @@ static struct regdata mb86a20s_init2[] = { + { 0x04, 0x07 }, { 0x05, 0xd8 }, + { 0x04, 0x12 }, { 0x05, 0x00 }, + { 0x04, 0x13 }, { 0x05, 0xff }, +- { 0x04, 0x15 }, { 0x05, 0x4e }, +- { 0x04, 0x16 }, { 0x05, 0x20 }, + + /* + * On this demod, when the bit count reaches the count below, +@@ -152,42 +152,36 @@ static struct regdata mb86a20s_init2[] = { + { 0x50, 0x51 }, { 0x51, 0x04 }, /* MER symbol 4 */ + { 0x45, 0x04 }, /* CN symbol 4 */ + { 0x48, 0x04 }, /* CN manual mode */ +- ++ { 0x50, 0xd5 }, { 0x51, 0x01 }, + { 0x50, 0xd6 }, { 0x51, 0x1f }, + { 0x50, 0xd2 }, { 0x51, 0x03 }, +- { 0x50, 0xd7 }, { 0x51, 0xbf }, +- { 0x28, 0x74 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xff }, +- { 0x28, 0x46 }, { 0x29, 0x00 }, { 0x2a, 0x1a }, { 0x2b, 0x0c }, +- +- { 0x04, 0x40 }, { 0x05, 0x00 }, +- { 0x28, 0x00 }, { 0x2b, 0x08 }, +- { 0x28, 0x05 }, { 0x2b, 0x00 }, ++ { 0x50, 0xd7 }, { 0x51, 0x3f }, + { 0x1c, 0x01 }, +- { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x1f }, +- { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x18 }, +- { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x12 }, +- { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x30 }, +- { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x37 }, +- { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 }, +- { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x09 }, +- { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x06 }, +- { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7b }, +- { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x76 }, +- { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7d }, +- { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x08 }, +- { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0b }, +- { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 }, +- { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf2 }, +- { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf3 }, +- { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x05 }, +- { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 }, +- { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f }, +- { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xef }, +- { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xd8 }, +- { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xf1 }, +- { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x3d }, +- { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x94 }, +- { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xba }, ++ { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x03 }, ++ { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0d }, ++ { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 }, ++ { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x01 }, ++ { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x21 }, ++ { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x29 }, ++ { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 }, ++ { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x31 }, ++ { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0e }, ++ { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x4e }, ++ { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x46 }, ++ { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f }, ++ { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x56 }, ++ { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x35 }, ++ { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbe }, ++ { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0x84 }, ++ { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x03 }, { 0x2b, 0xee }, ++ { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x98 }, ++ { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x9f }, ++ { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xb2 }, ++ { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0xc2 }, ++ { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0x4a }, ++ { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbc }, ++ { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x04 }, { 0x2b, 0xba }, ++ { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0x14 }, + { 0x50, 0x1e }, { 0x51, 0x5d }, + { 0x50, 0x22 }, { 0x51, 0x00 }, + { 0x50, 0x23 }, { 0x51, 0xc8 }, +@@ -196,9 +190,7 @@ static struct regdata mb86a20s_init2[] = { + { 0x50, 0x26 }, { 0x51, 0x00 }, + { 0x50, 0x27 }, { 0x51, 0xc3 }, + { 0x50, 0x39 }, { 0x51, 0x02 }, +- { 0xec, 0x0f }, +- { 0xeb, 0x1f }, +- { 0x28, 0x6a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 }, ++ { 0x50, 0xd5 }, { 0x51, 0x01 }, + { 0xd0, 0x00 }, + }; + +@@ -318,7 +310,11 @@ static int mb86a20s_read_status(struct dvb_frontend *fe, enum fe_status *status) + if (val >= 7) + *status |= FE_HAS_SYNC; + +- if (val >= 8) /* Maybe 9? */ ++ /* ++ * Actually, on state S8, it starts receiving TS, but the TS ++ * output is only on normal state after the transition to S9. ++ */ ++ if (val >= 9) + *status |= FE_HAS_LOCK; + + dev_dbg(&state->i2c->dev, "%s: Status = 0x%02x (state = %d)\n", +@@ -2058,6 +2054,11 @@ static void mb86a20s_release(struct dvb_frontend *fe) + kfree(state); + } + ++static int mb86a20s_get_frontend_algo(struct dvb_frontend *fe) ++{ ++ return DVBFE_ALGO_HW; ++} ++ + static struct dvb_frontend_ops mb86a20s_ops; + + struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config, +@@ -2130,6 +2131,7 @@ static struct dvb_frontend_ops mb86a20s_ops = { + .read_status = mb86a20s_read_status_and_stats, + .read_signal_strength = mb86a20s_read_signal_strength_from_cache, + .tune = mb86a20s_tune, ++ .get_frontend_algo = mb86a20s_get_frontend_algo, + }; + + MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware"); +diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c +index 4919137..2f52d66 100644 +--- a/drivers/media/usb/cx231xx/cx231xx-avcore.c ++++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c +@@ -1264,7 +1264,10 @@ int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev, + dev->board.agc_analog_digital_select_gpio, + analog_or_digital); + +- return status; ++ if (status < 0) ++ return status; ++ ++ return 0; + } + + int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3) +diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c +index c63248a..72c246b 100644 +--- a/drivers/media/usb/cx231xx/cx231xx-cards.c ++++ b/drivers/media/usb/cx231xx/cx231xx-cards.c +@@ -486,7 +486,7 @@ struct cx231xx_board cx231xx_boards[] = { + .output_mode = OUT_MODE_VIP11, + .demod_xfer_mode = 0, + .ctl_pin_status_mask = 0xFFFFFFC4, +- .agc_analog_digital_select_gpio = 0x00, /* According with PV cxPolaris.inf file */ ++ .agc_analog_digital_select_gpio = 0x1c, + .tuner_sif_gpio = -1, + .tuner_scl_gpio = -1, + .tuner_sda_gpio = -1, +diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c +index 630f4fc..ea9a99e 100644 +--- a/drivers/media/usb/cx231xx/cx231xx-core.c ++++ b/drivers/media/usb/cx231xx/cx231xx-core.c +@@ -712,6 +712,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode) + break; + case CX231XX_BOARD_CNXT_RDE_253S: + case CX231XX_BOARD_CNXT_RDU_253S: ++ case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: + errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1); + break; + case CX231XX_BOARD_HAUPPAUGE_EXETER: +@@ -738,7 +739,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode) + case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: + case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL: + case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC: +- errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0); ++ errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0); + break; + default: + break; +@@ -1301,15 +1302,29 @@ int cx231xx_dev_init(struct cx231xx *dev) + dev->i2c_bus[2].i2c_reserve = 0; + + /* register I2C buses */ +- cx231xx_i2c_register(&dev->i2c_bus[0]); +- cx231xx_i2c_register(&dev->i2c_bus[1]); +- cx231xx_i2c_register(&dev->i2c_bus[2]); ++ errCode = cx231xx_i2c_register(&dev->i2c_bus[0]); ++ if (errCode < 0) ++ return errCode; ++ errCode = cx231xx_i2c_register(&dev->i2c_bus[1]); ++ if (errCode < 0) ++ return errCode; ++ errCode = cx231xx_i2c_register(&dev->i2c_bus[2]); ++ if (errCode < 0) ++ return errCode; + + errCode = cx231xx_i2c_mux_create(dev); ++ if (errCode < 0) { ++ dev_err(dev->dev, ++ "%s: Failed to create I2C mux\n", __func__); ++ return errCode; ++ } ++ errCode = cx231xx_i2c_mux_register(dev, 0); ++ if (errCode < 0) ++ return errCode; ++ ++ errCode = cx231xx_i2c_mux_register(dev, 1); + if (errCode < 0) + return errCode; +- cx231xx_i2c_mux_register(dev, 0); +- cx231xx_i2c_mux_register(dev, 1); + + /* scan the real bus segments in the order of physical port numbers */ + cx231xx_do_i2c_scan(dev, I2C_0); +diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c +index d34bc35..2e3cf01 100644 +--- a/drivers/memstick/host/rtsx_usb_ms.c ++++ b/drivers/memstick/host/rtsx_usb_ms.c +@@ -524,6 +524,7 @@ static void rtsx_usb_ms_handle_req(struct work_struct *work) + int rc; + + if (!host->req) { ++ pm_runtime_get_sync(ms_dev(host)); + do { + rc = memstick_next_req(msh, &host->req); + dev_dbg(ms_dev(host), "next req %d\n", rc); +@@ -544,6 +545,7 @@ static void rtsx_usb_ms_handle_req(struct work_struct *work) + host->req->error); + } + } while (!rc); ++ pm_runtime_put(ms_dev(host)); + } + + } +@@ -570,6 +572,7 @@ static int rtsx_usb_ms_set_param(struct memstick_host *msh, + dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n", + __func__, param, value); + ++ pm_runtime_get_sync(ms_dev(host)); + mutex_lock(&ucr->dev_mutex); + + err = rtsx_usb_card_exclusive_check(ucr, RTSX_USB_MS_CARD); +@@ -635,6 +638,7 @@ static int rtsx_usb_ms_set_param(struct memstick_host *msh, + } + out: + mutex_unlock(&ucr->dev_mutex); ++ pm_runtime_put(ms_dev(host)); + + /* power-on delay */ + if (param == MEMSTICK_POWER && value == MEMSTICK_POWER_ON) +@@ -681,6 +685,7 @@ static int rtsx_usb_detect_ms_card(void *__host) + int err; + + for (;;) { ++ pm_runtime_get_sync(ms_dev(host)); + mutex_lock(&ucr->dev_mutex); + + /* Check pending MS card changes */ +@@ -703,6 +708,7 @@ static int rtsx_usb_detect_ms_card(void *__host) + } + + poll_again: ++ pm_runtime_put(ms_dev(host)); + if (host->eject) + break; + +diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c +index f3d34b9..af23d7d 100644 +--- a/drivers/misc/cxl/api.c ++++ b/drivers/misc/cxl/api.c +@@ -229,6 +229,14 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed, + if (ctx->status == STARTED) + goto out; /* already started */ + ++ /* ++ * Increment the mapped context count for adapter. This also checks ++ * if adapter_context_lock is taken. ++ */ ++ rc = cxl_adapter_context_get(ctx->afu->adapter); ++ if (rc) ++ goto out; ++ + if (task) { + ctx->pid = get_task_pid(task, PIDTYPE_PID); + ctx->glpid = get_task_pid(task->group_leader, PIDTYPE_PID); +@@ -240,6 +248,7 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed, + + if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) { + put_pid(ctx->pid); ++ cxl_adapter_context_put(ctx->afu->adapter); + cxl_ctx_put(); + goto out; + } +diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c +index c466ee2..5e506c1 100644 +--- a/drivers/misc/cxl/context.c ++++ b/drivers/misc/cxl/context.c +@@ -238,6 +238,9 @@ int __detach_context(struct cxl_context *ctx) + put_pid(ctx->glpid); + + cxl_ctx_put(); ++ ++ /* Decrease the attached context count on the adapter */ ++ cxl_adapter_context_put(ctx->afu->adapter); + return 0; + } + +diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h +index 344a0ff..19aa2ac 100644 +--- a/drivers/misc/cxl/cxl.h ++++ b/drivers/misc/cxl/cxl.h +@@ -615,6 +615,14 @@ struct cxl { + bool perst_select_user; + bool perst_same_image; + bool psl_timebase_synced; ++ ++ /* ++ * number of contexts mapped on to this card. Possible values are: ++ * >0: Number of contexts mapped and new one can be mapped. ++ * 0: No active contexts and new ones can be mapped. ++ * -1: No contexts mapped and new ones cannot be mapped. ++ */ ++ atomic_t contexts_num; + }; + + int cxl_pci_alloc_one_irq(struct cxl *adapter); +@@ -940,4 +948,20 @@ bool cxl_pci_is_vphb_device(struct pci_dev *dev); + + /* decode AFU error bits in the PSL register PSL_SERR_An */ + void cxl_afu_decode_psl_serr(struct cxl_afu *afu, u64 serr); ++ ++/* ++ * Increments the number of attached contexts on an adapter. ++ * In case an adapter_context_lock is taken the return -EBUSY. ++ */ ++int cxl_adapter_context_get(struct cxl *adapter); ++ ++/* Decrements the number of attached contexts on an adapter */ ++void cxl_adapter_context_put(struct cxl *adapter); ++ ++/* If no active contexts then prevents contexts from being attached */ ++int cxl_adapter_context_lock(struct cxl *adapter); ++ ++/* Unlock the contexts-lock if taken. Warn and force unlock otherwise */ ++void cxl_adapter_context_unlock(struct cxl *adapter); ++ + #endif +diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c +index 5fb9894..d0b421f 100644 +--- a/drivers/misc/cxl/file.c ++++ b/drivers/misc/cxl/file.c +@@ -205,11 +205,22 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, + ctx->pid = get_task_pid(current, PIDTYPE_PID); + ctx->glpid = get_task_pid(current->group_leader, PIDTYPE_PID); + ++ /* ++ * Increment the mapped context count for adapter. This also checks ++ * if adapter_context_lock is taken. ++ */ ++ rc = cxl_adapter_context_get(ctx->afu->adapter); ++ if (rc) { ++ afu_release_irqs(ctx, ctx); ++ goto out; ++ } ++ + trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr); + + if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor, + amr))) { + afu_release_irqs(ctx, ctx); ++ cxl_adapter_context_put(ctx->afu->adapter); + goto out; + } + +diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c +index 9aa58a7..3e102cd 100644 +--- a/drivers/misc/cxl/guest.c ++++ b/drivers/misc/cxl/guest.c +@@ -1152,6 +1152,9 @@ struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_devic + if ((rc = cxl_sysfs_adapter_add(adapter))) + goto err_put1; + ++ /* release the context lock as the adapter is configured */ ++ cxl_adapter_context_unlock(adapter); ++ + return adapter; + + err_put1: +diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c +index d9be23b2..62e0dfb 100644 +--- a/drivers/misc/cxl/main.c ++++ b/drivers/misc/cxl/main.c +@@ -243,8 +243,10 @@ struct cxl *cxl_alloc_adapter(void) + if (dev_set_name(&adapter->dev, "card%i", adapter->adapter_num)) + goto err2; + +- return adapter; ++ /* start with context lock taken */ ++ atomic_set(&adapter->contexts_num, -1); + ++ return adapter; + err2: + cxl_remove_adapter_nr(adapter); + err1: +@@ -286,6 +288,44 @@ int cxl_afu_select_best_mode(struct cxl_afu *afu) + return 0; + } + ++int cxl_adapter_context_get(struct cxl *adapter) ++{ ++ int rc; ++ ++ rc = atomic_inc_unless_negative(&adapter->contexts_num); ++ return rc >= 0 ? 0 : -EBUSY; ++} ++ ++void cxl_adapter_context_put(struct cxl *adapter) ++{ ++ atomic_dec_if_positive(&adapter->contexts_num); ++} ++ ++int cxl_adapter_context_lock(struct cxl *adapter) ++{ ++ int rc; ++ /* no active contexts -> contexts_num == 0 */ ++ rc = atomic_cmpxchg(&adapter->contexts_num, 0, -1); ++ return rc ? -EBUSY : 0; ++} ++ ++void cxl_adapter_context_unlock(struct cxl *adapter) ++{ ++ int val = atomic_cmpxchg(&adapter->contexts_num, -1, 0); ++ ++ /* ++ * contexts lock taken -> contexts_num == -1 ++ * If not true then show a warning and force reset the lock. ++ * This will happen when context_unlock was requested without ++ * doing a context_lock. ++ */ ++ if (val != -1) { ++ atomic_set(&adapter->contexts_num, 0); ++ WARN(1, "Adapter context unlocked with %d active contexts", ++ val); ++ } ++} ++ + static int __init init_cxl(void) + { + int rc = 0; +diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c +index 6f0c4ac..8ad4e4f 100644 +--- a/drivers/misc/cxl/pci.c ++++ b/drivers/misc/cxl/pci.c +@@ -1484,6 +1484,8 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev) + if ((rc = cxl_native_register_psl_err_irq(adapter))) + goto err; + ++ /* Release the context lock as adapter is configured */ ++ cxl_adapter_context_unlock(adapter); + return 0; + + err: +diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c +index b043c20..a8b6d6a 100644 +--- a/drivers/misc/cxl/sysfs.c ++++ b/drivers/misc/cxl/sysfs.c +@@ -75,12 +75,31 @@ static ssize_t reset_adapter_store(struct device *device, + int val; + + rc = sscanf(buf, "%i", &val); +- if ((rc != 1) || (val != 1)) ++ if ((rc != 1) || (val != 1 && val != -1)) + return -EINVAL; + +- if ((rc = cxl_ops->adapter_reset(adapter))) +- return rc; +- return count; ++ /* ++ * See if we can lock the context mapping that's only allowed ++ * when there are no contexts attached to the adapter. Once ++ * taken this will also prevent any context from getting activated. ++ */ ++ if (val == 1) { ++ rc = cxl_adapter_context_lock(adapter); ++ if (rc) ++ goto out; ++ ++ rc = cxl_ops->adapter_reset(adapter); ++ /* In case reset failed release context lock */ ++ if (rc) ++ cxl_adapter_context_unlock(adapter); ++ ++ } else if (val == -1) { ++ /* Perform a forced adapter reset */ ++ rc = cxl_ops->adapter_reset(adapter); ++ } ++ ++out: ++ return rc ? rc : count; + } + + static ssize_t load_image_on_perst_show(struct device *device, +diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c +index fd9271b..cd01e34 100644 +--- a/drivers/misc/mei/amthif.c ++++ b/drivers/misc/mei/amthif.c +@@ -139,7 +139,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, + return -ERESTARTSYS; + + if (!mei_cl_is_connected(cl)) { +- rets = -EBUSY; ++ rets = -ENODEV; + goto out; + } + +diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c +index e094df3..5b5b2e0 100644 +--- a/drivers/misc/mei/bus.c ++++ b/drivers/misc/mei/bus.c +@@ -142,7 +142,7 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) + mutex_lock(&bus->device_lock); + + if (!mei_cl_is_connected(cl)) { +- rets = -EBUSY; ++ rets = -ENODEV; + goto out; + } + } +diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h +index 0dcb854..7ad15d6 100644 +--- a/drivers/misc/mei/hw-me-regs.h ++++ b/drivers/misc/mei/hw-me-regs.h +@@ -125,6 +125,9 @@ + #define MEI_DEV_ID_BXT_M 0x1A9A /* Broxton M */ + #define MEI_DEV_ID_APL_I 0x5A9A /* Apollo Lake I */ + ++#define MEI_DEV_ID_KBP 0xA2BA /* Kaby Point */ ++#define MEI_DEV_ID_KBP_2 0xA2BB /* Kaby Point 2 */ ++ + /* + * MEI HW Section + */ +diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c +index 52635b0..080208d 100644 +--- a/drivers/misc/mei/main.c ++++ b/drivers/misc/mei/main.c +@@ -202,7 +202,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, + + mutex_lock(&dev->device_lock); + if (!mei_cl_is_connected(cl)) { +- rets = -EBUSY; ++ rets = -ENODEV; + goto out; + } + } +diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c +index 71cea9b..5eb9b75 100644 +--- a/drivers/misc/mei/pci-me.c ++++ b/drivers/misc/mei/pci-me.c +@@ -91,6 +91,9 @@ static const struct pci_device_id mei_me_pci_tbl[] = { + {MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, mei_me_pch8_cfg)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, mei_me_pch8_cfg)}, + ++ {MEI_PCI_DEVICE(MEI_DEV_ID_KBP, mei_me_pch8_cfg)}, ++ {MEI_PCI_DEVICE(MEI_DEV_ID_KBP_2, mei_me_pch8_cfg)}, ++ + /* required last entry */ + {0, } + }; +diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c +index 2206d44..17891f1 100644 +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -1778,7 +1778,7 @@ static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq, + struct mmc_blk_data *md = mq->data; + struct mmc_packed *packed = mqrq->packed; + bool do_rel_wr, do_data_tag; +- u32 *packed_cmd_hdr; ++ __le32 *packed_cmd_hdr; + u8 hdr_blocks; + u8 i = 1; + +@@ -2303,7 +2303,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, + set_capacity(md->disk, size); + + if (mmc_host_cmd23(card->host)) { +- if (mmc_card_mmc(card) || ++ if ((mmc_card_mmc(card) && ++ card->csd.mmca_vsn >= CSD_SPEC_VER_3) || + (mmc_card_sd(card) && + card->scr.cmds & SD_SCR_CMD23_SUPPORT)) + md->flags |= MMC_BLK_CMD23; +diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h +index fee5e12..7f16709 100644 +--- a/drivers/mmc/card/queue.h ++++ b/drivers/mmc/card/queue.h +@@ -31,7 +31,7 @@ enum mmc_packed_type { + + struct mmc_packed { + struct list_head list; +- u32 cmd_hdr[1024]; ++ __le32 cmd_hdr[1024]; + unsigned int blocks; + u8 nr_entries; + u8 retries; +diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c +index f2d185c..c57eb32 100644 +--- a/drivers/mmc/core/mmc.c ++++ b/drivers/mmc/core/mmc.c +@@ -1259,6 +1259,16 @@ static int mmc_select_hs400es(struct mmc_card *card) + goto out_err; + } + ++ if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_2V) ++ err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); ++ ++ if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_8V) ++ err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); ++ ++ /* If fails try again during next card power cycle */ ++ if (err) ++ goto out_err; ++ + err = mmc_select_bus_width(card); + if (err < 0) + goto out_err; +diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c +index 6c71fc9..da9f71b 100644 +--- a/drivers/mmc/host/rtsx_usb_sdmmc.c ++++ b/drivers/mmc/host/rtsx_usb_sdmmc.c +@@ -1138,11 +1138,6 @@ static void sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + dev_dbg(sdmmc_dev(host), "%s\n", __func__); + mutex_lock(&ucr->dev_mutex); + +- if (rtsx_usb_card_exclusive_check(ucr, RTSX_USB_SD_CARD)) { +- mutex_unlock(&ucr->dev_mutex); +- return; +- } +- + sd_set_power_mode(host, ios->power_mode); + sd_set_bus_width(host, ios->bus_width); + sd_set_timing(host, ios->timing, &host->ddr_mode); +@@ -1314,6 +1309,7 @@ static void rtsx_usb_update_led(struct work_struct *work) + container_of(work, struct rtsx_usb_sdmmc, led_work); + struct rtsx_ucr *ucr = host->ucr; + ++ pm_runtime_get_sync(sdmmc_dev(host)); + mutex_lock(&ucr->dev_mutex); + + if (host->led.brightness == LED_OFF) +@@ -1322,6 +1318,7 @@ static void rtsx_usb_update_led(struct work_struct *work) + rtsx_usb_turn_on_led(ucr); + + mutex_unlock(&ucr->dev_mutex); ++ pm_runtime_put(sdmmc_dev(host)); + } + #endif + +diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c +index cd65d47..a8a022a 100644 +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -687,7 +687,7 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) + * host->clock is in Hz. target_timeout is in us. + * Hence, us = 1000000 * cycles / Hz. Round up. + */ +- val = 1000000 * data->timeout_clks; ++ val = 1000000ULL * data->timeout_clks; + if (do_div(val, host->clock)) + target_timeout++; + target_timeout += val; +diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c +index f453326..b419c7c 100644 +--- a/drivers/mtd/ubi/wl.c ++++ b/drivers/mtd/ubi/wl.c +@@ -644,7 +644,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, + int shutdown) + { + int err, scrubbing = 0, torture = 0, protect = 0, erroneous = 0; +- int vol_id = -1, lnum = -1; ++ int erase = 0, keep = 0, vol_id = -1, lnum = -1; + #ifdef CONFIG_MTD_UBI_FASTMAP + int anchor = wrk->anchor; + #endif +@@ -780,6 +780,16 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, + e1->pnum); + scrubbing = 1; + goto out_not_moved; ++ } else if (ubi->fast_attach && err == UBI_IO_BAD_HDR_EBADMSG) { ++ /* ++ * While a full scan would detect interrupted erasures ++ * at attach time we can face them here when attached from ++ * Fastmap. ++ */ ++ dbg_wl("PEB %d has ECC errors, maybe from an interrupted erasure", ++ e1->pnum); ++ erase = 1; ++ goto out_not_moved; + } + + ubi_err(ubi, "error %d while reading VID header from PEB %d", +@@ -815,6 +825,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, + * Target PEB had bit-flips or write error - torture it. + */ + torture = 1; ++ keep = 1; + goto out_not_moved; + } + +@@ -901,7 +912,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, + ubi->erroneous_peb_count += 1; + } else if (scrubbing) + wl_tree_add(e1, &ubi->scrub); +- else ++ else if (keep) + wl_tree_add(e1, &ubi->used); + if (dst_leb_clean) { + wl_tree_add(e2, &ubi->free); +@@ -922,6 +933,12 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, + goto out_ro; + } + ++ if (erase) { ++ err = do_sync_erase(ubi, e1, vol_id, lnum, 1); ++ if (err) ++ goto out_ro; ++ } ++ + mutex_unlock(&ubi->move_mutex); + return 0; + +diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c +index 9fb8d74..da9998e 100644 +--- a/drivers/net/wireless/ath/ath10k/ce.c ++++ b/drivers/net/wireless/ath/ath10k/ce.c +@@ -433,6 +433,13 @@ void ath10k_ce_rx_update_write_idx(struct ath10k_ce_pipe *pipe, u32 nentries) + unsigned int nentries_mask = dest_ring->nentries_mask; + unsigned int write_index = dest_ring->write_index; + u32 ctrl_addr = pipe->ctrl_addr; ++ u32 cur_write_idx = ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr); ++ ++ /* Prevent CE ring stuck issue that will occur when ring is full. ++ * Make sure that write index is 1 less than read index. ++ */ ++ if ((cur_write_idx + nentries) == dest_ring->sw_index) ++ nentries -= 1; + + write_index = CE_RING_IDX_ADD(nentries_mask, write_index, nentries); + ath10k_ce_dest_ring_write_index_set(ar, ctrl_addr, write_index); +diff --git a/drivers/net/wireless/realtek/rtlwifi/regd.c b/drivers/net/wireless/realtek/rtlwifi/regd.c +index 3524441..6ee6bf8 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/regd.c ++++ b/drivers/net/wireless/realtek/rtlwifi/regd.c +@@ -345,9 +345,9 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select( + return &rtl_regdom_no_midband; + case COUNTRY_CODE_IC: + return &rtl_regdom_11; +- case COUNTRY_CODE_ETSI: + case COUNTRY_CODE_TELEC_NETGEAR: + return &rtl_regdom_60_64; ++ case COUNTRY_CODE_ETSI: + case COUNTRY_CODE_SPAIN: + case COUNTRY_CODE_FRANCE: + case COUNTRY_CODE_ISRAEL: +@@ -406,6 +406,8 @@ static u8 channel_plan_to_country_code(u8 channelplan) + return COUNTRY_CODE_WORLD_WIDE_13; + case 0x22: + return COUNTRY_CODE_IC; ++ case 0x25: ++ return COUNTRY_CODE_ETSI; + case 0x32: + return COUNTRY_CODE_TELEC_NETGEAR; + case 0x41: +diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c +index 6de0757..84d650d 100644 +--- a/drivers/pci/host/pci-tegra.c ++++ b/drivers/pci/host/pci-tegra.c +@@ -856,7 +856,7 @@ static int tegra_pcie_phy_disable(struct tegra_pcie *pcie) + /* override IDDQ */ + value = pads_readl(pcie, PADS_CTL); + value |= PADS_CTL_IDDQ_1L; +- pads_writel(pcie, PADS_CTL, value); ++ pads_writel(pcie, value, PADS_CTL); + + /* reset PLL */ + value = pads_readl(pcie, soc->pads_pll_ctl); +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 44e0ff3..4bf1a88 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -3198,6 +3198,7 @@ static void quirk_no_bus_reset(struct pci_dev *dev) + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0032, quirk_no_bus_reset); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0033, quirk_no_bus_reset); + + static void quirk_no_pm_reset(struct pci_dev *dev) + { +diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c +index d22a9fe..71bbeb9 100644 +--- a/drivers/pinctrl/intel/pinctrl-baytrail.c ++++ b/drivers/pinctrl/intel/pinctrl-baytrail.c +@@ -1808,6 +1808,8 @@ static int byt_pinctrl_probe(struct platform_device *pdev) + return PTR_ERR(vg->pctl_dev); + } + ++ raw_spin_lock_init(&vg->lock); ++ + ret = byt_gpio_probe(vg); + if (ret) { + pinctrl_unregister(vg->pctl_dev); +@@ -1815,7 +1817,6 @@ static int byt_pinctrl_probe(struct platform_device *pdev) + } + + platform_set_drvdata(pdev, vg); +- raw_spin_lock_init(&vg->lock); + pm_runtime_enable(&pdev->dev); + + return 0; +diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c +index 257cab1..2b5b20bf 100644 +--- a/drivers/pinctrl/intel/pinctrl-intel.c ++++ b/drivers/pinctrl/intel/pinctrl-intel.c +@@ -19,6 +19,7 @@ + #include <linux/pinctrl/pinconf.h> + #include <linux/pinctrl/pinconf-generic.h> + ++#include "../core.h" + #include "pinctrl-intel.h" + + /* Offset from regs */ +@@ -1079,6 +1080,26 @@ int intel_pinctrl_remove(struct platform_device *pdev) + EXPORT_SYMBOL_GPL(intel_pinctrl_remove); + + #ifdef CONFIG_PM_SLEEP ++static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned pin) ++{ ++ const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin); ++ ++ if (!pd || !intel_pad_usable(pctrl, pin)) ++ return false; ++ ++ /* ++ * Only restore the pin if it is actually in use by the kernel (or ++ * by userspace). It is possible that some pins are used by the ++ * BIOS during resume and those are not always locked down so leave ++ * them alone. ++ */ ++ if (pd->mux_owner || pd->gpio_owner || ++ gpiochip_line_is_irq(&pctrl->chip, pin)) ++ return true; ++ ++ return false; ++} ++ + int intel_pinctrl_suspend(struct device *dev) + { + struct platform_device *pdev = to_platform_device(dev); +@@ -1092,7 +1113,7 @@ int intel_pinctrl_suspend(struct device *dev) + const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i]; + u32 val; + +- if (!intel_pad_usable(pctrl, desc->number)) ++ if (!intel_pinctrl_should_save(pctrl, desc->number)) + continue; + + val = readl(intel_get_padcfg(pctrl, desc->number, PADCFG0)); +@@ -1153,7 +1174,7 @@ int intel_pinctrl_resume(struct device *dev) + void __iomem *padcfg; + u32 val; + +- if (!intel_pad_usable(pctrl, desc->number)) ++ if (!intel_pinctrl_should_save(pctrl, desc->number)) + continue; + + padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG0); +diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c +index fb991ec..696116e 100644 +--- a/drivers/regulator/tps65910-regulator.c ++++ b/drivers/regulator/tps65910-regulator.c +@@ -1111,6 +1111,12 @@ static int tps65910_probe(struct platform_device *pdev) + pmic->num_regulators = ARRAY_SIZE(tps65910_regs); + pmic->ext_sleep_control = tps65910_ext_sleep_control; + info = tps65910_regs; ++ /* Work around silicon erratum SWCZ010: output programmed ++ * voltage level can go higher than expected or crash ++ * Workaround: use no synchronization of DCDC clocks ++ */ ++ tps65910_reg_clear_bits(pmic->mfd, TPS65910_DCDCCTRL, ++ DCDCCTRL_DCDCCKSYNC_MASK); + break; + case TPS65911: + pmic->get_ctrl_reg = &tps65911_get_ctrl_register; +diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c +index 5d7fbe4..5810019 100644 +--- a/drivers/s390/scsi/zfcp_dbf.c ++++ b/drivers/s390/scsi/zfcp_dbf.c +@@ -3,7 +3,7 @@ + * + * Debug traces for zfcp. + * +- * Copyright IBM Corp. 2002, 2013 ++ * Copyright IBM Corp. 2002, 2016 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -65,7 +65,7 @@ void zfcp_dbf_pl_write(struct zfcp_dbf *dbf, void *data, u16 length, char *area, + * @tag: tag indicating which kind of unsolicited status has been received + * @req: request for which a response was received + */ +-void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req) ++void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req) + { + struct zfcp_dbf *dbf = req->adapter->dbf; + struct fsf_qtcb_prefix *q_pref = &req->qtcb->prefix; +@@ -85,6 +85,8 @@ void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req) + rec->u.res.req_issued = req->issued; + rec->u.res.prot_status = q_pref->prot_status; + rec->u.res.fsf_status = q_head->fsf_status; ++ rec->u.res.port_handle = q_head->port_handle; ++ rec->u.res.lun_handle = q_head->lun_handle; + + memcpy(rec->u.res.prot_status_qual, &q_pref->prot_status_qual, + FSF_PROT_STATUS_QUAL_SIZE); +@@ -97,7 +99,7 @@ void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req) + rec->pl_len, "fsf_res", req->req_id); + } + +- debug_event(dbf->hba, 1, rec, sizeof(*rec)); ++ debug_event(dbf->hba, level, rec, sizeof(*rec)); + spin_unlock_irqrestore(&dbf->hba_lock, flags); + } + +@@ -241,7 +243,8 @@ static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec, + if (sdev) { + rec->lun_status = atomic_read(&sdev_to_zfcp(sdev)->status); + rec->lun = zfcp_scsi_dev_lun(sdev); +- } ++ } else ++ rec->lun = ZFCP_DBF_INVALID_LUN; + } + + /** +@@ -320,13 +323,48 @@ void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp) + spin_unlock_irqrestore(&dbf->rec_lock, flags); + } + ++/** ++ * zfcp_dbf_rec_run_wka - trace wka port event with info like running recovery ++ * @tag: identifier for event ++ * @wka_port: well known address port ++ * @req_id: request ID to correlate with potential HBA trace record ++ */ ++void zfcp_dbf_rec_run_wka(char *tag, struct zfcp_fc_wka_port *wka_port, ++ u64 req_id) ++{ ++ struct zfcp_dbf *dbf = wka_port->adapter->dbf; ++ struct zfcp_dbf_rec *rec = &dbf->rec_buf; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dbf->rec_lock, flags); ++ memset(rec, 0, sizeof(*rec)); ++ ++ rec->id = ZFCP_DBF_REC_RUN; ++ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); ++ rec->port_status = wka_port->status; ++ rec->d_id = wka_port->d_id; ++ rec->lun = ZFCP_DBF_INVALID_LUN; ++ ++ rec->u.run.fsf_req_id = req_id; ++ rec->u.run.rec_status = ~0; ++ rec->u.run.rec_step = ~0; ++ rec->u.run.rec_action = ~0; ++ rec->u.run.rec_count = ~0; ++ ++ debug_event(dbf->rec, 1, rec, sizeof(*rec)); ++ spin_unlock_irqrestore(&dbf->rec_lock, flags); ++} ++ + static inline +-void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len, +- u64 req_id, u32 d_id) ++void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, ++ char *paytag, struct scatterlist *sg, u8 id, u16 len, ++ u64 req_id, u32 d_id, u16 cap_len) + { + struct zfcp_dbf_san *rec = &dbf->san_buf; + u16 rec_len; + unsigned long flags; ++ struct zfcp_dbf_pay *payload = &dbf->pay_buf; ++ u16 pay_sum = 0; + + spin_lock_irqsave(&dbf->san_lock, flags); + memset(rec, 0, sizeof(*rec)); +@@ -334,10 +372,41 @@ void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len, + rec->id = id; + rec->fsf_req_id = req_id; + rec->d_id = d_id; +- rec_len = min(len, (u16)ZFCP_DBF_SAN_MAX_PAYLOAD); +- memcpy(rec->payload, data, rec_len); + memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); ++ rec->pl_len = len; /* full length even if we cap pay below */ ++ if (!sg) ++ goto out; ++ rec_len = min_t(unsigned int, sg->length, ZFCP_DBF_SAN_MAX_PAYLOAD); ++ memcpy(rec->payload, sg_virt(sg), rec_len); /* part of 1st sg entry */ ++ if (len <= rec_len) ++ goto out; /* skip pay record if full content in rec->payload */ ++ ++ /* if (len > rec_len): ++ * dump data up to cap_len ignoring small duplicate in rec->payload ++ */ ++ spin_lock(&dbf->pay_lock); ++ memset(payload, 0, sizeof(*payload)); ++ memcpy(payload->area, paytag, ZFCP_DBF_TAG_LEN); ++ payload->fsf_req_id = req_id; ++ payload->counter = 0; ++ for (; sg && pay_sum < cap_len; sg = sg_next(sg)) { ++ u16 pay_len, offset = 0; ++ ++ while (offset < sg->length && pay_sum < cap_len) { ++ pay_len = min((u16)ZFCP_DBF_PAY_MAX_REC, ++ (u16)(sg->length - offset)); ++ /* cap_len <= pay_sum < cap_len+ZFCP_DBF_PAY_MAX_REC */ ++ memcpy(payload->data, sg_virt(sg) + offset, pay_len); ++ debug_event(dbf->pay, 1, payload, ++ zfcp_dbf_plen(pay_len)); ++ payload->counter++; ++ offset += pay_len; ++ pay_sum += pay_len; ++ } ++ } ++ spin_unlock(&dbf->pay_lock); + ++out: + debug_event(dbf->san, 1, rec, sizeof(*rec)); + spin_unlock_irqrestore(&dbf->san_lock, flags); + } +@@ -354,9 +423,62 @@ void zfcp_dbf_san_req(char *tag, struct zfcp_fsf_req *fsf, u32 d_id) + struct zfcp_fsf_ct_els *ct_els = fsf->data; + u16 length; + +- length = (u16)(ct_els->req->length + FC_CT_HDR_LEN); +- zfcp_dbf_san(tag, dbf, sg_virt(ct_els->req), ZFCP_DBF_SAN_REQ, length, +- fsf->req_id, d_id); ++ length = (u16)zfcp_qdio_real_bytes(ct_els->req); ++ zfcp_dbf_san(tag, dbf, "san_req", ct_els->req, ZFCP_DBF_SAN_REQ, ++ length, fsf->req_id, d_id, length); ++} ++ ++static u16 zfcp_dbf_san_res_cap_len_if_gpn_ft(char *tag, ++ struct zfcp_fsf_req *fsf, ++ u16 len) ++{ ++ struct zfcp_fsf_ct_els *ct_els = fsf->data; ++ struct fc_ct_hdr *reqh = sg_virt(ct_els->req); ++ struct fc_ns_gid_ft *reqn = (struct fc_ns_gid_ft *)(reqh + 1); ++ struct scatterlist *resp_entry = ct_els->resp; ++ struct fc_gpn_ft_resp *acc; ++ int max_entries, x, last = 0; ++ ++ if (!(memcmp(tag, "fsscth2", 7) == 0 ++ && ct_els->d_id == FC_FID_DIR_SERV ++ && reqh->ct_rev == FC_CT_REV ++ && reqh->ct_in_id[0] == 0 ++ && reqh->ct_in_id[1] == 0 ++ && reqh->ct_in_id[2] == 0 ++ && reqh->ct_fs_type == FC_FST_DIR ++ && reqh->ct_fs_subtype == FC_NS_SUBTYPE ++ && reqh->ct_options == 0 ++ && reqh->_ct_resvd1 == 0 ++ && reqh->ct_cmd == FC_NS_GPN_FT ++ /* reqh->ct_mr_size can vary so do not match but read below */ ++ && reqh->_ct_resvd2 == 0 ++ && reqh->ct_reason == 0 ++ && reqh->ct_explan == 0 ++ && reqh->ct_vendor == 0 ++ && reqn->fn_resvd == 0 ++ && reqn->fn_domain_id_scope == 0 ++ && reqn->fn_area_id_scope == 0 ++ && reqn->fn_fc4_type == FC_TYPE_FCP)) ++ return len; /* not GPN_FT response so do not cap */ ++ ++ acc = sg_virt(resp_entry); ++ max_entries = (reqh->ct_mr_size * 4 / sizeof(struct fc_gpn_ft_resp)) ++ + 1 /* zfcp_fc_scan_ports: bytes correct, entries off-by-one ++ * to account for header as 1st pseudo "entry" */; ++ ++ /* the basic CT_IU preamble is the same size as one entry in the GPN_FT ++ * response, allowing us to skip special handling for it - just skip it ++ */ ++ for (x = 1; x < max_entries && !last; x++) { ++ if (x % (ZFCP_FC_GPN_FT_ENT_PAGE + 1)) ++ acc++; ++ else ++ acc = sg_virt(++resp_entry); ++ ++ last = acc->fp_flags & FC_NS_FID_LAST; ++ } ++ len = min(len, (u16)(x * sizeof(struct fc_gpn_ft_resp))); ++ return len; /* cap after last entry */ + } + + /** +@@ -370,9 +492,10 @@ void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf) + struct zfcp_fsf_ct_els *ct_els = fsf->data; + u16 length; + +- length = (u16)(ct_els->resp->length + FC_CT_HDR_LEN); +- zfcp_dbf_san(tag, dbf, sg_virt(ct_els->resp), ZFCP_DBF_SAN_RES, length, +- fsf->req_id, 0); ++ length = (u16)zfcp_qdio_real_bytes(ct_els->resp); ++ zfcp_dbf_san(tag, dbf, "san_res", ct_els->resp, ZFCP_DBF_SAN_RES, ++ length, fsf->req_id, ct_els->d_id, ++ zfcp_dbf_san_res_cap_len_if_gpn_ft(tag, fsf, length)); + } + + /** +@@ -386,11 +509,13 @@ void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf) + struct fsf_status_read_buffer *srb = + (struct fsf_status_read_buffer *) fsf->data; + u16 length; ++ struct scatterlist sg; + + length = (u16)(srb->length - + offsetof(struct fsf_status_read_buffer, payload)); +- zfcp_dbf_san(tag, dbf, srb->payload.data, ZFCP_DBF_SAN_ELS, length, +- fsf->req_id, ntoh24(srb->d_id)); ++ sg_init_one(&sg, srb->payload.data, length); ++ zfcp_dbf_san(tag, dbf, "san_els", &sg, ZFCP_DBF_SAN_ELS, length, ++ fsf->req_id, ntoh24(srb->d_id), length); + } + + /** +@@ -399,7 +524,8 @@ void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf) + * @sc: pointer to struct scsi_cmnd + * @fsf: pointer to struct zfcp_fsf_req + */ +-void zfcp_dbf_scsi(char *tag, struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf) ++void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc, ++ struct zfcp_fsf_req *fsf) + { + struct zfcp_adapter *adapter = + (struct zfcp_adapter *) sc->device->host->hostdata[0]; +@@ -442,7 +568,7 @@ void zfcp_dbf_scsi(char *tag, struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf) + } + } + +- debug_event(dbf->scsi, 1, rec, sizeof(*rec)); ++ debug_event(dbf->scsi, level, rec, sizeof(*rec)); + spin_unlock_irqrestore(&dbf->scsi_lock, flags); + } + +diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h +index 0be3d48..36d0758 100644 +--- a/drivers/s390/scsi/zfcp_dbf.h ++++ b/drivers/s390/scsi/zfcp_dbf.h +@@ -2,7 +2,7 @@ + * zfcp device driver + * debug feature declarations + * +- * Copyright IBM Corp. 2008, 2010 ++ * Copyright IBM Corp. 2008, 2015 + */ + + #ifndef ZFCP_DBF_H +@@ -17,6 +17,11 @@ + + #define ZFCP_DBF_INVALID_LUN 0xFFFFFFFFFFFFFFFFull + ++enum zfcp_dbf_pseudo_erp_act_type { ++ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD = 0xff, ++ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL = 0xfe, ++}; ++ + /** + * struct zfcp_dbf_rec_trigger - trace record for triggered recovery action + * @ready: number of ready recovery actions +@@ -110,6 +115,7 @@ struct zfcp_dbf_san { + u32 d_id; + #define ZFCP_DBF_SAN_MAX_PAYLOAD (FC_CT_HDR_LEN + 32) + char payload[ZFCP_DBF_SAN_MAX_PAYLOAD]; ++ u16 pl_len; + } __packed; + + /** +@@ -126,6 +132,8 @@ struct zfcp_dbf_hba_res { + u8 prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE]; + u32 fsf_status; + u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE]; ++ u32 port_handle; ++ u32 lun_handle; + } __packed; + + /** +@@ -279,7 +287,7 @@ static inline + void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req) + { + if (debug_level_enabled(req->adapter->dbf->hba, level)) +- zfcp_dbf_hba_fsf_res(tag, req); ++ zfcp_dbf_hba_fsf_res(tag, level, req); + } + + /** +@@ -318,7 +326,7 @@ void _zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *scmd, + scmd->device->host->hostdata[0]; + + if (debug_level_enabled(adapter->dbf->scsi, level)) +- zfcp_dbf_scsi(tag, scmd, req); ++ zfcp_dbf_scsi(tag, level, scmd, req); + } + + /** +diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c +index 3fb4109..a59d678 100644 +--- a/drivers/s390/scsi/zfcp_erp.c ++++ b/drivers/s390/scsi/zfcp_erp.c +@@ -3,7 +3,7 @@ + * + * Error Recovery Procedures (ERP). + * +- * Copyright IBM Corp. 2002, 2010 ++ * Copyright IBM Corp. 2002, 2015 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -1217,8 +1217,14 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) + break; + + case ZFCP_ERP_ACTION_REOPEN_PORT: +- if (result == ZFCP_ERP_SUCCEEDED) +- zfcp_scsi_schedule_rport_register(port); ++ /* This switch case might also happen after a forced reopen ++ * was successfully done and thus overwritten with a new ++ * non-forced reopen at `ersfs_2'. In this case, we must not ++ * do the clean-up of the non-forced version. ++ */ ++ if (act->step != ZFCP_ERP_STEP_UNINITIALIZED) ++ if (result == ZFCP_ERP_SUCCEEDED) ++ zfcp_scsi_schedule_rport_register(port); + /* fall through */ + case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: + put_device(&port->dev); +diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h +index 5b50065..c8fed9f 100644 +--- a/drivers/s390/scsi/zfcp_ext.h ++++ b/drivers/s390/scsi/zfcp_ext.h +@@ -3,7 +3,7 @@ + * + * External function declarations. + * +- * Copyright IBM Corp. 2002, 2010 ++ * Copyright IBM Corp. 2002, 2015 + */ + + #ifndef ZFCP_EXT_H +@@ -35,8 +35,9 @@ extern void zfcp_dbf_adapter_unregister(struct zfcp_adapter *); + extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *, + struct zfcp_port *, struct scsi_device *, u8, u8); + extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *); ++extern void zfcp_dbf_rec_run_wka(char *, struct zfcp_fc_wka_port *, u64); + extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *); +-extern void zfcp_dbf_hba_fsf_res(char *, struct zfcp_fsf_req *); ++extern void zfcp_dbf_hba_fsf_res(char *, int, struct zfcp_fsf_req *); + extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *); + extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *); + extern void zfcp_dbf_hba_def_err(struct zfcp_adapter *, u64, u16, void **); +@@ -44,7 +45,8 @@ extern void zfcp_dbf_hba_basic(char *, struct zfcp_adapter *); + extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32); + extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *); + extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *); +-extern void zfcp_dbf_scsi(char *, struct scsi_cmnd *, struct zfcp_fsf_req *); ++extern void zfcp_dbf_scsi(char *, int, struct scsi_cmnd *, ++ struct zfcp_fsf_req *); + + /* zfcp_erp.c */ + extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32); +diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c +index 522a633..75f820ca 100644 +--- a/drivers/s390/scsi/zfcp_fsf.c ++++ b/drivers/s390/scsi/zfcp_fsf.c +@@ -3,7 +3,7 @@ + * + * Implementation of FSF commands. + * +- * Copyright IBM Corp. 2002, 2013 ++ * Copyright IBM Corp. 2002, 2015 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -508,7 +508,10 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) + fc_host_port_type(shost) = FC_PORTTYPE_PTP; + break; + case FSF_TOPO_FABRIC: +- fc_host_port_type(shost) = FC_PORTTYPE_NPORT; ++ if (bottom->connection_features & FSF_FEATURE_NPIV_MODE) ++ fc_host_port_type(shost) = FC_PORTTYPE_NPIV; ++ else ++ fc_host_port_type(shost) = FC_PORTTYPE_NPORT; + break; + case FSF_TOPO_AL: + fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; +@@ -613,7 +616,6 @@ static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req) + + if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) { + fc_host_permanent_port_name(shost) = bottom->wwpn; +- fc_host_port_type(shost) = FC_PORTTYPE_NPIV; + } else + fc_host_permanent_port_name(shost) = fc_host_port_name(shost); + fc_host_maxframe_size(shost) = bottom->maximum_frame_size; +@@ -982,8 +984,12 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, + if (zfcp_adapter_multi_buffer_active(adapter)) { + if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_req)) + return -EIO; ++ qtcb->bottom.support.req_buf_length = ++ zfcp_qdio_real_bytes(sg_req); + if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_resp)) + return -EIO; ++ qtcb->bottom.support.resp_buf_length = ++ zfcp_qdio_real_bytes(sg_resp); + + zfcp_qdio_set_data_div(qdio, &req->qdio_req, + zfcp_qdio_sbale_count(sg_req)); +@@ -1073,6 +1079,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, + + req->handler = zfcp_fsf_send_ct_handler; + req->qtcb->header.port_handle = wka_port->handle; ++ ct->d_id = wka_port->d_id; + req->data = ct; + + zfcp_dbf_san_req("fssct_1", req, wka_port->d_id); +@@ -1169,6 +1176,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, + + hton24(req->qtcb->bottom.support.d_id, d_id); + req->handler = zfcp_fsf_send_els_handler; ++ els->d_id = d_id; + req->data = els; + + zfcp_dbf_san_req("fssels1", req, d_id); +@@ -1575,7 +1583,7 @@ static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req) + int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) + { + struct zfcp_qdio *qdio = wka_port->adapter->qdio; +- struct zfcp_fsf_req *req; ++ struct zfcp_fsf_req *req = NULL; + int retval = -EIO; + + spin_lock_irq(&qdio->req_q_lock); +@@ -1604,6 +1612,8 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) + zfcp_fsf_req_free(req); + out: + spin_unlock_irq(&qdio->req_q_lock); ++ if (req && !IS_ERR(req)) ++ zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id); + return retval; + } + +@@ -1628,7 +1638,7 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req) + int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) + { + struct zfcp_qdio *qdio = wka_port->adapter->qdio; +- struct zfcp_fsf_req *req; ++ struct zfcp_fsf_req *req = NULL; + int retval = -EIO; + + spin_lock_irq(&qdio->req_q_lock); +@@ -1657,6 +1667,8 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) + zfcp_fsf_req_free(req); + out: + spin_unlock_irq(&qdio->req_q_lock); ++ if (req && !IS_ERR(req)) ++ zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id); + return retval; + } + +diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h +index 57ae3ae..be1c04b 100644 +--- a/drivers/s390/scsi/zfcp_fsf.h ++++ b/drivers/s390/scsi/zfcp_fsf.h +@@ -3,7 +3,7 @@ + * + * Interface to the FSF support functions. + * +- * Copyright IBM Corp. 2002, 2010 ++ * Copyright IBM Corp. 2002, 2015 + */ + + #ifndef FSF_H +@@ -436,6 +436,7 @@ struct zfcp_blk_drv_data { + * @handler_data: data passed to handler function + * @port: Optional pointer to port for zfcp internal ELS (only test link ADISC) + * @status: used to pass error status to calling function ++ * @d_id: Destination ID of either open WKA port for CT or of D_ID for ELS + */ + struct zfcp_fsf_ct_els { + struct scatterlist *req; +@@ -444,6 +445,7 @@ struct zfcp_fsf_ct_els { + void *handler_data; + struct zfcp_port *port; + int status; ++ u32 d_id; + }; + + #endif /* FSF_H */ +diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c +index b3c6ff4..9069f98 100644 +--- a/drivers/s390/scsi/zfcp_scsi.c ++++ b/drivers/s390/scsi/zfcp_scsi.c +@@ -3,7 +3,7 @@ + * + * Interface to Linux SCSI midlayer. + * +- * Copyright IBM Corp. 2002, 2013 ++ * Copyright IBM Corp. 2002, 2015 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -556,6 +556,9 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port) + ids.port_id = port->d_id; + ids.roles = FC_RPORT_ROLE_FCP_TARGET; + ++ zfcp_dbf_rec_trig("scpaddy", port->adapter, port, NULL, ++ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD, ++ ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD); + rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids); + if (!rport) { + dev_err(&port->adapter->ccw_device->dev, +@@ -577,6 +580,9 @@ static void zfcp_scsi_rport_block(struct zfcp_port *port) + struct fc_rport *rport = port->rport; + + if (rport) { ++ zfcp_dbf_rec_trig("scpdely", port->adapter, port, NULL, ++ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL, ++ ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL); + fc_remote_port_delete(rport); + port->rport = NULL; + } +diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c +index e0a78f5..bac8cdf 100644 +--- a/drivers/scsi/scsi_scan.c ++++ b/drivers/scsi/scsi_scan.c +@@ -1472,12 +1472,12 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, + out_err: + kfree(lun_data); + out: +- scsi_device_put(sdev); + if (scsi_device_created(sdev)) + /* + * the sdev we used didn't appear in the report luns scan + */ + __scsi_remove_device(sdev); ++ scsi_device_put(sdev); + return ret; + } + +diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c +index 333eb22..0aaf429 100644 +--- a/drivers/soc/fsl/qe/gpio.c ++++ b/drivers/soc/fsl/qe/gpio.c +@@ -41,7 +41,8 @@ struct qe_gpio_chip { + + static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc) + { +- struct qe_gpio_chip *qe_gc = gpiochip_get_data(&mm_gc->gc); ++ struct qe_gpio_chip *qe_gc = ++ container_of(mm_gc, struct qe_gpio_chip, mm_gc); + struct qe_pio_regs __iomem *regs = mm_gc->regs; + + qe_gc->cpdata = in_be32(®s->cpdata); +diff --git a/drivers/soc/fsl/qe/qe_common.c b/drivers/soc/fsl/qe/qe_common.c +index 41eff80..104e68d 100644 +--- a/drivers/soc/fsl/qe/qe_common.c ++++ b/drivers/soc/fsl/qe/qe_common.c +@@ -70,6 +70,11 @@ int cpm_muram_init(void) + } + + muram_pool = gen_pool_create(0, -1); ++ if (!muram_pool) { ++ pr_err("Cannot allocate memory pool for CPM/QE muram"); ++ ret = -ENOMEM; ++ goto out_muram; ++ } + muram_pbase = of_translate_address(np, zero); + if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) { + pr_err("Cannot translate zero through CPM muram node"); +@@ -116,6 +121,9 @@ static unsigned long cpm_muram_alloc_common(unsigned long size, + struct muram_block *entry; + unsigned long start; + ++ if (!muram_pool && cpm_muram_init()) ++ goto out2; ++ + start = gen_pool_alloc_algo(muram_pool, size, algo, data); + if (!start) + goto out2; +diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c +index 6094a6b..e825d58 100644 +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -754,15 +754,7 @@ EXPORT_SYMBOL(target_complete_cmd); + + void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int length) + { +- if (scsi_status != SAM_STAT_GOOD) { +- return; +- } +- +- /* +- * Calculate new residual count based upon length of SCSI data +- * transferred. +- */ +- if (length < cmd->data_length) { ++ if (scsi_status == SAM_STAT_GOOD && length < cmd->data_length) { + if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) { + cmd->residual_count += cmd->data_length - length; + } else { +@@ -771,12 +763,6 @@ void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int len + } + + cmd->data_length = length; +- } else if (length > cmd->data_length) { +- cmd->se_cmd_flags |= SCF_OVERFLOW_BIT; +- cmd->residual_count = length - cmd->data_length; +- } else { +- cmd->se_cmd_flags &= ~(SCF_OVERFLOW_BIT | SCF_UNDERFLOW_BIT); +- cmd->residual_count = 0; + } + + target_complete_cmd(cmd, scsi_status); +@@ -1706,6 +1692,7 @@ void transport_generic_request_failure(struct se_cmd *cmd, + case TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED: + case TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED: + case TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED: ++ case TCM_COPY_TARGET_DEVICE_NOT_REACHABLE: + break; + case TCM_OUT_OF_RESOURCES: + sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; +@@ -2547,8 +2534,10 @@ int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref) + * fabric acknowledgement that requires two target_put_sess_cmd() + * invocations before se_cmd descriptor release. + */ +- if (ack_kref) ++ if (ack_kref) { + kref_get(&se_cmd->cmd_kref); ++ se_cmd->se_cmd_flags |= SCF_ACK_KREF; ++ } + + spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); + if (se_sess->sess_tearing_down) { +@@ -2871,6 +2860,12 @@ static const struct sense_info sense_info_table[] = { + .ascq = 0x03, /* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */ + .add_sector_info = true, + }, ++ [TCM_COPY_TARGET_DEVICE_NOT_REACHABLE] = { ++ .key = COPY_ABORTED, ++ .asc = 0x0d, ++ .ascq = 0x02, /* COPY TARGET DEVICE NOT REACHABLE */ ++ ++ }, + [TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE] = { + /* + * Returning ILLEGAL REQUEST would cause immediate IO errors on +diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c +index 75cd854..094a144 100644 +--- a/drivers/target/target_core_xcopy.c ++++ b/drivers/target/target_core_xcopy.c +@@ -104,7 +104,7 @@ static int target_xcopy_locate_se_dev_e4(struct se_cmd *se_cmd, struct xcopy_op + } + mutex_unlock(&g_device_mutex); + +- pr_err("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n"); ++ pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n"); + return -EINVAL; + } + +@@ -185,7 +185,7 @@ static int target_xcopy_parse_tiddesc_e4(struct se_cmd *se_cmd, struct xcopy_op + + static int target_xcopy_parse_target_descriptors(struct se_cmd *se_cmd, + struct xcopy_op *xop, unsigned char *p, +- unsigned short tdll) ++ unsigned short tdll, sense_reason_t *sense_ret) + { + struct se_device *local_dev = se_cmd->se_dev; + unsigned char *desc = p; +@@ -193,6 +193,8 @@ static int target_xcopy_parse_target_descriptors(struct se_cmd *se_cmd, + unsigned short start = 0; + bool src = true; + ++ *sense_ret = TCM_INVALID_PARAMETER_LIST; ++ + if (offset != 0) { + pr_err("XCOPY target descriptor list length is not" + " multiple of %d\n", XCOPY_TARGET_DESC_LEN); +@@ -243,9 +245,16 @@ static int target_xcopy_parse_target_descriptors(struct se_cmd *se_cmd, + rc = target_xcopy_locate_se_dev_e4(se_cmd, xop, true); + else + rc = target_xcopy_locate_se_dev_e4(se_cmd, xop, false); +- +- if (rc < 0) ++ /* ++ * If a matching IEEE NAA 0x83 descriptor for the requested device ++ * is not located on this node, return COPY_ABORTED with ASQ/ASQC ++ * 0x0d/0x02 - COPY_TARGET_DEVICE_NOT_REACHABLE to request the ++ * initiator to fall back to normal copy method. ++ */ ++ if (rc < 0) { ++ *sense_ret = TCM_COPY_TARGET_DEVICE_NOT_REACHABLE; + goto out; ++ } + + pr_debug("XCOPY TGT desc: Source dev: %p NAA IEEE WWN: 0x%16phN\n", + xop->src_dev, &xop->src_tid_wwn[0]); +@@ -653,6 +662,7 @@ static int target_xcopy_read_source( + rc = target_xcopy_setup_pt_cmd(xpt_cmd, xop, src_dev, &cdb[0], + remote_port, true); + if (rc < 0) { ++ ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status; + transport_generic_free_cmd(se_cmd, 0); + return rc; + } +@@ -664,6 +674,7 @@ static int target_xcopy_read_source( + + rc = target_xcopy_issue_pt_cmd(xpt_cmd); + if (rc < 0) { ++ ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status; + transport_generic_free_cmd(se_cmd, 0); + return rc; + } +@@ -714,6 +725,7 @@ static int target_xcopy_write_destination( + remote_port, false); + if (rc < 0) { + struct se_cmd *src_cmd = &xop->src_pt_cmd->se_cmd; ++ ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status; + /* + * If the failure happened before the t_mem_list hand-off in + * target_xcopy_setup_pt_cmd(), Reset memory + clear flag so that +@@ -729,6 +741,7 @@ static int target_xcopy_write_destination( + + rc = target_xcopy_issue_pt_cmd(xpt_cmd); + if (rc < 0) { ++ ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status; + se_cmd->se_cmd_flags &= ~SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC; + transport_generic_free_cmd(se_cmd, 0); + return rc; +@@ -815,9 +828,14 @@ static void target_xcopy_do_work(struct work_struct *work) + out: + xcopy_pt_undepend_remotedev(xop); + kfree(xop); +- +- pr_warn("target_xcopy_do_work: Setting X-COPY CHECK_CONDITION -> sending response\n"); +- ec_cmd->scsi_status = SAM_STAT_CHECK_CONDITION; ++ /* ++ * Don't override an error scsi status if it has already been set ++ */ ++ if (ec_cmd->scsi_status == SAM_STAT_GOOD) { ++ pr_warn_ratelimited("target_xcopy_do_work: rc: %d, Setting X-COPY" ++ " CHECK_CONDITION -> sending response\n", rc); ++ ec_cmd->scsi_status = SAM_STAT_CHECK_CONDITION; ++ } + target_complete_cmd(ec_cmd, SAM_STAT_CHECK_CONDITION); + } + +@@ -875,7 +893,7 @@ sense_reason_t target_do_xcopy(struct se_cmd *se_cmd) + " tdll: %hu sdll: %u inline_dl: %u\n", list_id, list_id_usage, + tdll, sdll, inline_dl); + +- rc = target_xcopy_parse_target_descriptors(se_cmd, xop, &p[16], tdll); ++ rc = target_xcopy_parse_target_descriptors(se_cmd, xop, &p[16], tdll, &ret); + if (rc <= 0) + goto out; + +diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c +index 216e18c..9a874a8 100644 +--- a/drivers/target/tcm_fc/tfc_cmd.c ++++ b/drivers/target/tcm_fc/tfc_cmd.c +@@ -572,7 +572,7 @@ static void ft_send_work(struct work_struct *work) + if (target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, fcp->fc_cdb, + &cmd->ft_sense_buffer[0], scsilun_to_int(&fcp->fc_lun), + ntohl(fcp->fc_dl), task_attr, data_dir, +- TARGET_SCF_ACK_KREF)) ++ TARGET_SCF_ACK_KREF | TARGET_SCF_USE_CPUID)) + goto err; + + pr_debug("r_ctl %x alloc target_submit_cmd\n", fh->fh_r_ctl); +diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c +index 924bad4..37a37c4 100644 +--- a/drivers/video/fbdev/efifb.c ++++ b/drivers/video/fbdev/efifb.c +@@ -50,9 +50,9 @@ static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, + return 1; + + if (regno < 16) { +- red >>= 8; +- green >>= 8; +- blue >>= 8; ++ red >>= 16 - info->var.red.length; ++ green >>= 16 - info->var.green.length; ++ blue >>= 16 - info->var.blue.length; + ((u32 *)(info->pseudo_palette))[regno] = + (red << info->var.red.offset) | + (green << info->var.green.offset) | +diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c +index 4a2290f..d5735c1 100644 +--- a/drivers/watchdog/mt7621_wdt.c ++++ b/drivers/watchdog/mt7621_wdt.c +@@ -139,7 +139,6 @@ static int mt7621_wdt_probe(struct platform_device *pdev) + if (!IS_ERR(mt7621_wdt_reset)) + reset_control_deassert(mt7621_wdt_reset); + +- mt7621_wdt_dev.dev = &pdev->dev; + mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause(); + + watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout, +diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c +index 1967919..14b4fd4 100644 +--- a/drivers/watchdog/rt2880_wdt.c ++++ b/drivers/watchdog/rt2880_wdt.c +@@ -158,7 +158,6 @@ static int rt288x_wdt_probe(struct platform_device *pdev) + + rt288x_wdt_freq = clk_get_rate(rt288x_wdt_clk) / RALINK_WDT_PRESCALE; + +- rt288x_wdt_dev.dev = &pdev->dev; + rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause(); + rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq); + rt288x_wdt_dev.parent = &pdev->dev; +diff --git a/fs/ceph/file.c b/fs/ceph/file.c +index 0f5375d..eede975 100644 +--- a/fs/ceph/file.c ++++ b/fs/ceph/file.c +@@ -1272,7 +1272,8 @@ static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to) + statret = __ceph_do_getattr(inode, page, + CEPH_STAT_CAP_INLINE_DATA, !!page); + if (statret < 0) { +- __free_page(page); ++ if (page) ++ __free_page(page); + if (statret == -ENODATA) { + BUG_ON(retry_op != READ_INLINE); + goto again; +diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c +index 6c58e13..3d03e48 100644 +--- a/fs/cifs/cifs_debug.c ++++ b/fs/cifs/cifs_debug.c +@@ -152,6 +152,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) + list_for_each(tmp1, &cifs_tcp_ses_list) { + server = list_entry(tmp1, struct TCP_Server_Info, + tcp_ses_list); ++ seq_printf(m, "\nNumber of credits: %d", server->credits); + i++; + list_for_each(tmp2, &server->smb_ses_list) { + ses = list_entry(tmp2, struct cifs_ses, +diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c +index 14ae4b8..8c68d03 100644 +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -271,7 +271,7 @@ cifs_alloc_inode(struct super_block *sb) + cifs_inode->createtime = 0; + cifs_inode->epoch = 0; + #ifdef CONFIG_CIFS_SMB2 +- get_random_bytes(cifs_inode->lease_key, SMB2_LEASE_KEY_SIZE); ++ generate_random_uuid(cifs_inode->lease_key); + #endif + /* + * Can not set i_flags here - they get immediately overwritten to zero +@@ -1271,7 +1271,6 @@ init_cifs(void) + GlobalTotalActiveXid = 0; + GlobalMaxActiveXid = 0; + spin_lock_init(&cifs_tcp_ses_lock); +- spin_lock_init(&cifs_file_list_lock); + spin_lock_init(&GlobalMid_Lock); + + get_random_bytes(&cifs_lock_secret, sizeof(cifs_lock_secret)); +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index 8f1d8c1..65f78b7 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -833,6 +833,7 @@ struct cifs_tcon { + struct list_head tcon_list; + int tc_count; + struct list_head openFileList; ++ spinlock_t open_file_lock; /* protects list above */ + struct cifs_ses *ses; /* pointer to session associated with */ + char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */ + char *nativeFileSystem; +@@ -889,7 +890,7 @@ struct cifs_tcon { + #endif /* CONFIG_CIFS_STATS2 */ + __u64 bytes_read; + __u64 bytes_written; +- spinlock_t stat_lock; ++ spinlock_t stat_lock; /* protects the two fields above */ + #endif /* CONFIG_CIFS_STATS */ + FILE_SYSTEM_DEVICE_INFO fsDevInfo; + FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */ +@@ -1040,8 +1041,10 @@ struct cifs_fid_locks { + }; + + struct cifsFileInfo { ++ /* following two lists are protected by tcon->open_file_lock */ + struct list_head tlist; /* pointer to next fid owned by tcon */ + struct list_head flist; /* next fid (file instance) for this inode */ ++ /* lock list below protected by cifsi->lock_sem */ + struct cifs_fid_locks *llist; /* brlocks held by this fid */ + kuid_t uid; /* allows finding which FileInfo structure */ + __u32 pid; /* process id who opened file */ +@@ -1049,11 +1052,12 @@ struct cifsFileInfo { + /* BB add lock scope info here if needed */ ; + /* lock scope id (0 if none) */ + struct dentry *dentry; +- unsigned int f_flags; + struct tcon_link *tlink; ++ unsigned int f_flags; + bool invalidHandle:1; /* file closed via session abend */ + bool oplock_break_cancelled:1; +- int count; /* refcount protected by cifs_file_list_lock */ ++ int count; ++ spinlock_t file_info_lock; /* protects four flag/count fields above */ + struct mutex fh_mutex; /* prevents reopen race after dead ses*/ + struct cifs_search_info srch_inf; + struct work_struct oplock_break; /* work for oplock breaks */ +@@ -1120,7 +1124,7 @@ struct cifs_writedata { + + /* + * Take a reference on the file private data. Must be called with +- * cifs_file_list_lock held. ++ * cfile->file_info_lock held. + */ + static inline void + cifsFileInfo_get_locked(struct cifsFileInfo *cifs_file) +@@ -1514,8 +1518,10 @@ require use of the stronger protocol */ + * GlobalMid_Lock protects: + * list operations on pending_mid_q and oplockQ + * updates to XID counters, multiplex id and SMB sequence numbers +- * cifs_file_list_lock protects: +- * list operations on tcp and SMB session lists and tCon lists ++ * tcp_ses_lock protects: ++ * list operations on tcp and SMB session lists ++ * tcon->open_file_lock protects the list of open files hanging off the tcon ++ * cfile->file_info_lock protects counters and fields in cifs file struct + * f_owner.lock protects certain per file struct operations + * mapping->page_lock protects certain per page operations + * +@@ -1547,18 +1553,12 @@ GLOBAL_EXTERN struct list_head cifs_tcp_ses_list; + * tcp session, and the list of tcon's per smb session. It also protects + * the reference counters for the server, smb session, and tcon. Finally, + * changes to the tcon->tidStatus should be done while holding this lock. ++ * generally the locks should be taken in order tcp_ses_lock before ++ * tcon->open_file_lock and that before file->file_info_lock since the ++ * structure order is cifs_socket-->cifs_ses-->cifs_tcon-->cifs_file + */ + GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock; + +-/* +- * This lock protects the cifs_file->llist and cifs_file->flist +- * list operations, and updates to some flags (cifs_file->invalidHandle) +- * It will be moved to either use the tcon->stat_lock or equivalent later. +- * If cifs_tcp_ses_lock and the lock below are both needed to be held, then +- * the cifs_tcp_ses_lock must be grabbed first and released last. +- */ +-GLOBAL_EXTERN spinlock_t cifs_file_list_lock; +- + #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */ + /* Outstanding dir notify requests */ + GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; +diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c +index d47197e..7804605 100644 +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -98,13 +98,13 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon) + struct list_head *tmp1; + + /* list all files open on tree connection and mark them invalid */ +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + list_for_each_safe(tmp, tmp1, &tcon->openFileList) { + open_file = list_entry(tmp, struct cifsFileInfo, tlist); + open_file->invalidHandle = true; + open_file->oplock_break_cancelled = true; + } +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + /* + * BB Add call to invalidate_inodes(sb) for all superblocks mounted + * to this tcon. +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index 2e4f4ba..7b67179 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -2163,7 +2163,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) + memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr, + sizeof(tcp_ses->dstaddr)); + #ifdef CONFIG_CIFS_SMB2 +- get_random_bytes(tcp_ses->client_guid, SMB2_CLIENT_GUID_SIZE); ++ generate_random_uuid(tcp_ses->client_guid); + #endif + /* + * at this point we are the only ones with the pointer +@@ -3688,14 +3688,16 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) + goto mount_fail_check; + } + +- rc = cifs_are_all_path_components_accessible(server, ++ if (rc != -EREMOTE) { ++ rc = cifs_are_all_path_components_accessible(server, + xid, tcon, cifs_sb, + full_path); +- if (rc != 0) { +- cifs_dbg(VFS, "cannot query dirs between root and final path, " +- "enabling CIFS_MOUNT_USE_PREFIX_PATH\n"); +- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; +- rc = 0; ++ if (rc != 0) { ++ cifs_dbg(VFS, "cannot query dirs between root and final path, " ++ "enabling CIFS_MOUNT_USE_PREFIX_PATH\n"); ++ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; ++ rc = 0; ++ } + } + kfree(full_path); + } +diff --git a/fs/cifs/file.c b/fs/cifs/file.c +index 579e41b..605438a 100644 +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -305,6 +305,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, + cfile->tlink = cifs_get_tlink(tlink); + INIT_WORK(&cfile->oplock_break, cifs_oplock_break); + mutex_init(&cfile->fh_mutex); ++ spin_lock_init(&cfile->file_info_lock); + + cifs_sb_active(inode->i_sb); + +@@ -317,7 +318,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, + oplock = 0; + } + +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + if (fid->pending_open->oplock != CIFS_OPLOCK_NO_CHANGE && oplock) + oplock = fid->pending_open->oplock; + list_del(&fid->pending_open->olist); +@@ -326,12 +327,13 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, + server->ops->set_fid(cfile, fid, oplock); + + list_add(&cfile->tlist, &tcon->openFileList); ++ + /* if readable file instance put first in list*/ + if (file->f_mode & FMODE_READ) + list_add(&cfile->flist, &cinode->openFileList); + else + list_add_tail(&cfile->flist, &cinode->openFileList); +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + + if (fid->purge_cache) + cifs_zap_mapping(inode); +@@ -343,16 +345,16 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, + struct cifsFileInfo * + cifsFileInfo_get(struct cifsFileInfo *cifs_file) + { +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&cifs_file->file_info_lock); + cifsFileInfo_get_locked(cifs_file); +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&cifs_file->file_info_lock); + return cifs_file; + } + + /* + * Release a reference on the file private data. This may involve closing + * the filehandle out on the server. Must be called without holding +- * cifs_file_list_lock. ++ * tcon->open_file_lock and cifs_file->file_info_lock. + */ + void cifsFileInfo_put(struct cifsFileInfo *cifs_file) + { +@@ -367,11 +369,15 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) + struct cifs_pending_open open; + bool oplock_break_cancelled; + +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); ++ ++ spin_lock(&cifs_file->file_info_lock); + if (--cifs_file->count > 0) { +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&cifs_file->file_info_lock); ++ spin_unlock(&tcon->open_file_lock); + return; + } ++ spin_unlock(&cifs_file->file_info_lock); + + if (server->ops->get_lease_key) + server->ops->get_lease_key(inode, &fid); +@@ -395,7 +401,8 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) + set_bit(CIFS_INO_INVALID_MAPPING, &cifsi->flags); + cifs_set_oplock_level(cifsi, 0); + } +- spin_unlock(&cifs_file_list_lock); ++ ++ spin_unlock(&tcon->open_file_lock); + + oplock_break_cancelled = cancel_work_sync(&cifs_file->oplock_break); + +@@ -772,10 +779,10 @@ int cifs_closedir(struct inode *inode, struct file *file) + server = tcon->ses->server; + + cifs_dbg(FYI, "Freeing private data in close dir\n"); +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&cfile->file_info_lock); + if (server->ops->dir_needs_close(cfile)) { + cfile->invalidHandle = true; +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&cfile->file_info_lock); + if (server->ops->close_dir) + rc = server->ops->close_dir(xid, tcon, &cfile->fid); + else +@@ -784,7 +791,7 @@ int cifs_closedir(struct inode *inode, struct file *file) + /* not much we can do if it fails anyway, ignore rc */ + rc = 0; + } else +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&cfile->file_info_lock); + + buf = cfile->srch_inf.ntwrk_buf_start; + if (buf) { +@@ -1728,12 +1735,13 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, + { + struct cifsFileInfo *open_file = NULL; + struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); ++ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); + + /* only filter by fsuid on multiuser mounts */ + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) + fsuid_only = false; + +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + /* we could simply get the first_list_entry since write-only entries + are always at the end of the list but since the first entry might + have a close pending, we go through the whole list */ +@@ -1744,8 +1752,8 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, + if (!open_file->invalidHandle) { + /* found a good file */ + /* lock it so it will not be closed on us */ +- cifsFileInfo_get_locked(open_file); +- spin_unlock(&cifs_file_list_lock); ++ cifsFileInfo_get(open_file); ++ spin_unlock(&tcon->open_file_lock); + return open_file; + } /* else might as well continue, and look for + another, or simply have the caller reopen it +@@ -1753,7 +1761,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, + } else /* write only file */ + break; /* write only files are last so must be done */ + } +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + return NULL; + } + +@@ -1762,6 +1770,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, + { + struct cifsFileInfo *open_file, *inv_file = NULL; + struct cifs_sb_info *cifs_sb; ++ struct cifs_tcon *tcon; + bool any_available = false; + int rc; + unsigned int refind = 0; +@@ -1777,15 +1786,16 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, + } + + cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); ++ tcon = cifs_sb_master_tcon(cifs_sb); + + /* only filter by fsuid on multiuser mounts */ + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) + fsuid_only = false; + +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + refind_writable: + if (refind > MAX_REOPEN_ATT) { +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + return NULL; + } + list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { +@@ -1796,8 +1806,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, + if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { + if (!open_file->invalidHandle) { + /* found a good writable file */ +- cifsFileInfo_get_locked(open_file); +- spin_unlock(&cifs_file_list_lock); ++ cifsFileInfo_get(open_file); ++ spin_unlock(&tcon->open_file_lock); + return open_file; + } else { + if (!inv_file) +@@ -1813,24 +1823,24 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, + + if (inv_file) { + any_available = false; +- cifsFileInfo_get_locked(inv_file); ++ cifsFileInfo_get(inv_file); + } + +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + + if (inv_file) { + rc = cifs_reopen_file(inv_file, false); + if (!rc) + return inv_file; + else { +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + list_move_tail(&inv_file->flist, + &cifs_inode->openFileList); +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + cifsFileInfo_put(inv_file); +- spin_lock(&cifs_file_list_lock); + ++refind; + inv_file = NULL; ++ spin_lock(&tcon->open_file_lock); + goto refind_writable; + } + } +@@ -3618,15 +3628,17 @@ static int cifs_readpage(struct file *file, struct page *page) + static int is_inode_writable(struct cifsInodeInfo *cifs_inode) + { + struct cifsFileInfo *open_file; ++ struct cifs_tcon *tcon = ++ cifs_sb_master_tcon(CIFS_SB(cifs_inode->vfs_inode.i_sb)); + +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { + if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + return 1; + } + } +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + return 0; + } + +diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c +index 813fe13..c672915 100644 +--- a/fs/cifs/misc.c ++++ b/fs/cifs/misc.c +@@ -120,6 +120,7 @@ tconInfoAlloc(void) + ++ret_buf->tc_count; + INIT_LIST_HEAD(&ret_buf->openFileList); + INIT_LIST_HEAD(&ret_buf->tcon_list); ++ spin_lock_init(&ret_buf->open_file_lock); + #ifdef CONFIG_CIFS_STATS + spin_lock_init(&ret_buf->stat_lock); + #endif +@@ -465,7 +466,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) + continue; + + cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks); +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + list_for_each(tmp2, &tcon->openFileList) { + netfile = list_entry(tmp2, struct cifsFileInfo, + tlist); +@@ -495,11 +496,11 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) + &netfile->oplock_break); + netfile->oplock_break_cancelled = false; + +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + spin_unlock(&cifs_tcp_ses_lock); + return true; + } +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + spin_unlock(&cifs_tcp_ses_lock); + cifs_dbg(FYI, "No matching file for oplock break\n"); + return true; +@@ -613,9 +614,9 @@ backup_cred(struct cifs_sb_info *cifs_sb) + void + cifs_del_pending_open(struct cifs_pending_open *open) + { +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tlink_tcon(open->tlink)->open_file_lock); + list_del(&open->olist); +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tlink_tcon(open->tlink)->open_file_lock); + } + + void +@@ -635,7 +636,7 @@ void + cifs_add_pending_open(struct cifs_fid *fid, struct tcon_link *tlink, + struct cifs_pending_open *open) + { +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tlink_tcon(tlink)->open_file_lock); + cifs_add_pending_open_locked(fid, tlink, open); +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tlink_tcon(open->tlink)->open_file_lock); + } +diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c +index 65cf85d..8f6a2a5 100644 +--- a/fs/cifs/readdir.c ++++ b/fs/cifs/readdir.c +@@ -597,14 +597,14 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos, + is_dir_changed(file)) || (index_to_find < first_entry_in_buffer)) { + /* close and restart search */ + cifs_dbg(FYI, "search backing up - close and restart search\n"); +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&cfile->file_info_lock); + if (server->ops->dir_needs_close(cfile)) { + cfile->invalidHandle = true; +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&cfile->file_info_lock); + if (server->ops->close_dir) + server->ops->close_dir(xid, tcon, &cfile->fid); + } else +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&cfile->file_info_lock); + if (cfile->srch_inf.ntwrk_buf_start) { + cifs_dbg(FYI, "freeing SMB ff cache buf on search rewind\n"); + if (cfile->srch_inf.smallBuf) +diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h +index 0ffa180..238759c 100644 +--- a/fs/cifs/smb2glob.h ++++ b/fs/cifs/smb2glob.h +@@ -61,4 +61,14 @@ + /* Maximum buffer size value we can send with 1 credit */ + #define SMB2_MAX_BUFFER_SIZE 65536 + ++/* ++ * Maximum number of credits to keep available. ++ * This value is chosen somewhat arbitrarily. The Windows client ++ * defaults to 128 credits, the Windows server allows clients up to ++ * 512 credits, and the NetApp server does not limit clients at all. ++ * Choose a high enough value such that the client shouldn't limit ++ * performance. ++ */ ++#define SMB2_MAX_CREDITS_AVAILABLE 32000 ++ + #endif /* _SMB2_GLOB_H */ +diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c +index 4f0231e..1238cd3 100644 +--- a/fs/cifs/smb2inode.c ++++ b/fs/cifs/smb2inode.c +@@ -266,9 +266,15 @@ smb2_set_file_info(struct inode *inode, const char *full_path, + struct tcon_link *tlink; + int rc; + ++ if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) && ++ (buf->LastWriteTime == 0) && (buf->ChangeTime) && ++ (buf->Attributes == 0)) ++ return 0; /* would be a no op, no sense sending this */ ++ + tlink = cifs_sb_tlink(cifs_sb); + if (IS_ERR(tlink)) + return PTR_ERR(tlink); ++ + rc = smb2_open_op_close(xid, tlink_tcon(tlink), cifs_sb, full_path, + FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, buf, + SMB2_OP_SET_INFO); +diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c +index 389fb9f..3d38348 100644 +--- a/fs/cifs/smb2misc.c ++++ b/fs/cifs/smb2misc.c +@@ -549,19 +549,19 @@ smb2_is_valid_lease_break(char *buffer) + list_for_each(tmp1, &server->smb_ses_list) { + ses = list_entry(tmp1, struct cifs_ses, smb_ses_list); + +- spin_lock(&cifs_file_list_lock); + list_for_each(tmp2, &ses->tcon_list) { + tcon = list_entry(tmp2, struct cifs_tcon, + tcon_list); ++ spin_lock(&tcon->open_file_lock); + cifs_stats_inc( + &tcon->stats.cifs_stats.num_oplock_brks); + if (smb2_tcon_has_lease(tcon, rsp, lw)) { +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + spin_unlock(&cifs_tcp_ses_lock); + return true; + } ++ spin_unlock(&tcon->open_file_lock); + } +- spin_unlock(&cifs_file_list_lock); + } + } + spin_unlock(&cifs_tcp_ses_lock); +@@ -603,7 +603,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) + tcon = list_entry(tmp1, struct cifs_tcon, tcon_list); + + cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks); +- spin_lock(&cifs_file_list_lock); ++ spin_lock(&tcon->open_file_lock); + list_for_each(tmp2, &tcon->openFileList) { + cfile = list_entry(tmp2, struct cifsFileInfo, + tlist); +@@ -615,7 +615,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) + + cifs_dbg(FYI, "file id match, oplock break\n"); + cinode = CIFS_I(d_inode(cfile->dentry)); +- ++ spin_lock(&cfile->file_info_lock); + if (!CIFS_CACHE_WRITE(cinode) && + rsp->OplockLevel == SMB2_OPLOCK_LEVEL_NONE) + cfile->oplock_break_cancelled = true; +@@ -637,14 +637,14 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) + clear_bit( + CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, + &cinode->flags); +- ++ spin_unlock(&cfile->file_info_lock); + queue_work(cifsiod_wq, &cfile->oplock_break); + +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + spin_unlock(&cifs_tcp_ses_lock); + return true; + } +- spin_unlock(&cifs_file_list_lock); ++ spin_unlock(&tcon->open_file_lock); + spin_unlock(&cifs_tcp_ses_lock); + cifs_dbg(FYI, "No matching file for oplock break\n"); + return true; +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index d203c03..0e73cef 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -287,7 +287,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon) + cifs_dbg(FYI, "Link Speed %lld\n", + le64_to_cpu(out_buf->LinkSpeed)); + } +- ++ kfree(out_buf); + return rc; + } + #endif /* STATS2 */ +@@ -541,6 +541,7 @@ smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock) + server->ops->set_oplock_level(cinode, oplock, fid->epoch, + &fid->purge_cache); + cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode); ++ memcpy(cfile->fid.create_guid, fid->create_guid, 16); + } + + static void +@@ -699,6 +700,7 @@ smb2_clone_range(const unsigned int xid, + + cchunk_out: + kfree(pcchunk); ++ kfree(retbuf); + return rc; + } + +@@ -823,7 +825,6 @@ smb2_duplicate_extents(const unsigned int xid, + { + int rc; + unsigned int ret_data_len; +- char *retbuf = NULL; + struct duplicate_extents_to_file dup_ext_buf; + struct cifs_tcon *tcon = tlink_tcon(trgtfile->tlink); + +@@ -849,7 +850,7 @@ smb2_duplicate_extents(const unsigned int xid, + FSCTL_DUPLICATE_EXTENTS_TO_FILE, + true /* is_fsctl */, (char *)&dup_ext_buf, + sizeof(struct duplicate_extents_to_file), +- (char **)&retbuf, ++ NULL, + &ret_data_len); + + if (ret_data_len > 0) +@@ -872,7 +873,6 @@ smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon, + struct cifsFileInfo *cfile) + { + struct fsctl_set_integrity_information_req integr_info; +- char *retbuf = NULL; + unsigned int ret_data_len; + + integr_info.ChecksumAlgorithm = cpu_to_le16(CHECKSUM_TYPE_UNCHANGED); +@@ -884,7 +884,7 @@ smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon, + FSCTL_SET_INTEGRITY_INFORMATION, + true /* is_fsctl */, (char *)&integr_info, + sizeof(struct fsctl_set_integrity_information_req), +- (char **)&retbuf, ++ NULL, + &ret_data_len); + + } +@@ -1041,7 +1041,7 @@ smb2_set_lease_key(struct inode *inode, struct cifs_fid *fid) + static void + smb2_new_lease_key(struct cifs_fid *fid) + { +- get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE); ++ generate_random_uuid(fid->lease_key); + } + + #define SMB2_SYMLINK_STRUCT_SIZE \ +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 29e06db..3eec96c 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -100,7 +100,21 @@ smb2_hdr_assemble(struct smb2_hdr *hdr, __le16 smb2_cmd /* command */ , + hdr->ProtocolId = SMB2_PROTO_NUMBER; + hdr->StructureSize = cpu_to_le16(64); + hdr->Command = smb2_cmd; +- hdr->CreditRequest = cpu_to_le16(2); /* BB make this dynamic */ ++ if (tcon && tcon->ses && tcon->ses->server) { ++ struct TCP_Server_Info *server = tcon->ses->server; ++ ++ spin_lock(&server->req_lock); ++ /* Request up to 2 credits but don't go over the limit. */ ++ if (server->credits >= SMB2_MAX_CREDITS_AVAILABLE) ++ hdr->CreditRequest = cpu_to_le16(0); ++ else ++ hdr->CreditRequest = cpu_to_le16( ++ min_t(int, SMB2_MAX_CREDITS_AVAILABLE - ++ server->credits, 2)); ++ spin_unlock(&server->req_lock); ++ } else { ++ hdr->CreditRequest = cpu_to_le16(2); ++ } + hdr->ProcessId = cpu_to_le32((__u16)current->tgid); + + if (!tcon) +@@ -590,6 +604,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses, + char *security_blob = NULL; + unsigned char *ntlmssp_blob = NULL; + bool use_spnego = false; /* else use raw ntlmssp */ ++ u64 previous_session = ses->Suid; + + cifs_dbg(FYI, "Session Setup\n"); + +@@ -627,6 +642,10 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses, + return rc; + + req->hdr.SessionId = 0; /* First session, not a reauthenticate */ ++ ++ /* if reconnect, we need to send previous sess id, otherwise it is 0 */ ++ req->PreviousSessionId = previous_session; ++ + req->Flags = 0; /* MBZ */ + /* to enable echos and oplocks */ + req->hdr.CreditRequest = cpu_to_le16(3); +@@ -1164,7 +1183,7 @@ create_durable_v2_buf(struct cifs_fid *pfid) + + buf->dcontext.Timeout = 0; /* Should this be configurable by workload */ + buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT); +- get_random_bytes(buf->dcontext.CreateGuid, 16); ++ generate_random_uuid(buf->dcontext.CreateGuid); + memcpy(pfid->create_guid, buf->dcontext.CreateGuid, 16); + + /* SMB2_CREATE_DURABLE_HANDLE_REQUEST is "DH2Q" */ +@@ -2057,6 +2076,7 @@ smb2_async_readv(struct cifs_readdata *rdata) + if (rdata->credits) { + buf->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes, + SMB2_MAX_BUFFER_SIZE)); ++ buf->CreditRequest = buf->CreditCharge; + spin_lock(&server->req_lock); + server->credits += rdata->credits - + le16_to_cpu(buf->CreditCharge); +@@ -2243,6 +2263,7 @@ smb2_async_writev(struct cifs_writedata *wdata, + if (wdata->credits) { + req->hdr.CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes, + SMB2_MAX_BUFFER_SIZE)); ++ req->hdr.CreditRequest = req->hdr.CreditCharge; + spin_lock(&server->req_lock); + server->credits += wdata->credits - + le16_to_cpu(req->hdr.CreditCharge); +diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h +index ff88d9f..fd3709e 100644 +--- a/fs/cifs/smb2pdu.h ++++ b/fs/cifs/smb2pdu.h +@@ -276,7 +276,7 @@ struct smb2_sess_setup_req { + __le32 Channel; + __le16 SecurityBufferOffset; + __le16 SecurityBufferLength; +- __le64 PreviousSessionId; ++ __u64 PreviousSessionId; + __u8 Buffer[1]; /* variable length GSS security buffer */ + } __packed; + +diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c +index c502c11..55d64fb 100644 +--- a/fs/crypto/crypto.c ++++ b/fs/crypto/crypto.c +@@ -152,7 +152,10 @@ static int do_page_crypto(struct inode *inode, + struct page *src_page, struct page *dest_page, + gfp_t gfp_flags) + { +- u8 xts_tweak[FS_XTS_TWEAK_SIZE]; ++ struct { ++ __le64 index; ++ u8 padding[FS_XTS_TWEAK_SIZE - sizeof(__le64)]; ++ } xts_tweak; + struct skcipher_request *req = NULL; + DECLARE_FS_COMPLETION_RESULT(ecr); + struct scatterlist dst, src; +@@ -172,17 +175,15 @@ static int do_page_crypto(struct inode *inode, + req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, + fscrypt_complete, &ecr); + +- BUILD_BUG_ON(FS_XTS_TWEAK_SIZE < sizeof(index)); +- memcpy(xts_tweak, &index, sizeof(index)); +- memset(&xts_tweak[sizeof(index)], 0, +- FS_XTS_TWEAK_SIZE - sizeof(index)); ++ BUILD_BUG_ON(sizeof(xts_tweak) != FS_XTS_TWEAK_SIZE); ++ xts_tweak.index = cpu_to_le64(index); ++ memset(xts_tweak.padding, 0, sizeof(xts_tweak.padding)); + + sg_init_table(&dst, 1); + sg_set_page(&dst, dest_page, PAGE_SIZE, 0); + sg_init_table(&src, 1); + sg_set_page(&src, src_page, PAGE_SIZE, 0); +- skcipher_request_set_crypt(req, &src, &dst, PAGE_SIZE, +- xts_tweak); ++ skcipher_request_set_crypt(req, &src, &dst, PAGE_SIZE, &xts_tweak); + if (rw == FS_DECRYPT) + res = crypto_skcipher_decrypt(req); + else +diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c +index ed115ac..6865663 100644 +--- a/fs/crypto/policy.c ++++ b/fs/crypto/policy.c +@@ -109,6 +109,8 @@ int fscrypt_process_policy(struct file *filp, + if (ret) + return ret; + ++ inode_lock(inode); ++ + if (!inode_has_encryption_context(inode)) { + if (!S_ISDIR(inode->i_mode)) + ret = -EINVAL; +@@ -127,6 +129,8 @@ int fscrypt_process_policy(struct file *filp, + ret = -EINVAL; + } + ++ inode_unlock(inode); ++ + mnt_drop_write_file(filp); + return ret; + } +diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c +index 73bcfd4..42145be 100644 +--- a/fs/ext4/sysfs.c ++++ b/fs/ext4/sysfs.c +@@ -223,14 +223,18 @@ static struct attribute *ext4_attrs[] = { + EXT4_ATTR_FEATURE(lazy_itable_init); + EXT4_ATTR_FEATURE(batched_discard); + EXT4_ATTR_FEATURE(meta_bg_resize); ++#ifdef CONFIG_EXT4_FS_ENCRYPTION + EXT4_ATTR_FEATURE(encryption); ++#endif + EXT4_ATTR_FEATURE(metadata_csum_seed); + + static struct attribute *ext4_feat_attrs[] = { + ATTR_LIST(lazy_itable_init), + ATTR_LIST(batched_discard), + ATTR_LIST(meta_bg_resize), ++#ifdef CONFIG_EXT4_FS_ENCRYPTION + ATTR_LIST(encryption), ++#endif + ATTR_LIST(metadata_csum_seed), + NULL, + }; +diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c +index ad0c745..871c8b3 100644 +--- a/fs/isofs/inode.c ++++ b/fs/isofs/inode.c +@@ -687,6 +687,11 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) + pri_bh = NULL; + + root_found: ++ /* We don't support read-write mounts */ ++ if (!(s->s_flags & MS_RDONLY)) { ++ error = -EACCES; ++ goto out_freebh; ++ } + + if (joliet_level && (pri == NULL || !opt.rock)) { + /* This is the case of Joliet with the norock mount flag. +@@ -1501,9 +1506,6 @@ struct inode *__isofs_iget(struct super_block *sb, + static struct dentry *isofs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) + { +- /* We don't support read-write mounts */ +- if (!(flags & MS_RDONLY)) +- return ERR_PTR(-EACCES); + return mount_bdev(fs_type, flags, dev_name, data, isofs_fill_super); + } + +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index 3d8246a..e165266 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -1149,6 +1149,7 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh) + JBUFFER_TRACE(jh, "file as BJ_Reserved"); + spin_lock(&journal->j_list_lock); + __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved); ++ spin_unlock(&journal->j_list_lock); + } else if (jh->b_transaction == journal->j_committing_transaction) { + /* first access by this transaction */ + jh->b_modified = 0; +@@ -1156,8 +1157,8 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh) + JBUFFER_TRACE(jh, "set next transaction"); + spin_lock(&journal->j_list_lock); + jh->b_next_transaction = transaction; ++ spin_unlock(&journal->j_list_lock); + } +- spin_unlock(&journal->j_list_lock); + jbd_unlock_bh_state(bh); + + /* +diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c +index 2178476..2905479 100644 +--- a/fs/nfs/blocklayout/blocklayout.c ++++ b/fs/nfs/blocklayout/blocklayout.c +@@ -344,9 +344,10 @@ static void bl_write_cleanup(struct work_struct *work) + u64 start = hdr->args.offset & (loff_t)PAGE_MASK; + u64 end = (hdr->args.offset + hdr->args.count + + PAGE_SIZE - 1) & (loff_t)PAGE_MASK; ++ u64 lwb = hdr->args.offset + hdr->args.count; + + ext_tree_mark_written(bl, start >> SECTOR_SHIFT, +- (end - start) >> SECTOR_SHIFT, end); ++ (end - start) >> SECTOR_SHIFT, lwb); + } + + pnfs_ld_write_done(hdr); +diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c +index 322c258..b9c6542 100644 +--- a/fs/nfs/delegation.c ++++ b/fs/nfs/delegation.c +@@ -41,6 +41,17 @@ void nfs_mark_delegation_referenced(struct nfs_delegation *delegation) + set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags); + } + ++static bool ++nfs4_is_valid_delegation(const struct nfs_delegation *delegation, ++ fmode_t flags) ++{ ++ if (delegation != NULL && (delegation->type & flags) == flags && ++ !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) && ++ !test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) ++ return true; ++ return false; ++} ++ + static int + nfs4_do_check_delegation(struct inode *inode, fmode_t flags, bool mark) + { +@@ -50,8 +61,7 @@ nfs4_do_check_delegation(struct inode *inode, fmode_t flags, bool mark) + flags &= FMODE_READ|FMODE_WRITE; + rcu_read_lock(); + delegation = rcu_dereference(NFS_I(inode)->delegation); +- if (delegation != NULL && (delegation->type & flags) == flags && +- !test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) { ++ if (nfs4_is_valid_delegation(delegation, flags)) { + if (mark) + nfs_mark_delegation_referenced(delegation); + ret = 1; +@@ -893,7 +903,7 @@ bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags, + flags &= FMODE_READ|FMODE_WRITE; + rcu_read_lock(); + delegation = rcu_dereference(nfsi->delegation); +- ret = (delegation != NULL && (delegation->type & flags) == flags); ++ ret = nfs4_is_valid_delegation(delegation, flags); + if (ret) { + nfs4_stateid_copy(dst, &delegation->stateid); + nfs_mark_delegation_referenced(delegation); +diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c +index 177fefb..6bc5a68 100644 +--- a/fs/nfs/dir.c ++++ b/fs/nfs/dir.c +@@ -435,11 +435,11 @@ int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry) + return 0; + + nfsi = NFS_I(inode); +- if (entry->fattr->fileid == nfsi->fileid) +- return 1; +- if (nfs_compare_fh(entry->fh, &nfsi->fh) == 0) +- return 1; +- return 0; ++ if (entry->fattr->fileid != nfsi->fileid) ++ return 0; ++ if (entry->fh->size && nfs_compare_fh(entry->fh, &nfsi->fh) != 0) ++ return 0; ++ return 1; + } + + static +@@ -517,6 +517,8 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) + &entry->fattr->fsid)) + goto out; + if (nfs_same_file(dentry, entry)) { ++ if (!entry->fh->size) ++ goto out; + nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); + status = nfs_refresh_inode(d_inode(dentry), entry->fattr); + if (!status) +@@ -529,6 +531,10 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) + goto again; + } + } ++ if (!entry->fh->size) { ++ d_lookup_done(dentry); ++ goto out; ++ } + + inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr, entry->label); + alias = d_splice_alias(inode, dentry); +diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c +index 64b43b4..6085019 100644 +--- a/fs/nfs/nfs42proc.c ++++ b/fs/nfs/nfs42proc.c +@@ -443,6 +443,7 @@ int nfs42_proc_layoutstats_generic(struct nfs_server *server, + task = rpc_run_task(&task_setup); + if (IS_ERR(task)) + return PTR_ERR(task); ++ rpc_put_task(task); + return 0; + } + +diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c +index cada00a..8353f33f 100644 +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -1498,6 +1498,9 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs + __func__, status); + case -ENOENT: + case -ENOMEM: ++ case -EACCES: ++ case -EROFS: ++ case -EIO: + case -ESTALE: + /* Open state on this file cannot be recovered */ + nfs4_state_mark_recovery_failed(state, status); +diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c +index 45007ac..a2b65fc 100644 +--- a/fs/nfsd/nfssvc.c ++++ b/fs/nfsd/nfssvc.c +@@ -366,14 +366,21 @@ static struct notifier_block nfsd_inet6addr_notifier = { + }; + #endif + ++/* Only used under nfsd_mutex, so this atomic may be overkill: */ ++static atomic_t nfsd_notifier_refcount = ATOMIC_INIT(0); ++ + static void nfsd_last_thread(struct svc_serv *serv, struct net *net) + { + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + +- unregister_inetaddr_notifier(&nfsd_inetaddr_notifier); ++ /* check if the notifier still has clients */ ++ if (atomic_dec_return(&nfsd_notifier_refcount) == 0) { ++ unregister_inetaddr_notifier(&nfsd_inetaddr_notifier); + #if IS_ENABLED(CONFIG_IPV6) +- unregister_inet6addr_notifier(&nfsd_inet6addr_notifier); ++ unregister_inet6addr_notifier(&nfsd_inet6addr_notifier); + #endif ++ } ++ + /* + * write_ports can create the server without actually starting + * any threads--if we get shut down before any threads are +@@ -488,10 +495,13 @@ int nfsd_create_serv(struct net *net) + } + + set_max_drc(); +- register_inetaddr_notifier(&nfsd_inetaddr_notifier); ++ /* check if the notifier is already set */ ++ if (atomic_inc_return(&nfsd_notifier_refcount) == 1) { ++ register_inetaddr_notifier(&nfsd_inetaddr_notifier); + #if IS_ENABLED(CONFIG_IPV6) +- register_inet6addr_notifier(&nfsd_inet6addr_notifier); ++ register_inet6addr_notifier(&nfsd_inet6addr_notifier); + #endif ++ } + do_gettimeofday(&nn->nfssvc_boot); /* record boot time */ + return 0; + } +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index 43fdc27..abadbc3 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -57,6 +57,7 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new) + ssize_t list_size, size, value_size = 0; + char *buf, *name, *value = NULL; + int uninitialized_var(error); ++ size_t slen; + + if (!old->d_inode->i_op->getxattr || + !new->d_inode->i_op->getxattr) +@@ -79,7 +80,16 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new) + goto out; + } + +- for (name = buf; name < (buf + list_size); name += strlen(name) + 1) { ++ for (name = buf; list_size; name += slen) { ++ slen = strnlen(name, list_size) + 1; ++ ++ /* underlying fs providing us with an broken xattr list? */ ++ if (WARN_ON(slen > list_size)) { ++ error = -EIO; ++ break; ++ } ++ list_size -= slen; ++ + if (ovl_is_private_xattr(name)) + continue; + retry: +diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c +index 1560fdc..74e6964 100644 +--- a/fs/overlayfs/dir.c ++++ b/fs/overlayfs/dir.c +@@ -14,6 +14,7 @@ + #include <linux/cred.h> + #include <linux/posix_acl.h> + #include <linux/posix_acl_xattr.h> ++#include <linux/atomic.h> + #include "overlayfs.h" + + void ovl_cleanup(struct inode *wdir, struct dentry *wdentry) +@@ -37,8 +38,10 @@ struct dentry *ovl_lookup_temp(struct dentry *workdir, struct dentry *dentry) + { + struct dentry *temp; + char name[20]; ++ static atomic_t temp_id = ATOMIC_INIT(0); + +- snprintf(name, sizeof(name), "#%lx", (unsigned long) dentry); ++ /* counter is allowed to wrap, since temp dentries are ephemeral */ ++ snprintf(name, sizeof(name), "#%x", atomic_inc_return(&temp_id)); + + temp = lookup_one_len(name, workdir, strlen(name)); + if (!IS_ERR(temp) && temp->d_inode) { +diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c +index 7a034d6..2340262 100644 +--- a/fs/pstore/ram.c ++++ b/fs/pstore/ram.c +@@ -377,13 +377,14 @@ static void ramoops_free_przs(struct ramoops_context *cxt) + { + int i; + +- cxt->max_dump_cnt = 0; + if (!cxt->przs) + return; + +- for (i = 0; !IS_ERR_OR_NULL(cxt->przs[i]); i++) ++ for (i = 0; i < cxt->max_dump_cnt; i++) + persistent_ram_free(cxt->przs[i]); ++ + kfree(cxt->przs); ++ cxt->max_dump_cnt = 0; + } + + static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt, +@@ -408,7 +409,7 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt, + GFP_KERNEL); + if (!cxt->przs) { + dev_err(dev, "failed to initialize a prz array for dumps\n"); +- goto fail_prz; ++ goto fail_mem; + } + + for (i = 0; i < cxt->max_dump_cnt; i++) { +@@ -419,6 +420,11 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt, + err = PTR_ERR(cxt->przs[i]); + dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n", + cxt->record_size, (unsigned long long)*paddr, err); ++ ++ while (i > 0) { ++ i--; ++ persistent_ram_free(cxt->przs[i]); ++ } + goto fail_prz; + } + *paddr += cxt->record_size; +@@ -426,7 +432,9 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt, + + return 0; + fail_prz: +- ramoops_free_przs(cxt); ++ kfree(cxt->przs); ++fail_mem: ++ cxt->max_dump_cnt = 0; + return err; + } + +@@ -659,7 +667,6 @@ static int ramoops_remove(struct platform_device *pdev) + struct ramoops_context *cxt = &oops_cxt; + + pstore_unregister(&cxt->pstore); +- cxt->max_dump_cnt = 0; + + kfree(cxt->pstore.buf); + cxt->pstore.bufsize = 0; +diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c +index 76c3f80..364d2df 100644 +--- a/fs/pstore/ram_core.c ++++ b/fs/pstore/ram_core.c +@@ -47,43 +47,10 @@ static inline size_t buffer_start(struct persistent_ram_zone *prz) + return atomic_read(&prz->buffer->start); + } + +-/* increase and wrap the start pointer, returning the old value */ +-static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a) +-{ +- int old; +- int new; +- +- do { +- old = atomic_read(&prz->buffer->start); +- new = old + a; +- while (unlikely(new >= prz->buffer_size)) +- new -= prz->buffer_size; +- } while (atomic_cmpxchg(&prz->buffer->start, old, new) != old); +- +- return old; +-} +- +-/* increase the size counter until it hits the max size */ +-static void buffer_size_add_atomic(struct persistent_ram_zone *prz, size_t a) +-{ +- size_t old; +- size_t new; +- +- if (atomic_read(&prz->buffer->size) == prz->buffer_size) +- return; +- +- do { +- old = atomic_read(&prz->buffer->size); +- new = old + a; +- if (new > prz->buffer_size) +- new = prz->buffer_size; +- } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old); +-} +- + static DEFINE_RAW_SPINLOCK(buffer_lock); + + /* increase and wrap the start pointer, returning the old value */ +-static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a) ++static size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a) + { + int old; + int new; +@@ -103,7 +70,7 @@ static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a) + } + + /* increase the size counter until it hits the max size */ +-static void buffer_size_add_locked(struct persistent_ram_zone *prz, size_t a) ++static void buffer_size_add(struct persistent_ram_zone *prz, size_t a) + { + size_t old; + size_t new; +@@ -124,9 +91,6 @@ static void buffer_size_add_locked(struct persistent_ram_zone *prz, size_t a) + raw_spin_unlock_irqrestore(&buffer_lock, flags); + } + +-static size_t (*buffer_start_add)(struct persistent_ram_zone *, size_t) = buffer_start_add_atomic; +-static void (*buffer_size_add)(struct persistent_ram_zone *, size_t) = buffer_size_add_atomic; +- + static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz, + uint8_t *data, size_t len, uint8_t *ecc) + { +@@ -299,7 +263,7 @@ static void notrace persistent_ram_update(struct persistent_ram_zone *prz, + const void *s, unsigned int start, unsigned int count) + { + struct persistent_ram_buffer *buffer = prz->buffer; +- memcpy(buffer->data + start, s, count); ++ memcpy_toio(buffer->data + start, s, count); + persistent_ram_update_ecc(prz, start, count); + } + +@@ -322,8 +286,8 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) + } + + prz->old_log_size = size; +- memcpy(prz->old_log, &buffer->data[start], size - start); +- memcpy(prz->old_log + size - start, &buffer->data[0], start); ++ memcpy_fromio(prz->old_log, &buffer->data[start], size - start); ++ memcpy_fromio(prz->old_log + size - start, &buffer->data[0], start); + } + + int notrace persistent_ram_write(struct persistent_ram_zone *prz, +@@ -426,9 +390,6 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size, + return NULL; + } + +- buffer_start_add = buffer_start_add_locked; +- buffer_size_add = buffer_size_add_locked; +- + if (memtype) + va = ioremap(start, size); + else +diff --git a/fs/super.c b/fs/super.c +index c2ff475..47d11e0 100644 +--- a/fs/super.c ++++ b/fs/super.c +@@ -1379,8 +1379,8 @@ int freeze_super(struct super_block *sb) + } + } + /* +- * This is just for debugging purposes so that fs can warn if it +- * sees write activity when frozen is set to SB_FREEZE_COMPLETE. ++ * For debugging purposes so that fs can warn if it sees write activity ++ * when frozen is set to SB_FREEZE_COMPLETE, and for thaw_super(). + */ + sb->s_writers.frozen = SB_FREEZE_COMPLETE; + up_write(&sb->s_umount); +@@ -1399,7 +1399,7 @@ int thaw_super(struct super_block *sb) + int error; + + down_write(&sb->s_umount); +- if (sb->s_writers.frozen == SB_UNFROZEN) { ++ if (sb->s_writers.frozen != SB_FREEZE_COMPLETE) { + up_write(&sb->s_umount); + return -EINVAL; + } +diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c +index 11a0041..c9ee6f6 100644 +--- a/fs/ubifs/xattr.c ++++ b/fs/ubifs/xattr.c +@@ -172,6 +172,7 @@ static int create_xattr(struct ubifs_info *c, struct inode *host, + host_ui->xattr_cnt -= 1; + host_ui->xattr_size -= CALC_DENT_SIZE(nm->len); + host_ui->xattr_size -= CALC_XATTR_BYTES(size); ++ host_ui->xattr_names -= nm->len; + mutex_unlock(&host_ui->ui_mutex); + out_free: + make_bad_inode(inode); +@@ -476,6 +477,7 @@ static int remove_xattr(struct ubifs_info *c, struct inode *host, + host_ui->xattr_cnt += 1; + host_ui->xattr_size += CALC_DENT_SIZE(nm->len); + host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len); ++ host_ui->xattr_names += nm->len; + mutex_unlock(&host_ui->ui_mutex); + ubifs_release_budget(c, &req); + make_bad_inode(inode); +diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h +index 2905033..da59fd9 100644 +--- a/include/dt-bindings/clock/imx6qdl-clock.h ++++ b/include/dt-bindings/clock/imx6qdl-clock.h +@@ -269,6 +269,8 @@ + #define IMX6QDL_CLK_PRG0_APB 256 + #define IMX6QDL_CLK_PRG1_APB 257 + #define IMX6QDL_CLK_PRE_AXI 258 +-#define IMX6QDL_CLK_END 259 ++#define IMX6QDL_CLK_MLB_SEL 259 ++#define IMX6QDL_CLK_MLB_PODF 260 ++#define IMX6QDL_CLK_END 261 + + #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */ +diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h +index 631ba33b..32dc0cbd 100644 +--- a/include/linux/cpufreq.h ++++ b/include/linux/cpufreq.h +@@ -639,19 +639,19 @@ static inline int cpufreq_table_find_index_al(struct cpufreq_policy *policy, + unsigned int target_freq) + { + struct cpufreq_frequency_table *table = policy->freq_table; ++ struct cpufreq_frequency_table *pos, *best = table - 1; + unsigned int freq; +- int i, best = -1; + +- for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { +- freq = table[i].frequency; ++ cpufreq_for_each_valid_entry(pos, table) { ++ freq = pos->frequency; + + if (freq >= target_freq) +- return i; ++ return pos - table; + +- best = i; ++ best = pos; + } + +- return best; ++ return best - table; + } + + /* Find lowest freq at or above target in a table in descending order */ +@@ -659,28 +659,28 @@ static inline int cpufreq_table_find_index_dl(struct cpufreq_policy *policy, + unsigned int target_freq) + { + struct cpufreq_frequency_table *table = policy->freq_table; ++ struct cpufreq_frequency_table *pos, *best = table - 1; + unsigned int freq; +- int i, best = -1; + +- for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { +- freq = table[i].frequency; ++ cpufreq_for_each_valid_entry(pos, table) { ++ freq = pos->frequency; + + if (freq == target_freq) +- return i; ++ return pos - table; + + if (freq > target_freq) { +- best = i; ++ best = pos; + continue; + } + + /* No freq found above target_freq */ +- if (best == -1) +- return i; ++ if (best == table - 1) ++ return pos - table; + +- return best; ++ return best - table; + } + +- return best; ++ return best - table; + } + + /* Works only on sorted freq-tables */ +@@ -700,28 +700,28 @@ static inline int cpufreq_table_find_index_ah(struct cpufreq_policy *policy, + unsigned int target_freq) + { + struct cpufreq_frequency_table *table = policy->freq_table; ++ struct cpufreq_frequency_table *pos, *best = table - 1; + unsigned int freq; +- int i, best = -1; + +- for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { +- freq = table[i].frequency; ++ cpufreq_for_each_valid_entry(pos, table) { ++ freq = pos->frequency; + + if (freq == target_freq) +- return i; ++ return pos - table; + + if (freq < target_freq) { +- best = i; ++ best = pos; + continue; + } + + /* No freq found below target_freq */ +- if (best == -1) +- return i; ++ if (best == table - 1) ++ return pos - table; + +- return best; ++ return best - table; + } + +- return best; ++ return best - table; + } + + /* Find highest freq at or below target in a table in descending order */ +@@ -729,19 +729,19 @@ static inline int cpufreq_table_find_index_dh(struct cpufreq_policy *policy, + unsigned int target_freq) + { + struct cpufreq_frequency_table *table = policy->freq_table; ++ struct cpufreq_frequency_table *pos, *best = table - 1; + unsigned int freq; +- int i, best = -1; + +- for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { +- freq = table[i].frequency; ++ cpufreq_for_each_valid_entry(pos, table) { ++ freq = pos->frequency; + + if (freq <= target_freq) +- return i; ++ return pos - table; + +- best = i; ++ best = pos; + } + +- return best; ++ return best - table; + } + + /* Works only on sorted freq-tables */ +@@ -761,32 +761,32 @@ static inline int cpufreq_table_find_index_ac(struct cpufreq_policy *policy, + unsigned int target_freq) + { + struct cpufreq_frequency_table *table = policy->freq_table; ++ struct cpufreq_frequency_table *pos, *best = table - 1; + unsigned int freq; +- int i, best = -1; + +- for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { +- freq = table[i].frequency; ++ cpufreq_for_each_valid_entry(pos, table) { ++ freq = pos->frequency; + + if (freq == target_freq) +- return i; ++ return pos - table; + + if (freq < target_freq) { +- best = i; ++ best = pos; + continue; + } + + /* No freq found below target_freq */ +- if (best == -1) +- return i; ++ if (best == table - 1) ++ return pos - table; + + /* Choose the closest freq */ +- if (target_freq - table[best].frequency > freq - target_freq) +- return i; ++ if (target_freq - best->frequency > freq - target_freq) ++ return pos - table; + +- return best; ++ return best - table; + } + +- return best; ++ return best - table; + } + + /* Find closest freq to target in a table in descending order */ +@@ -794,32 +794,32 @@ static inline int cpufreq_table_find_index_dc(struct cpufreq_policy *policy, + unsigned int target_freq) + { + struct cpufreq_frequency_table *table = policy->freq_table; ++ struct cpufreq_frequency_table *pos, *best = table - 1; + unsigned int freq; +- int i, best = -1; + +- for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) { +- freq = table[i].frequency; ++ cpufreq_for_each_valid_entry(pos, table) { ++ freq = pos->frequency; + + if (freq == target_freq) +- return i; ++ return pos - table; + + if (freq > target_freq) { +- best = i; ++ best = pos; + continue; + } + + /* No freq found above target_freq */ +- if (best == -1) +- return i; ++ if (best == table - 1) ++ return pos - table; + + /* Choose the closest freq */ +- if (table[best].frequency - target_freq > target_freq - freq) +- return i; ++ if (best->frequency - target_freq > target_freq - freq) ++ return pos - table; + +- return best; ++ return best - table; + } + +- return best; ++ return best - table; + } + + /* Works only on sorted freq-tables */ +diff --git a/include/linux/devfreq-event.h b/include/linux/devfreq-event.h +index 0a83a1e..4db00b0 100644 +--- a/include/linux/devfreq-event.h ++++ b/include/linux/devfreq-event.h +@@ -148,11 +148,6 @@ static inline int devfreq_event_reset_event(struct devfreq_event_dev *edev) + return -EINVAL; + } + +-static inline void *devfreq_event_get_drvdata(struct devfreq_event_dev *edev) +-{ +- return ERR_PTR(-EINVAL); +-} +- + static inline struct devfreq_event_dev *devfreq_event_get_edev_by_phandle( + struct device *dev, int index) + { +diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h +index 99ac022..3a8610e 100644 +--- a/include/linux/irqchip/arm-gic-v3.h ++++ b/include/linux/irqchip/arm-gic-v3.h +@@ -290,7 +290,7 @@ + #define GITS_BASER_TYPE_SHIFT (56) + #define GITS_BASER_TYPE(r) (((r) >> GITS_BASER_TYPE_SHIFT) & 7) + #define GITS_BASER_ENTRY_SIZE_SHIFT (48) +-#define GITS_BASER_ENTRY_SIZE(r) ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0xff) + 1) ++#define GITS_BASER_ENTRY_SIZE(r) ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1) + #define GITS_BASER_SHAREABILITY_SHIFT (10) + #define GITS_BASER_InnerShareable \ + GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable) +diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h +index fb8e3b6..c211900 100644 +--- a/include/target/target_core_base.h ++++ b/include/target/target_core_base.h +@@ -177,6 +177,7 @@ enum tcm_sense_reason_table { + TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED = R(0x15), + TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED = R(0x16), + TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED = R(0x17), ++ TCM_COPY_TARGET_DEVICE_NOT_REACHABLE = R(0x18), + #undef R + }; + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 039de34..8b3610c 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -456,17 +456,23 @@ static inline int entity_before(struct sched_entity *a, + + static void update_min_vruntime(struct cfs_rq *cfs_rq) + { ++ struct sched_entity *curr = cfs_rq->curr; ++ + u64 vruntime = cfs_rq->min_vruntime; + +- if (cfs_rq->curr) +- vruntime = cfs_rq->curr->vruntime; ++ if (curr) { ++ if (curr->on_rq) ++ vruntime = curr->vruntime; ++ else ++ curr = NULL; ++ } + + if (cfs_rq->rb_leftmost) { + struct sched_entity *se = rb_entry(cfs_rq->rb_leftmost, + struct sched_entity, + run_node); + +- if (!cfs_rq->curr) ++ if (!curr) + vruntime = se->vruntime; + else + vruntime = min_vruntime(vruntime, se->vruntime); +@@ -680,7 +686,14 @@ void init_entity_runnable_average(struct sched_entity *se) + * will definitely be update (after enqueue). + */ + sa->period_contrib = 1023; +- sa->load_avg = scale_load_down(se->load.weight); ++ /* ++ * Tasks are intialized with full load to be seen as heavy tasks until ++ * they get a chance to stabilize to their real load level. ++ * Group entities are intialized with zero load to reflect the fact that ++ * nothing has been attached to the task group yet. ++ */ ++ if (entity_is_task(se)) ++ sa->load_avg = scale_load_down(se->load.weight); + sa->load_sum = sa->load_avg * LOAD_AVG_MAX; + /* + * At this point, util_avg won't be used in select_task_rq_fair anyway +@@ -3459,9 +3472,10 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) + account_entity_dequeue(cfs_rq, se); + + /* +- * Normalize the entity after updating the min_vruntime because the +- * update can refer to the ->curr item and we need to reflect this +- * movement in our normalized position. ++ * Normalize after update_curr(); which will also have moved ++ * min_vruntime if @se is the one holding it back. But before doing ++ * update_min_vruntime() again, which will discount @se's position and ++ * can move min_vruntime forward still more. + */ + if (!(flags & DEQUEUE_SLEEP)) + se->vruntime -= cfs_rq->min_vruntime; +@@ -3469,8 +3483,16 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) + /* return excess runtime on last dequeue */ + return_cfs_rq_runtime(cfs_rq); + +- update_min_vruntime(cfs_rq); + update_cfs_shares(cfs_rq); ++ ++ /* ++ * Now advance min_vruntime if @se was the entity holding it back, ++ * except when: DEQUEUE_SAVE && !DEQUEUE_MOVE, in this case we'll be ++ * put back on, and if we advance min_vruntime, we'll be placed back ++ * further than we started -- ie. we'll be penalized. ++ */ ++ if ((flags & (DEQUEUE_SAVE | DEQUEUE_MOVE)) == DEQUEUE_SAVE) ++ update_min_vruntime(cfs_rq); + } + + /* +diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c +index bf16883..e72581d 100644 +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -473,7 +473,16 @@ static int xs_nospace(struct rpc_task *task) + spin_unlock_bh(&xprt->transport_lock); + + /* Race breaker in case memory is freed before above code is called */ +- sk->sk_write_space(sk); ++ if (ret == -EAGAIN) { ++ struct socket_wq *wq; ++ ++ rcu_read_lock(); ++ wq = rcu_dereference(sk->sk_wq); ++ set_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags); ++ rcu_read_unlock(); ++ ++ sk->sk_write_space(sk); ++ } + return ret; + } + +diff --git a/sound/pci/hda/dell_wmi_helper.c b/sound/pci/hda/dell_wmi_helper.c +index 9c22f95..19d41da 100644 +--- a/sound/pci/hda/dell_wmi_helper.c ++++ b/sound/pci/hda/dell_wmi_helper.c +@@ -49,7 +49,7 @@ static void alc_fixup_dell_wmi(struct hda_codec *codec, + removefunc = true; + if (dell_led_set_func(DELL_LED_MICMUTE, false) >= 0) { + dell_led_value = 0; +- if (spec->gen.num_adc_nids > 1) ++ if (spec->gen.num_adc_nids > 1 && !spec->gen.dyn_adc_switch) + codec_dbg(codec, "Skipping micmute LED control due to several ADCs"); + else { + dell_old_cap_hook = spec->gen.cap_sync_hook; +diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c +index f0955fd..6a23302 100644 +--- a/sound/pci/hda/thinkpad_helper.c ++++ b/sound/pci/hda/thinkpad_helper.c +@@ -62,7 +62,7 @@ static void hda_fixup_thinkpad_acpi(struct hda_codec *codec, + removefunc = false; + } + if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) { +- if (spec->num_adc_nids > 1) ++ if (spec->num_adc_nids > 1 && !spec->dyn_adc_switch) + codec_dbg(codec, + "Skipping micmute LED control due to several ADCs"); + else { +diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +index 8ff6c6a..c9c8dc3 100644 +--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c ++++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +@@ -89,6 +89,7 @@ struct intel_pt_decoder { + bool pge; + bool have_tma; + bool have_cyc; ++ bool fixup_last_mtc; + uint64_t pos; + uint64_t last_ip; + uint64_t ip; +@@ -584,10 +585,31 @@ struct intel_pt_calc_cyc_to_tsc_info { + uint64_t tsc_timestamp; + uint64_t timestamp; + bool have_tma; ++ bool fixup_last_mtc; + bool from_mtc; + double cbr_cyc_to_tsc; + }; + ++/* ++ * MTC provides a 8-bit slice of CTC but the TMA packet only provides the lower ++ * 16 bits of CTC. If mtc_shift > 8 then some of the MTC bits are not in the CTC ++ * provided by the TMA packet. Fix-up the last_mtc calculated from the TMA ++ * packet by copying the missing bits from the current MTC assuming the least ++ * difference between the two, and that the current MTC comes after last_mtc. ++ */ ++static void intel_pt_fixup_last_mtc(uint32_t mtc, int mtc_shift, ++ uint32_t *last_mtc) ++{ ++ uint32_t first_missing_bit = 1U << (16 - mtc_shift); ++ uint32_t mask = ~(first_missing_bit - 1); ++ ++ *last_mtc |= mtc & mask; ++ if (*last_mtc >= mtc) { ++ *last_mtc -= first_missing_bit; ++ *last_mtc &= 0xff; ++ } ++} ++ + static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info) + { + struct intel_pt_decoder *decoder = pkt_info->decoder; +@@ -617,6 +639,11 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info) + return 0; + + mtc = pkt_info->packet.payload; ++ if (decoder->mtc_shift > 8 && data->fixup_last_mtc) { ++ data->fixup_last_mtc = false; ++ intel_pt_fixup_last_mtc(mtc, decoder->mtc_shift, ++ &data->last_mtc); ++ } + if (mtc > data->last_mtc) + mtc_delta = mtc - data->last_mtc; + else +@@ -685,6 +712,7 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info) + + data->ctc_delta = 0; + data->have_tma = true; ++ data->fixup_last_mtc = true; + + return 0; + +@@ -751,6 +779,7 @@ static void intel_pt_calc_cyc_to_tsc(struct intel_pt_decoder *decoder, + .tsc_timestamp = decoder->tsc_timestamp, + .timestamp = decoder->timestamp, + .have_tma = decoder->have_tma, ++ .fixup_last_mtc = decoder->fixup_last_mtc, + .from_mtc = from_mtc, + .cbr_cyc_to_tsc = 0, + }; +@@ -1241,6 +1270,7 @@ static void intel_pt_calc_tma(struct intel_pt_decoder *decoder) + } + decoder->ctc_delta = 0; + decoder->have_tma = true; ++ decoder->fixup_last_mtc = true; + intel_pt_log("CTC timestamp " x64_fmt " last MTC %#x CTC rem %#x\n", + decoder->ctc_timestamp, decoder->last_mtc, ctc_rem); + } +@@ -1255,6 +1285,12 @@ static void intel_pt_calc_mtc_timestamp(struct intel_pt_decoder *decoder) + + mtc = decoder->packet.payload; + ++ if (decoder->mtc_shift > 8 && decoder->fixup_last_mtc) { ++ decoder->fixup_last_mtc = false; ++ intel_pt_fixup_last_mtc(mtc, decoder->mtc_shift, ++ &decoder->last_mtc); ++ } ++ + if (mtc > decoder->last_mtc) + mtc_delta = mtc - decoder->last_mtc; + else +@@ -1323,6 +1359,8 @@ static void intel_pt_calc_cyc_timestamp(struct intel_pt_decoder *decoder) + timestamp, decoder->timestamp); + else + decoder->timestamp = timestamp; ++ ++ decoder->timestamp_insn_cnt = 0; + } + + /* Walk PSB+ packets when already in sync. */ +diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c +index 551ff6f..b2878d2 100644 +--- a/tools/perf/util/intel-pt.c ++++ b/tools/perf/util/intel-pt.c +@@ -241,7 +241,7 @@ static int intel_pt_get_trace(struct intel_pt_buffer *b, void *data) + } + + queue = &ptq->pt->queues.queue_array[ptq->queue_nr]; +- ++next: + buffer = auxtrace_buffer__next(queue, buffer); + if (!buffer) { + if (old_buffer) +@@ -264,9 +264,6 @@ static int intel_pt_get_trace(struct intel_pt_buffer *b, void *data) + intel_pt_do_fix_overlap(ptq->pt, old_buffer, buffer)) + return -ENOMEM; + +- if (old_buffer) +- auxtrace_buffer__drop_data(old_buffer); +- + if (buffer->use_data) { + b->len = buffer->use_size; + b->buf = buffer->use_data; +@@ -276,6 +273,16 @@ static int intel_pt_get_trace(struct intel_pt_buffer *b, void *data) + } + b->ref_timestamp = buffer->reference; + ++ /* ++ * If in snapshot mode and the buffer has no usable data, get next ++ * buffer and again check overlap against old_buffer. ++ */ ++ if (ptq->pt->snapshot_mode && !b->len) ++ goto next; ++ ++ if (old_buffer) ++ auxtrace_buffer__drop_data(old_buffer); ++ + if (!old_buffer || ptq->pt->sampling_mode || (ptq->pt->snapshot_mode && + !buffer->consecutive)) { + b->consecutive = false; +diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c +index 8a73d81..f3825b6 100644 +--- a/tools/spi/spidev_test.c ++++ b/tools/spi/spidev_test.c +@@ -284,7 +284,7 @@ static void parse_opts(int argc, char *argv[]) + + static void transfer_escaped_string(int fd, char *str) + { +- size_t size = strlen(str + 1); ++ size_t size = strlen(str); + uint8_t *tx; + uint8_t *rx; + |