commit: dc93dbc1a0e8814da2e5ae4a6f6d9e7bc83aabcc Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Wed Apr 12 18:02:09 2017 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Wed Apr 12 18:02:09 2017 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=dc93dbc1
Linux patch 4.10.10 0000_README | 4 + 1009_linux-4.10.10.patch | 4168 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 4172 insertions(+) diff --git a/0000_README b/0000_README index 5f8d5b0..abc6f43 100644 --- a/0000_README +++ b/0000_README @@ -79,6 +79,10 @@ Patch: 1008_linux-4.10.9.patch From: http://www.kernel.org Desc: Linux 4.10.9 +Patch: 1009_linux-4.10.10.patch +From: http://www.kernel.org +Desc: Linux 4.10.10 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1009_linux-4.10.10.patch b/1009_linux-4.10.10.patch new file mode 100644 index 0000000..8380fc6 --- /dev/null +++ b/1009_linux-4.10.10.patch @@ -0,0 +1,4168 @@ +diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt +index 0b7d8576001c..2d80b60eeabe 100644 +--- a/Documentation/devicetree/bindings/usb/usb-xhci.txt ++++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt +@@ -27,6 +27,7 @@ Required properties: + Optional properties: + - clocks: reference to a clock + - usb3-lpm-capable: determines if platform is USB3 LPM capable ++ - quirk-broken-port-ped: set if the controller has broken port disable mechanism + + Example: + usb@f0931000 { +diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt +index 8f3d96af81d7..1f6e101e299a 100644 +--- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt ++++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt +@@ -6,10 +6,11 @@ occurred. + + Required properties: + - compatible : should be one among the following +- (a) "samsung,s3c2410-wdt" for Exynos4 and previous SoCs +- (b) "samsung,exynos5250-wdt" for Exynos5250 +- (c) "samsung,exynos5420-wdt" for Exynos5420 +- (c) "samsung,exynos7-wdt" for Exynos7 ++ - "samsung,s3c2410-wdt" for S3C2410 ++ - "samsung,s3c6410-wdt" for S3C6410, S5PV210 and Exynos4 ++ - "samsung,exynos5250-wdt" for Exynos5250 ++ - "samsung,exynos5420-wdt" for Exynos5420 ++ - "samsung,exynos7-wdt" for Exynos7 + + - reg : base physical address of the controller and length of memory mapped + region. +diff --git a/Documentation/process/stable-kernel-rules.rst b/Documentation/process/stable-kernel-rules.rst +index 11ec2d93a5e0..61e9c78bd6d1 100644 +--- a/Documentation/process/stable-kernel-rules.rst ++++ b/Documentation/process/stable-kernel-rules.rst +@@ -124,7 +124,7 @@ specified in the following format in the sign-off area: + + .. code-block:: none + +- Cc: <sta...@vger.kernel.org> # 3.3.x- ++ Cc: <sta...@vger.kernel.org> # 3.3.x + + The tag has the meaning of: + +diff --git a/Makefile b/Makefile +index 4ebd511dee58..52858726495b 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 10 +-SUBLEVEL = 9 ++SUBLEVEL = 10 + EXTRAVERSION = + NAME = Fearless Coyote + +@@ -370,7 +370,7 @@ LDFLAGS_MODULE = + CFLAGS_KERNEL = + AFLAGS_KERNEL = + LDFLAGS_vmlinux = +-CFLAGS_GCOV = -fprofile-arcs -ftest-coverage -fno-tree-loop-im -Wno-maybe-uninitialized ++CFLAGS_GCOV := -fprofile-arcs -ftest-coverage -fno-tree-loop-im $(call cc-disable-warning,maybe-uninitialized,) + CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,) + + +@@ -651,6 +651,12 @@ KBUILD_CFLAGS += $(call cc-ifversion, -lt, 0409, \ + # Tell gcc to never replace conditional load with a non-conditional one + KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) + ++# check for 'asm goto' ++ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC) $(KBUILD_CFLAGS)), y) ++ KBUILD_CFLAGS += -DCC_HAVE_ASM_GOTO ++ KBUILD_AFLAGS += -DCC_HAVE_ASM_GOTO ++endif ++ + include scripts/Makefile.gcc-plugins + + ifdef CONFIG_READABLE_ASM +@@ -796,12 +802,6 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types) + # use the deterministic mode of AR if available + KBUILD_ARFLAGS := $(call ar-option,D) + +-# check for 'asm goto' +-ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC) $(KBUILD_CFLAGS)), y) +- KBUILD_CFLAGS += -DCC_HAVE_ASM_GOTO +- KBUILD_AFLAGS += -DCC_HAVE_ASM_GOTO +-endif +- + include scripts/Makefile.kasan + include scripts/Makefile.extrawarn + include scripts/Makefile.ubsan +diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c +index 7e45f69a0ddc..8e8d20cdbce7 100644 +--- a/arch/arm/kernel/armksyms.c ++++ b/arch/arm/kernel/armksyms.c +@@ -178,6 +178,6 @@ EXPORT_SYMBOL(__pv_offset); + #endif + + #ifdef CONFIG_HAVE_ARM_SMCCC +-EXPORT_SYMBOL(arm_smccc_smc); +-EXPORT_SYMBOL(arm_smccc_hvc); ++EXPORT_SYMBOL(__arm_smccc_smc); ++EXPORT_SYMBOL(__arm_smccc_hvc); + #endif +diff --git a/arch/arm/kernel/smccc-call.S b/arch/arm/kernel/smccc-call.S +index 2e48b674aab1..e5d43066b889 100644 +--- a/arch/arm/kernel/smccc-call.S ++++ b/arch/arm/kernel/smccc-call.S +@@ -46,17 +46,19 @@ UNWIND( .fnend) + /* + * void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, + * unsigned long a3, unsigned long a4, unsigned long a5, +- * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) ++ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, ++ * struct arm_smccc_quirk *quirk) + */ +-ENTRY(arm_smccc_smc) ++ENTRY(__arm_smccc_smc) + SMCCC SMCCC_SMC +-ENDPROC(arm_smccc_smc) ++ENDPROC(__arm_smccc_smc) + + /* + * void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, + * unsigned long a3, unsigned long a4, unsigned long a5, +- * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) ++ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, ++ * struct arm_smccc_quirk *quirk) + */ +-ENTRY(arm_smccc_hvc) ++ENTRY(__arm_smccc_hvc) + SMCCC SMCCC_HVC +-ENDPROC(arm_smccc_hvc) ++ENDPROC(__arm_smccc_hvc) +diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c +index a5265edbeeab..2fd5c135e8a4 100644 +--- a/arch/arm/kvm/mmu.c ++++ b/arch/arm/kvm/mmu.c +@@ -292,11 +292,18 @@ static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size) + phys_addr_t addr = start, end = start + size; + phys_addr_t next; + ++ assert_spin_locked(&kvm->mmu_lock); + pgd = kvm->arch.pgd + stage2_pgd_index(addr); + do { + next = stage2_pgd_addr_end(addr, end); + if (!stage2_pgd_none(*pgd)) + unmap_stage2_puds(kvm, pgd, addr, next); ++ /* ++ * If the range is too large, release the kvm->mmu_lock ++ * to prevent starvation and lockup detector warnings. ++ */ ++ if (next != end) ++ cond_resched_lock(&kvm->mmu_lock); + } while (pgd++, addr = next, addr != end); + } + +@@ -803,6 +810,7 @@ void stage2_unmap_vm(struct kvm *kvm) + int idx; + + idx = srcu_read_lock(&kvm->srcu); ++ down_read(¤t->mm->mmap_sem); + spin_lock(&kvm->mmu_lock); + + slots = kvm_memslots(kvm); +@@ -810,6 +818,7 @@ void stage2_unmap_vm(struct kvm *kvm) + stage2_unmap_memslot(kvm, memslot); + + spin_unlock(&kvm->mmu_lock); ++ up_read(¤t->mm->mmap_sem); + srcu_read_unlock(&kvm->srcu, idx); + } + +@@ -829,7 +838,10 @@ void kvm_free_stage2_pgd(struct kvm *kvm) + if (kvm->arch.pgd == NULL) + return; + ++ spin_lock(&kvm->mmu_lock); + unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); ++ spin_unlock(&kvm->mmu_lock); ++ + /* Free the HW pgd, one page at a time */ + free_pages_exact(kvm->arch.pgd, S2_PGD_SIZE); + kvm->arch.pgd = NULL; +@@ -1804,6 +1816,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + (KVM_PHYS_SIZE >> PAGE_SHIFT)) + return -EFAULT; + ++ down_read(¤t->mm->mmap_sem); + /* + * A memory region could potentially cover multiple VMAs, and any holes + * between them, so iterate over all of them to find out if we can map +@@ -1847,8 +1860,10 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + pa += vm_start - vma->vm_start; + + /* IO region dirty page logging not allowed */ +- if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) +- return -EINVAL; ++ if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) { ++ ret = -EINVAL; ++ goto out; ++ } + + ret = kvm_phys_addr_ioremap(kvm, gpa, pa, + vm_end - vm_start, +@@ -1860,7 +1875,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + } while (hva < reg_end); + + if (change == KVM_MR_FLAGS_ONLY) +- return ret; ++ goto out; + + spin_lock(&kvm->mmu_lock); + if (ret) +@@ -1868,6 +1883,8 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + else + stage2_flush_memslot(kvm, memslot); + spin_unlock(&kvm->mmu_lock); ++out: ++ up_read(¤t->mm->mmap_sem); + return ret; + } + +diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c +index 78f368039c79..e9c4dc9e0ada 100644 +--- a/arch/arm64/kernel/arm64ksyms.c ++++ b/arch/arm64/kernel/arm64ksyms.c +@@ -73,5 +73,5 @@ NOKPROBE_SYMBOL(_mcount); + #endif + + /* arm-smccc */ +-EXPORT_SYMBOL(arm_smccc_smc); +-EXPORT_SYMBOL(arm_smccc_hvc); ++EXPORT_SYMBOL(__arm_smccc_smc); ++EXPORT_SYMBOL(__arm_smccc_hvc); +diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c +index bc049afc73a7..b3bb7ef97bc8 100644 +--- a/arch/arm64/kernel/asm-offsets.c ++++ b/arch/arm64/kernel/asm-offsets.c +@@ -143,8 +143,11 @@ int main(void) + DEFINE(SLEEP_STACK_DATA_SYSTEM_REGS, offsetof(struct sleep_stack_data, system_regs)); + DEFINE(SLEEP_STACK_DATA_CALLEE_REGS, offsetof(struct sleep_stack_data, callee_saved_regs)); + #endif +- DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0)); +- DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2)); ++ DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0)); ++ DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2)); ++ DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id)); ++ DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state)); ++ + BLANK(); + DEFINE(HIBERN_PBE_ORIG, offsetof(struct pbe, orig_address)); + DEFINE(HIBERN_PBE_ADDR, offsetof(struct pbe, address)); +diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S +index ae0496fa4235..62522342e1e4 100644 +--- a/arch/arm64/kernel/smccc-call.S ++++ b/arch/arm64/kernel/smccc-call.S +@@ -12,6 +12,7 @@ + * + */ + #include <linux/linkage.h> ++#include <linux/arm-smccc.h> + #include <asm/asm-offsets.h> + + .macro SMCCC instr +@@ -20,24 +21,32 @@ + ldr x4, [sp] + stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] + stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS] +- ret ++ ldr x4, [sp, #8] ++ cbz x4, 1f /* no quirk structure */ ++ ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS] ++ cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6 ++ b.ne 1f ++ str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS] ++1: ret + .cfi_endproc + .endm + + /* + * void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, + * unsigned long a3, unsigned long a4, unsigned long a5, +- * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) ++ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, ++ * struct arm_smccc_quirk *quirk) + */ +-ENTRY(arm_smccc_smc) ++ENTRY(__arm_smccc_smc) + SMCCC smc +-ENDPROC(arm_smccc_smc) ++ENDPROC(__arm_smccc_smc) + + /* + * void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, + * unsigned long a3, unsigned long a4, unsigned long a5, +- * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) ++ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, ++ * struct arm_smccc_quirk *quirk) + */ +-ENTRY(arm_smccc_hvc) ++ENTRY(__arm_smccc_hvc) + SMCCC hvc +-ENDPROC(arm_smccc_hvc) ++ENDPROC(__arm_smccc_hvc) +diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c +index 156169c6981b..ed0f50b565c3 100644 +--- a/arch/arm64/mm/fault.c ++++ b/arch/arm64/mm/fault.c +@@ -41,7 +41,20 @@ + #include <asm/pgtable.h> + #include <asm/tlbflush.h> + +-static const char *fault_name(unsigned int esr); ++struct fault_info { ++ int (*fn)(unsigned long addr, unsigned int esr, ++ struct pt_regs *regs); ++ int sig; ++ int code; ++ const char *name; ++}; ++ ++static const struct fault_info fault_info[]; ++ ++static inline const struct fault_info *esr_to_fault_info(unsigned int esr) ++{ ++ return fault_info + (esr & 63); ++} + + #ifdef CONFIG_KPROBES + static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr) +@@ -196,10 +209,12 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr, + struct pt_regs *regs) + { + struct siginfo si; ++ const struct fault_info *inf; + + if (unhandled_signal(tsk, sig) && show_unhandled_signals_ratelimited()) { ++ inf = esr_to_fault_info(esr); + pr_info("%s[%d]: unhandled %s (%d) at 0x%08lx, esr 0x%03x\n", +- tsk->comm, task_pid_nr(tsk), fault_name(esr), sig, ++ tsk->comm, task_pid_nr(tsk), inf->name, sig, + addr, esr); + show_pte(tsk->mm, addr); + show_regs(regs); +@@ -218,14 +233,16 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re + { + struct task_struct *tsk = current; + struct mm_struct *mm = tsk->active_mm; ++ const struct fault_info *inf; + + /* + * If we are in kernel mode at this point, we have no context to + * handle this fault with. + */ +- if (user_mode(regs)) +- __do_user_fault(tsk, addr, esr, SIGSEGV, SEGV_MAPERR, regs); +- else ++ if (user_mode(regs)) { ++ inf = esr_to_fault_info(esr); ++ __do_user_fault(tsk, addr, esr, inf->sig, inf->code, regs); ++ } else + __do_kernel_fault(mm, addr, esr, regs); + } + +@@ -487,12 +504,7 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs) + return 1; + } + +-static const struct fault_info { +- int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs); +- int sig; +- int code; +- const char *name; +-} fault_info[] = { ++static const struct fault_info fault_info[] = { + { do_bad, SIGBUS, 0, "ttbr address size fault" }, + { do_bad, SIGBUS, 0, "level 1 address size fault" }, + { do_bad, SIGBUS, 0, "level 2 address size fault" }, +@@ -559,19 +571,13 @@ static const struct fault_info { + { do_bad, SIGBUS, 0, "unknown 63" }, + }; + +-static const char *fault_name(unsigned int esr) +-{ +- const struct fault_info *inf = fault_info + (esr & 63); +- return inf->name; +-} +- + /* + * Dispatch a data abort to the relevant handler. + */ + asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, + struct pt_regs *regs) + { +- const struct fault_info *inf = fault_info + (esr & 63); ++ const struct fault_info *inf = esr_to_fault_info(esr); + struct siginfo info; + + if (!inf->fn(addr, esr, regs)) +diff --git a/arch/metag/include/asm/uaccess.h b/arch/metag/include/asm/uaccess.h +index 273e61225c27..07238b39638c 100644 +--- a/arch/metag/include/asm/uaccess.h ++++ b/arch/metag/include/asm/uaccess.h +@@ -197,20 +197,21 @@ extern long __must_check strnlen_user(const char __user *src, long count); + + #define strlen_user(str) strnlen_user(str, 32767) + +-extern unsigned long __must_check __copy_user_zeroing(void *to, +- const void __user *from, +- unsigned long n); ++extern unsigned long raw_copy_from_user(void *to, const void __user *from, ++ unsigned long n); + + static inline unsigned long + copy_from_user(void *to, const void __user *from, unsigned long n) + { ++ unsigned long res = n; + if (likely(access_ok(VERIFY_READ, from, n))) +- return __copy_user_zeroing(to, from, n); +- memset(to, 0, n); +- return n; ++ res = raw_copy_from_user(to, from, n); ++ if (unlikely(res)) ++ memset(to + (n - res), 0, res); ++ return res; + } + +-#define __copy_from_user(to, from, n) __copy_user_zeroing(to, from, n) ++#define __copy_from_user(to, from, n) raw_copy_from_user(to, from, n) + #define __copy_from_user_inatomic __copy_from_user + + extern unsigned long __must_check __copy_user(void __user *to, +diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c +index b3ebfe9c8e88..2792fc621088 100644 +--- a/arch/metag/lib/usercopy.c ++++ b/arch/metag/lib/usercopy.c +@@ -29,7 +29,6 @@ + COPY \ + "1:\n" \ + " .section .fixup,\"ax\"\n" \ +- " MOV D1Ar1,#0\n" \ + FIXUP \ + " MOVT D1Ar1,#HI(1b)\n" \ + " JUMP D1Ar1,#LO(1b)\n" \ +@@ -260,27 +259,31 @@ + "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "22:\n" \ + "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ +- "SUB %3, %3, #32\n" \ + "23:\n" \ +- "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ ++ "SUB %3, %3, #32\n" \ + "24:\n" \ ++ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ ++ "25:\n" \ + "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "26:\n" \ + "SUB %3, %3, #32\n" \ + "DCACHE [%1+#-64], D0Ar6\n" \ + "BR $Lloop"id"\n" \ + \ + "MOV RAPF, %1\n" \ +- "25:\n" \ ++ "27:\n" \ + "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "26:\n" \ ++ "28:\n" \ + "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "29:\n" \ + "SUB %3, %3, #32\n" \ +- "27:\n" \ ++ "30:\n" \ + "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "28:\n" \ ++ "31:\n" \ + "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "32:\n" \ + "SUB %0, %0, #8\n" \ +- "29:\n" \ ++ "33:\n" \ + "SETL [%0++], D0.7, D1.7\n" \ + "SUB %3, %3, #32\n" \ + "1:" \ +@@ -312,11 +315,15 @@ + " .long 26b,3b\n" \ + " .long 27b,3b\n" \ + " .long 28b,3b\n" \ +- " .long 29b,4b\n" \ ++ " .long 29b,3b\n" \ ++ " .long 30b,3b\n" \ ++ " .long 31b,3b\n" \ ++ " .long 32b,3b\n" \ ++ " .long 33b,4b\n" \ + " .previous\n" \ + : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ + : "0" (to), "1" (from), "2" (ret), "3" (n) \ +- : "D1Ar1", "D0Ar2", "memory") ++ : "D1Ar1", "D0Ar2", "cc", "memory") + + /* rewind 'to' and 'from' pointers when a fault occurs + * +@@ -342,7 +349,7 @@ + #define __asm_copy_to_user_64bit_rapf_loop(to, from, ret, n, id)\ + __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ + "LSR D0Ar2, D0Ar2, #8\n" \ +- "AND D0Ar2, D0Ar2, #0x7\n" \ ++ "ANDS D0Ar2, D0Ar2, #0x7\n" \ + "ADDZ D0Ar2, D0Ar2, #4\n" \ + "SUB D0Ar2, D0Ar2, #1\n" \ + "MOV D1Ar1, #4\n" \ +@@ -403,47 +410,55 @@ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "22:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ +- "SUB %3, %3, #16\n" \ + "23:\n" \ +- "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "24:\n" \ +- "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "SUB %3, %3, #16\n" \ +- "25:\n" \ ++ "24:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "26:\n" \ ++ "25:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "26:\n" \ + "SUB %3, %3, #16\n" \ + "27:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "28:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "29:\n" \ ++ "SUB %3, %3, #16\n" \ ++ "30:\n" \ ++ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ ++ "31:\n" \ ++ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "32:\n" \ + "SUB %3, %3, #16\n" \ + "DCACHE [%1+#-64], D0Ar6\n" \ + "BR $Lloop"id"\n" \ + \ + "MOV RAPF, %1\n" \ +- "29:\n" \ ++ "33:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "30:\n" \ ++ "34:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "35:\n" \ + "SUB %3, %3, #16\n" \ +- "31:\n" \ ++ "36:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "32:\n" \ ++ "37:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "38:\n" \ + "SUB %3, %3, #16\n" \ +- "33:\n" \ ++ "39:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "34:\n" \ ++ "40:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "41:\n" \ + "SUB %3, %3, #16\n" \ +- "35:\n" \ ++ "42:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ +- "36:\n" \ ++ "43:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ ++ "44:\n" \ + "SUB %0, %0, #4\n" \ +- "37:\n" \ ++ "45:\n" \ + "SETD [%0++], D0.7\n" \ + "SUB %3, %3, #16\n" \ + "1:" \ +@@ -483,11 +498,19 @@ + " .long 34b,3b\n" \ + " .long 35b,3b\n" \ + " .long 36b,3b\n" \ +- " .long 37b,4b\n" \ ++ " .long 37b,3b\n" \ ++ " .long 38b,3b\n" \ ++ " .long 39b,3b\n" \ ++ " .long 40b,3b\n" \ ++ " .long 41b,3b\n" \ ++ " .long 42b,3b\n" \ ++ " .long 43b,3b\n" \ ++ " .long 44b,3b\n" \ ++ " .long 45b,4b\n" \ + " .previous\n" \ + : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ + : "0" (to), "1" (from), "2" (ret), "3" (n) \ +- : "D1Ar1", "D0Ar2", "memory") ++ : "D1Ar1", "D0Ar2", "cc", "memory") + + /* rewind 'to' and 'from' pointers when a fault occurs + * +@@ -513,7 +536,7 @@ + #define __asm_copy_to_user_32bit_rapf_loop(to, from, ret, n, id)\ + __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ + "LSR D0Ar2, D0Ar2, #8\n" \ +- "AND D0Ar2, D0Ar2, #0x7\n" \ ++ "ANDS D0Ar2, D0Ar2, #0x7\n" \ + "ADDZ D0Ar2, D0Ar2, #4\n" \ + "SUB D0Ar2, D0Ar2, #1\n" \ + "MOV D1Ar1, #4\n" \ +@@ -538,23 +561,31 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, + if ((unsigned long) src & 1) { + __asm_copy_to_user_1(dst, src, retn); + n--; ++ if (retn) ++ return retn + n; + } + if ((unsigned long) dst & 1) { + /* Worst case - byte copy */ + while (n > 0) { + __asm_copy_to_user_1(dst, src, retn); + n--; ++ if (retn) ++ return retn + n; + } + } + if (((unsigned long) src & 2) && n >= 2) { + __asm_copy_to_user_2(dst, src, retn); + n -= 2; ++ if (retn) ++ return retn + n; + } + if ((unsigned long) dst & 2) { + /* Second worst case - word copy */ + while (n >= 2) { + __asm_copy_to_user_2(dst, src, retn); + n -= 2; ++ if (retn) ++ return retn + n; + } + } + +@@ -569,6 +600,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, + while (n >= 8) { + __asm_copy_to_user_8x64(dst, src, retn); + n -= 8; ++ if (retn) ++ return retn + n; + } + } + if (n >= RAPF_MIN_BUF_SIZE) { +@@ -581,6 +614,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, + while (n >= 8) { + __asm_copy_to_user_8x64(dst, src, retn); + n -= 8; ++ if (retn) ++ return retn + n; + } + } + #endif +@@ -588,11 +623,15 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, + while (n >= 16) { + __asm_copy_to_user_16(dst, src, retn); + n -= 16; ++ if (retn) ++ return retn + n; + } + + while (n >= 4) { + __asm_copy_to_user_4(dst, src, retn); + n -= 4; ++ if (retn) ++ return retn + n; + } + + switch (n) { +@@ -609,6 +648,10 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, + break; + } + ++ /* ++ * If we get here, retn correctly reflects the number of failing ++ * bytes. ++ */ + return retn; + } + EXPORT_SYMBOL(__copy_user); +@@ -617,16 +660,14 @@ EXPORT_SYMBOL(__copy_user); + __asm_copy_user_cont(to, from, ret, \ + " GETB D1Ar1,[%1++]\n" \ + "2: SETB [%0++],D1Ar1\n", \ +- "3: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ ++ "3: ADD %2,%2,#1\n", \ + " .long 2b,3b\n") + + #define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_user_cont(to, from, ret, \ + " GETW D1Ar1,[%1++]\n" \ + "2: SETW [%0++],D1Ar1\n" COPY, \ +- "3: ADD %2,%2,#2\n" \ +- " SETW [%0++],D1Ar1\n" FIXUP, \ ++ "3: ADD %2,%2,#2\n" FIXUP, \ + " .long 2b,3b\n" TENTRY) + + #define __asm_copy_from_user_2(to, from, ret) \ +@@ -636,145 +677,26 @@ EXPORT_SYMBOL(__copy_user); + __asm_copy_from_user_2x_cont(to, from, ret, \ + " GETB D1Ar1,[%1++]\n" \ + "4: SETB [%0++],D1Ar1\n", \ +- "5: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ ++ "5: ADD %2,%2,#1\n", \ + " .long 4b,5b\n") + + #define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ + __asm_copy_user_cont(to, from, ret, \ + " GETD D1Ar1,[%1++]\n" \ + "2: SETD [%0++],D1Ar1\n" COPY, \ +- "3: ADD %2,%2,#4\n" \ +- " SETD [%0++],D1Ar1\n" FIXUP, \ ++ "3: ADD %2,%2,#4\n" FIXUP, \ + " .long 2b,3b\n" TENTRY) + + #define __asm_copy_from_user_4(to, from, ret) \ + __asm_copy_from_user_4x_cont(to, from, ret, "", "", "") + +-#define __asm_copy_from_user_5(to, from, ret) \ +- __asm_copy_from_user_4x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "4: SETB [%0++],D1Ar1\n", \ +- "5: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 4b,5b\n") +- +-#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_4x_cont(to, from, ret, \ +- " GETW D1Ar1,[%1++]\n" \ +- "4: SETW [%0++],D1Ar1\n" COPY, \ +- "5: ADD %2,%2,#2\n" \ +- " SETW [%0++],D1Ar1\n" FIXUP, \ +- " .long 4b,5b\n" TENTRY) +- +-#define __asm_copy_from_user_6(to, from, ret) \ +- __asm_copy_from_user_6x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_7(to, from, ret) \ +- __asm_copy_from_user_6x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "6: SETB [%0++],D1Ar1\n", \ +- "7: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 6b,7b\n") +- +-#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_4x_cont(to, from, ret, \ +- " GETD D1Ar1,[%1++]\n" \ +- "4: SETD [%0++],D1Ar1\n" COPY, \ +- "5: ADD %2,%2,#4\n" \ +- " SETD [%0++],D1Ar1\n" FIXUP, \ +- " .long 4b,5b\n" TENTRY) +- +-#define __asm_copy_from_user_8(to, from, ret) \ +- __asm_copy_from_user_8x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_9(to, from, ret) \ +- __asm_copy_from_user_8x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "6: SETB [%0++],D1Ar1\n", \ +- "7: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 6b,7b\n") +- +-#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_8x_cont(to, from, ret, \ +- " GETW D1Ar1,[%1++]\n" \ +- "6: SETW [%0++],D1Ar1\n" COPY, \ +- "7: ADD %2,%2,#2\n" \ +- " SETW [%0++],D1Ar1\n" FIXUP, \ +- " .long 6b,7b\n" TENTRY) +- +-#define __asm_copy_from_user_10(to, from, ret) \ +- __asm_copy_from_user_10x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_11(to, from, ret) \ +- __asm_copy_from_user_10x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "8: SETB [%0++],D1Ar1\n", \ +- "9: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 8b,9b\n") +- +-#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_8x_cont(to, from, ret, \ +- " GETD D1Ar1,[%1++]\n" \ +- "6: SETD [%0++],D1Ar1\n" COPY, \ +- "7: ADD %2,%2,#4\n" \ +- " SETD [%0++],D1Ar1\n" FIXUP, \ +- " .long 6b,7b\n" TENTRY) +- +-#define __asm_copy_from_user_12(to, from, ret) \ +- __asm_copy_from_user_12x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_13(to, from, ret) \ +- __asm_copy_from_user_12x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "8: SETB [%0++],D1Ar1\n", \ +- "9: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 8b,9b\n") +- +-#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_12x_cont(to, from, ret, \ +- " GETW D1Ar1,[%1++]\n" \ +- "8: SETW [%0++],D1Ar1\n" COPY, \ +- "9: ADD %2,%2,#2\n" \ +- " SETW [%0++],D1Ar1\n" FIXUP, \ +- " .long 8b,9b\n" TENTRY) +- +-#define __asm_copy_from_user_14(to, from, ret) \ +- __asm_copy_from_user_14x_cont(to, from, ret, "", "", "") +- +-#define __asm_copy_from_user_15(to, from, ret) \ +- __asm_copy_from_user_14x_cont(to, from, ret, \ +- " GETB D1Ar1,[%1++]\n" \ +- "10: SETB [%0++],D1Ar1\n", \ +- "11: ADD %2,%2,#1\n" \ +- " SETB [%0++],D1Ar1\n", \ +- " .long 10b,11b\n") +- +-#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ +- __asm_copy_from_user_12x_cont(to, from, ret, \ +- " GETD D1Ar1,[%1++]\n" \ +- "8: SETD [%0++],D1Ar1\n" COPY, \ +- "9: ADD %2,%2,#4\n" \ +- " SETD [%0++],D1Ar1\n" FIXUP, \ +- " .long 8b,9b\n" TENTRY) +- +-#define __asm_copy_from_user_16(to, from, ret) \ +- __asm_copy_from_user_16x_cont(to, from, ret, "", "", "") +- + #define __asm_copy_from_user_8x64(to, from, ret) \ + asm volatile ( \ + " GETL D0Ar2,D1Ar1,[%1++]\n" \ + "2: SETL [%0++],D0Ar2,D1Ar1\n" \ + "1:\n" \ + " .section .fixup,\"ax\"\n" \ +- " MOV D1Ar1,#0\n" \ +- " MOV D0Ar2,#0\n" \ + "3: ADD %2,%2,#8\n" \ +- " SETL [%0++],D0Ar2,D1Ar1\n" \ + " MOVT D0Ar2,#HI(1b)\n" \ + " JUMP D0Ar2,#LO(1b)\n" \ + " .previous\n" \ +@@ -789,36 +711,57 @@ EXPORT_SYMBOL(__copy_user); + * + * Rationale: + * A fault occurs while reading from user buffer, which is the +- * source. Since the fault is at a single address, we only +- * need to rewind by 8 bytes. ++ * source. + * Since we don't write to kernel buffer until we read first, + * the kernel buffer is at the right state and needn't be +- * corrected. ++ * corrected, but the source must be rewound to the beginning of ++ * the block, which is LSM_STEP*8 bytes. ++ * LSM_STEP is bits 10:8 in TXSTATUS which is already read ++ * and stored in D0Ar2 ++ * ++ * NOTE: If a fault occurs at the last operation in M{G,S}ETL ++ * LSM_STEP will be 0. ie: we do 4 writes in our case, if ++ * a fault happens at the 4th write, LSM_STEP will be 0 ++ * instead of 4. The code copes with that. + */ + #define __asm_copy_from_user_64bit_rapf_loop(to, from, ret, n, id) \ + __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ +- "SUB %1, %1, #8\n") ++ "LSR D0Ar2, D0Ar2, #5\n" \ ++ "ANDS D0Ar2, D0Ar2, #0x38\n" \ ++ "ADDZ D0Ar2, D0Ar2, #32\n" \ ++ "SUB %1, %1, D0Ar2\n") + + /* rewind 'from' pointer when a fault occurs + * + * Rationale: + * A fault occurs while reading from user buffer, which is the +- * source. Since the fault is at a single address, we only +- * need to rewind by 4 bytes. ++ * source. + * Since we don't write to kernel buffer until we read first, + * the kernel buffer is at the right state and needn't be +- * corrected. ++ * corrected, but the source must be rewound to the beginning of ++ * the block, which is LSM_STEP*4 bytes. ++ * LSM_STEP is bits 10:8 in TXSTATUS which is already read ++ * and stored in D0Ar2 ++ * ++ * NOTE: If a fault occurs at the last operation in M{G,S}ETL ++ * LSM_STEP will be 0. ie: we do 4 writes in our case, if ++ * a fault happens at the 4th write, LSM_STEP will be 0 ++ * instead of 4. The code copes with that. + */ + #define __asm_copy_from_user_32bit_rapf_loop(to, from, ret, n, id) \ + __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ +- "SUB %1, %1, #4\n") ++ "LSR D0Ar2, D0Ar2, #6\n" \ ++ "ANDS D0Ar2, D0Ar2, #0x1c\n" \ ++ "ADDZ D0Ar2, D0Ar2, #16\n" \ ++ "SUB %1, %1, D0Ar2\n") + + +-/* Copy from user to kernel, zeroing the bytes that were inaccessible in +- userland. The return-value is the number of bytes that were +- inaccessible. */ +-unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, +- unsigned long n) ++/* ++ * Copy from user to kernel. The return-value is the number of bytes that were ++ * inaccessible. ++ */ ++unsigned long raw_copy_from_user(void *pdst, const void __user *psrc, ++ unsigned long n) + { + register char *dst asm ("A0.2") = pdst; + register const char __user *src asm ("A1.2") = psrc; +@@ -830,6 +773,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + if ((unsigned long) src & 1) { + __asm_copy_from_user_1(dst, src, retn); + n--; ++ if (retn) ++ return retn + n; + } + if ((unsigned long) dst & 1) { + /* Worst case - byte copy */ +@@ -837,12 +782,14 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + __asm_copy_from_user_1(dst, src, retn); + n--; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + } + if (((unsigned long) src & 2) && n >= 2) { + __asm_copy_from_user_2(dst, src, retn); + n -= 2; ++ if (retn) ++ return retn + n; + } + if ((unsigned long) dst & 2) { + /* Second worst case - word copy */ +@@ -850,16 +797,10 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + __asm_copy_from_user_2(dst, src, retn); + n -= 2; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + } + +- /* We only need one check after the unalignment-adjustments, +- because if both adjustments were done, either both or +- neither reference had an exception. */ +- if (retn != 0) +- goto copy_exception_bytes; +- + #ifdef USE_RAPF + /* 64 bit copy loop */ + if (!(((unsigned long) src | (unsigned long) dst) & 7)) { +@@ -872,7 +813,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + __asm_copy_from_user_8x64(dst, src, retn); + n -= 8; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + } + +@@ -888,7 +829,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + __asm_copy_from_user_8x64(dst, src, retn); + n -= 8; + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + } + #endif +@@ -898,7 +839,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + n -= 4; + + if (retn) +- goto copy_exception_bytes; ++ return retn + n; + } + + /* If we get here, there were no memory read faults. */ +@@ -924,21 +865,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, + /* If we get here, retn correctly reflects the number of failing + bytes. */ + return retn; +- +- copy_exception_bytes: +- /* We already have "retn" bytes cleared, and need to clear the +- remaining "n" bytes. A non-optimized simple byte-for-byte in-line +- memset is preferred here, since this isn't speed-critical code and +- we'd rather have this a leaf-function than calling memset. */ +- { +- char *endp; +- for (endp = dst + n; dst < endp; dst++) +- *dst = 0; +- } +- +- return retn + n; + } +-EXPORT_SYMBOL(__copy_user_zeroing); ++EXPORT_SYMBOL(raw_copy_from_user); + + #define __asm_clear_8x64(to, ret) \ + asm volatile ( \ +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index b3c5bde43d34..9a6e11b6f457 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -1526,7 +1526,7 @@ config CPU_MIPS64_R6 + select CPU_SUPPORTS_HIGHMEM + select CPU_SUPPORTS_MSA + select GENERIC_CSUM +- select MIPS_O32_FP64_SUPPORT if MIPS32_O32 ++ select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32 + select HAVE_KVM + help + Choose this option to build a kernel for release 6 or later of the +diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h +index f485afe51514..a8df44d60607 100644 +--- a/arch/mips/include/asm/spinlock.h ++++ b/arch/mips/include/asm/spinlock.h +@@ -127,7 +127,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) + " andi %[ticket], %[ticket], 0xffff \n" + " bne %[ticket], %[my_ticket], 4f \n" + " subu %[ticket], %[my_ticket], %[ticket] \n" +- "2: \n" ++ "2: .insn \n" + " .subsection 2 \n" + "4: andi %[ticket], %[ticket], 0xffff \n" + " sll %[ticket], 5 \n" +@@ -202,7 +202,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) + " sc %[ticket], %[ticket_ptr] \n" + " beqz %[ticket], 1b \n" + " li %[ticket], 1 \n" +- "2: \n" ++ "2: .insn \n" + " .subsection 2 \n" + "3: b 2b \n" + " li %[ticket], 0 \n" +@@ -382,7 +382,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) + " .set reorder \n" + __WEAK_LLSC_MB + " li %2, 1 \n" +- "2: \n" ++ "2: .insn \n" + : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) + : GCC_OFF_SMALL_ASM() (rw->lock) + : "memory"); +@@ -422,7 +422,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) + " lui %1, 0x8000 \n" + " sc %1, %0 \n" + " li %2, 1 \n" +- "2: \n" ++ "2: .insn \n" + : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp), + "=&r" (ret) + : GCC_OFF_SMALL_ASM() (rw->lock) +diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c +index 07718bb5fc9d..12422fd4af23 100644 +--- a/arch/mips/kernel/cpu-probe.c ++++ b/arch/mips/kernel/cpu-probe.c +@@ -1824,7 +1824,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) + } + + decode_configs(c); +- c->options |= MIPS_CPU_TLBINV | MIPS_CPU_LDPTE; ++ c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE; + c->writecombine = _CACHE_UNCACHED_ACCELERATED; + break; + default: +diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S +index dc0b29612891..52a4fdfc8513 100644 +--- a/arch/mips/kernel/genex.S ++++ b/arch/mips/kernel/genex.S +@@ -448,7 +448,7 @@ NESTED(nmi_handler, PT_SIZE, sp) + BUILD_HANDLER reserved reserved sti verbose /* others */ + + .align 5 +- LEAF(handle_ri_rdhwr_vivt) ++ LEAF(handle_ri_rdhwr_tlbp) + .set push + .set noat + .set noreorder +@@ -467,7 +467,7 @@ NESTED(nmi_handler, PT_SIZE, sp) + .set pop + bltz k1, handle_ri /* slow path */ + /* fall thru */ +- END(handle_ri_rdhwr_vivt) ++ END(handle_ri_rdhwr_tlbp) + + LEAF(handle_ri_rdhwr) + .set push +diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c +index 6c7f9d7e92b3..6e2487d59fee 100644 +--- a/arch/mips/kernel/traps.c ++++ b/arch/mips/kernel/traps.c +@@ -81,7 +81,7 @@ extern asmlinkage void handle_dbe(void); + extern asmlinkage void handle_sys(void); + extern asmlinkage void handle_bp(void); + extern asmlinkage void handle_ri(void); +-extern asmlinkage void handle_ri_rdhwr_vivt(void); ++extern asmlinkage void handle_ri_rdhwr_tlbp(void); + extern asmlinkage void handle_ri_rdhwr(void); + extern asmlinkage void handle_cpu(void); + extern asmlinkage void handle_ov(void); +@@ -2352,9 +2352,18 @@ void __init trap_init(void) + + set_except_vector(EXCCODE_SYS, handle_sys); + set_except_vector(EXCCODE_BP, handle_bp); +- set_except_vector(EXCCODE_RI, rdhwr_noopt ? handle_ri : +- (cpu_has_vtag_icache ? +- handle_ri_rdhwr_vivt : handle_ri_rdhwr)); ++ ++ if (rdhwr_noopt) ++ set_except_vector(EXCCODE_RI, handle_ri); ++ else { ++ if (cpu_has_vtag_icache) ++ set_except_vector(EXCCODE_RI, handle_ri_rdhwr_tlbp); ++ else if (current_cpu_type() == CPU_LOONGSON3) ++ set_except_vector(EXCCODE_RI, handle_ri_rdhwr_tlbp); ++ else ++ set_except_vector(EXCCODE_RI, handle_ri_rdhwr); ++ } ++ + set_except_vector(EXCCODE_CPU, handle_cpu); + set_except_vector(EXCCODE_OV, handle_ov); + set_except_vector(EXCCODE_TR, handle_tr); +diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c +index 9a61671c00a7..90565477dfbd 100644 +--- a/arch/mips/lantiq/xway/sysctrl.c ++++ b/arch/mips/lantiq/xway/sysctrl.c +@@ -467,7 +467,7 @@ void __init ltq_soc_init(void) + + if (!np_xbar) + panic("Failed to load xbar nodes from devicetree"); +- if (of_address_to_resource(np_pmu, 0, &res_xbar)) ++ if (of_address_to_resource(np_xbar, 0, &res_xbar)) + panic("Failed to get xbar resources"); + if (request_mem_region(res_xbar.start, resource_size(&res_xbar), + res_xbar.name) < 0) +diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c +index 88cfaf81c958..9d0107fbb169 100644 +--- a/arch/mips/mm/c-r4k.c ++++ b/arch/mips/mm/c-r4k.c +@@ -1558,6 +1558,7 @@ static void probe_vcache(void) + vcache_size = c->vcache.sets * c->vcache.ways * c->vcache.linesz; + + c->vcache.waybit = 0; ++ c->vcache.waysize = vcache_size / c->vcache.ways; + + pr_info("Unified victim cache %ldkB %s, linesize %d bytes.\n", + vcache_size >> 10, way_string[c->vcache.ways], c->vcache.linesz); +@@ -1660,6 +1661,7 @@ static void __init loongson3_sc_init(void) + /* Loongson-3 has 4 cores, 1MB scache for each. scaches are shared */ + scache_size *= 4; + c->scache.waybit = 0; ++ c->scache.waysize = scache_size / c->scache.ways; + pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n", + scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); + if (scache_size) +diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c +index 55ce39606cb8..2da5649fc545 100644 +--- a/arch/mips/mm/tlbex.c ++++ b/arch/mips/mm/tlbex.c +@@ -762,7 +762,8 @@ static void build_huge_update_entries(u32 **p, unsigned int pte, + static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r, + struct uasm_label **l, + unsigned int pte, +- unsigned int ptr) ++ unsigned int ptr, ++ unsigned int flush) + { + #ifdef CONFIG_SMP + UASM_i_SC(p, pte, 0, ptr); +@@ -771,6 +772,22 @@ static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r, + #else + UASM_i_SW(p, pte, 0, ptr); + #endif ++ if (cpu_has_ftlb && flush) { ++ BUG_ON(!cpu_has_tlbinv); ++ ++ UASM_i_MFC0(p, ptr, C0_ENTRYHI); ++ uasm_i_ori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); ++ UASM_i_MTC0(p, ptr, C0_ENTRYHI); ++ build_tlb_write_entry(p, l, r, tlb_indexed); ++ ++ uasm_i_xori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); ++ UASM_i_MTC0(p, ptr, C0_ENTRYHI); ++ build_huge_update_entries(p, pte, ptr); ++ build_huge_tlb_write_entry(p, l, r, pte, tlb_random, 0); ++ ++ return; ++ } ++ + build_huge_update_entries(p, pte, ptr); + build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed, 0); + } +@@ -2197,7 +2214,7 @@ static void build_r4000_tlb_load_handler(void) + uasm_l_tlbl_goaround2(&l, p); + } + uasm_i_ori(&p, wr.r1, wr.r1, (_PAGE_ACCESSED | _PAGE_VALID)); +- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); ++ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); + #endif + + uasm_l_nopage_tlbl(&l, p); +@@ -2252,7 +2269,7 @@ static void build_r4000_tlb_store_handler(void) + build_tlb_probe_entry(&p); + uasm_i_ori(&p, wr.r1, wr.r1, + _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); +- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); ++ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); + #endif + + uasm_l_nopage_tlbs(&l, p); +@@ -2308,7 +2325,7 @@ static void build_r4000_tlb_modify_handler(void) + build_tlb_probe_entry(&p); + uasm_i_ori(&p, wr.r1, wr.r1, + _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); +- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); ++ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 0); + #endif + + uasm_l_nopage_tlbm(&l, p); +diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c +index 3e0aa09c6b55..9e4631acfcb5 100644 +--- a/arch/mips/ralink/rt3883.c ++++ b/arch/mips/ralink/rt3883.c +@@ -36,7 +36,7 @@ static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) }; + static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; + static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; + static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) }; +-static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna a", 0, 35, 3) }; ++static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna g", 0, 35, 3) }; + static struct rt2880_pmx_func pci_func[] = { + FUNC("pci-dev", 0, 40, 32), + FUNC("pci-host2", 1, 40, 32), +@@ -44,7 +44,7 @@ static struct rt2880_pmx_func pci_func[] = { + FUNC("pci-fnc", 3, 40, 32) + }; + static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) }; +-static struct rt2880_pmx_func ge2_func[] = { FUNC("ge1", 0, 84, 12) }; ++static struct rt2880_pmx_func ge2_func[] = { FUNC("ge2", 0, 84, 12) }; + + static struct rt2880_pmx_group rt3883_pinmux_data[] = { + GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C), +diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c +index 367c5426157b..3901b80d4420 100644 +--- a/arch/nios2/kernel/prom.c ++++ b/arch/nios2/kernel/prom.c +@@ -48,6 +48,13 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) + return alloc_bootmem_align(size, align); + } + ++int __init early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size, ++ bool nomap) ++{ ++ reserve_bootmem(base, size, BOOTMEM_DEFAULT); ++ return 0; ++} ++ + void __init early_init_devtree(void *params) + { + __be32 *dtb = (u32 *)__dtb_start; +diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c +index a3fa80d1aacc..72ef4077bf2b 100644 +--- a/arch/nios2/kernel/setup.c ++++ b/arch/nios2/kernel/setup.c +@@ -200,6 +200,9 @@ void __init setup_arch(char **cmdline_p) + } + #endif /* CONFIG_BLK_DEV_INITRD */ + ++ early_init_fdt_reserve_self(); ++ early_init_fdt_scan_reserved_mem(); ++ + unflatten_and_copy_device_tree(); + + setup_cpuinfo(); +diff --git a/arch/powerpc/crypto/crc32c-vpmsum_glue.c b/arch/powerpc/crypto/crc32c-vpmsum_glue.c +index 411994551afc..f058e0c3e4d4 100644 +--- a/arch/powerpc/crypto/crc32c-vpmsum_glue.c ++++ b/arch/powerpc/crypto/crc32c-vpmsum_glue.c +@@ -33,10 +33,13 @@ static u32 crc32c_vpmsum(u32 crc, unsigned char const *p, size_t len) + } + + if (len & ~VMX_ALIGN_MASK) { ++ preempt_disable(); + pagefault_disable(); + enable_kernel_altivec(); + crc = __crc32c_vpmsum(crc, p, len & ~VMX_ALIGN_MASK); ++ disable_kernel_altivec(); + pagefault_enable(); ++ preempt_enable(); + } + + tail = len & VMX_ALIGN_MASK; +diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c +index 8d58c61908f7..df88d2067348 100644 +--- a/arch/powerpc/kernel/align.c ++++ b/arch/powerpc/kernel/align.c +@@ -807,14 +807,25 @@ int fix_alignment(struct pt_regs *regs) + nb = aligninfo[instr].len; + flags = aligninfo[instr].flags; + +- /* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */ +- if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) { +- nb = 8; +- flags = LD+SW; +- } else if (IS_XFORM(instruction) && +- ((instruction >> 1) & 0x3ff) == 660) { +- nb = 8; +- flags = ST+SW; ++ /* ++ * Handle some cases which give overlaps in the DSISR values. ++ */ ++ if (IS_XFORM(instruction)) { ++ switch (get_xop(instruction)) { ++ case 532: /* ldbrx */ ++ nb = 8; ++ flags = LD+SW; ++ break; ++ case 660: /* stdbrx */ ++ nb = 8; ++ flags = ST+SW; ++ break; ++ case 20: /* lwarx */ ++ case 84: /* ldarx */ ++ case 116: /* lharx */ ++ case 276: /* lqarx */ ++ return 0; /* not emulated ever */ ++ } + } + + /* Byteswap little endian loads and stores */ +diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S +index 32be2a844947..d5f2431daa5e 100644 +--- a/arch/powerpc/kernel/misc_64.S ++++ b/arch/powerpc/kernel/misc_64.S +@@ -67,7 +67,7 @@ PPC64_CACHES: + * flush all bytes from start through stop-1 inclusive + */ + +-_GLOBAL(flush_icache_range) ++_GLOBAL_TOC(flush_icache_range) + BEGIN_FTR_SECTION + PURGE_PREFETCHED_INS + blr +@@ -120,7 +120,7 @@ EXPORT_SYMBOL(flush_icache_range) + * + * flush all bytes from start to stop-1 inclusive + */ +-_GLOBAL(flush_dcache_range) ++_GLOBAL_TOC(flush_dcache_range) + + /* + * Flush the data cache to memory +diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c +index 6824157e4d2e..18a0946837d4 100644 +--- a/arch/powerpc/kernel/setup_64.c ++++ b/arch/powerpc/kernel/setup_64.c +@@ -245,6 +245,15 @@ static void cpu_ready_for_interrupts(void) + mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3); + } + ++ /* ++ * Fixup HFSCR:TM based on CPU features. The bit is set by our ++ * early asm init because at that point we haven't updated our ++ * CPU features from firmware and device-tree. Here we have, ++ * so let's do it. ++ */ ++ if (cpu_has_feature(CPU_FTR_HVMODE) && !cpu_has_feature(CPU_FTR_TM_COMP)) ++ mtspr(SPRN_HFSCR, mfspr(SPRN_HFSCR) & ~HFSCR_TM); ++ + /* Set IR and DR in PACA MSR */ + get_paca()->kernel_msr = MSR_KERNEL; + } +diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c +index cc332608e656..65bb8f33b399 100644 +--- a/arch/powerpc/mm/hash_native_64.c ++++ b/arch/powerpc/mm/hash_native_64.c +@@ -638,6 +638,10 @@ static void native_flush_hash_range(unsigned long number, int local) + unsigned long psize = batch->psize; + int ssize = batch->ssize; + int i; ++ unsigned int use_local; ++ ++ use_local = local && mmu_has_feature(MMU_FTR_TLBIEL) && ++ mmu_psize_defs[psize].tlbiel && !cxl_ctx_in_use(); + + local_irq_save(flags); + +@@ -667,8 +671,7 @@ static void native_flush_hash_range(unsigned long number, int local) + } pte_iterate_hashed_end(); + } + +- if (mmu_has_feature(MMU_FTR_TLBIEL) && +- mmu_psize_defs[psize].tlbiel && local) { ++ if (use_local) { + asm volatile("ptesync":::"memory"); + for (i = 0; i < number; i++) { + vpn = batch->vpn[i]; +diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c +index 8515dd5a5663..bd90448347eb 100644 +--- a/arch/s390/boot/compressed/misc.c ++++ b/arch/s390/boot/compressed/misc.c +@@ -141,31 +141,34 @@ static void check_ipl_parmblock(void *start, unsigned long size) + + unsigned long decompress_kernel(void) + { +- unsigned long output_addr; +- unsigned char *output; ++ void *output, *kernel_end; + +- output_addr = ((unsigned long) &_end + HEAP_SIZE + 4095UL) & -4096UL; +- check_ipl_parmblock((void *) 0, output_addr + SZ__bss_start); +- memset(&_bss, 0, &_ebss - &_bss); +- free_mem_ptr = (unsigned long)&_end; +- free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; +- output = (unsigned char *) output_addr; ++ output = (void *) ALIGN((unsigned long) &_end + HEAP_SIZE, PAGE_SIZE); ++ kernel_end = output + SZ__bss_start; ++ check_ipl_parmblock((void *) 0, (unsigned long) kernel_end); + + #ifdef CONFIG_BLK_DEV_INITRD + /* + * Move the initrd right behind the end of the decompressed +- * kernel image. ++ * kernel image. This also prevents initrd corruption caused by ++ * bss clearing since kernel_end will always be located behind the ++ * current bss section.. + */ +- if (INITRD_START && INITRD_SIZE && +- INITRD_START < (unsigned long) output + SZ__bss_start) { +- check_ipl_parmblock(output + SZ__bss_start, +- INITRD_START + INITRD_SIZE); +- memmove(output + SZ__bss_start, +- (void *) INITRD_START, INITRD_SIZE); +- INITRD_START = (unsigned long) output + SZ__bss_start; ++ if (INITRD_START && INITRD_SIZE && kernel_end > (void *) INITRD_START) { ++ check_ipl_parmblock(kernel_end, INITRD_SIZE); ++ memmove(kernel_end, (void *) INITRD_START, INITRD_SIZE); ++ INITRD_START = (unsigned long) kernel_end; + } + #endif + ++ /* ++ * Clear bss section. free_mem_ptr and free_mem_end_ptr need to be ++ * initialized afterwards since they reside in bss. ++ */ ++ memset(&_bss, 0, &_ebss - &_bss); ++ free_mem_ptr = (unsigned long) &_end; ++ free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; ++ + puts("Uncompressing Linux... "); + __decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error); + puts("Ok, booting the kernel.\n"); +diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h +index f82b04e85a21..7e99fb34ff23 100644 +--- a/arch/s390/include/asm/uaccess.h ++++ b/arch/s390/include/asm/uaccess.h +@@ -144,7 +144,7 @@ unsigned long __must_check __copy_to_user(void __user *to, const void *from, + " jg 2b\n" \ + ".popsection\n" \ + EX_TABLE(0b,3b) EX_TABLE(1b,3b) \ +- : "=d" (__rc), "=Q" (*(to)) \ ++ : "=d" (__rc), "+Q" (*(to)) \ + : "d" (size), "Q" (*(from)), \ + "d" (__reg0), "K" (-EFAULT) \ + : "cc"); \ +diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c +index 537c6647d84c..036fc03aefbd 100644 +--- a/arch/x86/kernel/cpu/mcheck/mce.c ++++ b/arch/x86/kernel/cpu/mcheck/mce.c +@@ -54,6 +54,8 @@ + + static DEFINE_MUTEX(mce_chrdev_read_mutex); + ++static int mce_chrdev_open_count; /* #times opened */ ++ + #define mce_log_get_idx_check(p) \ + ({ \ + RCU_LOCKDEP_WARN(!rcu_read_lock_sched_held() && \ +@@ -601,6 +603,10 @@ static int mce_default_notifier(struct notifier_block *nb, unsigned long val, + if (atomic_read(&num_notifiers) > 2) + return NOTIFY_DONE; + ++ /* Don't print when mcelog is running */ ++ if (mce_chrdev_open_count > 0) ++ return NOTIFY_DONE; ++ + __print_mce(m); + + return NOTIFY_DONE; +@@ -1871,7 +1877,6 @@ void mcheck_cpu_clear(struct cpuinfo_x86 *c) + */ + + static DEFINE_SPINLOCK(mce_chrdev_state_lock); +-static int mce_chrdev_open_count; /* #times opened */ + static int mce_chrdev_open_exclu; /* already open exclusive? */ + + static int mce_chrdev_open(struct inode *inode, struct file *file) +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index e244c19a2451..067f9813fd2c 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -223,6 +223,22 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { + DMI_MATCH(DMI_BOARD_NAME, "P4S800"), + }, + }, ++ { /* Handle problems with rebooting on ASUS EeeBook X205TA */ ++ .callback = set_acpi_reboot, ++ .ident = "ASUS EeeBook X205TA", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X205TA"), ++ }, ++ }, ++ { /* Handle problems with rebooting on ASUS EeeBook X205TAW */ ++ .callback = set_acpi_reboot, ++ .ident = "ASUS EeeBook X205TAW", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "X205TAW"), ++ }, ++ }, + + /* Certec */ + { /* Handle problems with rebooting on Certec BPC600 */ +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 9764463ce833..cce7d2e3be15 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -7086,13 +7086,18 @@ static int nested_vmx_check_vmptr(struct kvm_vcpu *vcpu, int exit_reason, + } + + page = nested_get_page(vcpu, vmptr); +- if (page == NULL || +- *(u32 *)kmap(page) != VMCS12_REVISION) { ++ if (page == NULL) { + nested_vmx_failInvalid(vcpu); ++ return kvm_skip_emulated_instruction(vcpu); ++ } ++ if (*(u32 *)kmap(page) != VMCS12_REVISION) { + kunmap(page); ++ nested_release_page_clean(page); ++ nested_vmx_failInvalid(vcpu); + return kvm_skip_emulated_instruction(vcpu); + } + kunmap(page); ++ nested_release_page_clean(page); + vmx->nested.vmxon_ptr = vmptr; + break; + case EXIT_REASON_VMCLEAR: +diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h +index 976b1d70edbc..4ddbfd57a7c8 100644 +--- a/arch/xtensa/include/asm/page.h ++++ b/arch/xtensa/include/asm/page.h +@@ -164,8 +164,21 @@ void copy_user_highpage(struct page *to, struct page *from, + + #define ARCH_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) + ++#ifdef CONFIG_MMU ++static inline unsigned long ___pa(unsigned long va) ++{ ++ unsigned long off = va - PAGE_OFFSET; ++ ++ if (off >= XCHAL_KSEG_SIZE) ++ off -= XCHAL_KSEG_SIZE; ++ ++ return off + PHYS_OFFSET; ++} ++#define __pa(x) ___pa((unsigned long)(x)) ++#else + #define __pa(x) \ + ((unsigned long) (x) - PAGE_OFFSET + PHYS_OFFSET) ++#endif + #define __va(x) \ + ((void *)((unsigned long) (x) - PHYS_OFFSET + PAGE_OFFSET)) + #define pfn_valid(pfn) \ +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index e19f530f1083..6d5a8c1d3132 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -113,7 +113,7 @@ struct acpi_button { + + static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); + static struct acpi_device *lid_device; +-static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; ++static u8 lid_init_state = ACPI_BUTTON_LID_INIT_OPEN; + + static unsigned long lid_report_interval __read_mostly = 500; + module_param(lid_report_interval, ulong, 0644); +diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c +index fb19e1cdb641..edc8663b5db3 100644 +--- a/drivers/acpi/glue.c ++++ b/drivers/acpi/glue.c +@@ -99,13 +99,13 @@ static int find_child_checks(struct acpi_device *adev, bool check_children) + return -ENODEV; + + /* +- * If the device has a _HID (or _CID) returning a valid ACPI/PNP +- * device ID, it is better to make it look less attractive here, so that +- * the other device with the same _ADR value (that may not have a valid +- * device ID) can be matched going forward. [This means a second spec +- * violation in a row, so whatever we do here is best effort anyway.] ++ * If the device has a _HID returning a valid ACPI/PNP device ID, it is ++ * better to make it look less attractive here, so that the other device ++ * with the same _ADR value (that may not have a valid device ID) can be ++ * matched going forward. [This means a second spec violation in a row, ++ * so whatever we do here is best effort anyway.] + */ +- return sta_present && list_empty(&adev->pnp.ids) ? ++ return sta_present && !adev->pnp.type.platform_id ? + FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE; + } + +diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c +index 54abb26b7366..a4327af676fe 100644 +--- a/drivers/acpi/sleep.c ++++ b/drivers/acpi/sleep.c +@@ -130,6 +130,12 @@ void __init acpi_nvs_nosave_s3(void) + nvs_nosave_s3 = true; + } + ++static int __init init_nvs_save_s3(const struct dmi_system_id *d) ++{ ++ nvs_nosave_s3 = false; ++ return 0; ++} ++ + /* + * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the + * user to request that behavior by using the 'acpi_old_suspend_ordering' +@@ -324,6 +330,19 @@ static struct dmi_system_id acpisleep_dmi_table[] __initdata = { + DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"), + }, + }, ++ /* ++ * https://bugzilla.kernel.org/show_bug.cgi?id=189431 ++ * Lenovo G50-45 is a platform later than 2012, but needs nvs memory ++ * saving during S3. ++ */ ++ { ++ .callback = init_nvs_save_s3, ++ .ident = "Lenovo G50-45", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "80E3"), ++ }, ++ }, + {}, + }; + +diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c +index 267a3d3e79f4..52f2674d5e89 100644 +--- a/drivers/ata/ahci_da850.c ++++ b/drivers/ata/ahci_da850.c +@@ -54,11 +54,42 @@ static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg, + writel(val, ahci_base + SATA_P0PHYCR_REG); + } + ++static int ahci_da850_softreset(struct ata_link *link, ++ unsigned int *class, unsigned long deadline) ++{ ++ int pmp, ret; ++ ++ pmp = sata_srst_pmp(link); ++ ++ /* ++ * There's an issue with the SATA controller on da850 SoCs: if we ++ * enable Port Multiplier support, but the drive is connected directly ++ * to the board, it can't be detected. As a workaround: if PMP is ++ * enabled, we first call ahci_do_softreset() and pass it the result of ++ * sata_srst_pmp(). If this call fails, we retry with pmp = 0. ++ */ ++ ret = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready); ++ if (pmp && ret == -EBUSY) ++ return ahci_do_softreset(link, class, 0, ++ deadline, ahci_check_ready); ++ ++ return ret; ++} ++ ++static struct ata_port_operations ahci_da850_port_ops = { ++ .inherits = &ahci_platform_ops, ++ .softreset = ahci_da850_softreset, ++ /* ++ * No need to override .pmp_softreset - it's only used for actual ++ * PMP-enabled ports. ++ */ ++}; ++ + static const struct ata_port_info ahci_da850_port_info = { + .flags = AHCI_FLAG_COMMON, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, +- .port_ops = &ahci_platform_ops, ++ .port_ops = &ahci_da850_port_ops, + }; + + static struct scsi_host_template ahci_platform_sht = { +diff --git a/drivers/char/random.c b/drivers/char/random.c +index 1ef26403bcc8..433facfd6cb8 100644 +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -2042,63 +2042,65 @@ struct ctl_table random_table[] = { + }; + #endif /* CONFIG_SYSCTL */ + +-static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; +- +-int random_int_secret_init(void) +-{ +- get_random_bytes(random_int_secret, sizeof(random_int_secret)); +- return 0; +-} +- +-static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash) +- __aligned(sizeof(unsigned long)); ++struct batched_entropy { ++ union { ++ unsigned long entropy_long[CHACHA20_BLOCK_SIZE / sizeof(unsigned long)]; ++ unsigned int entropy_int[CHACHA20_BLOCK_SIZE / sizeof(unsigned int)]; ++ }; ++ unsigned int position; ++}; + + /* +- * Get a random word for internal kernel use only. Similar to urandom but +- * with the goal of minimal entropy pool depletion. As a result, the random +- * value is not cryptographically secure but for several uses the cost of +- * depleting entropy is too high ++ * Get a random word for internal kernel use only. The quality of the random ++ * number is either as good as RDRAND or as good as /dev/urandom, with the ++ * goal of being quite fast and not depleting entropy. + */ +-unsigned int get_random_int(void) ++static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_long); ++unsigned long get_random_long(void) + { +- __u32 *hash; +- unsigned int ret; ++ unsigned long ret; ++ struct batched_entropy *batch; + +- if (arch_get_random_int(&ret)) ++ if (arch_get_random_long(&ret)) + return ret; + +- hash = get_cpu_var(get_random_int_hash); +- +- hash[0] += current->pid + jiffies + random_get_entropy(); +- md5_transform(hash, random_int_secret); +- ret = hash[0]; +- put_cpu_var(get_random_int_hash); +- ++ batch = &get_cpu_var(batched_entropy_long); ++ if (batch->position % ARRAY_SIZE(batch->entropy_long) == 0) { ++ extract_crng((u8 *)batch->entropy_long); ++ batch->position = 0; ++ } ++ ret = batch->entropy_long[batch->position++]; ++ put_cpu_var(batched_entropy_long); + return ret; + } +-EXPORT_SYMBOL(get_random_int); ++EXPORT_SYMBOL(get_random_long); + +-/* +- * Same as get_random_int(), but returns unsigned long. +- */ +-unsigned long get_random_long(void) ++#if BITS_PER_LONG == 32 ++unsigned int get_random_int(void) + { +- __u32 *hash; +- unsigned long ret; ++ return get_random_long(); ++} ++#else ++static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_int); ++unsigned int get_random_int(void) ++{ ++ unsigned int ret; ++ struct batched_entropy *batch; + +- if (arch_get_random_long(&ret)) ++ if (arch_get_random_int(&ret)) + return ret; + +- hash = get_cpu_var(get_random_int_hash); +- +- hash[0] += current->pid + jiffies + random_get_entropy(); +- md5_transform(hash, random_int_secret); +- ret = *(unsigned long *)hash; +- put_cpu_var(get_random_int_hash); +- ++ batch = &get_cpu_var(batched_entropy_int); ++ if (batch->position % ARRAY_SIZE(batch->entropy_int) == 0) { ++ extract_crng((u8 *)batch->entropy_int); ++ batch->position = 0; ++ } ++ ret = batch->entropy_int[batch->position++]; ++ put_cpu_var(batched_entropy_int); + return ret; + } +-EXPORT_SYMBOL(get_random_long); ++#endif ++EXPORT_SYMBOL(get_random_int); + + /** + * randomize_page - Generate a random, page aligned address +diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c +index 4a0f5ead4fb5..1e2e5198db53 100644 +--- a/drivers/firmware/qcom_scm-64.c ++++ b/drivers/firmware/qcom_scm-64.c +@@ -91,6 +91,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, + dma_addr_t args_phys = 0; + void *args_virt = NULL; + size_t alloc_len; ++ struct arm_smccc_quirk quirk = {.id = ARM_SMCCC_QUIRK_QCOM_A6}; + + if (unlikely(arglen > N_REGISTER_ARGS)) { + alloc_len = N_EXT_QCOM_SCM_ARGS * sizeof(u64); +@@ -131,10 +132,16 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, + qcom_smccc_convention, + ARM_SMCCC_OWNER_SIP, fn_id); + ++ quirk.state.a6 = 0; ++ + do { +- arm_smccc_smc(cmd, desc->arginfo, desc->args[0], +- desc->args[1], desc->args[2], x5, 0, 0, +- res); ++ arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0], ++ desc->args[1], desc->args[2], x5, ++ quirk.state.a6, 0, res, &quirk); ++ ++ if (res->a0 == QCOM_SCM_INTERRUPTED) ++ cmd = res->a0; ++ + } while (res->a0 == QCOM_SCM_INTERRUPTED); + + mutex_unlock(&qcom_scm_lock); +diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c +index a3faefa44f68..d3f9f028a37b 100644 +--- a/drivers/gpio/gpiolib-acpi.c ++++ b/drivers/gpio/gpiolib-acpi.c +@@ -572,8 +572,10 @@ struct gpio_desc *acpi_find_gpio(struct device *dev, + } + + desc = acpi_get_gpiod_by_index(adev, propname, idx, &info); +- if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER)) ++ if (!IS_ERR(desc)) + break; ++ if (PTR_ERR(desc) == -EPROBE_DEFER) ++ return ERR_CAST(desc); + } + + /* Then from plain _CRS GPIOs */ +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index ec6474b01dbc..7cce86933000 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -90,7 +90,7 @@ struct detailed_mode_closure { + #define LEVEL_GTF2 2 + #define LEVEL_CVT 3 + +-static struct edid_quirk { ++static const struct edid_quirk { + char vendor[4]; + int product_id; + u32 quirks; +@@ -1480,7 +1480,7 @@ EXPORT_SYMBOL(drm_edid_duplicate); + * + * Returns true if @vendor is in @edid, false otherwise + */ +-static bool edid_vendor(struct edid *edid, char *vendor) ++static bool edid_vendor(struct edid *edid, const char *vendor) + { + char edid_vendor[3]; + +@@ -1500,7 +1500,7 @@ static bool edid_vendor(struct edid *edid, char *vendor) + */ + static u32 edid_get_quirks(struct edid *edid) + { +- struct edid_quirk *quirk; ++ const struct edid_quirk *quirk; + int i; + + for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) { +diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c +index 325cb9b55989..5f30a0716531 100644 +--- a/drivers/gpu/drm/i915/gvt/kvmgt.c ++++ b/drivers/gpu/drm/i915/gvt/kvmgt.c +@@ -1422,7 +1422,7 @@ static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa, + { + struct kvmgt_guest_info *info; + struct kvm *kvm; +- int ret; ++ int idx, ret; + bool kthread = current->mm == NULL; + + if (!handle_valid(handle)) +@@ -1434,8 +1434,10 @@ static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa, + if (kthread) + use_mm(kvm->mm); + ++ idx = srcu_read_lock(&kvm->srcu); + ret = write ? kvm_write_guest(kvm, gpa, buf, len) : + kvm_read_guest(kvm, gpa, buf, len); ++ srcu_read_unlock(&kvm->srcu, idx); + + if (kthread) + unuse_mm(kvm->mm); +diff --git a/drivers/gpu/drm/i915/gvt/sched_policy.c b/drivers/gpu/drm/i915/gvt/sched_policy.c +index 678b0be85376..3635dbe328ef 100644 +--- a/drivers/gpu/drm/i915/gvt/sched_policy.c ++++ b/drivers/gpu/drm/i915/gvt/sched_policy.c +@@ -101,7 +101,7 @@ struct tbs_sched_data { + struct list_head runq_head; + }; + +-#define GVT_DEFAULT_TIME_SLICE (1 * HZ / 1000) ++#define GVT_DEFAULT_TIME_SLICE (msecs_to_jiffies(1)) + + static void tbs_sched_func(struct work_struct *work) + { +@@ -224,7 +224,7 @@ static void tbs_sched_start_schedule(struct intel_vgpu *vgpu) + return; + + list_add_tail(&vgpu_data->list, &sched_data->runq_head); +- schedule_delayed_work(&sched_data->work, sched_data->period); ++ schedule_delayed_work(&sched_data->work, 0); + } + + static void tbs_sched_stop_schedule(struct intel_vgpu *vgpu) +diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c +index fce8e198bc76..08e274e16165 100644 +--- a/drivers/gpu/drm/i915/i915_pci.c ++++ b/drivers/gpu/drm/i915/i915_pci.c +@@ -421,6 +421,7 @@ static const struct pci_device_id pciidlist[] = { + INTEL_VLV_IDS(&intel_valleyview_info), + INTEL_BDW_GT12_IDS(&intel_broadwell_info), + INTEL_BDW_GT3_IDS(&intel_broadwell_gt3_info), ++ INTEL_BDW_RSVD_IDS(&intel_broadwell_info), + INTEL_CHV_IDS(&intel_cherryview_info), + INTEL_SKL_GT1_IDS(&intel_skylake_info), + INTEL_SKL_GT2_IDS(&intel_skylake_info), +diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c +index 1f2f9ca25901..4556e2b13ac5 100644 +--- a/drivers/gpu/drm/mga/mga_dma.c ++++ b/drivers/gpu/drm/mga/mga_dma.c +@@ -392,6 +392,24 @@ int mga_driver_load(struct drm_device *dev, unsigned long flags) + drm_mga_private_t *dev_priv; + int ret; + ++ /* There are PCI versions of the G450. These cards have the ++ * same PCI ID as the AGP G450, but have an additional PCI-to-PCI ++ * bridge chip. We detect these cards, which are not currently ++ * supported by this driver, by looking at the device ID of the ++ * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the ++ * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the ++ * device. ++ */ ++ if ((dev->pdev->device == 0x0525) && dev->pdev->bus->self ++ && (dev->pdev->bus->self->vendor == 0x3388) ++ && (dev->pdev->bus->self->device == 0x0021) ++ && dev->agp) { ++ /* FIXME: This should be quirked in the pci core, but oh well ++ * the hw probably stopped existing. */ ++ arch_phys_wc_del(dev->agp->agp_mtrr); ++ kfree(dev->agp); ++ dev->agp = NULL; ++ } + dev_priv = kzalloc(sizeof(drm_mga_private_t), GFP_KERNEL); + if (!dev_priv) + return -ENOMEM; +@@ -698,7 +716,7 @@ static int mga_do_pci_dma_bootstrap(struct drm_device *dev, + static int mga_do_dma_bootstrap(struct drm_device *dev, + drm_mga_dma_bootstrap_t *dma_bs) + { +- const int is_agp = (dma_bs->agp_mode != 0) && drm_pci_device_is_agp(dev); ++ const int is_agp = (dma_bs->agp_mode != 0) && dev->agp; + int err; + drm_mga_private_t *const dev_priv = + (drm_mga_private_t *) dev->dev_private; +diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c +index 25b2a1a424e6..63ba0699d107 100644 +--- a/drivers/gpu/drm/mga/mga_drv.c ++++ b/drivers/gpu/drm/mga/mga_drv.c +@@ -37,8 +37,6 @@ + + #include <drm/drm_pciids.h> + +-static int mga_driver_device_is_agp(struct drm_device *dev); +- + static struct pci_device_id pciidlist[] = { + mga_PCI_IDS + }; +@@ -66,7 +64,6 @@ static struct drm_driver driver = { + .lastclose = mga_driver_lastclose, + .set_busid = drm_pci_set_busid, + .dma_quiescent = mga_driver_dma_quiescent, +- .device_is_agp = mga_driver_device_is_agp, + .get_vblank_counter = mga_get_vblank_counter, + .enable_vblank = mga_enable_vblank, + .disable_vblank = mga_disable_vblank, +@@ -107,37 +104,3 @@ module_exit(mga_exit); + MODULE_AUTHOR(DRIVER_AUTHOR); + MODULE_DESCRIPTION(DRIVER_DESC); + MODULE_LICENSE("GPL and additional rights"); +- +-/** +- * Determine if the device really is AGP or not. +- * +- * In addition to the usual tests performed by \c drm_device_is_agp, this +- * function detects PCI G450 cards that appear to the system exactly like +- * AGP G450 cards. +- * +- * \param dev The device to be tested. +- * +- * \returns +- * If the device is a PCI G450, zero is returned. Otherwise 2 is returned. +- */ +-static int mga_driver_device_is_agp(struct drm_device *dev) +-{ +- const struct pci_dev *const pdev = dev->pdev; +- +- /* There are PCI versions of the G450. These cards have the +- * same PCI ID as the AGP G450, but have an additional PCI-to-PCI +- * bridge chip. We detect these cards, which are not currently +- * supported by this driver, by looking at the device ID of the +- * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the +- * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the +- * device. +- */ +- +- if ((pdev->device == 0x0525) && pdev->bus->self +- && (pdev->bus->self->vendor == 0x3388) +- && (pdev->bus->self->device == 0x0021)) { +- return 0; +- } +- +- return 2; +-} +diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +index b8647198c11c..657874077400 100644 +--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +@@ -846,7 +846,9 @@ static const struct adreno_gpu_funcs funcs = { + .idle = a5xx_idle, + .irq = a5xx_irq, + .destroy = a5xx_destroy, ++#ifdef CONFIG_DEBUG_FS + .show = a5xx_show, ++#endif + }, + .get_timestamp = a5xx_get_timestamp, + }; +diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c +index 4f5fa8d65fe9..144367c0c28f 100644 +--- a/drivers/gpu/drm/ttm/ttm_object.c ++++ b/drivers/gpu/drm/ttm/ttm_object.c +@@ -179,7 +179,7 @@ int ttm_base_object_init(struct ttm_object_file *tfile, + if (unlikely(ret != 0)) + goto out_err0; + +- ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL); ++ ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false); + if (unlikely(ret != 0)) + goto out_err1; + +@@ -318,7 +318,8 @@ EXPORT_SYMBOL(ttm_ref_object_exists); + + int ttm_ref_object_add(struct ttm_object_file *tfile, + struct ttm_base_object *base, +- enum ttm_ref_type ref_type, bool *existed) ++ enum ttm_ref_type ref_type, bool *existed, ++ bool require_existed) + { + struct drm_open_hash *ht = &tfile->ref_hash[ref_type]; + struct ttm_ref_object *ref; +@@ -345,6 +346,9 @@ int ttm_ref_object_add(struct ttm_object_file *tfile, + } + + rcu_read_unlock(); ++ if (require_existed) ++ return -EPERM; ++ + ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref), + false, false); + if (unlikely(ret != 0)) +@@ -635,7 +639,7 @@ int ttm_prime_fd_to_handle(struct ttm_object_file *tfile, + prime = (struct ttm_prime_object *) dma_buf->priv; + base = &prime->base; + *handle = base->hash.key; +- ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL); ++ ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false); + + dma_buf_put(dma_buf); + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +index 6541dd8b82dc..6b2708b4eafe 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +@@ -538,7 +538,7 @@ int vmw_fence_create(struct vmw_fence_manager *fman, + struct vmw_fence_obj **p_fence) + { + struct vmw_fence_obj *fence; +- int ret; ++ int ret; + + fence = kzalloc(sizeof(*fence), GFP_KERNEL); + if (unlikely(fence == NULL)) +@@ -701,6 +701,41 @@ void vmw_fence_fifo_up(struct vmw_fence_manager *fman) + } + + ++/** ++ * vmw_fence_obj_lookup - Look up a user-space fence object ++ * ++ * @tfile: A struct ttm_object_file identifying the caller. ++ * @handle: A handle identifying the fence object. ++ * @return: A struct vmw_user_fence base ttm object on success or ++ * an error pointer on failure. ++ * ++ * The fence object is looked up and type-checked. The caller needs ++ * to have opened the fence object first, but since that happens on ++ * creation and fence objects aren't shareable, that's not an ++ * issue currently. ++ */ ++static struct ttm_base_object * ++vmw_fence_obj_lookup(struct ttm_object_file *tfile, u32 handle) ++{ ++ struct ttm_base_object *base = ttm_base_object_lookup(tfile, handle); ++ ++ if (!base) { ++ pr_err("Invalid fence object handle 0x%08lx.\n", ++ (unsigned long)handle); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ if (base->refcount_release != vmw_user_fence_base_release) { ++ pr_err("Invalid fence object handle 0x%08lx.\n", ++ (unsigned long)handle); ++ ttm_base_object_unref(&base); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ return base; ++} ++ ++ + int vmw_fence_obj_wait_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { +@@ -726,13 +761,9 @@ int vmw_fence_obj_wait_ioctl(struct drm_device *dev, void *data, + arg->kernel_cookie = jiffies + wait_timeout; + } + +- base = ttm_base_object_lookup(tfile, arg->handle); +- if (unlikely(base == NULL)) { +- printk(KERN_ERR "Wait invalid fence object handle " +- "0x%08lx.\n", +- (unsigned long)arg->handle); +- return -EINVAL; +- } ++ base = vmw_fence_obj_lookup(tfile, arg->handle); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); + + fence = &(container_of(base, struct vmw_user_fence, base)->fence); + +@@ -771,13 +802,9 @@ int vmw_fence_obj_signaled_ioctl(struct drm_device *dev, void *data, + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + struct vmw_private *dev_priv = vmw_priv(dev); + +- base = ttm_base_object_lookup(tfile, arg->handle); +- if (unlikely(base == NULL)) { +- printk(KERN_ERR "Fence signaled invalid fence object handle " +- "0x%08lx.\n", +- (unsigned long)arg->handle); +- return -EINVAL; +- } ++ base = vmw_fence_obj_lookup(tfile, arg->handle); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); + + fence = &(container_of(base, struct vmw_user_fence, base)->fence); + fman = fman_from_fence(fence); +@@ -1024,6 +1051,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, + (struct drm_vmw_fence_event_arg *) data; + struct vmw_fence_obj *fence = NULL; + struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); ++ struct ttm_object_file *tfile = vmw_fp->tfile; + struct drm_vmw_fence_rep __user *user_fence_rep = + (struct drm_vmw_fence_rep __user *)(unsigned long) + arg->fence_rep; +@@ -1037,24 +1065,18 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, + */ + if (arg->handle) { + struct ttm_base_object *base = +- ttm_base_object_lookup_for_ref(dev_priv->tdev, +- arg->handle); +- +- if (unlikely(base == NULL)) { +- DRM_ERROR("Fence event invalid fence object handle " +- "0x%08lx.\n", +- (unsigned long)arg->handle); +- return -EINVAL; +- } ++ vmw_fence_obj_lookup(tfile, arg->handle); ++ ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ + fence = &(container_of(base, struct vmw_user_fence, + base)->fence); + (void) vmw_fence_obj_reference(fence); + + if (user_fence_rep != NULL) { +- bool existed; +- + ret = ttm_ref_object_add(vmw_fp->tfile, base, +- TTM_REF_USAGE, &existed); ++ TTM_REF_USAGE, NULL, false); + if (unlikely(ret != 0)) { + DRM_ERROR("Failed to reference a fence " + "object.\n"); +@@ -1097,8 +1119,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, + return 0; + out_no_create: + if (user_fence_rep != NULL) +- ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, +- handle, TTM_REF_USAGE); ++ ttm_ref_object_base_unref(tfile, handle, TTM_REF_USAGE); + out_no_ref_obj: + vmw_fence_obj_unreference(&fence); + return ret; +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +index b8c6a03c8c54..5ec24fd801cd 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +@@ -114,8 +114,6 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, + param->value = dev_priv->has_dx; + break; + default: +- DRM_ERROR("Illegal vmwgfx get param request: %d\n", +- param->param); + return -EINVAL; + } + +@@ -186,7 +184,7 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, + bool gb_objects = !!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS); + struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); + +- if (unlikely(arg->pad64 != 0)) { ++ if (unlikely(arg->pad64 != 0 || arg->max_size == 0)) { + DRM_ERROR("Illegal GET_3D_CAP argument.\n"); + return -EINVAL; + } +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +index 8e86d6d4141b..53fa9f1c1d10 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +@@ -589,7 +589,7 @@ static int vmw_user_dmabuf_synccpu_grab(struct vmw_user_dma_buffer *user_bo, + return ret; + + ret = ttm_ref_object_add(tfile, &user_bo->prime.base, +- TTM_REF_SYNCCPU_WRITE, &existed); ++ TTM_REF_SYNCCPU_WRITE, &existed, false); + if (ret != 0 || existed) + ttm_bo_synccpu_write_release(&user_bo->dma.base); + +@@ -773,7 +773,7 @@ int vmw_user_dmabuf_reference(struct ttm_object_file *tfile, + + *handle = user_bo->prime.base.hash.key; + return ttm_ref_object_add(tfile, &user_bo->prime.base, +- TTM_REF_USAGE, NULL); ++ TTM_REF_USAGE, NULL, false); + } + + /* +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +index b445ce9b9757..05fa092c942b 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +@@ -713,11 +713,14 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, + 128; + + num_sizes = 0; +- for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) ++ for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) { ++ if (req->mip_levels[i] > DRM_VMW_MAX_MIP_LEVELS) ++ return -EINVAL; + num_sizes += req->mip_levels[i]; ++ } + +- if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * +- DRM_VMW_MAX_MIP_LEVELS) ++ if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS || ++ num_sizes == 0) + return -EINVAL; + + size = vmw_user_surface_size + 128 + +@@ -891,17 +894,16 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv, + uint32_t handle; + struct ttm_base_object *base; + int ret; ++ bool require_exist = false; + + if (handle_type == DRM_VMW_HANDLE_PRIME) { + ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle); + if (unlikely(ret != 0)) + return ret; + } else { +- if (unlikely(drm_is_render_client(file_priv))) { +- DRM_ERROR("Render client refused legacy " +- "surface reference.\n"); +- return -EACCES; +- } ++ if (unlikely(drm_is_render_client(file_priv))) ++ require_exist = true; ++ + if (ACCESS_ONCE(vmw_fpriv(file_priv)->locked_master)) { + DRM_ERROR("Locked master refused legacy " + "surface reference.\n"); +@@ -929,17 +931,14 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv, + + /* + * Make sure the surface creator has the same +- * authenticating master. ++ * authenticating master, or is already registered with us. + */ + if (drm_is_primary_client(file_priv) && +- user_srf->master != file_priv->master) { +- DRM_ERROR("Trying to reference surface outside of" +- " master domain.\n"); +- ret = -EACCES; +- goto out_bad_resource; +- } ++ user_srf->master != file_priv->master) ++ require_exist = true; + +- ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL); ++ ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, ++ require_exist); + if (unlikely(ret != 0)) { + DRM_ERROR("Could not add a reference to a surface.\n"); + goto out_bad_resource; +diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c +index 672145b0d8f5..6ef4f2fcfe43 100644 +--- a/drivers/hid/wacom_wac.c ++++ b/drivers/hid/wacom_wac.c +@@ -3290,6 +3290,9 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, + { + struct wacom_features *features = &wacom_wac->features; + ++ if ((features->type == HID_GENERIC) && features->numbered_buttons > 0) ++ features->device_type |= WACOM_DEVICETYPE_PAD; ++ + if (!(features->device_type & WACOM_DEVICETYPE_PAD)) + return -ENODEV; + +diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c +index f7fcfa886f72..821919dd245b 100644 +--- a/drivers/iio/gyro/bmg160_core.c ++++ b/drivers/iio/gyro/bmg160_core.c +@@ -27,6 +27,7 @@ + #include <linux/iio/trigger_consumer.h> + #include <linux/iio/triggered_buffer.h> + #include <linux/regmap.h> ++#include <linux/delay.h> + #include "bmg160.h" + + #define BMG160_IRQ_NAME "bmg160_event" +@@ -52,6 +53,9 @@ + #define BMG160_DEF_BW 100 + #define BMG160_REG_PMU_BW_RES BIT(7) + ++#define BMG160_GYRO_REG_RESET 0x14 ++#define BMG160_GYRO_RESET_VAL 0xb6 ++ + #define BMG160_REG_INT_MAP_0 0x17 + #define BMG160_INT_MAP_0_BIT_ANY BIT(1) + +@@ -236,6 +240,14 @@ static int bmg160_chip_init(struct bmg160_data *data) + int ret; + unsigned int val; + ++ /* ++ * Reset chip to get it in a known good state. A delay of 30ms after ++ * reset is required according to the datasheet. ++ */ ++ regmap_write(data->regmap, BMG160_GYRO_REG_RESET, ++ BMG160_GYRO_RESET_VAL); ++ usleep_range(30000, 30700); ++ + ret = regmap_read(data->regmap, BMG160_REG_CHIP_ID, &val); + if (ret < 0) { + dev_err(dev, "Error reading reg_chip_id\n"); +diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c +index aaca42862389..d9c15e411e10 100644 +--- a/drivers/iio/industrialio-core.c ++++ b/drivers/iio/industrialio-core.c +@@ -608,10 +608,9 @@ static ssize_t __iio_format_value(char *buf, size_t len, unsigned int type, + tmp0 = (int)div_s64_rem(tmp, 1000000000, &tmp1); + return snprintf(buf, len, "%d.%09u", tmp0, abs(tmp1)); + case IIO_VAL_FRACTIONAL_LOG2: +- tmp = (s64)vals[0] * 1000000000LL >> vals[1]; +- tmp1 = do_div(tmp, 1000000000LL); +- tmp0 = tmp; +- return snprintf(buf, len, "%d.%09u", tmp0, tmp1); ++ tmp = shift_right((s64)vals[0] * 1000000000LL, vals[1]); ++ tmp0 = (int)div_s64_rem(tmp, 1000000000LL, &tmp1); ++ return snprintf(buf, len, "%d.%09u", tmp0, abs(tmp1)); + case IIO_VAL_INT_MULTIPLE: + { + int i; +diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c +index e19e0787864c..f82560a4f772 100644 +--- a/drivers/iio/pressure/st_pressure_core.c ++++ b/drivers/iio/pressure/st_pressure_core.c +@@ -455,6 +455,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = { + .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, + }, + .multi_read_bit = true, ++ .bootime = 2, + }, + }; + +diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c +index 4a157b0f4155..fd4f3ace200b 100644 +--- a/drivers/md/dm-raid.c ++++ b/drivers/md/dm-raid.c +@@ -3594,7 +3594,7 @@ static int raid_preresume(struct dm_target *ti) + return r; + + /* Resize bitmap to adjust to changed region size (aka MD bitmap chunksize) */ +- if (test_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags) && ++ if (test_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags) && mddev->bitmap && + mddev->bitmap_info.chunksize != to_bytes(rs->requested_bitmap_chunk_sectors)) { + r = bitmap_resize(mddev->bitmap, mddev->dev_sectors, + to_bytes(rs->requested_bitmap_chunk_sectors), 0); +diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c +index 0f0eb8a3d922..78f36012eaca 100644 +--- a/drivers/md/dm-verity-fec.c ++++ b/drivers/md/dm-verity-fec.c +@@ -146,8 +146,6 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio, + block = fec_buffer_rs_block(v, fio, n, i); + res = fec_decode_rs8(v, fio, block, &par[offset], neras); + if (res < 0) { +- dm_bufio_release(buf); +- + r = res; + goto error; + } +@@ -172,6 +170,8 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio, + done: + r = corrected; + error: ++ dm_bufio_release(buf); ++ + if (r < 0 && neras) + DMERR_LIMIT("%s: FEC %llu: failed to correct: %d", + v->data_dev->name, (unsigned long long)rsb, r); +@@ -269,7 +269,7 @@ static int fec_read_bufs(struct dm_verity *v, struct dm_verity_io *io, + &is_zero) == 0) { + /* skip known zero blocks entirely */ + if (is_zero) +- continue; ++ goto done; + + /* + * skip if we have already found the theoretical +@@ -439,6 +439,13 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, + if (!verity_fec_is_enabled(v)) + return -EOPNOTSUPP; + ++ if (fio->level >= DM_VERITY_FEC_MAX_RECURSION) { ++ DMWARN_LIMIT("%s: FEC: recursion too deep", v->data_dev->name); ++ return -EIO; ++ } ++ ++ fio->level++; ++ + if (type == DM_VERITY_BLOCK_TYPE_METADATA) + block += v->data_blocks; + +@@ -470,7 +477,7 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, + if (r < 0) { + r = fec_decode_rsb(v, io, fio, rsb, offset, true); + if (r < 0) +- return r; ++ goto done; + } + + if (dest) +@@ -480,6 +487,8 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, + r = verity_for_bv_block(v, io, iter, fec_bv_copy); + } + ++done: ++ fio->level--; + return r; + } + +@@ -520,6 +529,7 @@ void verity_fec_init_io(struct dm_verity_io *io) + memset(fio->bufs, 0, sizeof(fio->bufs)); + fio->nbufs = 0; + fio->output = NULL; ++ fio->level = 0; + } + + /* +diff --git a/drivers/md/dm-verity-fec.h b/drivers/md/dm-verity-fec.h +index 7fa0298b995e..bb31ce87a933 100644 +--- a/drivers/md/dm-verity-fec.h ++++ b/drivers/md/dm-verity-fec.h +@@ -27,6 +27,9 @@ + #define DM_VERITY_FEC_BUF_MAX \ + (1 << (PAGE_SHIFT - DM_VERITY_FEC_BUF_RS_BITS)) + ++/* maximum recursion level for verity_fec_decode */ ++#define DM_VERITY_FEC_MAX_RECURSION 4 ++ + #define DM_VERITY_OPT_FEC_DEV "use_fec_from_device" + #define DM_VERITY_OPT_FEC_BLOCKS "fec_blocks" + #define DM_VERITY_OPT_FEC_START "fec_start" +@@ -58,6 +61,7 @@ struct dm_verity_fec_io { + unsigned nbufs; /* number of buffers allocated */ + u8 *output; /* buffer for corrected output */ + size_t output_pos; ++ unsigned level; /* recursion level */ + }; + + #ifdef CONFIG_DM_VERITY_FEC +diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c +index 9a6eb4492172..364f6b87a728 100644 +--- a/drivers/mmc/host/sdhci-of-esdhc.c ++++ b/drivers/mmc/host/sdhci-of-esdhc.c +@@ -569,16 +569,19 @@ static const struct sdhci_ops sdhci_esdhc_le_ops = { + }; + + static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = { +- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION +- | SDHCI_QUIRK_NO_CARD_NO_RESET +- | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, ++ .quirks = ESDHC_DEFAULT_QUIRKS | ++#ifdef CONFIG_PPC ++ SDHCI_QUIRK_BROKEN_CARD_DETECTION | ++#endif ++ SDHCI_QUIRK_NO_CARD_NO_RESET | ++ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, + .ops = &sdhci_esdhc_be_ops, + }; + + static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = { +- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION +- | SDHCI_QUIRK_NO_CARD_NO_RESET +- | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, ++ .quirks = ESDHC_DEFAULT_QUIRKS | ++ SDHCI_QUIRK_NO_CARD_NO_RESET | ++ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, + .ops = &sdhci_esdhc_le_ops, + }; + +@@ -643,8 +646,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev) + of_device_is_compatible(np, "fsl,p5020-esdhc") || + of_device_is_compatible(np, "fsl,p4080-esdhc") || + of_device_is_compatible(np, "fsl,p1020-esdhc") || +- of_device_is_compatible(np, "fsl,t1040-esdhc") || +- of_device_is_compatible(np, "fsl,ls1021a-esdhc")) ++ of_device_is_compatible(np, "fsl,t1040-esdhc")) + host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; + + if (of_device_is_compatible(np, "fsl,ls1021a-esdhc")) +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +index de19c7c92bc6..85d949e03f79 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -2238,14 +2238,16 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) + struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); + struct brcmf_p2p_info *p2p = &cfg->p2p; + struct brcmf_cfg80211_vif *vif; ++ enum nl80211_iftype iftype; + bool wait_for_disable = false; + int err; + + brcmf_dbg(TRACE, "delete P2P vif\n"); + vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); + ++ iftype = vif->wdev.iftype; + brcmf_cfg80211_arm_vif_event(cfg, vif); +- switch (vif->wdev.iftype) { ++ switch (iftype) { + case NL80211_IFTYPE_P2P_CLIENT: + if (test_bit(BRCMF_VIF_STATUS_DISCONNECTING, &vif->sme_state)) + wait_for_disable = true; +@@ -2275,7 +2277,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) + BRCMF_P2P_DISABLE_TIMEOUT); + + err = 0; +- if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) { ++ if (iftype != NL80211_IFTYPE_P2P_DEVICE) { + brcmf_vif_clear_mgmt_ies(vif); + err = brcmf_p2p_release_p2p_if(vif); + } +@@ -2291,7 +2293,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) + brcmf_remove_interface(vif->ifp, true); + + brcmf_cfg80211_arm_vif_event(cfg, NULL); +- if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) ++ if (iftype != NL80211_IFTYPE_P2P_DEVICE) + p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL; + + return err; +diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c +index e354010fb006..cea581414e10 100644 +--- a/drivers/pci/host/pci-thunder-pem.c ++++ b/drivers/pci/host/pci-thunder-pem.c +@@ -14,6 +14,7 @@ + * Copyright (C) 2015 - 2016 Cavium, Inc. + */ + ++#include <linux/bitfield.h> + #include <linux/kernel.h> + #include <linux/init.h> + #include <linux/of_address.h> +@@ -319,6 +320,49 @@ static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg, + + #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) + ++#define PEM_RES_BASE 0x87e0c0000000UL ++#define PEM_NODE_MASK GENMASK(45, 44) ++#define PEM_INDX_MASK GENMASK(26, 24) ++#define PEM_MIN_DOM_IN_NODE 4 ++#define PEM_MAX_DOM_IN_NODE 10 ++ ++static void thunder_pem_reserve_range(struct device *dev, int seg, ++ struct resource *r) ++{ ++ resource_size_t start = r->start, end = r->end; ++ struct resource *res; ++ const char *regionid; ++ ++ regionid = kasprintf(GFP_KERNEL, "PEM RC:%d", seg); ++ if (!regionid) ++ return; ++ ++ res = request_mem_region(start, end - start + 1, regionid); ++ if (res) ++ res->flags &= ~IORESOURCE_BUSY; ++ else ++ kfree(regionid); ++ ++ dev_info(dev, "%pR %s reserved\n", r, ++ res ? "has been" : "could not be"); ++} ++ ++static void thunder_pem_legacy_fw(struct acpi_pci_root *root, ++ struct resource *res_pem) ++{ ++ int node = acpi_get_node(root->device->handle); ++ int index; ++ ++ if (node == NUMA_NO_NODE) ++ node = 0; ++ ++ index = root->segment - PEM_MIN_DOM_IN_NODE; ++ index -= node * PEM_MAX_DOM_IN_NODE; ++ res_pem->start = PEM_RES_BASE | FIELD_PREP(PEM_NODE_MASK, node) | ++ FIELD_PREP(PEM_INDX_MASK, index); ++ res_pem->flags = IORESOURCE_MEM; ++} ++ + static int thunder_pem_acpi_init(struct pci_config_window *cfg) + { + struct device *dev = cfg->parent; +@@ -332,9 +376,23 @@ static int thunder_pem_acpi_init(struct pci_config_window *cfg) + return -ENOMEM; + + ret = acpi_get_rc_resources(dev, "CAVA02B", root->segment, res_pem); ++ ++ /* ++ * If we fail to gather resources it means that we run with old ++ * FW where we need to calculate PEM-specific resources manually. ++ */ + if (ret) { +- dev_err(dev, "can't get rc base address\n"); +- return ret; ++ thunder_pem_legacy_fw(root, res_pem); ++ /* ++ * Reserve 64K size PEM specific resources. The full 16M range ++ * size is required for thunder_pem_init() call. ++ */ ++ res_pem->end = res_pem->start + SZ_64K - 1; ++ thunder_pem_reserve_range(dev, root->segment, res_pem); ++ res_pem->end = res_pem->start + SZ_16M - 1; ++ ++ /* Reserve PCI configuration space as well. */ ++ thunder_pem_reserve_range(dev, root->segment, &cfg->res); + } + + return thunder_pem_init(dev, cfg, res_pem); +diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c +index 7c3b54b9eb17..142a1669dd82 100644 +--- a/drivers/pci/host/pci-xgene.c ++++ b/drivers/pci/host/pci-xgene.c +@@ -246,14 +246,11 @@ static int xgene_pcie_ecam_init(struct pci_config_window *cfg, u32 ipversion) + ret = xgene_get_csr_resource(adev, &csr); + if (ret) { + dev_err(dev, "can't get CSR resource\n"); +- kfree(port); + return ret; + } + port->csr_base = devm_ioremap_resource(dev, &csr); +- if (IS_ERR(port->csr_base)) { +- kfree(port); +- return -ENOMEM; +- } ++ if (IS_ERR(port->csr_base)) ++ return PTR_ERR(port->csr_base); + + port->cfg_base = cfg->win; + port->version = ipversion; +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 024def5bb3fa..a171762048e7 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -1634,6 +1634,7 @@ static void quirk_pcie_mch(struct pci_dev *pdev) + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_pcie_mch); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_pcie_mch); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_pcie_mch); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0x1610, quirk_pcie_mch); + + + /* +@@ -2240,6 +2241,27 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_BROADCOM, + PCI_DEVICE_ID_TIGON3_5719, + quirk_brcm_5719_limit_mrrs); + ++#ifdef CONFIG_PCIE_IPROC_PLATFORM ++static void quirk_paxc_bridge(struct pci_dev *pdev) ++{ ++ /* The PCI config space is shared with the PAXC root port and the first ++ * Ethernet device. So, we need to workaround this by telling the PCI ++ * code that the bridge is not an Ethernet device. ++ */ ++ if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ++ pdev->class = PCI_CLASS_BRIDGE_PCI << 8; ++ ++ /* MPSS is not being set properly (as it is currently 0). This is ++ * because that area of the PCI config space is hard coded to zero, and ++ * is not modifiable by firmware. Set this to 2 (e.g., 512 byte MPS) ++ * so that the MPS can be set to the real max value. ++ */ ++ pdev->pcie_mpss = 2; ++} ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16cd, quirk_paxc_bridge); ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, quirk_paxc_bridge); ++#endif ++ + /* Originally in EDAC sources for i82875P: + * Intel tells BIOS developers to hide device 6 which + * configures the overflow device access containing +@@ -3114,30 +3136,32 @@ static void quirk_remove_d3_delay(struct pci_dev *dev) + { + dev->d3_delay = 0; + } +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c00, quirk_remove_d3_delay); ++/* C600 Series devices do not need 10ms d3_delay */ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0412, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c00, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c0c, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c31, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3a, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3d, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c2d, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c20, quirk_remove_d3_delay); ++/* Lynxpoint-H PCH devices do not need 10ms d3_delay */ ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c02, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c18, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c1c, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c20, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c26, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c2d, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c31, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3a, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3d, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c4e, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c02, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, quirk_remove_d3_delay); + /* Intel Cherrytrail devices do not need 10ms d3_delay */ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2280, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b0, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3_delay); ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b8, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22d8, quirk_remove_d3_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22dc, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay); + + /* + * Some devices may pass our check in pci_intx_mask_supported() if +@@ -4137,6 +4161,26 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags) + } + + /* ++ * These QCOM root ports do provide ACS-like features to disable peer ++ * transactions and validate bus numbers in requests, but do not provide an ++ * actual PCIe ACS capability. Hardware supports source validation but it ++ * will report the issue as Completer Abort instead of ACS Violation. ++ * Hardware doesn't support peer-to-peer and each root port is a root ++ * complex with unique segment numbers. It is not possible for one root ++ * port to pass traffic to another root port. All PCIe transactions are ++ * terminated inside the root port. ++ */ ++static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags) ++{ ++ u16 flags = (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_SV); ++ int ret = acs_flags & ~flags ? 0 : 1; ++ ++ dev_info(&dev->dev, "Using QCOM ACS Quirk (%d)\n", ret); ++ ++ return ret; ++} ++ ++/* + * Sunrise Point PCH root ports implement ACS, but unfortunately as shown in + * the datasheet (Intel 100 Series Chipset Family PCH Datasheet, Vol. 2, + * 12.1.46, 12.1.47)[1] this chipset uses dwords for the ACS capability and +@@ -4151,15 +4195,35 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags) + * + * N.B. This doesn't fix what lspci shows. + * ++ * The 100 series chipset specification update includes this as errata #23[3]. ++ * ++ * The 200 series chipset (Union Point) has the same bug according to the ++ * specification update (Intel 200 Series Chipset Family Platform Controller ++ * Hub, Specification Update, January 2017, Revision 001, Document# 335194-001, ++ * Errata 22)[4]. Per the datasheet[5], root port PCI Device IDs for this ++ * chipset include: ++ * ++ * 0xa290-0xa29f PCI Express Root port #{0-16} ++ * 0xa2e7-0xa2ee PCI Express Root port #{17-24} ++ * + * [1] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-2.html + * [2] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-1.html ++ * [3] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-spec-update.html ++ * [4] http://www.intel.com/content/www/us/en/chipsets/200-series-chipset-pch-spec-update.html ++ * [5] http://www.intel.com/content/www/us/en/chipsets/200-series-chipset-pch-datasheet-vol-1.html + */ + static bool pci_quirk_intel_spt_pch_acs_match(struct pci_dev *dev) + { +- return pci_is_pcie(dev) && +- pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT && +- ((dev->device & ~0xf) == 0xa110 || +- (dev->device >= 0xa167 && dev->device <= 0xa16a)); ++ if (!pci_is_pcie(dev) || pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) ++ return false; ++ ++ switch (dev->device) { ++ case 0xa110 ... 0xa11f: case 0xa167 ... 0xa16a: /* Sunrise Point */ ++ case 0xa290 ... 0xa29f: case 0xa2e7 ... 0xa2ee: /* Union Point */ ++ return true; ++ } ++ ++ return false; + } + + #define INTEL_SPT_ACS_CTRL (PCI_ACS_CAP + 4) +@@ -4272,6 +4336,9 @@ static const struct pci_dev_acs_enabled { + /* I219 */ + { PCI_VENDOR_ID_INTEL, 0x15b7, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_INTEL, 0x15b8, pci_quirk_mf_endpoint_acs }, ++ /* QCOM QDF2xxx root ports */ ++ { 0x17cb, 0x400, pci_quirk_qcom_rp_acs }, ++ { 0x17cb, 0x401, pci_quirk_qcom_rp_acs }, + /* Intel PCH root ports */ + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_spt_pch_acs }, +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 43cb680adbb4..8499d3ae4257 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -159,6 +159,8 @@ MODULE_LICENSE("GPL"); + #define USB_INTEL_XUSB2PR 0xD0 + #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 + ++static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL }; ++ + struct bios_args { + u32 arg0; + u32 arg1; +@@ -2051,6 +2053,16 @@ static int asus_wmi_fan_init(struct asus_wmi *asus) + return 0; + } + ++static bool ashs_present(void) ++{ ++ int i = 0; ++ while (ashs_ids[i]) { ++ if (acpi_dev_found(ashs_ids[i++])) ++ return true; ++ } ++ return false; ++} ++ + /* + * WMI Driver + */ +@@ -2095,6 +2107,13 @@ static int asus_wmi_add(struct platform_device *pdev) + if (err) + goto fail_leds; + ++ asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); ++ if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) ++ asus->driver->wlan_ctrl_by_user = 1; ++ ++ if (asus->driver->wlan_ctrl_by_user && ashs_present()) ++ asus->driver->quirks->no_rfkill = 1; ++ + if (!asus->driver->quirks->no_rfkill) { + err = asus_wmi_rfkill_init(asus); + if (err) +@@ -2134,10 +2153,6 @@ static int asus_wmi_add(struct platform_device *pdev) + if (err) + goto fail_debugfs; + +- asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); +- if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) +- asus->driver->wlan_ctrl_by_user = 1; +- + return 0; + + fail_debugfs: +diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c +index 7cbad0d45b9c..6ba270e0494d 100644 +--- a/drivers/staging/android/ashmem.c ++++ b/drivers/staging/android/ashmem.c +@@ -409,6 +409,7 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma) + ret = PTR_ERR(vmfile); + goto out; + } ++ vmfile->f_mode |= FMODE_LSEEK; + asma->file = vmfile; + } + get_file(asma->file); +diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c +index 61ad6c3b20a0..f4eb807a2616 100644 +--- a/drivers/tty/serial/8250/8250_omap.c ++++ b/drivers/tty/serial/8250/8250_omap.c +@@ -1075,15 +1075,15 @@ static int omap8250_no_handle_irq(struct uart_port *port) + } + + static const u8 am3352_habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE; +-static const u8 am4372_habit = UART_ERRATA_CLOCK_DISABLE; ++static const u8 dra742_habit = UART_ERRATA_CLOCK_DISABLE; + + static const struct of_device_id omap8250_dt_ids[] = { + { .compatible = "ti,omap2-uart" }, + { .compatible = "ti,omap3-uart" }, + { .compatible = "ti,omap4-uart" }, + { .compatible = "ti,am3352-uart", .data = &am3352_habit, }, +- { .compatible = "ti,am4372-uart", .data = &am4372_habit, }, +- { .compatible = "ti,dra742-uart", .data = &am4372_habit, }, ++ { .compatible = "ti,am4372-uart", .data = &am3352_habit, }, ++ { .compatible = "ti,dra742-uart", .data = &dra742_habit, }, + {}, + }; + MODULE_DEVICE_TABLE(of, omap8250_dt_ids); +@@ -1218,9 +1218,6 @@ static int omap8250_probe(struct platform_device *pdev) + priv->omap8250_dma.rx_size = RX_TRIGGER; + priv->omap8250_dma.rxconf.src_maxburst = RX_TRIGGER; + priv->omap8250_dma.txconf.dst_maxburst = TX_TRIGGER; +- +- if (of_machine_is_compatible("ti,am33xx")) +- priv->habit |= OMAP_DMA_TX_KICK; + /* + * pause is currently not supported atleast on omap-sdma + * and edma on most earlier kernels. +diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c +index 3889809fd0c4..37591a4b1346 100644 +--- a/drivers/usb/chipidea/ci_hdrc_msm.c ++++ b/drivers/usb/chipidea/ci_hdrc_msm.c +@@ -24,7 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) + switch (event) { + case CI_HDRC_CONTROLLER_RESET_EVENT: + dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n"); +- writel(0, USB_AHBBURST); + /* use AHB transactor, allow posted data writes */ + writel(0x8, USB_AHBMODE); + usb_phy_init(ci->usb_phy); +@@ -47,7 +46,8 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = { + .name = "ci_hdrc_msm", + .capoffset = DEF_CAPOFFSET, + .flags = CI_HDRC_REGS_SHARED | +- CI_HDRC_DISABLE_STREAMING, ++ CI_HDRC_DISABLE_STREAMING | ++ CI_HDRC_OVERRIDE_AHB_BURST, + + .notify_event = ci_hdrc_msm_notify_event, + }; +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index a8a4fe4ffa30..16768abf7f7c 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -171,6 +171,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, + int status) + { + struct dwc3 *dwc = dep->dwc; ++ unsigned int unmap_after_complete = false; + + req->started = false; + list_del(&req->list); +@@ -180,11 +181,19 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, + if (req->request.status == -EINPROGRESS) + req->request.status = status; + +- if (dwc->ep0_bounced && dep->number <= 1) ++ /* ++ * NOTICE we don't want to unmap before calling ->complete() if we're ++ * dealing with a bounced ep0 request. If we unmap it here, we would end ++ * up overwritting the contents of req->buf and this could confuse the ++ * gadget driver. ++ */ ++ if (dwc->ep0_bounced && dep->number <= 1) { + dwc->ep0_bounced = false; +- +- usb_gadget_unmap_request_by_dev(dwc->sysdev, +- &req->request, req->direction); ++ unmap_after_complete = true; ++ } else { ++ usb_gadget_unmap_request_by_dev(dwc->sysdev, ++ &req->request, req->direction); ++ } + + trace_dwc3_gadget_giveback(req); + +@@ -192,6 +201,10 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, + usb_gadget_giveback_request(&dep->endpoint, &req->request); + spin_lock(&dwc->lock); + ++ if (unmap_after_complete) ++ usb_gadget_unmap_request_by_dev(dwc->sysdev, ++ &req->request, req->direction); ++ + if (dep->number > 1) + pm_runtime_put(dwc->dev); + } +diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c +index 487f0ff6ae25..76f0b0df37c1 100644 +--- a/drivers/usb/dwc3/host.c ++++ b/drivers/usb/dwc3/host.c +@@ -54,11 +54,12 @@ static int dwc3_host_get_irq(struct dwc3 *dwc) + + int dwc3_host_init(struct dwc3 *dwc) + { +- struct property_entry props[2]; ++ struct property_entry props[3]; + struct platform_device *xhci; + int ret, irq; + struct resource *res; + struct platform_device *dwc3_pdev = to_platform_device(dwc->dev); ++ int prop_idx = 0; + + irq = dwc3_host_get_irq(dwc); + if (irq < 0) +@@ -97,8 +98,22 @@ int dwc3_host_init(struct dwc3 *dwc) + + memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props)); + +- if (dwc->usb3_lpm_capable) { +- props[0].name = "usb3-lpm-capable"; ++ if (dwc->usb3_lpm_capable) ++ props[prop_idx++].name = "usb3-lpm-capable"; ++ ++ /** ++ * WORKAROUND: dwc3 revisions <=3.00a have a limitation ++ * where Port Disable command doesn't work. ++ * ++ * The suggested workaround is that we avoid Port Disable ++ * completely. ++ * ++ * This following flag tells XHCI to do just that. ++ */ ++ if (dwc->revision <= DWC3_REVISION_300A) ++ props[prop_idx++].name = "quirk-broken-port-ped"; ++ ++ if (prop_idx) { + ret = platform_device_add_properties(xhci, props); + if (ret) { + dev_err(dwc->dev, "failed to add properties to xHCI\n"); +diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c +index 0ef16900efed..1d41637a53e5 100644 +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -458,6 +458,12 @@ static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, + return; + } + ++ if (xhci->quirks & XHCI_BROKEN_PORT_PED) { ++ xhci_dbg(xhci, ++ "Broken Port Enabled/Disabled, ignoring port disable request.\n"); ++ return; ++ } ++ + /* Write 1 to disable the port */ + writel(port_status | PORT_PE, addr); + port_status = readl(addr); +diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c +index 9715200eb36e..bd02a6cd8e2c 100644 +--- a/drivers/usb/host/xhci-plat.c ++++ b/drivers/usb/host/xhci-plat.c +@@ -232,6 +232,9 @@ static int xhci_plat_probe(struct platform_device *pdev) + if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable")) + xhci->quirks |= XHCI_LPM_SUPPORT; + ++ if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped")) ++ xhci->quirks |= XHCI_BROKEN_PORT_PED; ++ + hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); + if (IS_ERR(hcd->usb_phy)) { + ret = PTR_ERR(hcd->usb_phy); +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 2d7b6374b58d..ea18bf49c2eb 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1650,6 +1650,9 @@ struct xhci_hcd { + #define XHCI_SSIC_PORT_UNUSED (1 << 22) + #define XHCI_NO_64BIT_SUPPORT (1 << 23) + #define XHCI_MISSING_CAS (1 << 24) ++/* For controller with a broken Port Disable implementation */ ++#define XHCI_BROKEN_PORT_PED (1 << 25) ++ + unsigned int num_active_eps; + unsigned int limit_active_eps; + /* There are two roothubs to keep track of bus suspend info for */ +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index 16cc18369111..9129f6cb8230 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -2071,6 +2071,20 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + ++/* ++ * Reported by Tobias Jakobi <tjak...@math.uni-bielefeld.de> ++ * The INIC-3619 bridge is used in the StarTech SLSODDU33B ++ * SATA-USB enclosure for slimline optical drives. ++ * ++ * The quirk enables MakeMKV to properly exchange keys with ++ * an installed BD drive. ++ */ ++UNUSUAL_DEV( 0x13fd, 0x3609, 0x0209, 0x0209, ++ "Initio Corporation", ++ "INIC-3619", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_IGNORE_RESIDUE ), ++ + /* Reported by Qinglin Ye <yest...@gmail.com> */ + UNUSUAL_DEV( 0x13fe, 0x3600, 0x0100, 0x0100, + "Kingston", +diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c +index 59e95762a6de..c5a567a73f59 100644 +--- a/drivers/watchdog/s3c2410_wdt.c ++++ b/drivers/watchdog/s3c2410_wdt.c +@@ -46,6 +46,7 @@ + #define S3C2410_WTCON 0x00 + #define S3C2410_WTDAT 0x04 + #define S3C2410_WTCNT 0x08 ++#define S3C2410_WTCLRINT 0x0c + + #define S3C2410_WTCNT_MAXCNT 0xffff + +@@ -72,6 +73,7 @@ + #define EXYNOS5_WDT_MASK_RESET_REG_OFFSET 0x040c + #define QUIRK_HAS_PMU_CONFIG (1 << 0) + #define QUIRK_HAS_RST_STAT (1 << 1) ++#define QUIRK_HAS_WTCLRINT_REG (1 << 2) + + /* These quirks require that we have a PMU register map */ + #define QUIRKS_HAVE_PMUREG (QUIRK_HAS_PMU_CONFIG | \ +@@ -143,13 +145,18 @@ static const struct s3c2410_wdt_variant drv_data_s3c2410 = { + }; + + #ifdef CONFIG_OF ++static const struct s3c2410_wdt_variant drv_data_s3c6410 = { ++ .quirks = QUIRK_HAS_WTCLRINT_REG, ++}; ++ + static const struct s3c2410_wdt_variant drv_data_exynos5250 = { + .disable_reg = EXYNOS5_WDT_DISABLE_REG_OFFSET, + .mask_reset_reg = EXYNOS5_WDT_MASK_RESET_REG_OFFSET, + .mask_bit = 20, + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, + .rst_stat_bit = 20, +- .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, ++ .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ ++ | QUIRK_HAS_WTCLRINT_REG, + }; + + static const struct s3c2410_wdt_variant drv_data_exynos5420 = { +@@ -158,7 +165,8 @@ static const struct s3c2410_wdt_variant drv_data_exynos5420 = { + .mask_bit = 0, + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, + .rst_stat_bit = 9, +- .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, ++ .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ ++ | QUIRK_HAS_WTCLRINT_REG, + }; + + static const struct s3c2410_wdt_variant drv_data_exynos7 = { +@@ -167,12 +175,15 @@ static const struct s3c2410_wdt_variant drv_data_exynos7 = { + .mask_bit = 23, + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, + .rst_stat_bit = 23, /* A57 WDTRESET */ +- .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, ++ .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ ++ | QUIRK_HAS_WTCLRINT_REG, + }; + + static const struct of_device_id s3c2410_wdt_match[] = { + { .compatible = "samsung,s3c2410-wdt", + .data = &drv_data_s3c2410 }, ++ { .compatible = "samsung,s3c6410-wdt", ++ .data = &drv_data_s3c6410 }, + { .compatible = "samsung,exynos5250-wdt", + .data = &drv_data_exynos5250 }, + { .compatible = "samsung,exynos5420-wdt", +@@ -418,6 +429,10 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param) + dev_info(wdt->dev, "watchdog timer expired (irq)\n"); + + s3c2410wdt_keepalive(&wdt->wdt_device); ++ ++ if (wdt->drv_data->quirks & QUIRK_HAS_WTCLRINT_REG) ++ writel(0x1, wdt->reg_base + S3C2410_WTCLRINT); ++ + return IRQ_HANDLED; + } + +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 87457227812c..bdd32925a15e 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -1104,6 +1104,10 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, + return -EINVAL; + } + ++ /* SMB2 TREE_CONNECT request must be called with TreeId == 0 */ ++ if (tcon) ++ tcon->tid = 0; ++ + rc = small_smb2_init(SMB2_TREE_CONNECT, tcon, (void **) &req); + if (rc) { + kfree(unc_path); +diff --git a/fs/dax.c b/fs/dax.c +index c45598b912e1..a39b404b646a 100644 +--- a/fs/dax.c ++++ b/fs/dax.c +@@ -369,6 +369,22 @@ static void *grab_mapping_entry(struct address_space *mapping, pgoff_t index, + } + spin_lock_irq(&mapping->tree_lock); + ++ if (!entry) { ++ /* ++ * We needed to drop the page_tree lock while calling ++ * radix_tree_preload() and we didn't have an entry to ++ * lock. See if another thread inserted an entry at ++ * our index during this time. ++ */ ++ entry = __radix_tree_lookup(&mapping->page_tree, index, ++ NULL, &slot); ++ if (entry) { ++ radix_tree_preload_end(); ++ spin_unlock_irq(&mapping->tree_lock); ++ goto restart; ++ } ++ } ++ + if (pmd_downgrade) { + radix_tree_delete(&mapping->page_tree, index); + mapping->nrexceptional--; +@@ -384,19 +400,12 @@ static void *grab_mapping_entry(struct address_space *mapping, pgoff_t index, + if (err) { + spin_unlock_irq(&mapping->tree_lock); + /* +- * Someone already created the entry? This is a +- * normal failure when inserting PMDs in a range +- * that already contains PTEs. In that case we want +- * to return -EEXIST immediately. +- */ +- if (err == -EEXIST && !(size_flag & RADIX_DAX_PMD)) +- goto restart; +- /* +- * Our insertion of a DAX PMD entry failed, most +- * likely because it collided with a PTE sized entry +- * at a different index in the PMD range. We haven't +- * inserted anything into the radix tree and have no +- * waiters to wake. ++ * Our insertion of a DAX entry failed, most likely ++ * because we were inserting a PMD entry and it ++ * collided with a PTE sized entry at a different ++ * index in the PMD range. We haven't inserted ++ * anything into the radix tree and have no waiters to ++ * wake. + */ + return ERR_PTR(err); + } +diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c +index 67c24351a67f..cd261c8de53a 100644 +--- a/fs/orangefs/super.c ++++ b/fs/orangefs/super.c +@@ -263,8 +263,13 @@ int orangefs_remount(struct orangefs_sb_info_s *orangefs_sb) + if (!new_op) + return -ENOMEM; + new_op->upcall.req.features.features = 0; +- ret = service_operation(new_op, "orangefs_features", 0); +- orangefs_features = new_op->downcall.resp.features.features; ++ ret = service_operation(new_op, "orangefs_features", ++ ORANGEFS_OP_PRIORITY | ORANGEFS_OP_NO_MUTEX); ++ if (!ret) ++ orangefs_features = ++ new_op->downcall.resp.features.features; ++ else ++ orangefs_features = 0; + op_release(new_op); + } else { + orangefs_features = 0; +diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c +index b803213d1307..39c75a86c67f 100644 +--- a/fs/sysfs/file.c ++++ b/fs/sysfs/file.c +@@ -108,7 +108,7 @@ static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf, + { + const struct sysfs_ops *ops = sysfs_file_ops(of->kn); + struct kobject *kobj = of->kn->parent->priv; +- size_t len; ++ ssize_t len; + + /* + * If buf != of->prealloc_buf, we don't know how +@@ -117,13 +117,15 @@ static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf, + if (WARN_ON_ONCE(buf != of->prealloc_buf)) + return 0; + len = ops->show(kobj, of->kn->priv, buf); ++ if (len < 0) ++ return len; + if (pos) { + if (len <= pos) + return 0; + len -= pos; + memmove(buf, buf + pos, len); + } +- return min(count, len); ++ return min_t(ssize_t, count, len); + } + + /* kernfs write callback for regular sysfs files */ +diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c +index c516d7158a21..205ab55d595d 100644 +--- a/fs/xfs/xfs_bmap_util.c ++++ b/fs/xfs/xfs_bmap_util.c +@@ -1318,8 +1318,16 @@ xfs_free_file_space( + /* + * Now that we've unmap all full blocks we'll have to zero out any + * partial block at the beginning and/or end. xfs_zero_range is +- * smart enough to skip any holes, including those we just created. ++ * smart enough to skip any holes, including those we just created, ++ * but we must take care not to zero beyond EOF and enlarge i_size. + */ ++ ++ if (offset >= XFS_ISIZE(ip)) ++ return 0; ++ ++ if (offset + len > XFS_ISIZE(ip)) ++ len = XFS_ISIZE(ip) - offset; ++ + return xfs_zero_range(ip, offset, len, NULL); + } + +diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h +index 0d5f4268d75f..61766a420f6b 100644 +--- a/include/drm/i915_pciids.h ++++ b/include/drm/i915_pciids.h +@@ -226,23 +226,18 @@ + INTEL_VGA_DEVICE(0x162A, info), /* Server */ \ + INTEL_VGA_DEVICE(0x162D, info) /* Workstation */ + +-#define INTEL_BDW_RSVDM_IDS(info) \ ++#define INTEL_BDW_RSVD_IDS(info) \ + INTEL_VGA_DEVICE(0x1632, info), /* ULT */ \ + INTEL_VGA_DEVICE(0x1636, info), /* ULT */ \ + INTEL_VGA_DEVICE(0x163B, info), /* Iris */ \ +- INTEL_VGA_DEVICE(0x163E, info) /* ULX */ +- +-#define INTEL_BDW_RSVDD_IDS(info) \ ++ INTEL_VGA_DEVICE(0x163E, info), /* ULX */ \ + INTEL_VGA_DEVICE(0x163A, info), /* Server */ \ + INTEL_VGA_DEVICE(0x163D, info) /* Workstation */ + + #define INTEL_BDW_IDS(info) \ + INTEL_BDW_GT12_IDS(info), \ + INTEL_BDW_GT3_IDS(info), \ +- INTEL_BDW_RSVDM_IDS(info), \ +- INTEL_BDW_GT12_IDS(info), \ +- INTEL_BDW_GT3_IDS(info), \ +- INTEL_BDW_RSVDD_IDS(info) ++ INTEL_BDW_RSVD_IDS(info) + + #define INTEL_CHV_IDS(info) \ + INTEL_VGA_DEVICE(0x22b0, info), \ +diff --git a/include/drm/ttm/ttm_object.h b/include/drm/ttm/ttm_object.h +index ed953f98f0e1..1487011fe057 100644 +--- a/include/drm/ttm/ttm_object.h ++++ b/include/drm/ttm/ttm_object.h +@@ -229,6 +229,8 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base); + * @ref_type: The type of reference. + * @existed: Upon completion, indicates that an identical reference object + * already existed, and the refcount was upped on that object instead. ++ * @require_existed: Fail with -EPERM if an identical ref object didn't ++ * already exist. + * + * Checks that the base object is shareable and adds a ref object to it. + * +@@ -243,7 +245,8 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base); + */ + extern int ttm_ref_object_add(struct ttm_object_file *tfile, + struct ttm_base_object *base, +- enum ttm_ref_type ref_type, bool *existed); ++ enum ttm_ref_type ref_type, bool *existed, ++ bool require_existed); + + extern bool ttm_ref_object_exists(struct ttm_object_file *tfile, + struct ttm_base_object *base); +diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h +index b5abfda80465..4c5bca38c653 100644 +--- a/include/linux/arm-smccc.h ++++ b/include/linux/arm-smccc.h +@@ -14,9 +14,6 @@ + #ifndef __LINUX_ARM_SMCCC_H + #define __LINUX_ARM_SMCCC_H + +-#include <linux/linkage.h> +-#include <linux/types.h> +- + /* + * This file provides common defines for ARM SMC Calling Convention as + * specified in +@@ -60,6 +57,13 @@ + #define ARM_SMCCC_OWNER_TRUSTED_OS 50 + #define ARM_SMCCC_OWNER_TRUSTED_OS_END 63 + ++#define ARM_SMCCC_QUIRK_NONE 0 ++#define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */ ++ ++#ifndef __ASSEMBLY__ ++ ++#include <linux/linkage.h> ++#include <linux/types.h> + /** + * struct arm_smccc_res - Result from SMC/HVC call + * @a0-a3 result values from registers 0 to 3 +@@ -72,33 +76,59 @@ struct arm_smccc_res { + }; + + /** +- * arm_smccc_smc() - make SMC calls ++ * struct arm_smccc_quirk - Contains quirk information ++ * @id: quirk identification ++ * @state: quirk specific information ++ * @a6: Qualcomm quirk entry for returning post-smc call contents of a6 ++ */ ++struct arm_smccc_quirk { ++ int id; ++ union { ++ unsigned long a6; ++ } state; ++}; ++ ++/** ++ * __arm_smccc_smc() - make SMC calls + * @a0-a7: arguments passed in registers 0 to 7 + * @res: result values from registers 0 to 3 ++ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required. + * + * This function is used to make SMC calls following SMC Calling Convention. + * The content of the supplied param are copied to registers 0 to 7 prior + * to the SMC instruction. The return values are updated with the content +- * from register 0 to 3 on return from the SMC instruction. ++ * from register 0 to 3 on return from the SMC instruction. An optional ++ * quirk structure provides vendor specific behavior. + */ +-asmlinkage void arm_smccc_smc(unsigned long a0, unsigned long a1, ++asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1, + unsigned long a2, unsigned long a3, unsigned long a4, + unsigned long a5, unsigned long a6, unsigned long a7, +- struct arm_smccc_res *res); ++ struct arm_smccc_res *res, struct arm_smccc_quirk *quirk); + + /** +- * arm_smccc_hvc() - make HVC calls ++ * __arm_smccc_hvc() - make HVC calls + * @a0-a7: arguments passed in registers 0 to 7 + * @res: result values from registers 0 to 3 ++ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required. + * + * This function is used to make HVC calls following SMC Calling + * Convention. The content of the supplied param are copied to registers 0 + * to 7 prior to the HVC instruction. The return values are updated with +- * the content from register 0 to 3 on return from the HVC instruction. ++ * the content from register 0 to 3 on return from the HVC instruction. An ++ * optional quirk structure provides vendor specific behavior. + */ +-asmlinkage void arm_smccc_hvc(unsigned long a0, unsigned long a1, ++asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, + unsigned long a2, unsigned long a3, unsigned long a4, + unsigned long a5, unsigned long a6, unsigned long a7, +- struct arm_smccc_res *res); ++ struct arm_smccc_res *res, struct arm_smccc_quirk *quirk); ++ ++#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL) ++ ++#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__) ++ ++#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL) ++ ++#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__) + ++#endif /*__ASSEMBLY__*/ + #endif /*__LINUX_ARM_SMCCC_H*/ +diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h +index 73dda0edcb97..a4f77feecbb0 100644 +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -2516,6 +2516,8 @@ + #define PCI_DEVICE_ID_KORENIX_JETCARDF2 0x1700 + #define PCI_DEVICE_ID_KORENIX_JETCARDF3 0x17ff + ++#define PCI_VENDOR_ID_HUAWEI 0x19e5 ++ + #define PCI_VENDOR_ID_NETRONOME 0x19ee + #define PCI_DEVICE_ID_NETRONOME_NFP3200 0x3200 + #define PCI_DEVICE_ID_NETRONOME_NFP3240 0x3240 +diff --git a/include/linux/random.h b/include/linux/random.h +index 7bd2403e4fef..16ab429735a7 100644 +--- a/include/linux/random.h ++++ b/include/linux/random.h +@@ -37,7 +37,6 @@ extern void get_random_bytes(void *buf, int nbytes); + extern int add_random_ready_callback(struct random_ready_callback *rdy); + extern void del_random_ready_callback(struct random_ready_callback *rdy); + extern void get_random_bytes_arch(void *buf, int nbytes); +-extern int random_int_secret_init(void); + + #ifndef MODULE + extern const struct file_operations random_fops, urandom_fops; +diff --git a/init/main.c b/init/main.c +index b0c9d6facef9..09beb7fc6e8c 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -879,7 +879,6 @@ static void __init do_basic_setup(void) + do_ctors(); + usermodehelper_enable(); + do_initcalls(); +- random_int_secret_init(); + } + + static void __init do_pre_smp_initcalls(void) +diff --git a/kernel/ptrace.c b/kernel/ptrace.c +index 49ba7c1ade9d..a5caecef88be 100644 +--- a/kernel/ptrace.c ++++ b/kernel/ptrace.c +@@ -181,11 +181,17 @@ static void ptrace_unfreeze_traced(struct task_struct *task) + + WARN_ON(!task->ptrace || task->parent != current); + ++ /* ++ * PTRACE_LISTEN can allow ptrace_trap_notify to wake us up remotely. ++ * Recheck state under the lock to close this race. ++ */ + spin_lock_irq(&task->sighand->siglock); +- if (__fatal_signal_pending(task)) +- wake_up_state(task, __TASK_TRACED); +- else +- task->state = TASK_TRACED; ++ if (task->state == __TASK_TRACED) { ++ if (__fatal_signal_pending(task)) ++ wake_up_state(task, __TASK_TRACED); ++ else ++ task->state = TASK_TRACED; ++ } + spin_unlock_irq(&task->sighand->siglock); + } + +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index a85739efcc30..8df48ccb8af6 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -4825,9 +4825,9 @@ static __init int test_ringbuffer(void) + rb_data[cpu].cnt = cpu; + rb_threads[cpu] = kthread_create(rb_test, &rb_data[cpu], + "rbtester/%d", cpu); +- if (WARN_ON(!rb_threads[cpu])) { ++ if (WARN_ON(IS_ERR(rb_threads[cpu]))) { + pr_cont("FAILED\n"); +- ret = -1; ++ ret = PTR_ERR(rb_threads[cpu]); + goto out_free; + } + +@@ -4837,9 +4837,9 @@ static __init int test_ringbuffer(void) + + /* Now create the rb hammer! */ + rb_hammer = kthread_run(rb_hammer_test, NULL, "rbhammer"); +- if (WARN_ON(!rb_hammer)) { ++ if (WARN_ON(IS_ERR(rb_hammer))) { + pr_cont("FAILED\n"); +- ret = -1; ++ ret = PTR_ERR(rb_hammer); + goto out_free; + } + +diff --git a/mm/mempolicy.c b/mm/mempolicy.c +index 1e7873e40c9a..dc8a2672c407 100644 +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -1526,7 +1526,6 @@ COMPAT_SYSCALL_DEFINE5(get_mempolicy, int __user *, policy, + COMPAT_SYSCALL_DEFINE3(set_mempolicy, int, mode, compat_ulong_t __user *, nmask, + compat_ulong_t, maxnode) + { +- long err = 0; + unsigned long __user *nm = NULL; + unsigned long nr_bits, alloc_size; + DECLARE_BITMAP(bm, MAX_NUMNODES); +@@ -1535,14 +1534,13 @@ COMPAT_SYSCALL_DEFINE3(set_mempolicy, int, mode, compat_ulong_t __user *, nmask, + alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; + + if (nmask) { +- err = compat_get_bitmap(bm, nmask, nr_bits); ++ if (compat_get_bitmap(bm, nmask, nr_bits)) ++ return -EFAULT; + nm = compat_alloc_user_space(alloc_size); +- err |= copy_to_user(nm, bm, alloc_size); ++ if (copy_to_user(nm, bm, alloc_size)) ++ return -EFAULT; + } + +- if (err) +- return -EFAULT; +- + return sys_set_mempolicy(mode, nm, nr_bits+1); + } + +@@ -1550,7 +1548,6 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulong_t, start, compat_ulong_t, len, + compat_ulong_t, mode, compat_ulong_t __user *, nmask, + compat_ulong_t, maxnode, compat_ulong_t, flags) + { +- long err = 0; + unsigned long __user *nm = NULL; + unsigned long nr_bits, alloc_size; + nodemask_t bm; +@@ -1559,14 +1556,13 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulong_t, start, compat_ulong_t, len, + alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; + + if (nmask) { +- err = compat_get_bitmap(nodes_addr(bm), nmask, nr_bits); ++ if (compat_get_bitmap(nodes_addr(bm), nmask, nr_bits)) ++ return -EFAULT; + nm = compat_alloc_user_space(alloc_size); +- err |= copy_to_user(nm, nodes_addr(bm), alloc_size); ++ if (copy_to_user(nm, nodes_addr(bm), alloc_size)) ++ return -EFAULT; + } + +- if (err) +- return -EFAULT; +- + return sys_mbind(start, len, mode, nm, nr_bits+1, flags); + } + +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 1a5f6655958e..1aec370bf9e9 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -4381,13 +4381,13 @@ void show_free_areas(unsigned int filter) + K(node_page_state(pgdat, NR_FILE_MAPPED)), + K(node_page_state(pgdat, NR_FILE_DIRTY)), + K(node_page_state(pgdat, NR_WRITEBACK)), ++ K(node_page_state(pgdat, NR_SHMEM)), + #ifdef CONFIG_TRANSPARENT_HUGEPAGE + K(node_page_state(pgdat, NR_SHMEM_THPS) * HPAGE_PMD_NR), + K(node_page_state(pgdat, NR_SHMEM_PMDMAPPED) + * HPAGE_PMD_NR), + K(node_page_state(pgdat, NR_ANON_THPS) * HPAGE_PMD_NR), + #endif +- K(node_page_state(pgdat, NR_SHMEM)), + K(node_page_state(pgdat, NR_WRITEBACK_TEMP)), + K(node_page_state(pgdat, NR_UNSTABLE_NFS)), + node_page_state(pgdat, NR_PAGES_SCANNED), +diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c +index d37ae7dc114b..56d491950390 100644 +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -718,7 +718,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) + ieee80211_recalc_ps(local); + + if (sdata->vif.type == NL80211_IFTYPE_MONITOR || +- sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { ++ sdata->vif.type == NL80211_IFTYPE_AP_VLAN || ++ local->ops->wake_tx_queue) { + /* XXX: for AP_VLAN, actually track AP queues */ + netif_tx_start_all_queues(dev); + } else if (dev) { +diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c +index 14b3f007826d..2927d06faa6e 100644 +--- a/net/wireless/sysfs.c ++++ b/net/wireless/sysfs.c +@@ -130,12 +130,10 @@ static int wiphy_resume(struct device *dev) + /* Age scan results with time spent in suspend */ + cfg80211_bss_age(rdev, get_seconds() - rdev->suspend_at); + +- if (rdev->ops->resume) { +- rtnl_lock(); +- if (rdev->wiphy.registered) +- ret = rdev_resume(rdev); +- rtnl_unlock(); +- } ++ rtnl_lock(); ++ if (rdev->wiphy.registered && rdev->ops->resume) ++ ret = rdev_resume(rdev); ++ rtnl_unlock(); + + return ret; + } +diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c +index 97bafac3bc15..17d20b99f041 100644 +--- a/sound/soc/codecs/rt5670.c ++++ b/sound/soc/codecs/rt5670.c +@@ -2814,6 +2814,7 @@ MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id); + static const struct acpi_device_id rt5670_acpi_match[] = { + { "10EC5670", 0}, + { "10EC5672", 0}, ++ { "10EC5640", 0}, /* quirk */ + { }, + }; + MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match); +diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c +index f4d92bbc5373..63820080dd16 100644 +--- a/sound/soc/intel/atom/sst/sst_acpi.c ++++ b/sound/soc/intel/atom/sst/sst_acpi.c +@@ -400,6 +400,7 @@ static int sst_acpi_remove(struct platform_device *pdev) + static unsigned long cht_machine_id; + + #define CHT_SURFACE_MACH 1 ++#define BYT_THINKPAD_10 2 + + static int cht_surface_quirk_cb(const struct dmi_system_id *id) + { +@@ -407,6 +408,23 @@ static int cht_surface_quirk_cb(const struct dmi_system_id *id) + return 1; + } + ++static int byt_thinkpad10_quirk_cb(const struct dmi_system_id *id) ++{ ++ cht_machine_id = BYT_THINKPAD_10; ++ return 1; ++} ++ ++ ++static const struct dmi_system_id byt_table[] = { ++ { ++ .callback = byt_thinkpad10_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "20C3001VHH"), ++ }, ++ }, ++ { } ++}; + + static const struct dmi_system_id cht_table[] = { + { +@@ -424,6 +442,10 @@ static struct sst_acpi_mach cht_surface_mach = { + "10EC5640", "cht-bsw-rt5645", "intel/fw_sst_22a8.bin", "cht-bsw", NULL, + &chv_platform_data }; + ++static struct sst_acpi_mach byt_thinkpad_10 = { ++ "10EC5640", "cht-bsw-rt5672", "intel/fw_sst_0f28.bin", "cht-bsw", NULL, ++ &byt_rvp_platform_data }; ++ + static struct sst_acpi_mach *cht_quirk(void *arg) + { + struct sst_acpi_mach *mach = arg; +@@ -436,8 +458,21 @@ static struct sst_acpi_mach *cht_quirk(void *arg) + return mach; + } + ++static struct sst_acpi_mach *byt_quirk(void *arg) ++{ ++ struct sst_acpi_mach *mach = arg; ++ ++ dmi_check_system(byt_table); ++ ++ if (cht_machine_id == BYT_THINKPAD_10) ++ return &byt_thinkpad_10; ++ else ++ return mach; ++} ++ ++ + static struct sst_acpi_mach sst_acpi_bytcr[] = { +- {"10EC5640", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL, ++ {"10EC5640", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", byt_quirk, + &byt_rvp_platform_data }, + {"10EC5642", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL, + &byt_rvp_platform_data }, +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index 8d2fb2d6f532..1bd985f01c73 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -387,6 +387,16 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { + BYT_RT5640_SSP0_AIF1), + + }, ++ { ++ .callback = byt_rt5640_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), ++ }, ++ .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP | ++ BYT_RT5640_MCLK_EN | ++ BYT_RT5640_SSP0_AIF1), ++ ++ }, + {} + }; + +diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c +index f504a0e18f91..753938371965 100644 +--- a/sound/soc/intel/boards/cht_bsw_rt5645.c ++++ b/sound/soc/intel/boards/cht_bsw_rt5645.c +@@ -24,6 +24,9 @@ + #include <linux/acpi.h> + #include <linux/platform_device.h> + #include <linux/slab.h> ++#include <asm/cpu_device_id.h> ++#include <asm/platform_sst_audio.h> ++#include <linux/clk.h> + #include <sound/pcm.h> + #include <sound/pcm_params.h> + #include <sound/soc.h> +@@ -45,6 +48,7 @@ struct cht_mc_private { + struct snd_soc_jack jack; + struct cht_acpi_card *acpi_card; + char codec_name[16]; ++ struct clk *mclk; + }; + + static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) +@@ -65,6 +69,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct snd_soc_dai *codec_dai; ++ struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); + int ret; + + codec_dai = cht_get_codec_dai(card); +@@ -73,19 +78,30 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, + return -EIO; + } + +- if (!SND_SOC_DAPM_EVENT_OFF(event)) +- return 0; ++ if (SND_SOC_DAPM_EVENT_ON(event)) { ++ if (ctx->mclk) { ++ ret = clk_prepare_enable(ctx->mclk); ++ if (ret < 0) { ++ dev_err(card->dev, ++ "could not configure MCLK state"); ++ return ret; ++ } ++ } ++ } else { ++ /* Set codec sysclk source to its internal clock because codec PLL will ++ * be off when idle and MCLK will also be off when codec is ++ * runtime suspended. Codec needs clock for jack detection and button ++ * press. MCLK is turned off with clock framework or ACPI. ++ */ ++ ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK, ++ 48000 * 512, SND_SOC_CLOCK_IN); ++ if (ret < 0) { ++ dev_err(card->dev, "can't set codec sysclk: %d\n", ret); ++ return ret; ++ } + +- /* Set codec sysclk source to its internal clock because codec PLL will +- * be off when idle and MCLK will also be off by ACPI when codec is +- * runtime suspended. Codec needs clock for jack detection and button +- * press. +- */ +- ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK, +- 0, SND_SOC_CLOCK_IN); +- if (ret < 0) { +- dev_err(card->dev, "can't set codec sysclk: %d\n", ret); +- return ret; ++ if (ctx->mclk) ++ clk_disable_unprepare(ctx->mclk); + } + + return 0; +@@ -97,7 +113,7 @@ static const struct snd_soc_dapm_widget cht_dapm_widgets[] = { + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_SPK("Ext Spk", NULL), + SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, +- platform_clock_control, SND_SOC_DAPM_POST_PMD), ++ platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + }; + + static const struct snd_soc_dapm_route cht_rt5645_audio_map[] = { +@@ -225,6 +241,26 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) + + rt5645_set_jack_detect(codec, &ctx->jack, &ctx->jack, &ctx->jack); + ++ if (ctx->mclk) { ++ /* ++ * The firmware might enable the clock at ++ * boot (this information may or may not ++ * be reflected in the enable clock register). ++ * To change the rate we must disable the clock ++ * first to cover these cases. Due to common ++ * clock framework restrictions that do not allow ++ * to disable a clock that has not been enabled, ++ * we need to enable the clock first. ++ */ ++ ret = clk_prepare_enable(ctx->mclk); ++ if (!ret) ++ clk_disable_unprepare(ctx->mclk); ++ ++ ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ); ++ ++ if (ret) ++ dev_err(runtime->dev, "unable to set MCLK rate\n"); ++ } + return ret; + } + +@@ -349,6 +385,18 @@ static struct cht_acpi_card snd_soc_cards[] = { + + static char cht_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ + ++static bool is_valleyview(void) ++{ ++ static const struct x86_cpu_id cpu_ids[] = { ++ { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */ ++ {} ++ }; ++ ++ if (!x86_match_cpu(cpu_ids)) ++ return false; ++ return true; ++} ++ + static int snd_cht_mc_probe(struct platform_device *pdev) + { + int ret_val = 0; +@@ -358,22 +406,32 @@ static int snd_cht_mc_probe(struct platform_device *pdev) + struct sst_acpi_mach *mach; + const char *i2c_name = NULL; + int dai_index = 0; ++ bool found = false; + + drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); + if (!drv) + return -ENOMEM; + ++ mach = (&pdev->dev)->platform_data; ++ + for (i = 0; i < ARRAY_SIZE(snd_soc_cards); i++) { +- if (acpi_dev_found(snd_soc_cards[i].codec_id)) { ++ if (acpi_dev_found(snd_soc_cards[i].codec_id) && ++ (!strncmp(snd_soc_cards[i].codec_id, mach->id, 8))) { + dev_dbg(&pdev->dev, + "found codec %s\n", snd_soc_cards[i].codec_id); + card = snd_soc_cards[i].soc_card; + drv->acpi_card = &snd_soc_cards[i]; ++ found = true; + break; + } + } ++ ++ if (!found) { ++ dev_err(&pdev->dev, "No matching HID found in supported list\n"); ++ return -ENODEV; ++ } ++ + card->dev = &pdev->dev; +- mach = card->dev->platform_data; + sprintf(drv->codec_name, "i2c-%s:00", drv->acpi_card->codec_id); + + /* set correct codec name */ +@@ -391,6 +449,16 @@ static int snd_cht_mc_probe(struct platform_device *pdev) + cht_dailink[dai_index].codec_name = cht_rt5640_codec_name; + } + ++ if (is_valleyview()) { ++ drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); ++ if (IS_ERR(drv->mclk)) { ++ dev_err(&pdev->dev, ++ "Failed to get MCLK from pmc_plt_clk_3: %ld\n", ++ PTR_ERR(drv->mclk)); ++ return PTR_ERR(drv->mclk); ++ } ++ } ++ + snd_soc_card_set_drvdata(card, drv); + ret_val = devm_snd_soc_register_card(&pdev->dev, card); + if (ret_val) { +diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c +index f24d19526603..268f2bf691b3 100644 +--- a/sound/soc/sunxi/sun4i-i2s.c ++++ b/sound/soc/sunxi/sun4i-i2s.c +@@ -14,9 +14,11 @@ + #include <linux/clk.h> + #include <linux/dmaengine.h> + #include <linux/module.h> ++#include <linux/of_device.h> + #include <linux/platform_device.h> + #include <linux/pm_runtime.h> + #include <linux/regmap.h> ++#include <linux/reset.h> + + #include <sound/dmaengine_pcm.h> + #include <sound/pcm_params.h> +@@ -92,6 +94,7 @@ struct sun4i_i2s { + struct clk *bus_clk; + struct clk *mod_clk; + struct regmap *regmap; ++ struct reset_control *rst; + + unsigned int mclk_freq; + +@@ -651,9 +654,22 @@ static int sun4i_i2s_runtime_suspend(struct device *dev) + return 0; + } + ++struct sun4i_i2s_quirks { ++ bool has_reset; ++}; ++ ++static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { ++ .has_reset = false, ++}; ++ ++static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { ++ .has_reset = true, ++}; ++ + static int sun4i_i2s_probe(struct platform_device *pdev) + { + struct sun4i_i2s *i2s; ++ const struct sun4i_i2s_quirks *quirks; + struct resource *res; + void __iomem *regs; + int irq, ret; +@@ -674,6 +690,12 @@ static int sun4i_i2s_probe(struct platform_device *pdev) + return irq; + } + ++ quirks = of_device_get_match_data(&pdev->dev); ++ if (!quirks) { ++ dev_err(&pdev->dev, "Failed to determine the quirks to use\n"); ++ return -ENODEV; ++ } ++ + i2s->bus_clk = devm_clk_get(&pdev->dev, "apb"); + if (IS_ERR(i2s->bus_clk)) { + dev_err(&pdev->dev, "Can't get our bus clock\n"); +@@ -692,7 +714,24 @@ static int sun4i_i2s_probe(struct platform_device *pdev) + dev_err(&pdev->dev, "Can't get our mod clock\n"); + return PTR_ERR(i2s->mod_clk); + } +- ++ ++ if (quirks->has_reset) { ++ i2s->rst = devm_reset_control_get(&pdev->dev, NULL); ++ if (IS_ERR(i2s->rst)) { ++ dev_err(&pdev->dev, "Failed to get reset control\n"); ++ return PTR_ERR(i2s->rst); ++ } ++ } ++ ++ if (!IS_ERR(i2s->rst)) { ++ ret = reset_control_deassert(i2s->rst); ++ if (ret) { ++ dev_err(&pdev->dev, ++ "Failed to deassert the reset control\n"); ++ return -EINVAL; ++ } ++ } ++ + i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG; + i2s->playback_dma_data.maxburst = 4; + +@@ -727,23 +766,37 @@ static int sun4i_i2s_probe(struct platform_device *pdev) + sun4i_i2s_runtime_suspend(&pdev->dev); + err_pm_disable: + pm_runtime_disable(&pdev->dev); ++ if (!IS_ERR(i2s->rst)) ++ reset_control_assert(i2s->rst); + + return ret; + } + + static int sun4i_i2s_remove(struct platform_device *pdev) + { ++ struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev); ++ + snd_dmaengine_pcm_unregister(&pdev->dev); + + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) + sun4i_i2s_runtime_suspend(&pdev->dev); + ++ if (!IS_ERR(i2s->rst)) ++ reset_control_assert(i2s->rst); ++ + return 0; + } + + static const struct of_device_id sun4i_i2s_match[] = { +- { .compatible = "allwinner,sun4i-a10-i2s", }, ++ { ++ .compatible = "allwinner,sun4i-a10-i2s", ++ .data = &sun4i_a10_i2s_quirks, ++ }, ++ { ++ .compatible = "allwinner,sun6i-a31-i2s", ++ .data = &sun6i_a31_i2s_quirks, ++ }, + {} + }; + MODULE_DEVICE_TABLE(of, sun4i_i2s_match);