diff options
author | Mike Pagano <mpagano@gentoo.org> | 2021-03-17 11:37:06 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2021-03-17 11:37:06 -0400 |
commit | 19f87c252db39a231b8b6c78a0a347cb206bd572 (patch) | |
tree | 106d1b5e33fd87151f6e2e653cab6e7a3aaa2c39 | |
parent | Linux patch 4.4.261 (diff) | |
download | linux-patches-19f87c252db39a231b8b6c78a0a347cb206bd572.tar.gz linux-patches-19f87c252db39a231b8b6c78a0a347cb206bd572.tar.bz2 linux-patches-19f87c252db39a231b8b6c78a0a347cb206bd572.zip |
Linuxpatch 4.4.2624.4-264
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1261_linux-4.4.262.patch | 4156 |
2 files changed, 4160 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 6c7b6f94..77ec9dd1 100644 --- a/0000_README +++ b/0000_README @@ -1087,6 +1087,10 @@ Patch: 1260_linux-4.4.261.patch From: http://www.kernel.org Desc: Linux 4.4.261 +Patch: 1261_linux-4.4.262.patch +From: http://www.kernel.org +Desc: Linux 4.4.262 + 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/1261_linux-4.4.262.patch b/1261_linux-4.4.262.patch new file mode 100644 index 00000000..62f7b1aa --- /dev/null +++ b/1261_linux-4.4.262.patch @@ -0,0 +1,4156 @@ +diff --git a/Makefile b/Makefile +index 607f1b19555f9..11acd6dd024a2 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 261 ++SUBLEVEL = 262 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild +index ffd9cf5ec8c40..bf8475ce85ee2 100644 +--- a/arch/alpha/include/asm/Kbuild ++++ b/arch/alpha/include/asm/Kbuild +@@ -3,6 +3,7 @@ + generic-y += clkdev.h + generic-y += cputime.h + generic-y += exec.h ++generic-y += export.h + generic-y += irq_work.h + generic-y += mcs_spinlock.h + generic-y += mm-arch-hooks.h +diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h +index c0ddbbf73400e..89413a29cb079 100644 +--- a/arch/alpha/include/asm/uaccess.h ++++ b/arch/alpha/include/asm/uaccess.h +@@ -341,45 +341,17 @@ __asm__ __volatile__("1: stb %r2,%1\n" \ + * Complex access routines + */ + +-/* This little bit of silliness is to get the GP loaded for a function +- that ordinarily wouldn't. Otherwise we could have it done by the macro +- directly, which can be optimized the linker. */ +-#ifdef MODULE +-#define __module_address(sym) "r"(sym), +-#define __module_call(ra, arg, sym) "jsr $" #ra ",(%" #arg ")," #sym +-#else +-#define __module_address(sym) +-#define __module_call(ra, arg, sym) "bsr $" #ra "," #sym " !samegp" +-#endif +- +-extern void __copy_user(void); +- +-extern inline long +-__copy_tofrom_user_nocheck(void *to, const void *from, long len) +-{ +- register void * __cu_to __asm__("$6") = to; +- register const void * __cu_from __asm__("$7") = from; +- register long __cu_len __asm__("$0") = len; +- +- __asm__ __volatile__( +- __module_call(28, 3, __copy_user) +- : "=r" (__cu_len), "=r" (__cu_from), "=r" (__cu_to) +- : __module_address(__copy_user) +- "0" (__cu_len), "1" (__cu_from), "2" (__cu_to) +- : "$1", "$2", "$3", "$4", "$5", "$28", "memory"); +- +- return __cu_len; +-} ++extern long __copy_user(void *to, const void *from, long len); + +-#define __copy_to_user(to, from, n) \ +-({ \ +- __chk_user_ptr(to); \ +- __copy_tofrom_user_nocheck((__force void *)(to), (from), (n)); \ ++#define __copy_to_user(to, from, n) \ ++({ \ ++ __chk_user_ptr(to); \ ++ __copy_user((__force void *)(to), (from), (n)); \ + }) +-#define __copy_from_user(to, from, n) \ +-({ \ +- __chk_user_ptr(from); \ +- __copy_tofrom_user_nocheck((to), (__force void *)(from), (n)); \ ++#define __copy_from_user(to, from, n) \ ++({ \ ++ __chk_user_ptr(from); \ ++ __copy_user((to), (__force void *)(from), (n)); \ + }) + + #define __copy_to_user_inatomic __copy_to_user +@@ -389,35 +361,22 @@ extern inline long + copy_to_user(void __user *to, const void *from, long n) + { + if (likely(__access_ok((unsigned long)to, n, get_fs()))) +- n = __copy_tofrom_user_nocheck((__force void *)to, from, n); ++ n = __copy_user((__force void *)to, from, n); + return n; + } + + extern inline long + copy_from_user(void *to, const void __user *from, long n) + { ++ long res = n; + if (likely(__access_ok((unsigned long)from, n, get_fs()))) +- n = __copy_tofrom_user_nocheck(to, (__force void *)from, n); +- else +- memset(to, 0, n); +- return n; ++ res = __copy_from_user_inatomic(to, from, n); ++ if (unlikely(res)) ++ memset(to + (n - res), 0, res); ++ return res; + } + +-extern void __do_clear_user(void); +- +-extern inline long +-__clear_user(void __user *to, long len) +-{ +- register void __user * __cl_to __asm__("$6") = to; +- register long __cl_len __asm__("$0") = len; +- __asm__ __volatile__( +- __module_call(28, 2, __do_clear_user) +- : "=r"(__cl_len), "=r"(__cl_to) +- : __module_address(__do_clear_user) +- "0"(__cl_len), "1"(__cl_to) +- : "$1", "$2", "$3", "$4", "$5", "$28", "memory"); +- return __cl_len; +-} ++extern long __clear_user(void __user *to, long len); + + extern inline long + clear_user(void __user *to, long len) +@@ -427,9 +386,6 @@ clear_user(void __user *to, long len) + return len; + } + +-#undef __module_address +-#undef __module_call +- + #define user_addr_max() \ + (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL) + +diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile +index 3ecac0106c8a1..8ce13d7a2ad38 100644 +--- a/arch/alpha/kernel/Makefile ++++ b/arch/alpha/kernel/Makefile +@@ -8,7 +8,7 @@ ccflags-y := -Wno-sign-compare + + obj-y := entry.o traps.o process.o osf_sys.o irq.o \ + irq_alpha.o signal.o setup.o ptrace.o time.o \ +- alpha_ksyms.o systbls.o err_common.o io.o ++ systbls.o err_common.o io.o + + obj-$(CONFIG_VGA_HOSE) += console.o + obj-$(CONFIG_SMP) += smp.o +diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c +deleted file mode 100644 +index f4c7ab6f43b0d..0000000000000 +--- a/arch/alpha/kernel/alpha_ksyms.c ++++ /dev/null +@@ -1,102 +0,0 @@ +-/* +- * linux/arch/alpha/kernel/alpha_ksyms.c +- * +- * Export the alpha-specific functions that are needed for loadable +- * modules. +- */ +- +-#include <linux/module.h> +-#include <asm/console.h> +-#include <asm/uaccess.h> +-#include <asm/checksum.h> +-#include <asm/fpu.h> +-#include <asm/machvec.h> +- +-#include <linux/syscalls.h> +- +-/* these are C runtime functions with special calling conventions: */ +-extern void __divl (void); +-extern void __reml (void); +-extern void __divq (void); +-extern void __remq (void); +-extern void __divlu (void); +-extern void __remlu (void); +-extern void __divqu (void); +-extern void __remqu (void); +- +-EXPORT_SYMBOL(alpha_mv); +-EXPORT_SYMBOL(callback_getenv); +-EXPORT_SYMBOL(callback_setenv); +-EXPORT_SYMBOL(callback_save_env); +- +-/* platform dependent support */ +-EXPORT_SYMBOL(strcat); +-EXPORT_SYMBOL(strcpy); +-EXPORT_SYMBOL(strlen); +-EXPORT_SYMBOL(strncpy); +-EXPORT_SYMBOL(strncat); +-EXPORT_SYMBOL(strchr); +-EXPORT_SYMBOL(strrchr); +-EXPORT_SYMBOL(memmove); +-EXPORT_SYMBOL(__memcpy); +-EXPORT_SYMBOL(__memset); +-EXPORT_SYMBOL(___memset); +-EXPORT_SYMBOL(__memsetw); +-EXPORT_SYMBOL(__constant_c_memset); +-EXPORT_SYMBOL(copy_page); +-EXPORT_SYMBOL(clear_page); +- +-EXPORT_SYMBOL(alpha_read_fp_reg); +-EXPORT_SYMBOL(alpha_read_fp_reg_s); +-EXPORT_SYMBOL(alpha_write_fp_reg); +-EXPORT_SYMBOL(alpha_write_fp_reg_s); +- +-/* Networking helper routines. */ +-EXPORT_SYMBOL(csum_tcpudp_magic); +-EXPORT_SYMBOL(ip_compute_csum); +-EXPORT_SYMBOL(ip_fast_csum); +-EXPORT_SYMBOL(csum_partial_copy_nocheck); +-EXPORT_SYMBOL(csum_partial_copy_from_user); +-EXPORT_SYMBOL(csum_ipv6_magic); +- +-#ifdef CONFIG_MATHEMU_MODULE +-extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long); +-extern long (*alpha_fp_emul) (unsigned long pc); +-EXPORT_SYMBOL(alpha_fp_emul_imprecise); +-EXPORT_SYMBOL(alpha_fp_emul); +-#endif +- +-/* +- * The following are specially called from the uaccess assembly stubs. +- */ +-EXPORT_SYMBOL(__copy_user); +-EXPORT_SYMBOL(__do_clear_user); +- +-/* +- * SMP-specific symbols. +- */ +- +-#ifdef CONFIG_SMP +-EXPORT_SYMBOL(_atomic_dec_and_lock); +-#endif /* CONFIG_SMP */ +- +-/* +- * The following are special because they're not called +- * explicitly (the C compiler or assembler generates them in +- * response to division operations). Fortunately, their +- * interface isn't gonna change any time soon now, so it's OK +- * to leave it out of version control. +- */ +-# undef memcpy +-# undef memset +-EXPORT_SYMBOL(__divl); +-EXPORT_SYMBOL(__divlu); +-EXPORT_SYMBOL(__divq); +-EXPORT_SYMBOL(__divqu); +-EXPORT_SYMBOL(__reml); +-EXPORT_SYMBOL(__remlu); +-EXPORT_SYMBOL(__remq); +-EXPORT_SYMBOL(__remqu); +-EXPORT_SYMBOL(memcpy); +-EXPORT_SYMBOL(memset); +-EXPORT_SYMBOL(memchr); +diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h +index f54bdf658cd0b..8c6516025efbc 100644 +--- a/arch/alpha/kernel/machvec_impl.h ++++ b/arch/alpha/kernel/machvec_impl.h +@@ -144,9 +144,11 @@ + else beforehand. Fine. We'll do it ourselves. */ + #if 0 + #define ALIAS_MV(system) \ +- struct alpha_machine_vector alpha_mv __attribute__((alias(#system "_mv"))); ++ struct alpha_machine_vector alpha_mv __attribute__((alias(#system "_mv"))); \ ++ EXPORT_SYMBOL(alpha_mv); + #else + #define ALIAS_MV(system) \ +- asm(".global alpha_mv\nalpha_mv = " #system "_mv"); ++ asm(".global alpha_mv\nalpha_mv = " #system "_mv"); \ ++ EXPORT_SYMBOL(alpha_mv); + #endif + #endif /* GENERIC */ +diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c +index b20af76f12c1d..4811e54069fcf 100644 +--- a/arch/alpha/kernel/setup.c ++++ b/arch/alpha/kernel/setup.c +@@ -115,6 +115,7 @@ unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE; + + #ifdef CONFIG_ALPHA_GENERIC + struct alpha_machine_vector alpha_mv; ++EXPORT_SYMBOL(alpha_mv); + #endif + + #ifndef alpha_using_srm +diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile +index 59660743237cc..a808159603645 100644 +--- a/arch/alpha/lib/Makefile ++++ b/arch/alpha/lib/Makefile +@@ -20,12 +20,8 @@ lib-y = __divqu.o __remqu.o __divlu.o __remlu.o \ + checksum.o \ + csum_partial_copy.o \ + $(ev67-y)strlen.o \ +- $(ev67-y)strcat.o \ +- strcpy.o \ +- $(ev67-y)strncat.o \ +- strncpy.o \ +- $(ev6-y)stxcpy.o \ +- $(ev6-y)stxncpy.o \ ++ stycpy.o \ ++ styncpy.o \ + $(ev67-y)strchr.o \ + $(ev67-y)strrchr.o \ + $(ev6-y)memchr.o \ +@@ -46,11 +42,20 @@ AFLAGS___remqu.o = -DREM + AFLAGS___divlu.o = -DDIV -DINTSIZE + AFLAGS___remlu.o = -DREM -DINTSIZE + +-$(obj)/__divqu.o: $(obj)/$(ev6-y)divide.S +- $(cmd_as_o_S) +-$(obj)/__remqu.o: $(obj)/$(ev6-y)divide.S +- $(cmd_as_o_S) +-$(obj)/__divlu.o: $(obj)/$(ev6-y)divide.S +- $(cmd_as_o_S) +-$(obj)/__remlu.o: $(obj)/$(ev6-y)divide.S +- $(cmd_as_o_S) ++$(addprefix $(obj)/,__divqu.o __remqu.o __divlu.o __remlu.o): \ ++ $(src)/$(ev6-y)divide.S FORCE ++ $(call if_changed_rule,as_o_S) ++ ++# There are direct branches between {str*cpy,str*cat} and stx*cpy. ++# Ensure the branches are within range by merging these objects. ++ ++LDFLAGS_stycpy.o := -r ++LDFLAGS_styncpy.o := -r ++ ++$(obj)/stycpy.o: $(obj)/strcpy.o $(obj)/$(ev67-y)strcat.o \ ++ $(obj)/$(ev6-y)stxcpy.o FORCE ++ $(call if_changed,ld) ++ ++$(obj)/styncpy.o: $(obj)/strncpy.o $(obj)/$(ev67-y)strncat.o \ ++ $(obj)/$(ev6-y)stxncpy.o FORCE ++ $(call if_changed,ld) +diff --git a/arch/alpha/lib/callback_srm.S b/arch/alpha/lib/callback_srm.S +index 8804bec2c6448..6093addc931a5 100644 +--- a/arch/alpha/lib/callback_srm.S ++++ b/arch/alpha/lib/callback_srm.S +@@ -3,6 +3,7 @@ + */ + + #include <asm/console.h> ++#include <asm/export.h> + + .text + #define HWRPB_CRB_OFFSET 0xc0 +@@ -92,6 +93,10 @@ CALLBACK(reset_env, CCB_RESET_ENV, 4) + CALLBACK(save_env, CCB_SAVE_ENV, 1) + CALLBACK(pswitch, CCB_PSWITCH, 3) + CALLBACK(bios_emul, CCB_BIOS_EMUL, 5) ++ ++EXPORT_SYMBOL(callback_getenv) ++EXPORT_SYMBOL(callback_setenv) ++EXPORT_SYMBOL(callback_save_env) + + .data + __alpha_using_srm: # For use by bootpheader +diff --git a/arch/alpha/lib/checksum.c b/arch/alpha/lib/checksum.c +index 199f6efa83faa..65197c3c08451 100644 +--- a/arch/alpha/lib/checksum.c ++++ b/arch/alpha/lib/checksum.c +@@ -50,6 +50,7 @@ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + (__force u64)saddr + (__force u64)daddr + + (__force u64)sum + ((len + proto) << 8)); + } ++EXPORT_SYMBOL(csum_tcpudp_magic); + + __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + unsigned short len, +@@ -148,6 +149,7 @@ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) + { + return (__force __sum16)~do_csum(iph,ihl*4); + } ++EXPORT_SYMBOL(ip_fast_csum); + + /* + * computes the checksum of a memory block at buff, length len, +@@ -182,3 +184,4 @@ __sum16 ip_compute_csum(const void *buff, int len) + { + return (__force __sum16)~from64to16(do_csum(buff,len)); + } ++EXPORT_SYMBOL(ip_compute_csum); +diff --git a/arch/alpha/lib/clear_page.S b/arch/alpha/lib/clear_page.S +index a221ae266e290..263d7393c0e7a 100644 +--- a/arch/alpha/lib/clear_page.S ++++ b/arch/alpha/lib/clear_page.S +@@ -3,7 +3,7 @@ + * + * Zero an entire page. + */ +- ++#include <asm/export.h> + .text + .align 4 + .global clear_page +@@ -37,3 +37,4 @@ clear_page: + nop + + .end clear_page ++ EXPORT_SYMBOL(clear_page) +diff --git a/arch/alpha/lib/clear_user.S b/arch/alpha/lib/clear_user.S +index 8860316c19576..006f469fef73a 100644 +--- a/arch/alpha/lib/clear_user.S ++++ b/arch/alpha/lib/clear_user.S +@@ -8,22 +8,8 @@ + * right "bytes left to zero" value (and that it is updated only _after_ + * a successful copy). There is also some rather minor exception setup + * stuff. +- * +- * NOTE! This is not directly C-callable, because the calling semantics +- * are different: +- * +- * Inputs: +- * length in $0 +- * destination address in $6 +- * exception pointer in $7 +- * return address in $28 (exceptions expect it there) +- * +- * Outputs: +- * bytes left to copy in $0 +- * +- * Clobbers: +- * $1,$2,$3,$4,$5,$6 + */ ++#include <asm/export.h> + + /* Allow an exception for an insn; exit if we get one. */ + #define EX(x,y...) \ +@@ -37,62 +23,63 @@ + .set noreorder + .align 4 + +- .globl __do_clear_user +- .ent __do_clear_user +- .frame $30, 0, $28 ++ .globl __clear_user ++ .ent __clear_user ++ .frame $30, 0, $26 + .prologue 0 + + $loop: + and $1, 3, $4 # e0 : + beq $4, 1f # .. e1 : + +-0: EX( stq_u $31, 0($6) ) # e0 : zero one word ++0: EX( stq_u $31, 0($16) ) # e0 : zero one word + subq $0, 8, $0 # .. e1 : + subq $4, 1, $4 # e0 : +- addq $6, 8, $6 # .. e1 : ++ addq $16, 8, $16 # .. e1 : + bne $4, 0b # e1 : + unop # : + + 1: bic $1, 3, $1 # e0 : + beq $1, $tail # .. e1 : + +-2: EX( stq_u $31, 0($6) ) # e0 : zero four words ++2: EX( stq_u $31, 0($16) ) # e0 : zero four words + subq $0, 8, $0 # .. e1 : +- EX( stq_u $31, 8($6) ) # e0 : ++ EX( stq_u $31, 8($16) ) # e0 : + subq $0, 8, $0 # .. e1 : +- EX( stq_u $31, 16($6) ) # e0 : ++ EX( stq_u $31, 16($16) ) # e0 : + subq $0, 8, $0 # .. e1 : +- EX( stq_u $31, 24($6) ) # e0 : ++ EX( stq_u $31, 24($16) ) # e0 : + subq $0, 8, $0 # .. e1 : + subq $1, 4, $1 # e0 : +- addq $6, 32, $6 # .. e1 : ++ addq $16, 32, $16 # .. e1 : + bne $1, 2b # e1 : + + $tail: + bne $2, 1f # e1 : is there a tail to do? +- ret $31, ($28), 1 # .. e1 : ++ ret $31, ($26), 1 # .. e1 : + +-1: EX( ldq_u $5, 0($6) ) # e0 : ++1: EX( ldq_u $5, 0($16) ) # e0 : + clr $0 # .. e1 : + nop # e1 : + mskqh $5, $0, $5 # e0 : +- EX( stq_u $5, 0($6) ) # e0 : +- ret $31, ($28), 1 # .. e1 : ++ EX( stq_u $5, 0($16) ) # e0 : ++ ret $31, ($26), 1 # .. e1 : + +-__do_clear_user: +- and $6, 7, $4 # e0 : find dest misalignment ++__clear_user: ++ and $17, $17, $0 ++ and $16, 7, $4 # e0 : find dest misalignment + beq $0, $zerolength # .. e1 : + addq $0, $4, $1 # e0 : bias counter + and $1, 7, $2 # e1 : number of bytes in tail + srl $1, 3, $1 # e0 : + beq $4, $loop # .. e1 : + +- EX( ldq_u $5, 0($6) ) # e0 : load dst word to mask back in ++ EX( ldq_u $5, 0($16) ) # e0 : load dst word to mask back in + beq $1, $oneword # .. e1 : sub-word store? + +- mskql $5, $6, $5 # e0 : take care of misaligned head +- addq $6, 8, $6 # .. e1 : +- EX( stq_u $5, -8($6) ) # e0 : ++ mskql $5, $16, $5 # e0 : take care of misaligned head ++ addq $16, 8, $16 # .. e1 : ++ EX( stq_u $5, -8($16) ) # e0 : + addq $0, $4, $0 # .. e1 : bytes left -= 8 - misalignment + subq $1, 1, $1 # e0 : + subq $0, 8, $0 # .. e1 : +@@ -100,14 +87,15 @@ __do_clear_user: + unop # : + + $oneword: +- mskql $5, $6, $4 # e0 : ++ mskql $5, $16, $4 # e0 : + mskqh $5, $2, $5 # e0 : + or $5, $4, $5 # e1 : +- EX( stq_u $5, 0($6) ) # e0 : ++ EX( stq_u $5, 0($16) ) # e0 : + clr $0 # .. e1 : + + $zerolength: + $exception: +- ret $31, ($28), 1 # .. e1 : ++ ret $31, ($26), 1 # .. e1 : + +- .end __do_clear_user ++ .end __clear_user ++ EXPORT_SYMBOL(__clear_user) +diff --git a/arch/alpha/lib/copy_page.S b/arch/alpha/lib/copy_page.S +index 9f3b97459cc64..2ee0bd0508c59 100644 +--- a/arch/alpha/lib/copy_page.S ++++ b/arch/alpha/lib/copy_page.S +@@ -3,7 +3,7 @@ + * + * Copy an entire page. + */ +- ++#include <asm/export.h> + .text + .align 4 + .global copy_page +@@ -47,3 +47,4 @@ copy_page: + nop + + .end copy_page ++ EXPORT_SYMBOL(copy_page) +diff --git a/arch/alpha/lib/copy_user.S b/arch/alpha/lib/copy_user.S +index 6f3fab9eb4344..159f1b7e6e495 100644 +--- a/arch/alpha/lib/copy_user.S ++++ b/arch/alpha/lib/copy_user.S +@@ -9,23 +9,10 @@ + * contains the right "bytes left to copy" value (and that it is updated + * only _after_ a successful copy). There is also some rather minor + * exception setup stuff.. +- * +- * NOTE! This is not directly C-callable, because the calling semantics are +- * different: +- * +- * Inputs: +- * length in $0 +- * destination address in $6 +- * source address in $7 +- * return address in $28 +- * +- * Outputs: +- * bytes left to copy in $0 +- * +- * Clobbers: +- * $1,$2,$3,$4,$5,$6,$7 + */ + ++#include <asm/export.h> ++ + /* Allow an exception for an insn; exit if we get one. */ + #define EXI(x,y...) \ + 99: x,##y; \ +@@ -47,58 +34,59 @@ + .ent __copy_user + __copy_user: + .prologue 0 +- and $6,7,$3 ++ and $18,$18,$0 ++ and $16,7,$3 + beq $0,$35 + beq $3,$36 + subq $3,8,$3 + .align 4 + $37: +- EXI( ldq_u $1,0($7) ) +- EXO( ldq_u $2,0($6) ) +- extbl $1,$7,$1 +- mskbl $2,$6,$2 +- insbl $1,$6,$1 ++ EXI( ldq_u $1,0($17) ) ++ EXO( ldq_u $2,0($16) ) ++ extbl $1,$17,$1 ++ mskbl $2,$16,$2 ++ insbl $1,$16,$1 + addq $3,1,$3 + bis $1,$2,$1 +- EXO( stq_u $1,0($6) ) ++ EXO( stq_u $1,0($16) ) + subq $0,1,$0 +- addq $6,1,$6 +- addq $7,1,$7 ++ addq $16,1,$16 ++ addq $17,1,$17 + beq $0,$41 + bne $3,$37 + $36: +- and $7,7,$1 ++ and $17,7,$1 + bic $0,7,$4 + beq $1,$43 + beq $4,$48 +- EXI( ldq_u $3,0($7) ) ++ EXI( ldq_u $3,0($17) ) + .align 4 + $50: +- EXI( ldq_u $2,8($7) ) ++ EXI( ldq_u $2,8($17) ) + subq $4,8,$4 +- extql $3,$7,$3 +- extqh $2,$7,$1 ++ extql $3,$17,$3 ++ extqh $2,$17,$1 + bis $3,$1,$1 +- EXO( stq $1,0($6) ) +- addq $7,8,$7 ++ EXO( stq $1,0($16) ) ++ addq $17,8,$17 + subq $0,8,$0 +- addq $6,8,$6 ++ addq $16,8,$16 + bis $2,$2,$3 + bne $4,$50 + $48: + beq $0,$41 + .align 4 + $57: +- EXI( ldq_u $1,0($7) ) +- EXO( ldq_u $2,0($6) ) +- extbl $1,$7,$1 +- mskbl $2,$6,$2 +- insbl $1,$6,$1 ++ EXI( ldq_u $1,0($17) ) ++ EXO( ldq_u $2,0($16) ) ++ extbl $1,$17,$1 ++ mskbl $2,$16,$2 ++ insbl $1,$16,$1 + bis $1,$2,$1 +- EXO( stq_u $1,0($6) ) ++ EXO( stq_u $1,0($16) ) + subq $0,1,$0 +- addq $6,1,$6 +- addq $7,1,$7 ++ addq $16,1,$16 ++ addq $17,1,$17 + bne $0,$57 + br $31,$41 + .align 4 +@@ -106,40 +94,27 @@ $43: + beq $4,$65 + .align 4 + $66: +- EXI( ldq $1,0($7) ) ++ EXI( ldq $1,0($17) ) + subq $4,8,$4 +- EXO( stq $1,0($6) ) +- addq $7,8,$7 ++ EXO( stq $1,0($16) ) ++ addq $17,8,$17 + subq $0,8,$0 +- addq $6,8,$6 ++ addq $16,8,$16 + bne $4,$66 + $65: + beq $0,$41 +- EXI( ldq $2,0($7) ) +- EXO( ldq $1,0($6) ) ++ EXI( ldq $2,0($17) ) ++ EXO( ldq $1,0($16) ) + mskql $2,$0,$2 + mskqh $1,$0,$1 + bis $2,$1,$2 +- EXO( stq $2,0($6) ) ++ EXO( stq $2,0($16) ) + bis $31,$31,$0 + $41: + $35: +-$exitout: +- ret $31,($28),1 +- + $exitin: +- /* A stupid byte-by-byte zeroing of the rest of the output +- buffer. This cures security holes by never leaving +- random kernel data around to be copied elsewhere. */ +- +- mov $0,$1 +-$101: +- EXO ( ldq_u $2,0($6) ) +- subq $1,1,$1 +- mskbl $2,$6,$2 +- EXO ( stq_u $2,0($6) ) +- addq $6,1,$6 +- bgt $1,$101 +- ret $31,($28),1 ++$exitout: ++ ret $31,($26),1 + + .end __copy_user ++EXPORT_SYMBOL(__copy_user) +diff --git a/arch/alpha/lib/csum_ipv6_magic.S b/arch/alpha/lib/csum_ipv6_magic.S +index 2c2acb96deb68..e74b4544b0cce 100644 +--- a/arch/alpha/lib/csum_ipv6_magic.S ++++ b/arch/alpha/lib/csum_ipv6_magic.S +@@ -12,6 +12,7 @@ + * added by Ivan Kokshaysky <ink@jurassic.park.msu.ru> + */ + ++#include <asm/export.h> + .globl csum_ipv6_magic + .align 4 + .ent csum_ipv6_magic +@@ -113,3 +114,4 @@ csum_ipv6_magic: + ret # .. e1 : + + .end csum_ipv6_magic ++ EXPORT_SYMBOL(csum_ipv6_magic) +diff --git a/arch/alpha/lib/csum_partial_copy.c b/arch/alpha/lib/csum_partial_copy.c +index 5675dca8dbb14..b4ff3b683bcd5 100644 +--- a/arch/alpha/lib/csum_partial_copy.c ++++ b/arch/alpha/lib/csum_partial_copy.c +@@ -374,6 +374,7 @@ csum_partial_copy_from_user(const void __user *src, void *dst, int len, + } + return (__force __wsum)checksum; + } ++EXPORT_SYMBOL(csum_partial_copy_from_user); + + __wsum + csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) +@@ -386,3 +387,4 @@ csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) + set_fs(oldfs); + return checksum; + } ++EXPORT_SYMBOL(csum_partial_copy_nocheck); +diff --git a/arch/alpha/lib/dec_and_lock.c b/arch/alpha/lib/dec_and_lock.c +index f9f5fe830e9f9..4221b40167eed 100644 +--- a/arch/alpha/lib/dec_and_lock.c ++++ b/arch/alpha/lib/dec_and_lock.c +@@ -7,6 +7,7 @@ + + #include <linux/spinlock.h> + #include <linux/atomic.h> ++#include <linux/export.h> + + asm (".text \n\ + .global _atomic_dec_and_lock \n\ +@@ -39,3 +40,4 @@ static int __used atomic_dec_and_lock_1(atomic_t *atomic, spinlock_t *lock) + spin_unlock(lock); + return 0; + } ++EXPORT_SYMBOL(_atomic_dec_and_lock); +diff --git a/arch/alpha/lib/divide.S b/arch/alpha/lib/divide.S +index 2d1a0484a99e0..1e33bd1276213 100644 +--- a/arch/alpha/lib/divide.S ++++ b/arch/alpha/lib/divide.S +@@ -45,6 +45,7 @@ + * $28 - compare status + */ + ++#include <asm/export.h> + #define halt .long 0 + + /* +@@ -151,6 +152,7 @@ ufunction: + addq $30,STACK,$30 + ret $31,($23),1 + .end ufunction ++EXPORT_SYMBOL(ufunction) + + /* + * Uhh.. Ugly signed division. I'd rather not have it at all, but +@@ -193,3 +195,4 @@ sfunction: + addq $30,STACK,$30 + ret $31,($23),1 + .end sfunction ++EXPORT_SYMBOL(sfunction) +diff --git a/arch/alpha/lib/ev6-clear_page.S b/arch/alpha/lib/ev6-clear_page.S +index adf4f7be0e2b6..abe99e69a1945 100644 +--- a/arch/alpha/lib/ev6-clear_page.S ++++ b/arch/alpha/lib/ev6-clear_page.S +@@ -3,7 +3,7 @@ + * + * Zero an entire page. + */ +- ++#include <asm/export.h> + .text + .align 4 + .global clear_page +@@ -52,3 +52,4 @@ clear_page: + nop + + .end clear_page ++ EXPORT_SYMBOL(clear_page) +diff --git a/arch/alpha/lib/ev6-clear_user.S b/arch/alpha/lib/ev6-clear_user.S +index 4f42a16b7f53d..e179e4757ef89 100644 +--- a/arch/alpha/lib/ev6-clear_user.S ++++ b/arch/alpha/lib/ev6-clear_user.S +@@ -9,21 +9,6 @@ + * a successful copy). There is also some rather minor exception setup + * stuff. + * +- * NOTE! This is not directly C-callable, because the calling semantics +- * are different: +- * +- * Inputs: +- * length in $0 +- * destination address in $6 +- * exception pointer in $7 +- * return address in $28 (exceptions expect it there) +- * +- * Outputs: +- * bytes left to copy in $0 +- * +- * Clobbers: +- * $1,$2,$3,$4,$5,$6 +- * + * Much of the information about 21264 scheduling/coding comes from: + * Compiler Writer's Guide for the Alpha 21264 + * abbreviated as 'CWG' in other comments here +@@ -43,6 +28,7 @@ + * want to leave a hole (and we also want to avoid repeating lots of work) + */ + ++#include <asm/export.h> + /* Allow an exception for an insn; exit if we get one. */ + #define EX(x,y...) \ + 99: x,##y; \ +@@ -55,14 +41,15 @@ + .set noreorder + .align 4 + +- .globl __do_clear_user +- .ent __do_clear_user +- .frame $30, 0, $28 ++ .globl __clear_user ++ .ent __clear_user ++ .frame $30, 0, $26 + .prologue 0 + + # Pipeline info : Slotting & Comments +-__do_clear_user: +- and $6, 7, $4 # .. E .. .. : find dest head misalignment ++__clear_user: ++ and $17, $17, $0 ++ and $16, 7, $4 # .. E .. .. : find dest head misalignment + beq $0, $zerolength # U .. .. .. : U L U L + + addq $0, $4, $1 # .. .. .. E : bias counter +@@ -74,14 +61,14 @@ __do_clear_user: + + /* + * Head is not aligned. Write (8 - $4) bytes to head of destination +- * This means $6 is known to be misaligned ++ * This means $16 is known to be misaligned + */ +- EX( ldq_u $5, 0($6) ) # .. .. .. L : load dst word to mask back in ++ EX( ldq_u $5, 0($16) ) # .. .. .. L : load dst word to mask back in + beq $1, $onebyte # .. .. U .. : sub-word store? +- mskql $5, $6, $5 # .. U .. .. : take care of misaligned head +- addq $6, 8, $6 # E .. .. .. : L U U L ++ mskql $5, $16, $5 # .. U .. .. : take care of misaligned head ++ addq $16, 8, $16 # E .. .. .. : L U U L + +- EX( stq_u $5, -8($6) ) # .. .. .. L : ++ EX( stq_u $5, -8($16) ) # .. .. .. L : + subq $1, 1, $1 # .. .. E .. : + addq $0, $4, $0 # .. E .. .. : bytes left -= 8 - misalignment + subq $0, 8, $0 # E .. .. .. : U L U L +@@ -92,11 +79,11 @@ __do_clear_user: + * values upon initial entry to the loop + * $1 is number of quadwords to clear (zero is a valid value) + * $2 is number of trailing bytes (0..7) ($2 never used...) +- * $6 is known to be aligned 0mod8 ++ * $16 is known to be aligned 0mod8 + */ + $headalign: + subq $1, 16, $4 # .. .. .. E : If < 16, we can not use the huge loop +- and $6, 0x3f, $2 # .. .. E .. : Forward work for huge loop ++ and $16, 0x3f, $2 # .. .. E .. : Forward work for huge loop + subq $2, 0x40, $3 # .. E .. .. : bias counter (huge loop) + blt $4, $trailquad # U .. .. .. : U L U L + +@@ -113,21 +100,21 @@ $headalign: + beq $3, $bigalign # U .. .. .. : U L U L : Aligned 0mod64 + + $alignmod64: +- EX( stq_u $31, 0($6) ) # .. .. .. L ++ EX( stq_u $31, 0($16) ) # .. .. .. L + addq $3, 8, $3 # .. .. E .. + subq $0, 8, $0 # .. E .. .. + nop # E .. .. .. : U L U L + + nop # .. .. .. E + subq $1, 1, $1 # .. .. E .. +- addq $6, 8, $6 # .. E .. .. ++ addq $16, 8, $16 # .. E .. .. + blt $3, $alignmod64 # U .. .. .. : U L U L + + $bigalign: + /* + * $0 is the number of bytes left + * $1 is the number of quads left +- * $6 is aligned 0mod64 ++ * $16 is aligned 0mod64 + * we know that we'll be taking a minimum of one trip through + * CWG Section 3.7.6: do not expect a sustained store rate of > 1/cycle + * We are _not_ going to update $0 after every single store. That +@@ -144,39 +131,39 @@ $bigalign: + nop # E : + nop # E : + nop # E : +- bis $6,$6,$3 # E : U L U L : Initial wh64 address is dest ++ bis $16,$16,$3 # E : U L U L : Initial wh64 address is dest + /* This might actually help for the current trip... */ + + $do_wh64: + wh64 ($3) # .. .. .. L1 : memory subsystem hint + subq $1, 16, $4 # .. .. E .. : Forward calculation - repeat the loop? +- EX( stq_u $31, 0($6) ) # .. L .. .. ++ EX( stq_u $31, 0($16) ) # .. L .. .. + subq $0, 8, $0 # E .. .. .. : U L U L + +- addq $6, 128, $3 # E : Target address of wh64 +- EX( stq_u $31, 8($6) ) # L : +- EX( stq_u $31, 16($6) ) # L : ++ addq $16, 128, $3 # E : Target address of wh64 ++ EX( stq_u $31, 8($16) ) # L : ++ EX( stq_u $31, 16($16) ) # L : + subq $0, 16, $0 # E : U L L U + + nop # E : +- EX( stq_u $31, 24($6) ) # L : +- EX( stq_u $31, 32($6) ) # L : ++ EX( stq_u $31, 24($16) ) # L : ++ EX( stq_u $31, 32($16) ) # L : + subq $0, 168, $5 # E : U L L U : two trips through the loop left? + /* 168 = 192 - 24, since we've already completed some stores */ + + subq $0, 16, $0 # E : +- EX( stq_u $31, 40($6) ) # L : +- EX( stq_u $31, 48($6) ) # L : +- cmovlt $5, $6, $3 # E : U L L U : Latency 2, extra mapping cycle ++ EX( stq_u $31, 40($16) ) # L : ++ EX( stq_u $31, 48($16) ) # L : ++ cmovlt $5, $16, $3 # E : U L L U : Latency 2, extra mapping cycle + + subq $1, 8, $1 # E : + subq $0, 16, $0 # E : +- EX( stq_u $31, 56($6) ) # L : ++ EX( stq_u $31, 56($16) ) # L : + nop # E : U L U L + + nop # E : + subq $0, 8, $0 # E : +- addq $6, 64, $6 # E : ++ addq $16, 64, $16 # E : + bge $4, $do_wh64 # U : U L U L + + $trailquad: +@@ -189,14 +176,14 @@ $trailquad: + beq $1, $trailbytes # U .. .. .. : U L U L : Only 0..7 bytes to go + + $onequad: +- EX( stq_u $31, 0($6) ) # .. .. .. L ++ EX( stq_u $31, 0($16) ) # .. .. .. L + subq $1, 1, $1 # .. .. E .. + subq $0, 8, $0 # .. E .. .. + nop # E .. .. .. : U L U L + + nop # .. .. .. E + nop # .. .. E .. +- addq $6, 8, $6 # .. E .. .. ++ addq $16, 8, $16 # .. E .. .. + bgt $1, $onequad # U .. .. .. : U L U L + + # We have an unknown number of bytes left to go. +@@ -210,9 +197,9 @@ $trailbytes: + # so we will use $0 as the loop counter + # We know for a fact that $0 > 0 zero due to previous context + $onebyte: +- EX( stb $31, 0($6) ) # .. .. .. L ++ EX( stb $31, 0($16) ) # .. .. .. L + subq $0, 1, $0 # .. .. E .. : +- addq $6, 1, $6 # .. E .. .. : ++ addq $16, 1, $16 # .. E .. .. : + bgt $0, $onebyte # U .. .. .. : U L U L + + $zerolength: +@@ -220,6 +207,6 @@ $exception: # Destination for exception recovery(?) + nop # .. .. .. E : + nop # .. .. E .. : + nop # .. E .. .. : +- ret $31, ($28), 1 # L0 .. .. .. : L U L U +- .end __do_clear_user +- ++ ret $31, ($26), 1 # L0 .. .. .. : L U L U ++ .end __clear_user ++ EXPORT_SYMBOL(__clear_user) +diff --git a/arch/alpha/lib/ev6-copy_page.S b/arch/alpha/lib/ev6-copy_page.S +index b789db1927544..77935061bddbb 100644 +--- a/arch/alpha/lib/ev6-copy_page.S ++++ b/arch/alpha/lib/ev6-copy_page.S +@@ -56,7 +56,7 @@ + destination pages are in the dcache, but it is my guess that this is + less important than the dcache miss case. */ + +- ++#include <asm/export.h> + .text + .align 4 + .global copy_page +@@ -201,3 +201,4 @@ copy_page: + nop + + .end copy_page ++ EXPORT_SYMBOL(copy_page) +diff --git a/arch/alpha/lib/ev6-copy_user.S b/arch/alpha/lib/ev6-copy_user.S +index db42ffe9c350b..35e6710d07005 100644 +--- a/arch/alpha/lib/ev6-copy_user.S ++++ b/arch/alpha/lib/ev6-copy_user.S +@@ -12,21 +12,6 @@ + * only _after_ a successful copy). There is also some rather minor + * exception setup stuff.. + * +- * NOTE! This is not directly C-callable, because the calling semantics are +- * different: +- * +- * Inputs: +- * length in $0 +- * destination address in $6 +- * source address in $7 +- * return address in $28 +- * +- * Outputs: +- * bytes left to copy in $0 +- * +- * Clobbers: +- * $1,$2,$3,$4,$5,$6,$7 +- * + * Much of the information about 21264 scheduling/coding comes from: + * Compiler Writer's Guide for the Alpha 21264 + * abbreviated as 'CWG' in other comments here +@@ -37,6 +22,7 @@ + * L - lower subcluster; L0 - subcluster L0; L1 - subcluster L1 + */ + ++#include <asm/export.h> + /* Allow an exception for an insn; exit if we get one. */ + #define EXI(x,y...) \ + 99: x,##y; \ +@@ -59,10 +45,11 @@ + # Pipeline info: Slotting & Comments + __copy_user: + .prologue 0 +- subq $0, 32, $1 # .. E .. .. : Is this going to be a small copy? ++ andq $18, $18, $0 ++ subq $18, 32, $1 # .. E .. .. : Is this going to be a small copy? + beq $0, $zerolength # U .. .. .. : U L U L + +- and $6,7,$3 # .. .. .. E : is leading dest misalignment ++ and $16,7,$3 # .. .. .. E : is leading dest misalignment + ble $1, $onebyteloop # .. .. U .. : 1st branch : small amount of data + beq $3, $destaligned # .. U .. .. : 2nd (one cycle fetcher stall) + subq $3, 8, $3 # E .. .. .. : L U U L : trip counter +@@ -72,17 +59,17 @@ __copy_user: + * We know we have at least one trip through this loop + */ + $aligndest: +- EXI( ldbu $1,0($7) ) # .. .. .. L : Keep loads separate from stores +- addq $6,1,$6 # .. .. E .. : Section 3.8 in the CWG ++ EXI( ldbu $1,0($17) ) # .. .. .. L : Keep loads separate from stores ++ addq $16,1,$16 # .. .. E .. : Section 3.8 in the CWG + addq $3,1,$3 # .. E .. .. : + nop # E .. .. .. : U L U L + + /* +- * the -1 is to compensate for the inc($6) done in a previous quadpack ++ * the -1 is to compensate for the inc($16) done in a previous quadpack + * which allows us zero dependencies within either quadpack in the loop + */ +- EXO( stb $1,-1($6) ) # .. .. .. L : +- addq $7,1,$7 # .. .. E .. : Section 3.8 in the CWG ++ EXO( stb $1,-1($16) ) # .. .. .. L : ++ addq $17,1,$17 # .. .. E .. : Section 3.8 in the CWG + subq $0,1,$0 # .. E .. .. : + bne $3, $aligndest # U .. .. .. : U L U L + +@@ -91,29 +78,29 @@ $aligndest: + * If we arrived via branch, we have a minimum of 32 bytes + */ + $destaligned: +- and $7,7,$1 # .. .. .. E : Check _current_ source alignment ++ and $17,7,$1 # .. .. .. E : Check _current_ source alignment + bic $0,7,$4 # .. .. E .. : number bytes as a quadword loop +- EXI( ldq_u $3,0($7) ) # .. L .. .. : Forward fetch for fallthrough code ++ EXI( ldq_u $3,0($17) ) # .. L .. .. : Forward fetch for fallthrough code + beq $1,$quadaligned # U .. .. .. : U L U L + + /* +- * In the worst case, we've just executed an ldq_u here from 0($7) ++ * In the worst case, we've just executed an ldq_u here from 0($17) + * and we'll repeat it once if we take the branch + */ + + /* Misaligned quadword loop - not unrolled. Leave it that way. */ + $misquad: +- EXI( ldq_u $2,8($7) ) # .. .. .. L : ++ EXI( ldq_u $2,8($17) ) # .. .. .. L : + subq $4,8,$4 # .. .. E .. : +- extql $3,$7,$3 # .. U .. .. : +- extqh $2,$7,$1 # U .. .. .. : U U L L ++ extql $3,$17,$3 # .. U .. .. : ++ extqh $2,$17,$1 # U .. .. .. : U U L L + + bis $3,$1,$1 # .. .. .. E : +- EXO( stq $1,0($6) ) # .. .. L .. : +- addq $7,8,$7 # .. E .. .. : ++ EXO( stq $1,0($16) ) # .. .. L .. : ++ addq $17,8,$17 # .. E .. .. : + subq $0,8,$0 # E .. .. .. : U L L U + +- addq $6,8,$6 # .. .. .. E : ++ addq $16,8,$16 # .. .. .. E : + bis $2,$2,$3 # .. .. E .. : + nop # .. E .. .. : + bne $4,$misquad # U .. .. .. : U L U L +@@ -124,8 +111,8 @@ $misquad: + beq $0,$zerolength # U .. .. .. : U L U L + + /* We know we have at least one trip through the byte loop */ +- EXI ( ldbu $2,0($7) ) # .. .. .. L : No loads in the same quad +- addq $6,1,$6 # .. .. E .. : as the store (Section 3.8 in CWG) ++ EXI ( ldbu $2,0($17) ) # .. .. .. L : No loads in the same quad ++ addq $16,1,$16 # .. .. E .. : as the store (Section 3.8 in CWG) + nop # .. E .. .. : + br $31, $dirtyentry # L0 .. .. .. : L U U L + /* Do the trailing byte loop load, then hop into the store part of the loop */ +@@ -135,8 +122,8 @@ $misquad: + * Based upon the usage context, it's worth the effort to unroll this loop + * $0 - number of bytes to be moved + * $4 - number of bytes to move as quadwords +- * $6 is current destination address +- * $7 is current source address ++ * $16 is current destination address ++ * $17 is current source address + */ + $quadaligned: + subq $4, 32, $2 # .. .. .. E : do not unroll for small stuff +@@ -154,29 +141,29 @@ $quadaligned: + * instruction memory hint instruction). + */ + $unroll4: +- EXI( ldq $1,0($7) ) # .. .. .. L +- EXI( ldq $2,8($7) ) # .. .. L .. ++ EXI( ldq $1,0($17) ) # .. .. .. L ++ EXI( ldq $2,8($17) ) # .. .. L .. + subq $4,32,$4 # .. E .. .. + nop # E .. .. .. : U U L L + +- addq $7,16,$7 # .. .. .. E +- EXO( stq $1,0($6) ) # .. .. L .. +- EXO( stq $2,8($6) ) # .. L .. .. ++ addq $17,16,$17 # .. .. .. E ++ EXO( stq $1,0($16) ) # .. .. L .. ++ EXO( stq $2,8($16) ) # .. L .. .. + subq $0,16,$0 # E .. .. .. : U L L U + +- addq $6,16,$6 # .. .. .. E +- EXI( ldq $1,0($7) ) # .. .. L .. +- EXI( ldq $2,8($7) ) # .. L .. .. ++ addq $16,16,$16 # .. .. .. E ++ EXI( ldq $1,0($17) ) # .. .. L .. ++ EXI( ldq $2,8($17) ) # .. L .. .. + subq $4, 32, $3 # E .. .. .. : U U L L : is there enough for another trip? + +- EXO( stq $1,0($6) ) # .. .. .. L +- EXO( stq $2,8($6) ) # .. .. L .. ++ EXO( stq $1,0($16) ) # .. .. .. L ++ EXO( stq $2,8($16) ) # .. .. L .. + subq $0,16,$0 # .. E .. .. +- addq $7,16,$7 # E .. .. .. : U L L U ++ addq $17,16,$17 # E .. .. .. : U L L U + + nop # .. .. .. E + nop # .. .. E .. +- addq $6,16,$6 # .. E .. .. ++ addq $16,16,$16 # .. E .. .. + bgt $3,$unroll4 # U .. .. .. : U L U L + + nop +@@ -185,14 +172,14 @@ $unroll4: + beq $4, $noquads + + $onequad: +- EXI( ldq $1,0($7) ) ++ EXI( ldq $1,0($17) ) + subq $4,8,$4 +- addq $7,8,$7 ++ addq $17,8,$17 + nop + +- EXO( stq $1,0($6) ) ++ EXO( stq $1,0($16) ) + subq $0,8,$0 +- addq $6,8,$6 ++ addq $16,8,$16 + bne $4,$onequad + + $noquads: +@@ -206,54 +193,33 @@ $noquads: + * There's no point in doing a lot of complex alignment calculations to try to + * to quadword stuff for a small amount of data. + * $0 - remaining number of bytes left to copy +- * $6 - current dest addr +- * $7 - current source addr ++ * $16 - current dest addr ++ * $17 - current source addr + */ + + $onebyteloop: +- EXI ( ldbu $2,0($7) ) # .. .. .. L : No loads in the same quad +- addq $6,1,$6 # .. .. E .. : as the store (Section 3.8 in CWG) ++ EXI ( ldbu $2,0($17) ) # .. .. .. L : No loads in the same quad ++ addq $16,1,$16 # .. .. E .. : as the store (Section 3.8 in CWG) + nop # .. E .. .. : + nop # E .. .. .. : U L U L + + $dirtyentry: + /* +- * the -1 is to compensate for the inc($6) done in a previous quadpack ++ * the -1 is to compensate for the inc($16) done in a previous quadpack + * which allows us zero dependencies within either quadpack in the loop + */ +- EXO ( stb $2,-1($6) ) # .. .. .. L : +- addq $7,1,$7 # .. .. E .. : quadpack as the load ++ EXO ( stb $2,-1($16) ) # .. .. .. L : ++ addq $17,1,$17 # .. .. E .. : quadpack as the load + subq $0,1,$0 # .. E .. .. : change count _after_ copy + bgt $0,$onebyteloop # U .. .. .. : U L U L + + $zerolength: ++$exitin: + $exitout: # Destination for exception recovery(?) + nop # .. .. .. E + nop # .. .. E .. + nop # .. E .. .. +- ret $31,($28),1 # L0 .. .. .. : L U L U +- +-$exitin: +- +- /* A stupid byte-by-byte zeroing of the rest of the output +- buffer. This cures security holes by never leaving +- random kernel data around to be copied elsewhere. */ +- +- nop +- nop +- nop +- mov $0,$1 +- +-$101: +- EXO ( stb $31,0($6) ) # L +- subq $1,1,$1 # E +- addq $6,1,$6 # E +- bgt $1,$101 # U +- +- nop +- nop +- nop +- ret $31,($28),1 # L0 ++ ret $31,($26),1 # L0 .. .. .. : L U L U + + .end __copy_user +- ++ EXPORT_SYMBOL(__copy_user) +diff --git a/arch/alpha/lib/ev6-csum_ipv6_magic.S b/arch/alpha/lib/ev6-csum_ipv6_magic.S +index fc0bc399f872d..de62627ac4fe1 100644 +--- a/arch/alpha/lib/ev6-csum_ipv6_magic.S ++++ b/arch/alpha/lib/ev6-csum_ipv6_magic.S +@@ -52,6 +52,7 @@ + * may cause additional delay in rare cases (load-load replay traps). + */ + ++#include <asm/export.h> + .globl csum_ipv6_magic + .align 4 + .ent csum_ipv6_magic +@@ -148,3 +149,4 @@ csum_ipv6_magic: + ret # L0 : L U L U + + .end csum_ipv6_magic ++ EXPORT_SYMBOL(csum_ipv6_magic) +diff --git a/arch/alpha/lib/ev6-divide.S b/arch/alpha/lib/ev6-divide.S +index 2a82b9be93fa2..d18dc0e96e3d7 100644 +--- a/arch/alpha/lib/ev6-divide.S ++++ b/arch/alpha/lib/ev6-divide.S +@@ -55,6 +55,7 @@ + * Try not to change the actual algorithm if possible for consistency. + */ + ++#include <asm/export.h> + #define halt .long 0 + + /* +@@ -205,6 +206,7 @@ ufunction: + addq $30,STACK,$30 # E : + ret $31,($23),1 # L0 : L U U L + .end ufunction ++EXPORT_SYMBOL(ufunction) + + /* + * Uhh.. Ugly signed division. I'd rather not have it at all, but +@@ -257,3 +259,4 @@ sfunction: + addq $30,STACK,$30 # E : + ret $31,($23),1 # L0 : L U U L + .end sfunction ++EXPORT_SYMBOL(sfunction) +diff --git a/arch/alpha/lib/ev6-memchr.S b/arch/alpha/lib/ev6-memchr.S +index 1a5f71b9d8b10..419adc53ccb4e 100644 +--- a/arch/alpha/lib/ev6-memchr.S ++++ b/arch/alpha/lib/ev6-memchr.S +@@ -27,7 +27,7 @@ + * L - lower subcluster; L0 - subcluster L0; L1 - subcluster L1 + * Try not to change the actual algorithm if possible for consistency. + */ +- ++#include <asm/export.h> + .set noreorder + .set noat + +@@ -189,3 +189,4 @@ $not_found: + ret # L0 : + + .end memchr ++ EXPORT_SYMBOL(memchr) +diff --git a/arch/alpha/lib/ev6-memcpy.S b/arch/alpha/lib/ev6-memcpy.S +index 52b37b0f2af51..b19798b2efc09 100644 +--- a/arch/alpha/lib/ev6-memcpy.S ++++ b/arch/alpha/lib/ev6-memcpy.S +@@ -19,7 +19,7 @@ + * Temp usage notes: + * $1,$2, - scratch + */ +- ++#include <asm/export.h> + .set noreorder + .set noat + +@@ -242,6 +242,7 @@ $nomoredata: + nop # E : + + .end memcpy ++ EXPORT_SYMBOL(memcpy) + + /* For backwards module compatibility. */ + __memcpy = memcpy +diff --git a/arch/alpha/lib/ev6-memset.S b/arch/alpha/lib/ev6-memset.S +index 356bb2fdd7056..fed21c6893e8e 100644 +--- a/arch/alpha/lib/ev6-memset.S ++++ b/arch/alpha/lib/ev6-memset.S +@@ -26,7 +26,7 @@ + * as fixes will need to be made in multiple places. The performance gain + * is worth it. + */ +- ++#include <asm/export.h> + .set noat + .set noreorder + .text +@@ -229,6 +229,7 @@ end_b: + nop + ret $31,($26),1 # L0 : + .end ___memset ++ EXPORT_SYMBOL(___memset) + + /* + * This is the original body of code, prior to replication and +@@ -406,6 +407,7 @@ end: + nop + ret $31,($26),1 # L0 : + .end __constant_c_memset ++ EXPORT_SYMBOL(__constant_c_memset) + + /* + * This is a replicant of the __constant_c_memset code, rescheduled +@@ -594,6 +596,9 @@ end_w: + ret $31,($26),1 # L0 : + + .end __memsetw ++ EXPORT_SYMBOL(__memsetw) + + memset = ___memset + __memset = ___memset ++ EXPORT_SYMBOL(memset) ++ EXPORT_SYMBOL(__memset) +diff --git a/arch/alpha/lib/ev67-strcat.S b/arch/alpha/lib/ev67-strcat.S +index c426fe3ed72f4..b69f60419be1b 100644 +--- a/arch/alpha/lib/ev67-strcat.S ++++ b/arch/alpha/lib/ev67-strcat.S +@@ -19,7 +19,7 @@ + * string once. + */ + +- ++#include <asm/export.h> + .text + + .align 4 +@@ -52,3 +52,4 @@ $found: cttz $2, $3 # U0 : + br __stxcpy # L0 : + + .end strcat ++ EXPORT_SYMBOL(strcat) +diff --git a/arch/alpha/lib/ev67-strchr.S b/arch/alpha/lib/ev67-strchr.S +index fbb7b4ffade9e..ea8f2f35db9ce 100644 +--- a/arch/alpha/lib/ev67-strchr.S ++++ b/arch/alpha/lib/ev67-strchr.S +@@ -15,7 +15,7 @@ + * L - lower subcluster; L0 - subcluster L0; L1 - subcluster L1 + * Try not to change the actual algorithm if possible for consistency. + */ +- ++#include <asm/export.h> + #include <asm/regdef.h> + + .set noreorder +@@ -86,3 +86,4 @@ $found: negq t0, t1 # E : clear all but least set bit + ret # L0 : + + .end strchr ++ EXPORT_SYMBOL(strchr) +diff --git a/arch/alpha/lib/ev67-strlen.S b/arch/alpha/lib/ev67-strlen.S +index 503928072523e..736fd41884a8c 100644 +--- a/arch/alpha/lib/ev67-strlen.S ++++ b/arch/alpha/lib/ev67-strlen.S +@@ -17,7 +17,7 @@ + * U - upper subcluster; U0 - subcluster U0; U1 - subcluster U1 + * L - lower subcluster; L0 - subcluster L0; L1 - subcluster L1 + */ +- ++#include <asm/export.h> + .set noreorder + .set noat + +@@ -47,3 +47,4 @@ $found: + ret $31, ($26) # L0 : + + .end strlen ++ EXPORT_SYMBOL(strlen) +diff --git a/arch/alpha/lib/ev67-strncat.S b/arch/alpha/lib/ev67-strncat.S +index 4ae716cd2bfbf..cd35cbade73ae 100644 +--- a/arch/alpha/lib/ev67-strncat.S ++++ b/arch/alpha/lib/ev67-strncat.S +@@ -20,7 +20,7 @@ + * Try not to change the actual algorithm if possible for consistency. + */ + +- ++#include <asm/export.h> + .text + + .align 4 +@@ -92,3 +92,4 @@ $zerocount: + ret # L0 : + + .end strncat ++ EXPORT_SYMBOL(strncat) +diff --git a/arch/alpha/lib/ev67-strrchr.S b/arch/alpha/lib/ev67-strrchr.S +index dd0d8c6b9f59f..747455f0328cf 100644 +--- a/arch/alpha/lib/ev67-strrchr.S ++++ b/arch/alpha/lib/ev67-strrchr.S +@@ -18,7 +18,7 @@ + * L - lower subcluster; L0 - subcluster L0; L1 - subcluster L1 + */ + +- ++#include <asm/export.h> + #include <asm/regdef.h> + + .set noreorder +@@ -107,3 +107,4 @@ $eos: + nop + + .end strrchr ++ EXPORT_SYMBOL(strrchr) +diff --git a/arch/alpha/lib/fpreg.c b/arch/alpha/lib/fpreg.c +index 05017ba34c3cc..4aa6dbfa14eec 100644 +--- a/arch/alpha/lib/fpreg.c ++++ b/arch/alpha/lib/fpreg.c +@@ -4,6 +4,9 @@ + * (C) Copyright 1998 Linus Torvalds + */ + ++#include <linux/compiler.h> ++#include <linux/export.h> ++ + #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67) + #define STT(reg,val) asm volatile ("ftoit $f"#reg",%0" : "=r"(val)); + #else +@@ -52,6 +55,7 @@ alpha_read_fp_reg (unsigned long reg) + } + return val; + } ++EXPORT_SYMBOL(alpha_read_fp_reg); + + #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67) + #define LDT(reg,val) asm volatile ("itoft %0,$f"#reg : : "r"(val)); +@@ -97,6 +101,7 @@ alpha_write_fp_reg (unsigned long reg, unsigned long val) + case 31: LDT(31, val); break; + } + } ++EXPORT_SYMBOL(alpha_write_fp_reg); + + #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67) + #define STS(reg,val) asm volatile ("ftois $f"#reg",%0" : "=r"(val)); +@@ -146,6 +151,7 @@ alpha_read_fp_reg_s (unsigned long reg) + } + return val; + } ++EXPORT_SYMBOL(alpha_read_fp_reg_s); + + #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67) + #define LDS(reg,val) asm volatile ("itofs %0,$f"#reg : : "r"(val)); +@@ -191,3 +197,4 @@ alpha_write_fp_reg_s (unsigned long reg, unsigned long val) + case 31: LDS(31, val); break; + } + } ++EXPORT_SYMBOL(alpha_write_fp_reg_s); +diff --git a/arch/alpha/lib/memchr.S b/arch/alpha/lib/memchr.S +index 14427eeb555e6..c13d3eca2e059 100644 +--- a/arch/alpha/lib/memchr.S ++++ b/arch/alpha/lib/memchr.S +@@ -31,7 +31,7 @@ For correctness consider that: + - only minimum number of quadwords may be accessed + - the third argument is an unsigned long + */ +- ++#include <asm/export.h> + .set noreorder + .set noat + +@@ -162,3 +162,4 @@ $not_found: + ret # .. e1 : + + .end memchr ++ EXPORT_SYMBOL(memchr) +diff --git a/arch/alpha/lib/memcpy.c b/arch/alpha/lib/memcpy.c +index 64083fc732389..57d9291ad172c 100644 +--- a/arch/alpha/lib/memcpy.c ++++ b/arch/alpha/lib/memcpy.c +@@ -16,6 +16,7 @@ + */ + + #include <linux/types.h> ++#include <linux/export.h> + + /* + * This should be done in one go with ldq_u*2/mask/stq_u. Do it +@@ -158,6 +159,4 @@ void * memcpy(void * dest, const void *src, size_t n) + __memcpy_unaligned_up ((unsigned long) dest, (unsigned long) src, n); + return dest; + } +- +-/* For backward modules compatibility, define __memcpy. */ +-asm("__memcpy = memcpy; .globl __memcpy"); ++EXPORT_SYMBOL(memcpy); +diff --git a/arch/alpha/lib/memmove.S b/arch/alpha/lib/memmove.S +index eb3b6e02242f4..ff6a39d38385c 100644 +--- a/arch/alpha/lib/memmove.S ++++ b/arch/alpha/lib/memmove.S +@@ -6,7 +6,7 @@ + * This is hand-massaged output from the original memcpy.c. We defer to + * memcpy whenever possible; the backwards copy loops are not unrolled. + */ +- ++#include <asm/export.h> + .set noat + .set noreorder + .text +@@ -179,3 +179,4 @@ $egress: + nop + + .end memmove ++ EXPORT_SYMBOL(memmove) +diff --git a/arch/alpha/lib/memset.S b/arch/alpha/lib/memset.S +index 76ccc6d1f364d..89a26f5e89de3 100644 +--- a/arch/alpha/lib/memset.S ++++ b/arch/alpha/lib/memset.S +@@ -13,7 +13,7 @@ + * The scheduling comments are according to the EV5 documentation (and done by + * hand, so they might well be incorrect, please do tell me about it..) + */ +- ++#include <asm/export.h> + .set noat + .set noreorder + .text +@@ -106,6 +106,8 @@ within_one_quad: + end: + ret $31,($26),1 /* E1 */ + .end ___memset ++EXPORT_SYMBOL(___memset) ++EXPORT_SYMBOL(__constant_c_memset) + + .align 5 + .ent __memsetw +@@ -122,6 +124,9 @@ __memsetw: + br __constant_c_memset /* .. E1 */ + + .end __memsetw ++EXPORT_SYMBOL(__memsetw) + + memset = ___memset + __memset = ___memset ++ EXPORT_SYMBOL(memset) ++ EXPORT_SYMBOL(__memset) +diff --git a/arch/alpha/lib/strcat.S b/arch/alpha/lib/strcat.S +index 393f50384878f..249837b03d4b9 100644 +--- a/arch/alpha/lib/strcat.S ++++ b/arch/alpha/lib/strcat.S +@@ -4,6 +4,7 @@ + * + * Append a null-terminated string from SRC to DST. + */ ++#include <asm/export.h> + + .text + +@@ -50,3 +51,4 @@ $found: negq $2, $3 # clear all but least set bit + br __stxcpy + + .end strcat ++EXPORT_SYMBOL(strcat); +diff --git a/arch/alpha/lib/strchr.S b/arch/alpha/lib/strchr.S +index 011a175e83292..7412a173ea393 100644 +--- a/arch/alpha/lib/strchr.S ++++ b/arch/alpha/lib/strchr.S +@@ -5,7 +5,7 @@ + * Return the address of a given character within a null-terminated + * string, or null if it is not found. + */ +- ++#include <asm/export.h> + #include <asm/regdef.h> + + .set noreorder +@@ -68,3 +68,4 @@ $retnull: + ret # .. e1 : + + .end strchr ++ EXPORT_SYMBOL(strchr) +diff --git a/arch/alpha/lib/strcpy.S b/arch/alpha/lib/strcpy.S +index e0728e4ad21fd..98deae1e4d085 100644 +--- a/arch/alpha/lib/strcpy.S ++++ b/arch/alpha/lib/strcpy.S +@@ -5,7 +5,7 @@ + * Copy a null-terminated string from SRC to DST. Return a pointer + * to the null-terminator in the source. + */ +- ++#include <asm/export.h> + .text + + .align 3 +@@ -21,3 +21,4 @@ strcpy: + br __stxcpy # do the copy + + .end strcpy ++ EXPORT_SYMBOL(strcpy) +diff --git a/arch/alpha/lib/strlen.S b/arch/alpha/lib/strlen.S +index fe63353de152d..79c416f71bacd 100644 +--- a/arch/alpha/lib/strlen.S ++++ b/arch/alpha/lib/strlen.S +@@ -11,7 +11,7 @@ + * do this instead of the 9 instructions that + * binary search needs). + */ +- ++#include <asm/export.h> + .set noreorder + .set noat + +@@ -55,3 +55,4 @@ done: subq $0, $16, $0 + ret $31, ($26) + + .end strlen ++ EXPORT_SYMBOL(strlen) +diff --git a/arch/alpha/lib/strncat.S b/arch/alpha/lib/strncat.S +index a8278163c9720..6c29ea60869ae 100644 +--- a/arch/alpha/lib/strncat.S ++++ b/arch/alpha/lib/strncat.S +@@ -9,7 +9,7 @@ + * past count, whereas libc may write to count+1. This follows the generic + * implementation in lib/string.c and is, IMHO, more sensible. + */ +- ++#include <asm/export.h> + .text + + .align 3 +@@ -82,3 +82,4 @@ $zerocount: + ret + + .end strncat ++ EXPORT_SYMBOL(strncat) +diff --git a/arch/alpha/lib/strncpy.S b/arch/alpha/lib/strncpy.S +index a46f7f3ad8c73..e102cf1567ddd 100644 +--- a/arch/alpha/lib/strncpy.S ++++ b/arch/alpha/lib/strncpy.S +@@ -10,7 +10,7 @@ + * version has cropped that bit o' nastiness as well as assuming that + * __stxncpy is in range of a branch. + */ +- ++#include <asm/export.h> + .set noat + .set noreorder + +@@ -79,3 +79,4 @@ $zerolen: + ret + + .end strncpy ++ EXPORT_SYMBOL(strncpy) +diff --git a/arch/alpha/lib/strrchr.S b/arch/alpha/lib/strrchr.S +index 1970dc07cfd12..4bc6cb4b9812e 100644 +--- a/arch/alpha/lib/strrchr.S ++++ b/arch/alpha/lib/strrchr.S +@@ -5,7 +5,7 @@ + * Return the address of the last occurrence of a given character + * within a null-terminated string, or null if it is not found. + */ +- ++#include <asm/export.h> + #include <asm/regdef.h> + + .set noreorder +@@ -85,3 +85,4 @@ $retnull: + ret # .. e1 : + + .end strrchr ++ EXPORT_SYMBOL(strrchr) +diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c +index edd392fdc14bb..b44fdee5cd6b2 100644 +--- a/arch/arm/kvm/mmu.c ++++ b/arch/arm/kvm/mmu.c +@@ -1789,7 +1789,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + * Prevent userspace from creating a memory region outside of the IPA + * space addressable by the KVM guest IPA space. + */ +- if (memslot->base_gfn + memslot->npages >= ++ if (memslot->base_gfn + memslot->npages > + (KVM_PHYS_SIZE >> PAGE_SHIFT)) + return -EFAULT; + +diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h +index a734b4b34d26b..9c7eb907b1653 100644 +--- a/arch/powerpc/include/asm/code-patching.h ++++ b/arch/powerpc/include/asm/code-patching.h +@@ -45,7 +45,7 @@ void __patch_exception(int exc, unsigned long addr); + #endif + + #define OP_RT_RA_MASK 0xffff0000UL +-#define LIS_R2 0x3c020000UL ++#define LIS_R2 0x3c400000UL + #define ADDIS_R2_R12 0x3c4c0000UL + #define ADDI_R2_R2 0x38420000UL + +diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c +index e593e7f856ed0..7a80e1cff6e2e 100644 +--- a/arch/powerpc/perf/core-book3s.c ++++ b/arch/powerpc/perf/core-book3s.c +@@ -2008,7 +2008,17 @@ static void record_and_restart(struct perf_event *event, unsigned long val, + left += period; + if (left <= 0) + left = period; +- record = siar_valid(regs); ++ ++ /* ++ * If address is not requested in the sample via ++ * PERF_SAMPLE_IP, just record that sample irrespective ++ * of SIAR valid check. ++ */ ++ if (event->attr.sample_type & PERF_SAMPLE_IP) ++ record = siar_valid(regs); ++ else ++ record = 1; ++ + event->hw.last_period = event->hw.sample_period; + } + if (left < 0x80000000LL) +@@ -2026,9 +2036,10 @@ static void record_and_restart(struct perf_event *event, unsigned long val, + * MMCR2. Check attr.exclude_kernel and address to drop the sample in + * these cases. + */ +- if (event->attr.exclude_kernel && record) +- if (is_kernel_addr(mfspr(SPRN_SIAR))) +- record = 0; ++ if (event->attr.exclude_kernel && ++ (event->attr.sample_type & PERF_SAMPLE_IP) && ++ is_kernel_addr(mfspr(SPRN_SIAR))) ++ record = 0; + + /* + * Finally record data if requested. +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index f113fcd781d87..486f0d4f9aee8 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -738,7 +738,7 @@ static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail, + static int __smp_rescan_cpus(struct sclp_core_info *info, bool early) + { + struct sclp_core_entry *core; +- cpumask_t avail; ++ static cpumask_t avail; + bool configured; + u16 core_id; + int nr, i; +diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c +index 31bbe5410b180..ae6b798b76bb2 100644 +--- a/drivers/block/floppy.c ++++ b/drivers/block/floppy.c +@@ -870,7 +870,7 @@ static void set_fdc(int drive) + } + + /* locks the driver */ +-static int lock_fdc(int drive, bool interruptible) ++static int lock_fdc(int drive) + { + if (WARN(atomic_read(&usage_count) == 0, + "Trying to lock fdc while usage count=0\n")) +@@ -2180,7 +2180,7 @@ static int do_format(int drive, struct format_descr *tmp_format_req) + { + int ret; + +- if (lock_fdc(drive, true)) ++ if (lock_fdc(drive)) + return -EINTR; + + set_floppy(drive); +@@ -2967,7 +2967,7 @@ static int user_reset_fdc(int drive, int arg, bool interruptible) + { + int ret; + +- if (lock_fdc(drive, interruptible)) ++ if (lock_fdc(drive)) + return -EINTR; + + if (arg == FD_RESET_ALWAYS) +@@ -3254,7 +3254,7 @@ static int set_geometry(unsigned int cmd, struct floppy_struct *g, + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + mutex_lock(&open_lock); +- if (lock_fdc(drive, true)) { ++ if (lock_fdc(drive)) { + mutex_unlock(&open_lock); + return -EINTR; + } +@@ -3274,7 +3274,7 @@ static int set_geometry(unsigned int cmd, struct floppy_struct *g, + } else { + int oldStretch; + +- if (lock_fdc(drive, true)) ++ if (lock_fdc(drive)) + return -EINTR; + if (cmd != FDDEFPRM) { + /* notice a disk change immediately, else +@@ -3360,7 +3360,7 @@ static int get_floppy_geometry(int drive, int type, struct floppy_struct **g) + if (type) + *g = &floppy_type[type]; + else { +- if (lock_fdc(drive, false)) ++ if (lock_fdc(drive)) + return -EINTR; + if (poll_drive(false, 0) == -EINTR) + return -EINTR; +@@ -3462,7 +3462,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int + if (UDRS->fd_ref != 1) + /* somebody else has this drive open */ + return -EBUSY; +- if (lock_fdc(drive, true)) ++ if (lock_fdc(drive)) + return -EINTR; + + /* do the actual eject. Fails on +@@ -3474,7 +3474,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int + process_fd_request(); + return ret; + case FDCLRPRM: +- if (lock_fdc(drive, true)) ++ if (lock_fdc(drive)) + return -EINTR; + current_type[drive] = NULL; + floppy_sizes[drive] = MAX_DISK_SIZE << 1; +@@ -3499,7 +3499,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int + UDP->flags &= ~FTD_MSG; + return 0; + case FDFMTBEG: +- if (lock_fdc(drive, true)) ++ if (lock_fdc(drive)) + return -EINTR; + if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) + return -EINTR; +@@ -3516,7 +3516,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int + return do_format(drive, &inparam.f); + case FDFMTEND: + case FDFLUSH: +- if (lock_fdc(drive, true)) ++ if (lock_fdc(drive)) + return -EINTR; + return invalidate_drive(bdev); + case FDSETEMSGTRESH: +@@ -3542,7 +3542,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int + outparam = UDP; + break; + case FDPOLLDRVSTAT: +- if (lock_fdc(drive, true)) ++ if (lock_fdc(drive)) + return -EINTR; + if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) + return -EINTR; +@@ -3565,7 +3565,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int + case FDRAWCMD: + if (type) + return -EINVAL; +- if (lock_fdc(drive, true)) ++ if (lock_fdc(drive)) + return -EINTR; + set_floppy(drive); + i = raw_cmd_ioctl(cmd, (void __user *)param); +@@ -3574,7 +3574,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int + process_fd_request(); + return i; + case FDTWADDLE: +- if (lock_fdc(drive, true)) ++ if (lock_fdc(drive)) + return -EINTR; + twaddle(); + process_fd_request(); +@@ -3801,7 +3801,7 @@ static int compat_getdrvstat(int drive, bool poll, + mutex_lock(&floppy_mutex); + + if (poll) { +- if (lock_fdc(drive, true)) ++ if (lock_fdc(drive)) + goto Eintr; + if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) + goto Eintr; +@@ -4109,7 +4109,8 @@ static unsigned int floppy_check_events(struct gendisk *disk, + return DISK_EVENT_MEDIA_CHANGE; + + if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) { +- lock_fdc(drive, false); ++ if (lock_fdc(drive)) ++ return -EINTR; + poll_drive(false, 0); + process_fd_request(); + } +@@ -4208,7 +4209,9 @@ static int floppy_revalidate(struct gendisk *disk) + "VFS: revalidate called on non-open device.\n")) + return -EFAULT; + +- lock_fdc(drive, false); ++ res = lock_fdc(drive); ++ if (res) ++ return res; + cf = (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || + test_bit(FD_VERIFY_BIT, &UDRS->flags)); + if (!(cf || test_bit(drive, &fake_change) || drive_no_geom(drive))) { +diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c +index 0d9137408e3c8..a53271acc2a25 100644 +--- a/drivers/block/rsxx/core.c ++++ b/drivers/block/rsxx/core.c +@@ -895,6 +895,7 @@ static int rsxx_pci_probe(struct pci_dev *dev, + card->event_wq = create_singlethread_workqueue(DRIVER_NAME"_event"); + if (!card->event_wq) { + dev_err(CARD_TO_DEV(card), "Failed card event setup.\n"); ++ st = -ENOMEM; + goto failed_event_handler; + } + +diff --git a/drivers/iio/imu/adis16400_buffer.c b/drivers/iio/imu/adis16400_buffer.c +index 90c24a23c679b..c0eb9dfd1c454 100644 +--- a/drivers/iio/imu/adis16400_buffer.c ++++ b/drivers/iio/imu/adis16400_buffer.c +@@ -37,8 +37,11 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev, + return -ENOMEM; + + adis->buffer = kzalloc(burst_length + sizeof(u16), GFP_KERNEL); +- if (!adis->buffer) ++ if (!adis->buffer) { ++ kfree(adis->xfer); ++ adis->xfer = NULL; + return -ENOMEM; ++ } + + tx = adis->buffer + burst_length; + tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD); +diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c +index 36607d52fee06..9de553e8c214f 100644 +--- a/drivers/iio/imu/adis_buffer.c ++++ b/drivers/iio/imu/adis_buffer.c +@@ -39,8 +39,11 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, + return -ENOMEM; + + adis->buffer = kzalloc(indio_dev->scan_bytes * 2, GFP_KERNEL); +- if (!adis->buffer) ++ if (!adis->buffer) { ++ kfree(adis->xfer); ++ adis->xfer = NULL; + return -ENOMEM; ++ } + + rx = adis->buffer; + tx = rx + scan_count; +diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c +index 7b5c493f02b0a..9f95b048123dc 100644 +--- a/drivers/media/usb/hdpvr/hdpvr-core.c ++++ b/drivers/media/usb/hdpvr/hdpvr-core.c +@@ -297,7 +297,7 @@ static int hdpvr_probe(struct usb_interface *interface, + /* register v4l2_device early so it can be used for printks */ + if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) { + dev_err(&interface->dev, "v4l2_device_register failed\n"); +- goto error; ++ goto error_free_dev; + } + + mutex_init(&dev->io_mutex); +@@ -306,7 +306,7 @@ static int hdpvr_probe(struct usb_interface *interface, + dev->usbc_buf = kmalloc(64, GFP_KERNEL); + if (!dev->usbc_buf) { + v4l2_err(&dev->v4l2_dev, "Out of memory\n"); +- goto error; ++ goto error_v4l2_unregister; + } + + init_waitqueue_head(&dev->wait_buffer); +@@ -314,7 +314,7 @@ static int hdpvr_probe(struct usb_interface *interface, + + dev->workqueue = create_singlethread_workqueue("hdpvr_buffer"); + if (!dev->workqueue) +- goto error; ++ goto err_free_usbc; + + dev->options = hdpvr_default_options; + +@@ -348,13 +348,13 @@ static int hdpvr_probe(struct usb_interface *interface, + } + if (!dev->bulk_in_endpointAddr) { + v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n"); +- goto error; ++ goto error_put_usb; + } + + /* init the device */ + if (hdpvr_device_init(dev)) { + v4l2_err(&dev->v4l2_dev, "device init failed\n"); +- goto error; ++ goto error_put_usb; + } + + mutex_lock(&dev->io_mutex); +@@ -362,7 +362,7 @@ static int hdpvr_probe(struct usb_interface *interface, + mutex_unlock(&dev->io_mutex); + v4l2_err(&dev->v4l2_dev, + "allocating transfer buffers failed\n"); +- goto error; ++ goto error_put_usb; + } + mutex_unlock(&dev->io_mutex); + +@@ -370,7 +370,7 @@ static int hdpvr_probe(struct usb_interface *interface, + retval = hdpvr_register_i2c_adapter(dev); + if (retval < 0) { + v4l2_err(&dev->v4l2_dev, "i2c adapter register failed\n"); +- goto error; ++ goto error_free_buffers; + } + + client = hdpvr_register_ir_rx_i2c(dev); +@@ -412,15 +412,20 @@ static int hdpvr_probe(struct usb_interface *interface, + reg_fail: + #if IS_ENABLED(CONFIG_I2C) + i2c_del_adapter(&dev->i2c_adapter); ++error_free_buffers: + #endif ++ hdpvr_free_buffers(dev); ++error_put_usb: ++ usb_put_dev(dev->udev); ++ /* Destroy single thread */ ++ destroy_workqueue(dev->workqueue); ++err_free_usbc: ++ kfree(dev->usbc_buf); ++error_v4l2_unregister: ++ v4l2_device_unregister(&dev->v4l2_dev); ++error_free_dev: ++ kfree(dev); + error: +- if (dev) { +- /* Destroy single thread */ +- if (dev->workqueue) +- destroy_workqueue(dev->workqueue); +- /* this frees allocated memory */ +- hdpvr_delete(dev); +- } + return retval; + } + +diff --git a/drivers/media/usb/usbtv/usbtv-audio.c b/drivers/media/usb/usbtv/usbtv-audio.c +index 5dab02432e821..17128340ea5da 100644 +--- a/drivers/media/usb/usbtv/usbtv-audio.c ++++ b/drivers/media/usb/usbtv/usbtv-audio.c +@@ -384,7 +384,7 @@ void usbtv_audio_free(struct usbtv *usbtv) + cancel_work_sync(&usbtv->snd_trigger); + + if (usbtv->snd && usbtv->udev) { +- snd_card_free(usbtv->snd); ++ snd_card_free_when_closed(usbtv->snd); + usbtv->snd = NULL; + } + } +diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c +index 7844baecf3060..1506152983139 100644 +--- a/drivers/mmc/core/mmc.c ++++ b/drivers/mmc/core/mmc.c +@@ -400,10 +400,6 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) + + /* EXT_CSD value is in units of 10ms, but we store in ms */ + card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME]; +- /* Some eMMC set the value too low so set a minimum */ +- if (card->ext_csd.part_time && +- card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME) +- card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME; + + /* Sleep / awake timeout in 100ns units */ + if (sa_shift > 0 && sa_shift <= 0x17) +@@ -585,6 +581,17 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) + card->ext_csd.data_sector_size = 512; + } + ++ /* ++ * GENERIC_CMD6_TIME is to be used "unless a specific timeout is defined ++ * when accessing a specific field", so use it here if there is no ++ * PARTITION_SWITCH_TIME. ++ */ ++ if (!card->ext_csd.part_time) ++ card->ext_csd.part_time = card->ext_csd.generic_cmd6_time; ++ /* Some eMMC set the value too low so set a minimum */ ++ if (card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME) ++ card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME; ++ + /* eMMC v5 or later */ + if (card->ext_csd.rev >= 7) { + memcpy(card->ext_csd.fwrev, &ext_csd[EXT_CSD_FIRMWARE_VERSION], +diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c +index 5ef25463494f4..1770c8df9d1b8 100644 +--- a/drivers/mmc/host/mtk-sd.c ++++ b/drivers/mmc/host/mtk-sd.c +@@ -720,13 +720,13 @@ static void msdc_track_cmd_data(struct msdc_host *host, + static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq) + { + unsigned long flags; +- bool ret; + +- ret = cancel_delayed_work(&host->req_timeout); +- if (!ret) { +- /* delay work already running */ +- return; +- } ++ /* ++ * No need check the return value of cancel_delayed_work, as only ONE ++ * path will go here! ++ */ ++ cancel_delayed_work(&host->req_timeout); ++ + spin_lock_irqsave(&host->lock, flags); + host->mrq = NULL; + spin_unlock_irqrestore(&host->lock, flags); +@@ -747,7 +747,7 @@ static bool msdc_cmd_done(struct msdc_host *host, int events, + bool done = false; + bool sbc_error; + unsigned long flags; +- u32 *rsp = cmd->resp; ++ u32 *rsp; + + if (mrq->sbc && cmd == mrq->cmd && + (events & (MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR +@@ -768,6 +768,7 @@ static bool msdc_cmd_done(struct msdc_host *host, int events, + + if (done) + return true; ++ rsp = cmd->resp; + + sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask); + +@@ -942,7 +943,7 @@ static void msdc_data_xfer_next(struct msdc_host *host, + static bool msdc_data_xfer_done(struct msdc_host *host, u32 events, + struct mmc_request *mrq, struct mmc_data *data) + { +- struct mmc_command *stop = data->stop; ++ struct mmc_command *stop; + unsigned long flags; + bool done; + unsigned int check_data = events & +@@ -958,6 +959,7 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events, + + if (done) + return true; ++ stop = data->stop; + + if (check_data || (stop && stop->error)) { + dev_dbg(host->dev, "DMA status: 0x%8X\n", +diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c +index c8b8ac66ff7e3..687fd68fbbcd1 100644 +--- a/drivers/mmc/host/mxs-mmc.c ++++ b/drivers/mmc/host/mxs-mmc.c +@@ -651,7 +651,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) + + ret = mmc_of_parse(mmc); + if (ret) +- goto out_clk_disable; ++ goto out_free_dma; + + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + +diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c +index 6b866d0451b21..b18bb0334ded6 100644 +--- a/drivers/net/can/flexcan.c ++++ b/drivers/net/can/flexcan.c +@@ -383,7 +383,7 @@ static int flexcan_chip_freeze(struct flexcan_priv *priv) + u32 reg; + + reg = flexcan_read(®s->mcr); +- reg |= FLEXCAN_MCR_HALT; ++ reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT; + flexcan_write(reg, ®s->mcr); + + while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) +@@ -1098,10 +1098,14 @@ static int register_flexcandev(struct net_device *dev) + if (err) + goto out_chip_disable; + +- /* set freeze, halt and activate FIFO, restrict register access */ ++ /* set freeze, halt */ ++ err = flexcan_chip_freeze(priv); ++ if (err) ++ goto out_chip_disable; ++ ++ /* activate FIFO, restrict register access */ + reg = flexcan_read(®s->mcr); +- reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | +- FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; ++ reg |= FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; + flexcan_write(reg, ®s->mcr); + + /* Currently we only support newer versions of this core +diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c +index cf94b72dbacd9..ab06cf36af083 100644 +--- a/drivers/net/ethernet/davicom/dm9000.c ++++ b/drivers/net/ethernet/davicom/dm9000.c +@@ -144,6 +144,8 @@ struct board_info { + u32 wake_state; + + int ip_summed; ++ ++ struct regulator *power_supply; + }; + + /* debug code */ +@@ -1462,7 +1464,7 @@ dm9000_probe(struct platform_device *pdev) + if (ret) { + dev_err(dev, "failed to request reset gpio %d: %d\n", + reset_gpios, ret); +- return -ENODEV; ++ goto out_regulator_disable; + } + + /* According to manual PWRST# Low Period Min 1ms */ +@@ -1474,8 +1476,10 @@ dm9000_probe(struct platform_device *pdev) + + if (!pdata) { + pdata = dm9000_parse_dt(&pdev->dev); +- if (IS_ERR(pdata)) +- return PTR_ERR(pdata); ++ if (IS_ERR(pdata)) { ++ ret = PTR_ERR(pdata); ++ goto out_regulator_disable; ++ } + } + + /* Init network device */ +@@ -1492,6 +1496,8 @@ dm9000_probe(struct platform_device *pdev) + + db->dev = &pdev->dev; + db->ndev = ndev; ++ if (!IS_ERR(power)) ++ db->power_supply = power; + + spin_lock_init(&db->lock); + mutex_init(&db->addr_lock); +@@ -1710,6 +1716,10 @@ out: + dm9000_release_board(pdev, db); + free_netdev(ndev); + ++out_regulator_disable: ++ if (!IS_ERR(power)) ++ regulator_disable(power); ++ + return ret; + } + +@@ -1769,10 +1779,13 @@ static int + dm9000_drv_remove(struct platform_device *pdev) + { + struct net_device *ndev = platform_get_drvdata(pdev); ++ struct board_info *dm = to_dm9000_board(ndev); + + unregister_netdev(ndev); +- dm9000_release_board(pdev, netdev_priv(ndev)); ++ dm9000_release_board(pdev, dm); + free_netdev(ndev); /* free device structure */ ++ if (dm->power_supply) ++ regulator_disable(dm->power_supply); + + dev_dbg(&pdev->dev, "released and freed device\n"); + return 0; +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +index b52491f09a4d0..14a3e9e601e8d 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +@@ -47,7 +47,7 @@ + #define EN_ETHTOOL_SHORT_MASK cpu_to_be16(0xffff) + #define EN_ETHTOOL_WORD_MASK cpu_to_be32(0xffffffff) + +-static int mlx4_en_moderation_update(struct mlx4_en_priv *priv) ++int mlx4_en_moderation_update(struct mlx4_en_priv *priv) + { + int i; + int err = 0; +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +index b7bde70a3e952..112ce16717cda 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +@@ -3188,6 +3188,8 @@ int mlx4_en_reset_config(struct net_device *dev, + en_err(priv, "Failed starting port\n"); + } + ++ if (!err) ++ err = mlx4_en_moderation_update(priv); + out: + mutex_unlock(&mdev->state_lock); + netdev_features_change(dev); +diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +index 440f1ab6d92e2..b6cd733791a81 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h ++++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +@@ -839,6 +839,7 @@ void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev); + #define DEV_FEATURE_CHANGED(dev, new_features, feature) \ + ((dev->features & feature) ^ (new_features & feature)) + ++int mlx4_en_moderation_update(struct mlx4_en_priv *priv); + int mlx4_en_reset_config(struct net_device *dev, + struct hwtstamp_config ts_config, + netdev_features_t new_features); +diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c +index ef746ba74ab4c..666bbacb8cb49 100644 +--- a/drivers/net/wan/lapbether.c ++++ b/drivers/net/wan/lapbether.c +@@ -286,7 +286,6 @@ static int lapbeth_open(struct net_device *dev) + return -ENODEV; + } + +- netif_start_queue(dev); + return 0; + } + +@@ -294,8 +293,6 @@ static int lapbeth_close(struct net_device *dev) + { + int err; + +- netif_stop_queue(dev); +- + if ((err = lapb_unregister(dev)) != LAPB_OK) + pr_err("lapb_unregister error: %d\n", err); + +diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h +index a660e40f2df1e..70b5dbe9de6aa 100644 +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -178,7 +178,8 @@ struct ath_frame_info { + s8 txq; + u8 keyix; + u8 rtscts_rate; +- u8 retries : 7; ++ u8 retries : 6; ++ u8 dyn_smps : 1; + u8 baw_tracked : 1; + u8 tx_power; + enum ath9k_key_type keytype:2; +diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c +index 3e3dac3d70604..94fac5dc1b4af 100644 +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -1228,6 +1228,11 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, + is_40, is_sgi, is_sp); + if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) + info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC; ++ if (rix >= 8 && fi->dyn_smps) { ++ info->rates[i].RateFlags |= ++ ATH9K_RATESERIES_RTS_CTS; ++ info->flags |= ATH9K_TXDESC_CTSENA; ++ } + + info->txpower[i] = ath_get_rate_txpower(sc, bf, rix, + is_40, false); +@@ -2114,6 +2119,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, + fi->keyix = an->ps_key; + else + fi->keyix = ATH9K_TXKEYIX_INVALID; ++ fi->dyn_smps = sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC; + fi->keytype = keytype; + fi->framelen = framelen; + fi->tx_power = txpower; +diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c +index 33ceda296c9c6..45d68ee682f6d 100644 +--- a/drivers/net/wireless/libertas/if_sdio.c ++++ b/drivers/net/wireless/libertas/if_sdio.c +@@ -1229,6 +1229,10 @@ static int if_sdio_probe(struct sdio_func *func, + + spin_lock_init(&card->lock); + card->workqueue = create_workqueue("libertas_sdio"); ++ if (unlikely(!card->workqueue)) { ++ ret = -ENOMEM; ++ goto err_queue; ++ } + INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker); + init_waitqueue_head(&card->pwron_waitq); + +@@ -1282,6 +1286,7 @@ err_activate_card: + lbs_remove_card(priv); + free: + destroy_workqueue(card->workqueue); ++err_queue: + while (card->packets) { + packet = card->packets; + card->packets = card->packets->next; +diff --git a/drivers/pci/host/pci-xgene-msi.c b/drivers/pci/host/pci-xgene-msi.c +index a6456b5782692..b6a099371ad24 100644 +--- a/drivers/pci/host/pci-xgene-msi.c ++++ b/drivers/pci/host/pci-xgene-msi.c +@@ -393,13 +393,9 @@ static int xgene_msi_hwirq_alloc(unsigned int cpu) + if (!msi_group->gic_irq) + continue; + +- irq_set_chained_handler(msi_group->gic_irq, +- xgene_msi_isr); +- err = irq_set_handler_data(msi_group->gic_irq, msi_group); +- if (err) { +- pr_err("failed to register GIC IRQ handler\n"); +- return -EINVAL; +- } ++ irq_set_chained_handler_and_data(msi_group->gic_irq, ++ xgene_msi_isr, msi_group); ++ + /* + * Statically allocate MSI GIC IRQs to each CPU core. + * With 8-core X-Gene v1, 2 MSI GIC IRQs are allocated +diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c +index b76a85d14ef0c..aec25ea99d194 100644 +--- a/drivers/s390/block/dasd.c ++++ b/drivers/s390/block/dasd.c +@@ -3286,8 +3286,6 @@ void dasd_generic_remove(struct ccw_device *cdev) + struct dasd_device *device; + struct dasd_block *block; + +- cdev->handler = NULL; +- + device = dasd_device_from_cdev(cdev); + if (IS_ERR(device)) { + dasd_remove_sysfs_files(cdev); +@@ -3306,6 +3304,7 @@ void dasd_generic_remove(struct ccw_device *cdev) + * no quite down yet. + */ + dasd_set_target_state(device, DASD_STATE_NEW); ++ cdev->handler = NULL; + /* dasd_delete_device destroys the device reference. */ + block = device->block; + dasd_delete_device(device); +diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c +index ecf3950c44383..18b8d86ef74b2 100644 +--- a/drivers/scsi/libiscsi.c ++++ b/drivers/scsi/libiscsi.c +@@ -1568,14 +1568,9 @@ check_mgmt: + } + rc = iscsi_prep_scsi_cmd_pdu(conn->task); + if (rc) { +- if (rc == -ENOMEM || rc == -EACCES) { +- spin_lock_bh(&conn->taskqueuelock); +- list_add_tail(&conn->task->running, +- &conn->cmdqueue); +- conn->task = NULL; +- spin_unlock_bh(&conn->taskqueuelock); +- goto done; +- } else ++ if (rc == -ENOMEM || rc == -EACCES) ++ fail_scsi_task(conn->task, DID_IMM_RETRY); ++ else + fail_scsi_task(conn->task, DID_ABORT); + spin_lock_bh(&conn->taskqueuelock); + continue; +diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c +index 536a135cd00b3..9058ef473c336 100644 +--- a/drivers/staging/comedi/drivers/addi_apci_1032.c ++++ b/drivers/staging/comedi/drivers/addi_apci_1032.c +@@ -269,6 +269,7 @@ static irqreturn_t apci1032_interrupt(int irq, void *d) + struct apci1032_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; + unsigned int ctrl; ++ unsigned short val; + + /* check interrupt is from this device */ + if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) & +@@ -284,7 +285,8 @@ static irqreturn_t apci1032_interrupt(int irq, void *d) + outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG); + + s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff; +- comedi_buf_write_samples(s, &s->state, 1); ++ val = s->state; ++ comedi_buf_write_samples(s, &val, 1); + comedi_handle_events(dev, s); + + /* enable the interrupt */ +diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c +index c4e36fb6df9d5..1f25f565041cb 100644 +--- a/drivers/staging/comedi/drivers/addi_apci_1500.c ++++ b/drivers/staging/comedi/drivers/addi_apci_1500.c +@@ -217,7 +217,7 @@ static irqreturn_t apci1500_interrupt(int irq, void *d) + struct comedi_device *dev = d; + struct apci1500_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; +- unsigned int status = 0; ++ unsigned short status = 0; + unsigned int val; + + val = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); +@@ -247,14 +247,14 @@ static irqreturn_t apci1500_interrupt(int irq, void *d) + * + * Mask Meaning + * ---------- ------------------------------------------ +- * 0x00000001 Event 1 has occurred +- * 0x00000010 Event 2 has occurred +- * 0x00000100 Counter/timer 1 has run down (not implemented) +- * 0x00001000 Counter/timer 2 has run down (not implemented) +- * 0x00010000 Counter 3 has run down (not implemented) +- * 0x00100000 Watchdog has run down (not implemented) +- * 0x01000000 Voltage error +- * 0x10000000 Short-circuit error ++ * 0b00000001 Event 1 has occurred ++ * 0b00000010 Event 2 has occurred ++ * 0b00000100 Counter/timer 1 has run down (not implemented) ++ * 0b00001000 Counter/timer 2 has run down (not implemented) ++ * 0b00010000 Counter 3 has run down (not implemented) ++ * 0b00100000 Watchdog has run down (not implemented) ++ * 0b01000000 Voltage error ++ * 0b10000000 Short-circuit error + */ + comedi_buf_write_samples(s, &status, 1); + comedi_handle_events(dev, s); +diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c +index 399c511cfe0ab..8599258f8c8d2 100644 +--- a/drivers/staging/comedi/drivers/adv_pci1710.c ++++ b/drivers/staging/comedi/drivers/adv_pci1710.c +@@ -351,11 +351,11 @@ static int pci171x_ai_eoc(struct comedi_device *dev, + static int pci171x_ai_read_sample(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int cur_chan, +- unsigned int *val) ++ unsigned short *val) + { + const struct boardtype *board = dev->board_ptr; + struct pci1710_private *devpriv = dev->private; +- unsigned int sample; ++ unsigned short sample; + unsigned int chan; + + sample = inw(dev->iobase + PCI171X_AD_DATA_REG); +@@ -395,7 +395,7 @@ static int pci171x_ai_insn_read(struct comedi_device *dev, + pci171x_ai_setup_chanlist(dev, s, &insn->chanspec, 1, 1); + + for (i = 0; i < insn->n; i++) { +- unsigned int val; ++ unsigned short val; + + /* start conversion */ + outw(0, dev->iobase + PCI171X_SOFTTRG_REG); +@@ -516,7 +516,7 @@ static void pci1710_handle_every_sample(struct comedi_device *dev, + { + struct comedi_cmd *cmd = &s->async->cmd; + unsigned int status; +- unsigned int val; ++ unsigned short val; + int ret; + + status = inw(dev->iobase + PCI171X_STATUS_REG); +@@ -576,7 +576,7 @@ static void pci1710_handle_fifo(struct comedi_device *dev, + } + + for (i = 0; i < devpriv->max_samples; i++) { +- unsigned int val; ++ unsigned short val; + int ret; + + ret = pci171x_ai_read_sample(dev, s, s->async->cur_chan, &val); +diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c +index 1701294b79cdd..666d199983ba9 100644 +--- a/drivers/staging/comedi/drivers/das6402.c ++++ b/drivers/staging/comedi/drivers/das6402.c +@@ -193,7 +193,7 @@ static irqreturn_t das6402_interrupt(int irq, void *d) + if (status & DAS6402_STATUS_FFULL) { + async->events |= COMEDI_CB_OVERFLOW; + } else if (status & DAS6402_STATUS_FFNE) { +- unsigned int val; ++ unsigned short val; + + val = das6402_ai_read_sample(dev, s); + comedi_buf_write_samples(s, &val, 1); +diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c +index b02f12201cf78..91a0c4ec7fdb5 100644 +--- a/drivers/staging/comedi/drivers/das800.c ++++ b/drivers/staging/comedi/drivers/das800.c +@@ -436,7 +436,7 @@ static irqreturn_t das800_interrupt(int irq, void *d) + struct comedi_cmd *cmd; + unsigned long irq_flags; + unsigned int status; +- unsigned int val; ++ unsigned short val; + bool fifo_empty; + bool fifo_overflow; + int i; +diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c +index 958c0d4aae5c0..48645ecde8109 100644 +--- a/drivers/staging/comedi/drivers/dmm32at.c ++++ b/drivers/staging/comedi/drivers/dmm32at.c +@@ -411,7 +411,7 @@ static irqreturn_t dmm32at_isr(int irq, void *d) + { + struct comedi_device *dev = d; + unsigned char intstat; +- unsigned int val; ++ unsigned short val; + int i; + + if (!dev->attached) { +diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c +index 15a53204a36a5..4fe856128870b 100644 +--- a/drivers/staging/comedi/drivers/me4000.c ++++ b/drivers/staging/comedi/drivers/me4000.c +@@ -933,7 +933,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) + struct comedi_subdevice *s = dev->read_subdev; + int i; + int c = 0; +- unsigned int lval; ++ unsigned short lval; + + if (!dev->attached) + return IRQ_NONE; +diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c +index 3774daa9d6615..e1334733abe77 100644 +--- a/drivers/staging/comedi/drivers/pcl711.c ++++ b/drivers/staging/comedi/drivers/pcl711.c +@@ -193,7 +193,7 @@ static irqreturn_t pcl711_interrupt(int irq, void *d) + struct comedi_device *dev = d; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_cmd *cmd = &s->async->cmd; +- unsigned int data; ++ unsigned short data; + + if (!dev->attached) { + dev_err(dev->class_dev, "spurious interrupt\n"); +diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c +index 5aeed44dff706..f062417123087 100644 +--- a/drivers/staging/comedi/drivers/pcl818.c ++++ b/drivers/staging/comedi/drivers/pcl818.c +@@ -422,7 +422,7 @@ static int pcl818_ai_eoc(struct comedi_device *dev, + + static bool pcl818_ai_write_sample(struct comedi_device *dev, + struct comedi_subdevice *s, +- unsigned int chan, unsigned int val) ++ unsigned int chan, unsigned short val) + { + struct pcl818_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; +diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c +index f5cedbbc552af..d14a2313fccea 100644 +--- a/drivers/staging/rtl8188eu/core/rtw_ap.c ++++ b/drivers/staging/rtl8188eu/core/rtw_ap.c +@@ -921,6 +921,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) + /* SSID */ + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if (p && ie_len > 0) { ++ ie_len = min_t(int, ie_len, sizeof(pbss_network->Ssid.Ssid)); + memset(&pbss_network->Ssid, 0, sizeof(struct ndis_802_11_ssid)); + memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len); + pbss_network->Ssid.SsidLength = ie_len; +@@ -939,6 +940,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) + /* get supported rates */ + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_)); + if (p != NULL) { ++ ie_len = min_t(int, ie_len, NDIS_802_11_LENGTH_RATES_EX); + memcpy(supportRate, p+2, ie_len); + supportRateNum = ie_len; + } +@@ -946,6 +948,8 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) + /* get ext_supported rates */ + p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_); + if (p != NULL) { ++ ie_len = min_t(int, ie_len, ++ NDIS_802_11_LENGTH_RATES_EX - supportRateNum); + memcpy(supportRate+supportRateNum, p+2, ie_len); + supportRateNum += ie_len; + } +@@ -1061,6 +1065,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) + pht_cap->supp_mcs_set[0] = 0xff; + pht_cap->supp_mcs_set[1] = 0x0; + } ++ ie_len = min_t(int, ie_len, sizeof(pmlmepriv->htpriv.ht_cap)); + memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len); + } + +diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +index 2a6192e08b750..c29dc91824703 100644 +--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c ++++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +@@ -1174,9 +1174,11 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a, + break; + } + sec_len = *(pos++); len -= 1; +- if (sec_len > 0 && sec_len <= len) { ++ if (sec_len > 0 && ++ sec_len <= len && ++ sec_len <= 32) { + ssid[ssid_index].SsidLength = sec_len; +- memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength); ++ memcpy(ssid[ssid_index].Ssid, pos, sec_len); + ssid_index++; + } + pos += sec_len; +diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +index 70df6a1485d6f..6f0be1db6fb18 100644 +--- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c ++++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +@@ -419,9 +419,10 @@ static int _rtl92e_wx_set_scan(struct net_device *dev, + struct iw_scan_req *req = (struct iw_scan_req *)b; + + if (req->essid_len) { +- ieee->current_network.ssid_len = req->essid_len; +- memcpy(ieee->current_network.ssid, req->essid, +- req->essid_len); ++ int len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE); ++ ++ ieee->current_network.ssid_len = len; ++ memcpy(ieee->current_network.ssid, req->essid, len); + } + } + +diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c +index 4911fef2e2e5f..8fb1940751498 100644 +--- a/drivers/staging/rtl8192u/r8192U_wx.c ++++ b/drivers/staging/rtl8192u/r8192U_wx.c +@@ -341,8 +341,10 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, + struct iw_scan_req *req = (struct iw_scan_req *)b; + + if (req->essid_len) { +- ieee->current_network.ssid_len = req->essid_len; +- memcpy(ieee->current_network.ssid, req->essid, req->essid_len); ++ int len = min_t(int, req->essid_len, IW_ESSID_MAX_SIZE); ++ ++ ieee->current_network.ssid_len = len; ++ memcpy(ieee->current_network.ssid, req->essid, len); + } + } + +diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c +index 562a102031277..b4eb6af4e5656 100644 +--- a/drivers/staging/rtl8712/rtl871x_cmd.c ++++ b/drivers/staging/rtl8712/rtl871x_cmd.c +@@ -242,8 +242,10 @@ u8 r8712_sitesurvey_cmd(struct _adapter *padapter, + psurveyPara->ss_ssidlen = 0; + memset(psurveyPara->ss_ssid, 0, IW_ESSID_MAX_SIZE + 1); + if ((pssid != NULL) && (pssid->SsidLength)) { +- memcpy(psurveyPara->ss_ssid, pssid->Ssid, pssid->SsidLength); +- psurveyPara->ss_ssidlen = cpu_to_le32(pssid->SsidLength); ++ int len = min_t(int, pssid->SsidLength, IW_ESSID_MAX_SIZE); ++ ++ memcpy(psurveyPara->ss_ssid, pssid->Ssid, len); ++ psurveyPara->ss_ssidlen = cpu_to_le32(len); + } + set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); + r8712_enqueue_cmd(pcmdpriv, ph2c); +diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +index 2b348439242f1..20052fa2eedf1 100644 +--- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c ++++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +@@ -935,7 +935,7 @@ static int r871x_wx_set_priv(struct net_device *dev, + struct iw_point *dwrq = (struct iw_point *)awrq; + + len = dwrq->length; +- ext = memdup_user(dwrq->pointer, len); ++ ext = strndup_user(dwrq->pointer, len); + if (IS_ERR(ext)) + return PTR_ERR(ext); + +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index e5ee349a5382b..53d2f02e18a32 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1928,6 +1928,11 @@ static const struct usb_device_id acm_ids[] = { + .driver_info = SEND_ZERO_PACKET, + }, + ++ /* Exclude Goodix Fingerprint Reader */ ++ { USB_DEVICE(0x27c6, 0x5395), ++ .driver_info = IGNORE_DEVICE, ++ }, ++ + /* control interfaces without any protocol set */ + { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, + USB_CDC_PROTO_NONE) }, +diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c +index 81af315774c62..6903d02a933f5 100644 +--- a/drivers/usb/gadget/function/f_uac2.c ++++ b/drivers/usb/gadget/function/f_uac2.c +@@ -997,7 +997,7 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, + } + + max_size_bw = num_channels(chmask) * ssize * +- DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); ++ ((srate / (factor / (1 << (ep_desc->bInterval - 1)))) + 1); + ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, + max_size_ep)); + +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index e7dee8e3ca8b1..bd6e3555c0479 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1018,6 +1018,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + struct usb_hcd *secondary_hcd; + int retval = 0; + bool comp_timer_running = false; ++ bool pending_portevent = false; + + if (!hcd->state) + return 0; +@@ -1151,13 +1152,22 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + + done: + if (retval == 0) { +- /* Resume root hubs only when have pending events. */ +- if (xhci_pending_portevent(xhci)) { ++ /* ++ * Resume roothubs only if there are pending events. ++ * USB 3 devices resend U3 LFPS wake after a 100ms delay if ++ * the first wake signalling failed, give it that chance. ++ */ ++ pending_portevent = xhci_pending_portevent(xhci); ++ if (!pending_portevent) { ++ msleep(120); ++ pending_portevent = xhci_pending_portevent(xhci); ++ } ++ ++ if (pending_portevent) { + usb_hcd_resume_root_hub(xhci->shared_hcd); + usb_hcd_resume_root_hub(hcd); + } + } +- + /* + * If system is subject to the Quirk, Compliance Mode Timer needs to + * be re-initialized Always after a system resume. Ports are subject +diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c +index 75fb41d4e9fc0..22249e389c3d0 100644 +--- a/drivers/usb/renesas_usbhs/pipe.c ++++ b/drivers/usb/renesas_usbhs/pipe.c +@@ -805,6 +805,8 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, + + void usbhs_pipe_free(struct usbhs_pipe *pipe) + { ++ usbhsp_pipe_select(pipe); ++ usbhsp_pipe_cfg_set(pipe, 0xFFFF, 0); + usbhsp_put_pipe(pipe); + } + +diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c +index c3d82cabbe65c..2cff9c40f28aa 100644 +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -75,6 +75,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x1a86, 0x7522) }, + { USB_DEVICE(0x1a86, 0x7523) }, + { USB_DEVICE(0x4348, 0x5523) }, ++ { USB_DEVICE(0x9986, 0x7523) }, + { }, + }; + MODULE_DEVICE_TABLE(usb, id_table); +diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c +index ded4c8f2bba4e..91462ff9a99d0 100644 +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -142,6 +142,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */ + { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ + { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ ++ { USB_DEVICE(0x10C4, 0x88D8) }, /* Acuity Brands nLight Air Adapter */ + { USB_DEVICE(0x10C4, 0x88FB) }, /* CESINEL MEDCAL STII Network Analyzer */ + { USB_DEVICE(0x10C4, 0x8938) }, /* CESINEL MEDCAL S II Network Analyzer */ + { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ +@@ -198,6 +199,8 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ + { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */ + { USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */ ++ { USB_DEVICE(0x1901, 0x0197) }, /* GE CS1000 Display serial interface */ ++ { USB_DEVICE(0x1901, 0x0198) }, /* GE CS1000 M.2 Key E serial interface */ + { USB_DEVICE(0x199B, 0xBA30) }, /* LORD WSDA-200-USB */ + { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ + { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ +diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c +index b639d064e5da2..14ab47f88251b 100644 +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -2966,26 +2966,32 @@ static int edge_startup(struct usb_serial *serial) + response = -ENODEV; + } + +- usb_free_urb(edge_serial->interrupt_read_urb); +- kfree(edge_serial->interrupt_in_buffer); +- +- usb_free_urb(edge_serial->read_urb); +- kfree(edge_serial->bulk_in_buffer); +- +- kfree(edge_serial); +- +- return response; ++ goto error; + } + + /* start interrupt read for this edgeport this interrupt will + * continue as long as the edgeport is connected */ + response = usb_submit_urb(edge_serial->interrupt_read_urb, + GFP_KERNEL); +- if (response) ++ if (response) { + dev_err(ddev, "%s - Error %d submitting control urb\n", + __func__, response); ++ ++ goto error; ++ } + } + return response; ++ ++error: ++ usb_free_urb(edge_serial->interrupt_read_urb); ++ kfree(edge_serial->interrupt_in_buffer); ++ ++ usb_free_urb(edge_serial->read_urb); ++ kfree(edge_serial->bulk_in_buffer); ++ ++ kfree(edge_serial); ++ ++ return response; + } + + +diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c +index 4aad99a59958b..5501eb89f3951 100644 +--- a/drivers/usb/usbip/stub_dev.c ++++ b/drivers/usb/usbip/stub_dev.c +@@ -60,6 +60,8 @@ static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr, + int sockfd = 0; + struct socket *socket; + int rv; ++ struct task_struct *tcp_rx = NULL; ++ struct task_struct *tcp_tx = NULL; + + if (!sdev) { + dev_err(dev, "sdev is null\n"); +@@ -83,23 +85,47 @@ static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr, + } + + socket = sockfd_lookup(sockfd, &err); +- if (!socket) ++ if (!socket) { ++ dev_err(dev, "failed to lookup sock"); + goto err; ++ } + +- sdev->ud.tcp_socket = socket; +- sdev->ud.sockfd = sockfd; ++ if (socket->type != SOCK_STREAM) { ++ dev_err(dev, "Expecting SOCK_STREAM - found %d", ++ socket->type); ++ goto sock_err; ++ } + ++ /* unlock and create threads and get tasks */ + spin_unlock_irq(&sdev->ud.lock); ++ tcp_rx = kthread_create(stub_rx_loop, &sdev->ud, "stub_rx"); ++ if (IS_ERR(tcp_rx)) { ++ sockfd_put(socket); ++ return -EINVAL; ++ } ++ tcp_tx = kthread_create(stub_tx_loop, &sdev->ud, "stub_tx"); ++ if (IS_ERR(tcp_tx)) { ++ kthread_stop(tcp_rx); ++ sockfd_put(socket); ++ return -EINVAL; ++ } + +- sdev->ud.tcp_rx = kthread_get_run(stub_rx_loop, &sdev->ud, +- "stub_rx"); +- sdev->ud.tcp_tx = kthread_get_run(stub_tx_loop, &sdev->ud, +- "stub_tx"); ++ /* get task structs now */ ++ get_task_struct(tcp_rx); ++ get_task_struct(tcp_tx); + ++ /* lock and update sdev->ud state */ + spin_lock_irq(&sdev->ud.lock); ++ sdev->ud.tcp_socket = socket; ++ sdev->ud.sockfd = sockfd; ++ sdev->ud.tcp_rx = tcp_rx; ++ sdev->ud.tcp_tx = tcp_tx; + sdev->ud.status = SDEV_ST_USED; + spin_unlock_irq(&sdev->ud.lock); + ++ wake_up_process(sdev->ud.tcp_rx); ++ wake_up_process(sdev->ud.tcp_tx); ++ + } else { + dev_info(dev, "stub down\n"); + +@@ -114,6 +140,8 @@ static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr, + + return count; + ++sock_err: ++ sockfd_put(socket); + err: + spin_unlock_irq(&sdev->ud.lock); + return -EINVAL; +diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c +index b9432fdec7750..1d681990b398f 100644 +--- a/drivers/usb/usbip/vhci_sysfs.c ++++ b/drivers/usb/usbip/vhci_sysfs.c +@@ -202,8 +202,16 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, + + /* Extract socket from fd. */ + socket = sockfd_lookup(sockfd, &err); +- if (!socket) ++ if (!socket) { ++ dev_err(dev, "failed to lookup sock"); + return -EINVAL; ++ } ++ if (socket->type != SOCK_STREAM) { ++ dev_err(dev, "Expecting SOCK_STREAM - found %d", ++ socket->type); ++ sockfd_put(socket); ++ return -EINVAL; ++ } + + /* now need lock until setting vdev status as used */ + +diff --git a/drivers/xen/events/events_2l.c b/drivers/xen/events/events_2l.c +index e902512fcfb50..ca729f19061d3 100644 +--- a/drivers/xen/events/events_2l.c ++++ b/drivers/xen/events/events_2l.c +@@ -46,6 +46,11 @@ static unsigned evtchn_2l_max_channels(void) + return EVTCHN_2L_NR_CHANNELS; + } + ++static void evtchn_2l_remove(evtchn_port_t evtchn, unsigned int cpu) ++{ ++ clear_bit(evtchn, BM(per_cpu(cpu_evtchn_mask, cpu))); ++} ++ + static void evtchn_2l_bind_to_cpu(struct irq_info *info, unsigned cpu) + { + clear_bit(info->evtchn, BM(per_cpu(cpu_evtchn_mask, info->cpu))); +@@ -70,12 +75,6 @@ static bool evtchn_2l_is_pending(unsigned port) + return sync_test_bit(port, BM(&s->evtchn_pending[0])); + } + +-static bool evtchn_2l_test_and_set_mask(unsigned port) +-{ +- struct shared_info *s = HYPERVISOR_shared_info; +- return sync_test_and_set_bit(port, BM(&s->evtchn_mask[0])); +-} +- + static void evtchn_2l_mask(unsigned port) + { + struct shared_info *s = HYPERVISOR_shared_info; +@@ -353,18 +352,27 @@ static void evtchn_2l_resume(void) + EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD); + } + ++static int evtchn_2l_percpu_deinit(unsigned int cpu) ++{ ++ memset(per_cpu(cpu_evtchn_mask, cpu), 0, sizeof(xen_ulong_t) * ++ EVTCHN_2L_NR_CHANNELS/BITS_PER_EVTCHN_WORD); ++ ++ return 0; ++} ++ + static const struct evtchn_ops evtchn_ops_2l = { + .max_channels = evtchn_2l_max_channels, + .nr_channels = evtchn_2l_max_channels, ++ .remove = evtchn_2l_remove, + .bind_to_cpu = evtchn_2l_bind_to_cpu, + .clear_pending = evtchn_2l_clear_pending, + .set_pending = evtchn_2l_set_pending, + .is_pending = evtchn_2l_is_pending, +- .test_and_set_mask = evtchn_2l_test_and_set_mask, + .mask = evtchn_2l_mask, + .unmask = evtchn_2l_unmask, + .handle_events = evtchn_2l_handle_events, + .resume = evtchn_2l_resume, ++ .percpu_deinit = evtchn_2l_percpu_deinit, + }; + + void __init xen_evtchn_2l_init(void) +diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c +index ec4074c66d9db..d1e68b4835953 100644 +--- a/drivers/xen/events/events_base.c ++++ b/drivers/xen/events/events_base.c +@@ -99,6 +99,7 @@ static DEFINE_RWLOCK(evtchn_rwlock); + * evtchn_rwlock + * IRQ-desc lock + * percpu eoi_list_lock ++ * irq_info->lock + */ + + static LIST_HEAD(xen_irq_list_head); +@@ -220,6 +221,8 @@ static int xen_irq_info_common_setup(struct irq_info *info, + info->irq = irq; + info->evtchn = evtchn; + info->cpu = cpu; ++ info->mask_reason = EVT_MASK_REASON_EXPLICIT; ++ spin_lock_init(&info->lock); + + ret = set_evtchn_to_irq(evtchn, irq); + if (ret < 0) +@@ -286,6 +289,7 @@ static int xen_irq_info_pirq_setup(unsigned irq, + static void xen_irq_info_cleanup(struct irq_info *info) + { + set_evtchn_to_irq(info->evtchn, -1); ++ xen_evtchn_port_remove(info->evtchn, info->cpu); + info->evtchn = 0; + } + +@@ -366,6 +370,34 @@ unsigned int cpu_from_evtchn(unsigned int evtchn) + return ret; + } + ++static void do_mask(struct irq_info *info, u8 reason) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&info->lock, flags); ++ ++ if (!info->mask_reason) ++ mask_evtchn(info->evtchn); ++ ++ info->mask_reason |= reason; ++ ++ spin_unlock_irqrestore(&info->lock, flags); ++} ++ ++static void do_unmask(struct irq_info *info, u8 reason) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&info->lock, flags); ++ ++ info->mask_reason &= ~reason; ++ ++ if (!info->mask_reason) ++ unmask_evtchn(info->evtchn); ++ ++ spin_unlock_irqrestore(&info->lock, flags); ++} ++ + #ifdef CONFIG_X86 + static bool pirq_check_eoi_map(unsigned irq) + { +@@ -501,7 +533,7 @@ static void xen_irq_lateeoi_locked(struct irq_info *info, bool spurious) + } + + info->eoi_time = 0; +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_EOI_PENDING); + } + + static void xen_irq_lateeoi_worker(struct work_struct *work) +@@ -670,6 +702,12 @@ static void xen_evtchn_close(unsigned int port) + BUG(); + } + ++static void event_handler_exit(struct irq_info *info) ++{ ++ smp_store_release(&info->is_active, 0); ++ clear_evtchn(info->evtchn); ++} ++ + static void pirq_query_unmask(int irq) + { + struct physdev_irq_status_query irq_status; +@@ -688,7 +726,8 @@ static void pirq_query_unmask(int irq) + + static void eoi_pirq(struct irq_data *data) + { +- int evtchn = evtchn_from_irq(data->irq); ++ struct irq_info *info = info_for_irq(data->irq); ++ int evtchn = info ? info->evtchn : 0; + struct physdev_eoi eoi = { .irq = pirq_from_irq(data->irq) }; + int rc = 0; + +@@ -697,16 +736,15 @@ static void eoi_pirq(struct irq_data *data) + + if (unlikely(irqd_is_setaffinity_pending(data)) && + likely(!irqd_irq_disabled(data))) { +- int masked = test_and_set_mask(evtchn); ++ do_mask(info, EVT_MASK_REASON_TEMPORARY); + +- clear_evtchn(evtchn); ++ event_handler_exit(info); + + irq_move_masked_irq(data); + +- if (!masked) +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_TEMPORARY); + } else +- clear_evtchn(evtchn); ++ event_handler_exit(info); + + if (pirq_needs_eoi(data->irq)) { + rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi); +@@ -757,7 +795,8 @@ static unsigned int __startup_pirq(unsigned int irq) + goto err; + + out: +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_EXPLICIT); ++ + eoi_pirq(irq_get_irq_data(irq)); + + return 0; +@@ -784,7 +823,7 @@ static void shutdown_pirq(struct irq_data *data) + if (!VALID_EVTCHN(evtchn)) + return; + +- mask_evtchn(evtchn); ++ do_mask(info, EVT_MASK_REASON_EXPLICIT); + xen_evtchn_close(evtchn); + xen_irq_info_cleanup(info); + } +@@ -1540,6 +1579,8 @@ void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl) + } + + info = info_for_irq(irq); ++ if (xchg_acquire(&info->is_active, 1)) ++ return; + + if (ctrl->defer_eoi) { + info->eoi_cpu = smp_processor_id(); +@@ -1646,8 +1687,8 @@ void rebind_evtchn_irq(int evtchn, int irq) + static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) + { + struct evtchn_bind_vcpu bind_vcpu; +- int evtchn = evtchn_from_irq(irq); +- int masked; ++ struct irq_info *info = info_for_irq(irq); ++ int evtchn = info ? info->evtchn : 0; + + if (!VALID_EVTCHN(evtchn)) + return -1; +@@ -1663,7 +1704,7 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) + * Mask the event while changing the VCPU binding to prevent + * it being delivered on an unexpected VCPU. + */ +- masked = test_and_set_mask(evtchn); ++ do_mask(info, EVT_MASK_REASON_TEMPORARY); + + /* + * If this fails, it usually just indicates that we're dealing with a +@@ -1673,8 +1714,7 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) + if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) + bind_evtchn_to_cpu(evtchn, tcpu); + +- if (!masked) +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_TEMPORARY); + + return 0; + } +@@ -1689,39 +1729,41 @@ static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest, + + static void enable_dynirq(struct irq_data *data) + { +- int evtchn = evtchn_from_irq(data->irq); ++ struct irq_info *info = info_for_irq(data->irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; + + if (VALID_EVTCHN(evtchn)) +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_EXPLICIT); + } + + static void disable_dynirq(struct irq_data *data) + { +- int evtchn = evtchn_from_irq(data->irq); ++ struct irq_info *info = info_for_irq(data->irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; + + if (VALID_EVTCHN(evtchn)) +- mask_evtchn(evtchn); ++ do_mask(info, EVT_MASK_REASON_EXPLICIT); + } + + static void ack_dynirq(struct irq_data *data) + { +- int evtchn = evtchn_from_irq(data->irq); ++ struct irq_info *info = info_for_irq(data->irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; + + if (!VALID_EVTCHN(evtchn)) + return; + + if (unlikely(irqd_is_setaffinity_pending(data)) && + likely(!irqd_irq_disabled(data))) { +- int masked = test_and_set_mask(evtchn); ++ do_mask(info, EVT_MASK_REASON_TEMPORARY); + +- clear_evtchn(evtchn); ++ event_handler_exit(info); + + irq_move_masked_irq(data); + +- if (!masked) +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_TEMPORARY); + } else +- clear_evtchn(evtchn); ++ event_handler_exit(info); + } + + static void mask_ack_dynirq(struct irq_data *data) +@@ -1730,18 +1772,39 @@ static void mask_ack_dynirq(struct irq_data *data) + ack_dynirq(data); + } + ++static void lateeoi_ack_dynirq(struct irq_data *data) ++{ ++ struct irq_info *info = info_for_irq(data->irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; ++ ++ if (VALID_EVTCHN(evtchn)) { ++ do_mask(info, EVT_MASK_REASON_EOI_PENDING); ++ event_handler_exit(info); ++ } ++} ++ ++static void lateeoi_mask_ack_dynirq(struct irq_data *data) ++{ ++ struct irq_info *info = info_for_irq(data->irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; ++ ++ if (VALID_EVTCHN(evtchn)) { ++ do_mask(info, EVT_MASK_REASON_EXPLICIT); ++ event_handler_exit(info); ++ } ++} ++ + static int retrigger_dynirq(struct irq_data *data) + { +- unsigned int evtchn = evtchn_from_irq(data->irq); +- int masked; ++ struct irq_info *info = info_for_irq(data->irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; + + if (!VALID_EVTCHN(evtchn)) + return 0; + +- masked = test_and_set_mask(evtchn); ++ do_mask(info, EVT_MASK_REASON_TEMPORARY); + set_evtchn(evtchn); +- if (!masked) +- unmask_evtchn(evtchn); ++ do_unmask(info, EVT_MASK_REASON_TEMPORARY); + + return 1; + } +@@ -1836,10 +1899,11 @@ static void restore_cpu_ipis(unsigned int cpu) + /* Clear an irq's pending state, in preparation for polling on it */ + void xen_clear_irq_pending(int irq) + { +- int evtchn = evtchn_from_irq(irq); ++ struct irq_info *info = info_for_irq(irq); ++ evtchn_port_t evtchn = info ? info->evtchn : 0; + + if (VALID_EVTCHN(evtchn)) +- clear_evtchn(evtchn); ++ event_handler_exit(info); + } + EXPORT_SYMBOL(xen_clear_irq_pending); + void xen_set_irq_pending(int irq) +@@ -1948,8 +2012,8 @@ static struct irq_chip xen_lateeoi_chip __read_mostly = { + .irq_mask = disable_dynirq, + .irq_unmask = enable_dynirq, + +- .irq_ack = mask_ack_dynirq, +- .irq_mask_ack = mask_ack_dynirq, ++ .irq_ack = lateeoi_ack_dynirq, ++ .irq_mask_ack = lateeoi_mask_ack_dynirq, + + .irq_set_affinity = set_affinity_irq, + .irq_retrigger = retrigger_dynirq, +diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c +index 7addca0d8d26b..5e6ff21201326 100644 +--- a/drivers/xen/events/events_fifo.c ++++ b/drivers/xen/events/events_fifo.c +@@ -209,12 +209,6 @@ static bool evtchn_fifo_is_pending(unsigned port) + return sync_test_bit(EVTCHN_FIFO_BIT(PENDING, word), BM(word)); + } + +-static bool evtchn_fifo_test_and_set_mask(unsigned port) +-{ +- event_word_t *word = event_word_from_port(port); +- return sync_test_and_set_bit(EVTCHN_FIFO_BIT(MASKED, word), BM(word)); +-} +- + static void evtchn_fifo_mask(unsigned port) + { + event_word_t *word = event_word_from_port(port); +@@ -421,7 +415,6 @@ static const struct evtchn_ops evtchn_ops_fifo = { + .clear_pending = evtchn_fifo_clear_pending, + .set_pending = evtchn_fifo_set_pending, + .is_pending = evtchn_fifo_is_pending, +- .test_and_set_mask = evtchn_fifo_test_and_set_mask, + .mask = evtchn_fifo_mask, + .unmask = evtchn_fifo_unmask, + .handle_events = evtchn_fifo_handle_events, +diff --git a/drivers/xen/events/events_internal.h b/drivers/xen/events/events_internal.h +index b9b4f59198930..3df6f28b75e69 100644 +--- a/drivers/xen/events/events_internal.h ++++ b/drivers/xen/events/events_internal.h +@@ -35,13 +35,19 @@ struct irq_info { + struct list_head eoi_list; + short refcnt; + short spurious_cnt; +- enum xen_irq_type type; /* type */ ++ short type; /* type */ ++ u8 mask_reason; /* Why is event channel masked */ ++#define EVT_MASK_REASON_EXPLICIT 0x01 ++#define EVT_MASK_REASON_TEMPORARY 0x02 ++#define EVT_MASK_REASON_EOI_PENDING 0x04 ++ u8 is_active; /* Is event just being handled? */ + unsigned irq; + unsigned int evtchn; /* event channel */ + unsigned short cpu; /* cpu bound */ + unsigned short eoi_cpu; /* EOI must happen on this cpu */ + unsigned int irq_epoch; /* If eoi_cpu valid: irq_epoch of event */ + u64 eoi_time; /* Time in jiffies when to EOI. */ ++ spinlock_t lock; + + union { + unsigned short virq; +@@ -67,12 +73,12 @@ struct evtchn_ops { + unsigned (*nr_channels)(void); + + int (*setup)(struct irq_info *info); ++ void (*remove)(evtchn_port_t port, unsigned int cpu); + void (*bind_to_cpu)(struct irq_info *info, unsigned cpu); + + void (*clear_pending)(unsigned port); + void (*set_pending)(unsigned port); + bool (*is_pending)(unsigned port); +- bool (*test_and_set_mask)(unsigned port); + void (*mask)(unsigned port); + void (*unmask)(unsigned port); + +@@ -109,6 +115,13 @@ static inline int xen_evtchn_port_setup(struct irq_info *info) + return 0; + } + ++static inline void xen_evtchn_port_remove(evtchn_port_t evtchn, ++ unsigned int cpu) ++{ ++ if (evtchn_ops->remove) ++ evtchn_ops->remove(evtchn, cpu); ++} ++ + static inline void xen_evtchn_port_bind_to_cpu(struct irq_info *info, + unsigned cpu) + { +@@ -130,11 +143,6 @@ static inline bool test_evtchn(unsigned port) + return evtchn_ops->is_pending(port); + } + +-static inline bool test_and_set_mask(unsigned port) +-{ +- return evtchn_ops->test_and_set_mask(port); +-} +- + static inline void mask_evtchn(unsigned port) + { + return evtchn_ops->mask(port); +diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c +index 4f4fc9ff36365..5666eb49bbbdd 100644 +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -204,7 +204,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) + rc = server->ops->queryfs(xid, tcon, buf); + + free_xid(xid); +- return 0; ++ return rc; + } + + static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len) +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 3c15291ba1aaa..0c9386978d9d8 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -4922,7 +4922,7 @@ static int _nfs4_get_security_label(struct inode *inode, void *buf, + return ret; + if (!(fattr.valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL)) + return -ENOENT; +- return 0; ++ return label.len; + } + + static int nfs4_get_security_label(struct inode *inode, void *buf, +diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h +index 1a2111c775ae1..0e7350973e0e5 100644 +--- a/include/linux/can/skb.h ++++ b/include/linux/can/skb.h +@@ -48,8 +48,12 @@ static inline void can_skb_reserve(struct sk_buff *skb) + + static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk) + { +- if (sk) { +- sock_hold(sk); ++ /* If the socket has already been closed by user space, the ++ * refcount may already be 0 (and the socket will be freed ++ * after the last TX skb has been freed). So only increase ++ * socket refcount if the refcount is > 0. ++ */ ++ if (sk && atomic_inc_not_zero(&sk->sk_refcnt)) { + skb->destructor = sock_efree; + skb->sk = sk; + } +diff --git a/include/uapi/linux/netfilter/nfnetlink_cthelper.h b/include/uapi/linux/netfilter/nfnetlink_cthelper.h +index 33659f6fad3ee..30557bade9354 100644 +--- a/include/uapi/linux/netfilter/nfnetlink_cthelper.h ++++ b/include/uapi/linux/netfilter/nfnetlink_cthelper.h +@@ -4,7 +4,7 @@ + #define NFCT_HELPER_STATUS_DISABLED 0 + #define NFCT_HELPER_STATUS_ENABLED 1 + +-enum nfnl_acct_msg_types { ++enum nfnl_cthelper_msg_types { + NFNL_MSG_CTHELPER_NEW, + NFNL_MSG_CTHELPER_GET, + NFNL_MSG_CTHELPER_DEL, +diff --git a/kernel/futex.c b/kernel/futex.c +index 95cdc11c89f8e..ff5499b0c5b34 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -1016,6 +1016,39 @@ static void exit_pi_state_list(struct task_struct *curr) + * [10] There is no transient state which leaves owner and user space + * TID out of sync. Except one error case where the kernel is denied + * write access to the user address, see fixup_pi_state_owner(). ++ * ++ * ++ * Serialization and lifetime rules: ++ * ++ * hb->lock: ++ * ++ * hb -> futex_q, relation ++ * futex_q -> pi_state, relation ++ * ++ * (cannot be raw because hb can contain arbitrary amount ++ * of futex_q's) ++ * ++ * pi_mutex->wait_lock: ++ * ++ * {uval, pi_state} ++ * ++ * (and pi_mutex 'obviously') ++ * ++ * p->pi_lock: ++ * ++ * p->pi_state_list -> pi_state->list, relation ++ * ++ * pi_state->refcount: ++ * ++ * pi_state lifetime ++ * ++ * ++ * Lock order: ++ * ++ * hb->lock ++ * pi_mutex->wait_lock ++ * p->pi_lock ++ * + */ + + /* +@@ -1023,10 +1056,12 @@ static void exit_pi_state_list(struct task_struct *curr) + * the pi_state against the user space value. If correct, attach to + * it. + */ +-static int attach_to_pi_state(u32 uval, struct futex_pi_state *pi_state, ++static int attach_to_pi_state(u32 __user *uaddr, u32 uval, ++ struct futex_pi_state *pi_state, + struct futex_pi_state **ps) + { + pid_t pid = uval & FUTEX_TID_MASK; ++ int ret, uval2; + + /* + * Userspace might have messed up non-PI and PI futexes [3] +@@ -1034,8 +1069,33 @@ static int attach_to_pi_state(u32 uval, struct futex_pi_state *pi_state, + if (unlikely(!pi_state)) + return -EINVAL; + ++ /* ++ * We get here with hb->lock held, and having found a ++ * futex_top_waiter(). This means that futex_lock_pi() of said futex_q ++ * has dropped the hb->lock in between queue_me() and unqueue_me_pi(), ++ * which in turn means that futex_lock_pi() still has a reference on ++ * our pi_state. ++ */ + WARN_ON(!atomic_read(&pi_state->refcount)); + ++ /* ++ * Now that we have a pi_state, we can acquire wait_lock ++ * and do the state validation. ++ */ ++ raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); ++ ++ /* ++ * Since {uval, pi_state} is serialized by wait_lock, and our current ++ * uval was read without holding it, it can have changed. Verify it ++ * still is what we expect it to be, otherwise retry the entire ++ * operation. ++ */ ++ if (get_futex_value_locked(&uval2, uaddr)) ++ goto out_efault; ++ ++ if (uval != uval2) ++ goto out_eagain; ++ + /* + * Handle the owner died case: + */ +@@ -1051,11 +1111,11 @@ static int attach_to_pi_state(u32 uval, struct futex_pi_state *pi_state, + * is not 0. Inconsistent state. [5] + */ + if (pid) +- return -EINVAL; ++ goto out_einval; + /* + * Take a ref on the state and return success. [4] + */ +- goto out_state; ++ goto out_attach; + } + + /* +@@ -1067,14 +1127,14 @@ static int attach_to_pi_state(u32 uval, struct futex_pi_state *pi_state, + * Take a ref on the state and return success. [6] + */ + if (!pid) +- goto out_state; ++ goto out_attach; + } else { + /* + * If the owner died bit is not set, then the pi_state + * must have an owner. [7] + */ + if (!pi_state->owner) +- return -EINVAL; ++ goto out_einval; + } + + /* +@@ -1083,11 +1143,29 @@ static int attach_to_pi_state(u32 uval, struct futex_pi_state *pi_state, + * user space TID. [9/10] + */ + if (pid != task_pid_vnr(pi_state->owner)) +- return -EINVAL; +-out_state: ++ goto out_einval; ++ ++out_attach: + atomic_inc(&pi_state->refcount); ++ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); + *ps = pi_state; + return 0; ++ ++out_einval: ++ ret = -EINVAL; ++ goto out_error; ++ ++out_eagain: ++ ret = -EAGAIN; ++ goto out_error; ++ ++out_efault: ++ ret = -EFAULT; ++ goto out_error; ++ ++out_error: ++ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); ++ return ret; + } + + /** +@@ -1120,11 +1198,67 @@ static void wait_for_owner_exiting(int ret, struct task_struct *exiting) + put_task_struct(exiting); + } + ++static int handle_exit_race(u32 __user *uaddr, u32 uval, ++ struct task_struct *tsk) ++{ ++ u32 uval2; ++ ++ /* ++ * If the futex exit state is not yet FUTEX_STATE_DEAD, tell the ++ * caller that the alleged owner is busy. ++ */ ++ if (tsk && tsk->futex_state != FUTEX_STATE_DEAD) ++ return -EBUSY; ++ ++ /* ++ * Reread the user space value to handle the following situation: ++ * ++ * CPU0 CPU1 ++ * ++ * sys_exit() sys_futex() ++ * do_exit() futex_lock_pi() ++ * futex_lock_pi_atomic() ++ * exit_signals(tsk) No waiters: ++ * tsk->flags |= PF_EXITING; *uaddr == 0x00000PID ++ * mm_release(tsk) Set waiter bit ++ * exit_robust_list(tsk) { *uaddr = 0x80000PID; ++ * Set owner died attach_to_pi_owner() { ++ * *uaddr = 0xC0000000; tsk = get_task(PID); ++ * } if (!tsk->flags & PF_EXITING) { ++ * ... attach(); ++ * tsk->futex_state = } else { ++ * FUTEX_STATE_DEAD; if (tsk->futex_state != ++ * FUTEX_STATE_DEAD) ++ * return -EAGAIN; ++ * return -ESRCH; <--- FAIL ++ * } ++ * ++ * Returning ESRCH unconditionally is wrong here because the ++ * user space value has been changed by the exiting task. ++ * ++ * The same logic applies to the case where the exiting task is ++ * already gone. ++ */ ++ if (get_futex_value_locked(&uval2, uaddr)) ++ return -EFAULT; ++ ++ /* If the user space value has changed, try again. */ ++ if (uval2 != uval) ++ return -EAGAIN; ++ ++ /* ++ * The exiting task did not have a robust list, the robust list was ++ * corrupted or the user space value in *uaddr is simply bogus. ++ * Give up and tell user space. ++ */ ++ return -ESRCH; ++} ++ + /* + * Lookup the task for the TID provided from user space and attach to + * it after doing proper sanity checks. + */ +-static int attach_to_pi_owner(u32 uval, union futex_key *key, ++static int attach_to_pi_owner(u32 __user *uaddr, u32 uval, union futex_key *key, + struct futex_pi_state **ps, + struct task_struct **exiting) + { +@@ -1135,12 +1269,15 @@ static int attach_to_pi_owner(u32 uval, union futex_key *key, + /* + * We are the first waiter - try to look up the real owner and attach + * the new pi_state to it, but bail out when TID = 0 [1] ++ * ++ * The !pid check is paranoid. None of the call sites should end up ++ * with pid == 0, but better safe than sorry. Let the caller retry + */ + if (!pid) +- return -ESRCH; ++ return -EAGAIN; + p = futex_find_get_task(pid); + if (!p) +- return -ESRCH; ++ return handle_exit_race(uaddr, uval, NULL); + + if (unlikely(p->flags & PF_KTHREAD)) { + put_task_struct(p); +@@ -1159,7 +1296,7 @@ static int attach_to_pi_owner(u32 uval, union futex_key *key, + * FUTEX_STATE_DEAD, we know that the task has finished + * the cleanup: + */ +- int ret = (p->futex_state = FUTEX_STATE_DEAD) ? -ESRCH : -EAGAIN; ++ int ret = handle_exit_race(uaddr, uval, p); + + raw_spin_unlock_irq(&p->pi_lock); + /* +@@ -1180,6 +1317,9 @@ static int attach_to_pi_owner(u32 uval, union futex_key *key, + + /* + * No existing pi state. First waiter. [2] ++ * ++ * This creates pi_state, we have hb->lock held, this means nothing can ++ * observe this state, wait_lock is irrelevant. + */ + pi_state = alloc_pi_state(); + +@@ -1204,7 +1344,8 @@ static int attach_to_pi_owner(u32 uval, union futex_key *key, + return 0; + } + +-static int lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, ++static int lookup_pi_state(u32 __user *uaddr, u32 uval, ++ struct futex_hash_bucket *hb, + union futex_key *key, struct futex_pi_state **ps, + struct task_struct **exiting) + { +@@ -1215,13 +1356,13 @@ static int lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, + * attach to the pi_state when the validation succeeds. + */ + if (match) +- return attach_to_pi_state(uval, match->pi_state, ps); ++ return attach_to_pi_state(uaddr, uval, match->pi_state, ps); + + /* + * We are the first waiter - try to look up the owner based on + * @uval and attach to it. + */ +- return attach_to_pi_owner(uval, key, ps, exiting); ++ return attach_to_pi_owner(uaddr, uval, key, ps, exiting); + } + + static int lock_pi_update_atomic(u32 __user *uaddr, u32 uval, u32 newval) +@@ -1234,7 +1375,7 @@ static int lock_pi_update_atomic(u32 __user *uaddr, u32 uval, u32 newval) + if (unlikely(cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))) + return -EFAULT; + +- /*If user space value changed, let the caller retry */ ++ /* If user space value changed, let the caller retry */ + return curval != uval ? -EAGAIN : 0; + } + +@@ -1298,7 +1439,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, + */ + match = futex_top_waiter(hb, key); + if (match) +- return attach_to_pi_state(uval, match->pi_state, ps); ++ return attach_to_pi_state(uaddr, uval, match->pi_state, ps); + + /* + * No waiter and user TID is 0. We are here because the +@@ -1337,7 +1478,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, + * attach to the owner. If that fails, no harm done, we only + * set the FUTEX_WAITERS bit in the user space variable. + */ +- return attach_to_pi_owner(uval, key, ps, exiting); ++ return attach_to_pi_owner(uaddr, newval, key, ps, exiting); + } + + /** +@@ -1438,6 +1579,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this, + + if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) { + ret = -EFAULT; ++ + } else if (curval != uval) { + /* + * If a unconditional UNLOCK_PI operation (user space did not +@@ -1971,7 +2113,7 @@ retry_private: + * rereading and handing potential crap to + * lookup_pi_state. + */ +- ret = lookup_pi_state(ret, hb2, &key2, ++ ret = lookup_pi_state(uaddr2, ret, hb2, &key2, + &pi_state, &exiting); + } + +@@ -2249,7 +2391,6 @@ static int __fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, + int err = 0; + + oldowner = pi_state->owner; +- + /* + * We are here because either: + * +@@ -2268,11 +2409,10 @@ static int __fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, + * because we can fault here. Imagine swapped out pages or a fork + * that marked all the anonymous memory readonly for cow. + * +- * Modifying pi_state _before_ the user space value would +- * leave the pi_state in an inconsistent state when we fault +- * here, because we need to drop the hash bucket lock to +- * handle the fault. This might be observed in the PID check +- * in lookup_pi_state. ++ * Modifying pi_state _before_ the user space value would leave the ++ * pi_state in an inconsistent state when we fault here, because we ++ * need to drop the locks to handle the fault. This might be observed ++ * in the PID check in lookup_pi_state. + */ + retry: + if (!argowner) { +@@ -2333,21 +2473,26 @@ retry: + return argowner == current; + + /* +- * To handle the page fault we need to drop the hash bucket +- * lock here. That gives the other task (either the highest priority +- * waiter itself or the task which stole the rtmutex) the +- * chance to try the fixup of the pi_state. So once we are +- * back from handling the fault we need to check the pi_state +- * after reacquiring the hash bucket lock and before trying to +- * do another fixup. When the fixup has been done already we +- * simply return. ++ * To handle the page fault we need to drop the locks here. That gives ++ * the other task (either the highest priority waiter itself or the ++ * task which stole the rtmutex) the chance to try the fixup of the ++ * pi_state. So once we are back from handling the fault we need to ++ * check the pi_state after reacquiring the locks and before trying to ++ * do another fixup. When the fixup has been done already we simply ++ * return. ++ * ++ * Note: we hold both hb->lock and pi_mutex->wait_lock. We can safely ++ * drop hb->lock since the caller owns the hb -> futex_q relation. ++ * Dropping the pi_mutex->wait_lock requires the state revalidate. + */ + handle_fault: ++ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); + spin_unlock(q->lock_ptr); + + err = fault_in_user_writeable(uaddr); + + spin_lock(q->lock_ptr); ++ raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); + + /* + * Check if someone else fixed it for us: +diff --git a/mm/slub.c b/mm/slub.c +index 18d1622144afe..40c7a3fbd031e 100644 +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -1682,7 +1682,7 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n, + + t = acquire_slab(s, n, page, object == NULL, &objects); + if (!t) +- continue; /* cmpxchg raced */ ++ break; + + available += objects; + if (!object) { +diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c +index 6dfc3daf7c21e..2a37f367dc047 100644 +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -300,7 +300,7 @@ struct sk_buff **udp_gro_receive(struct sk_buff **head, struct sk_buff *skb, + int flush = 1; + + if (NAPI_GRO_CB(skb)->encap_mark || +- (skb->ip_summed != CHECKSUM_PARTIAL && ++ (uh->check && skb->ip_summed != CHECKSUM_PARTIAL && + NAPI_GRO_CB(skb)->csum_cnt == 0 && + !NAPI_GRO_CB(skb)->csum_valid)) + goto out; +diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c +index cdafbd38a456b..8caae1c5d93df 100644 +--- a/net/netfilter/x_tables.c ++++ b/net/netfilter/x_tables.c +@@ -271,6 +271,7 @@ static int match_revfn(u8 af, const char *name, u8 revision, int *bestp) + const struct xt_match *m; + int have_rev = 0; + ++ mutex_lock(&xt[af].mutex); + list_for_each_entry(m, &xt[af].match, list) { + if (strcmp(m->name, name) == 0) { + if (m->revision > *bestp) +@@ -279,6 +280,7 @@ static int match_revfn(u8 af, const char *name, u8 revision, int *bestp) + have_rev = 1; + } + } ++ mutex_unlock(&xt[af].mutex); + + if (af != NFPROTO_UNSPEC && !have_rev) + return match_revfn(NFPROTO_UNSPEC, name, revision, bestp); +@@ -291,6 +293,7 @@ static int target_revfn(u8 af, const char *name, u8 revision, int *bestp) + const struct xt_target *t; + int have_rev = 0; + ++ mutex_lock(&xt[af].mutex); + list_for_each_entry(t, &xt[af].target, list) { + if (strcmp(t->name, name) == 0) { + if (t->revision > *bestp) +@@ -299,6 +302,7 @@ static int target_revfn(u8 af, const char *name, u8 revision, int *bestp) + have_rev = 1; + } + } ++ mutex_unlock(&xt[af].mutex); + + if (af != NFPROTO_UNSPEC && !have_rev) + return target_revfn(NFPROTO_UNSPEC, name, revision, bestp); +@@ -312,12 +316,10 @@ int xt_find_revision(u8 af, const char *name, u8 revision, int target, + { + int have_rev, best = -1; + +- mutex_lock(&xt[af].mutex); + if (target == 1) + have_rev = target_revfn(af, name, revision, &best); + else + have_rev = match_revfn(af, name, revision, &best); +- mutex_unlock(&xt[af].mutex); + + /* Nothing at all? Return 0 to try loading module. */ + if (best == -1) { +diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c +index 7250fb38350ce..8cba4c44da4c2 100644 +--- a/scripts/recordmcount.c ++++ b/scripts/recordmcount.c +@@ -362,7 +362,7 @@ static uint32_t (*w2)(uint16_t); + static int + is_mcounted_section_name(char const *const txtname) + { +- return strcmp(".text", txtname) == 0 || ++ return strncmp(".text", txtname, 5) == 0 || + strcmp(".ref.text", txtname) == 0 || + strcmp(".sched.text", txtname) == 0 || + strcmp(".spinlock.text", txtname) == 0 || +diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl +index ccd6614ea2182..5ca4ec2970197 100755 +--- a/scripts/recordmcount.pl ++++ b/scripts/recordmcount.pl +@@ -138,6 +138,11 @@ my %text_sections = ( + ".text.unlikely" => 1, + ); + ++# Acceptable section-prefixes to record. ++my %text_section_prefixes = ( ++ ".text." => 1, ++); ++ + # Note: we are nice to C-programmers here, thus we skip the '||='-idiom. + $objdump = 'objdump' if (!$objdump); + $objcopy = 'objcopy' if (!$objcopy); +@@ -503,6 +508,14 @@ while (<IN>) { + + # Only record text sections that we know are safe + $read_function = defined($text_sections{$1}); ++ if (!$read_function) { ++ foreach my $prefix (keys %text_section_prefixes) { ++ if (substr($1, 0, length $prefix) eq $prefix) { ++ $read_function = 1; ++ last; ++ } ++ } ++ } + # print out any recorded offsets + update_funcs(); + +diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c +index d0d6dfbfcfdf8..f25c2c43c5626 100644 +--- a/sound/pci/hda/hda_bind.c ++++ b/sound/pci/hda/hda_bind.c +@@ -46,6 +46,10 @@ static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev) + if (codec->bus->shutdown) + return; + ++ /* ignore unsol events during system suspend/resume */ ++ if (codec->core.dev.power.power_state.event != PM_EVENT_ON) ++ return; ++ + if (codec->patch_ops.unsol_event) + codec->patch_ops.unsol_event(codec, ev); + } +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index b249b1b857464..785c64b854ec6 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -2239,6 +2239,18 @@ static void generic_hdmi_free(struct hda_codec *codec) + } + + #ifdef CONFIG_PM ++static int generic_hdmi_suspend(struct hda_codec *codec) ++{ ++ struct hdmi_spec *spec = codec->spec; ++ int pin_idx; ++ ++ for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { ++ struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); ++ cancel_delayed_work_sync(&per_pin->work); ++ } ++ return 0; ++} ++ + static int generic_hdmi_resume(struct hda_codec *codec) + { + struct hdmi_spec *spec = codec->spec; +@@ -2262,6 +2274,7 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = { + .build_controls = generic_hdmi_build_controls, + .unsol_event = hdmi_unsol_event, + #ifdef CONFIG_PM ++ .suspend = generic_hdmi_suspend, + .resume = generic_hdmi_resume, + #endif + }; +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 59529a9cab614..79cffe44388f9 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1154,6 +1154,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) + case USB_ID(0x1de7, 0x0114): /* Phoenix Audio MT202pcs */ + case USB_ID(0x21B4, 0x0081): /* AudioQuest DragonFly */ + case USB_ID(0x2912, 0x30c8): /* Audioengine D1 */ ++ case USB_ID(0x413c, 0xa506): /* Dell AE515 sound bar */ + return true; + } + return false; |