diff options
author | Mike Pagano <mpagano@gentoo.org> | 2019-07-14 11:43:42 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2019-07-14 11:43:42 -0400 |
commit | 1ef22f135a36d059936f5137213f56461a3582f3 (patch) | |
tree | 7486a933fbbfbdeff462cfbcdca84d80dc9db870 | |
parent | Linux patch 4.19.58 (diff) | |
download | linux-patches-1ef22f135a36d059936f5137213f56461a3582f3.tar.gz linux-patches-1ef22f135a36d059936f5137213f56461a3582f3.tar.bz2 linux-patches-1ef22f135a36d059936f5137213f56461a3582f3.zip |
Linux patch 4.19.594.19-59
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1058_linux-4.19.59.patch | 4271 |
2 files changed, 4275 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 9cbece90..8871e402 100644 --- a/0000_README +++ b/0000_README @@ -275,6 +275,10 @@ Patch: 1057_linux-4.19.58.patch From: https://www.kernel.org Desc: Linux 4.19.58 +Patch: 1058_linux-4.19.59.patch +From: https://www.kernel.org +Desc: Linux 4.19.59 + 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/1058_linux-4.19.59.patch b/1058_linux-4.19.59.patch new file mode 100644 index 00000000..2c2de1c6 --- /dev/null +++ b/1058_linux-4.19.59.patch @@ -0,0 +1,4271 @@ +diff --git a/Documentation/ABI/testing/sysfs-class-net-qmi b/Documentation/ABI/testing/sysfs-class-net-qmi +index 7122d6264c49..c310db4ccbc2 100644 +--- a/Documentation/ABI/testing/sysfs-class-net-qmi ++++ b/Documentation/ABI/testing/sysfs-class-net-qmi +@@ -29,7 +29,7 @@ Contact: Bjørn Mork <bjorn@mork.no> + Description: + Unsigned integer. + +- Write a number ranging from 1 to 127 to add a qmap mux ++ Write a number ranging from 1 to 254 to add a qmap mux + based network device, supported by recent Qualcomm based + modems. + +@@ -46,5 +46,5 @@ Contact: Bjørn Mork <bjorn@mork.no> + Description: + Unsigned integer. + +- Write a number ranging from 1 to 127 to delete a previously ++ Write a number ranging from 1 to 254 to delete a previously + created qmap mux based network device. +diff --git a/Documentation/admin-guide/hw-vuln/index.rst b/Documentation/admin-guide/hw-vuln/index.rst +index ffc064c1ec68..49311f3da6f2 100644 +--- a/Documentation/admin-guide/hw-vuln/index.rst ++++ b/Documentation/admin-guide/hw-vuln/index.rst +@@ -9,5 +9,6 @@ are configurable at compile, boot or run time. + .. toctree:: + :maxdepth: 1 + ++ spectre + l1tf + mds +diff --git a/Documentation/admin-guide/hw-vuln/spectre.rst b/Documentation/admin-guide/hw-vuln/spectre.rst +new file mode 100644 +index 000000000000..25f3b2532198 +--- /dev/null ++++ b/Documentation/admin-guide/hw-vuln/spectre.rst +@@ -0,0 +1,697 @@ ++.. SPDX-License-Identifier: GPL-2.0 ++ ++Spectre Side Channels ++===================== ++ ++Spectre is a class of side channel attacks that exploit branch prediction ++and speculative execution on modern CPUs to read memory, possibly ++bypassing access controls. Speculative execution side channel exploits ++do not modify memory but attempt to infer privileged data in the memory. ++ ++This document covers Spectre variant 1 and Spectre variant 2. ++ ++Affected processors ++------------------- ++ ++Speculative execution side channel methods affect a wide range of modern ++high performance processors, since most modern high speed processors ++use branch prediction and speculative execution. ++ ++The following CPUs are vulnerable: ++ ++ - Intel Core, Atom, Pentium, and Xeon processors ++ ++ - AMD Phenom, EPYC, and Zen processors ++ ++ - IBM POWER and zSeries processors ++ ++ - Higher end ARM processors ++ ++ - Apple CPUs ++ ++ - Higher end MIPS CPUs ++ ++ - Likely most other high performance CPUs. Contact your CPU vendor for details. ++ ++Whether a processor is affected or not can be read out from the Spectre ++vulnerability files in sysfs. See :ref:`spectre_sys_info`. ++ ++Related CVEs ++------------ ++ ++The following CVE entries describe Spectre variants: ++ ++ ============= ======================= ================= ++ CVE-2017-5753 Bounds check bypass Spectre variant 1 ++ CVE-2017-5715 Branch target injection Spectre variant 2 ++ ============= ======================= ================= ++ ++Problem ++------- ++ ++CPUs use speculative operations to improve performance. That may leave ++traces of memory accesses or computations in the processor's caches, ++buffers, and branch predictors. Malicious software may be able to ++influence the speculative execution paths, and then use the side effects ++of the speculative execution in the CPUs' caches and buffers to infer ++privileged data touched during the speculative execution. ++ ++Spectre variant 1 attacks take advantage of speculative execution of ++conditional branches, while Spectre variant 2 attacks use speculative ++execution of indirect branches to leak privileged memory. ++See :ref:`[1] <spec_ref1>` :ref:`[5] <spec_ref5>` :ref:`[7] <spec_ref7>` ++:ref:`[10] <spec_ref10>` :ref:`[11] <spec_ref11>`. ++ ++Spectre variant 1 (Bounds Check Bypass) ++--------------------------------------- ++ ++The bounds check bypass attack :ref:`[2] <spec_ref2>` takes advantage ++of speculative execution that bypasses conditional branch instructions ++used for memory access bounds check (e.g. checking if the index of an ++array results in memory access within a valid range). This results in ++memory accesses to invalid memory (with out-of-bound index) that are ++done speculatively before validation checks resolve. Such speculative ++memory accesses can leave side effects, creating side channels which ++leak information to the attacker. ++ ++There are some extensions of Spectre variant 1 attacks for reading data ++over the network, see :ref:`[12] <spec_ref12>`. However such attacks ++are difficult, low bandwidth, fragile, and are considered low risk. ++ ++Spectre variant 2 (Branch Target Injection) ++------------------------------------------- ++ ++The branch target injection attack takes advantage of speculative ++execution of indirect branches :ref:`[3] <spec_ref3>`. The indirect ++branch predictors inside the processor used to guess the target of ++indirect branches can be influenced by an attacker, causing gadget code ++to be speculatively executed, thus exposing sensitive data touched by ++the victim. The side effects left in the CPU's caches during speculative ++execution can be measured to infer data values. ++ ++.. _poison_btb: ++ ++In Spectre variant 2 attacks, the attacker can steer speculative indirect ++branches in the victim to gadget code by poisoning the branch target ++buffer of a CPU used for predicting indirect branch addresses. Such ++poisoning could be done by indirect branching into existing code, ++with the address offset of the indirect branch under the attacker's ++control. Since the branch prediction on impacted hardware does not ++fully disambiguate branch address and uses the offset for prediction, ++this could cause privileged code's indirect branch to jump to a gadget ++code with the same offset. ++ ++The most useful gadgets take an attacker-controlled input parameter (such ++as a register value) so that the memory read can be controlled. Gadgets ++without input parameters might be possible, but the attacker would have ++very little control over what memory can be read, reducing the risk of ++the attack revealing useful data. ++ ++One other variant 2 attack vector is for the attacker to poison the ++return stack buffer (RSB) :ref:`[13] <spec_ref13>` to cause speculative ++subroutine return instruction execution to go to a gadget. An attacker's ++imbalanced subroutine call instructions might "poison" entries in the ++return stack buffer which are later consumed by a victim's subroutine ++return instructions. This attack can be mitigated by flushing the return ++stack buffer on context switch, or virtual machine (VM) exit. ++ ++On systems with simultaneous multi-threading (SMT), attacks are possible ++from the sibling thread, as level 1 cache and branch target buffer ++(BTB) may be shared between hardware threads in a CPU core. A malicious ++program running on the sibling thread may influence its peer's BTB to ++steer its indirect branch speculations to gadget code, and measure the ++speculative execution's side effects left in level 1 cache to infer the ++victim's data. ++ ++Attack scenarios ++---------------- ++ ++The following list of attack scenarios have been anticipated, but may ++not cover all possible attack vectors. ++ ++1. A user process attacking the kernel ++^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ++ ++ The attacker passes a parameter to the kernel via a register or ++ via a known address in memory during a syscall. Such parameter may ++ be used later by the kernel as an index to an array or to derive ++ a pointer for a Spectre variant 1 attack. The index or pointer ++ is invalid, but bound checks are bypassed in the code branch taken ++ for speculative execution. This could cause privileged memory to be ++ accessed and leaked. ++ ++ For kernel code that has been identified where data pointers could ++ potentially be influenced for Spectre attacks, new "nospec" accessor ++ macros are used to prevent speculative loading of data. ++ ++ Spectre variant 2 attacker can :ref:`poison <poison_btb>` the branch ++ target buffer (BTB) before issuing syscall to launch an attack. ++ After entering the kernel, the kernel could use the poisoned branch ++ target buffer on indirect jump and jump to gadget code in speculative ++ execution. ++ ++ If an attacker tries to control the memory addresses leaked during ++ speculative execution, he would also need to pass a parameter to the ++ gadget, either through a register or a known address in memory. After ++ the gadget has executed, he can measure the side effect. ++ ++ The kernel can protect itself against consuming poisoned branch ++ target buffer entries by using return trampolines (also known as ++ "retpoline") :ref:`[3] <spec_ref3>` :ref:`[9] <spec_ref9>` for all ++ indirect branches. Return trampolines trap speculative execution paths ++ to prevent jumping to gadget code during speculative execution. ++ x86 CPUs with Enhanced Indirect Branch Restricted Speculation ++ (Enhanced IBRS) available in hardware should use the feature to ++ mitigate Spectre variant 2 instead of retpoline. Enhanced IBRS is ++ more efficient than retpoline. ++ ++ There may be gadget code in firmware which could be exploited with ++ Spectre variant 2 attack by a rogue user process. To mitigate such ++ attacks on x86, Indirect Branch Restricted Speculation (IBRS) feature ++ is turned on before the kernel invokes any firmware code. ++ ++2. A user process attacking another user process ++^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ++ ++ A malicious user process can try to attack another user process, ++ either via a context switch on the same hardware thread, or from the ++ sibling hyperthread sharing a physical processor core on simultaneous ++ multi-threading (SMT) system. ++ ++ Spectre variant 1 attacks generally require passing parameters ++ between the processes, which needs a data passing relationship, such ++ as remote procedure calls (RPC). Those parameters are used in gadget ++ code to derive invalid data pointers accessing privileged memory in ++ the attacked process. ++ ++ Spectre variant 2 attacks can be launched from a rogue process by ++ :ref:`poisoning <poison_btb>` the branch target buffer. This can ++ influence the indirect branch targets for a victim process that either ++ runs later on the same hardware thread, or running concurrently on ++ a sibling hardware thread sharing the same physical core. ++ ++ A user process can protect itself against Spectre variant 2 attacks ++ by using the prctl() syscall to disable indirect branch speculation ++ for itself. An administrator can also cordon off an unsafe process ++ from polluting the branch target buffer by disabling the process's ++ indirect branch speculation. This comes with a performance cost ++ from not using indirect branch speculation and clearing the branch ++ target buffer. When SMT is enabled on x86, for a process that has ++ indirect branch speculation disabled, Single Threaded Indirect Branch ++ Predictors (STIBP) :ref:`[4] <spec_ref4>` are turned on to prevent the ++ sibling thread from controlling branch target buffer. In addition, ++ the Indirect Branch Prediction Barrier (IBPB) is issued to clear the ++ branch target buffer when context switching to and from such process. ++ ++ On x86, the return stack buffer is stuffed on context switch. ++ This prevents the branch target buffer from being used for branch ++ prediction when the return stack buffer underflows while switching to ++ a deeper call stack. Any poisoned entries in the return stack buffer ++ left by the previous process will also be cleared. ++ ++ User programs should use address space randomization to make attacks ++ more difficult (Set /proc/sys/kernel/randomize_va_space = 1 or 2). ++ ++3. A virtualized guest attacking the host ++^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ++ ++ The attack mechanism is similar to how user processes attack the ++ kernel. The kernel is entered via hyper-calls or other virtualization ++ exit paths. ++ ++ For Spectre variant 1 attacks, rogue guests can pass parameters ++ (e.g. in registers) via hyper-calls to derive invalid pointers to ++ speculate into privileged memory after entering the kernel. For places ++ where such kernel code has been identified, nospec accessor macros ++ are used to stop speculative memory access. ++ ++ For Spectre variant 2 attacks, rogue guests can :ref:`poison ++ <poison_btb>` the branch target buffer or return stack buffer, causing ++ the kernel to jump to gadget code in the speculative execution paths. ++ ++ To mitigate variant 2, the host kernel can use return trampolines ++ for indirect branches to bypass the poisoned branch target buffer, ++ and flushing the return stack buffer on VM exit. This prevents rogue ++ guests from affecting indirect branching in the host kernel. ++ ++ To protect host processes from rogue guests, host processes can have ++ indirect branch speculation disabled via prctl(). The branch target ++ buffer is cleared before context switching to such processes. ++ ++4. A virtualized guest attacking other guest ++^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ++ ++ A rogue guest may attack another guest to get data accessible by the ++ other guest. ++ ++ Spectre variant 1 attacks are possible if parameters can be passed ++ between guests. This may be done via mechanisms such as shared memory ++ or message passing. Such parameters could be used to derive data ++ pointers to privileged data in guest. The privileged data could be ++ accessed by gadget code in the victim's speculation paths. ++ ++ Spectre variant 2 attacks can be launched from a rogue guest by ++ :ref:`poisoning <poison_btb>` the branch target buffer or the return ++ stack buffer. Such poisoned entries could be used to influence ++ speculation execution paths in the victim guest. ++ ++ Linux kernel mitigates attacks to other guests running in the same ++ CPU hardware thread by flushing the return stack buffer on VM exit, ++ and clearing the branch target buffer before switching to a new guest. ++ ++ If SMT is used, Spectre variant 2 attacks from an untrusted guest ++ in the sibling hyperthread can be mitigated by the administrator, ++ by turning off the unsafe guest's indirect branch speculation via ++ prctl(). A guest can also protect itself by turning on microcode ++ based mitigations (such as IBPB or STIBP on x86) within the guest. ++ ++.. _spectre_sys_info: ++ ++Spectre system information ++-------------------------- ++ ++The Linux kernel provides a sysfs interface to enumerate the current ++mitigation status of the system for Spectre: whether the system is ++vulnerable, and which mitigations are active. ++ ++The sysfs file showing Spectre variant 1 mitigation status is: ++ ++ /sys/devices/system/cpu/vulnerabilities/spectre_v1 ++ ++The possible values in this file are: ++ ++ ======================================= ================================= ++ 'Mitigation: __user pointer sanitation' Protection in kernel on a case by ++ case base with explicit pointer ++ sanitation. ++ ======================================= ================================= ++ ++However, the protections are put in place on a case by case basis, ++and there is no guarantee that all possible attack vectors for Spectre ++variant 1 are covered. ++ ++The spectre_v2 kernel file reports if the kernel has been compiled with ++retpoline mitigation or if the CPU has hardware mitigation, and if the ++CPU has support for additional process-specific mitigation. ++ ++This file also reports CPU features enabled by microcode to mitigate ++attack between user processes: ++ ++1. Indirect Branch Prediction Barrier (IBPB) to add additional ++ isolation between processes of different users. ++2. Single Thread Indirect Branch Predictors (STIBP) to add additional ++ isolation between CPU threads running on the same core. ++ ++These CPU features may impact performance when used and can be enabled ++per process on a case-by-case base. ++ ++The sysfs file showing Spectre variant 2 mitigation status is: ++ ++ /sys/devices/system/cpu/vulnerabilities/spectre_v2 ++ ++The possible values in this file are: ++ ++ - Kernel status: ++ ++ ==================================== ================================= ++ 'Not affected' The processor is not vulnerable ++ 'Vulnerable' Vulnerable, no mitigation ++ 'Mitigation: Full generic retpoline' Software-focused mitigation ++ 'Mitigation: Full AMD retpoline' AMD-specific software mitigation ++ 'Mitigation: Enhanced IBRS' Hardware-focused mitigation ++ ==================================== ================================= ++ ++ - Firmware status: Show if Indirect Branch Restricted Speculation (IBRS) is ++ used to protect against Spectre variant 2 attacks when calling firmware (x86 only). ++ ++ ========== ============================================================= ++ 'IBRS_FW' Protection against user program attacks when calling firmware ++ ========== ============================================================= ++ ++ - Indirect branch prediction barrier (IBPB) status for protection between ++ processes of different users. This feature can be controlled through ++ prctl() per process, or through kernel command line options. This is ++ an x86 only feature. For more details see below. ++ ++ =================== ======================================================== ++ 'IBPB: disabled' IBPB unused ++ 'IBPB: always-on' Use IBPB on all tasks ++ 'IBPB: conditional' Use IBPB on SECCOMP or indirect branch restricted tasks ++ =================== ======================================================== ++ ++ - Single threaded indirect branch prediction (STIBP) status for protection ++ between different hyper threads. This feature can be controlled through ++ prctl per process, or through kernel command line options. This is x86 ++ only feature. For more details see below. ++ ++ ==================== ======================================================== ++ 'STIBP: disabled' STIBP unused ++ 'STIBP: forced' Use STIBP on all tasks ++ 'STIBP: conditional' Use STIBP on SECCOMP or indirect branch restricted tasks ++ ==================== ======================================================== ++ ++ - Return stack buffer (RSB) protection status: ++ ++ ============= =========================================== ++ 'RSB filling' Protection of RSB on context switch enabled ++ ============= =========================================== ++ ++Full mitigation might require a microcode update from the CPU ++vendor. When the necessary microcode is not available, the kernel will ++report vulnerability. ++ ++Turning on mitigation for Spectre variant 1 and Spectre variant 2 ++----------------------------------------------------------------- ++ ++1. Kernel mitigation ++^^^^^^^^^^^^^^^^^^^^ ++ ++ For the Spectre variant 1, vulnerable kernel code (as determined ++ by code audit or scanning tools) is annotated on a case by case ++ basis to use nospec accessor macros for bounds clipping :ref:`[2] ++ <spec_ref2>` to avoid any usable disclosure gadgets. However, it may ++ not cover all attack vectors for Spectre variant 1. ++ ++ For Spectre variant 2 mitigation, the compiler turns indirect calls or ++ jumps in the kernel into equivalent return trampolines (retpolines) ++ :ref:`[3] <spec_ref3>` :ref:`[9] <spec_ref9>` to go to the target ++ addresses. Speculative execution paths under retpolines are trapped ++ in an infinite loop to prevent any speculative execution jumping to ++ a gadget. ++ ++ To turn on retpoline mitigation on a vulnerable CPU, the kernel ++ needs to be compiled with a gcc compiler that supports the ++ -mindirect-branch=thunk-extern -mindirect-branch-register options. ++ If the kernel is compiled with a Clang compiler, the compiler needs ++ to support -mretpoline-external-thunk option. The kernel config ++ CONFIG_RETPOLINE needs to be turned on, and the CPU needs to run with ++ the latest updated microcode. ++ ++ On Intel Skylake-era systems the mitigation covers most, but not all, ++ cases. See :ref:`[3] <spec_ref3>` for more details. ++ ++ On CPUs with hardware mitigation for Spectre variant 2 (e.g. Enhanced ++ IBRS on x86), retpoline is automatically disabled at run time. ++ ++ The retpoline mitigation is turned on by default on vulnerable ++ CPUs. It can be forced on or off by the administrator ++ via the kernel command line and sysfs control files. See ++ :ref:`spectre_mitigation_control_command_line`. ++ ++ On x86, indirect branch restricted speculation is turned on by default ++ before invoking any firmware code to prevent Spectre variant 2 exploits ++ using the firmware. ++ ++ Using kernel address space randomization (CONFIG_RANDOMIZE_SLAB=y ++ and CONFIG_SLAB_FREELIST_RANDOM=y in the kernel configuration) makes ++ attacks on the kernel generally more difficult. ++ ++2. User program mitigation ++^^^^^^^^^^^^^^^^^^^^^^^^^^ ++ ++ User programs can mitigate Spectre variant 1 using LFENCE or "bounds ++ clipping". For more details see :ref:`[2] <spec_ref2>`. ++ ++ For Spectre variant 2 mitigation, individual user programs ++ can be compiled with return trampolines for indirect branches. ++ This protects them from consuming poisoned entries in the branch ++ target buffer left by malicious software. Alternatively, the ++ programs can disable their indirect branch speculation via prctl() ++ (See :ref:`Documentation/userspace-api/spec_ctrl.rst <set_spec_ctrl>`). ++ On x86, this will turn on STIBP to guard against attacks from the ++ sibling thread when the user program is running, and use IBPB to ++ flush the branch target buffer when switching to/from the program. ++ ++ Restricting indirect branch speculation on a user program will ++ also prevent the program from launching a variant 2 attack ++ on x86. All sand-boxed SECCOMP programs have indirect branch ++ speculation restricted by default. Administrators can change ++ that behavior via the kernel command line and sysfs control files. ++ See :ref:`spectre_mitigation_control_command_line`. ++ ++ Programs that disable their indirect branch speculation will have ++ more overhead and run slower. ++ ++ User programs should use address space randomization ++ (/proc/sys/kernel/randomize_va_space = 1 or 2) to make attacks more ++ difficult. ++ ++3. VM mitigation ++^^^^^^^^^^^^^^^^ ++ ++ Within the kernel, Spectre variant 1 attacks from rogue guests are ++ mitigated on a case by case basis in VM exit paths. Vulnerable code ++ uses nospec accessor macros for "bounds clipping", to avoid any ++ usable disclosure gadgets. However, this may not cover all variant ++ 1 attack vectors. ++ ++ For Spectre variant 2 attacks from rogue guests to the kernel, the ++ Linux kernel uses retpoline or Enhanced IBRS to prevent consumption of ++ poisoned entries in branch target buffer left by rogue guests. It also ++ flushes the return stack buffer on every VM exit to prevent a return ++ stack buffer underflow so poisoned branch target buffer could be used, ++ or attacker guests leaving poisoned entries in the return stack buffer. ++ ++ To mitigate guest-to-guest attacks in the same CPU hardware thread, ++ the branch target buffer is sanitized by flushing before switching ++ to a new guest on a CPU. ++ ++ The above mitigations are turned on by default on vulnerable CPUs. ++ ++ To mitigate guest-to-guest attacks from sibling thread when SMT is ++ in use, an untrusted guest running in the sibling thread can have ++ its indirect branch speculation disabled by administrator via prctl(). ++ ++ The kernel also allows guests to use any microcode based mitigation ++ they choose to use (such as IBPB or STIBP on x86) to protect themselves. ++ ++.. _spectre_mitigation_control_command_line: ++ ++Mitigation control on the kernel command line ++--------------------------------------------- ++ ++Spectre variant 2 mitigation can be disabled or force enabled at the ++kernel command line. ++ ++ nospectre_v2 ++ ++ [X86] Disable all mitigations for the Spectre variant 2 ++ (indirect branch prediction) vulnerability. System may ++ allow data leaks with this option, which is equivalent ++ to spectre_v2=off. ++ ++ ++ spectre_v2= ++ ++ [X86] Control mitigation of Spectre variant 2 ++ (indirect branch speculation) vulnerability. ++ The default operation protects the kernel from ++ user space attacks. ++ ++ on ++ unconditionally enable, implies ++ spectre_v2_user=on ++ off ++ unconditionally disable, implies ++ spectre_v2_user=off ++ auto ++ kernel detects whether your CPU model is ++ vulnerable ++ ++ Selecting 'on' will, and 'auto' may, choose a ++ mitigation method at run time according to the ++ CPU, the available microcode, the setting of the ++ CONFIG_RETPOLINE configuration option, and the ++ compiler with which the kernel was built. ++ ++ Selecting 'on' will also enable the mitigation ++ against user space to user space task attacks. ++ ++ Selecting 'off' will disable both the kernel and ++ the user space protections. ++ ++ Specific mitigations can also be selected manually: ++ ++ retpoline ++ replace indirect branches ++ retpoline,generic ++ google's original retpoline ++ retpoline,amd ++ AMD-specific minimal thunk ++ ++ Not specifying this option is equivalent to ++ spectre_v2=auto. ++ ++For user space mitigation: ++ ++ spectre_v2_user= ++ ++ [X86] Control mitigation of Spectre variant 2 ++ (indirect branch speculation) vulnerability between ++ user space tasks ++ ++ on ++ Unconditionally enable mitigations. Is ++ enforced by spectre_v2=on ++ ++ off ++ Unconditionally disable mitigations. Is ++ enforced by spectre_v2=off ++ ++ prctl ++ Indirect branch speculation is enabled, ++ but mitigation can be enabled via prctl ++ per thread. The mitigation control state ++ is inherited on fork. ++ ++ prctl,ibpb ++ Like "prctl" above, but only STIBP is ++ controlled per thread. IBPB is issued ++ always when switching between different user ++ space processes. ++ ++ seccomp ++ Same as "prctl" above, but all seccomp ++ threads will enable the mitigation unless ++ they explicitly opt out. ++ ++ seccomp,ibpb ++ Like "seccomp" above, but only STIBP is ++ controlled per thread. IBPB is issued ++ always when switching between different ++ user space processes. ++ ++ auto ++ Kernel selects the mitigation depending on ++ the available CPU features and vulnerability. ++ ++ Default mitigation: ++ If CONFIG_SECCOMP=y then "seccomp", otherwise "prctl" ++ ++ Not specifying this option is equivalent to ++ spectre_v2_user=auto. ++ ++ In general the kernel by default selects ++ reasonable mitigations for the current CPU. To ++ disable Spectre variant 2 mitigations, boot with ++ spectre_v2=off. Spectre variant 1 mitigations ++ cannot be disabled. ++ ++Mitigation selection guide ++-------------------------- ++ ++1. Trusted userspace ++^^^^^^^^^^^^^^^^^^^^ ++ ++ If all userspace applications are from trusted sources and do not ++ execute externally supplied untrusted code, then the mitigations can ++ be disabled. ++ ++2. Protect sensitive programs ++^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ++ ++ For security-sensitive programs that have secrets (e.g. crypto ++ keys), protection against Spectre variant 2 can be put in place by ++ disabling indirect branch speculation when the program is running ++ (See :ref:`Documentation/userspace-api/spec_ctrl.rst <set_spec_ctrl>`). ++ ++3. Sandbox untrusted programs ++^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ++ ++ Untrusted programs that could be a source of attacks can be cordoned ++ off by disabling their indirect branch speculation when they are run ++ (See :ref:`Documentation/userspace-api/spec_ctrl.rst <set_spec_ctrl>`). ++ This prevents untrusted programs from polluting the branch target ++ buffer. All programs running in SECCOMP sandboxes have indirect ++ branch speculation restricted by default. This behavior can be ++ changed via the kernel command line and sysfs control files. See ++ :ref:`spectre_mitigation_control_command_line`. ++ ++3. High security mode ++^^^^^^^^^^^^^^^^^^^^^ ++ ++ All Spectre variant 2 mitigations can be forced on ++ at boot time for all programs (See the "on" option in ++ :ref:`spectre_mitigation_control_command_line`). This will add ++ overhead as indirect branch speculations for all programs will be ++ restricted. ++ ++ On x86, branch target buffer will be flushed with IBPB when switching ++ to a new program. STIBP is left on all the time to protect programs ++ against variant 2 attacks originating from programs running on ++ sibling threads. ++ ++ Alternatively, STIBP can be used only when running programs ++ whose indirect branch speculation is explicitly disabled, ++ while IBPB is still used all the time when switching to a new ++ program to clear the branch target buffer (See "ibpb" option in ++ :ref:`spectre_mitigation_control_command_line`). This "ibpb" option ++ has less performance cost than the "on" option, which leaves STIBP ++ on all the time. ++ ++References on Spectre ++--------------------- ++ ++Intel white papers: ++ ++.. _spec_ref1: ++ ++[1] `Intel analysis of speculative execution side channels <https://newsroom.intel.com/wp-content/uploads/sites/11/2018/01/Intel-Analysis-of-Speculative-Execution-Side-Channels.pdf>`_. ++ ++.. _spec_ref2: ++ ++[2] `Bounds check bypass <https://software.intel.com/security-software-guidance/software-guidance/bounds-check-bypass>`_. ++ ++.. _spec_ref3: ++ ++[3] `Deep dive: Retpoline: A branch target injection mitigation <https://software.intel.com/security-software-guidance/insights/deep-dive-retpoline-branch-target-injection-mitigation>`_. ++ ++.. _spec_ref4: ++ ++[4] `Deep Dive: Single Thread Indirect Branch Predictors <https://software.intel.com/security-software-guidance/insights/deep-dive-single-thread-indirect-branch-predictors>`_. ++ ++AMD white papers: ++ ++.. _spec_ref5: ++ ++[5] `AMD64 technology indirect branch control extension <https://developer.amd.com/wp-content/resources/Architecture_Guidelines_Update_Indirect_Branch_Control.pdf>`_. ++ ++.. _spec_ref6: ++ ++[6] `Software techniques for managing speculation on AMD processors <https://developer.amd.com/wp-content/resources/90343-B_SoftwareTechniquesforManagingSpeculation_WP_7-18Update_FNL.pdf>`_. ++ ++ARM white papers: ++ ++.. _spec_ref7: ++ ++[7] `Cache speculation side-channels <https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability/download-the-whitepaper>`_. ++ ++.. _spec_ref8: ++ ++[8] `Cache speculation issues update <https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability/latest-updates/cache-speculation-issues-update>`_. ++ ++Google white paper: ++ ++.. _spec_ref9: ++ ++[9] `Retpoline: a software construct for preventing branch-target-injection <https://support.google.com/faqs/answer/7625886>`_. ++ ++MIPS white paper: ++ ++.. _spec_ref10: ++ ++[10] `MIPS: response on speculative execution and side channel vulnerabilities <https://www.mips.com/blog/mips-response-on-speculative-execution-and-side-channel-vulnerabilities/>`_. ++ ++Academic papers: ++ ++.. _spec_ref11: ++ ++[11] `Spectre Attacks: Exploiting Speculative Execution <https://spectreattack.com/spectre.pdf>`_. ++ ++.. _spec_ref12: ++ ++[12] `NetSpectre: Read Arbitrary Memory over Network <https://arxiv.org/abs/1807.10535>`_. ++ ++.. _spec_ref13: ++ ++[13] `Spectre Returns! Speculation Attacks using the Return Stack Buffer <https://www.usenix.org/system/files/conference/woot18/woot18-paper-koruyeh.pdf>`_. +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index a29301d6e6c6..1cee1174cde6 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -4976,12 +4976,6 @@ + emulate [default] Vsyscalls turn into traps and are + emulated reasonably safely. + +- native Vsyscalls are native syscall instructions. +- This is a little bit faster than trapping +- and makes a few dynamic recompilers work +- better than they would in emulation mode. +- It also makes exploits much easier to write. +- + none Vsyscalls don't work at all. This makes + them quite hard to use for exploits but + might break your system. +diff --git a/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt b/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt +index 188c8bd4eb67..5a0111d4de58 100644 +--- a/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt ++++ b/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt +@@ -4,6 +4,7 @@ Required properties: + - compatible: Should be one of the following: + - "microchip,mcp2510" for MCP2510. + - "microchip,mcp2515" for MCP2515. ++ - "microchip,mcp25625" for MCP25625. + - reg: SPI chip select. + - clocks: The clock feeding the CAN controller. + - interrupts: Should contain IRQ line for the CAN controller. +diff --git a/Documentation/userspace-api/spec_ctrl.rst b/Documentation/userspace-api/spec_ctrl.rst +index c4dbe6f7cdae..0fda8f614110 100644 +--- a/Documentation/userspace-api/spec_ctrl.rst ++++ b/Documentation/userspace-api/spec_ctrl.rst +@@ -47,6 +47,8 @@ If PR_SPEC_PRCTL is set, then the per-task control of the mitigation is + available. If not set, prctl(PR_SET_SPECULATION_CTRL) for the speculation + misfeature will fail. + ++.. _set_spec_ctrl: ++ + PR_SET_SPECULATION_CTRL + ----------------------- + +diff --git a/Makefile b/Makefile +index 5dcd01cd1bf6..38f2150457fd 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 4 + PATCHLEVEL = 19 +-SUBLEVEL = 58 ++SUBLEVEL = 59 + EXTRAVERSION = + NAME = "People's Front" + +diff --git a/arch/arm/boot/dts/am335x-pcm-953.dtsi b/arch/arm/boot/dts/am335x-pcm-953.dtsi +index 1ec8e0d80191..572fbd254690 100644 +--- a/arch/arm/boot/dts/am335x-pcm-953.dtsi ++++ b/arch/arm/boot/dts/am335x-pcm-953.dtsi +@@ -197,7 +197,7 @@ + bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; +- cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; ++ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + status = "okay"; + }; + +diff --git a/arch/arm/boot/dts/am335x-wega.dtsi b/arch/arm/boot/dts/am335x-wega.dtsi +index 8ce541739b24..83e4fe595e37 100644 +--- a/arch/arm/boot/dts/am335x-wega.dtsi ++++ b/arch/arm/boot/dts/am335x-wega.dtsi +@@ -157,7 +157,7 @@ + bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; +- cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; ++ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + status = "okay"; + }; + +diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c +index e1a949b47306..774a3e535ad0 100644 +--- a/arch/arm/mach-davinci/board-da850-evm.c ++++ b/arch/arm/mach-davinci/board-da850-evm.c +@@ -1472,6 +1472,8 @@ static __init void da850_evm_init(void) + if (ret) + pr_warn("%s: dsp/rproc registration failed: %d\n", + __func__, ret); ++ ++ regulator_has_full_constraints(); + } + + #ifdef CONFIG_SERIAL_8250_CONSOLE +diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c +index 1fd3619f6a09..3c42bf9fa061 100644 +--- a/arch/arm/mach-davinci/devices-da8xx.c ++++ b/arch/arm/mach-davinci/devices-da8xx.c +@@ -685,6 +685,9 @@ static struct platform_device da8xx_lcdc_device = { + .id = 0, + .num_resources = ARRAY_SIZE(da8xx_lcdc_resources), + .resource = da8xx_lcdc_resources, ++ .dev = { ++ .coherent_dma_mask = DMA_BIT_MASK(32), ++ } + }; + + int __init da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata) +diff --git a/arch/mips/include/uapi/asm/sgidefs.h b/arch/mips/include/uapi/asm/sgidefs.h +index 26143e3b7c26..69c3de90c536 100644 +--- a/arch/mips/include/uapi/asm/sgidefs.h ++++ b/arch/mips/include/uapi/asm/sgidefs.h +@@ -11,14 +11,6 @@ + #ifndef __ASM_SGIDEFS_H + #define __ASM_SGIDEFS_H + +-/* +- * Using a Linux compiler for building Linux seems logic but not to +- * everybody. +- */ +-#ifndef __linux__ +-#error Use a Linux compiler or give up. +-#endif +- + /* + * Definitions for the ISA levels + * +diff --git a/arch/riscv/lib/delay.c b/arch/riscv/lib/delay.c +index dce8ae24c6d3..ee6853c1e341 100644 +--- a/arch/riscv/lib/delay.c ++++ b/arch/riscv/lib/delay.c +@@ -88,7 +88,7 @@ EXPORT_SYMBOL(__delay); + + void udelay(unsigned long usecs) + { +- unsigned long ucycles = usecs * lpj_fine * UDELAY_MULT; ++ u64 ucycles = (u64)usecs * lpj_fine * UDELAY_MULT; + + if (unlikely(usecs > MAX_UDELAY_US)) { + __delay((u64)usecs * riscv_timebase / 1000000ULL); +diff --git a/arch/s390/Makefile b/arch/s390/Makefile +index ee65185bbc80..e6c2e8925fef 100644 +--- a/arch/s390/Makefile ++++ b/arch/s390/Makefile +@@ -24,6 +24,7 @@ KBUILD_CFLAGS_DECOMPRESSOR += -DDISABLE_BRANCH_PROFILING -D__NO_FORTIFY + KBUILD_CFLAGS_DECOMPRESSOR += -fno-delete-null-pointer-checks -msoft-float + KBUILD_CFLAGS_DECOMPRESSOR += -fno-asynchronous-unwind-tables + KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-option,-ffreestanding) ++KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, address-of-packed-member) + KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),-g) + KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,)) + UTS_MACHINE := s390x +diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c +index e2ee403865eb..aeba77881d85 100644 +--- a/arch/x86/kernel/ptrace.c ++++ b/arch/x86/kernel/ptrace.c +@@ -24,6 +24,7 @@ + #include <linux/rcupdate.h> + #include <linux/export.h> + #include <linux/context_tracking.h> ++#include <linux/nospec.h> + + #include <linux/uaccess.h> + #include <asm/pgtable.h> +@@ -651,9 +652,11 @@ static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n) + { + struct thread_struct *thread = &tsk->thread; + unsigned long val = 0; ++ int index = n; + + if (n < HBP_NUM) { +- struct perf_event *bp = thread->ptrace_bps[n]; ++ struct perf_event *bp = thread->ptrace_bps[index]; ++ index = array_index_nospec(index, HBP_NUM); + + if (bp) + val = bp->hw.info.address; +diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c +index a5b802a12212..71d3fef1edc9 100644 +--- a/arch/x86/kernel/tls.c ++++ b/arch/x86/kernel/tls.c +@@ -5,6 +5,7 @@ + #include <linux/user.h> + #include <linux/regset.h> + #include <linux/syscalls.h> ++#include <linux/nospec.h> + + #include <linux/uaccess.h> + #include <asm/desc.h> +@@ -220,6 +221,7 @@ int do_get_thread_area(struct task_struct *p, int idx, + struct user_desc __user *u_info) + { + struct user_desc info; ++ int index; + + if (idx == -1 && get_user(idx, &u_info->entry_number)) + return -EFAULT; +@@ -227,8 +229,11 @@ int do_get_thread_area(struct task_struct *p, int idx, + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) + return -EINVAL; + +- fill_user_desc(&info, idx, +- &p->thread.tls_array[idx - GDT_ENTRY_TLS_MIN]); ++ index = idx - GDT_ENTRY_TLS_MIN; ++ index = array_index_nospec(index, ++ GDT_ENTRY_TLS_MAX - GDT_ENTRY_TLS_MIN + 1); ++ ++ fill_user_desc(&info, idx, &p->thread.tls_array[index]); + + if (copy_to_user(u_info, &info, sizeof(info))) + return -EFAULT; +diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c +index 2580cd2e98b1..a32fc3d99407 100644 +--- a/arch/x86/net/bpf_jit_comp.c ++++ b/arch/x86/net/bpf_jit_comp.c +@@ -190,9 +190,7 @@ struct jit_context { + #define BPF_MAX_INSN_SIZE 128 + #define BPF_INSN_SAFETY 64 + +-#define AUX_STACK_SPACE 40 /* Space for RBX, R13, R14, R15, tailcnt */ +- +-#define PROLOGUE_SIZE 37 ++#define PROLOGUE_SIZE 20 + + /* + * Emit x86-64 prologue code for BPF program and check its size. +@@ -203,44 +201,19 @@ static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf) + u8 *prog = *pprog; + int cnt = 0; + +- /* push rbp */ +- EMIT1(0x55); +- +- /* mov rbp,rsp */ +- EMIT3(0x48, 0x89, 0xE5); +- +- /* sub rsp, rounded_stack_depth + AUX_STACK_SPACE */ +- EMIT3_off32(0x48, 0x81, 0xEC, +- round_up(stack_depth, 8) + AUX_STACK_SPACE); +- +- /* sub rbp, AUX_STACK_SPACE */ +- EMIT4(0x48, 0x83, 0xED, AUX_STACK_SPACE); +- +- /* mov qword ptr [rbp+0],rbx */ +- EMIT4(0x48, 0x89, 0x5D, 0); +- /* mov qword ptr [rbp+8],r13 */ +- EMIT4(0x4C, 0x89, 0x6D, 8); +- /* mov qword ptr [rbp+16],r14 */ +- EMIT4(0x4C, 0x89, 0x75, 16); +- /* mov qword ptr [rbp+24],r15 */ +- EMIT4(0x4C, 0x89, 0x7D, 24); +- ++ EMIT1(0x55); /* push rbp */ ++ EMIT3(0x48, 0x89, 0xE5); /* mov rbp, rsp */ ++ /* sub rsp, rounded_stack_depth */ ++ EMIT3_off32(0x48, 0x81, 0xEC, round_up(stack_depth, 8)); ++ EMIT1(0x53); /* push rbx */ ++ EMIT2(0x41, 0x55); /* push r13 */ ++ EMIT2(0x41, 0x56); /* push r14 */ ++ EMIT2(0x41, 0x57); /* push r15 */ + if (!ebpf_from_cbpf) { +- /* +- * Clear the tail call counter (tail_call_cnt): for eBPF tail +- * calls we need to reset the counter to 0. It's done in two +- * instructions, resetting RAX register to 0, and moving it +- * to the counter location. +- */ +- +- /* xor eax, eax */ +- EMIT2(0x31, 0xc0); +- /* mov qword ptr [rbp+32], rax */ +- EMIT4(0x48, 0x89, 0x45, 32); +- ++ /* zero init tail_call_cnt */ ++ EMIT2(0x6a, 0x00); + BUILD_BUG_ON(cnt != PROLOGUE_SIZE); + } +- + *pprog = prog; + } + +@@ -285,13 +258,13 @@ static void emit_bpf_tail_call(u8 **pprog) + * if (tail_call_cnt > MAX_TAIL_CALL_CNT) + * goto out; + */ +- EMIT2_off32(0x8B, 0x85, 36); /* mov eax, dword ptr [rbp + 36] */ ++ EMIT2_off32(0x8B, 0x85, -36 - MAX_BPF_STACK); /* mov eax, dword ptr [rbp - 548] */ + EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */ + #define OFFSET2 (30 + RETPOLINE_RAX_BPF_JIT_SIZE) + EMIT2(X86_JA, OFFSET2); /* ja out */ + label2 = cnt; + EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */ +- EMIT2_off32(0x89, 0x85, 36); /* mov dword ptr [rbp + 36], eax */ ++ EMIT2_off32(0x89, 0x85, -36 - MAX_BPF_STACK); /* mov dword ptr [rbp -548], eax */ + + /* prog = array->ptrs[index]; */ + EMIT4_off32(0x48, 0x8B, 0x84, 0xD6, /* mov rax, [rsi + rdx * 8 + offsetof(...)] */ +@@ -1006,19 +979,14 @@ emit_jmp: + seen_exit = true; + /* Update cleanup_addr */ + ctx->cleanup_addr = proglen; +- /* mov rbx, qword ptr [rbp+0] */ +- EMIT4(0x48, 0x8B, 0x5D, 0); +- /* mov r13, qword ptr [rbp+8] */ +- EMIT4(0x4C, 0x8B, 0x6D, 8); +- /* mov r14, qword ptr [rbp+16] */ +- EMIT4(0x4C, 0x8B, 0x75, 16); +- /* mov r15, qword ptr [rbp+24] */ +- EMIT4(0x4C, 0x8B, 0x7D, 24); +- +- /* add rbp, AUX_STACK_SPACE */ +- EMIT4(0x48, 0x83, 0xC5, AUX_STACK_SPACE); +- EMIT1(0xC9); /* leave */ +- EMIT1(0xC3); /* ret */ ++ if (!bpf_prog_was_classic(bpf_prog)) ++ EMIT1(0x5B); /* get rid of tail_call_cnt */ ++ EMIT2(0x41, 0x5F); /* pop r15 */ ++ EMIT2(0x41, 0x5E); /* pop r14 */ ++ EMIT2(0x41, 0x5D); /* pop r13 */ ++ EMIT1(0x5B); /* pop rbx */ ++ EMIT1(0xC9); /* leave */ ++ EMIT1(0xC3); /* ret */ + break; + + default: +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +index 6bb397995610..becd793a258c 100644 +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -4116,6 +4116,7 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync) + unsigned long flags; + + spin_lock_irqsave(&bfqd->lock, flags); ++ bfqq->bic = NULL; + bfq_exit_bfqq(bfqd, bfqq); + bic_set_bfqq(bic, NULL, is_sync); + spin_unlock_irqrestore(&bfqd->lock, flags); +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index ce0e4d317d24..5d67f5fec6c1 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -3936,6 +3936,8 @@ retry: + case BINDER_WORK_TRANSACTION_COMPLETE: { + binder_inner_proc_unlock(proc); + cmd = BR_TRANSACTION_COMPLETE; ++ kfree(w); ++ binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); + if (put_user(cmd, (uint32_t __user *)ptr)) + return -EFAULT; + ptr += sizeof(uint32_t); +@@ -3944,8 +3946,6 @@ retry: + binder_debug(BINDER_DEBUG_TRANSACTION_COMPLETE, + "%d:%d BR_TRANSACTION_COMPLETE\n", + proc->pid, thread->pid); +- kfree(w); +- binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); + } break; + case BINDER_WORK_NODE: { + struct binder_node *node = container_of(w, struct binder_node, work); +diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c +index f4f3e9a5851e..c5859d3cb825 100644 +--- a/drivers/crypto/talitos.c ++++ b/drivers/crypto/talitos.c +@@ -2286,7 +2286,7 @@ static struct talitos_alg_template driver_algs[] = { + .base = { + .cra_name = "authenc(hmac(sha1),cbc(aes))", + .cra_driver_name = "authenc-hmac-sha1-" +- "cbc-aes-talitos", ++ "cbc-aes-talitos-hsna", + .cra_blocksize = AES_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_ASYNC, + }, +@@ -2330,7 +2330,7 @@ static struct talitos_alg_template driver_algs[] = { + .cra_name = "authenc(hmac(sha1)," + "cbc(des3_ede))", + .cra_driver_name = "authenc-hmac-sha1-" +- "cbc-3des-talitos", ++ "cbc-3des-talitos-hsna", + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_ASYNC, + }, +@@ -2372,7 +2372,7 @@ static struct talitos_alg_template driver_algs[] = { + .base = { + .cra_name = "authenc(hmac(sha224),cbc(aes))", + .cra_driver_name = "authenc-hmac-sha224-" +- "cbc-aes-talitos", ++ "cbc-aes-talitos-hsna", + .cra_blocksize = AES_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_ASYNC, + }, +@@ -2416,7 +2416,7 @@ static struct talitos_alg_template driver_algs[] = { + .cra_name = "authenc(hmac(sha224)," + "cbc(des3_ede))", + .cra_driver_name = "authenc-hmac-sha224-" +- "cbc-3des-talitos", ++ "cbc-3des-talitos-hsna", + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_ASYNC, + }, +@@ -2458,7 +2458,7 @@ static struct talitos_alg_template driver_algs[] = { + .base = { + .cra_name = "authenc(hmac(sha256),cbc(aes))", + .cra_driver_name = "authenc-hmac-sha256-" +- "cbc-aes-talitos", ++ "cbc-aes-talitos-hsna", + .cra_blocksize = AES_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_ASYNC, + }, +@@ -2502,7 +2502,7 @@ static struct talitos_alg_template driver_algs[] = { + .cra_name = "authenc(hmac(sha256)," + "cbc(des3_ede))", + .cra_driver_name = "authenc-hmac-sha256-" +- "cbc-3des-talitos", ++ "cbc-3des-talitos-hsna", + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_ASYNC, + }, +@@ -2628,7 +2628,7 @@ static struct talitos_alg_template driver_algs[] = { + .base = { + .cra_name = "authenc(hmac(md5),cbc(aes))", + .cra_driver_name = "authenc-hmac-md5-" +- "cbc-aes-talitos", ++ "cbc-aes-talitos-hsna", + .cra_blocksize = AES_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_ASYNC, + }, +@@ -2670,7 +2670,7 @@ static struct talitos_alg_template driver_algs[] = { + .base = { + .cra_name = "authenc(hmac(md5),cbc(des3_ede))", + .cra_driver_name = "authenc-hmac-md5-" +- "cbc-3des-talitos", ++ "cbc-3des-talitos-hsna", + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_ASYNC, + }, +diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c +index e2f775d1c112..21bec4548092 100644 +--- a/drivers/gpu/drm/drm_bufs.c ++++ b/drivers/gpu/drm/drm_bufs.c +@@ -1321,7 +1321,10 @@ static int copy_one_buf(void *data, int count, struct drm_buf_entry *from) + .size = from->buf_size, + .low_mark = from->low_mark, + .high_mark = from->high_mark}; +- return copy_to_user(to, &v, offsetof(struct drm_buf_desc, flags)); ++ ++ if (copy_to_user(to, &v, offsetof(struct drm_buf_desc, flags))) ++ return -EFAULT; ++ return 0; + } + + int drm_legacy_infobufs(struct drm_device *dev, void *data, +diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c +index 67b1fca39aa6..138680b37c70 100644 +--- a/drivers/gpu/drm/drm_ioc32.c ++++ b/drivers/gpu/drm/drm_ioc32.c +@@ -372,7 +372,10 @@ static int copy_one_buf32(void *data, int count, struct drm_buf_entry *from) + .size = from->buf_size, + .low_mark = from->low_mark, + .high_mark = from->high_mark}; +- return copy_to_user(to + count, &v, offsetof(drm_buf_desc32_t, flags)); ++ ++ if (copy_to_user(to + count, &v, offsetof(drm_buf_desc32_t, flags))) ++ return -EFAULT; ++ return 0; + } + + static int drm_legacy_infobufs32(struct drm_device *dev, void *data, +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +index 82ae68716696..05a800807c26 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +@@ -789,6 +789,9 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) + if (unlikely(ret != 0)) + goto out_err0; + ++ dma_set_max_seg_size(dev->dev, min_t(unsigned int, U32_MAX & PAGE_MASK, ++ SCATTERLIST_MAX_SEGMENT)); ++ + if (dev_priv->capabilities & SVGA_CAP_GMR2) { + DRM_INFO("Max GMR ids is %u\n", + (unsigned)dev_priv->max_gmr_ids); +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +index 31786b200afc..f388ad51e72b 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +@@ -448,11 +448,11 @@ static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt) + if (unlikely(ret != 0)) + return ret; + +- ret = sg_alloc_table_from_pages(&vmw_tt->sgt, vsgt->pages, +- vsgt->num_pages, 0, +- (unsigned long) +- vsgt->num_pages << PAGE_SHIFT, +- GFP_KERNEL); ++ ret = __sg_alloc_table_from_pages ++ (&vmw_tt->sgt, vsgt->pages, vsgt->num_pages, 0, ++ (unsigned long) vsgt->num_pages << PAGE_SHIFT, ++ dma_get_max_seg_size(dev_priv->dev->dev), ++ GFP_KERNEL); + if (unlikely(ret != 0)) + goto out_sg_alloc_fail; + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 97d33b8ed36c..92452992b368 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -1212,6 +1212,7 @@ + #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 + #define USB_DEVICE_ID_PRIMAX_REZEL 0x4e72 + #define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F 0x4d0f ++#define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D65 0x4d65 + #define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22 0x4e22 + + +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index e24790c988c0..5892f1bd037e 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -131,6 +131,7 @@ static const struct hid_device_id hid_quirks[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F), HID_QUIRK_ALWAYS_POLL }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D65), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS), HID_QUIRK_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001), HID_QUIRK_NOGET }, +diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c +index 539cb670de41..ae9c51cc85f9 100644 +--- a/drivers/input/keyboard/imx_keypad.c ++++ b/drivers/input/keyboard/imx_keypad.c +@@ -526,11 +526,12 @@ static int imx_keypad_probe(struct platform_device *pdev) + return 0; + } + +-static int __maybe_unused imx_kbd_suspend(struct device *dev) ++static int __maybe_unused imx_kbd_noirq_suspend(struct device *dev) + { + struct platform_device *pdev = to_platform_device(dev); + struct imx_keypad *kbd = platform_get_drvdata(pdev); + struct input_dev *input_dev = kbd->input_dev; ++ unsigned short reg_val = readw(kbd->mmio_base + KPSR); + + /* imx kbd can wake up system even clock is disabled */ + mutex_lock(&input_dev->mutex); +@@ -540,13 +541,20 @@ static int __maybe_unused imx_kbd_suspend(struct device *dev) + + mutex_unlock(&input_dev->mutex); + +- if (device_may_wakeup(&pdev->dev)) ++ if (device_may_wakeup(&pdev->dev)) { ++ if (reg_val & KBD_STAT_KPKD) ++ reg_val |= KBD_STAT_KRIE; ++ if (reg_val & KBD_STAT_KPKR) ++ reg_val |= KBD_STAT_KDIE; ++ writew(reg_val, kbd->mmio_base + KPSR); ++ + enable_irq_wake(kbd->irq); ++ } + + return 0; + } + +-static int __maybe_unused imx_kbd_resume(struct device *dev) ++static int __maybe_unused imx_kbd_noirq_resume(struct device *dev) + { + struct platform_device *pdev = to_platform_device(dev); + struct imx_keypad *kbd = platform_get_drvdata(pdev); +@@ -570,7 +578,9 @@ err_clk: + return ret; + } + +-static SIMPLE_DEV_PM_OPS(imx_kbd_pm_ops, imx_kbd_suspend, imx_kbd_resume); ++static const struct dev_pm_ops imx_kbd_pm_ops = { ++ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_kbd_noirq_suspend, imx_kbd_noirq_resume) ++}; + + static struct platform_driver imx_keypad_driver = { + .driver = { +diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c +index a7f8b1614559..530142b5a115 100644 +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1189,6 +1189,8 @@ static const char * const middle_button_pnp_ids[] = { + "LEN2132", /* ThinkPad P52 */ + "LEN2133", /* ThinkPad P72 w/ NFC */ + "LEN2134", /* ThinkPad P72 */ ++ "LEN0407", ++ "LEN0408", + NULL + }; + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index b924f62e2cd5..fb5d702e43b5 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -7625,9 +7625,9 @@ static void status_unused(struct seq_file *seq) + static int status_resync(struct seq_file *seq, struct mddev *mddev) + { + sector_t max_sectors, resync, res; +- unsigned long dt, db; +- sector_t rt; +- int scale; ++ unsigned long dt, db = 0; ++ sector_t rt, curr_mark_cnt, resync_mark_cnt; ++ int scale, recovery_active; + unsigned int per_milli; + + if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) || +@@ -7716,22 +7716,30 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev) + * db: blocks written from mark until now + * rt: remaining time + * +- * rt is a sector_t, so could be 32bit or 64bit. +- * So we divide before multiply in case it is 32bit and close +- * to the limit. +- * We scale the divisor (db) by 32 to avoid losing precision +- * near the end of resync when the number of remaining sectors +- * is close to 'db'. +- * We then divide rt by 32 after multiplying by db to compensate. +- * The '+1' avoids division by zero if db is very small. ++ * rt is a sector_t, which is always 64bit now. We are keeping ++ * the original algorithm, but it is not really necessary. ++ * ++ * Original algorithm: ++ * So we divide before multiply in case it is 32bit and close ++ * to the limit. ++ * We scale the divisor (db) by 32 to avoid losing precision ++ * near the end of resync when the number of remaining sectors ++ * is close to 'db'. ++ * We then divide rt by 32 after multiplying by db to compensate. ++ * The '+1' avoids division by zero if db is very small. + */ + dt = ((jiffies - mddev->resync_mark) / HZ); + if (!dt) dt++; +- db = (mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active)) +- - mddev->resync_mark_cnt; ++ ++ curr_mark_cnt = mddev->curr_mark_cnt; ++ recovery_active = atomic_read(&mddev->recovery_active); ++ resync_mark_cnt = mddev->resync_mark_cnt; ++ ++ if (curr_mark_cnt >= (recovery_active + resync_mark_cnt)) ++ db = curr_mark_cnt - (recovery_active + resync_mark_cnt); + + rt = max_sectors - resync; /* number of remaining sectors */ +- sector_div(rt, db/32+1); ++ rt = div64_u64(rt, db/32+1); + rt *= dt; + rt >>= 5; + +diff --git a/drivers/media/dvb-frontends/stv0297.c b/drivers/media/dvb-frontends/stv0297.c +index 9a9915f71483..3ef31a3a27ff 100644 +--- a/drivers/media/dvb-frontends/stv0297.c ++++ b/drivers/media/dvb-frontends/stv0297.c +@@ -694,7 +694,7 @@ static const struct dvb_frontend_ops stv0297_ops = { + .delsys = { SYS_DVBC_ANNEX_A }, + .info = { + .name = "ST STV0297 DVB-C", +- .frequency_min_hz = 470 * MHz, ++ .frequency_min_hz = 47 * MHz, + .frequency_max_hz = 862 * MHz, + .frequency_stepsize_hz = 62500, + .symbol_rate_min = 870000, +diff --git a/drivers/misc/lkdtm/Makefile b/drivers/misc/lkdtm/Makefile +index 3370a4138e94..cce47a15a79f 100644 +--- a/drivers/misc/lkdtm/Makefile ++++ b/drivers/misc/lkdtm/Makefile +@@ -13,8 +13,7 @@ KCOV_INSTRUMENT_rodata.o := n + + OBJCOPYFLAGS := + OBJCOPYFLAGS_rodata_objcopy.o := \ +- --set-section-flags .text=alloc,readonly \ +- --rename-section .text=.rodata ++ --rename-section .text=.rodata,alloc,readonly,load + targets += rodata.o rodata_objcopy.o + $(obj)/rodata_objcopy.o: $(obj)/rodata.o FORCE + $(call if_changed,objcopy) +diff --git a/drivers/misc/vmw_vmci/vmci_context.c b/drivers/misc/vmw_vmci/vmci_context.c +index 21d0fa592145..bc089e634a75 100644 +--- a/drivers/misc/vmw_vmci/vmci_context.c ++++ b/drivers/misc/vmw_vmci/vmci_context.c +@@ -29,6 +29,9 @@ + #include "vmci_driver.h" + #include "vmci_event.h" + ++/* Use a wide upper bound for the maximum contexts. */ ++#define VMCI_MAX_CONTEXTS 2000 ++ + /* + * List of current VMCI contexts. Contexts can be added by + * vmci_ctx_create() and removed via vmci_ctx_destroy(). +@@ -125,19 +128,22 @@ struct vmci_ctx *vmci_ctx_create(u32 cid, u32 priv_flags, + /* Initialize host-specific VMCI context. */ + init_waitqueue_head(&context->host_context.wait_queue); + +- context->queue_pair_array = vmci_handle_arr_create(0); ++ context->queue_pair_array = ++ vmci_handle_arr_create(0, VMCI_MAX_GUEST_QP_COUNT); + if (!context->queue_pair_array) { + error = -ENOMEM; + goto err_free_ctx; + } + +- context->doorbell_array = vmci_handle_arr_create(0); ++ context->doorbell_array = ++ vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT); + if (!context->doorbell_array) { + error = -ENOMEM; + goto err_free_qp_array; + } + +- context->pending_doorbell_array = vmci_handle_arr_create(0); ++ context->pending_doorbell_array = ++ vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT); + if (!context->pending_doorbell_array) { + error = -ENOMEM; + goto err_free_db_array; +@@ -212,7 +218,7 @@ static int ctx_fire_notification(u32 context_id, u32 priv_flags) + * We create an array to hold the subscribers we find when + * scanning through all contexts. + */ +- subscriber_array = vmci_handle_arr_create(0); ++ subscriber_array = vmci_handle_arr_create(0, VMCI_MAX_CONTEXTS); + if (subscriber_array == NULL) + return VMCI_ERROR_NO_MEM; + +@@ -631,20 +637,26 @@ int vmci_ctx_add_notification(u32 context_id, u32 remote_cid) + + spin_lock(&context->lock); + +- list_for_each_entry(n, &context->notifier_list, node) { +- if (vmci_handle_is_equal(n->handle, notifier->handle)) { +- exists = true; +- break; ++ if (context->n_notifiers < VMCI_MAX_CONTEXTS) { ++ list_for_each_entry(n, &context->notifier_list, node) { ++ if (vmci_handle_is_equal(n->handle, notifier->handle)) { ++ exists = true; ++ break; ++ } + } +- } + +- if (exists) { +- kfree(notifier); +- result = VMCI_ERROR_ALREADY_EXISTS; ++ if (exists) { ++ kfree(notifier); ++ result = VMCI_ERROR_ALREADY_EXISTS; ++ } else { ++ list_add_tail_rcu(¬ifier->node, ++ &context->notifier_list); ++ context->n_notifiers++; ++ result = VMCI_SUCCESS; ++ } + } else { +- list_add_tail_rcu(¬ifier->node, &context->notifier_list); +- context->n_notifiers++; +- result = VMCI_SUCCESS; ++ kfree(notifier); ++ result = VMCI_ERROR_NO_MEM; + } + + spin_unlock(&context->lock); +@@ -729,8 +741,7 @@ static int vmci_ctx_get_chkpt_doorbells(struct vmci_ctx *context, + u32 *buf_size, void **pbuf) + { + struct dbell_cpt_state *dbells; +- size_t n_doorbells; +- int i; ++ u32 i, n_doorbells; + + n_doorbells = vmci_handle_arr_get_size(context->doorbell_array); + if (n_doorbells > 0) { +@@ -868,7 +879,8 @@ int vmci_ctx_rcv_notifications_get(u32 context_id, + spin_lock(&context->lock); + + *db_handle_array = context->pending_doorbell_array; +- context->pending_doorbell_array = vmci_handle_arr_create(0); ++ context->pending_doorbell_array = ++ vmci_handle_arr_create(0, VMCI_MAX_GUEST_DOORBELL_COUNT); + if (!context->pending_doorbell_array) { + context->pending_doorbell_array = *db_handle_array; + *db_handle_array = NULL; +@@ -950,12 +962,11 @@ int vmci_ctx_dbell_create(u32 context_id, struct vmci_handle handle) + return VMCI_ERROR_NOT_FOUND; + + spin_lock(&context->lock); +- if (!vmci_handle_arr_has_entry(context->doorbell_array, handle)) { +- vmci_handle_arr_append_entry(&context->doorbell_array, handle); +- result = VMCI_SUCCESS; +- } else { ++ if (!vmci_handle_arr_has_entry(context->doorbell_array, handle)) ++ result = vmci_handle_arr_append_entry(&context->doorbell_array, ++ handle); ++ else + result = VMCI_ERROR_DUPLICATE_ENTRY; +- } + + spin_unlock(&context->lock); + vmci_ctx_put(context); +@@ -1091,15 +1102,16 @@ int vmci_ctx_notify_dbell(u32 src_cid, + if (!vmci_handle_arr_has_entry( + dst_context->pending_doorbell_array, + handle)) { +- vmci_handle_arr_append_entry( ++ result = vmci_handle_arr_append_entry( + &dst_context->pending_doorbell_array, + handle); +- +- ctx_signal_notify(dst_context); +- wake_up(&dst_context->host_context.wait_queue); +- ++ if (result == VMCI_SUCCESS) { ++ ctx_signal_notify(dst_context); ++ wake_up(&dst_context->host_context.wait_queue); ++ } ++ } else { ++ result = VMCI_SUCCESS; + } +- result = VMCI_SUCCESS; + } + spin_unlock(&dst_context->lock); + } +@@ -1126,13 +1138,11 @@ int vmci_ctx_qp_create(struct vmci_ctx *context, struct vmci_handle handle) + if (context == NULL || vmci_handle_is_invalid(handle)) + return VMCI_ERROR_INVALID_ARGS; + +- if (!vmci_handle_arr_has_entry(context->queue_pair_array, handle)) { +- vmci_handle_arr_append_entry(&context->queue_pair_array, +- handle); +- result = VMCI_SUCCESS; +- } else { ++ if (!vmci_handle_arr_has_entry(context->queue_pair_array, handle)) ++ result = vmci_handle_arr_append_entry( ++ &context->queue_pair_array, handle); ++ else + result = VMCI_ERROR_DUPLICATE_ENTRY; +- } + + return result; + } +diff --git a/drivers/misc/vmw_vmci/vmci_handle_array.c b/drivers/misc/vmw_vmci/vmci_handle_array.c +index 344973a0fb0a..917e18a8af95 100644 +--- a/drivers/misc/vmw_vmci/vmci_handle_array.c ++++ b/drivers/misc/vmw_vmci/vmci_handle_array.c +@@ -16,24 +16,29 @@ + #include <linux/slab.h> + #include "vmci_handle_array.h" + +-static size_t handle_arr_calc_size(size_t capacity) ++static size_t handle_arr_calc_size(u32 capacity) + { +- return sizeof(struct vmci_handle_arr) + ++ return VMCI_HANDLE_ARRAY_HEADER_SIZE + + capacity * sizeof(struct vmci_handle); + } + +-struct vmci_handle_arr *vmci_handle_arr_create(size_t capacity) ++struct vmci_handle_arr *vmci_handle_arr_create(u32 capacity, u32 max_capacity) + { + struct vmci_handle_arr *array; + ++ if (max_capacity == 0 || capacity > max_capacity) ++ return NULL; ++ + if (capacity == 0) +- capacity = VMCI_HANDLE_ARRAY_DEFAULT_SIZE; ++ capacity = min((u32)VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY, ++ max_capacity); + + array = kmalloc(handle_arr_calc_size(capacity), GFP_ATOMIC); + if (!array) + return NULL; + + array->capacity = capacity; ++ array->max_capacity = max_capacity; + array->size = 0; + + return array; +@@ -44,27 +49,34 @@ void vmci_handle_arr_destroy(struct vmci_handle_arr *array) + kfree(array); + } + +-void vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, +- struct vmci_handle handle) ++int vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, ++ struct vmci_handle handle) + { + struct vmci_handle_arr *array = *array_ptr; + + if (unlikely(array->size >= array->capacity)) { + /* reallocate. */ + struct vmci_handle_arr *new_array; +- size_t new_capacity = array->capacity * VMCI_ARR_CAP_MULT; +- size_t new_size = handle_arr_calc_size(new_capacity); ++ u32 capacity_bump = min(array->max_capacity - array->capacity, ++ array->capacity); ++ size_t new_size = handle_arr_calc_size(array->capacity + ++ capacity_bump); ++ ++ if (array->size >= array->max_capacity) ++ return VMCI_ERROR_NO_MEM; + + new_array = krealloc(array, new_size, GFP_ATOMIC); + if (!new_array) +- return; ++ return VMCI_ERROR_NO_MEM; + +- new_array->capacity = new_capacity; ++ new_array->capacity += capacity_bump; + *array_ptr = array = new_array; + } + + array->entries[array->size] = handle; + array->size++; ++ ++ return VMCI_SUCCESS; + } + + /* +@@ -74,7 +86,7 @@ struct vmci_handle vmci_handle_arr_remove_entry(struct vmci_handle_arr *array, + struct vmci_handle entry_handle) + { + struct vmci_handle handle = VMCI_INVALID_HANDLE; +- size_t i; ++ u32 i; + + for (i = 0; i < array->size; i++) { + if (vmci_handle_is_equal(array->entries[i], entry_handle)) { +@@ -109,7 +121,7 @@ struct vmci_handle vmci_handle_arr_remove_tail(struct vmci_handle_arr *array) + * Handle at given index, VMCI_INVALID_HANDLE if invalid index. + */ + struct vmci_handle +-vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, size_t index) ++vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, u32 index) + { + if (unlikely(index >= array->size)) + return VMCI_INVALID_HANDLE; +@@ -120,7 +132,7 @@ vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, size_t index) + bool vmci_handle_arr_has_entry(const struct vmci_handle_arr *array, + struct vmci_handle entry_handle) + { +- size_t i; ++ u32 i; + + for (i = 0; i < array->size; i++) + if (vmci_handle_is_equal(array->entries[i], entry_handle)) +diff --git a/drivers/misc/vmw_vmci/vmci_handle_array.h b/drivers/misc/vmw_vmci/vmci_handle_array.h +index b5f3a7f98cf1..0fc58597820e 100644 +--- a/drivers/misc/vmw_vmci/vmci_handle_array.h ++++ b/drivers/misc/vmw_vmci/vmci_handle_array.h +@@ -17,32 +17,41 @@ + #define _VMCI_HANDLE_ARRAY_H_ + + #include <linux/vmw_vmci_defs.h> ++#include <linux/limits.h> + #include <linux/types.h> + +-#define VMCI_HANDLE_ARRAY_DEFAULT_SIZE 4 +-#define VMCI_ARR_CAP_MULT 2 /* Array capacity multiplier */ +- + struct vmci_handle_arr { +- size_t capacity; +- size_t size; ++ u32 capacity; ++ u32 max_capacity; ++ u32 size; ++ u32 pad; + struct vmci_handle entries[]; + }; + +-struct vmci_handle_arr *vmci_handle_arr_create(size_t capacity); ++#define VMCI_HANDLE_ARRAY_HEADER_SIZE \ ++ offsetof(struct vmci_handle_arr, entries) ++/* Select a default capacity that results in a 64 byte sized array */ ++#define VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY 6 ++/* Make sure that the max array size can be expressed by a u32 */ ++#define VMCI_HANDLE_ARRAY_MAX_CAPACITY \ ++ ((U32_MAX - VMCI_HANDLE_ARRAY_HEADER_SIZE - 1) / \ ++ sizeof(struct vmci_handle)) ++ ++struct vmci_handle_arr *vmci_handle_arr_create(u32 capacity, u32 max_capacity); + void vmci_handle_arr_destroy(struct vmci_handle_arr *array); +-void vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, +- struct vmci_handle handle); ++int vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, ++ struct vmci_handle handle); + struct vmci_handle vmci_handle_arr_remove_entry(struct vmci_handle_arr *array, + struct vmci_handle + entry_handle); + struct vmci_handle vmci_handle_arr_remove_tail(struct vmci_handle_arr *array); + struct vmci_handle +-vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, size_t index); ++vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, u32 index); + bool vmci_handle_arr_has_entry(const struct vmci_handle_arr *array, + struct vmci_handle entry_handle); + struct vmci_handle *vmci_handle_arr_get_handles(struct vmci_handle_arr *array); + +-static inline size_t vmci_handle_arr_get_size( ++static inline u32 vmci_handle_arr_get_size( + const struct vmci_handle_arr *array) + { + return array->size; +diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c +index 55997cf84b39..f1fe446eee66 100644 +--- a/drivers/mmc/core/mmc.c ++++ b/drivers/mmc/core/mmc.c +@@ -1209,13 +1209,13 @@ static int mmc_select_hs400(struct mmc_card *card) + mmc_set_timing(host, MMC_TIMING_MMC_HS400); + mmc_set_bus_speed(card); + ++ if (host->ops->hs400_complete) ++ host->ops->hs400_complete(host); ++ + err = mmc_switch_status(card); + if (err) + goto out_err; + +- if (host->ops->hs400_complete) +- host->ops->hs400_complete(host); +- + return 0; + + out_err: +diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c +index 9b449400376b..deb274a19ba0 100644 +--- a/drivers/net/can/m_can/m_can.c ++++ b/drivers/net/can/m_can/m_can.c +@@ -822,6 +822,27 @@ static int m_can_poll(struct napi_struct *napi, int quota) + if (!irqstatus) + goto end; + ++ /* Errata workaround for issue "Needless activation of MRAF irq" ++ * During frame reception while the MCAN is in Error Passive state ++ * and the Receive Error Counter has the value MCAN_ECR.REC = 127, ++ * it may happen that MCAN_IR.MRAF is set although there was no ++ * Message RAM access failure. ++ * If MCAN_IR.MRAF is enabled, an interrupt to the Host CPU is generated ++ * The Message RAM Access Failure interrupt routine needs to check ++ * whether MCAN_ECR.RP = ’1’ and MCAN_ECR.REC = 127. ++ * In this case, reset MCAN_IR.MRAF. No further action is required. ++ */ ++ if ((priv->version <= 31) && (irqstatus & IR_MRAF) && ++ (m_can_read(priv, M_CAN_ECR) & ECR_RP)) { ++ struct can_berr_counter bec; ++ ++ __m_can_get_berr_counter(dev, &bec); ++ if (bec.rxerr == 127) { ++ m_can_write(priv, M_CAN_IR, IR_MRAF); ++ irqstatus &= ~IR_MRAF; ++ } ++ } ++ + psr = m_can_read(priv, M_CAN_PSR); + if (irqstatus & IR_ERR_STATE) + work_done += m_can_handle_state_errors(dev, psr); +diff --git a/drivers/net/can/spi/Kconfig b/drivers/net/can/spi/Kconfig +index 8f2e0dd7b756..792e9c6c4a2f 100644 +--- a/drivers/net/can/spi/Kconfig ++++ b/drivers/net/can/spi/Kconfig +@@ -8,9 +8,10 @@ config CAN_HI311X + Driver for the Holt HI311x SPI CAN controllers. + + config CAN_MCP251X +- tristate "Microchip MCP251x SPI CAN controllers" ++ tristate "Microchip MCP251x and MCP25625 SPI CAN controllers" + depends on HAS_DMA + ---help--- +- Driver for the Microchip MCP251x SPI CAN controllers. ++ Driver for the Microchip MCP251x and MCP25625 SPI CAN ++ controllers. + + endmenu +diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c +index e90817608645..da64e71a62ee 100644 +--- a/drivers/net/can/spi/mcp251x.c ++++ b/drivers/net/can/spi/mcp251x.c +@@ -1,5 +1,5 @@ + /* +- * CAN bus driver for Microchip 251x CAN Controller with SPI Interface ++ * CAN bus driver for Microchip 251x/25625 CAN Controller with SPI Interface + * + * MCP2510 support and bug fixes by Christian Pellegrin + * <chripell@evolware.org> +@@ -41,7 +41,7 @@ + * static struct spi_board_info spi_board_info[] = { + * { + * .modalias = "mcp2510", +- * // or "mcp2515" depending on your controller ++ * // "mcp2515" or "mcp25625" depending on your controller + * .platform_data = &mcp251x_info, + * .irq = IRQ_EINT13, + * .max_speed_hz = 2*1000*1000, +@@ -238,6 +238,7 @@ static const struct can_bittiming_const mcp251x_bittiming_const = { + enum mcp251x_model { + CAN_MCP251X_MCP2510 = 0x2510, + CAN_MCP251X_MCP2515 = 0x2515, ++ CAN_MCP251X_MCP25625 = 0x25625, + }; + + struct mcp251x_priv { +@@ -280,7 +281,6 @@ static inline int mcp251x_is_##_model(struct spi_device *spi) \ + } + + MCP251X_IS(2510); +-MCP251X_IS(2515); + + static void mcp251x_clean(struct net_device *net) + { +@@ -639,7 +639,7 @@ static int mcp251x_hw_reset(struct spi_device *spi) + + /* Wait for oscillator startup timer after reset */ + mdelay(MCP251X_OST_DELAY_MS); +- ++ + reg = mcp251x_read_reg(spi, CANSTAT); + if ((reg & CANCTRL_REQOP_MASK) != CANCTRL_REQOP_CONF) + return -ENODEV; +@@ -820,9 +820,8 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) + /* receive buffer 0 */ + if (intf & CANINTF_RX0IF) { + mcp251x_hw_rx(spi, 0); +- /* +- * Free one buffer ASAP +- * (The MCP2515 does this automatically.) ++ /* Free one buffer ASAP ++ * (The MCP2515/25625 does this automatically.) + */ + if (mcp251x_is_2510(spi)) + mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00); +@@ -831,7 +830,7 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) + /* receive buffer 1 */ + if (intf & CANINTF_RX1IF) { + mcp251x_hw_rx(spi, 1); +- /* the MCP2515 does this automatically */ ++ /* The MCP2515/25625 does this automatically. */ + if (mcp251x_is_2510(spi)) + clear_intf |= CANINTF_RX1IF; + } +@@ -1006,6 +1005,10 @@ static const struct of_device_id mcp251x_of_match[] = { + .compatible = "microchip,mcp2515", + .data = (void *)CAN_MCP251X_MCP2515, + }, ++ { ++ .compatible = "microchip,mcp25625", ++ .data = (void *)CAN_MCP251X_MCP25625, ++ }, + { } + }; + MODULE_DEVICE_TABLE(of, mcp251x_of_match); +@@ -1019,6 +1022,10 @@ static const struct spi_device_id mcp251x_id_table[] = { + .name = "mcp2515", + .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2515, + }, ++ { ++ .name = "mcp25625", ++ .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP25625, ++ }, + { } + }; + MODULE_DEVICE_TABLE(spi, mcp251x_id_table); +@@ -1259,5 +1266,5 @@ module_spi_driver(mcp251x_can_driver); + + MODULE_AUTHOR("Chris Elston <celston@katalix.com>, " + "Christian Pellegrin <chripell@evolware.org>"); +-MODULE_DESCRIPTION("Microchip 251x CAN driver"); ++MODULE_DESCRIPTION("Microchip 251x/25625 CAN driver"); + MODULE_LICENSE("GPL v2"); +diff --git a/drivers/net/dsa/mv88e6xxx/global1_vtu.c b/drivers/net/dsa/mv88e6xxx/global1_vtu.c +index 058326924f3e..7a6667e0b9f9 100644 +--- a/drivers/net/dsa/mv88e6xxx/global1_vtu.c ++++ b/drivers/net/dsa/mv88e6xxx/global1_vtu.c +@@ -419,7 +419,7 @@ int mv88e6185_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, + * VTU DBNum[7:4] are located in VTU Operation 11:8 + */ + op |= entry->fid & 0x000f; +- op |= (entry->fid & 0x00f0) << 8; ++ op |= (entry->fid & 0x00f0) << 4; + } + + return mv88e6xxx_g1_vtu_op(chip, op); +diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig +index f2f0264c58ba..443b34e2725f 100644 +--- a/drivers/net/ethernet/8390/Kconfig ++++ b/drivers/net/ethernet/8390/Kconfig +@@ -49,7 +49,7 @@ config XSURF100 + tristate "Amiga XSurf 100 AX88796/NE2000 clone support" + depends on ZORRO + select AX88796 +- select ASIX_PHY ++ select AX88796B_PHY + help + This driver is for the Individual Computers X-Surf 100 Ethernet + card (based on the Asix AX88796 chip). If you have such a card, +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +index a4a90b6cdb46..c428b0655c26 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +@@ -1581,7 +1581,8 @@ static int bnx2x_get_module_info(struct net_device *dev, + } + + if (!sff8472_comp || +- (diag_type & SFP_EEPROM_DIAG_ADDR_CHANGE_REQ)) { ++ (diag_type & SFP_EEPROM_DIAG_ADDR_CHANGE_REQ) || ++ !(diag_type & SFP_EEPROM_DDM_IMPLEMENTED)) { + modinfo->type = ETH_MODULE_SFF_8079; + modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN; + } else { +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +index b7d251108c19..7115f5025664 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +@@ -62,6 +62,7 @@ + #define SFP_EEPROM_DIAG_TYPE_ADDR 0x5c + #define SFP_EEPROM_DIAG_TYPE_SIZE 1 + #define SFP_EEPROM_DIAG_ADDR_CHANGE_REQ (1<<2) ++#define SFP_EEPROM_DDM_IMPLEMENTED (1<<6) + #define SFP_EEPROM_SFF_8472_COMP_ADDR 0x5e + #define SFP_EEPROM_SFF_8472_COMP_SIZE 1 + +diff --git a/drivers/net/ethernet/cavium/liquidio/lio_core.c b/drivers/net/ethernet/cavium/liquidio/lio_core.c +index 8093c5eafea2..781814835a4f 100644 +--- a/drivers/net/ethernet/cavium/liquidio/lio_core.c ++++ b/drivers/net/ethernet/cavium/liquidio/lio_core.c +@@ -985,7 +985,7 @@ static void liquidio_schedule_droq_pkt_handlers(struct octeon_device *oct) + + if (droq->ops.poll_mode) { + droq->ops.napi_fn(droq); +- oct_priv->napi_mask |= (1 << oq_no); ++ oct_priv->napi_mask |= BIT_ULL(oq_no); + } else { + tasklet_schedule(&oct_priv->droq_tasklet); + } +diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c +index 426789e2c23d..0ae43d27cdcf 100644 +--- a/drivers/net/ethernet/ibm/ibmvnic.c ++++ b/drivers/net/ethernet/ibm/ibmvnic.c +@@ -438,9 +438,10 @@ static int reset_rx_pools(struct ibmvnic_adapter *adapter) + if (rx_pool->buff_size != be64_to_cpu(size_array[i])) { + free_long_term_buff(adapter, &rx_pool->long_term_buff); + rx_pool->buff_size = be64_to_cpu(size_array[i]); +- alloc_long_term_buff(adapter, &rx_pool->long_term_buff, +- rx_pool->size * +- rx_pool->buff_size); ++ rc = alloc_long_term_buff(adapter, ++ &rx_pool->long_term_buff, ++ rx_pool->size * ++ rx_pool->buff_size); + } else { + rc = reset_long_term_buff(adapter, + &rx_pool->long_term_buff); +@@ -706,9 +707,9 @@ static int init_tx_pools(struct net_device *netdev) + return rc; + } + +- init_one_tx_pool(netdev, &adapter->tso_pool[i], +- IBMVNIC_TSO_BUFS, +- IBMVNIC_TSO_BUF_SZ); ++ rc = init_one_tx_pool(netdev, &adapter->tso_pool[i], ++ IBMVNIC_TSO_BUFS, ++ IBMVNIC_TSO_BUF_SZ); + if (rc) { + release_tx_pools(adapter); + return rc; +@@ -1754,7 +1755,8 @@ static int do_reset(struct ibmvnic_adapter *adapter, + + ibmvnic_cleanup(netdev); + +- if (adapter->reset_reason != VNIC_RESET_MOBILITY && ++ if (reset_state == VNIC_OPEN && ++ adapter->reset_reason != VNIC_RESET_MOBILITY && + adapter->reset_reason != VNIC_RESET_FAILOVER) { + rc = __ibmvnic_close(netdev); + if (rc) +@@ -1853,6 +1855,9 @@ static int do_reset(struct ibmvnic_adapter *adapter, + return 0; + } + ++ /* refresh device's multicast list */ ++ ibmvnic_set_multi(netdev); ++ + /* kick napi */ + for (i = 0; i < adapter->req_rx_queues; i++) + napi_schedule(&adapter->napi[i]); +diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h +index 6e8b619b769b..aee58b3892f2 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h ++++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h +@@ -877,7 +877,7 @@ static inline void mlxsw_reg_spaft_pack(char *payload, u8 local_port, + MLXSW_REG_ZERO(spaft, payload); + mlxsw_reg_spaft_local_port_set(payload, local_port); + mlxsw_reg_spaft_allow_untagged_set(payload, allow_untagged); +- mlxsw_reg_spaft_allow_prio_tagged_set(payload, true); ++ mlxsw_reg_spaft_allow_prio_tagged_set(payload, allow_untagged); + mlxsw_reg_spaft_allow_tagged_set(payload, true); + } + +diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig +index 82070792edbb..1f5fd24cd749 100644 +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -227,7 +227,7 @@ config AQUANTIA_PHY + ---help--- + Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405 + +-config ASIX_PHY ++config AX88796B_PHY + tristate "Asix PHYs" + help + Currently supports the Asix Electronics PHY found in the X-Surf 100 +diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile +index 5805c0b7d60e..f21cda9d865e 100644 +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -46,7 +46,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m) + + obj-$(CONFIG_AMD_PHY) += amd.o + obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o +-obj-$(CONFIG_ASIX_PHY) += asix.o ++obj-$(CONFIG_AX88796B_PHY) += ax88796b.o + obj-$(CONFIG_AT803X_PHY) += at803x.o + obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o + obj-$(CONFIG_BCM7XXX_PHY) += bcm7xxx.o +diff --git a/drivers/net/phy/asix.c b/drivers/net/phy/asix.c +deleted file mode 100644 +index 8ebe7f5484ae..000000000000 +--- a/drivers/net/phy/asix.c ++++ /dev/null +@@ -1,63 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-/* Driver for Asix PHYs +- * +- * Author: Michael Schmitz <schmitzmic@gmail.com> +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- */ +-#include <linux/kernel.h> +-#include <linux/errno.h> +-#include <linux/init.h> +-#include <linux/module.h> +-#include <linux/mii.h> +-#include <linux/phy.h> +- +-#define PHY_ID_ASIX_AX88796B 0x003b1841 +- +-MODULE_DESCRIPTION("Asix PHY driver"); +-MODULE_AUTHOR("Michael Schmitz <schmitzmic@gmail.com>"); +-MODULE_LICENSE("GPL"); +- +-/** +- * asix_soft_reset - software reset the PHY via BMCR_RESET bit +- * @phydev: target phy_device struct +- * +- * Description: Perform a software PHY reset using the standard +- * BMCR_RESET bit and poll for the reset bit to be cleared. +- * Toggle BMCR_RESET bit off to accommodate broken AX8796B PHY implementation +- * such as used on the Individual Computers' X-Surf 100 Zorro card. +- * +- * Returns: 0 on success, < 0 on failure +- */ +-static int asix_soft_reset(struct phy_device *phydev) +-{ +- int ret; +- +- /* Asix PHY won't reset unless reset bit toggles */ +- ret = phy_write(phydev, MII_BMCR, 0); +- if (ret < 0) +- return ret; +- +- return genphy_soft_reset(phydev); +-} +- +-static struct phy_driver asix_driver[] = { { +- .phy_id = PHY_ID_ASIX_AX88796B, +- .name = "Asix Electronics AX88796B", +- .phy_id_mask = 0xfffffff0, +- .features = PHY_BASIC_FEATURES, +- .soft_reset = asix_soft_reset, +-} }; +- +-module_phy_driver(asix_driver); +- +-static struct mdio_device_id __maybe_unused asix_tbl[] = { +- { PHY_ID_ASIX_AX88796B, 0xfffffff0 }, +- { } +-}; +- +-MODULE_DEVICE_TABLE(mdio, asix_tbl); +diff --git a/drivers/net/phy/ax88796b.c b/drivers/net/phy/ax88796b.c +new file mode 100644 +index 000000000000..8ebe7f5484ae +--- /dev/null ++++ b/drivers/net/phy/ax88796b.c +@@ -0,0 +1,63 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Driver for Asix PHYs ++ * ++ * Author: Michael Schmitz <schmitzmic@gmail.com> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ */ ++#include <linux/kernel.h> ++#include <linux/errno.h> ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/mii.h> ++#include <linux/phy.h> ++ ++#define PHY_ID_ASIX_AX88796B 0x003b1841 ++ ++MODULE_DESCRIPTION("Asix PHY driver"); ++MODULE_AUTHOR("Michael Schmitz <schmitzmic@gmail.com>"); ++MODULE_LICENSE("GPL"); ++ ++/** ++ * asix_soft_reset - software reset the PHY via BMCR_RESET bit ++ * @phydev: target phy_device struct ++ * ++ * Description: Perform a software PHY reset using the standard ++ * BMCR_RESET bit and poll for the reset bit to be cleared. ++ * Toggle BMCR_RESET bit off to accommodate broken AX8796B PHY implementation ++ * such as used on the Individual Computers' X-Surf 100 Zorro card. ++ * ++ * Returns: 0 on success, < 0 on failure ++ */ ++static int asix_soft_reset(struct phy_device *phydev) ++{ ++ int ret; ++ ++ /* Asix PHY won't reset unless reset bit toggles */ ++ ret = phy_write(phydev, MII_BMCR, 0); ++ if (ret < 0) ++ return ret; ++ ++ return genphy_soft_reset(phydev); ++} ++ ++static struct phy_driver asix_driver[] = { { ++ .phy_id = PHY_ID_ASIX_AX88796B, ++ .name = "Asix Electronics AX88796B", ++ .phy_id_mask = 0xfffffff0, ++ .features = PHY_BASIC_FEATURES, ++ .soft_reset = asix_soft_reset, ++} }; ++ ++module_phy_driver(asix_driver); ++ ++static struct mdio_device_id __maybe_unused asix_tbl[] = { ++ { PHY_ID_ASIX_AX88796B, 0xfffffff0 }, ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(mdio, asix_tbl); +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index e657d8947125..128c8a327d8e 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -153,7 +153,7 @@ static bool qmimux_has_slaves(struct usbnet *dev) + + static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + { +- unsigned int len, offset = 0; ++ unsigned int len, offset = 0, pad_len, pkt_len; + struct qmimux_hdr *hdr; + struct net_device *net; + struct sk_buff *skbn; +@@ -171,10 +171,16 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + if (hdr->pad & 0x80) + goto skip; + ++ /* extract padding length and check for valid length info */ ++ pad_len = hdr->pad & 0x3f; ++ if (len == 0 || pad_len >= len) ++ goto skip; ++ pkt_len = len - pad_len; ++ + net = qmimux_find_dev(dev, hdr->mux_id); + if (!net) + goto skip; +- skbn = netdev_alloc_skb(net, len); ++ skbn = netdev_alloc_skb(net, pkt_len); + if (!skbn) + return 0; + skbn->dev = net; +@@ -191,7 +197,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + goto skip; + } + +- skb_put_data(skbn, skb->data + offset + qmimux_hdr_sz, len); ++ skb_put_data(skbn, skb->data + offset + qmimux_hdr_sz, pkt_len); + if (netif_rx(skbn) != NET_RX_SUCCESS) + return 0; + +@@ -241,13 +247,14 @@ out_free_newdev: + return err; + } + +-static void qmimux_unregister_device(struct net_device *dev) ++static void qmimux_unregister_device(struct net_device *dev, ++ struct list_head *head) + { + struct qmimux_priv *priv = netdev_priv(dev); + struct net_device *real_dev = priv->real_dev; + + netdev_upper_dev_unlink(real_dev, dev); +- unregister_netdevice(dev); ++ unregister_netdevice_queue(dev, head); + + /* Get rid of the reference to real_dev */ + dev_put(real_dev); +@@ -356,8 +363,8 @@ static ssize_t add_mux_store(struct device *d, struct device_attribute *attr, c + if (kstrtou8(buf, 0, &mux_id)) + return -EINVAL; + +- /* mux_id [1 - 0x7f] range empirically found */ +- if (mux_id < 1 || mux_id > 0x7f) ++ /* mux_id [1 - 254] for compatibility with ip(8) and the rmnet driver */ ++ if (mux_id < 1 || mux_id > 254) + return -EINVAL; + + if (!rtnl_trylock()) +@@ -418,7 +425,7 @@ static ssize_t del_mux_store(struct device *d, struct device_attribute *attr, c + ret = -EINVAL; + goto err; + } +- qmimux_unregister_device(del_dev); ++ qmimux_unregister_device(del_dev, NULL); + + if (!qmimux_has_slaves(dev)) + info->flags &= ~QMI_WWAN_FLAG_MUX; +@@ -1428,6 +1435,7 @@ static void qmi_wwan_disconnect(struct usb_interface *intf) + struct qmi_wwan_state *info; + struct list_head *iter; + struct net_device *ldev; ++ LIST_HEAD(list); + + /* called twice if separate control and data intf */ + if (!dev) +@@ -1440,8 +1448,9 @@ static void qmi_wwan_disconnect(struct usb_interface *intf) + } + rcu_read_lock(); + netdev_for_each_upper_dev_rcu(dev->net, ldev, iter) +- qmimux_unregister_device(ldev); ++ qmimux_unregister_device(ldev, &list); + rcu_read_unlock(); ++ unregister_netdevice_many(&list); + rtnl_unlock(); + info->flags &= ~QMI_WWAN_FLAG_MUX; + } +diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c +index e7c3f3b8457d..99f1897a775d 100644 +--- a/drivers/net/wireless/ath/carl9170/usb.c ++++ b/drivers/net/wireless/ath/carl9170/usb.c +@@ -128,6 +128,8 @@ static const struct usb_device_id carl9170_usb_ids[] = { + }; + MODULE_DEVICE_TABLE(usb, carl9170_usb_ids); + ++static struct usb_driver carl9170_driver; ++ + static void carl9170_usb_submit_data_urb(struct ar9170 *ar) + { + struct urb *urb; +@@ -966,32 +968,28 @@ err_out: + + static void carl9170_usb_firmware_failed(struct ar9170 *ar) + { +- struct device *parent = ar->udev->dev.parent; +- struct usb_device *udev; +- +- /* +- * Store a copy of the usb_device pointer locally. +- * This is because device_release_driver initiates +- * carl9170_usb_disconnect, which in turn frees our +- * driver context (ar). ++ /* Store a copies of the usb_interface and usb_device pointer locally. ++ * This is because release_driver initiates carl9170_usb_disconnect, ++ * which in turn frees our driver context (ar). + */ +- udev = ar->udev; ++ struct usb_interface *intf = ar->intf; ++ struct usb_device *udev = ar->udev; + + complete(&ar->fw_load_wait); ++ /* at this point 'ar' could be already freed. Don't use it anymore */ ++ ar = NULL; + + /* unbind anything failed */ +- if (parent) +- device_lock(parent); +- +- device_release_driver(&udev->dev); +- if (parent) +- device_unlock(parent); ++ usb_lock_device(udev); ++ usb_driver_release_interface(&carl9170_driver, intf); ++ usb_unlock_device(udev); + +- usb_put_dev(udev); ++ usb_put_intf(intf); + } + + static void carl9170_usb_firmware_finish(struct ar9170 *ar) + { ++ struct usb_interface *intf = ar->intf; + int err; + + err = carl9170_parse_firmware(ar); +@@ -1009,7 +1007,7 @@ static void carl9170_usb_firmware_finish(struct ar9170 *ar) + goto err_unrx; + + complete(&ar->fw_load_wait); +- usb_put_dev(ar->udev); ++ usb_put_intf(intf); + return; + + err_unrx: +@@ -1052,7 +1050,6 @@ static int carl9170_usb_probe(struct usb_interface *intf, + return PTR_ERR(ar); + + udev = interface_to_usbdev(intf); +- usb_get_dev(udev); + ar->udev = udev; + ar->intf = intf; + ar->features = id->driver_info; +@@ -1094,15 +1091,14 @@ static int carl9170_usb_probe(struct usb_interface *intf, + atomic_set(&ar->rx_anch_urbs, 0); + atomic_set(&ar->rx_pool_urbs, 0); + +- usb_get_dev(ar->udev); ++ usb_get_intf(intf); + + carl9170_set_state(ar, CARL9170_STOPPED); + + err = request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, + &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2); + if (err) { +- usb_put_dev(udev); +- usb_put_dev(udev); ++ usb_put_intf(intf); + carl9170_free(ar); + } + return err; +@@ -1131,7 +1127,6 @@ static void carl9170_usb_disconnect(struct usb_interface *intf) + + carl9170_release_firmware(ar); + carl9170_free(ar); +- usb_put_dev(udev); + } + + #ifdef CONFIG_PM +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +index c0631255aee7..db6628d390a2 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +@@ -1547,7 +1547,6 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) + goto free; + + out_free_fw: +- iwl_dealloc_ucode(drv); + release_firmware(ucode_raw); + out_unbind: + complete(&drv->request_firmware_complete); +diff --git a/drivers/net/wireless/intersil/p54/p54usb.c b/drivers/net/wireless/intersil/p54/p54usb.c +index b0b86f701061..15661da6eedc 100644 +--- a/drivers/net/wireless/intersil/p54/p54usb.c ++++ b/drivers/net/wireless/intersil/p54/p54usb.c +@@ -33,6 +33,8 @@ MODULE_ALIAS("prism54usb"); + MODULE_FIRMWARE("isl3886usb"); + MODULE_FIRMWARE("isl3887usb"); + ++static struct usb_driver p54u_driver; ++ + /* + * Note: + * +@@ -921,9 +923,9 @@ static void p54u_load_firmware_cb(const struct firmware *firmware, + { + struct p54u_priv *priv = context; + struct usb_device *udev = priv->udev; ++ struct usb_interface *intf = priv->intf; + int err; + +- complete(&priv->fw_wait_load); + if (firmware) { + priv->fw = firmware; + err = p54u_start_ops(priv); +@@ -932,26 +934,22 @@ static void p54u_load_firmware_cb(const struct firmware *firmware, + dev_err(&udev->dev, "Firmware not found.\n"); + } + +- if (err) { +- struct device *parent = priv->udev->dev.parent; +- +- dev_err(&udev->dev, "failed to initialize device (%d)\n", err); +- +- if (parent) +- device_lock(parent); ++ complete(&priv->fw_wait_load); ++ /* ++ * At this point p54u_disconnect may have already freed ++ * the "priv" context. Do not use it anymore! ++ */ ++ priv = NULL; + +- device_release_driver(&udev->dev); +- /* +- * At this point p54u_disconnect has already freed +- * the "priv" context. Do not use it anymore! +- */ +- priv = NULL; ++ if (err) { ++ dev_err(&intf->dev, "failed to initialize device (%d)\n", err); + +- if (parent) +- device_unlock(parent); ++ usb_lock_device(udev); ++ usb_driver_release_interface(&p54u_driver, intf); ++ usb_unlock_device(udev); + } + +- usb_put_dev(udev); ++ usb_put_intf(intf); + } + + static int p54u_load_firmware(struct ieee80211_hw *dev, +@@ -972,14 +970,14 @@ static int p54u_load_firmware(struct ieee80211_hw *dev, + dev_info(&priv->udev->dev, "Loading firmware file %s\n", + p54u_fwlist[i].fw); + +- usb_get_dev(udev); ++ usb_get_intf(intf); + err = request_firmware_nowait(THIS_MODULE, 1, p54u_fwlist[i].fw, + device, GFP_KERNEL, priv, + p54u_load_firmware_cb); + if (err) { + dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s " + "(%d)!\n", p54u_fwlist[i].fw, err); +- usb_put_dev(udev); ++ usb_put_intf(intf); + } + + return err; +@@ -1011,8 +1009,6 @@ static int p54u_probe(struct usb_interface *intf, + skb_queue_head_init(&priv->rx_queue); + init_usb_anchor(&priv->submitted); + +- usb_get_dev(udev); +- + /* really lazy and simple way of figuring out if we're a 3887 */ + /* TODO: should just stick the identification in the device table */ + i = intf->altsetting->desc.bNumEndpoints; +@@ -1053,10 +1049,8 @@ static int p54u_probe(struct usb_interface *intf, + priv->upload_fw = p54u_upload_firmware_net2280; + } + err = p54u_load_firmware(dev, intf); +- if (err) { +- usb_put_dev(udev); ++ if (err) + p54_free_common(dev); +- } + return err; + } + +@@ -1072,7 +1066,6 @@ static void p54u_disconnect(struct usb_interface *intf) + wait_for_completion(&priv->fw_wait_load); + p54_unregister_common(dev); + +- usb_put_dev(interface_to_usbdev(intf)); + release_firmware(priv->fw); + p54_free_common(dev); + } +diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h +index b73f99dc5a72..1fb76d2f5d3f 100644 +--- a/drivers/net/wireless/marvell/mwifiex/fw.h ++++ b/drivers/net/wireless/marvell/mwifiex/fw.h +@@ -1759,9 +1759,10 @@ struct mwifiex_ie_types_wmm_queue_status { + struct ieee_types_vendor_header { + u8 element_id; + u8 len; +- u8 oui[4]; /* 0~2: oui, 3: oui_type */ +- u8 oui_subtype; +- u8 version; ++ struct { ++ u8 oui[3]; ++ u8 oui_type; ++ } __packed oui; + } __packed; + + struct ieee_types_wmm_parameter { +@@ -1775,6 +1776,9 @@ struct ieee_types_wmm_parameter { + * Version [1] + */ + struct ieee_types_vendor_header vend_hdr; ++ u8 oui_subtype; ++ u8 version; ++ + u8 qos_info_bitmap; + u8 reserved; + struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_NUM_ACS]; +@@ -1792,6 +1796,8 @@ struct ieee_types_wmm_info { + * Version [1] + */ + struct ieee_types_vendor_header vend_hdr; ++ u8 oui_subtype; ++ u8 version; + + u8 qos_info_bitmap; + } __packed; +diff --git a/drivers/net/wireless/marvell/mwifiex/ie.c b/drivers/net/wireless/marvell/mwifiex/ie.c +index 75cbd609d606..801a2d7b020a 100644 +--- a/drivers/net/wireless/marvell/mwifiex/ie.c ++++ b/drivers/net/wireless/marvell/mwifiex/ie.c +@@ -329,6 +329,8 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, + struct ieee80211_vendor_ie *vendorhdr; + u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0; + int left_len, parsed_len = 0; ++ unsigned int token_len; ++ int err = 0; + + if (!info->tail || !info->tail_len) + return 0; +@@ -344,6 +346,12 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, + */ + while (left_len > sizeof(struct ieee_types_header)) { + hdr = (void *)(info->tail + parsed_len); ++ token_len = hdr->len + sizeof(struct ieee_types_header); ++ if (token_len > left_len) { ++ err = -EINVAL; ++ goto out; ++ } ++ + switch (hdr->element_id) { + case WLAN_EID_SSID: + case WLAN_EID_SUPP_RATES: +@@ -361,16 +369,19 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, + if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, + WLAN_OUI_TYPE_MICROSOFT_WMM, + (const u8 *)hdr, +- hdr->len + sizeof(struct ieee_types_header))) ++ token_len)) + break; + default: +- memcpy(gen_ie->ie_buffer + ie_len, hdr, +- hdr->len + sizeof(struct ieee_types_header)); +- ie_len += hdr->len + sizeof(struct ieee_types_header); ++ if (ie_len + token_len > IEEE_MAX_IE_SIZE) { ++ err = -EINVAL; ++ goto out; ++ } ++ memcpy(gen_ie->ie_buffer + ie_len, hdr, token_len); ++ ie_len += token_len; + break; + } +- left_len -= hdr->len + sizeof(struct ieee_types_header); +- parsed_len += hdr->len + sizeof(struct ieee_types_header); ++ left_len -= token_len; ++ parsed_len += token_len; + } + + /* parse only WPA vendor IE from tail, WMM IE is configured by +@@ -380,15 +391,17 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, + WLAN_OUI_TYPE_MICROSOFT_WPA, + info->tail, info->tail_len); + if (vendorhdr) { +- memcpy(gen_ie->ie_buffer + ie_len, vendorhdr, +- vendorhdr->len + sizeof(struct ieee_types_header)); +- ie_len += vendorhdr->len + sizeof(struct ieee_types_header); ++ token_len = vendorhdr->len + sizeof(struct ieee_types_header); ++ if (ie_len + token_len > IEEE_MAX_IE_SIZE) { ++ err = -EINVAL; ++ goto out; ++ } ++ memcpy(gen_ie->ie_buffer + ie_len, vendorhdr, token_len); ++ ie_len += token_len; + } + +- if (!ie_len) { +- kfree(gen_ie); +- return 0; +- } ++ if (!ie_len) ++ goto out; + + gen_ie->ie_index = cpu_to_le16(gen_idx); + gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON | +@@ -398,13 +411,15 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, + + if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL, NULL, + NULL, NULL)) { +- kfree(gen_ie); +- return -1; ++ err = -EINVAL; ++ goto out; + } + + priv->gen_idx = gen_idx; ++ ++ out: + kfree(gen_ie); +- return 0; ++ return err; + } + + /* This function parses different IEs-head & tail IEs, beacon IEs, +diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c +index 8e483b0bc3b1..6dd771ce68a3 100644 +--- a/drivers/net/wireless/marvell/mwifiex/scan.c ++++ b/drivers/net/wireless/marvell/mwifiex/scan.c +@@ -1247,6 +1247,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, + } + switch (element_id) { + case WLAN_EID_SSID: ++ if (element_len > IEEE80211_MAX_SSID_LEN) ++ return -EINVAL; + bss_entry->ssid.ssid_len = element_len; + memcpy(bss_entry->ssid.ssid, (current_ptr + 2), + element_len); +@@ -1256,6 +1258,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, + break; + + case WLAN_EID_SUPP_RATES: ++ if (element_len > MWIFIEX_SUPPORTED_RATES) ++ return -EINVAL; + memcpy(bss_entry->data_rates, current_ptr + 2, + element_len); + memcpy(bss_entry->supported_rates, current_ptr + 2, +@@ -1265,6 +1269,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, + break; + + case WLAN_EID_FH_PARAMS: ++ if (element_len + 2 < sizeof(*fh_param_set)) ++ return -EINVAL; + fh_param_set = + (struct ieee_types_fh_param_set *) current_ptr; + memcpy(&bss_entry->phy_param_set.fh_param_set, +@@ -1273,6 +1279,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, + break; + + case WLAN_EID_DS_PARAMS: ++ if (element_len + 2 < sizeof(*ds_param_set)) ++ return -EINVAL; + ds_param_set = + (struct ieee_types_ds_param_set *) current_ptr; + +@@ -1284,6 +1292,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, + break; + + case WLAN_EID_CF_PARAMS: ++ if (element_len + 2 < sizeof(*cf_param_set)) ++ return -EINVAL; + cf_param_set = + (struct ieee_types_cf_param_set *) current_ptr; + memcpy(&bss_entry->ss_param_set.cf_param_set, +@@ -1292,6 +1302,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, + break; + + case WLAN_EID_IBSS_PARAMS: ++ if (element_len + 2 < sizeof(*ibss_param_set)) ++ return -EINVAL; + ibss_param_set = + (struct ieee_types_ibss_param_set *) + current_ptr; +@@ -1301,10 +1313,14 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, + break; + + case WLAN_EID_ERP_INFO: ++ if (!element_len) ++ return -EINVAL; + bss_entry->erp_flags = *(current_ptr + 2); + break; + + case WLAN_EID_PWR_CONSTRAINT: ++ if (!element_len) ++ return -EINVAL; + bss_entry->local_constraint = *(current_ptr + 2); + bss_entry->sensed_11h = true; + break; +@@ -1348,15 +1364,22 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, + vendor_ie = (struct ieee_types_vendor_specific *) + current_ptr; + +- if (!memcmp +- (vendor_ie->vend_hdr.oui, wpa_oui, +- sizeof(wpa_oui))) { ++ /* 802.11 requires at least 3-byte OUI. */ ++ if (element_len < sizeof(vendor_ie->vend_hdr.oui.oui)) ++ return -EINVAL; ++ ++ /* Not long enough for a match? Skip it. */ ++ if (element_len < sizeof(wpa_oui)) ++ break; ++ ++ if (!memcmp(&vendor_ie->vend_hdr.oui, wpa_oui, ++ sizeof(wpa_oui))) { + bss_entry->bcn_wpa_ie = + (struct ieee_types_vendor_specific *) + current_ptr; + bss_entry->wpa_offset = (u16) + (current_ptr - bss_entry->beacon_buf); +- } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui, ++ } else if (!memcmp(&vendor_ie->vend_hdr.oui, wmm_oui, + sizeof(wmm_oui))) { + if (total_ie_len == + sizeof(struct ieee_types_wmm_parameter) || +diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c +index b454b5f85503..843d65bba181 100644 +--- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c ++++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c +@@ -1348,7 +1348,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, + /* Test to see if it is a WPA IE, if not, then + * it is a gen IE + */ +- if (!memcmp(pvendor_ie->oui, wpa_oui, ++ if (!memcmp(&pvendor_ie->oui, wpa_oui, + sizeof(wpa_oui))) { + /* IE is a WPA/WPA2 IE so call set_wpa function + */ +@@ -1358,7 +1358,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, + goto next_ie; + } + +- if (!memcmp(pvendor_ie->oui, wps_oui, ++ if (!memcmp(&pvendor_ie->oui, wps_oui, + sizeof(wps_oui))) { + /* Test to see if it is a WPS IE, + * if so, enable wps session flag +diff --git a/drivers/net/wireless/marvell/mwifiex/wmm.c b/drivers/net/wireless/marvell/mwifiex/wmm.c +index 407b9932ca4d..64916ba15df5 100644 +--- a/drivers/net/wireless/marvell/mwifiex/wmm.c ++++ b/drivers/net/wireless/marvell/mwifiex/wmm.c +@@ -240,7 +240,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, + mwifiex_dbg(priv->adapter, INFO, + "info: WMM Parameter IE: version=%d,\t" + "qos_info Parameter Set Count=%d, Reserved=%#x\n", +- wmm_ie->vend_hdr.version, wmm_ie->qos_info_bitmap & ++ wmm_ie->version, wmm_ie->qos_info_bitmap & + IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK, + wmm_ie->reserved); + +diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c +index 4de740da547b..763c7628356b 100644 +--- a/drivers/scsi/qedi/qedi_main.c ++++ b/drivers/scsi/qedi/qedi_main.c +@@ -955,6 +955,9 @@ static int qedi_find_boot_info(struct qedi_ctx *qedi, + if (!iscsi_is_session_online(cls_sess)) + continue; + ++ if (!sess->targetname) ++ continue; ++ + if (pri_ctrl_flags) { + if (!strcmp(pri_tgt->iscsi_name, sess->targetname) && + !strcmp(pri_tgt->ip_addr, ep_ip_addr)) { +diff --git a/drivers/soc/bcm/brcmstb/biuctrl.c b/drivers/soc/bcm/brcmstb/biuctrl.c +index 6d89ebf13b8a..20b63bee5b09 100644 +--- a/drivers/soc/bcm/brcmstb/biuctrl.c ++++ b/drivers/soc/bcm/brcmstb/biuctrl.c +@@ -56,7 +56,7 @@ static inline void cbc_writel(u32 val, int reg) + if (offset == -1) + return; + +- writel_relaxed(val, cpubiuctrl_base + offset); ++ writel(val, cpubiuctrl_base + offset); + } + + enum cpubiuctrl_regs { +@@ -246,7 +246,9 @@ static int __init brcmstb_biuctrl_init(void) + if (!np) + return 0; + +- setup_hifcpubiuctrl_regs(np); ++ ret = setup_hifcpubiuctrl_regs(np); ++ if (ret) ++ return ret; + + ret = mcp_write_pairing_set(); + if (ret) { +diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c +index 0a8990e758f9..a6e2581ada70 100644 +--- a/drivers/soundwire/intel.c ++++ b/drivers/soundwire/intel.c +@@ -651,8 +651,8 @@ static int intel_create_dai(struct sdw_cdns *cdns, + return -ENOMEM; + } + +- dais[i].playback.channels_min = 1; +- dais[i].playback.channels_max = max_ch; ++ dais[i].capture.channels_min = 1; ++ dais[i].capture.channels_max = max_ch; + dais[i].capture.rates = SNDRV_PCM_RATE_48000; + dais[i].capture.formats = SNDRV_PCM_FMTBIT_S16_LE; + } +diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c +index e5c7e1ef6318..907a548645b7 100644 +--- a/drivers/soundwire/stream.c ++++ b/drivers/soundwire/stream.c +@@ -1236,9 +1236,7 @@ struct sdw_dpn_prop *sdw_get_slave_dpn_prop(struct sdw_slave *slave, + } + + for (i = 0; i < num_ports; i++) { +- dpn_prop = &dpn_prop[i]; +- +- if (dpn_prop->num == port_num) ++ if (dpn_prop[i].num == port_num) + return &dpn_prop[i]; + } + +diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c +index 08ffe26c5d43..0f16e85911f2 100644 +--- a/drivers/staging/comedi/drivers/amplc_pci230.c ++++ b/drivers/staging/comedi/drivers/amplc_pci230.c +@@ -2330,7 +2330,8 @@ static irqreturn_t pci230_interrupt(int irq, void *d) + devpriv->intr_running = false; + spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); + +- comedi_handle_events(dev, s_ao); ++ if (s_ao) ++ comedi_handle_events(dev, s_ao); + comedi_handle_events(dev, s_ai); + + return IRQ_HANDLED; +diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c +index 3be927f1d3a9..e15e33ed94ae 100644 +--- a/drivers/staging/comedi/drivers/dt282x.c ++++ b/drivers/staging/comedi/drivers/dt282x.c +@@ -557,7 +557,8 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) + } + #endif + comedi_handle_events(dev, s); +- comedi_handle_events(dev, s_ao); ++ if (s_ao) ++ comedi_handle_events(dev, s_ao); + + return IRQ_RETVAL(handled); + } +diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c +index ecdd3d84f956..8549e809363e 100644 +--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c ++++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c +@@ -1073,6 +1073,7 @@ static int port_switchdev_event(struct notifier_block *unused, + dev_hold(dev); + break; + default: ++ kfree(switchdev_work); + return NOTIFY_DONE; + } + +diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c +index d16084d7068c..a354ce6b2b7b 100644 +--- a/drivers/staging/iio/cdc/ad7150.c ++++ b/drivers/staging/iio/cdc/ad7150.c +@@ -6,6 +6,7 @@ + * Licensed under the GPL-2 or later. + */ + ++#include <linux/bitfield.h> + #include <linux/interrupt.h> + #include <linux/device.h> + #include <linux/kernel.h> +@@ -130,7 +131,7 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev, + { + int ret; + u8 threshtype; +- bool adaptive; ++ bool thrfixed; + struct ad7150_chip_info *chip = iio_priv(indio_dev); + + ret = i2c_smbus_read_byte_data(chip->client, AD7150_CFG); +@@ -138,21 +139,23 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev, + return ret; + + threshtype = (ret >> 5) & 0x03; +- adaptive = !!(ret & 0x80); ++ ++ /*check if threshold mode is fixed or adaptive*/ ++ thrfixed = FIELD_GET(AD7150_CFG_FIX, ret); + + switch (type) { + case IIO_EV_TYPE_MAG_ADAPTIVE: + if (dir == IIO_EV_DIR_RISING) +- return adaptive && (threshtype == 0x1); +- return adaptive && (threshtype == 0x0); ++ return !thrfixed && (threshtype == 0x1); ++ return !thrfixed && (threshtype == 0x0); + case IIO_EV_TYPE_THRESH_ADAPTIVE: + if (dir == IIO_EV_DIR_RISING) +- return adaptive && (threshtype == 0x3); +- return adaptive && (threshtype == 0x2); ++ return !thrfixed && (threshtype == 0x3); ++ return !thrfixed && (threshtype == 0x2); + case IIO_EV_TYPE_THRESH: + if (dir == IIO_EV_DIR_RISING) +- return !adaptive && (threshtype == 0x1); +- return !adaptive && (threshtype == 0x0); ++ return thrfixed && (threshtype == 0x1); ++ return thrfixed && (threshtype == 0x0); + default: + break; + } +diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +index c3ff7c3e6681..2f490a4bf60a 100644 +--- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c ++++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +@@ -141,10 +141,91 @@ static inline void handle_group_key(struct ieee_param *param, + } + } + +-static noinline_for_stack char *translate_scan(struct _adapter *padapter, +- struct iw_request_info *info, +- struct wlan_network *pnetwork, +- char *start, char *stop) ++static noinline_for_stack char *translate_scan_wpa(struct iw_request_info *info, ++ struct wlan_network *pnetwork, ++ struct iw_event *iwe, ++ char *start, char *stop) ++{ ++ /* parsing WPA/WPA2 IE */ ++ u8 buf[MAX_WPA_IE_LEN]; ++ u8 wpa_ie[255], rsn_ie[255]; ++ u16 wpa_len = 0, rsn_len = 0; ++ int n, i; ++ ++ r8712_get_sec_ie(pnetwork->network.IEs, ++ pnetwork->network.IELength, rsn_ie, &rsn_len, ++ wpa_ie, &wpa_len); ++ if (wpa_len > 0) { ++ memset(buf, 0, MAX_WPA_IE_LEN); ++ n = sprintf(buf, "wpa_ie="); ++ for (i = 0; i < wpa_len; i++) { ++ n += snprintf(buf + n, MAX_WPA_IE_LEN - n, ++ "%02x", wpa_ie[i]); ++ if (n >= MAX_WPA_IE_LEN) ++ break; ++ } ++ memset(iwe, 0, sizeof(*iwe)); ++ iwe->cmd = IWEVCUSTOM; ++ iwe->u.data.length = (u16)strlen(buf); ++ start = iwe_stream_add_point(info, start, stop, ++ iwe, buf); ++ memset(iwe, 0, sizeof(*iwe)); ++ iwe->cmd = IWEVGENIE; ++ iwe->u.data.length = (u16)wpa_len; ++ start = iwe_stream_add_point(info, start, stop, ++ iwe, wpa_ie); ++ } ++ if (rsn_len > 0) { ++ memset(buf, 0, MAX_WPA_IE_LEN); ++ n = sprintf(buf, "rsn_ie="); ++ for (i = 0; i < rsn_len; i++) { ++ n += snprintf(buf + n, MAX_WPA_IE_LEN - n, ++ "%02x", rsn_ie[i]); ++ if (n >= MAX_WPA_IE_LEN) ++ break; ++ } ++ memset(iwe, 0, sizeof(*iwe)); ++ iwe->cmd = IWEVCUSTOM; ++ iwe->u.data.length = strlen(buf); ++ start = iwe_stream_add_point(info, start, stop, ++ iwe, buf); ++ memset(iwe, 0, sizeof(*iwe)); ++ iwe->cmd = IWEVGENIE; ++ iwe->u.data.length = rsn_len; ++ start = iwe_stream_add_point(info, start, stop, iwe, ++ rsn_ie); ++ } ++ ++ return start; ++} ++ ++static noinline_for_stack char *translate_scan_wps(struct iw_request_info *info, ++ struct wlan_network *pnetwork, ++ struct iw_event *iwe, ++ char *start, char *stop) ++{ ++ /* parsing WPS IE */ ++ u8 wps_ie[512]; ++ uint wps_ielen; ++ ++ if (r8712_get_wps_ie(pnetwork->network.IEs, ++ pnetwork->network.IELength, ++ wps_ie, &wps_ielen)) { ++ if (wps_ielen > 2) { ++ iwe->cmd = IWEVGENIE; ++ iwe->u.data.length = (u16)wps_ielen; ++ start = iwe_stream_add_point(info, start, stop, ++ iwe, wps_ie); ++ } ++ } ++ ++ return start; ++} ++ ++static char *translate_scan(struct _adapter *padapter, ++ struct iw_request_info *info, ++ struct wlan_network *pnetwork, ++ char *start, char *stop) + { + struct iw_event iwe; + struct ieee80211_ht_cap *pht_capie; +@@ -257,73 +338,11 @@ static noinline_for_stack char *translate_scan(struct _adapter *padapter, + /* Check if we added any event */ + if ((current_val - start) > iwe_stream_lcp_len(info)) + start = current_val; +- /* parsing WPA/WPA2 IE */ +- { +- u8 buf[MAX_WPA_IE_LEN]; +- u8 wpa_ie[255], rsn_ie[255]; +- u16 wpa_len = 0, rsn_len = 0; +- int n; +- +- r8712_get_sec_ie(pnetwork->network.IEs, +- pnetwork->network.IELength, rsn_ie, &rsn_len, +- wpa_ie, &wpa_len); +- if (wpa_len > 0) { +- memset(buf, 0, MAX_WPA_IE_LEN); +- n = sprintf(buf, "wpa_ie="); +- for (i = 0; i < wpa_len; i++) { +- n += snprintf(buf + n, MAX_WPA_IE_LEN - n, +- "%02x", wpa_ie[i]); +- if (n >= MAX_WPA_IE_LEN) +- break; +- } +- memset(&iwe, 0, sizeof(iwe)); +- iwe.cmd = IWEVCUSTOM; +- iwe.u.data.length = (u16)strlen(buf); +- start = iwe_stream_add_point(info, start, stop, +- &iwe, buf); +- memset(&iwe, 0, sizeof(iwe)); +- iwe.cmd = IWEVGENIE; +- iwe.u.data.length = (u16)wpa_len; +- start = iwe_stream_add_point(info, start, stop, +- &iwe, wpa_ie); +- } +- if (rsn_len > 0) { +- memset(buf, 0, MAX_WPA_IE_LEN); +- n = sprintf(buf, "rsn_ie="); +- for (i = 0; i < rsn_len; i++) { +- n += snprintf(buf + n, MAX_WPA_IE_LEN - n, +- "%02x", rsn_ie[i]); +- if (n >= MAX_WPA_IE_LEN) +- break; +- } +- memset(&iwe, 0, sizeof(iwe)); +- iwe.cmd = IWEVCUSTOM; +- iwe.u.data.length = strlen(buf); +- start = iwe_stream_add_point(info, start, stop, +- &iwe, buf); +- memset(&iwe, 0, sizeof(iwe)); +- iwe.cmd = IWEVGENIE; +- iwe.u.data.length = rsn_len; +- start = iwe_stream_add_point(info, start, stop, &iwe, +- rsn_ie); +- } +- } + +- { /* parsing WPS IE */ +- u8 wps_ie[512]; +- uint wps_ielen; ++ start = translate_scan_wpa(info, pnetwork, &iwe, start, stop); ++ ++ start = translate_scan_wps(info, pnetwork, &iwe, start, stop); + +- if (r8712_get_wps_ie(pnetwork->network.IEs, +- pnetwork->network.IELength, +- wps_ie, &wps_ielen)) { +- if (wps_ielen > 2) { +- iwe.cmd = IWEVGENIE; +- iwe.u.data.length = (u16)wps_ielen; +- start = iwe_stream_add_point(info, start, stop, +- &iwe, wps_ie); +- } +- } +- } + /* Add quality statistics */ + iwe.cmd = IWEVQUAL; + rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi); +diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +index c04bdf070c87..455082867246 100644 +--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +@@ -342,16 +342,13 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, + return; + } else if (length == 0) { + /* stream ended */ +- if (buf) { +- /* this should only ever happen if the port is +- * disabled and there are buffers still queued ++ if (dev->capture.frame_count) { ++ /* empty buffer whilst capturing - expected to be an ++ * EOS, so grab another frame + */ +- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); +- pr_debug("Empty buffer"); +- } else if (dev->capture.frame_count) { +- /* grab another frame */ + if (is_capturing(dev)) { +- pr_debug("Grab another frame"); ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "Grab another frame"); + vchiq_mmal_port_parameter_set( + instance, + dev->capture.camera_port, +@@ -359,8 +356,14 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, + &dev->capture.frame_count, + sizeof(dev->capture.frame_count)); + } ++ if (vchiq_mmal_submit_buffer(instance, port, buf)) ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "Failed to return EOS buffer"); + } else { +- /* signal frame completion */ ++ /* stopping streaming. ++ * return buffer, and signal frame completion ++ */ ++ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); + complete(&dev->capture.frame_cmplt); + } + } else { +@@ -582,6 +585,7 @@ static void stop_streaming(struct vb2_queue *vq) + int ret; + unsigned long timeout; + struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq); ++ struct vchiq_mmal_port *port = dev->capture.port; + + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n", + __func__, dev); +@@ -605,12 +609,6 @@ static void stop_streaming(struct vb2_queue *vq) + &dev->capture.frame_count, + sizeof(dev->capture.frame_count)); + +- /* wait for last frame to complete */ +- timeout = wait_for_completion_timeout(&dev->capture.frame_cmplt, HZ); +- if (timeout == 0) +- v4l2_err(&dev->v4l2_dev, +- "timed out waiting for frame completion\n"); +- + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, + "disabling connection\n"); + +@@ -625,6 +623,21 @@ static void stop_streaming(struct vb2_queue *vq) + ret); + } + ++ /* wait for all buffers to be returned */ ++ while (atomic_read(&port->buffers_with_vpu)) { ++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, ++ "%s: Waiting for buffers to be returned - %d outstanding\n", ++ __func__, atomic_read(&port->buffers_with_vpu)); ++ timeout = wait_for_completion_timeout(&dev->capture.frame_cmplt, ++ HZ); ++ if (timeout == 0) { ++ v4l2_err(&dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n", ++ __func__, ++ atomic_read(&port->buffers_with_vpu)); ++ break; ++ } ++ } ++ + if (disable_camera(dev) < 0) + v4l2_err(&dev->v4l2_dev, "Failed to disable camera\n"); + } +diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c +index 51e5b04ff0f5..daa2b9656552 100644 +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c ++++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c +@@ -162,7 +162,8 @@ struct vchiq_mmal_instance { + void *bulk_scratch; + + struct idr context_map; +- spinlock_t context_map_lock; ++ /* protect accesses to context_map */ ++ struct mutex context_map_lock; + + /* component to use next */ + int component_idx; +@@ -185,10 +186,10 @@ get_msg_context(struct vchiq_mmal_instance *instance) + * that when we service the VCHI reply, we can look up what + * message is being replied to. + */ +- spin_lock(&instance->context_map_lock); ++ mutex_lock(&instance->context_map_lock); + handle = idr_alloc(&instance->context_map, msg_context, + 0, 0, GFP_KERNEL); +- spin_unlock(&instance->context_map_lock); ++ mutex_unlock(&instance->context_map_lock); + + if (handle < 0) { + kfree(msg_context); +@@ -212,9 +213,9 @@ release_msg_context(struct mmal_msg_context *msg_context) + { + struct vchiq_mmal_instance *instance = msg_context->instance; + +- spin_lock(&instance->context_map_lock); ++ mutex_lock(&instance->context_map_lock); + idr_remove(&instance->context_map, msg_context->handle); +- spin_unlock(&instance->context_map_lock); ++ mutex_unlock(&instance->context_map_lock); + kfree(msg_context); + } + +@@ -240,6 +241,8 @@ static void buffer_work_cb(struct work_struct *work) + struct mmal_msg_context *msg_context = + container_of(work, struct mmal_msg_context, u.bulk.work); + ++ atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu); ++ + msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance, + msg_context->u.bulk.port, + msg_context->u.bulk.status, +@@ -288,8 +291,6 @@ static int bulk_receive(struct vchiq_mmal_instance *instance, + + /* store length */ + msg_context->u.bulk.buffer_used = rd_len; +- msg_context->u.bulk.mmal_flags = +- msg->u.buffer_from_host.buffer_header.flags; + msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts; + msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts; + +@@ -380,6 +381,8 @@ buffer_from_host(struct vchiq_mmal_instance *instance, + /* initialise work structure ready to schedule callback */ + INIT_WORK(&msg_context->u.bulk.work, buffer_work_cb); + ++ atomic_inc(&port->buffers_with_vpu); ++ + /* prep the buffer from host message */ + memset(&m, 0xbc, sizeof(m)); /* just to make debug clearer */ + +@@ -448,6 +451,9 @@ static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, + return; + } + ++ msg_context->u.bulk.mmal_flags = ++ msg->u.buffer_from_host.buffer_header.flags; ++ + if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) { + /* message reception had an error */ + pr_warn("error %d in reply\n", msg->h.status); +@@ -1324,16 +1330,6 @@ static int port_enable(struct vchiq_mmal_instance *instance, + if (port->enabled) + return 0; + +- /* ensure there are enough buffers queued to cover the buffer headers */ +- if (port->buffer_cb) { +- hdr_count = 0; +- list_for_each(buf_head, &port->buffers) { +- hdr_count++; +- } +- if (hdr_count < port->current_buffer.num) +- return -ENOSPC; +- } +- + ret = port_action_port(instance, port, + MMAL_MSG_PORT_ACTION_TYPE_ENABLE); + if (ret) +@@ -1854,7 +1850,7 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) + + instance->bulk_scratch = vmalloc(PAGE_SIZE); + +- spin_lock_init(&instance->context_map_lock); ++ mutex_init(&instance->context_map_lock); + idr_init_base(&instance->context_map, 1); + + params.callback_param = instance; +diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h +index 22b839ecd5f0..b0ee1716525b 100644 +--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h ++++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h +@@ -71,6 +71,9 @@ struct vchiq_mmal_port { + struct list_head buffers; + /* lock to serialise adding and removing buffers from list */ + spinlock_t slock; ++ ++ /* Count of buffers the VPU has yet to return */ ++ atomic_t buffers_with_vpu; + /* callback on buffer completion */ + vchiq_mmal_buffer_cb buffer_cb; + /* callback context */ +diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c +index 3f779d25ec0c..e26d87b6ffc5 100644 +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -1869,8 +1869,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) + + status = serial_port_in(port, UART_LSR); + +- if (status & (UART_LSR_DR | UART_LSR_BI) && +- iir & UART_IIR_RDI) { ++ if (status & (UART_LSR_DR | UART_LSR_BI)) { + if (!up->dma || handle_rx_dma(up, iir)) + status = serial8250_rx_chars(up, status); + } +diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c +index 55d5ae2a7ec7..51d83f77dc04 100644 +--- a/drivers/usb/dwc2/core.c ++++ b/drivers/usb/dwc2/core.c +@@ -531,7 +531,7 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait) + } + + /* Wait for AHB master IDLE state */ +- if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL, GRSTCTL_AHBIDLE, 50)) { ++ if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL, GRSTCTL_AHBIDLE, 10000)) { + dev_warn(hsotg->dev, "%s: HANG! AHB Idle timeout GRSTCTL GRSTCTL_AHBIDLE\n", + __func__); + return -EBUSY; +diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c +index 0f026d445e31..0ef00315ec73 100644 +--- a/drivers/usb/gadget/function/u_ether.c ++++ b/drivers/usb/gadget/function/u_ether.c +@@ -186,11 +186,12 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) + out = dev->port_usb->out_ep; + else + out = NULL; +- spin_unlock_irqrestore(&dev->lock, flags); + + if (!out) ++ { ++ spin_unlock_irqrestore(&dev->lock, flags); + return -ENOTCONN; +- ++ } + + /* Padding up to RX_EXTRA handles minor disagreements with host. + * Normally we use the USB "terminate on short read" convention; +@@ -214,6 +215,7 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) + + if (dev->port_usb->is_fixed) + size = max_t(size_t, size, dev->port_usb->fixed_out_len); ++ spin_unlock_irqrestore(&dev->lock, flags); + + skb = __netdev_alloc_skb(dev->net, size + NET_IP_ALIGN, gfp_flags); + if (skb == NULL) { +diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c +index 39fa2fc1b8b7..6036cbae8c78 100644 +--- a/drivers/usb/renesas_usbhs/fifo.c ++++ b/drivers/usb/renesas_usbhs/fifo.c +@@ -802,9 +802,8 @@ static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map) + } + + static void usbhsf_dma_complete(void *arg); +-static void xfer_work(struct work_struct *work) ++static void usbhsf_dma_xfer_preparing(struct usbhs_pkt *pkt) + { +- struct usbhs_pkt *pkt = container_of(work, struct usbhs_pkt, work); + struct usbhs_pipe *pipe = pkt->pipe; + struct usbhs_fifo *fifo; + struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); +@@ -812,12 +811,10 @@ static void xfer_work(struct work_struct *work) + struct dma_chan *chan; + struct device *dev = usbhs_priv_to_dev(priv); + enum dma_transfer_direction dir; +- unsigned long flags; + +- usbhs_lock(priv, flags); + fifo = usbhs_pipe_to_fifo(pipe); + if (!fifo) +- goto xfer_work_end; ++ return; + + chan = usbhsf_dma_chan_get(fifo, pkt); + dir = usbhs_pipe_is_dir_in(pipe) ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV; +@@ -826,7 +823,7 @@ static void xfer_work(struct work_struct *work) + pkt->trans, dir, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc) +- goto xfer_work_end; ++ return; + + desc->callback = usbhsf_dma_complete; + desc->callback_param = pipe; +@@ -834,7 +831,7 @@ static void xfer_work(struct work_struct *work) + pkt->cookie = dmaengine_submit(desc); + if (pkt->cookie < 0) { + dev_err(dev, "Failed to submit dma descriptor\n"); +- goto xfer_work_end; ++ return; + } + + dev_dbg(dev, " %s %d (%d/ %d)\n", +@@ -845,8 +842,17 @@ static void xfer_work(struct work_struct *work) + dma_async_issue_pending(chan); + usbhsf_dma_start(pipe, fifo); + usbhs_pipe_enable(pipe); ++} ++ ++static void xfer_work(struct work_struct *work) ++{ ++ struct usbhs_pkt *pkt = container_of(work, struct usbhs_pkt, work); ++ struct usbhs_pipe *pipe = pkt->pipe; ++ struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); ++ unsigned long flags; + +-xfer_work_end: ++ usbhs_lock(priv, flags); ++ usbhsf_dma_xfer_preparing(pkt); + usbhs_unlock(priv, flags); + } + +@@ -899,8 +905,13 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done) + pkt->trans = len; + + usbhsf_tx_irq_ctrl(pipe, 0); +- INIT_WORK(&pkt->work, xfer_work); +- schedule_work(&pkt->work); ++ /* FIXME: Workaound for usb dmac that driver can be used in atomic */ ++ if (usbhs_get_dparam(priv, has_usb_dmac)) { ++ usbhsf_dma_xfer_preparing(pkt); ++ } else { ++ INIT_WORK(&pkt->work, xfer_work); ++ schedule_work(&pkt->work); ++ } + + return 0; + +@@ -1006,8 +1017,7 @@ static int usbhsf_dma_prepare_pop_with_usb_dmac(struct usbhs_pkt *pkt, + + pkt->trans = pkt->length; + +- INIT_WORK(&pkt->work, xfer_work); +- schedule_work(&pkt->work); ++ usbhsf_dma_xfer_preparing(pkt); + + return 0; + +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index c0dc4bc776db..e18735e00463 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1019,6 +1019,7 @@ static const struct usb_device_id id_table_combined[] = { + { USB_DEVICE(AIRBUS_DS_VID, AIRBUS_DS_P8GR) }, + /* EZPrototypes devices */ + { USB_DEVICE(EZPROTOTYPES_VID, HJELMSLUND_USB485_ISO_PID) }, ++ { USB_DEVICE_INTERFACE_NUMBER(UNJO_VID, UNJO_ISODEBUG_V1_PID, 1) }, + { } /* Terminating entry */ + }; + +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index 5755f0df0025..f12d806220b4 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -1543,3 +1543,9 @@ + #define CHETCO_SEASMART_DISPLAY_PID 0xA5AD /* SeaSmart NMEA2000 Display */ + #define CHETCO_SEASMART_LITE_PID 0xA5AE /* SeaSmart Lite USB Adapter */ + #define CHETCO_SEASMART_ANALOG_PID 0xA5AF /* SeaSmart Analog Adapter */ ++ ++/* ++ * Unjo AB ++ */ ++#define UNJO_VID 0x22B7 ++#define UNJO_ISODEBUG_V1_PID 0x150D +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index ea891195bbdf..e0a4749ba565 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1343,6 +1343,7 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x0601, 0xff) }, /* GosunCn ZTE WeLink ME3630 (RNDIS mode) */ + { USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x0602, 0xff) }, /* GosunCn ZTE WeLink ME3630 (MBIM mode) */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), + .driver_info = RSVD(4) }, +diff --git a/drivers/usb/typec/tps6598x.c b/drivers/usb/typec/tps6598x.c +index eb8046f87a54..987b8fcfb2aa 100644 +--- a/drivers/usb/typec/tps6598x.c ++++ b/drivers/usb/typec/tps6598x.c +@@ -39,7 +39,7 @@ + #define TPS_STATUS_VCONN(s) (!!((s) & BIT(7))) + + /* TPS_REG_SYSTEM_CONF bits */ +-#define TPS_SYSCONF_PORTINFO(c) ((c) & 3) ++#define TPS_SYSCONF_PORTINFO(c) ((c) & 7) + + enum { + TPS_PORTINFO_SINK, +@@ -111,7 +111,7 @@ tps6598x_block_read(struct tps6598x *tps, u8 reg, void *val, size_t len) + } + + static int tps6598x_block_write(struct tps6598x *tps, u8 reg, +- void *val, size_t len) ++ const void *val, size_t len) + { + u8 data[TPS_MAX_LEN + 1]; + +@@ -157,7 +157,7 @@ static inline int tps6598x_write64(struct tps6598x *tps, u8 reg, u64 val) + static inline int + tps6598x_write_4cc(struct tps6598x *tps, u8 reg, const char *val) + { +- return tps6598x_block_write(tps, reg, &val, sizeof(u32)); ++ return tps6598x_block_write(tps, reg, val, 4); + } + + static int tps6598x_read_partner_identity(struct tps6598x *tps) +diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c +index c6d431a5cce9..4288839501e9 100644 +--- a/fs/crypto/policy.c ++++ b/fs/crypto/policy.c +@@ -81,6 +81,8 @@ int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg) + if (ret == -ENODATA) { + if (!S_ISDIR(inode->i_mode)) + ret = -ENOTDIR; ++ else if (IS_DEADDIR(inode)) ++ ret = -ENOENT; + else if (!inode->i_sb->s_cop->empty_dir(inode)) + ret = -ENOTEMPTY; + else +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 53cf8599a46e..1de855e0ae61 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1243,10 +1243,20 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, + atomic_inc(&sp->so_count); + p->o_arg.open_flags = flags; + p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE); +- p->o_arg.umask = current_umask(); + p->o_arg.claim = nfs4_map_atomic_open_claim(server, claim); + p->o_arg.share_access = nfs4_map_atomic_open_share(server, + fmode, flags); ++ if (flags & O_CREAT) { ++ p->o_arg.umask = current_umask(); ++ p->o_arg.label = nfs4_label_copy(p->a_label, label); ++ if (c->sattr != NULL && c->sattr->ia_valid != 0) { ++ p->o_arg.u.attrs = &p->attrs; ++ memcpy(&p->attrs, c->sattr, sizeof(p->attrs)); ++ ++ memcpy(p->o_arg.u.verifier.data, c->verf, ++ sizeof(p->o_arg.u.verifier.data)); ++ } ++ } + /* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS + * will return permission denied for all bits until close */ + if (!(flags & O_EXCL)) { +@@ -1270,7 +1280,6 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, + p->o_arg.server = server; + p->o_arg.bitmask = nfs4_bitmask(server, label); + p->o_arg.open_bitmap = &nfs4_fattr_bitmap[0]; +- p->o_arg.label = nfs4_label_copy(p->a_label, label); + switch (p->o_arg.claim) { + case NFS4_OPEN_CLAIM_NULL: + case NFS4_OPEN_CLAIM_DELEGATE_CUR: +@@ -1283,13 +1292,6 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, + case NFS4_OPEN_CLAIM_DELEG_PREV_FH: + p->o_arg.fh = NFS_FH(d_inode(dentry)); + } +- if (c != NULL && c->sattr != NULL && c->sattr->ia_valid != 0) { +- p->o_arg.u.attrs = &p->attrs; +- memcpy(&p->attrs, c->sattr, sizeof(p->attrs)); +- +- memcpy(p->o_arg.u.verifier.data, c->verf, +- sizeof(p->o_arg.u.verifier.data)); +- } + p->c_arg.fh = &p->o_res.fh; + p->c_arg.stateid = &p->o_res.stateid; + p->c_arg.seqid = p->o_arg.seqid; +diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c +index fc20e06c56ba..dd1783ea7003 100644 +--- a/fs/quota/dquot.c ++++ b/fs/quota/dquot.c +@@ -1993,8 +1993,8 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) + &warn_to[cnt]); + if (ret) + goto over_quota; +- ret = dquot_add_space(transfer_to[cnt], cur_space, rsv_space, 0, +- &warn_to[cnt]); ++ ret = dquot_add_space(transfer_to[cnt], cur_space, rsv_space, ++ DQUOT_SPACE_WARN, &warn_to[cnt]); + if (ret) { + spin_lock(&transfer_to[cnt]->dq_dqb_lock); + dquot_decr_inodes(transfer_to[cnt], inode_usage); +diff --git a/fs/udf/inode.c b/fs/udf/inode.c +index ae796e10f68b..4c46ebf0e773 100644 +--- a/fs/udf/inode.c ++++ b/fs/udf/inode.c +@@ -470,13 +470,15 @@ static struct buffer_head *udf_getblk(struct inode *inode, udf_pblk_t block, + return NULL; + } + +-/* Extend the file by 'blocks' blocks, return the number of extents added */ ++/* Extend the file with new blocks totaling 'new_block_bytes', ++ * return the number of extents added ++ */ + static int udf_do_extend_file(struct inode *inode, + struct extent_position *last_pos, + struct kernel_long_ad *last_ext, +- sector_t blocks) ++ loff_t new_block_bytes) + { +- sector_t add; ++ uint32_t add; + int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK); + struct super_block *sb = inode->i_sb; + struct kernel_lb_addr prealloc_loc = {}; +@@ -486,7 +488,7 @@ static int udf_do_extend_file(struct inode *inode, + + /* The previous extent is fake and we should not extend by anything + * - there's nothing to do... */ +- if (!blocks && fake) ++ if (!new_block_bytes && fake) + return 0; + + iinfo = UDF_I(inode); +@@ -517,13 +519,12 @@ static int udf_do_extend_file(struct inode *inode, + /* Can we merge with the previous extent? */ + if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == + EXT_NOT_RECORDED_NOT_ALLOCATED) { +- add = ((1 << 30) - sb->s_blocksize - +- (last_ext->extLength & UDF_EXTENT_LENGTH_MASK)) >> +- sb->s_blocksize_bits; +- if (add > blocks) +- add = blocks; +- blocks -= add; +- last_ext->extLength += add << sb->s_blocksize_bits; ++ add = (1 << 30) - sb->s_blocksize - ++ (last_ext->extLength & UDF_EXTENT_LENGTH_MASK); ++ if (add > new_block_bytes) ++ add = new_block_bytes; ++ new_block_bytes -= add; ++ last_ext->extLength += add; + } + + if (fake) { +@@ -544,28 +545,27 @@ static int udf_do_extend_file(struct inode *inode, + } + + /* Managed to do everything necessary? */ +- if (!blocks) ++ if (!new_block_bytes) + goto out; + + /* All further extents will be NOT_RECORDED_NOT_ALLOCATED */ + last_ext->extLocation.logicalBlockNum = 0; + last_ext->extLocation.partitionReferenceNum = 0; +- add = (1 << (30-sb->s_blocksize_bits)) - 1; +- last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | +- (add << sb->s_blocksize_bits); ++ add = (1 << 30) - sb->s_blocksize; ++ last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | add; + + /* Create enough extents to cover the whole hole */ +- while (blocks > add) { +- blocks -= add; ++ while (new_block_bytes > add) { ++ new_block_bytes -= add; + err = udf_add_aext(inode, last_pos, &last_ext->extLocation, + last_ext->extLength, 1); + if (err) + return err; + count++; + } +- if (blocks) { ++ if (new_block_bytes) { + last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | +- (blocks << sb->s_blocksize_bits); ++ new_block_bytes; + err = udf_add_aext(inode, last_pos, &last_ext->extLocation, + last_ext->extLength, 1); + if (err) +@@ -596,6 +596,24 @@ out: + return count; + } + ++/* Extend the final block of the file to final_block_len bytes */ ++static void udf_do_extend_final_block(struct inode *inode, ++ struct extent_position *last_pos, ++ struct kernel_long_ad *last_ext, ++ uint32_t final_block_len) ++{ ++ struct super_block *sb = inode->i_sb; ++ uint32_t added_bytes; ++ ++ added_bytes = final_block_len - ++ (last_ext->extLength & (sb->s_blocksize - 1)); ++ last_ext->extLength += added_bytes; ++ UDF_I(inode)->i_lenExtents += added_bytes; ++ ++ udf_write_aext(inode, last_pos, &last_ext->extLocation, ++ last_ext->extLength, 1); ++} ++ + static int udf_extend_file(struct inode *inode, loff_t newsize) + { + +@@ -605,10 +623,12 @@ static int udf_extend_file(struct inode *inode, loff_t newsize) + int8_t etype; + struct super_block *sb = inode->i_sb; + sector_t first_block = newsize >> sb->s_blocksize_bits, offset; ++ unsigned long partial_final_block; + int adsize; + struct udf_inode_info *iinfo = UDF_I(inode); + struct kernel_long_ad extent; +- int err; ++ int err = 0; ++ int within_final_block; + + if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) + adsize = sizeof(struct short_ad); +@@ -618,18 +638,8 @@ static int udf_extend_file(struct inode *inode, loff_t newsize) + BUG(); + + etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset); ++ within_final_block = (etype != -1); + +- /* File has extent covering the new size (could happen when extending +- * inside a block)? */ +- if (etype != -1) +- return 0; +- if (newsize & (sb->s_blocksize - 1)) +- offset++; +- /* Extended file just to the boundary of the last file block? */ +- if (offset == 0) +- return 0; +- +- /* Truncate is extending the file by 'offset' blocks */ + if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) || + (epos.bh && epos.offset == sizeof(struct allocExtDesc))) { + /* File has no extents at all or has empty last +@@ -643,7 +653,22 @@ static int udf_extend_file(struct inode *inode, loff_t newsize) + &extent.extLength, 0); + extent.extLength |= etype << 30; + } +- err = udf_do_extend_file(inode, &epos, &extent, offset); ++ ++ partial_final_block = newsize & (sb->s_blocksize - 1); ++ ++ /* File has extent covering the new size (could happen when extending ++ * inside a block)? ++ */ ++ if (within_final_block) { ++ /* Extending file within the last file block */ ++ udf_do_extend_final_block(inode, &epos, &extent, ++ partial_final_block); ++ } else { ++ loff_t add = ((loff_t)offset << sb->s_blocksize_bits) | ++ partial_final_block; ++ err = udf_do_extend_file(inode, &epos, &extent, add); ++ } ++ + if (err < 0) + goto out; + err = 0; +@@ -745,6 +770,7 @@ static sector_t inode_getblk(struct inode *inode, sector_t block, + /* Are we beyond EOF? */ + if (etype == -1) { + int ret; ++ loff_t hole_len; + isBeyondEOF = true; + if (count) { + if (c) +@@ -760,7 +786,8 @@ static sector_t inode_getblk(struct inode *inode, sector_t block, + startnum = (offset > 0); + } + /* Create extents for the hole between EOF and offset */ +- ret = udf_do_extend_file(inode, &prev_epos, laarr, offset); ++ hole_len = (loff_t)offset << inode->i_blkbits; ++ ret = udf_do_extend_file(inode, &prev_epos, laarr, hole_len); + if (ret < 0) { + *err = ret; + newblock = 0; +diff --git a/include/linux/vmw_vmci_defs.h b/include/linux/vmw_vmci_defs.h +index b724ef7005de..53c5e40a2a8f 100644 +--- a/include/linux/vmw_vmci_defs.h ++++ b/include/linux/vmw_vmci_defs.h +@@ -68,9 +68,18 @@ enum { + + /* + * A single VMCI device has an upper limit of 128MB on the amount of +- * memory that can be used for queue pairs. ++ * memory that can be used for queue pairs. Since each queue pair ++ * consists of at least two pages, the memory limit also dictates the ++ * number of queue pairs a guest can create. + */ + #define VMCI_MAX_GUEST_QP_MEMORY (128 * 1024 * 1024) ++#define VMCI_MAX_GUEST_QP_COUNT (VMCI_MAX_GUEST_QP_MEMORY / PAGE_SIZE / 2) ++ ++/* ++ * There can be at most PAGE_SIZE doorbells since there is one doorbell ++ * per byte in the doorbell bitmap page. ++ */ ++#define VMCI_MAX_GUEST_DOORBELL_COUNT PAGE_SIZE + + /* + * Queues with pre-mapped data pages must be small, so that we don't pin +diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h +index 236e40ba06bf..f594eb71c274 100644 +--- a/include/net/ip6_tunnel.h ++++ b/include/net/ip6_tunnel.h +@@ -156,9 +156,12 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb, + memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); + pkt_len = skb->len - skb_inner_network_offset(skb); + err = ip6_local_out(dev_net(skb_dst(skb)->dev), sk, skb); +- if (unlikely(net_xmit_eval(err))) +- pkt_len = -1; +- iptunnel_xmit_stats(dev, pkt_len); ++ ++ if (dev) { ++ if (unlikely(net_xmit_eval(err))) ++ pkt_len = -1; ++ iptunnel_xmit_stats(dev, pkt_len); ++ } + } + #endif + #endif +diff --git a/include/uapi/linux/usb/audio.h b/include/uapi/linux/usb/audio.h +index ddc5396800aa..76b7c3f6cd0d 100644 +--- a/include/uapi/linux/usb/audio.h ++++ b/include/uapi/linux/usb/audio.h +@@ -450,6 +450,43 @@ static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_desc + } + } + ++/* ++ * Extension Unit (XU) has almost compatible layout with Processing Unit, but ++ * on UAC2, it has a different bmControls size (bControlSize); it's 1 byte for ++ * XU while 2 bytes for PU. The last iExtension field is a one-byte index as ++ * well as iProcessing field of PU. ++ */ ++static inline __u8 uac_extension_unit_bControlSize(struct uac_processing_unit_descriptor *desc, ++ int protocol) ++{ ++ switch (protocol) { ++ case UAC_VERSION_1: ++ return desc->baSourceID[desc->bNrInPins + 4]; ++ case UAC_VERSION_2: ++ return 1; /* in UAC2, this value is constant */ ++ case UAC_VERSION_3: ++ return 4; /* in UAC3, this value is constant */ ++ default: ++ return 1; ++ } ++} ++ ++static inline __u8 uac_extension_unit_iExtension(struct uac_processing_unit_descriptor *desc, ++ int protocol) ++{ ++ __u8 control_size = uac_extension_unit_bControlSize(desc, protocol); ++ ++ switch (protocol) { ++ case UAC_VERSION_1: ++ case UAC_VERSION_2: ++ default: ++ return *(uac_processing_unit_bmControls(desc, protocol) ++ + control_size); ++ case UAC_VERSION_3: ++ return 0; /* UAC3 does not have this field */ ++ } ++} ++ + /* 4.5.2 Class-Specific AS Interface Descriptor */ + struct uac1_as_header_descriptor { + __u8 bLength; /* in bytes: 7 */ +diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c +index 2faad033715f..fc500ca464d0 100644 +--- a/kernel/bpf/devmap.c ++++ b/kernel/bpf/devmap.c +@@ -186,6 +186,7 @@ static void dev_map_free(struct bpf_map *map) + if (!dev) + continue; + ++ free_percpu(dev->bulkq); + dev_put(dev->dev); + kfree(dev); + } +@@ -281,6 +282,7 @@ void __dev_map_flush(struct bpf_map *map) + unsigned long *bitmap = this_cpu_ptr(dtab->flush_needed); + u32 bit; + ++ rcu_read_lock(); + for_each_set_bit(bit, bitmap, map->max_entries) { + struct bpf_dtab_netdev *dev = READ_ONCE(dtab->netdev_map[bit]); + struct xdp_bulk_queue *bq; +@@ -291,11 +293,12 @@ void __dev_map_flush(struct bpf_map *map) + if (unlikely(!dev)) + continue; + +- __clear_bit(bit, bitmap); +- + bq = this_cpu_ptr(dev->bulkq); + bq_xmit_all(dev, bq, XDP_XMIT_FLUSH, true); ++ ++ __clear_bit(bit, bitmap); + } ++ rcu_read_unlock(); + } + + /* rcu_read_lock (from syscall and BPF contexts) ensures that if a delete and/or +@@ -388,6 +391,7 @@ static void dev_map_flush_old(struct bpf_dtab_netdev *dev) + + int cpu; + ++ rcu_read_lock(); + for_each_online_cpu(cpu) { + bitmap = per_cpu_ptr(dev->dtab->flush_needed, cpu); + __clear_bit(dev->bit, bitmap); +@@ -395,6 +399,7 @@ static void dev_map_flush_old(struct bpf_dtab_netdev *dev) + bq = per_cpu_ptr(dev->bulkq, cpu); + bq_xmit_all(dev, bq, XDP_XMIT_FLUSH, false); + } ++ rcu_read_unlock(); + } + } + +diff --git a/net/can/af_can.c b/net/can/af_can.c +index e386d654116d..04132b0b5d36 100644 +--- a/net/can/af_can.c ++++ b/net/can/af_can.c +@@ -959,6 +959,8 @@ static struct pernet_operations can_pernet_ops __read_mostly = { + + static __init int can_init(void) + { ++ int err; ++ + /* check for correct padding to be able to use the structs similarly */ + BUILD_BUG_ON(offsetof(struct can_frame, can_dlc) != + offsetof(struct canfd_frame, len) || +@@ -972,15 +974,31 @@ static __init int can_init(void) + if (!rcv_cache) + return -ENOMEM; + +- register_pernet_subsys(&can_pernet_ops); ++ err = register_pernet_subsys(&can_pernet_ops); ++ if (err) ++ goto out_pernet; + + /* protocol register */ +- sock_register(&can_family_ops); +- register_netdevice_notifier(&can_netdev_notifier); ++ err = sock_register(&can_family_ops); ++ if (err) ++ goto out_sock; ++ err = register_netdevice_notifier(&can_netdev_notifier); ++ if (err) ++ goto out_notifier; ++ + dev_add_pack(&can_packet); + dev_add_pack(&canfd_packet); + + return 0; ++ ++out_notifier: ++ sock_unregister(PF_CAN); ++out_sock: ++ unregister_pernet_subsys(&can_pernet_ops); ++out_pernet: ++ kmem_cache_destroy(rcv_cache); ++ ++ return err; + } + + static __exit void can_exit(void) +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 8b5768113acd..9b9f696281a9 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -2302,6 +2302,7 @@ do_frag_list: + kv.iov_base = skb->data + offset; + kv.iov_len = slen; + memset(&msg, 0, sizeof(msg)); ++ msg.msg_flags = MSG_DONTWAIT; + + ret = kernel_sendmsg_locked(sk, &msg, &kv, 1, slen); + if (ret <= 0) +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index 35c6dfa13fa8..cfd30671ccdf 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1410,7 +1410,7 @@ ieee80211_get_sband(struct ieee80211_sub_if_data *sdata) + rcu_read_lock(); + chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); + +- if (WARN_ON(!chanctx_conf)) { ++ if (WARN_ON_ONCE(!chanctx_conf)) { + rcu_read_unlock(); + return NULL; + } +@@ -1998,6 +1998,13 @@ void __ieee80211_flush_queues(struct ieee80211_local *local, + + static inline bool ieee80211_can_run_worker(struct ieee80211_local *local) + { ++ /* ++ * It's unsafe to try to do any work during reconfigure flow. ++ * When the flow ends the work will be requeued. ++ */ ++ if (local->in_reconfig) ++ return false; ++ + /* + * If quiescing is set, we are racing with __ieee80211_suspend. + * __ieee80211_suspend flushes the workers after setting quiescing, +diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c +index d51da26e9c18..3162f955f3ae 100644 +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -923,6 +923,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) + + /* flush STAs and mpaths on this iface */ + sta_info_flush(sdata); ++ ieee80211_free_keys(sdata, true); + mesh_path_flush_by_iface(sdata); + + /* stop the beacon */ +@@ -1212,7 +1213,8 @@ int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata) + ifmsh->chsw_ttl = 0; + + /* Remove the CSA and MCSP elements from the beacon */ +- tmp_csa_settings = rcu_dereference(ifmsh->csa); ++ tmp_csa_settings = rcu_dereference_protected(ifmsh->csa, ++ lockdep_is_held(&sdata->wdev.mtx)); + RCU_INIT_POINTER(ifmsh->csa, NULL); + if (tmp_csa_settings) + kfree_rcu(tmp_csa_settings, rcu_head); +@@ -1234,6 +1236,8 @@ int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata, + struct mesh_csa_settings *tmp_csa_settings; + int ret = 0; + ++ lockdep_assert_held(&sdata->wdev.mtx); ++ + tmp_csa_settings = kmalloc(sizeof(*tmp_csa_settings), + GFP_ATOMIC); + if (!tmp_csa_settings) +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index 2558a34c9df1..c59638574cf8 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -2224,6 +2224,10 @@ int ieee80211_reconfig(struct ieee80211_local *local) + mutex_lock(&local->mtx); + ieee80211_start_next_roc(local); + mutex_unlock(&local->mtx); ++ ++ /* Requeue all works */ ++ list_for_each_entry(sdata, &local->interfaces, list) ++ ieee80211_queue_work(&local->hw, &sdata->work); + } + + ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index 7e4553dbc3c7..0d7d149b1b1b 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -2713,6 +2713,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt, + xprt = xprt_iter_xprt(&clnt->cl_xpi); + if (xps == NULL || xprt == NULL) { + rcu_read_unlock(); ++ xprt_switch_put(xps); + return -EAGAIN; + } + resvport = xprt->resvport; +diff --git a/net/wireless/util.c b/net/wireless/util.c +index aad1c8e858e5..d57e2f679a3e 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -1219,7 +1219,7 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate) + if (rate->he_dcm) + result /= 2; + +- return result; ++ return result / 10000; + } + + u32 cfg80211_calculate_bitrate(struct rate_info *rate) +diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c +index cf40a8284a38..5061a2ec4564 100644 +--- a/samples/bpf/bpf_load.c ++++ b/samples/bpf/bpf_load.c +@@ -677,7 +677,7 @@ void read_trace_pipe(void) + static char buf[4096]; + ssize_t sz; + +- sz = read(trace_fd, buf, sizeof(buf)); ++ sz = read(trace_fd, buf, sizeof(buf) - 1); + if (sz > 0) { + buf[sz] = 0; + puts(buf); +diff --git a/samples/bpf/task_fd_query_user.c b/samples/bpf/task_fd_query_user.c +index 8381d792f138..06957f0fbe83 100644 +--- a/samples/bpf/task_fd_query_user.c ++++ b/samples/bpf/task_fd_query_user.c +@@ -216,7 +216,7 @@ static int test_debug_fs_uprobe(char *binary_path, long offset, bool is_return) + { + const char *event_type = "uprobe"; + struct perf_event_attr attr = {}; +- char buf[256], event_alias[256]; ++ char buf[256], event_alias[sizeof("test_1234567890")]; + __u64 probe_offset, probe_addr; + __u32 len, prog_id, fd_type; + int err, res, kfd, efd; +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 6453370abacc..98cfdcfce5b3 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -3236,6 +3236,7 @@ static void alc256_init(struct hda_codec *codec) + alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ + alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */ + alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15); ++ alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/ + } + + static void alc256_shutup(struct hda_codec *codec) +@@ -7686,7 +7687,6 @@ static int patch_alc269(struct hda_codec *codec) + spec->shutup = alc256_shutup; + spec->init_hook = alc256_init; + spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */ +- alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/ + break; + case 0x10ec0257: + spec->codec_variant = ALC269_TYPE_ALC257; +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index 5a10b1b7f6b9..7e1c6c2dc99e 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -2322,7 +2322,7 @@ static struct procunit_info extunits[] = { + */ + static int build_audio_procunit(struct mixer_build *state, int unitid, + void *raw_desc, struct procunit_info *list, +- char *name) ++ bool extension_unit) + { + struct uac_processing_unit_descriptor *desc = raw_desc; + int num_ins; +@@ -2339,6 +2339,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, + static struct procunit_info default_info = { + 0, NULL, default_value_info + }; ++ const char *name = extension_unit ? ++ "Extension Unit" : "Processing Unit"; + + if (desc->bLength < 13) { + usb_audio_err(state->chip, "invalid %s descriptor (id %d)\n", name, unitid); +@@ -2452,7 +2454,10 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, + } else if (info->name) { + strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name)); + } else { +- nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol); ++ if (extension_unit) ++ nameid = uac_extension_unit_iExtension(desc, state->mixer->protocol); ++ else ++ nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol); + len = 0; + if (nameid) + len = snd_usb_copy_string_desc(state->chip, +@@ -2485,10 +2490,10 @@ static int parse_audio_processing_unit(struct mixer_build *state, int unitid, + case UAC_VERSION_2: + default: + return build_audio_procunit(state, unitid, raw_desc, +- procunits, "Processing Unit"); ++ procunits, false); + case UAC_VERSION_3: + return build_audio_procunit(state, unitid, raw_desc, +- uac3_procunits, "Processing Unit"); ++ uac3_procunits, false); + } + } + +@@ -2499,8 +2504,7 @@ static int parse_audio_extension_unit(struct mixer_build *state, int unitid, + * Note that we parse extension units with processing unit descriptors. + * That's ok as the layout is the same. + */ +- return build_audio_procunit(state, unitid, raw_desc, +- extunits, "Extension Unit"); ++ return build_audio_procunit(state, unitid, raw_desc, extunits, true); + } + + /* +diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c +index 36cfc64c3824..c1acf04c9f7a 100644 +--- a/tools/perf/util/pmu.c ++++ b/tools/perf/util/pmu.c +@@ -750,9 +750,7 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu) + { + int i; + struct pmu_events_map *map; +- struct pmu_event *pe; + const char *name = pmu->name; +- const char *pname; + + map = perf_pmu__find_map(pmu); + if (!map) +@@ -763,28 +761,26 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu) + */ + i = 0; + while (1) { ++ const char *cpu_name = is_arm_pmu_core(name) ? name : "cpu"; ++ struct pmu_event *pe = &map->table[i++]; ++ const char *pname = pe->pmu ? pe->pmu : cpu_name; + +- pe = &map->table[i++]; + if (!pe->name) { + if (pe->metric_group || pe->metric_name) + continue; + break; + } + +- if (!is_arm_pmu_core(name)) { +- pname = pe->pmu ? pe->pmu : "cpu"; +- +- /* +- * uncore alias may be from different PMU +- * with common prefix +- */ +- if (pmu_is_uncore(name) && +- !strncmp(pname, name, strlen(pname))) +- goto new_alias; ++ /* ++ * uncore alias may be from different PMU ++ * with common prefix ++ */ ++ if (pmu_is_uncore(name) && ++ !strncmp(pname, name, strlen(pname))) ++ goto new_alias; + +- if (strcmp(pname, name)) +- continue; +- } ++ if (strcmp(pname, name)) ++ continue; + + new_alias: + /* need type casts to override 'const' */ +diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c +index 621bb004067e..0dbe332eb343 100644 +--- a/virt/kvm/arm/vgic/vgic-its.c ++++ b/virt/kvm/arm/vgic/vgic-its.c +@@ -1750,6 +1750,7 @@ static void vgic_its_destroy(struct kvm_device *kvm_dev) + + mutex_unlock(&its->its_lock); + kfree(its); ++ kfree(kvm_dev);/* alloc by kvm_ioctl_create_device, free by .destroy */ + } + + int vgic_its_has_attr_regs(struct kvm_device *dev, |