From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id C7B6E1584F2 for ; Thu, 13 Mar 2025 12:57:28 +0000 (UTC) Received: from lists.gentoo.org (bobolink.gentoo.org [140.211.166.189]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) (Authenticated sender: relay-lists.gentoo.org@gentoo.org) by smtp.gentoo.org (Postfix) with ESMTPSA id A988B343278 for ; Thu, 13 Mar 2025 12:57:28 +0000 (UTC) Received: from bobolink.gentoo.org (localhost [127.0.0.1]) by bobolink.gentoo.org (Postfix) with ESMTP id 440BA11037F; Thu, 13 Mar 2025 12:57:26 +0000 (UTC) Received: from smtp.gentoo.org (mail.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bobolink.gentoo.org (Postfix) with ESMTPS id 2F5BA11037F for ; Thu, 13 Mar 2025 12:57:26 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id E3F543430F1 for ; Thu, 13 Mar 2025 12:57:24 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 85AF61909 for ; Thu, 13 Mar 2025 12:57:23 +0000 (UTC) From: "Mike Pagano" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Mike Pagano" Message-ID: <1741870631.6e227c2c6a8e1d4868d0e60720b8a88aa35ea72f.mpagano@gentoo> Subject: [gentoo-commits] proj/linux-patches:5.15 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1178_linux-5.15.179.patch X-VCS-Directories: / X-VCS-Committer: mpagano X-VCS-Committer-Name: Mike Pagano X-VCS-Revision: 6e227c2c6a8e1d4868d0e60720b8a88aa35ea72f X-VCS-Branch: 5.15 Date: Thu, 13 Mar 2025 12:57:23 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 631fc599-1c7e-465b-a282-466966a46cd8 X-Archives-Hash: 23afb0f9c0e3c082954c92e816289634 commit: 6e227c2c6a8e1d4868d0e60720b8a88aa35ea72f Author: Mike Pagano gentoo org> AuthorDate: Thu Mar 13 12:57:11 2025 +0000 Commit: Mike Pagano gentoo org> CommitDate: Thu Mar 13 12:57:11 2025 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=6e227c2c Linux patch 5.15.179 Signed-off-by: Mike Pagano gentoo.org> 0000_README | 4 + 1178_linux-5.15.179.patch | 26055 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 26059 insertions(+) diff --git a/0000_README b/0000_README index 25236e9c..e9daa194 100644 --- a/0000_README +++ b/0000_README @@ -755,6 +755,10 @@ Patch: 1177_linux-5.15.178.patch From: https://www.kernel.org Desc: Linux 5.15.178 +Patch: 1178_linux-5.15.179.patch +From: https://www.kernel.org +Desc: Linux 5.15.179 + 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/1178_linux-5.15.179.patch b/1178_linux-5.15.179.patch new file mode 100644 index 00000000..35b2d264 --- /dev/null +++ b/1178_linux-5.15.179.patch @@ -0,0 +1,26055 @@ +diff --git a/Documentation/dev-tools/kfence.rst b/Documentation/dev-tools/kfence.rst +index 48244d32780f60..b6671d907836ab 100644 +--- a/Documentation/dev-tools/kfence.rst ++++ b/Documentation/dev-tools/kfence.rst +@@ -41,6 +41,18 @@ guarded by KFENCE. The default is configurable via the Kconfig option + ``CONFIG_KFENCE_SAMPLE_INTERVAL``. Setting ``kfence.sample_interval=0`` + disables KFENCE. + ++The sample interval controls a timer that sets up KFENCE allocations. By ++default, to keep the real sample interval predictable, the normal timer also ++causes CPU wake-ups when the system is completely idle. This may be undesirable ++on power-constrained systems. The boot parameter ``kfence.deferrable=1`` ++instead switches to a "deferrable" timer which does not force CPU wake-ups on ++idle systems, at the risk of unpredictable sample intervals. The default is ++configurable via the Kconfig option ``CONFIG_KFENCE_DEFERRABLE``. ++ ++.. warning:: ++ The KUnit test suite is very likely to fail when using a deferrable timer ++ since it currently causes very unpredictable sample intervals. ++ + The KFENCE memory pool is of fixed size, and if the pool is exhausted, no + further KFENCE allocations occur. With ``CONFIG_KFENCE_NUM_OBJECTS`` (default + 255), the number of available guarded objects can be controlled. Each object +diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml +index 7eb8659fa610fb..0420fa56353226 100644 +--- a/Documentation/devicetree/bindings/connector/usb-connector.yaml ++++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml +@@ -104,8 +104,7 @@ properties: + - "1.5A" and "3.0A", 5V 1.5A and 5V 3.0A respectively, as defined in USB + Type-C Cable and Connector specification, when Power Delivery is not + supported. +- allOf: +- - $ref: /schemas/types.yaml#/definitions/string ++ $ref: /schemas/types.yaml#/definitions/string + enum: + - default + - 1.5A +diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml +index a1d5a32660e0d2..a9d34dd7bbc539 100644 +--- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml ++++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml +@@ -72,8 +72,7 @@ properties: + - const: hpd-removed + + ddc: +- allOf: +- - $ref: /schemas/types.yaml#/definitions/phandle ++ $ref: /schemas/types.yaml#/definitions/phandle + description: > + Phandle of the I2C controller used for DDC EDID probing + +diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.yaml b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.yaml +index d3dd7a79b9093d..f08a01dfedf3fc 100644 +--- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.yaml ++++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.yaml +@@ -76,9 +76,8 @@ properties: + + adi,input-depth: + description: Number of bits per color component at the input. +- allOf: +- - $ref: /schemas/types.yaml#/definitions/uint32 +- - enum: [ 8, 10, 12 ] ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ enum: [ 8, 10, 12 ] + + adi,input-colorspace: + description: Input color space. +diff --git a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml +index 9be44a682e67aa..b00246faea57c8 100644 +--- a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml ++++ b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml +@@ -26,9 +26,8 @@ properties: + reg-io-width: + description: + Width (in bytes) of the registers specified by the reg property. +- allOf: +- - $ref: /schemas/types.yaml#/definitions/uint32 +- - enum: [1, 4] ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ enum: [1, 4] + default: 1 + + clocks: +diff --git a/Documentation/devicetree/bindings/display/panel/display-timings.yaml b/Documentation/devicetree/bindings/display/panel/display-timings.yaml +index 56903ded005e5c..6d30575819d3b2 100644 +--- a/Documentation/devicetree/bindings/display/panel/display-timings.yaml ++++ b/Documentation/devicetree/bindings/display/panel/display-timings.yaml +@@ -31,8 +31,7 @@ properties: + patternProperties: + "^timing": + type: object +- allOf: +- - $ref: panel-timing.yaml# ++ $ref: panel-timing.yaml# + + additionalProperties: false + +diff --git a/Documentation/devicetree/bindings/display/ste,mcde.yaml b/Documentation/devicetree/bindings/display/ste,mcde.yaml +index de0c678b3c2940..564ea845c82e05 100644 +--- a/Documentation/devicetree/bindings/display/ste,mcde.yaml ++++ b/Documentation/devicetree/bindings/display/ste,mcde.yaml +@@ -58,8 +58,8 @@ patternProperties: + "^dsi@[0-9a-f]+$": + description: subnodes for the three DSI host adapters + type: object +- allOf: +- - $ref: dsi-controller.yaml# ++ $ref: dsi-controller.yaml# ++ + properties: + compatible: + const: ste,mcde-dsi +diff --git a/Documentation/devicetree/bindings/input/adc-joystick.yaml b/Documentation/devicetree/bindings/input/adc-joystick.yaml +index 721878d5b7af23..2ee04e03bc2240 100644 +--- a/Documentation/devicetree/bindings/input/adc-joystick.yaml ++++ b/Documentation/devicetree/bindings/input/adc-joystick.yaml +@@ -61,11 +61,10 @@ patternProperties: + description: EV_ABS specific event code generated by the axis. + + abs-range: +- allOf: +- - $ref: /schemas/types.yaml#/definitions/uint32-array +- - items: +- - description: minimum value +- - description: maximum value ++ $ref: /schemas/types.yaml#/definitions/uint32-array ++ items: ++ - description: minimum value ++ - description: maximum value + description: > + Minimum and maximum values produced by the axis. + For an ABS_X axis this will be the left-most and right-most +diff --git a/Documentation/devicetree/bindings/leds/cznic,turris-omnia-leds.yaml b/Documentation/devicetree/bindings/leds/cznic,turris-omnia-leds.yaml +index c7ed2871da06a1..14bebe1ad8f8a1 100644 +--- a/Documentation/devicetree/bindings/leds/cznic,turris-omnia-leds.yaml ++++ b/Documentation/devicetree/bindings/leds/cznic,turris-omnia-leds.yaml +@@ -32,8 +32,9 @@ properties: + patternProperties: + "^multi-led@[0-9a-b]$": + type: object +- allOf: +- - $ref: leds-class-multicolor.yaml# ++ $ref: leds-class-multicolor.yaml# ++ unevaluatedProperties: false ++ + description: + This node represents one of the RGB LED devices on Turris Omnia. + No subnodes need to be added for subchannels since this controller only +diff --git a/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml b/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml +index 37445c68cdef9a..71fcd10cb9bc02 100644 +--- a/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml ++++ b/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml +@@ -19,22 +19,22 @@ description: | + LED class. Common LED nodes and properties are inherited from the common.yaml + within this documentation directory. + +-patternProperties: +- "^multi-led@([0-9a-f])$": +- type: object +- description: Represents the LEDs that are to be grouped. +- properties: +- color: +- description: | +- For multicolor LED support this property should be defined as either +- LED_COLOR_ID_RGB or LED_COLOR_ID_MULTI which can be found in +- include/linux/leds/common.h. +- enum: [ 8, 9 ] +- +- $ref: "common.yaml#" +- +- required: +- - color ++properties: ++ $nodename: ++ pattern: "^multi-led(@[0-9a-f])?$" ++ ++ color: ++ description: | ++ For multicolor LED support this property should be defined as either ++ LED_COLOR_ID_RGB or LED_COLOR_ID_MULTI which can be found in ++ include/dt-bindings/leds/common.h. ++ enum: [ 8, 9 ] ++ ++required: ++ - color ++ ++allOf: ++ - $ref: "common.yaml#" + + additionalProperties: true + +diff --git a/Documentation/devicetree/bindings/leds/leds-lp50xx.yaml b/Documentation/devicetree/bindings/leds/leds-lp50xx.yaml +index c192b5feadc76c..64d07fd20eab3a 100644 +--- a/Documentation/devicetree/bindings/leds/leds-lp50xx.yaml ++++ b/Documentation/devicetree/bindings/leds/leds-lp50xx.yaml +@@ -55,8 +55,9 @@ properties: + patternProperties: + '^multi-led@[0-9a-f]$': + type: object +- allOf: +- - $ref: leds-class-multicolor.yaml# ++ $ref: leds-class-multicolor.yaml# ++ unevaluatedProperties: false ++ + properties: + reg: + minItems: 1 +diff --git a/Documentation/devicetree/bindings/leds/leds-pwm-multicolor.yaml b/Documentation/devicetree/bindings/leds/leds-pwm-multicolor.yaml +new file mode 100644 +index 00000000000000..03fc14d1601f3c +--- /dev/null ++++ b/Documentation/devicetree/bindings/leds/leds-pwm-multicolor.yaml +@@ -0,0 +1,78 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/leds/leds-pwm-multicolor.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Multi-color LEDs connected to PWM ++ ++maintainers: ++ - Sven Schwermer ++ ++description: | ++ This driver combines several monochrome PWM LEDs into one multi-color ++ LED using the multicolor LED class. ++ ++properties: ++ compatible: ++ const: pwm-leds-multicolor ++ ++ multi-led: ++ type: object ++ $ref: leds-class-multicolor.yaml# ++ unevaluatedProperties: false ++ ++ patternProperties: ++ "^led-[0-9a-z]+$": ++ type: object ++ $ref: common.yaml# ++ ++ additionalProperties: false ++ ++ properties: ++ pwms: ++ maxItems: 1 ++ ++ pwm-names: true ++ ++ color: true ++ ++ required: ++ - pwms ++ - color ++ ++required: ++ - compatible ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ ++ led-controller { ++ compatible = "pwm-leds-multicolor"; ++ ++ multi-led { ++ color = ; ++ function = LED_FUNCTION_INDICATOR; ++ max-brightness = <65535>; ++ ++ led-red { ++ pwms = <&pwm1 0 1000000>; ++ color = ; ++ }; ++ ++ led-green { ++ pwms = <&pwm2 0 1000000>; ++ color = ; ++ }; ++ ++ led-blue { ++ pwms = <&pwm3 0 1000000>; ++ color = ; ++ }; ++ }; ++ }; ++ ++... +diff --git a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml +new file mode 100644 +index 00000000000000..6df2838d5f5b37 +--- /dev/null ++++ b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml +@@ -0,0 +1,175 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/leds/leds-qcom-lpg.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Qualcomm Light Pulse Generator ++ ++maintainers: ++ - Bjorn Andersson ++ ++description: > ++ The Qualcomm Light Pulse Generator consists of three different hardware blocks; ++ a ramp generator with lookup table, the light pulse generator and a three ++ channel current sink. These blocks are found in a wide range of Qualcomm PMICs. ++ ++properties: ++ compatible: ++ enum: ++ - qcom,pm8150b-lpg ++ - qcom,pm8150l-lpg ++ - qcom,pm8916-pwm ++ - qcom,pm8941-lpg ++ - qcom,pm8994-lpg ++ - qcom,pmc8180c-lpg ++ - qcom,pmi8994-lpg ++ - qcom,pmi8998-lpg ++ ++ "#pwm-cells": ++ const: 2 ++ ++ "#address-cells": ++ const: 1 ++ ++ "#size-cells": ++ const: 0 ++ ++ qcom,power-source: ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ description: ++ power-source used to drive the output, as defined in the datasheet. ++ Should be specified if the TRILED block is present ++ enum: [0, 1, 3] ++ ++ qcom,dtest: ++ $ref: /schemas/types.yaml#/definitions/uint32-matrix ++ description: > ++ A list of integer pairs, where each pair represent the dtest line the ++ particular channel should be connected to and the flags denoting how the ++ value should be outputed, as defined in the datasheet. The number of ++ pairs should be the same as the number of channels. ++ items: ++ items: ++ - description: dtest line to attach ++ - description: flags for the attachment ++ ++ multi-led: ++ type: object ++ $ref: leds-class-multicolor.yaml# ++ unevaluatedProperties: false ++ ++ properties: ++ "#address-cells": ++ const: 1 ++ ++ "#size-cells": ++ const: 0 ++ ++ patternProperties: ++ "^led@[0-9a-f]$": ++ type: object ++ $ref: common.yaml# ++ ++patternProperties: ++ "^led@[0-9a-f]$": ++ type: object ++ $ref: common.yaml# ++ ++ properties: ++ reg: true ++ ++ required: ++ - reg ++ ++required: ++ - compatible ++ ++additionalProperties: false ++ ++examples: ++ - | ++ #include ++ ++ led-controller { ++ compatible = "qcom,pmi8994-lpg"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ qcom,power-source = <1>; ++ ++ qcom,dtest = <0 0>, ++ <0 0>, ++ <0 0>, ++ <4 1>; ++ ++ led@1 { ++ reg = <1>; ++ color = ; ++ function = LED_FUNCTION_INDICATOR; ++ function-enumerator = <1>; ++ }; ++ ++ led@2 { ++ reg = <2>; ++ color = ; ++ function = LED_FUNCTION_INDICATOR; ++ function-enumerator = <0>; ++ default-state = "on"; ++ }; ++ ++ led@3 { ++ reg = <3>; ++ color = ; ++ function = LED_FUNCTION_INDICATOR; ++ function-enumerator = <2>; ++ }; ++ ++ led@4 { ++ reg = <4>; ++ color = ; ++ function = LED_FUNCTION_INDICATOR; ++ function-enumerator = <3>; ++ }; ++ }; ++ - | ++ #include ++ ++ led-controller { ++ compatible = "qcom,pmi8994-lpg"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ qcom,power-source = <1>; ++ ++ multi-led { ++ color = ; ++ function = LED_FUNCTION_STATUS; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ led@1 { ++ reg = <1>; ++ color = ; ++ }; ++ ++ led@2 { ++ reg = <2>; ++ color = ; ++ }; ++ ++ led@3 { ++ reg = <3>; ++ color = ; ++ }; ++ }; ++ }; ++ - | ++ pwm-controller { ++ compatible = "qcom,pm8916-pwm"; ++ #pwm-cells = <2>; ++ }; ++... +diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml +index d793dd0316b751..546746c2e406d7 100644 +--- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml ++++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml +@@ -39,18 +39,14 @@ properties: + description: + This property specifies the delay in usecs between the + assertion of the CS and the first clock pulse. +- allOf: +- - $ref: /schemas/types.yaml#/definitions/uint32 +- - default: 0 +- - minimum: 0 ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ default: 0 + + google,cros-ec-spi-msg-delay: + description: + This property specifies the delay in usecs between messages. +- allOf: +- - $ref: /schemas/types.yaml#/definitions/uint32 +- - default: 0 +- - minimum: 0 ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ default: 0 + + google,has-vbc-nvram: + description: +diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml +index fe265bcab50d9f..91df60d5662924 100644 +--- a/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml ++++ b/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml +@@ -50,15 +50,15 @@ properties: + minimum: 0 + maximum: 1 + +- rohm,charger-sense-resistor-ohms: +- minimum: 10000000 +- maximum: 50000000 ++ rohm,charger-sense-resistor-micro-ohms: ++ minimum: 10000 ++ maximum: 50000 + description: | +- BD71827 and BD71828 have SAR ADC for measuring charging currents. +- External sense resistor (RSENSE in data sheet) should be used. If +- something other but 30MOhm resistor is used the resistance value +- should be given here in Ohms. +- default: 30000000 ++ BD71815 has SAR ADC for measuring charging currents. External sense ++ resistor (RSENSE in data sheet) should be used. If something other ++ but a 30 mOhm resistor is used the resistance value should be given ++ here in micro Ohms. ++ default: 30000 + + regulators: + $ref: ../regulator/rohm,bd71815-regulator.yaml +@@ -67,7 +67,7 @@ properties: + + gpio-reserved-ranges: + description: | +- Usage of BD71828 GPIO pins can be changed via OTP. This property can be ++ Usage of BD71815 GPIO pins can be changed via OTP. This property can be + used to mark the pins which should not be configured for GPIO. Please see + the ../gpio/gpio.txt for more information. + +@@ -113,7 +113,7 @@ examples: + gpio-controller; + #gpio-cells = <2>; + +- rohm,charger-sense-resistor-ohms = <10000000>; ++ rohm,charger-sense-resistor-micro-ohms = <10000>; + + regulators { + buck1: buck1 { +diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml +index 25ac8e20097083..093bdad8daf82e 100644 +--- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml ++++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml +@@ -25,7 +25,7 @@ properties: + "#address-cells": + const: 1 + description: | +- The cell is the slot ID if a function subnode is used. ++ The cell is the SDIO function number if a function subnode is used. + + "#size-cells": + const: 0 +diff --git a/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml b/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml +index 0922536b181144..d681a4676f0693 100644 +--- a/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml ++++ b/Documentation/devicetree/bindings/mtd/rockchip,nand-controller.yaml +@@ -96,8 +96,7 @@ patternProperties: + + rockchip,boot-ecc-strength: + enum: [16, 24, 40, 60, 70] +- allOf: +- - $ref: /schemas/types.yaml#/definitions/uint32 ++ $ref: /schemas/types.yaml#/definitions/uint32 + description: | + If specified it indicates that a different BCH/ECC setting is + supported by the boot ROM. +diff --git a/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml b/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml +index 07a00f53adbf96..31bf825c65987c 100644 +--- a/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml ++++ b/Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml +@@ -88,8 +88,7 @@ properties: + type: object + description: CPSW external ports + +- allOf: +- - $ref: ethernet-controller.yaml# ++ $ref: ethernet-controller.yaml# + + properties: + reg: +diff --git a/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml b/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml +index 3329f1d33a4fea..3da0c4ee45cff7 100644 +--- a/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml ++++ b/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml +@@ -76,8 +76,7 @@ patternProperties: + + connector: + type: object +- allOf: +- - $ref: ../connector/usb-connector.yaml ++ $ref: /schemas/connector/usb-connector.yaml + properties: + vbus-supply: true + +diff --git a/Documentation/devicetree/bindings/power/supply/sbs,sbs-manager.yaml b/Documentation/devicetree/bindings/power/supply/sbs,sbs-manager.yaml +index 72e8f274c791d7..99f506d6b0a022 100644 +--- a/Documentation/devicetree/bindings/power/supply/sbs,sbs-manager.yaml ++++ b/Documentation/devicetree/bindings/power/supply/sbs,sbs-manager.yaml +@@ -46,9 +46,7 @@ additionalProperties: false + patternProperties: + "^i2c@[1-4]$": + type: object +- +- allOf: +- - $ref: /schemas/i2c/i2c-controller.yaml# ++ $ref: /schemas/i2c/i2c-controller.yaml# + + examples: + - | +diff --git a/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml b/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml +index 37402c370fbbc8..eed0b3fa2d82ca 100644 +--- a/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml ++++ b/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml +@@ -30,10 +30,6 @@ properties: + type: object + $ref: "regulator.yaml#" + +- properties: +- regulator-compatible: +- pattern: "^vbuck[1-4]$" +- + additionalProperties: false + + required: +@@ -51,7 +47,6 @@ examples: + + regulators { + vbuck1 { +- regulator-compatible = "vbuck1"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; +@@ -59,7 +54,6 @@ examples: + }; + + vbuck3 { +- regulator-compatible = "vbuck3"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1193750>; + regulator-enable-ramp-delay = <256>; +diff --git a/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml +index 130fbaacc4b153..3daa4b37f4f6dd 100644 +--- a/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml ++++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-r5f-rproc.yaml +@@ -94,8 +94,7 @@ patternProperties: + addresses. Cache and memory access settings are provided through a + Memory Protection Unit (MPU), programmable only from the R5Fs. + +- allOf: +- - $ref: /schemas/arm/keystone/ti,k3-sci-common.yaml# ++ $ref: /schemas/arm/keystone/ti,k3-sci-common.yaml# + + properties: + compatible: +diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml +index 9d128b9e7deb6f..64461d4320048e 100644 +--- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml ++++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml +@@ -281,10 +281,7 @@ patternProperties: + PRUSS INTC Node. Each PRUSS has a single interrupt controller instance + that is common to all the PRU cores. This should be represented as an + interrupt-controller node. +- +- allOf: +- - $ref: /schemas/interrupt-controller/ti,pruss-intc.yaml# +- ++ $ref: /schemas/interrupt-controller/ti,pruss-intc.yaml# + type: object + + mdio@[a-f0-9]+$: +@@ -292,10 +289,7 @@ patternProperties: + MDIO Node. Each PRUSS has an MDIO module that can be used to control + external PHYs. The MDIO module used within the PRU-ICSS is an instance of + the MDIO Controller used in TI Davinci SoCs. +- +- allOf: +- - $ref: /schemas/net/ti,davinci-mdio.yaml# +- ++ $ref: /schemas/net/ti,davinci-mdio.yaml# + type: object + + "^(pru|rtu|txpru)@[0-9a-f]+$": +@@ -305,10 +299,7 @@ patternProperties: + inactive by using the standard DT string property, "status". The ICSSG IP + present on K3 SoCs have additional auxiliary PRU cores with slightly + different IP integration. +- +- allOf: +- - $ref: /schemas/remoteproc/ti,pru-rproc.yaml# +- ++ $ref: /schemas/remoteproc/ti,pru-rproc.yaml# + type: object + + required: +diff --git a/Documentation/devicetree/bindings/sound/st,stm32-sai.yaml b/Documentation/devicetree/bindings/sound/st,stm32-sai.yaml +index f97132400bb609..2c5e237db49951 100644 +--- a/Documentation/devicetree/bindings/sound/st,stm32-sai.yaml ++++ b/Documentation/devicetree/bindings/sound/st,stm32-sai.yaml +@@ -113,8 +113,7 @@ patternProperties: + By default, custom protocol is assumed, meaning that protocol is + configured according to protocol defined in related DAI link node, + such as i2s, left justified, right justified, dsp and pdm protocols. +- allOf: +- - $ref: /schemas/types.yaml#/definitions/flag ++ $ref: /schemas/types.yaml#/definitions/flag + + "#clock-cells": + description: Configure the SAI device as master clock provider. +diff --git a/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml b/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml +index d77c8283526d94..2ad17b361db0a6 100644 +--- a/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml ++++ b/Documentation/devicetree/bindings/sound/tlv320adcx140.yaml +@@ -176,13 +176,12 @@ patternProperties: + 4 - Drive weak low and active high + 5 - Drive Hi-Z and active high + +- allOf: +- - $ref: /schemas/types.yaml#/definitions/uint32-array +- - minItems: 2 +- maxItems: 2 +- items: +- maximum: 15 +- default: [2, 2] ++ $ref: /schemas/types.yaml#/definitions/uint32-array ++ minItems: 2 ++ maxItems: 2 ++ items: ++ maximum: 15 ++ default: [2, 2] + + required: + - compatible +diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml +index 8246891602e776..6d0511a8727f77 100644 +--- a/Documentation/devicetree/bindings/spi/spi-controller.yaml ++++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml +@@ -93,74 +93,7 @@ properties: + patternProperties: + "^.*@[0-9a-f]+$": + type: object +- +- properties: +- compatible: +- description: +- Compatible of the SPI device. +- +- reg: +- minItems: 1 +- maxItems: 256 +- items: +- minimum: 0 +- maximum: 256 +- description: +- Chip select used by the device. +- +- spi-3wire: +- $ref: /schemas/types.yaml#/definitions/flag +- description: +- The device requires 3-wire mode. +- +- spi-cpha: +- $ref: /schemas/types.yaml#/definitions/flag +- description: +- The device requires shifted clock phase (CPHA) mode. +- +- spi-cpol: +- $ref: /schemas/types.yaml#/definitions/flag +- description: +- The device requires inverse clock polarity (CPOL) mode. +- +- spi-cs-high: +- $ref: /schemas/types.yaml#/definitions/flag +- description: +- The device requires the chip select active high. +- +- spi-lsb-first: +- $ref: /schemas/types.yaml#/definitions/flag +- description: +- The device requires the LSB first mode. +- +- spi-max-frequency: +- $ref: /schemas/types.yaml#/definitions/uint32 +- description: +- Maximum SPI clocking speed of the device in Hz. +- +- spi-rx-bus-width: +- description: +- Bus width to the SPI bus used for read transfers. +- If 0 is provided, then no RX will be possible on this device. +- $ref: /schemas/types.yaml#/definitions/uint32 +- enum: [0, 1, 2, 4, 8] +- default: 1 +- +- spi-rx-delay-us: +- description: +- Delay, in microseconds, after a read transfer. +- +- spi-tx-bus-width: +- description: +- Bus width to the SPI bus used for write transfers. +- If 0 is provided, then no TX will be possible on this device. +- $ref: /schemas/types.yaml#/definitions/uint32 +- enum: [0, 1, 2, 4, 8] +- default: 1 +- +- spi-tx-delay-us: +- description: +- Delay, in microseconds, after a write transfer. ++ $ref: spi-peripheral-props.yaml + + required: + - compatible +diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml +new file mode 100644 +index 00000000000000..105fa2840e72ab +--- /dev/null ++++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml +@@ -0,0 +1,87 @@ ++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/spi/spi-peripheral-props.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Peripheral-specific properties for a SPI bus. ++ ++description: ++ Many SPI controllers need to add properties to peripheral devices. They could ++ be common properties like spi-max-frequency, spi-cpha, etc. or they could be ++ controller specific like delay in clock or data lines, etc. These properties ++ need to be defined in the peripheral node because they are per-peripheral and ++ there can be multiple peripherals attached to a controller. All those ++ properties are listed here. The controller specific properties should go in ++ their own separate schema that should be referenced from here. ++ ++maintainers: ++ - Pratyush Yadav ++ ++properties: ++ reg: ++ minItems: 1 ++ maxItems: 256 ++ items: ++ minimum: 0 ++ maximum: 256 ++ description: ++ Chip select used by the device. ++ ++ spi-3wire: ++ $ref: /schemas/types.yaml#/definitions/flag ++ description: ++ The device requires 3-wire mode. ++ ++ spi-cpha: ++ $ref: /schemas/types.yaml#/definitions/flag ++ description: ++ The device requires shifted clock phase (CPHA) mode. ++ ++ spi-cpol: ++ $ref: /schemas/types.yaml#/definitions/flag ++ description: ++ The device requires inverse clock polarity (CPOL) mode. ++ ++ spi-cs-high: ++ $ref: /schemas/types.yaml#/definitions/flag ++ description: ++ The device requires the chip select active high. ++ ++ spi-lsb-first: ++ $ref: /schemas/types.yaml#/definitions/flag ++ description: ++ The device requires the LSB first mode. ++ ++ spi-max-frequency: ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ description: ++ Maximum SPI clocking speed of the device in Hz. ++ ++ spi-rx-bus-width: ++ description: ++ Bus width to the SPI bus used for read transfers. ++ If 0 is provided, then no RX will be possible on this device. ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ enum: [0, 1, 2, 4, 8] ++ default: 1 ++ ++ spi-rx-delay-us: ++ description: ++ Delay, in microseconds, after a read transfer. ++ ++ spi-tx-bus-width: ++ description: ++ Bus width to the SPI bus used for write transfers. ++ If 0 is provided, then no TX will be possible on this device. ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ enum: [0, 1, 2, 4, 8] ++ default: 1 ++ ++ spi-tx-delay-us: ++ description: ++ Delay, in microseconds, after a write transfer. ++ ++# The controller specific properties go here. ++ ++additionalProperties: true +diff --git a/Documentation/devicetree/bindings/usb/st,stusb160x.yaml b/Documentation/devicetree/bindings/usb/st,stusb160x.yaml +index 9a51efa9d101ea..35477fc6d9f43f 100644 +--- a/Documentation/devicetree/bindings/usb/st,stusb160x.yaml ++++ b/Documentation/devicetree/bindings/usb/st,stusb160x.yaml +@@ -32,9 +32,7 @@ properties: + + connector: + type: object +- +- allOf: +- - $ref: ../connector/usb-connector.yaml ++ $ref: /schemas/connector/usb-connector.yaml# + + properties: + compatible: +diff --git a/Documentation/kbuild/kconfig.rst b/Documentation/kbuild/kconfig.rst +index 5967c79c3baa76..eee0d298774abf 100644 +--- a/Documentation/kbuild/kconfig.rst ++++ b/Documentation/kbuild/kconfig.rst +@@ -54,6 +54,15 @@ KCONFIG_OVERWRITECONFIG + If you set KCONFIG_OVERWRITECONFIG in the environment, Kconfig will not + break symlinks when .config is a symlink to somewhere else. + ++KCONFIG_WARN_UNKNOWN_SYMBOLS ++---------------------------- ++This environment variable makes Kconfig warn about all unrecognized ++symbols in the config input. ++ ++KCONFIG_WERROR ++-------------- ++If set, Kconfig treats warnings as errors. ++ + `CONFIG_` + --------- + If you set `CONFIG_` in the environment, Kconfig will prefix all symbols +diff --git a/Makefile b/Makefile +index 7f7c67db948cab..6b3a24466e2882 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 15 +-SUBLEVEL = 178 ++SUBLEVEL = 179 + EXTRAVERSION = + NAME = Trick or Treat + +@@ -1114,6 +1114,11 @@ endif + KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CFLAGS)) + KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CFLAGS)) + ++# userspace programs are linked via the compiler, use the correct linker ++ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_LD_IS_LLD),yy) ++KBUILD_USERLDFLAGS += $(call cc-option, --ld-path=$(LD)) ++endif ++ + # make the checker run with the right architecture + CHECKFLAGS += --arch=$(ARCH) + +diff --git a/arch/alpha/include/uapi/asm/ptrace.h b/arch/alpha/include/uapi/asm/ptrace.h +index c29194181025f5..22170f7b8be86c 100644 +--- a/arch/alpha/include/uapi/asm/ptrace.h ++++ b/arch/alpha/include/uapi/asm/ptrace.h +@@ -42,6 +42,8 @@ struct pt_regs { + unsigned long trap_a0; + unsigned long trap_a1; + unsigned long trap_a2; ++/* This makes the stack 16-byte aligned as GCC expects */ ++ unsigned long __pad0; + /* These are saved by PAL-code: */ + unsigned long ps; + unsigned long pc; +diff --git a/arch/alpha/kernel/asm-offsets.c b/arch/alpha/kernel/asm-offsets.c +index 2e125e5c1508c3..05d9296af5ea6a 100644 +--- a/arch/alpha/kernel/asm-offsets.c ++++ b/arch/alpha/kernel/asm-offsets.c +@@ -32,7 +32,9 @@ void foo(void) + DEFINE(CRED_EGID, offsetof(struct cred, egid)); + BLANK(); + ++ DEFINE(SP_OFF, offsetof(struct pt_regs, ps)); + DEFINE(SIZEOF_PT_REGS, sizeof(struct pt_regs)); ++ DEFINE(SWITCH_STACK_SIZE, sizeof(struct switch_stack)); + DEFINE(PT_PTRACED, PT_PTRACED); + DEFINE(CLONE_VM, CLONE_VM); + DEFINE(CLONE_UNTRACED, CLONE_UNTRACED); +diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S +index c41a5a9c3b9f23..ba99cc9d27c7ca 100644 +--- a/arch/alpha/kernel/entry.S ++++ b/arch/alpha/kernel/entry.S +@@ -15,10 +15,6 @@ + .set noat + .cfi_sections .debug_frame + +-/* Stack offsets. */ +-#define SP_OFF 184 +-#define SWITCH_STACK_SIZE 320 +- + .macro CFI_START_OSF_FRAME func + .align 4 + .globl \func +@@ -199,8 +195,8 @@ CFI_END_OSF_FRAME entArith + CFI_START_OSF_FRAME entMM + SAVE_ALL + /* save $9 - $15 so the inline exception code can manipulate them. */ +- subq $sp, 56, $sp +- .cfi_adjust_cfa_offset 56 ++ subq $sp, 64, $sp ++ .cfi_adjust_cfa_offset 64 + stq $9, 0($sp) + stq $10, 8($sp) + stq $11, 16($sp) +@@ -215,7 +211,7 @@ CFI_START_OSF_FRAME entMM + .cfi_rel_offset $13, 32 + .cfi_rel_offset $14, 40 + .cfi_rel_offset $15, 48 +- addq $sp, 56, $19 ++ addq $sp, 64, $19 + /* handle the fault */ + lda $8, 0x3fff + bic $sp, $8, $8 +@@ -228,7 +224,7 @@ CFI_START_OSF_FRAME entMM + ldq $13, 32($sp) + ldq $14, 40($sp) + ldq $15, 48($sp) +- addq $sp, 56, $sp ++ addq $sp, 64, $sp + .cfi_restore $9 + .cfi_restore $10 + .cfi_restore $11 +@@ -236,7 +232,7 @@ CFI_START_OSF_FRAME entMM + .cfi_restore $13 + .cfi_restore $14 + .cfi_restore $15 +- .cfi_adjust_cfa_offset -56 ++ .cfi_adjust_cfa_offset -64 + /* finish up the syscall as normal. */ + br ret_from_sys_call + CFI_END_OSF_FRAME entMM +@@ -383,8 +379,8 @@ entUnaUser: + .cfi_restore $0 + .cfi_adjust_cfa_offset -256 + SAVE_ALL /* setup normal kernel stack */ +- lda $sp, -56($sp) +- .cfi_adjust_cfa_offset 56 ++ lda $sp, -64($sp) ++ .cfi_adjust_cfa_offset 64 + stq $9, 0($sp) + stq $10, 8($sp) + stq $11, 16($sp) +@@ -400,7 +396,7 @@ entUnaUser: + .cfi_rel_offset $14, 40 + .cfi_rel_offset $15, 48 + lda $8, 0x3fff +- addq $sp, 56, $19 ++ addq $sp, 64, $19 + bic $sp, $8, $8 + jsr $26, do_entUnaUser + ldq $9, 0($sp) +@@ -410,7 +406,7 @@ entUnaUser: + ldq $13, 32($sp) + ldq $14, 40($sp) + ldq $15, 48($sp) +- lda $sp, 56($sp) ++ lda $sp, 64($sp) + .cfi_restore $9 + .cfi_restore $10 + .cfi_restore $11 +@@ -418,7 +414,7 @@ entUnaUser: + .cfi_restore $13 + .cfi_restore $14 + .cfi_restore $15 +- .cfi_adjust_cfa_offset -56 ++ .cfi_adjust_cfa_offset -64 + br ret_from_sys_call + CFI_END_OSF_FRAME entUna + +diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c +index afaf4f6ad0f495..a78e93256ecb12 100644 +--- a/arch/alpha/kernel/traps.c ++++ b/arch/alpha/kernel/traps.c +@@ -709,7 +709,7 @@ s_reg_to_mem (unsigned long s_reg) + static int unauser_reg_offsets[32] = { + R(r0), R(r1), R(r2), R(r3), R(r4), R(r5), R(r6), R(r7), R(r8), + /* r9 ... r15 are stored in front of regs. */ +- -56, -48, -40, -32, -24, -16, -8, ++ -64, -56, -48, -40, -32, -24, -16, /* padding at -8 */ + R(r16), R(r17), R(r18), + R(r19), R(r20), R(r21), R(r22), R(r23), R(r24), R(r25), R(r26), + R(r27), R(r28), R(gp), +diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c +index e9193d52222eaa..56ea2856e48882 100644 +--- a/arch/alpha/mm/fault.c ++++ b/arch/alpha/mm/fault.c +@@ -78,8 +78,8 @@ __load_new_mm_context(struct mm_struct *next_mm) + + /* Macro for exception fixup code to access integer registers. */ + #define dpf_reg(r) \ +- (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-16 : \ +- (r) <= 18 ? (r)+10 : (r)-10]) ++ (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-17 : \ ++ (r) <= 18 ? (r)+11 : (r)-10]) + + asmlinkage void + do_page_fault(unsigned long address, unsigned long mmcsr, +diff --git a/arch/arm/boot/dts/dra7-l4.dtsi b/arch/arm/boot/dts/dra7-l4.dtsi +index 5733e3a4ea8e71..3fdb79b0e8bfe7 100644 +--- a/arch/arm/boot/dts/dra7-l4.dtsi ++++ b/arch/arm/boot/dts/dra7-l4.dtsi +@@ -12,6 +12,7 @@ &l4_cfg { /* 0x4a000000 */ + ranges = <0x00000000 0x4a000000 0x100000>, /* segment 0 */ + <0x00100000 0x4a100000 0x100000>, /* segment 1 */ + <0x00200000 0x4a200000 0x100000>; /* segment 2 */ ++ dma-ranges; + + segment@0 { /* 0x4a000000 */ + compatible = "simple-pm-bus"; +@@ -557,6 +558,7 @@ segment@100000 { /* 0x4a100000 */ + <0x0007e000 0x0017e000 0x001000>, /* ap 124 */ + <0x00059000 0x00159000 0x001000>, /* ap 125 */ + <0x0005a000 0x0015a000 0x001000>; /* ap 126 */ ++ dma-ranges; + + target-module@2000 { /* 0x4a102000, ap 27 3c.0 */ + compatible = "ti,sysc"; +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +index a7d62dbad6026b..64756888fd0d11 100644 +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -309,7 +309,7 @@ pwrap: pwrap@1000d000 { + clock-names = "spi", "wrap"; + }; + +- cir: cir@10013000 { ++ cir: ir-receiver@10013000 { + compatible = "mediatek,mt7623-cir"; + reg = <0 0x10013000 0 0x1000>; + interrupts = ; +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index c8cc993ca8ca13..91efc3d4de61d8 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -403,7 +403,21 @@ static int at91_suspend_finish(unsigned long val) + return 0; + } + +-static void at91_pm_switch_ba_to_vbat(void) ++/** ++ * at91_pm_switch_ba_to_auto() - Configure Backup Unit Power Switch ++ * to automatic/hardware mode. ++ * ++ * The Backup Unit Power Switch can be managed either by software or hardware. ++ * Enabling hardware mode allows the automatic transition of power between ++ * VDDANA (or VDDIN33) and VDDBU (or VBAT, respectively), based on the ++ * availability of these power sources. ++ * ++ * If the Backup Unit Power Switch is already in automatic mode, no action is ++ * required. If it is in software-controlled mode, it is switched to automatic ++ * mode to enhance safety and eliminate the need for toggling between power ++ * sources. ++ */ ++static void at91_pm_switch_ba_to_auto(void) + { + unsigned int offset = offsetof(struct at91_pm_sfrbu_regs, pswbu); + unsigned int val; +@@ -414,24 +428,19 @@ static void at91_pm_switch_ba_to_vbat(void) + + val = readl(soc_pm.data.sfrbu + offset); + +- /* Already on VBAT. */ +- if (!(val & soc_pm.sfrbu_regs.pswbu.state)) ++ /* Already on auto/hardware. */ ++ if (!(val & soc_pm.sfrbu_regs.pswbu.ctrl)) + return; + +- val &= ~soc_pm.sfrbu_regs.pswbu.softsw; +- val |= soc_pm.sfrbu_regs.pswbu.key | soc_pm.sfrbu_regs.pswbu.ctrl; ++ val &= ~soc_pm.sfrbu_regs.pswbu.ctrl; ++ val |= soc_pm.sfrbu_regs.pswbu.key; + writel(val, soc_pm.data.sfrbu + offset); +- +- /* Wait for update. */ +- val = readl(soc_pm.data.sfrbu + offset); +- while (val & soc_pm.sfrbu_regs.pswbu.state) +- val = readl(soc_pm.data.sfrbu + offset); + } + + static void at91_pm_suspend(suspend_state_t state) + { + if (soc_pm.data.mode == AT91_PM_BACKUP) { +- at91_pm_switch_ba_to_vbat(); ++ at91_pm_switch_ba_to_auto(); + + cpu_suspend(0, at91_suspend_finish); + +diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi +index e666ebb28980aa..7d15be690894cb 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi +@@ -914,7 +914,7 @@ pmic: mt6397 { + interrupt-controller; + #interrupt-cells = <2>; + +- clock: mt6397clock { ++ clock: clocks { + compatible = "mediatek,mt6397-clk"; + #clock-cells = <1>; + }; +@@ -926,11 +926,10 @@ pio6397: pinctrl { + #gpio-cells = <2>; + }; + +- regulator: mt6397regulator { ++ regulators { + compatible = "mediatek,mt6397-regulator"; + + mt6397_vpca15_reg: buck_vpca15 { +- regulator-compatible = "buck_vpca15"; + regulator-name = "vpca15"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -940,7 +939,6 @@ mt6397_vpca15_reg: buck_vpca15 { + }; + + mt6397_vpca7_reg: buck_vpca7 { +- regulator-compatible = "buck_vpca7"; + regulator-name = "vpca7"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -950,7 +948,6 @@ mt6397_vpca7_reg: buck_vpca7 { + }; + + mt6397_vsramca15_reg: buck_vsramca15 { +- regulator-compatible = "buck_vsramca15"; + regulator-name = "vsramca15"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -959,7 +956,6 @@ mt6397_vsramca15_reg: buck_vsramca15 { + }; + + mt6397_vsramca7_reg: buck_vsramca7 { +- regulator-compatible = "buck_vsramca7"; + regulator-name = "vsramca7"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -968,7 +964,6 @@ mt6397_vsramca7_reg: buck_vsramca7 { + }; + + mt6397_vcore_reg: buck_vcore { +- regulator-compatible = "buck_vcore"; + regulator-name = "vcore"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -977,7 +972,6 @@ mt6397_vcore_reg: buck_vcore { + }; + + mt6397_vgpu_reg: buck_vgpu { +- regulator-compatible = "buck_vgpu"; + regulator-name = "vgpu"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -986,7 +980,6 @@ mt6397_vgpu_reg: buck_vgpu { + }; + + mt6397_vdrm_reg: buck_vdrm { +- regulator-compatible = "buck_vdrm"; + regulator-name = "vdrm"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1400000>; +@@ -995,7 +988,6 @@ mt6397_vdrm_reg: buck_vdrm { + }; + + mt6397_vio18_reg: buck_vio18 { +- regulator-compatible = "buck_vio18"; + regulator-name = "vio18"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <1980000>; +@@ -1004,18 +996,15 @@ mt6397_vio18_reg: buck_vio18 { + }; + + mt6397_vtcxo_reg: ldo_vtcxo { +- regulator-compatible = "ldo_vtcxo"; + regulator-name = "vtcxo"; + regulator-always-on; + }; + + mt6397_va28_reg: ldo_va28 { +- regulator-compatible = "ldo_va28"; + regulator-name = "va28"; + }; + + mt6397_vcama_reg: ldo_vcama { +- regulator-compatible = "ldo_vcama"; + regulator-name = "vcama"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +@@ -1023,18 +1012,15 @@ mt6397_vcama_reg: ldo_vcama { + }; + + mt6397_vio28_reg: ldo_vio28 { +- regulator-compatible = "ldo_vio28"; + regulator-name = "vio28"; + regulator-always-on; + }; + + mt6397_vusb_reg: ldo_vusb { +- regulator-compatible = "ldo_vusb"; + regulator-name = "vusb"; + }; + + mt6397_vmc_reg: ldo_vmc { +- regulator-compatible = "ldo_vmc"; + regulator-name = "vmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; +@@ -1042,7 +1028,6 @@ mt6397_vmc_reg: ldo_vmc { + }; + + mt6397_vmch_reg: ldo_vmch { +- regulator-compatible = "ldo_vmch"; + regulator-name = "vmch"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; +@@ -1050,7 +1035,6 @@ mt6397_vmch_reg: ldo_vmch { + }; + + mt6397_vemc_3v3_reg: ldo_vemc3v3 { +- regulator-compatible = "ldo_vemc3v3"; + regulator-name = "vemc_3v3"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; +@@ -1058,7 +1042,6 @@ mt6397_vemc_3v3_reg: ldo_vemc3v3 { + }; + + mt6397_vgp1_reg: ldo_vgp1 { +- regulator-compatible = "ldo_vgp1"; + regulator-name = "vcamd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +@@ -1066,7 +1049,6 @@ mt6397_vgp1_reg: ldo_vgp1 { + }; + + mt6397_vgp2_reg: ldo_vgp2 { +- regulator-compatible = "ldo_vgp2"; + regulator-name = "vcamio"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; +@@ -1074,7 +1056,6 @@ mt6397_vgp2_reg: ldo_vgp2 { + }; + + mt6397_vgp3_reg: ldo_vgp3 { +- regulator-compatible = "ldo_vgp3"; + regulator-name = "vcamaf"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +@@ -1082,7 +1063,6 @@ mt6397_vgp3_reg: ldo_vgp3 { + }; + + mt6397_vgp4_reg: ldo_vgp4 { +- regulator-compatible = "ldo_vgp4"; + regulator-name = "vgp4"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; +@@ -1090,7 +1070,6 @@ mt6397_vgp4_reg: ldo_vgp4 { + }; + + mt6397_vgp5_reg: ldo_vgp5 { +- regulator-compatible = "ldo_vgp5"; + regulator-name = "vgp5"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3000000>; +@@ -1098,7 +1077,6 @@ mt6397_vgp5_reg: ldo_vgp5 { + }; + + mt6397_vgp6_reg: ldo_vgp6 { +- regulator-compatible = "ldo_vgp6"; + regulator-name = "vgp6"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; +@@ -1107,7 +1085,6 @@ mt6397_vgp6_reg: ldo_vgp6 { + }; + + mt6397_vibr_reg: ldo_vibr { +- regulator-compatible = "ldo_vibr"; + regulator-name = "vibr"; + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <3300000>; +@@ -1115,7 +1092,7 @@ mt6397_vibr_reg: ldo_vibr { + }; + }; + +- rtc: mt6397rtc { ++ rtc: rtc { + compatible = "mediatek,mt6397-rtc"; + }; + +diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +index 4e0c3aa264a5c5..52b56069c51d69 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +@@ -307,11 +307,10 @@ pmic: mt6397 { + interrupt-controller; + #interrupt-cells = <2>; + +- mt6397regulator: mt6397regulator { ++ regulators { + compatible = "mediatek,mt6397-regulator"; + + mt6397_vpca15_reg: buck_vpca15 { +- regulator-compatible = "buck_vpca15"; + regulator-name = "vpca15"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -320,7 +319,6 @@ mt6397_vpca15_reg: buck_vpca15 { + }; + + mt6397_vpca7_reg: buck_vpca7 { +- regulator-compatible = "buck_vpca7"; + regulator-name = "vpca7"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -329,7 +327,6 @@ mt6397_vpca7_reg: buck_vpca7 { + }; + + mt6397_vsramca15_reg: buck_vsramca15 { +- regulator-compatible = "buck_vsramca15"; + regulator-name = "vsramca15"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -338,7 +335,6 @@ mt6397_vsramca15_reg: buck_vsramca15 { + }; + + mt6397_vsramca7_reg: buck_vsramca7 { +- regulator-compatible = "buck_vsramca7"; + regulator-name = "vsramca7"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -347,7 +343,6 @@ mt6397_vsramca7_reg: buck_vsramca7 { + }; + + mt6397_vcore_reg: buck_vcore { +- regulator-compatible = "buck_vcore"; + regulator-name = "vcore"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -356,7 +351,6 @@ mt6397_vcore_reg: buck_vcore { + }; + + mt6397_vgpu_reg: buck_vgpu { +- regulator-compatible = "buck_vgpu"; + regulator-name = "vgpu"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; +@@ -365,7 +359,6 @@ mt6397_vgpu_reg: buck_vgpu { + }; + + mt6397_vdrm_reg: buck_vdrm { +- regulator-compatible = "buck_vdrm"; + regulator-name = "vdrm"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1400000>; +@@ -374,7 +367,6 @@ mt6397_vdrm_reg: buck_vdrm { + }; + + mt6397_vio18_reg: buck_vio18 { +- regulator-compatible = "buck_vio18"; + regulator-name = "vio18"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <1980000>; +@@ -383,19 +375,16 @@ mt6397_vio18_reg: buck_vio18 { + }; + + mt6397_vtcxo_reg: ldo_vtcxo { +- regulator-compatible = "ldo_vtcxo"; + regulator-name = "vtcxo"; + regulator-always-on; + }; + + mt6397_va28_reg: ldo_va28 { +- regulator-compatible = "ldo_va28"; + regulator-name = "va28"; + regulator-always-on; + }; + + mt6397_vcama_reg: ldo_vcama { +- regulator-compatible = "ldo_vcama"; + regulator-name = "vcama"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <2800000>; +@@ -403,18 +392,15 @@ mt6397_vcama_reg: ldo_vcama { + }; + + mt6397_vio28_reg: ldo_vio28 { +- regulator-compatible = "ldo_vio28"; + regulator-name = "vio28"; + regulator-always-on; + }; + + mt6397_vusb_reg: ldo_vusb { +- regulator-compatible = "ldo_vusb"; + regulator-name = "vusb"; + }; + + mt6397_vmc_reg: ldo_vmc { +- regulator-compatible = "ldo_vmc"; + regulator-name = "vmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; +@@ -422,7 +408,6 @@ mt6397_vmc_reg: ldo_vmc { + }; + + mt6397_vmch_reg: ldo_vmch { +- regulator-compatible = "ldo_vmch"; + regulator-name = "vmch"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; +@@ -430,7 +415,6 @@ mt6397_vmch_reg: ldo_vmch { + }; + + mt6397_vemc_3v3_reg: ldo_vemc3v3 { +- regulator-compatible = "ldo_vemc3v3"; + regulator-name = "vemc_3v3"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; +@@ -438,7 +422,6 @@ mt6397_vemc_3v3_reg: ldo_vemc3v3 { + }; + + mt6397_vgp1_reg: ldo_vgp1 { +- regulator-compatible = "ldo_vgp1"; + regulator-name = "vcamd"; + regulator-min-microvolt = <1220000>; + regulator-max-microvolt = <3300000>; +@@ -446,7 +429,6 @@ mt6397_vgp1_reg: ldo_vgp1 { + }; + + mt6397_vgp2_reg: ldo_vgp2 { +- regulator-compatible = "ldo_vgp2"; + regulator-name = "vcamio"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3300000>; +@@ -454,7 +436,6 @@ mt6397_vgp2_reg: ldo_vgp2 { + }; + + mt6397_vgp3_reg: ldo_vgp3 { +- regulator-compatible = "ldo_vgp3"; + regulator-name = "vcamaf"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; +@@ -462,7 +443,6 @@ mt6397_vgp3_reg: ldo_vgp3 { + }; + + mt6397_vgp4_reg: ldo_vgp4 { +- regulator-compatible = "ldo_vgp4"; + regulator-name = "vgp4"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; +@@ -470,7 +450,6 @@ mt6397_vgp4_reg: ldo_vgp4 { + }; + + mt6397_vgp5_reg: ldo_vgp5 { +- regulator-compatible = "ldo_vgp5"; + regulator-name = "vgp5"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3000000>; +@@ -478,7 +457,6 @@ mt6397_vgp5_reg: ldo_vgp5 { + }; + + mt6397_vgp6_reg: ldo_vgp6 { +- regulator-compatible = "ldo_vgp6"; + regulator-name = "vgp6"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; +@@ -486,7 +464,6 @@ mt6397_vgp6_reg: ldo_vgp6 { + }; + + mt6397_vibr_reg: ldo_vibr { +- regulator-compatible = "ldo_vibr"; + regulator-name = "vibr"; + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <3300000>; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts +index 8e0cba4d237265..9a35c657799620 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts +@@ -25,6 +25,10 @@ &touchscreen { + hid-descr-addr = <0x0001>; + }; + ++&mt6358codec { ++ mediatek,dmic-mode = <1>; /* one-wire */ ++}; ++ + &qca_wifi { + qcom,ath10k-calibration-variant = "GO_DAMU"; + }; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts +index 6f1aa692753ad6..a477e2cce20484 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts +@@ -10,3 +10,18 @@ / { + model = "Google kenzo sku17 board"; + compatible = "google,juniper-sku17", "google,juniper", "mediatek,mt8183"; + }; ++ ++&i2c0 { ++ touchscreen@40 { ++ compatible = "hid-over-i2c"; ++ reg = <0x40>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&touchscreen_pins>; ++ ++ interrupts-extended = <&pio 155 IRQ_TYPE_LEVEL_LOW>; ++ ++ post-power-on-delay-ms = <70>; ++ hid-descr-addr = <0x0001>; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi +index 76d33540166f90..c942e461a177ef 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi +@@ -6,6 +6,21 @@ + /dts-v1/; + #include "mt8183-kukui-jacuzzi.dtsi" + ++&i2c0 { ++ touchscreen@40 { ++ compatible = "hid-over-i2c"; ++ reg = <0x40>; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&touchscreen_pins>; ++ ++ interrupts-extended = <&pio 155 IRQ_TYPE_LEVEL_LOW>; ++ ++ post-power-on-delay-ms = <70>; ++ hid-descr-addr = <0x0001>; ++ }; ++}; ++ + &i2c2 { + trackpad@2c { + compatible = "hid-over-i2c"; +diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi +index f19bf2834b390e..3fa491dc52021f 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi +@@ -39,8 +39,6 @@ pp1800_mipibrdg: pp1800-mipibrdg { + pp3300_panel: pp3300-panel { + compatible = "regulator-fixed"; + regulator-name = "pp3300_panel"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; + pinctrl-names = "default"; + pinctrl-0 = <&pp3300_panel_pins>; + +diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +index 712ac1826d6869..68395d4c893037 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi +@@ -1236,6 +1236,7 @@ dsi0: dsi@14014000 { + clock-names = "engine", "digital", "hs"; + phys = <&mipi_tx0>; + phy-names = "dphy"; ++ status = "disabled"; + }; + + mutex: mutex@14016000 { +diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi +index bbe5a1419effcf..5655f12723f14f 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi +@@ -144,10 +144,10 @@ reserved-memory { + #size-cells = <2>; + ranges; + +- /* 128 KiB reserved for ARM Trusted Firmware (BL31) */ ++ /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ + bl31_secmon_reserved: secmon@43000000 { + no-map; +- reg = <0 0x43000000 0 0x20000>; ++ reg = <0 0x43000000 0 0x30000>; + }; + }; + +@@ -206,7 +206,7 @@ toprgu: toprgu@10007000 { + compatible = "mediatek,mt8516-wdt", + "mediatek,mt6589-wdt"; + reg = <0 0x10007000 0 0x1000>; +- interrupts = ; ++ interrupts = ; + #reset-cells = <1>; + }; + +@@ -269,7 +269,7 @@ gic: interrupt-controller@10310000 { + interrupt-parent = <&gic>; + interrupt-controller; + reg = <0 0x10310000 0 0x1000>, +- <0 0x10320000 0 0x1000>, ++ <0 0x1032f000 0 0x2000>, + <0 0x10340000 0 0x2000>, + <0 0x10360000 0 0x2000>; + interrupts = , + <0 0x11000180 0 0x80>; + interrupts = ; +- clocks = <&topckgen CLK_TOP_AHB_INFRA_D2>, +- <&infracfg CLK_IFR_I2C0_SEL>, +- <&topckgen CLK_TOP_I2C0>, ++ clock-div = <2>; ++ clocks = <&topckgen CLK_TOP_I2C0>, + <&topckgen CLK_TOP_APDMA>; +- clock-names = "main-source", +- "main-sel", +- "main", +- "dma"; ++ clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +@@ -364,14 +360,10 @@ i2c1: i2c@1100a000 { + reg = <0 0x1100a000 0 0x90>, + <0 0x11000200 0 0x80>; + interrupts = ; +- clocks = <&topckgen CLK_TOP_AHB_INFRA_D2>, +- <&infracfg CLK_IFR_I2C1_SEL>, +- <&topckgen CLK_TOP_I2C1>, ++ clock-div = <2>; ++ clocks = <&topckgen CLK_TOP_I2C1>, + <&topckgen CLK_TOP_APDMA>; +- clock-names = "main-source", +- "main-sel", +- "main", +- "dma"; ++ clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +@@ -383,14 +375,10 @@ i2c2: i2c@1100b000 { + reg = <0 0x1100b000 0 0x90>, + <0 0x11000280 0 0x80>; + interrupts = ; +- clocks = <&topckgen CLK_TOP_AHB_INFRA_D2>, +- <&infracfg CLK_IFR_I2C2_SEL>, +- <&topckgen CLK_TOP_I2C2>, ++ clock-div = <2>; ++ clocks = <&topckgen CLK_TOP_I2C2>, + <&topckgen CLK_TOP_APDMA>; +- clock-names = "main-source", +- "main-sel", +- "main", +- "dma"; ++ clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; +diff --git a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi +index 54514d62398f21..8696da3de4cbee 100644 +--- a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi ++++ b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi +@@ -48,7 +48,6 @@ volume-down { + }; + + &i2c0 { +- clock-div = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; +@@ -157,7 +156,6 @@ cam-pwdn-hog { + }; + + &i2c2 { +- clock-div = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + status = "okay"; +diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi +index 668674059d4850..79d5f1433800fb 100644 +--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi +@@ -105,7 +105,7 @@ xo_board: xo-board { + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; +- clock-frequency = <32768>; ++ clock-frequency = <32764>; + }; + }; + +diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi +index 4447ed146b3acc..1ae2fbef90582f 100644 +--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi +@@ -25,7 +25,7 @@ xo_board: xo-board { + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; +- clock-frequency = <32768>; ++ clock-frequency = <32764>; + clock-output-names = "sleep_clk"; + }; + }; +@@ -419,6 +419,15 @@ usb3: usb@f92f8800 { + #size-cells = <1>; + ranges; + ++ interrupts = , ++ , ++ , ++ ; ++ interrupt-names = "pwr_event", ++ "qusb2_phy", ++ "hs_phy_irq", ++ "ss_phy_irq"; ++ + clocks = <&gcc GCC_USB30_MASTER_CLK>, + <&gcc GCC_SYS_NOC_USB3_AXI_CLK>, + <&gcc GCC_USB30_SLEEP_CLK>, +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index 9ee8eebfcdb519..ec0f067a6a5d53 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -2608,9 +2608,14 @@ usb3: usb@6af8800 { + #size-cells = <1>; + ranges; + +- interrupts = , ++ interrupts = , ++ , ++ , + ; +- interrupt-names = "hs_phy_irq", "ss_phy_irq"; ++ interrupt-names = "pwr_event", ++ "qusb2_phy", ++ "hs_phy_irq", ++ "ss_phy_irq"; + + clocks = <&gcc GCC_SYS_NOC_USB3_AXI_CLK>, + <&gcc GCC_USB30_MASTER_CLK>, +diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi +index 929fc0667e985f..c65f3c9a6673f6 100644 +--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi +@@ -39,7 +39,7 @@ xo_board: xo-board { + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; +- clock-frequency = <32000>; ++ clock-frequency = <32764>; + #clock-cells = <0>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi +index cff5423e9c88dc..69212445d22c91 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi +@@ -3948,16 +3948,16 @@ camss: camss@acb3000 { + "vfe1", + "vfe_lite"; + +- interrupts = , +- , +- , +- , +- , +- , +- , +- , +- , +- ; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; + interrupt-names = "csid0", + "csid1", + "csid2", +diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi +index 2e4fe2bc1e0a87..0f6a9a5cbe178a 100644 +--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi +@@ -27,7 +27,7 @@ xo_board: xo-board { + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; +- clock-frequency = <32000>; ++ clock-frequency = <32764>; + clock-output-names = "sleep_clk"; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts b/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts +index 736da9af44e082..b233b56d4bbd0c 100644 +--- a/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts ++++ b/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts +@@ -375,8 +375,8 @@ da7280@4a { + pinctrl-0 = <&da7280_intr_default>; + + dlg,actuator-type = "LRA"; +- dlg,dlg,const-op-mode = <1>; +- dlg,dlg,periodic-op-mode = <1>; ++ dlg,const-op-mode = <1>; ++ dlg,periodic-op-mode = <1>; + dlg,nom-microvolt = <2000000>; + dlg,abs-max-microvolt = <2000000>; + dlg,imax-microamp = <129000>; +diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi +index 99afdd1ad7c6e5..bf91e0acd435f2 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi +@@ -82,7 +82,7 @@ xo_board: xo-board { + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; +- clock-frequency = <32768>; ++ clock-frequency = <32764>; + #clock-cells = <0>; + }; + }; +diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi +index 8506dc841c8690..df02fe5ceee9ce 100644 +--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi +@@ -32,7 +32,7 @@ xo_board: xo-board { + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; +- clock-frequency = <32000>; ++ clock-frequency = <32764>; + #clock-cells = <0>; + }; + +@@ -754,7 +754,7 @@ tcsr_mutex: hwlock@1f40000 { + + mpss: remoteproc@4080000 { + compatible = "qcom,sm8350-mpss-pas"; +- reg = <0x0 0x04080000 0x0 0x4040>; ++ reg = <0x0 0x04080000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>, + <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi +index d10074b5615617..09a8861deba244 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi +@@ -136,7 +136,7 @@ &gmac { + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; + tx_delay = <0x10>; +- rx_delay = <0x10>; ++ rx_delay = <0x23>; + status = "okay"; + }; + +diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h +index 56bc2e4e81a6e9..0070ee4ba8955f 100644 +--- a/arch/arm64/include/asm/mman.h ++++ b/arch/arm64/include/asm/mman.h +@@ -31,9 +31,12 @@ static inline unsigned long arch_calc_vm_flag_bits(struct file *file, + * backed by tags-capable memory. The vm_flags may be overridden by a + * filesystem supporting MTE (RAM-based). + */ +- if (system_supports_mte() && +- ((flags & MAP_ANONYMOUS) || shmem_file(file))) +- return VM_MTE_ALLOWED; ++ if (system_supports_mte()) { ++ if ((flags & MAP_ANONYMOUS) && !(flags & MAP_HUGETLB)) ++ return VM_MTE_ALLOWED; ++ if (shmem_file(file)) ++ return VM_MTE_ALLOWED; ++ } + + return 0; + } +diff --git a/arch/arm64/kernel/cacheinfo.c b/arch/arm64/kernel/cacheinfo.c +index 97c42be71338a9..1510f457b6154d 100644 +--- a/arch/arm64/kernel/cacheinfo.c ++++ b/arch/arm64/kernel/cacheinfo.c +@@ -87,16 +87,18 @@ int populate_cache_leaves(unsigned int cpu) + unsigned int level, idx; + enum cache_type type; + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); +- struct cacheinfo *this_leaf = this_cpu_ci->info_list; ++ struct cacheinfo *infos = this_cpu_ci->info_list; + + for (idx = 0, level = 1; level <= this_cpu_ci->num_levels && +- idx < this_cpu_ci->num_leaves; idx++, level++) { ++ idx < this_cpu_ci->num_leaves; level++) { + type = get_cache_type(level); + if (type == CACHE_TYPE_SEPARATE) { +- ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level); +- ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level); ++ if (idx + 1 >= this_cpu_ci->num_leaves) ++ break; ++ ci_leaf_init(&infos[idx++], CACHE_TYPE_DATA, level); ++ ci_leaf_init(&infos[idx++], CACHE_TYPE_INST, level); + } else { +- ci_leaf_init(this_leaf++, type, level); ++ ci_leaf_init(&infos[idx++], type, level); + } + } + return 0; +diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S +index a5e61e09ea927e..7dd11c4c945e72 100644 +--- a/arch/arm64/kernel/vdso/vdso.lds.S ++++ b/arch/arm64/kernel/vdso/vdso.lds.S +@@ -37,6 +37,7 @@ SECTIONS + */ + /DISCARD/ : { + *(.note.GNU-stack .note.gnu.property) ++ *(.ARM.attributes) + } + .note : { *(.note.*) } :text :note + +diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S +index 7bedadfa36422e..90aa16ceddc459 100644 +--- a/arch/arm64/kernel/vmlinux.lds.S ++++ b/arch/arm64/kernel/vmlinux.lds.S +@@ -139,6 +139,7 @@ SECTIONS + /DISCARD/ : { + *(.interp .dynamic) + *(.dynsym .dynstr .hash .gnu.hash) ++ *(.ARM.attributes) + } + + . = KIMAGE_VADDR; +diff --git a/arch/hexagon/include/asm/cmpxchg.h b/arch/hexagon/include/asm/cmpxchg.h +index cdb705e1496af8..72c6e16c3f2378 100644 +--- a/arch/hexagon/include/asm/cmpxchg.h ++++ b/arch/hexagon/include/asm/cmpxchg.h +@@ -56,7 +56,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, + __typeof__(ptr) __ptr = (ptr); \ + __typeof__(*(ptr)) __old = (old); \ + __typeof__(*(ptr)) __new = (new); \ +- __typeof__(*(ptr)) __oldval = 0; \ ++ __typeof__(*(ptr)) __oldval = (__typeof__(*(ptr))) 0; \ + \ + asm volatile( \ + "1: %0 = memw_locked(%1);\n" \ +diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c +index 1240f038cce02b..7aca1c329f9443 100644 +--- a/arch/hexagon/kernel/traps.c ++++ b/arch/hexagon/kernel/traps.c +@@ -195,8 +195,10 @@ int die(const char *str, struct pt_regs *regs, long err) + printk(KERN_EMERG "Oops: %s[#%d]:\n", str, ++die.counter); + + if (notify_die(DIE_OOPS, str, regs, err, pt_cause(regs), SIGSEGV) == +- NOTIFY_STOP) ++ NOTIFY_STOP) { ++ spin_unlock_irq(&die.lock); + return 1; ++ } + + print_modules(); + show_regs(regs); +diff --git a/arch/m68k/include/asm/vga.h b/arch/m68k/include/asm/vga.h +index 4742e6bc3ab8ea..cdd414fa8710a9 100644 +--- a/arch/m68k/include/asm/vga.h ++++ b/arch/m68k/include/asm/vga.h +@@ -9,7 +9,7 @@ + */ + #ifndef CONFIG_PCI + +-#include ++#include + #include + + /* +@@ -29,9 +29,9 @@ + #define inw_p(port) 0 + #define outb_p(port, val) do { } while (0) + #define outw(port, val) do { } while (0) +-#define readb raw_inb +-#define writeb raw_outb +-#define writew raw_outw ++#define readb __raw_readb ++#define writeb __raw_writeb ++#define writew __raw_writew + + #endif /* CONFIG_PCI */ + #endif /* _ASM_M68K_VGA_H */ +diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c +index 8c401e42301cbf..f39e85fd58fa99 100644 +--- a/arch/mips/kernel/ftrace.c ++++ b/arch/mips/kernel/ftrace.c +@@ -248,7 +248,7 @@ int ftrace_disable_ftrace_graph_caller(void) + #define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */ + #define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */ + +-unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long ++static unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long + old_parent_ra, unsigned long parent_ra_addr, unsigned long fp) + { + unsigned long sp, ip, tmp; +diff --git a/arch/mips/loongson64/boardinfo.c b/arch/mips/loongson64/boardinfo.c +index 280989c5a137b5..8bb275c93ac099 100644 +--- a/arch/mips/loongson64/boardinfo.c ++++ b/arch/mips/loongson64/boardinfo.c +@@ -21,13 +21,11 @@ static ssize_t boardinfo_show(struct kobject *kobj, + "BIOS Info\n" + "Vendor\t\t\t: %s\n" + "Version\t\t\t: %s\n" +- "ROM Size\t\t: %d KB\n" + "Release Date\t\t: %s\n", + strsep(&tmp_board_manufacturer, "-"), + eboard->name, + strsep(&tmp_bios_vendor, "-"), + einter->description, +- einter->size, + especial->special_name); + } + static struct kobj_attribute boardinfo_attr = __ATTR(boardinfo, 0444, +diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c +index 587cf1d115e8fa..d6fbb69baa2d8c 100644 +--- a/arch/mips/math-emu/cp1emu.c ++++ b/arch/mips/math-emu/cp1emu.c +@@ -1660,7 +1660,7 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, + break; + } + +- case 0x3: ++ case 0x7: + if (MIPSInst_FUNC(ir) != pfetch_op) + return SIGILL; + +diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c +index 833fcfc20b103f..81fda8c583ae16 100644 +--- a/arch/mips/mm/init.c ++++ b/arch/mips/mm/init.c +@@ -527,7 +527,7 @@ static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, + + static void __init pcpu_fc_free(void *ptr, size_t size) + { +- memblock_free_early(__pa(ptr), size); ++ memblock_free(__pa(ptr), size); + } + + void __init setup_per_cpu_areas(void) +diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h +index b6ac4f86c87b44..433d164374cb67 100644 +--- a/arch/powerpc/include/asm/book3s/64/hash-4k.h ++++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h +@@ -89,6 +89,34 @@ static inline int hash__hugepd_ok(hugepd_t hpd) + } + #endif + ++/* ++ * With 4K page size the real_pte machinery is all nops. ++ */ ++static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep, int offset) ++{ ++ return (real_pte_t){pte}; ++} ++ ++#define __rpte_to_pte(r) ((r).pte) ++ ++static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index) ++{ ++ return pte_val(__rpte_to_pte(rpte)) >> H_PAGE_F_GIX_SHIFT; ++} ++ ++#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ ++ do { \ ++ index = 0; \ ++ shift = mmu_psize_defs[psize].shift; \ ++ ++#define pte_iterate_hashed_end() } while(0) ++ ++/* ++ * We expect this to be called only for user addresses or kernel virtual ++ * addresses other than the linear mapping. ++ */ ++#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K ++ + /* + * 4K PTE format is different from 64K PTE format. Saving the hash_slot is just + * a matter of returning the PTE bits that need to be modified. On 64K PTE, +diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h +index 6866d860d4f30e..cd9088673ceaed 100644 +--- a/arch/powerpc/include/asm/book3s/64/pgtable.h ++++ b/arch/powerpc/include/asm/book3s/64/pgtable.h +@@ -336,32 +336,6 @@ extern unsigned long pci_io_base; + + #ifndef __ASSEMBLY__ + +-/* +- * This is the default implementation of various PTE accessors, it's +- * used in all cases except Book3S with 64K pages where we have a +- * concept of sub-pages +- */ +-#ifndef __real_pte +- +-#define __real_pte(e, p, o) ((real_pte_t){(e)}) +-#define __rpte_to_pte(r) ((r).pte) +-#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> H_PAGE_F_GIX_SHIFT) +- +-#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ +- do { \ +- index = 0; \ +- shift = mmu_psize_defs[psize].shift; \ +- +-#define pte_iterate_hashed_end() } while(0) +- +-/* +- * We expect this to be called only for user addresses or kernel virtual +- * addresses other than the linear mapping. +- */ +-#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K +- +-#endif /* __real_pte */ +- + static inline unsigned long pte_update(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, unsigned long clr, + unsigned long set, int huge) +diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c +index c5ed9882383521..e303e3f039a6f3 100644 +--- a/arch/powerpc/lib/code-patching.c ++++ b/arch/powerpc/lib/code-patching.c +@@ -51,7 +51,7 @@ static int text_area_cpu_up(unsigned int cpu) + { + struct vm_struct *area; + +- area = get_vm_area(PAGE_SIZE, VM_ALLOC); ++ area = get_vm_area(PAGE_SIZE, 0); + if (!area) { + WARN_ONCE(1, "Failed to create text area for cpu %d\n", + cpu); +diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c +index f51fd4ac3f0b63..38889a013a865b 100644 +--- a/arch/powerpc/platforms/pseries/eeh_pseries.c ++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c +@@ -578,8 +578,10 @@ static int pseries_eeh_get_state(struct eeh_pe *pe, int *delay) + + switch(rets[0]) { + case 0: +- result = EEH_STATE_MMIO_ACTIVE | +- EEH_STATE_DMA_ACTIVE; ++ result = EEH_STATE_MMIO_ACTIVE | ++ EEH_STATE_DMA_ACTIVE | ++ EEH_STATE_MMIO_ENABLED | ++ EEH_STATE_DMA_ENABLED; + break; + case 1: + result = EEH_STATE_RESET_ACTIVE | +diff --git a/arch/powerpc/platforms/pseries/svm.c b/arch/powerpc/platforms/pseries/svm.c +index 87f001b4c4e4fa..f12229ce730149 100644 +--- a/arch/powerpc/platforms/pseries/svm.c ++++ b/arch/powerpc/platforms/pseries/svm.c +@@ -56,8 +56,7 @@ void __init svm_swiotlb_init(void) + return; + + +- memblock_free_early(__pa(vstart), +- PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); ++ memblock_free(__pa(vstart), PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); + panic("SVM: Cannot allocate SWIOTLB buffer"); + } + +diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h +index bf15767b729f9f..002e0e6a9b2baf 100644 +--- a/arch/s390/include/asm/futex.h ++++ b/arch/s390/include/asm/futex.h +@@ -43,7 +43,7 @@ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + break; + case FUTEX_OP_ANDN: + __futex_atomic_op("lr %2,%1\nnr %2,%5\n", +- ret, oldval, newval, uaddr, oparg); ++ ret, oldval, newval, uaddr, ~oparg); + break; + case FUTEX_OP_XOR: + __futex_atomic_op("lr %2,%1\nxr %2,%5\n", +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index 48f67a69d119b3..5c1fd147591cba 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -875,7 +875,7 @@ void __init smp_detect_cpus(void) + + /* Add CPUs present at boot */ + __smp_rescan_cpus(info, true); +- memblock_free_early((unsigned long)info, sizeof(*info)); ++ memblock_free((unsigned long)info, sizeof(*info)); + } + + /* +diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c +index 4044826d72ae59..f9bed5ff5d48b4 100644 +--- a/arch/s390/kernel/traps.c ++++ b/arch/s390/kernel/traps.c +@@ -281,10 +281,10 @@ static void __init test_monitor_call(void) + return; + asm volatile( + " mc 0,0\n" +- "0: xgr %0,%0\n" ++ "0: lhi %[val],0\n" + "1:\n" +- EX_TABLE(0b,1b) +- : "+d" (val)); ++ EX_TABLE(0b, 1b) ++ : [val] "+d" (val)); + if (!val) + panic("Monitor call doesn't work!\n"); + } +diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c +index e07bc0d3df6ffb..b95677c4855aa9 100644 +--- a/arch/s390/kvm/vsie.c ++++ b/arch/s390/kvm/vsie.c +@@ -1321,8 +1321,14 @@ static struct vsie_page *get_vsie_page(struct kvm *kvm, unsigned long addr) + page = radix_tree_lookup(&kvm->arch.vsie.addr_to_page, addr >> 9); + rcu_read_unlock(); + if (page) { +- if (page_ref_inc_return(page) == 2) +- return page_to_virt(page); ++ if (page_ref_inc_return(page) == 2) { ++ if (page->index == addr) ++ return page_to_virt(page); ++ /* ++ * We raced with someone reusing + putting this vsie ++ * page before we grabbed it. ++ */ ++ } + page_ref_dec(page); + } + +@@ -1352,15 +1358,20 @@ static struct vsie_page *get_vsie_page(struct kvm *kvm, unsigned long addr) + kvm->arch.vsie.next++; + kvm->arch.vsie.next %= nr_vcpus; + } +- radix_tree_delete(&kvm->arch.vsie.addr_to_page, page->index >> 9); ++ if (page->index != ULONG_MAX) ++ radix_tree_delete(&kvm->arch.vsie.addr_to_page, ++ page->index >> 9); + } +- page->index = addr; +- /* double use of the same address */ ++ /* Mark it as invalid until it resides in the tree. */ ++ page->index = ULONG_MAX; ++ ++ /* Double use of the same address or allocation failure. */ + if (radix_tree_insert(&kvm->arch.vsie.addr_to_page, addr >> 9, page)) { + page_ref_dec(page); + mutex_unlock(&kvm->arch.vsie.mutex); + return NULL; + } ++ page->index = addr; + mutex_unlock(&kvm->arch.vsie.mutex); + + vsie_page = page_to_virt(page); +@@ -1453,7 +1464,9 @@ void kvm_s390_vsie_destroy(struct kvm *kvm) + vsie_page = page_to_virt(page); + release_gmap_shadow(vsie_page); + /* free the radix tree entry */ +- radix_tree_delete(&kvm->arch.vsie.addr_to_page, page->index >> 9); ++ if (page->index != ULONG_MAX) ++ radix_tree_delete(&kvm->arch.vsie.addr_to_page, ++ page->index >> 9); + __free_page(page); + } + kvm->arch.vsie.page_count = 0; +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index 2f6312e7ce81f3..90ac8d84389cfc 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -2449,7 +2449,8 @@ config CPU_IBPB_ENTRY + depends on CPU_SUP_AMD && X86_64 + default y + help +- Compile the kernel with support for the retbleed=ibpb mitigation. ++ Compile the kernel with support for the retbleed=ibpb and ++ spec_rstack_overflow={ibpb,ibpb-vmexit} mitigations. + + config CPU_IBRS_ENTRY + bool "Enable IBRS on kernel entry" +diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile +index 15c5ae62a0e944..3ec9fb6b03780b 100644 +--- a/arch/x86/boot/compressed/Makefile ++++ b/arch/x86/boot/compressed/Makefile +@@ -33,6 +33,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ + # avoid errors with '-march=i386', and future flags may depend on the target to + # be valid. + KBUILD_CFLAGS := -m$(BITS) -O2 $(CLANG_FLAGS) ++KBUILD_CFLAGS += -std=gnu11 + KBUILD_CFLAGS += -fno-strict-aliasing -fPIE + KBUILD_CFLAGS += -Wundef + KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index b70e1522a27ac6..767c60af13be33 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -4364,8 +4364,11 @@ static void intel_pmu_cpu_starting(int cpu) + + init_debug_store_on_cpu(cpu); + /* +- * Deal with CPUs that don't clear their LBRs on power-up. ++ * Deal with CPUs that don't clear their LBRs on power-up, and that may ++ * even boot with LBRs enabled. + */ ++ if (!static_cpu_has(X86_FEATURE_ARCH_LBR) && x86_pmu.lbr_nr) ++ msr_clear_bit(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR_BIT); + intel_pmu_lbr_reset(); + + cpuc->lbr_sel = NULL; +diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h +index 5d7494631ea95a..c07c018a1c1396 100644 +--- a/arch/x86/include/asm/mmu.h ++++ b/arch/x86/include/asm/mmu.h +@@ -33,6 +33,8 @@ typedef struct { + */ + atomic64_t tlb_gen; + ++ unsigned long next_trim_cpumask; ++ + #ifdef CONFIG_MODIFY_LDT_SYSCALL + struct rw_semaphore ldt_usr_sem; + struct ldt_struct *ldt; +diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h +index 27516046117a38..1d11aeb5975428 100644 +--- a/arch/x86/include/asm/mmu_context.h ++++ b/arch/x86/include/asm/mmu_context.h +@@ -106,6 +106,7 @@ static inline int init_new_context(struct task_struct *tsk, + + mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id); + atomic64_set(&mm->context.tlb_gen, 0); ++ mm->context.next_trim_cpumask = jiffies + HZ; + + #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS + if (cpu_feature_enabled(X86_FEATURE_OSPKE)) { +diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h +index 15939a71dca7c7..03b12c19458892 100644 +--- a/arch/x86/include/asm/msr-index.h ++++ b/arch/x86/include/asm/msr-index.h +@@ -337,7 +337,8 @@ + #define MSR_IA32_PASID_VALID BIT_ULL(31) + + /* DEBUGCTLMSR bits (others vary by model): */ +-#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */ ++#define DEBUGCTLMSR_LBR_BIT 0 /* last branch recording */ ++#define DEBUGCTLMSR_LBR (1UL << DEBUGCTLMSR_LBR_BIT) + #define DEBUGCTLMSR_BTF_SHIFT 1 + #define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */ + #define DEBUGCTLMSR_BUS_LOCK_DETECT (1UL << 2) +diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h +index b587a9ee9cb258..22b93e35fa8861 100644 +--- a/arch/x86/include/asm/tlbflush.h ++++ b/arch/x86/include/asm/tlbflush.h +@@ -207,6 +207,7 @@ struct flush_tlb_info { + unsigned int initiating_cpu; + u8 stride_shift; + u8 freed_tables; ++ u8 trim_cpumask; + }; + + void flush_tlb_local(void); +diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c +index 62cd2af806b47c..eda11832b6e62c 100644 +--- a/arch/x86/kernel/amd_nb.c ++++ b/arch/x86/kernel/amd_nb.c +@@ -544,6 +544,10 @@ static __init void fix_erratum_688(void) + + static __init int init_amd_nbs(void) + { ++ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD && ++ boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) ++ return 0; ++ + amd_cache_northbridges(); + amd_cache_gart(); + +diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c +index f84d59cd180b36..dfc02fb32375c6 100644 +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -1092,6 +1092,8 @@ static void __init retbleed_select_mitigation(void) + + case RETBLEED_MITIGATION_IBPB: + setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); ++ setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); ++ mitigate_smt = true; + + /* + * IBPB on entry already obviates the need for +@@ -1101,8 +1103,6 @@ static void __init retbleed_select_mitigation(void) + setup_clear_cpu_cap(X86_FEATURE_UNRET); + setup_clear_cpu_cap(X86_FEATURE_RETHUNK); + +- mitigate_smt = true; +- + /* + * There is no need for RSB filling: entry_ibpb() ensures + * all predictions, including the RSB, are invalidated, +@@ -2607,6 +2607,7 @@ static void __init srso_select_mitigation(void) + if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY)) { + if (has_microcode) { + setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); ++ setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); + srso_mitigation = SRSO_MITIGATION_IBPB; + + /* +@@ -2616,6 +2617,13 @@ static void __init srso_select_mitigation(void) + */ + setup_clear_cpu_cap(X86_FEATURE_UNRET); + setup_clear_cpu_cap(X86_FEATURE_RETHUNK); ++ ++ /* ++ * There is no need for RSB filling: entry_ibpb() ensures ++ * all predictions, including the RSB, are invalidated, ++ * regardless of IBPB implementation. ++ */ ++ setup_clear_cpu_cap(X86_FEATURE_RSB_VMEXIT); + } + } else { + pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n"); +@@ -2624,8 +2632,8 @@ static void __init srso_select_mitigation(void) + break; + + case SRSO_CMD_IBPB_ON_VMEXIT: +- if (IS_ENABLED(CONFIG_CPU_SRSO)) { +- if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) { ++ if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY)) { ++ if (has_microcode) { + setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); + srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT; + +@@ -2637,9 +2645,9 @@ static void __init srso_select_mitigation(void) + setup_clear_cpu_cap(X86_FEATURE_RSB_VMEXIT); + } + } else { +- pr_err("WARNING: kernel not compiled with CPU_SRSO.\n"); ++ pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n"); + goto pred_cmd; +- } ++ } + break; + + default: +diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c +index b5e36bd0425b57..a33c972cecf56c 100644 +--- a/arch/x86/kernel/cpu/cacheinfo.c ++++ b/arch/x86/kernel/cpu/cacheinfo.c +@@ -795,7 +795,7 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c) + cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]); + + /* If bit 31 is set, this is an unknown format */ +- for (j = 0 ; j < 3 ; j++) ++ for (j = 0 ; j < 4 ; j++) + if (regs[j] & (1 << 31)) + regs[j] = 0; + +diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c +index 7227c15299d0b8..7de799ab2a0486 100644 +--- a/arch/x86/kernel/cpu/cyrix.c ++++ b/arch/x86/kernel/cpu/cyrix.c +@@ -152,8 +152,8 @@ static void geode_configure(void) + u8 ccr3; + local_irq_save(flags); + +- /* Suspend on halt power saving and enable #SUSP pin */ +- setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x88); ++ /* Suspend on halt power saving */ ++ setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x08); + + ccr3 = getCx86(CX86_CCR3); + setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ +diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c +index 2b1cd4202e756c..e7145ee656df89 100644 +--- a/arch/x86/kernel/cpu/intel.c ++++ b/arch/x86/kernel/cpu/intel.c +@@ -749,26 +749,37 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size) + } + #endif + +-#define TLB_INST_4K 0x01 +-#define TLB_INST_4M 0x02 +-#define TLB_INST_2M_4M 0x03 ++#define TLB_INST_4K 0x01 ++#define TLB_INST_4M 0x02 ++#define TLB_INST_2M_4M 0x03 + +-#define TLB_INST_ALL 0x05 +-#define TLB_INST_1G 0x06 ++#define TLB_INST_ALL 0x05 ++#define TLB_INST_1G 0x06 + +-#define TLB_DATA_4K 0x11 +-#define TLB_DATA_4M 0x12 +-#define TLB_DATA_2M_4M 0x13 +-#define TLB_DATA_4K_4M 0x14 ++#define TLB_DATA_4K 0x11 ++#define TLB_DATA_4M 0x12 ++#define TLB_DATA_2M_4M 0x13 ++#define TLB_DATA_4K_4M 0x14 + +-#define TLB_DATA_1G 0x16 ++#define TLB_DATA_1G 0x16 ++#define TLB_DATA_1G_2M_4M 0x17 + +-#define TLB_DATA0_4K 0x21 +-#define TLB_DATA0_4M 0x22 +-#define TLB_DATA0_2M_4M 0x23 ++#define TLB_DATA0_4K 0x21 ++#define TLB_DATA0_4M 0x22 ++#define TLB_DATA0_2M_4M 0x23 + +-#define STLB_4K 0x41 +-#define STLB_4K_2M 0x42 ++#define STLB_4K 0x41 ++#define STLB_4K_2M 0x42 ++ ++/* ++ * All of leaf 0x2's one-byte TLB descriptors implies the same number of ++ * entries for their respective TLB types. The 0x63 descriptor is an ++ * exception: it implies 4 dTLB entries for 1GB pages 32 dTLB entries ++ * for 2MB or 4MB pages. Encode descriptor 0x63 dTLB entry count for ++ * 2MB/4MB pages here, as its count for dTLB 1GB pages is already at the ++ * intel_tlb_table[] mapping. ++ */ ++#define TLB_0x63_2M_4M_ENTRIES 32 + + static const struct _tlb_table intel_tlb_table[] = { + { 0x01, TLB_INST_4K, 32, " TLB_INST 4 KByte pages, 4-way set associative" }, +@@ -790,7 +801,8 @@ static const struct _tlb_table intel_tlb_table[] = { + { 0x5c, TLB_DATA_4K_4M, 128, " TLB_DATA 4 KByte and 4 MByte pages" }, + { 0x5d, TLB_DATA_4K_4M, 256, " TLB_DATA 4 KByte and 4 MByte pages" }, + { 0x61, TLB_INST_4K, 48, " TLB_INST 4 KByte pages, full associative" }, +- { 0x63, TLB_DATA_1G, 4, " TLB_DATA 1 GByte pages, 4-way set associative" }, ++ { 0x63, TLB_DATA_1G_2M_4M, 4, " TLB_DATA 1 GByte pages, 4-way set associative" ++ " (plus 32 entries TLB_DATA 2 MByte or 4 MByte pages, not encoded here)" }, + { 0x6b, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 8-way associative" }, + { 0x6c, TLB_DATA_2M_4M, 128, " TLB_DATA 2 MByte or 4 MByte pages, 8-way associative" }, + { 0x6d, TLB_DATA_1G, 16, " TLB_DATA 1 GByte pages, fully associative" }, +@@ -890,6 +902,12 @@ static void intel_tlb_lookup(const unsigned char desc) + if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) + tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; + break; ++ case TLB_DATA_1G_2M_4M: ++ if (tlb_lld_2m[ENTRIES] < TLB_0x63_2M_4M_ENTRIES) ++ tlb_lld_2m[ENTRIES] = TLB_0x63_2M_4M_ENTRIES; ++ if (tlb_lld_4m[ENTRIES] < TLB_0x63_2M_4M_ENTRIES) ++ tlb_lld_4m[ENTRIES] = TLB_0x63_2M_4M_ENTRIES; ++ fallthrough; + case TLB_DATA_1G: + if (tlb_lld_1g[ENTRIES] < intel_tlb_table[k].entries) + tlb_lld_1g[ENTRIES] = intel_tlb_table[k].entries; +@@ -913,7 +931,7 @@ static void intel_detect_tlb(struct cpuinfo_x86 *c) + cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]); + + /* If bit 31 is set, this is an unknown format */ +- for (j = 0 ; j < 3 ; j++) ++ for (j = 0 ; j < 4 ; j++) + if (regs[j] & (1 << 31)) + regs[j] = 0; + +diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c +index fa5777af8da1a3..2e93bafa7c475e 100644 +--- a/arch/x86/kernel/cpu/sgx/encl.c ++++ b/arch/x86/kernel/cpu/sgx/encl.c +@@ -232,25 +232,10 @@ static struct sgx_epc_page *sgx_encl_eldu(struct sgx_encl_page *encl_page, + return epc_page; + } + +-static struct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl, +- unsigned long addr, +- unsigned long vm_flags) ++static struct sgx_encl_page *__sgx_encl_load_page(struct sgx_encl *encl, ++ struct sgx_encl_page *entry) + { +- unsigned long vm_prot_bits = vm_flags & (VM_READ | VM_WRITE | VM_EXEC); + struct sgx_epc_page *epc_page; +- struct sgx_encl_page *entry; +- +- entry = xa_load(&encl->page_array, PFN_DOWN(addr)); +- if (!entry) +- return ERR_PTR(-EFAULT); +- +- /* +- * Verify that the faulted page has equal or higher build time +- * permissions than the VMA permissions (i.e. the subset of {VM_READ, +- * VM_WRITE, VM_EXECUTE} in vma->vm_flags). +- */ +- if ((entry->vm_max_prot_bits & vm_prot_bits) != vm_prot_bits) +- return ERR_PTR(-EFAULT); + + /* Entry successfully located. */ + if (entry->epc_page) { +@@ -276,6 +261,40 @@ static struct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl, + return entry; + } + ++static struct sgx_encl_page *sgx_encl_load_page_in_vma(struct sgx_encl *encl, ++ unsigned long addr, ++ unsigned long vm_flags) ++{ ++ unsigned long vm_prot_bits = vm_flags & (VM_READ | VM_WRITE | VM_EXEC); ++ struct sgx_encl_page *entry; ++ ++ entry = xa_load(&encl->page_array, PFN_DOWN(addr)); ++ if (!entry) ++ return ERR_PTR(-EFAULT); ++ ++ /* ++ * Verify that the page has equal or higher build time ++ * permissions than the VMA permissions (i.e. the subset of {VM_READ, ++ * VM_WRITE, VM_EXECUTE} in vma->vm_flags). ++ */ ++ if ((entry->vm_max_prot_bits & vm_prot_bits) != vm_prot_bits) ++ return ERR_PTR(-EFAULT); ++ ++ return __sgx_encl_load_page(encl, entry); ++} ++ ++struct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl, ++ unsigned long addr) ++{ ++ struct sgx_encl_page *entry; ++ ++ entry = xa_load(&encl->page_array, PFN_DOWN(addr)); ++ if (!entry) ++ return ERR_PTR(-EFAULT); ++ ++ return __sgx_encl_load_page(encl, entry); ++} ++ + static vm_fault_t sgx_vma_fault(struct vm_fault *vmf) + { + unsigned long addr = (unsigned long)vmf->address; +@@ -297,7 +316,7 @@ static vm_fault_t sgx_vma_fault(struct vm_fault *vmf) + + mutex_lock(&encl->lock); + +- entry = sgx_encl_load_page(encl, addr, vma->vm_flags); ++ entry = sgx_encl_load_page_in_vma(encl, addr, vma->vm_flags); + if (IS_ERR(entry)) { + mutex_unlock(&encl->lock); + +@@ -445,7 +464,7 @@ static struct sgx_encl_page *sgx_encl_reserve_page(struct sgx_encl *encl, + for ( ; ; ) { + mutex_lock(&encl->lock); + +- entry = sgx_encl_load_page(encl, addr, vm_flags); ++ entry = sgx_encl_load_page_in_vma(encl, addr, vm_flags); + if (PTR_ERR(entry) != -EBUSY) + break; + +@@ -702,7 +721,7 @@ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm) + + spin_lock(&encl->mm_lock); + list_add_rcu(&encl_mm->list, &encl->mm_list); +- /* Pairs with smp_rmb() in sgx_reclaimer_block(). */ ++ /* Pairs with smp_rmb() in sgx_zap_enclave_ptes(). */ + smp_wmb(); + encl->mm_list_version++; + spin_unlock(&encl->mm_lock); +@@ -917,8 +936,53 @@ int sgx_encl_test_and_clear_young(struct mm_struct *mm, + return ret; + } + ++/** ++ * sgx_zap_enclave_ptes() - remove PTEs mapping the address from enclave ++ * @encl: the enclave ++ * @addr: page aligned pointer to single page for which PTEs will be removed ++ * ++ * Multiple VMAs may have an enclave page mapped. Remove the PTE mapping ++ * @addr from each VMA. Ensure that page fault handler is ready to handle ++ * new mappings of @addr before calling this function. ++ */ ++void sgx_zap_enclave_ptes(struct sgx_encl *encl, unsigned long addr) ++{ ++ unsigned long mm_list_version; ++ struct sgx_encl_mm *encl_mm; ++ struct vm_area_struct *vma; ++ int idx, ret; ++ ++ do { ++ mm_list_version = encl->mm_list_version; ++ ++ /* Pairs with smp_wmb() in sgx_encl_mm_add(). */ ++ smp_rmb(); ++ ++ idx = srcu_read_lock(&encl->srcu); ++ ++ list_for_each_entry_rcu(encl_mm, &encl->mm_list, list) { ++ if (!mmget_not_zero(encl_mm->mm)) ++ continue; ++ ++ mmap_read_lock(encl_mm->mm); ++ ++ ret = sgx_encl_find(encl_mm->mm, addr, &vma); ++ if (!ret && encl == vma->vm_private_data) ++ zap_vma_ptes(vma, addr, PAGE_SIZE); ++ ++ mmap_read_unlock(encl_mm->mm); ++ ++ mmput_async(encl_mm->mm); ++ } ++ ++ srcu_read_unlock(&encl->srcu, idx); ++ } while (unlikely(encl->mm_list_version != mm_list_version)); ++} ++ + /** + * sgx_alloc_va_page() - Allocate a Version Array (VA) page ++ * @reclaim: Reclaim EPC pages directly if none available. Enclave ++ * mutex should not be held if this is set. + * + * Allocate a free EPC page and convert it to a Version Array (VA) page. + * +@@ -926,12 +990,12 @@ int sgx_encl_test_and_clear_young(struct mm_struct *mm, + * a VA page, + * -errno otherwise + */ +-struct sgx_epc_page *sgx_alloc_va_page(void) ++struct sgx_epc_page *sgx_alloc_va_page(bool reclaim) + { + struct sgx_epc_page *epc_page; + int ret; + +- epc_page = sgx_alloc_epc_page(NULL, true); ++ epc_page = sgx_alloc_epc_page(NULL, reclaim); + if (IS_ERR(epc_page)) + return ERR_CAST(epc_page); + +diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h +index 332ef3568267e3..b5e9602be127ef 100644 +--- a/arch/x86/kernel/cpu/sgx/encl.h ++++ b/arch/x86/kernel/cpu/sgx/encl.h +@@ -113,11 +113,15 @@ int sgx_encl_alloc_backing(struct sgx_encl *encl, unsigned long page_index, + void sgx_encl_put_backing(struct sgx_backing *backing); + int sgx_encl_test_and_clear_young(struct mm_struct *mm, + struct sgx_encl_page *page); +- +-struct sgx_epc_page *sgx_alloc_va_page(void); ++void sgx_zap_enclave_ptes(struct sgx_encl *encl, unsigned long addr); ++struct sgx_epc_page *sgx_alloc_va_page(bool reclaim); + unsigned int sgx_alloc_va_slot(struct sgx_va_page *va_page); + void sgx_free_va_slot(struct sgx_va_page *va_page, unsigned int offset); + bool sgx_va_page_full(struct sgx_va_page *va_page); + void sgx_encl_free_epc_page(struct sgx_epc_page *page); ++struct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl, ++ unsigned long addr); ++struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl, bool reclaim); ++void sgx_encl_shrink(struct sgx_encl *encl, struct sgx_va_page *va_page); + + #endif /* _X86_ENCL_H */ +diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c +index 217777c029eea6..14ee6d21800341 100644 +--- a/arch/x86/kernel/cpu/sgx/ioctl.c ++++ b/arch/x86/kernel/cpu/sgx/ioctl.c +@@ -17,7 +17,7 @@ + #include "encl.h" + #include "encls.h" + +-static struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl) ++struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl, bool reclaim) + { + struct sgx_va_page *va_page = NULL; + void *err; +@@ -30,7 +30,7 @@ static struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl) + if (!va_page) + return ERR_PTR(-ENOMEM); + +- va_page->epc_page = sgx_alloc_va_page(); ++ va_page->epc_page = sgx_alloc_va_page(reclaim); + if (IS_ERR(va_page->epc_page)) { + err = ERR_CAST(va_page->epc_page); + kfree(va_page); +@@ -43,7 +43,7 @@ static struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl) + return va_page; + } + +-static void sgx_encl_shrink(struct sgx_encl *encl, struct sgx_va_page *va_page) ++void sgx_encl_shrink(struct sgx_encl *encl, struct sgx_va_page *va_page) + { + encl->page_cnt--; + +@@ -64,7 +64,14 @@ static int sgx_encl_create(struct sgx_encl *encl, struct sgx_secs *secs) + struct file *backing; + long ret; + +- va_page = sgx_encl_grow(encl); ++ /* ++ * ECREATE would detect this too, but checking here also ensures ++ * that the 'encl_size' calculations below can never overflow. ++ */ ++ if (!is_power_of_2(secs->size)) ++ return -EINVAL; ++ ++ va_page = sgx_encl_grow(encl, true); + if (IS_ERR(va_page)) + return PTR_ERR(va_page); + else if (va_page) +@@ -306,7 +313,7 @@ static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long src, + return PTR_ERR(epc_page); + } + +- va_page = sgx_encl_grow(encl); ++ va_page = sgx_encl_grow(encl, true); + if (IS_ERR(va_page)) { + ret = PTR_ERR(va_page); + goto err_out_free; +diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c +index ad453b4387a443..fd786f1bc4e871 100644 +--- a/arch/x86/kernel/cpu/sgx/main.c ++++ b/arch/x86/kernel/cpu/sgx/main.c +@@ -122,36 +122,9 @@ static void sgx_reclaimer_block(struct sgx_epc_page *epc_page) + struct sgx_encl_page *page = epc_page->owner; + unsigned long addr = page->desc & PAGE_MASK; + struct sgx_encl *encl = page->encl; +- unsigned long mm_list_version; +- struct sgx_encl_mm *encl_mm; +- struct vm_area_struct *vma; +- int idx, ret; +- +- do { +- mm_list_version = encl->mm_list_version; +- +- /* Pairs with smp_rmb() in sgx_encl_mm_add(). */ +- smp_rmb(); +- +- idx = srcu_read_lock(&encl->srcu); +- +- list_for_each_entry_rcu(encl_mm, &encl->mm_list, list) { +- if (!mmget_not_zero(encl_mm->mm)) +- continue; +- +- mmap_read_lock(encl_mm->mm); +- +- ret = sgx_encl_find(encl_mm->mm, addr, &vma); +- if (!ret && encl == vma->vm_private_data) +- zap_vma_ptes(vma, addr, PAGE_SIZE); +- +- mmap_read_unlock(encl_mm->mm); +- +- mmput_async(encl_mm->mm); +- } ++ int ret; + +- srcu_read_unlock(&encl->srcu, idx); +- } while (unlikely(encl->mm_list_version != mm_list_version)); ++ sgx_zap_enclave_ptes(encl, addr); + + mutex_lock(&encl->lock); + +diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c +index 2b7999a1a50a83..80e262bb627fe1 100644 +--- a/arch/x86/kernel/i8253.c ++++ b/arch/x86/kernel/i8253.c +@@ -8,6 +8,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -39,9 +40,15 @@ static bool __init use_pit(void) + + bool __init pit_timer_init(void) + { +- if (!use_pit()) ++ if (!use_pit()) { ++ /* ++ * Don't just ignore the PIT. Ensure it's stopped, because ++ * VMMs otherwise steal CPU time just to pointlessly waggle ++ * the (masked) IRQ. ++ */ ++ clockevent_i8253_disable(); + return false; +- ++ } + clockevent_i8253_init(true); + global_clock_event = &i8253_clockevent; + return true; +diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c +index 54d87bc2af7b0e..a5dd11c92d055c 100644 +--- a/arch/x86/kernel/static_call.c ++++ b/arch/x86/kernel/static_call.c +@@ -169,7 +169,6 @@ EXPORT_SYMBOL_GPL(arch_static_call_transform); + noinstr void __static_call_update_early(void *tramp, void *func) + { + BUG_ON(system_state != SYSTEM_BOOTING); +- BUG_ON(!early_boot_irqs_disabled); + BUG_ON(static_call_initialized); + __text_gen_insn(tramp, JMP32_INSN_OPCODE, tramp, func, JMP32_INSN_SIZE); + sync_core(); +diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c +index 29a96d1c7e2b89..32d1c9064b5e8d 100644 +--- a/arch/x86/kvm/hyperv.c ++++ b/arch/x86/kvm/hyperv.c +@@ -1902,6 +1902,9 @@ static u64 kvm_hv_send_ipi(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc) + bool all_cpus; + int i; + ++ if (!lapic_in_kernel(vcpu)) ++ return HV_STATUS_INVALID_HYPERCALL_INPUT; ++ + if (hc->code == HVCALL_SEND_IPI) { + if (!hc->fast) { + if (unlikely(kvm_read_guest(kvm, hc->ingpa, &send_ipi, +@@ -2507,7 +2510,8 @@ int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid, + ent->eax |= HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED; + ent->eax |= HV_X64_APIC_ACCESS_RECOMMENDED; + ent->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED; +- ent->eax |= HV_X64_CLUSTER_IPI_RECOMMENDED; ++ if (!vcpu || lapic_in_kernel(vcpu)) ++ ent->eax |= HV_X64_CLUSTER_IPI_RECOMMENDED; + ent->eax |= HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED; + if (evmcs_ver) + ent->eax |= HV_X64_ENLIGHTENED_VMCS_RECOMMENDED; +diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c +index 5953c7482016e7..1110f6dda3525c 100644 +--- a/arch/x86/mm/init.c ++++ b/arch/x86/mm/init.c +@@ -264,28 +264,33 @@ static void __init probe_page_size_mask(void) + } + + /* +- * INVLPG may not properly flush Global entries +- * on these CPUs when PCIDs are enabled. ++ * INVLPG may not properly flush Global entries on ++ * these CPUs. New microcode fixes the issue. + */ + static const struct x86_cpu_id invlpg_miss_ids[] = { +- X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, 0), +- X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, 0), +- X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, 0), +- X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, 0), +- X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, 0), +- X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, 0), ++ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, 0x2e), ++ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, 0x42c), ++ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, 0x11), ++ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, 0x118), ++ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, 0x4117), ++ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, 0x2e), + {} + }; + + static void setup_pcid(void) + { ++ const struct x86_cpu_id *invlpg_miss_match; ++ + if (!IS_ENABLED(CONFIG_X86_64)) + return; + + if (!boot_cpu_has(X86_FEATURE_PCID)) + return; + +- if (x86_match_cpu(invlpg_miss_ids)) { ++ invlpg_miss_match = x86_match_cpu(invlpg_miss_ids); ++ ++ if (invlpg_miss_match && ++ boot_cpu_data.microcode < invlpg_miss_match->driver_data) { + pr_info("Incomplete global flushes, disabling PCID"); + setup_clear_cpu_cap(X86_FEATURE_PCID); + return; +diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c +index 511172d70825c5..19d083ad2de795 100644 +--- a/arch/x86/mm/tlb.c ++++ b/arch/x86/mm/tlb.c +@@ -854,9 +854,36 @@ static void flush_tlb_func(void *info) + nr_invalidate); + } + +-static bool tlb_is_not_lazy(int cpu, void *data) ++static bool should_flush_tlb(int cpu, void *data) + { +- return !per_cpu(cpu_tlbstate_shared.is_lazy, cpu); ++ struct flush_tlb_info *info = data; ++ ++ /* Lazy TLB will get flushed at the next context switch. */ ++ if (per_cpu(cpu_tlbstate_shared.is_lazy, cpu)) ++ return false; ++ ++ /* No mm means kernel memory flush. */ ++ if (!info->mm) ++ return true; ++ ++ /* The target mm is loaded, and the CPU is not lazy. */ ++ if (per_cpu(cpu_tlbstate.loaded_mm, cpu) == info->mm) ++ return true; ++ ++ /* In cpumask, but not the loaded mm? Periodically remove by flushing. */ ++ if (info->trim_cpumask) ++ return true; ++ ++ return false; ++} ++ ++static bool should_trim_cpumask(struct mm_struct *mm) ++{ ++ if (time_after(jiffies, READ_ONCE(mm->context.next_trim_cpumask))) { ++ WRITE_ONCE(mm->context.next_trim_cpumask, jiffies + HZ); ++ return true; ++ } ++ return false; + } + + DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state_shared, cpu_tlbstate_shared); +@@ -890,7 +917,7 @@ STATIC_NOPV void native_flush_tlb_multi(const struct cpumask *cpumask, + if (info->freed_tables) + on_each_cpu_mask(cpumask, flush_tlb_func, (void *)info, true); + else +- on_each_cpu_cond_mask(tlb_is_not_lazy, flush_tlb_func, ++ on_each_cpu_cond_mask(should_flush_tlb, flush_tlb_func, + (void *)info, 1, cpumask); + } + +@@ -941,6 +968,7 @@ static struct flush_tlb_info *get_flush_tlb_info(struct mm_struct *mm, + info->freed_tables = freed_tables; + info->new_tlb_gen = new_tlb_gen; + info->initiating_cpu = smp_processor_id(); ++ info->trim_cpumask = 0; + + return info; + } +@@ -983,6 +1011,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, + * flush_tlb_func_local() directly in this case. + */ + if (cpumask_any_but(mm_cpumask(mm), cpu) < nr_cpu_ids) { ++ info->trim_cpumask = should_trim_cpumask(mm); + flush_tlb_multi(mm_cpumask(mm), info); + } else if (mm == this_cpu_read(cpu_tlbstate.loaded_mm)) { + lockdep_assert_irqs_enabled(); +diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c +index 3359c23573c501..4eb6a6bb609f4e 100644 +--- a/arch/x86/xen/mmu_pv.c ++++ b/arch/x86/xen/mmu_pv.c +@@ -95,6 +95,51 @@ static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss; + */ + static DEFINE_SPINLOCK(xen_reservation_lock); + ++/* Protected by xen_reservation_lock. */ ++#define MIN_CONTIG_ORDER 9 /* 2MB */ ++static unsigned int discontig_frames_order = MIN_CONTIG_ORDER; ++static unsigned long discontig_frames_early[1UL << MIN_CONTIG_ORDER] __initdata; ++static unsigned long *discontig_frames __refdata = discontig_frames_early; ++static bool discontig_frames_dyn; ++ ++static int alloc_discontig_frames(unsigned int order) ++{ ++ unsigned long *new_array, *old_array; ++ unsigned int old_order; ++ unsigned long flags; ++ ++ BUG_ON(order < MIN_CONTIG_ORDER); ++ BUILD_BUG_ON(sizeof(discontig_frames_early) != PAGE_SIZE); ++ ++ new_array = (unsigned long *)__get_free_pages(GFP_KERNEL, ++ order - MIN_CONTIG_ORDER); ++ if (!new_array) ++ return -ENOMEM; ++ ++ spin_lock_irqsave(&xen_reservation_lock, flags); ++ ++ old_order = discontig_frames_order; ++ ++ if (order > discontig_frames_order || !discontig_frames_dyn) { ++ if (!discontig_frames_dyn) ++ old_array = NULL; ++ else ++ old_array = discontig_frames; ++ ++ discontig_frames = new_array; ++ discontig_frames_order = order; ++ discontig_frames_dyn = true; ++ } else { ++ old_array = new_array; ++ } ++ ++ spin_unlock_irqrestore(&xen_reservation_lock, flags); ++ ++ free_pages((unsigned long)old_array, old_order - MIN_CONTIG_ORDER); ++ ++ return 0; ++} ++ + /* + * Note about cr3 (pagetable base) values: + * +@@ -762,6 +807,7 @@ void xen_mm_pin_all(void) + { + struct page *page; + ++ spin_lock(&init_mm.page_table_lock); + spin_lock(&pgd_lock); + + list_for_each_entry(page, &pgd_list, lru) { +@@ -772,6 +818,7 @@ void xen_mm_pin_all(void) + } + + spin_unlock(&pgd_lock); ++ spin_unlock(&init_mm.page_table_lock); + } + + static void __init xen_mark_pinned(struct mm_struct *mm, struct page *page, +@@ -791,6 +838,9 @@ static void __init xen_after_bootmem(void) + static_branch_enable(&xen_struct_pages_ready); + SetPagePinned(virt_to_page(level3_user_vsyscall)); + xen_pgd_walk(&init_mm, xen_mark_pinned, FIXADDR_TOP); ++ ++ if (alloc_discontig_frames(MIN_CONTIG_ORDER)) ++ BUG(); + } + + static void xen_unpin_page(struct mm_struct *mm, struct page *page, +@@ -866,6 +916,7 @@ void xen_mm_unpin_all(void) + { + struct page *page; + ++ spin_lock(&init_mm.page_table_lock); + spin_lock(&pgd_lock); + + list_for_each_entry(page, &pgd_list, lru) { +@@ -877,6 +928,7 @@ void xen_mm_unpin_all(void) + } + + spin_unlock(&pgd_lock); ++ spin_unlock(&init_mm.page_table_lock); + } + + static void xen_activate_mm(struct mm_struct *prev, struct mm_struct *next) +@@ -2151,10 +2203,6 @@ void __init xen_init_mmu_ops(void) + memset(dummy_mapping, 0xff, PAGE_SIZE); + } + +-/* Protected by xen_reservation_lock. */ +-#define MAX_CONTIG_ORDER 9 /* 2MB */ +-static unsigned long discontig_frames[1< discontig_frames_order)) { ++ if (!discontig_frames_dyn) ++ return -ENOMEM; + +- if (unlikely(order > MAX_CONTIG_ORDER)) +- return -ENOMEM; ++ if (alloc_discontig_frames(order)) ++ return -ENOMEM; ++ } + + memset((void *) vstart, 0, PAGE_SIZE << order); + + spin_lock_irqsave(&xen_reservation_lock, flags); + ++ in_frames = discontig_frames; ++ + /* 1. Zap current PTEs, remembering MFNs. */ + xen_zap_pfn_range(vstart, order, in_frames, NULL); + +@@ -2312,12 +2361,12 @@ int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order, + + void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order) + { +- unsigned long *out_frames = discontig_frames, in_frame; ++ unsigned long *out_frames, in_frame; + unsigned long flags; + int success; + unsigned long vstart; + +- if (unlikely(order > MAX_CONTIG_ORDER)) ++ if (unlikely(order > discontig_frames_order)) + return; + + vstart = (unsigned long)phys_to_virt(pstart); +@@ -2325,6 +2374,8 @@ void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order) + + spin_lock_irqsave(&xen_reservation_lock, flags); + ++ out_frames = discontig_frames; ++ + /* 1. Find start MFN of contiguous extent. */ + in_frame = virt_to_mfn(vstart); + +diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c +index 9b3a9fa4a0ade3..899590f1f74a51 100644 +--- a/arch/x86/xen/p2m.c ++++ b/arch/x86/xen/p2m.c +@@ -197,7 +197,7 @@ static void * __ref alloc_p2m_page(void) + static void __ref free_p2m_page(void *p) + { + if (unlikely(!slab_is_available())) { +- memblock_free((unsigned long)p, PAGE_SIZE); ++ memblock_free_ptr(p, PAGE_SIZE); + return; + } + +diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S +index 152bbe900a174a..6105404ba57036 100644 +--- a/arch/x86/xen/xen-head.S ++++ b/arch/x86/xen/xen-head.S +@@ -115,8 +115,8 @@ SYM_FUNC_START(xen_hypercall_hvm) + pop %ebx + pop %eax + #else +- lea xen_hypercall_amd(%rip), %rbx +- cmp %rax, %rbx ++ lea xen_hypercall_amd(%rip), %rcx ++ cmp %rax, %rcx + #ifdef CONFIG_FRAME_POINTER + pop %rax /* Dummy pop. */ + #endif +@@ -130,6 +130,7 @@ SYM_FUNC_START(xen_hypercall_hvm) + pop %rcx + pop %rax + #endif ++ FRAME_END + /* Use correct hypercall function. */ + jz xen_hypercall_amd + jmp xen_hypercall_intel +diff --git a/block/Kconfig b/block/Kconfig +index 8e28ae7718bd23..0d415226e3daae 100644 +--- a/block/Kconfig ++++ b/block/Kconfig +@@ -26,6 +26,18 @@ menuconfig BLOCK + + if BLOCK + ++config BLOCK_LEGACY_AUTOLOAD ++ bool "Legacy autoloading support" ++ help ++ Enable loading modules and creating block device instances based on ++ accesses through their device special file. This is a historic Linux ++ feature and makes no sense in a udev world where device files are ++ created on demand. ++ ++ Say N here unless booting or other functionality broke without it, in ++ which case you should also send a report to your distribution and ++ linux-block@vger.kernel.org. ++ + config BLK_RQ_ALLOC_TIME + bool + +diff --git a/block/bdev.c b/block/bdev.c +index b8599a4088843d..85c090ef3bf2c3 100644 +--- a/block/bdev.c ++++ b/block/bdev.c +@@ -736,12 +736,15 @@ struct block_device *blkdev_get_no_open(dev_t dev) + struct inode *inode; + + inode = ilookup(blockdev_superblock, dev); +- if (!inode) { ++ if (!inode && IS_ENABLED(CONFIG_BLOCK_LEGACY_AUTOLOAD)) { + blk_request_module(dev); + inode = ilookup(blockdev_superblock, dev); +- if (!inode) +- return NULL; ++ if (inode) ++ pr_warn_ratelimited( ++"block device autoloading is deprecated. It will be removed in Linux 5.19\n"); + } ++ if (!inode) ++ return NULL; + + /* switch from the inode reference to a device mode one: */ + bdev = &BDEV_I(inode)->bdev; +diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c +index fd81a737086453..6180c680136b8a 100644 +--- a/block/blk-cgroup.c ++++ b/block/blk-cgroup.c +@@ -894,6 +894,7 @@ static void blkcg_fill_root_iostats(void) + blkg_iostat_set(&blkg->iostat.cur, &tmp); + u64_stats_update_end_irqrestore(&blkg->iostat.sync, flags); + } ++ class_dev_iter_exit(&iter); + } + + static void blkcg_print_one_stat(struct blkcg_gq *blkg, struct seq_file *s) +diff --git a/block/genhd.c b/block/genhd.c +index 88d1a6385a2423..421e02794614e6 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -182,7 +182,9 @@ static struct blk_major_name { + struct blk_major_name *next; + int major; + char name[16]; ++#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD + void (*probe)(dev_t devt); ++#endif + } *major_names[BLKDEV_MAJOR_HASH_SIZE]; + static DEFINE_MUTEX(major_names_lock); + static DEFINE_SPINLOCK(major_names_spinlock); +@@ -269,7 +271,9 @@ int __register_blkdev(unsigned int major, const char *name, + } + + p->major = major; ++#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD + p->probe = probe; ++#endif + strlcpy(p->name, name, sizeof(p->name)); + p->next = NULL; + index = major_to_index(major); +@@ -669,7 +673,8 @@ static ssize_t disk_badblocks_store(struct device *dev, + return badblocks_store(disk->bb, page, len, 0); + } + +-void blk_request_module(dev_t devt) ++#ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD ++static bool blk_probe_dev(dev_t devt) + { + unsigned int major = MAJOR(devt); + struct blk_major_name **n; +@@ -679,15 +684,28 @@ void blk_request_module(dev_t devt) + if ((*n)->major == major && (*n)->probe) { + (*n)->probe(devt); + mutex_unlock(&major_names_lock); +- return; ++ return true; + } + } + mutex_unlock(&major_names_lock); ++ return false; ++} ++ ++void blk_request_module(dev_t devt) ++{ ++ int error; ++ ++ if (blk_probe_dev(devt)) ++ return; + +- if (request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)) > 0) +- /* Make old-style 2.4 aliases work */ +- request_module("block-major-%d", MAJOR(devt)); ++ error = request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)); ++ /* Make old-style 2.4 aliases work */ ++ if (error > 0) ++ error = request_module("block-major-%d", MAJOR(devt)); ++ if (!error) ++ blk_probe_dev(devt); + } ++#endif /* CONFIG_BLOCK_LEGACY_AUTOLOAD */ + + /* + * print a full list of all partitions - intended for places where the root +diff --git a/block/partitions/efi.c b/block/partitions/efi.c +index 7ca5c4c374d4d5..c945695858387f 100644 +--- a/block/partitions/efi.c ++++ b/block/partitions/efi.c +@@ -682,7 +682,7 @@ static void utf16_le_to_7bit(const __le16 *in, unsigned int size, u8 *out) + out[size] = 0; + + while (i < size) { +- u8 c = le16_to_cpu(in[i]) & 0xff; ++ u8 c = le16_to_cpu(in[i]) & 0x7f; + + if (c && !isprint(c)) + c = '!'; +diff --git a/block/partitions/ldm.h b/block/partitions/ldm.h +index 8693704dcf5e99..84a66b51cd2ab8 100644 +--- a/block/partitions/ldm.h ++++ b/block/partitions/ldm.h +@@ -1,5 +1,5 @@ + // SPDX-License-Identifier: GPL-2.0-or-later +-/** ++/* + * ldm - Part of the Linux-NTFS project. + * + * Copyright (C) 2001,2002 Richard Russon +diff --git a/block/partitions/mac.c b/block/partitions/mac.c +index 7b521df00a39f4..6415213cd184e7 100644 +--- a/block/partitions/mac.c ++++ b/block/partitions/mac.c +@@ -51,13 +51,25 @@ int mac_partition(struct parsed_partitions *state) + } + secsize = be16_to_cpu(md->block_size); + put_dev_sector(sect); ++ ++ /* ++ * If the "block size" is not a power of 2, things get weird - we might ++ * end up with a partition straddling a sector boundary, so we wouldn't ++ * be able to read a partition entry with read_part_sector(). ++ * Real block sizes are probably (?) powers of two, so just require ++ * that. ++ */ ++ if (!is_power_of_2(secsize)) ++ return -1; + datasize = round_down(secsize, 512); + data = read_part_sector(state, datasize / 512, §); + if (!data) + return -1; + partoffset = secsize % 512; +- if (partoffset + sizeof(*part) > datasize) ++ if (partoffset + sizeof(*part) > datasize) { ++ put_dev_sector(sect); + return -1; ++ } + part = (struct mac_partition *) (data + partoffset); + if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) { + put_dev_sector(sect); +@@ -110,8 +122,8 @@ int mac_partition(struct parsed_partitions *state) + int i, l; + + goodness++; +- l = strlen(part->name); +- if (strcmp(part->name, "/") == 0) ++ l = strnlen(part->name, sizeof(part->name)); ++ if (strncmp(part->name, "/", sizeof(part->name)) == 0) + goodness++; + for (i = 0; i <= l - 4; ++i) { + if (strncasecmp(part->name + i, "root", +diff --git a/crypto/testmgr.h b/crypto/testmgr.h +index 2be20a590a6069..8eb0a0558cf3ab 100644 +--- a/crypto/testmgr.h ++++ b/crypto/testmgr.h +@@ -183,8 +183,8 @@ static const struct akcipher_testvec rsa_tv_template[] = { + { + #ifndef CONFIG_CRYPTO_FIPS + .key = +- "\x30\x81\x9A" /* sequence of 154 bytes */ +- "\x02\x01\x01" /* version - integer of 1 byte */ ++ "\x30\x82\x01\x38" /* sequence of 312 bytes */ ++ "\x02\x01\x00" /* version - integer of 1 byte */ + "\x02\x41" /* modulus - integer of 65 bytes */ + "\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F" + "\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5" +@@ -197,24 +197,37 @@ static const struct akcipher_testvec rsa_tv_template[] = { + "\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64" + "\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9" + "\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51" +- "\x02\x01\x00" /* prime1 - integer of 1 byte */ +- "\x02\x01\x00" /* prime2 - integer of 1 byte */ +- "\x02\x01\x00" /* exponent1 - integer of 1 byte */ +- "\x02\x01\x00" /* exponent2 - integer of 1 byte */ +- "\x02\x01\x00", /* coefficient - integer of 1 byte */ ++ "\x02\x21" /* prime1 - integer of 33 bytes */ ++ "\x00\xD8\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5" ++ "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x12" ++ "\x0D" ++ "\x02\x21" /* prime2 - integer of 33 bytes */ ++ "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9" ++ "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D" ++ "\x89" ++ "\x02\x20" /* exponent1 - integer of 32 bytes */ ++ "\x59\x0B\x95\x72\xA2\xC2\xA9\xC4\x06\x05\x9D\xC2\xAB\x2F\x1D\xAF" ++ "\xEB\x7E\x8B\x4F\x10\xA7\x54\x9E\x8E\xED\xF5\xB4\xFC\xE0\x9E\x05" ++ "\x02\x21" /* exponent2 - integer of 33 bytes */ ++ "\x00\x8E\x3C\x05\x21\xFE\x15\xE0\xEA\x06\xA3\x6F\xF0\xF1\x0C\x99" ++ "\x52\xC3\x5B\x7A\x75\x14\xFD\x32\x38\xB8\x0A\xAD\x52\x98\x62\x8D" ++ "\x51" ++ "\x02\x20" /* coefficient - integer of 32 bytes */ ++ "\x36\x3F\xF7\x18\x9D\xA8\xE9\x0B\x1D\x34\x1F\x71\xD0\x9B\x76\xA8" ++ "\xA9\x43\xE1\x1D\x10\xB2\x4D\x24\x9F\x2D\xEA\xFE\xF8\x0C\x18\x26", + .m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a", + .c = + "\x63\x1c\xcd\x7b\xe1\x7e\xe4\xde\xc9\xa8\x89\xa1\x74\xcb\x3c\x63" + "\x7d\x24\xec\x83\xc3\x15\xe4\x7f\x73\x05\x34\xd1\xec\x22\xbb\x8a" + "\x5e\x32\x39\x6d\xc1\x1d\x7d\x50\x3b\x9f\x7a\xad\xf0\x2e\x25\x53" + "\x9f\x6e\xbd\x4c\x55\x84\x0c\x9b\xcf\x1a\x4b\x51\x1e\x9e\x0c\x06", +- .key_len = 157, ++ .key_len = 316, + .m_size = 8, + .c_size = 64, + }, { + .key = +- "\x30\x82\x01\x1D" /* sequence of 285 bytes */ +- "\x02\x01\x01" /* version - integer of 1 byte */ ++ "\x30\x82\x02\x5B" /* sequence of 603 bytes */ ++ "\x02\x01\x00" /* version - integer of 1 byte */ + "\x02\x81\x81" /* modulus - integer of 129 bytes */ + "\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71" + "\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5" +@@ -236,12 +249,35 @@ static const struct akcipher_testvec rsa_tv_template[] = { + "\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94" + "\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3" + "\xC1" +- "\x02\x01\x00" /* prime1 - integer of 1 byte */ +- "\x02\x01\x00" /* prime2 - integer of 1 byte */ +- "\x02\x01\x00" /* exponent1 - integer of 1 byte */ +- "\x02\x01\x00" /* exponent2 - integer of 1 byte */ +- "\x02\x01\x00", /* coefficient - integer of 1 byte */ +- .key_len = 289, ++ "\x02\x41" /* prime1 - integer of 65 bytes */ ++ "\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60" ++ "\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6" ++ "\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A" ++ "\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65" ++ "\x99" ++ "\x02\x41" /* prime2 - integer of 65 bytes */ ++ "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9" ++ "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D" ++ "\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5" ++ "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15" ++ "\x03" ++ "\x02\x40" /* exponent1 - integer of 64 bytes */ ++ "\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A" ++ "\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E" ++ "\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E" ++ "\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81" ++ "\x02\x40" /* exponent2 - integer of 64 bytes */ ++ "\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9" ++ "\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7" ++ "\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D" ++ "\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D" ++ "\x02\x41" /* coefficient - integer of 65 bytes */ ++ "\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23" ++ "\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11" ++ "\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E" ++ "\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39" ++ "\xF7", ++ .key_len = 607, + .m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a", + .c = + "\x74\x1b\x55\xac\x47\xb5\x08\x0a\x6e\x2b\x2d\xf7\x94\xb8\x8a\x95" +@@ -257,9 +293,9 @@ static const struct akcipher_testvec rsa_tv_template[] = { + }, { + #endif + .key = +- "\x30\x82\x02\x1F" /* sequence of 543 bytes */ +- "\x02\x01\x01" /* version - integer of 1 byte */ +- "\x02\x82\x01\x00" /* modulus - integer of 256 bytes */ ++ "\x30\x82\x04\xA3" /* sequence of 1187 bytes */ ++ "\x02\x01\x00" /* version - integer of 1 byte */ ++ "\x02\x82\x01\x01\x00" /* modulus - integer of 256 bytes */ + "\xDB\x10\x1A\xC2\xA3\xF1\xDC\xFF\x13\x6B\xED\x44\xDF\xF0\x02\x6D" + "\x13\xC7\x88\xDA\x70\x6B\x54\xF1\xE8\x27\xDC\xC3\x0F\x99\x6A\xFA" + "\xC6\x67\xFF\x1D\x1E\x3C\x1D\xC1\xB5\x5F\x6C\xC0\xB2\x07\x3A\x6D" +@@ -294,12 +330,55 @@ static const struct akcipher_testvec rsa_tv_template[] = { + "\x62\xFF\xE9\x46\xB8\xD8\x44\xDB\xA5\xCC\x31\x54\x34\xCE\x3E\x82" + "\xD6\xBF\x7A\x0B\x64\x21\x6D\x88\x7E\x5B\x45\x12\x1E\x63\x8D\x49" + "\xA7\x1D\xD9\x1E\x06\xCD\xE8\xBA\x2C\x8C\x69\x32\xEA\xBE\x60\x71" +- "\x02\x01\x00" /* prime1 - integer of 1 byte */ +- "\x02\x01\x00" /* prime2 - integer of 1 byte */ +- "\x02\x01\x00" /* exponent1 - integer of 1 byte */ +- "\x02\x01\x00" /* exponent2 - integer of 1 byte */ +- "\x02\x01\x00", /* coefficient - integer of 1 byte */ +- .key_len = 547, ++ "\x02\x81\x81" /* prime1 - integer of 129 bytes */ ++ "\x00\xFA\xAC\xE1\x37\x5E\x32\x11\x34\xC6\x72\x58\x2D\x91\x06\x3E" ++ "\x77\xE7\x11\x21\xCD\x4A\xF8\xA4\x3F\x0F\xEF\x31\xE3\xF3\x55\xA0" ++ "\xB9\xAC\xB6\xCB\xBB\x41\xD0\x32\x81\x9A\x8F\x7A\x99\x30\x77\x6C" ++ "\x68\x27\xE2\x96\xB5\x72\xC9\xC3\xD4\x42\xAA\xAA\xCA\x95\x8F\xFF" ++ "\xC9\x9B\x52\x34\x30\x1D\xCF\xFE\xCF\x3C\x56\x68\x6E\xEF\xE7\x6C" ++ "\xD7\xFB\x99\xF5\x4A\xA5\x21\x1F\x2B\xEA\x93\xE8\x98\x26\xC4\x6E" ++ "\x42\x21\x5E\xA0\xA1\x2A\x58\x35\xBB\x10\xE7\xBA\x27\x0A\x3B\xB3" ++ "\xAF\xE2\x75\x36\x04\xAC\x56\xA0\xAB\x52\xDE\xCE\xDD\x2C\x28\x77" ++ "\x03" ++ "\x02\x81\x81" /* prime2 - integer of 129 bytes */ ++ "\x00\xDF\xB7\x52\xB6\xD7\xC0\xE2\x96\xE7\xC9\xFE\x5D\x71\x5A\xC4" ++ "\x40\x96\x2F\xE5\x87\xEA\xF3\xA5\x77\x11\x67\x3C\x8D\x56\x08\xA7" ++ "\xB5\x67\xFA\x37\xA8\xB8\xCF\x61\xE8\x63\xD8\x38\x06\x21\x2B\x92" ++ "\x09\xA6\x39\x3A\xEA\xA8\xB4\x45\x4B\x36\x10\x4C\xE4\x00\x66\x71" ++ "\x65\xF8\x0B\x94\x59\x4F\x8C\xFD\xD5\x34\xA2\xE7\x62\x84\x0A\xA7" ++ "\xBB\xDB\xD9\x8A\xCD\x05\xE1\xCC\x57\x7B\xF1\xF1\x1F\x11\x9D\xBA" ++ "\x3E\x45\x18\x99\x1B\x41\x64\x43\xEE\x97\x5D\x77\x13\x5B\x74\x69" ++ "\x73\x87\x95\x05\x07\xBE\x45\x07\x17\x7E\x4A\x69\x22\xF3\xDB\x05" ++ "\x39" ++ "\x02\x81\x80" /* exponent1 - integer of 128 bytes */ ++ "\x5E\xD8\xDC\xDA\x53\x44\xC4\x67\xE0\x92\x51\x34\xE4\x83\xA5\x4D" ++ "\x3E\xDB\xA7\x9B\x82\xBB\x73\x81\xFC\xE8\x77\x4B\x15\xBE\x17\x73" ++ "\x49\x9B\x5C\x98\xBC\xBD\x26\xEF\x0C\xE9\x2E\xED\x19\x7E\x86\x41" ++ "\x1E\x9E\x48\x81\xDD\x2D\xE4\x6F\xC2\xCD\xCA\x93\x9E\x65\x7E\xD5" ++ "\xEC\x73\xFD\x15\x1B\xA2\xA0\x7A\x0F\x0D\x6E\xB4\x53\x07\x90\x92" ++ "\x64\x3B\x8B\xA9\x33\xB3\xC5\x94\x9B\x4C\x5D\x9C\x7C\x46\xA4\xA5" ++ "\x56\xF4\xF3\xF8\x27\x0A\x7B\x42\x0D\x92\x70\x47\xE7\x42\x51\xA9" ++ "\xC2\x18\xB1\x58\xB1\x50\x91\xB8\x61\x41\xB6\xA9\xCE\xD4\x7C\xBB" ++ "\x02\x81\x80" /* exponent2 - integer of 128 bytes */ ++ "\x54\x09\x1F\x0F\x03\xD8\xB6\xC5\x0C\xE8\xB9\x9E\x0C\x38\x96\x43" ++ "\xD4\xA6\xC5\x47\xDB\x20\x0E\xE5\xBD\x29\xD4\x7B\x1A\xF8\x41\x57" ++ "\x49\x69\x9A\x82\xCC\x79\x4A\x43\xEB\x4D\x8B\x2D\xF2\x43\xD5\xA5" ++ "\xBE\x44\xFD\x36\xAC\x8C\x9B\x02\xF7\x9A\x03\xE8\x19\xA6\x61\xAE" ++ "\x76\x10\x93\x77\x41\x04\xAB\x4C\xED\x6A\xCC\x14\x1B\x99\x8D\x0C" ++ "\x6A\x37\x3B\x86\x6C\x51\x37\x5B\x1D\x79\xF2\xA3\x43\x10\xC6\xA7" ++ "\x21\x79\x6D\xF9\xE9\x04\x6A\xE8\x32\xFF\xAE\xFD\x1C\x7B\x8C\x29" ++ "\x13\xA3\x0C\xB2\xAD\xEC\x6C\x0F\x8D\x27\x12\x7B\x48\xB2\xDB\x31" ++ "\x02\x81\x81" /* coefficient - integer of 129 bytes */ ++ "\x00\x8D\x1B\x05\xCA\x24\x1F\x0C\x53\x19\x52\x74\x63\x21\xFA\x78" ++ "\x46\x79\xAF\x5C\xDE\x30\xA4\x6C\x20\x38\xE6\x97\x39\xB8\x7A\x70" ++ "\x0D\x8B\x6C\x6D\x13\x74\xD5\x1C\xDE\xA9\xF4\x60\x37\xFE\x68\x77" ++ "\x5E\x0B\x4E\x5E\x03\x31\x30\xDF\xD6\xAE\x85\xD0\x81\xBB\x61\xC7" ++ "\xB1\x04\x5A\xC4\x6D\x56\x1C\xD9\x64\xE7\x85\x7F\x88\x91\xC9\x60" ++ "\x28\x05\xE2\xC6\x24\x8F\xDD\x61\x64\xD8\x09\xDE\x7E\xD3\x4A\x61" ++ "\x1A\xD3\x73\x58\x4B\xD8\xA0\x54\x25\x48\x83\x6F\x82\x6C\xAF\x36" ++ "\x51\x2A\x5D\x14\x2F\x41\x25\x00\xDD\xF8\xF3\x95\xFE\x31\x25\x50" ++ "\x12", ++ .key_len = 1191, + .m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a", + .c = + "\xb2\x97\x76\xb4\xae\x3e\x38\x3c\x7e\x64\x1f\xcc\xa2\x7f\xf6\xbe" +@@ -1150,7 +1229,7 @@ static const struct akcipher_testvec ecrdsa_tv_template[] = { + static const struct akcipher_testvec pkcs1pad_rsa_tv_template[] = { + { + .key = +- "\x30\x82\x03\x1f\x02\x01\x00\x02\x82\x01\x01\x00\xd7\x1e\x77\x82" ++ "\x30\x82\x04\xa5\x02\x01\x00\x02\x82\x01\x01\x00\xd7\x1e\x77\x82" + "\x8c\x92\x31\xe7\x69\x02\xa2\xd5\x5c\x78\xde\xa2\x0c\x8f\xfe\x28" + "\x59\x31\xdf\x40\x9c\x60\x61\x06\xb9\x2f\x62\x40\x80\x76\xcb\x67" + "\x4a\xb5\x59\x56\x69\x17\x07\xfa\xf9\x4c\xbd\x6c\x37\x7a\x46\x7d" +@@ -1166,42 +1245,66 @@ static const struct akcipher_testvec pkcs1pad_rsa_tv_template[] = { + "\x9e\x49\x63\x6e\x02\xc1\xc9\x3a\x9b\xa5\x22\x1b\x07\x95\xd6\x10" + "\x02\x50\xfd\xfd\xd1\x9b\xbe\xab\xc2\xc0\x74\xd7\xec\x00\xfb\x11" + "\x71\xcb\x7a\xdc\x81\x79\x9f\x86\x68\x46\x63\x82\x4d\xb7\xf1\xe6" +- "\x16\x6f\x42\x63\xf4\x94\xa0\xca\x33\xcc\x75\x13\x02\x82\x01\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01" +- "\x02\x82\x01\x00\x62\xb5\x60\x31\x4f\x3f\x66\x16\xc1\x60\xac\x47" +- "\x2a\xff\x6b\x69\x00\x4a\xb2\x5c\xe1\x50\xb9\x18\x74\xa8\xe4\xdc" +- "\xa8\xec\xcd\x30\xbb\xc1\xc6\xe3\xc6\xac\x20\x2a\x3e\x5e\x8b\x12" +- "\xe6\x82\x08\x09\x38\x0b\xab\x7c\xb3\xcc\x9c\xce\x97\x67\xdd\xef" +- "\x95\x40\x4e\x92\xe2\x44\xe9\x1d\xc1\x14\xfd\xa9\xb1\xdc\x71\x9c" +- "\x46\x21\xbd\x58\x88\x6e\x22\x15\x56\xc1\xef\xe0\xc9\x8d\xe5\x80" +- "\x3e\xda\x7e\x93\x0f\x52\xf6\xf5\xc1\x91\x90\x9e\x42\x49\x4f\x8d" +- "\x9c\xba\x38\x83\xe9\x33\xc2\x50\x4f\xec\xc2\xf0\xa8\xb7\x6e\x28" +- "\x25\x56\x6b\x62\x67\xfe\x08\xf1\x56\xe5\x6f\x0e\x99\xf1\xe5\x95" +- "\x7b\xef\xeb\x0a\x2c\x92\x97\x57\x23\x33\x36\x07\xdd\xfb\xae\xf1" +- "\xb1\xd8\x33\xb7\x96\x71\x42\x36\xc5\xa4\xa9\x19\x4b\x1b\x52\x4c" +- "\x50\x69\x91\xf0\x0e\xfa\x80\x37\x4b\xb5\xd0\x2f\xb7\x44\x0d\xd4" +- "\xf8\x39\x8d\xab\x71\x67\x59\x05\x88\x3d\xeb\x48\x48\x33\x88\x4e" +- "\xfe\xf8\x27\x1b\xd6\x55\x60\x5e\x48\xb7\x6d\x9a\xa8\x37\xf9\x7a" +- "\xde\x1b\xcd\x5d\x1a\x30\xd4\xe9\x9e\x5b\x3c\x15\xf8\x9c\x1f\xda" +- "\xd1\x86\x48\x55\xce\x83\xee\x8e\x51\xc7\xde\x32\x12\x47\x7d\x46" +- "\xb8\x35\xdf\x41\x02\x01\x00\x02\x01\x00\x02\x01\x00\x02\x01\x00" +- "\x02\x01\x00", +- .key_len = 804, ++ "\x16\x6f\x42\x63\xf4\x94\xa0\xca\x33\xcc\x75\x13\x02\x03\x01\x00" ++ "\x01\x02\x82\x01\x00\x62\xb5\x60\x31\x4f\x3f\x66\x16\xc1\x60\xac" ++ "\x47\x2a\xff\x6b\x69\x00\x4a\xb2\x5c\xe1\x50\xb9\x18\x74\xa8\xe4" ++ "\xdc\xa8\xec\xcd\x30\xbb\xc1\xc6\xe3\xc6\xac\x20\x2a\x3e\x5e\x8b" ++ "\x12\xe6\x82\x08\x09\x38\x0b\xab\x7c\xb3\xcc\x9c\xce\x97\x67\xdd" ++ "\xef\x95\x40\x4e\x92\xe2\x44\xe9\x1d\xc1\x14\xfd\xa9\xb1\xdc\x71" ++ "\x9c\x46\x21\xbd\x58\x88\x6e\x22\x15\x56\xc1\xef\xe0\xc9\x8d\xe5" ++ "\x80\x3e\xda\x7e\x93\x0f\x52\xf6\xf5\xc1\x91\x90\x9e\x42\x49\x4f" ++ "\x8d\x9c\xba\x38\x83\xe9\x33\xc2\x50\x4f\xec\xc2\xf0\xa8\xb7\x6e" ++ "\x28\x25\x56\x6b\x62\x67\xfe\x08\xf1\x56\xe5\x6f\x0e\x99\xf1\xe5" ++ "\x95\x7b\xef\xeb\x0a\x2c\x92\x97\x57\x23\x33\x36\x07\xdd\xfb\xae" ++ "\xf1\xb1\xd8\x33\xb7\x96\x71\x42\x36\xc5\xa4\xa9\x19\x4b\x1b\x52" ++ "\x4c\x50\x69\x91\xf0\x0e\xfa\x80\x37\x4b\xb5\xd0\x2f\xb7\x44\x0d" ++ "\xd4\xf8\x39\x8d\xab\x71\x67\x59\x05\x88\x3d\xeb\x48\x48\x33\x88" ++ "\x4e\xfe\xf8\x27\x1b\xd6\x55\x60\x5e\x48\xb7\x6d\x9a\xa8\x37\xf9" ++ "\x7a\xde\x1b\xcd\x5d\x1a\x30\xd4\xe9\x9e\x5b\x3c\x15\xf8\x9c\x1f" ++ "\xda\xd1\x86\x48\x55\xce\x83\xee\x8e\x51\xc7\xde\x32\x12\x47\x7d" ++ "\x46\xb8\x35\xdf\x41\x02\x81\x81\x00\xe4\x4c\xae\xde\x16\xfd\x9f" ++ "\x83\x55\x5b\x84\x4a\xcf\x1c\xf1\x37\x95\xad\xca\x29\x7f\x2d\x6e" ++ "\x32\x81\xa4\x2b\x26\x14\x96\x1d\x40\x05\xec\x0c\xaf\x3f\x2c\x6f" ++ "\x2c\xe8\xbf\x1d\xee\xd0\xb3\xef\x7c\x5b\x9e\x88\x4f\x2a\x8b\x0e" ++ "\x4a\xbd\xb7\x8c\xfa\x10\x0e\x3b\xda\x68\xad\x41\x2b\xe4\x96\xfa" ++ "\x7f\x80\x52\x5f\x07\x9f\x0e\x3b\x5e\x96\x45\x1a\x13\x2b\x94\xce" ++ "\x1f\x07\x69\x85\x35\xfc\x69\x63\x5b\xf8\xf8\x3f\xce\x9d\x40\x1e" ++ "\x7c\xad\xfb\x9e\xce\xe0\x01\xf8\xef\x59\x5d\xdc\x00\x79\xab\x8a" ++ "\x3f\x80\xa2\x76\x32\x94\xa9\xea\x65\x02\x81\x81\x00\xf1\x38\x60" ++ "\x90\x0d\x0c\x2e\x3d\x34\xe5\x90\xea\x21\x43\x1f\x68\x63\x16\x7b" ++ "\x25\x8d\xde\x82\x2b\x52\xf8\xa3\xfd\x0f\x39\xe7\xe9\x5e\x32\x75" ++ "\x15\x7d\xd0\xc9\xce\x06\xe5\xfb\xa9\xcb\x22\xe5\xdb\x49\x09\xf2" ++ "\xe6\xb7\xa5\xa7\x75\x2e\x91\x2d\x2b\x5d\xf1\x48\x61\x45\x43\xd7" ++ "\xbd\xfc\x11\x73\xb5\x11\x9f\xb2\x18\x3a\x6f\x36\xa7\xc2\xd3\x18" ++ "\x4d\xf0\xc5\x1f\x70\x8c\x9b\xc5\x1d\x95\xa8\x5a\x9e\x8c\xb1\x4b" ++ "\x6a\x2a\x84\x76\x2c\xd8\x4f\x47\xb0\x81\x84\x02\x45\xf0\x85\xf8" ++ "\x0c\x6d\xa7\x0c\x4d\x2c\xb2\x5b\x81\x70\xfd\x6e\x17\x02\x81\x81" ++ "\x00\x8d\x07\xc5\xfa\x92\x4f\x48\xcb\xd3\xdd\xfe\x02\x4c\xa1\x7f" ++ "\x6d\xab\xfc\x38\xe7\x9b\x95\xcf\xfe\x49\x51\xc6\x09\xf7\x2b\xa8" ++ "\x94\x15\x54\x75\x9d\x88\xb4\x05\x55\xc3\xcd\xd4\x4a\xe4\x08\x53" ++ "\xc8\x09\xbd\x0c\x4d\x83\x65\x75\x85\xbc\x5e\xf8\x2a\xbd\xe2\x5d" ++ "\x1d\x16\x0e\xf9\x34\x89\x38\xaf\x34\x36\x6c\x2c\x22\x44\x22\x81" ++ "\x90\x73\xd9\xea\x3a\xaf\x70\x74\x48\x7c\xc6\xb5\xb0\xdc\xe5\xa9" ++ "\xa8\x76\x4b\xbc\xf7\x00\xf3\x4c\x22\x0f\x44\x62\x1d\x40\x0a\x57" ++ "\xe2\x5b\xdd\x7c\x7b\x9a\xad\xda\x70\x52\x21\x8a\x4c\xc2\xc3\x98" ++ "\x75\x02\x81\x81\x00\xed\x24\x5c\xa2\x21\x81\xa1\x0f\xa1\x2a\x33" ++ "\x0e\x49\xc7\x00\x60\x92\x51\x6e\x9d\x9b\xdc\x6d\x22\x04\x7e\xd6" ++ "\x51\x19\x9f\xf6\xe3\x91\x2c\x8f\xb8\xa2\x29\x19\xcc\x47\x31\xdf" ++ "\xf8\xab\xf0\xd2\x02\x83\xca\x99\x16\xc2\xe2\xc3\x3f\x4b\x99\x83" ++ "\xcb\x87\x9e\x86\x66\xc2\x3e\x91\x21\x80\x66\xf3\xd6\xc5\xcd\xb6" ++ "\xbb\x64\xef\x22\xcf\x48\x94\x58\xe7\x7e\xd5\x7c\x34\x1c\xb7\xa2" ++ "\xd0\x93\xe9\x9f\xb5\x11\x61\xd7\x5f\x37\x0f\x64\x52\x70\x11\x78" ++ "\xcc\x08\x77\xeb\xf8\x30\x1e\xb4\x9e\x1b\x4a\xc7\xa8\x33\x51\xe0" ++ "\xed\xdf\x53\xf6\xdf\x02\x81\x81\x00\x86\xd9\x4c\xee\x65\x61\xc1" ++ "\x19\xa9\xd5\x74\x9b\xd5\xca\xf6\x83\x2b\x06\xb4\x20\xfe\x45\x29" ++ "\xe8\xe3\xfa\xe1\x4f\x28\x8e\x63\x2f\x74\xc3\x3a\x5c\x9a\xf5\x9e" ++ "\x0e\x0d\xc5\xfe\xa0\x4c\x00\xce\x7b\xa4\x19\x17\x59\xaf\x13\x3a" ++ "\x03\x8f\x54\xf5\x60\x39\x2e\xd9\x06\xb3\x7c\xd6\x90\x06\x41\x77" ++ "\xf3\x93\xe1\x7a\x01\x41\xc1\x8f\xfe\x4c\x88\x39\xdb\xde\x71\x9e" ++ "\x58\xd1\x49\x50\x80\xb2\x5a\x4f\x69\x8b\xb8\xfe\x63\xd4\x42\x3d" ++ "\x37\x61\xa8\x4c\xff\xb6\x99\x4c\xf4\x51\xe0\x44\xaa\x69\x79\x3f" ++ "\x81\xa4\x61\x3d\x26\xe9\x04\x52\x64", ++ .key_len = 1193, + /* + * m is SHA256 hash of following message: + * "\x49\x41\xbe\x0a\x0c\xc9\xf6\x35\x51\xe4\x27\x56\x13\x71\x4b\xd0" +diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c +index 160606af8b4f55..a6c8514110736b 100644 +--- a/drivers/acpi/apei/ghes.c ++++ b/drivers/acpi/apei/ghes.c +@@ -155,8 +155,6 @@ static unsigned long ghes_estatus_pool_size_request; + static struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE]; + static atomic_t ghes_estatus_cache_alloced; + +-static int ghes_panic_timeout __read_mostly = 30; +- + static void __iomem *ghes_map(u64 pfn, enum fixed_addresses fixmap_idx) + { + phys_addr_t paddr; +@@ -858,14 +856,16 @@ static void __ghes_panic(struct ghes *ghes, + struct acpi_hest_generic_status *estatus, + u64 buf_paddr, enum fixed_addresses fixmap_idx) + { ++ const char *msg = GHES_PFX "Fatal hardware error"; ++ + __ghes_print_estatus(KERN_EMERG, ghes->generic, estatus); + + ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx); + +- /* reboot to log the error! */ + if (!panic_timeout) +- panic_timeout = ghes_panic_timeout; +- panic("Fatal hardware error!"); ++ pr_emerg("%s but panic disabled\n", msg); ++ ++ panic(msg); + } + + static int ghes_proc(struct ghes *ghes) +diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c +index 5cd0ceb50bc8a4..936429e81d8c83 100644 +--- a/drivers/acpi/fan.c ++++ b/drivers/acpi/fan.c +@@ -423,19 +423,25 @@ static int acpi_fan_probe(struct platform_device *pdev) + result = sysfs_create_link(&pdev->dev.kobj, + &cdev->device.kobj, + "thermal_cooling"); +- if (result) ++ if (result) { + dev_err(&pdev->dev, "Failed to create sysfs link 'thermal_cooling'\n"); ++ goto err_unregister; ++ } + + result = sysfs_create_link(&cdev->device.kobj, + &pdev->dev.kobj, + "device"); + if (result) { + dev_err(&pdev->dev, "Failed to create sysfs link 'device'\n"); +- goto err_end; ++ goto err_remove_link; + } + + return 0; + ++err_remove_link: ++ sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling"); ++err_unregister: ++ thermal_cooling_device_unregister(cdev); + err_end: + if (fan->acpi4) { + int i; +diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c +index bce0902dccb40e..6d4a9558471406 100644 +--- a/drivers/base/arch_numa.c ++++ b/drivers/base/arch_numa.c +@@ -165,7 +165,7 @@ static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, + + static void __init pcpu_fc_free(void *ptr, size_t size) + { +- memblock_free_early(__pa(ptr), size); ++ memblock_free(__pa(ptr), size); + } + + void __init setup_per_cpu_areas(void) +diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c +index e3769e70844be1..9a40a644bd661d 100644 +--- a/drivers/base/regmap/regmap-irq.c ++++ b/drivers/base/regmap/regmap-irq.c +@@ -904,6 +904,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, + kfree(d->wake_buf); + kfree(d->mask_buf_def); + kfree(d->mask_buf); ++ kfree(d->main_status_buf); + kfree(d->status_buf); + kfree(d->status_reg_buf); + if (d->virt_buf) { +@@ -979,6 +980,7 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d) + kfree(d->wake_buf); + kfree(d->mask_buf_def); + kfree(d->mask_buf); ++ kfree(d->main_status_buf); + kfree(d->status_reg_buf); + kfree(d->status_buf); + kfree(d); +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index d12e9f1721c8e8..1b04fd7c6b98a4 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -2055,6 +2055,7 @@ static void nbd_disconnect_and_put(struct nbd_device *nbd) + flush_workqueue(nbd->recv_workq); + nbd_clear_que(nbd); + nbd->task_setup = NULL; ++ clear_bit(NBD_RT_BOUND, &nbd->config->runtime_flags); + mutex_unlock(&nbd->config_lock); + + if (test_and_clear_bit(NBD_RT_HAS_CONFIG_REF, +diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c +index b780990faf8065..6eb3a5b715a26b 100644 +--- a/drivers/bus/mhi/host/pci_generic.c ++++ b/drivers/bus/mhi/host/pci_generic.c +@@ -732,8 +732,9 @@ static void mhi_pci_recovery_work(struct work_struct *work) + err_unprepare: + mhi_unprepare_after_power_down(mhi_cntrl); + err_try_reset: +- if (pci_reset_function(pdev)) +- dev_err(&pdev->dev, "Recovery failed\n"); ++ err = pci_try_reset_function(pdev); ++ if (err) ++ dev_err(&pdev->dev, "Recovery failed: %d\n", err); + } + + static void health_check(struct timer_list *t) +diff --git a/drivers/char/ipmi/ipmb_dev_int.c b/drivers/char/ipmi/ipmb_dev_int.c +index 49b8f22fdcf03b..964bde656f0d3d 100644 +--- a/drivers/char/ipmi/ipmb_dev_int.c ++++ b/drivers/char/ipmi/ipmb_dev_int.c +@@ -322,6 +322,9 @@ static int ipmb_probe(struct i2c_client *client, + ipmb_dev->miscdev.name = devm_kasprintf(&client->dev, GFP_KERNEL, + "%s%d", "ipmb-", + client->adapter->nr); ++ if (!ipmb_dev->miscdev.name) ++ return -ENOMEM; ++ + ipmb_dev->miscdev.fops = &ipmb_fops; + ipmb_dev->miscdev.parent = &client->dev; + ret = misc_register(&ipmb_dev->miscdev); +diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c +index cd266021d01039..1a5644051d3103 100644 +--- a/drivers/char/tpm/eventlog/acpi.c ++++ b/drivers/char/tpm/eventlog/acpi.c +@@ -14,6 +14,7 @@ + * Access to the event log extended by the TCG BIOS of PC platform + */ + ++#include + #include + #include + #include +@@ -62,6 +63,11 @@ static bool tpm_is_tpm2_log(void *bios_event_log, u64 len) + return n == 0; + } + ++static void tpm_bios_log_free(void *data) ++{ ++ kvfree(data); ++} ++ + /* read binary bios log */ + int tpm_read_log_acpi(struct tpm_chip *chip) + { +@@ -135,7 +141,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip) + } + + /* malloc EventLog space */ +- log->bios_event_log = kmalloc(len, GFP_KERNEL); ++ log->bios_event_log = kvmalloc(len, GFP_KERNEL); + if (!log->bios_event_log) + return -ENOMEM; + +@@ -161,10 +167,16 @@ int tpm_read_log_acpi(struct tpm_chip *chip) + goto err; + } + ++ ret = devm_add_action(&chip->dev, tpm_bios_log_free, log->bios_event_log); ++ if (ret) { ++ log->bios_event_log = NULL; ++ goto err; ++ } ++ + return format; + + err: +- kfree(log->bios_event_log); ++ tpm_bios_log_free(log->bios_event_log); + log->bios_event_log = NULL; + return ret; + } +diff --git a/drivers/char/tpm/eventlog/efi.c b/drivers/char/tpm/eventlog/efi.c +index e6cb9d525e30ca..4e9d7c2bf32ee4 100644 +--- a/drivers/char/tpm/eventlog/efi.c ++++ b/drivers/char/tpm/eventlog/efi.c +@@ -6,6 +6,7 @@ + * Thiebaud Weksteen + */ + ++#include + #include + #include + +@@ -55,7 +56,7 @@ int tpm_read_log_efi(struct tpm_chip *chip) + } + + /* malloc EventLog space */ +- log->bios_event_log = kmemdup(log_tbl->log, log_size, GFP_KERNEL); ++ log->bios_event_log = devm_kmemdup(&chip->dev, log_tbl->log, log_size, GFP_KERNEL); + if (!log->bios_event_log) { + ret = -ENOMEM; + goto out; +@@ -76,7 +77,7 @@ int tpm_read_log_efi(struct tpm_chip *chip) + MEMREMAP_WB); + if (!final_tbl) { + pr_err("Could not map UEFI TPM final log\n"); +- kfree(log->bios_event_log); ++ devm_kfree(&chip->dev, log->bios_event_log); + ret = -ENOMEM; + goto out; + } +@@ -91,11 +92,11 @@ int tpm_read_log_efi(struct tpm_chip *chip) + * Allocate memory for the 'combined log' where we will append the + * 'final events log' to. + */ +- tmp = krealloc(log->bios_event_log, +- log_size + final_events_log_size, +- GFP_KERNEL); ++ tmp = devm_krealloc(&chip->dev, log->bios_event_log, ++ log_size + final_events_log_size, ++ GFP_KERNEL); + if (!tmp) { +- kfree(log->bios_event_log); ++ devm_kfree(&chip->dev, log->bios_event_log); + ret = -ENOMEM; + goto out; + } +diff --git a/drivers/char/tpm/eventlog/of.c b/drivers/char/tpm/eventlog/of.c +index a9ce66d09a754d..741ab2204b11aa 100644 +--- a/drivers/char/tpm/eventlog/of.c ++++ b/drivers/char/tpm/eventlog/of.c +@@ -10,6 +10,7 @@ + * Read the event log created by the firmware on PPC64 + */ + ++#include + #include + #include + #include +@@ -65,7 +66,7 @@ int tpm_read_log_of(struct tpm_chip *chip) + return -EIO; + } + +- log->bios_event_log = kmemdup(__va(base), size, GFP_KERNEL); ++ log->bios_event_log = devm_kmemdup(&chip->dev, __va(base), size, GFP_KERNEL); + if (!log->bios_event_log) + return -ENOMEM; + +diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c +index 65d800ecc99643..a3459238ecb36d 100644 +--- a/drivers/char/tpm/tpm-chip.c ++++ b/drivers/char/tpm/tpm-chip.c +@@ -267,7 +267,6 @@ static void tpm_dev_release(struct device *dev) + idr_remove(&dev_nums_idr, chip->dev_num); + mutex_unlock(&idr_lock); + +- kfree(chip->log.bios_event_log); + kfree(chip->work_space.context_buf); + kfree(chip->work_space.session_buf); + kfree(chip->allocated_banks); +diff --git a/drivers/clk/analogbits/wrpll-cln28hpc.c b/drivers/clk/analogbits/wrpll-cln28hpc.c +index 09ca8235639930..d8ae3929599697 100644 +--- a/drivers/clk/analogbits/wrpll-cln28hpc.c ++++ b/drivers/clk/analogbits/wrpll-cln28hpc.c +@@ -291,7 +291,7 @@ int wrpll_configure_for_rate(struct wrpll_cfg *c, u32 target_rate, + vco = vco_pre * f; + } + +- delta = abs(target_rate - vco); ++ delta = abs(target_vco_rate - vco); + if (delta < best_delta) { + best_delta = delta; + best_r = r; +diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c +index 8e980271b9dc66..0f9ec5e0f5f818 100644 +--- a/drivers/clk/imx/clk-imx8mp.c ++++ b/drivers/clk/imx/clk-imx8mp.c +@@ -398,8 +398,9 @@ static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_r + + static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out", + "dummy", "dummy", "gpu_pll_out", "vpu_pll_out", +- "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3", +- "dummy", "dummy", "osc_24m", "dummy", "osc_32k"}; ++ "arm_pll_out", "sys_pll1_out", "sys_pll2_out", ++ "sys_pll3_out", "dummy", "dummy", "osc_24m", ++ "dummy", "osc_32k"}; + + static struct clk_hw **hws; + static struct clk_hw_onecell_data *clk_hw_data; +diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c +index 6426d933153d17..5d061b1b0eaec9 100644 +--- a/drivers/clk/qcom/clk-alpha-pll.c ++++ b/drivers/clk/qcom/clk-alpha-pll.c +@@ -284,6 +284,8 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + mask |= config->pre_div_mask; + mask |= config->post_div_mask; + mask |= config->vco_mask; ++ mask |= config->alpha_en_mask; ++ mask |= config->alpha_mode_mask; + + regmap_update_bits(regmap, PLL_USER_CTL(pll), mask, val); + +diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c +index 7b19ef531ce495..34619cbe9b6e1c 100644 +--- a/drivers/clk/qcom/clk-rpmh.c ++++ b/drivers/clk/qcom/clk-rpmh.c +@@ -331,7 +331,7 @@ static unsigned long clk_rpmh_bcm_recalc_rate(struct clk_hw *hw, + { + struct clk_rpmh *c = to_clk_rpmh(hw); + +- return c->aggr_state * c->unit; ++ return (unsigned long)c->aggr_state * c->unit; + } + + static const struct clk_ops clk_rpmh_bcm_ops = { +diff --git a/drivers/clk/qcom/gcc-mdm9607.c b/drivers/clk/qcom/gcc-mdm9607.c +index 4c9078e99bb37c..19c701b23ac71d 100644 +--- a/drivers/clk/qcom/gcc-mdm9607.c ++++ b/drivers/clk/qcom/gcc-mdm9607.c +@@ -536,7 +536,7 @@ static struct clk_rcg2 blsp1_uart5_apps_clk_src = { + }; + + static struct clk_rcg2 blsp1_uart6_apps_clk_src = { +- .cmd_rcgr = 0x6044, ++ .cmd_rcgr = 0x7044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, +diff --git a/drivers/clk/qcom/gcc-sm6350.c b/drivers/clk/qcom/gcc-sm6350.c +index 84ae27184cfd07..0860c6178b4d3f 100644 +--- a/drivers/clk/qcom/gcc-sm6350.c ++++ b/drivers/clk/qcom/gcc-sm6350.c +@@ -181,6 +181,14 @@ static const struct clk_parent_data gcc_parent_data_2_ao[] = { + { .hw = &gpll0_out_odd.clkr.hw }, + }; + ++static const struct parent_map gcc_parent_map_3[] = { ++ { P_BI_TCXO, 0 }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_3[] = { ++ { .fw_name = "bi_tcxo" }, ++}; ++ + static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, +@@ -700,13 +708,12 @@ static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { + .cmd_rcgr = 0x3a0b0, + .mnd_width = 0, + .hid_width = 5, ++ .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_phy_aux_clk_src", +- .parent_data = &(const struct clk_parent_data){ +- .fw_name = "bi_tcxo", +- }, +- .num_parents = 1, ++ .parent_data = gcc_parent_data_3, ++ .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, + }; +@@ -763,13 +770,12 @@ static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0x1a034, + .mnd_width = 0, + .hid_width = 5, ++ .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_mock_utmi_clk_src", +- .parent_data = &(const struct clk_parent_data){ +- .fw_name = "bi_tcxo", +- }, +- .num_parents = 1, ++ .parent_data = gcc_parent_data_3, ++ .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, + }; +diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c +index 913bb08e6dee8b..7ccf8033b860de 100644 +--- a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c ++++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c +@@ -437,7 +437,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830, + 24, 2, /* mux */ + BIT(31), /* gate */ + 2, /* post-div */ +- CLK_SET_RATE_NO_REPARENT); ++ 0); + + static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834, + 0, 4, /* M */ +@@ -445,7 +445,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834, + 24, 2, /* mux */ + BIT(31), /* gate */ + 2, /* post-div */ +- CLK_SET_RATE_NO_REPARENT); ++ 0); + + static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838, + 0, 4, /* M */ +@@ -453,7 +453,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838, + 24, 2, /* mux */ + BIT(31), /* gate */ + 2, /* post-div */ +- CLK_SET_RATE_NO_REPARENT); ++ 0); + + static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0); + static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0); +diff --git a/drivers/clocksource/i8253.c b/drivers/clocksource/i8253.c +index d4350bb10b83a2..cb215e6f2e8344 100644 +--- a/drivers/clocksource/i8253.c ++++ b/drivers/clocksource/i8253.c +@@ -108,11 +108,8 @@ int __init clocksource_i8253_init(void) + #endif + + #ifdef CONFIG_CLKEVT_I8253 +-static int pit_shutdown(struct clock_event_device *evt) ++void clockevent_i8253_disable(void) + { +- if (!clockevent_state_oneshot(evt) && !clockevent_state_periodic(evt)) +- return 0; +- + raw_spin_lock(&i8253_lock); + + outb_p(0x30, PIT_MODE); +@@ -123,6 +120,14 @@ static int pit_shutdown(struct clock_event_device *evt) + } + + raw_spin_unlock(&i8253_lock); ++} ++ ++static int pit_shutdown(struct clock_event_device *evt) ++{ ++ if (!clockevent_state_oneshot(evt) && !clockevent_state_periodic(evt)) ++ return 0; ++ ++ clockevent_i8253_disable(); + return 0; + } + +diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c +index 28467d83c7452d..4a31bd90406c99 100644 +--- a/drivers/cpufreq/acpi-cpufreq.c ++++ b/drivers/cpufreq/acpi-cpufreq.c +@@ -630,7 +630,14 @@ static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c) + #endif + + #ifdef CONFIG_ACPI_CPPC_LIB +-static u64 get_max_boost_ratio(unsigned int cpu) ++/* ++ * get_max_boost_ratio: Computes the max_boost_ratio as the ratio ++ * between the highest_perf and the nominal_perf. ++ * ++ * Returns the max_boost_ratio for @cpu. Returns the CPPC nominal ++ * frequency via @nominal_freq if it is non-NULL pointer. ++ */ ++static u64 get_max_boost_ratio(unsigned int cpu, u64 *nominal_freq) + { + struct cppc_perf_caps perf_caps; + u64 highest_perf, nominal_perf; +@@ -653,6 +660,9 @@ static u64 get_max_boost_ratio(unsigned int cpu) + + nominal_perf = perf_caps.nominal_perf; + ++ if (nominal_freq) ++ *nominal_freq = perf_caps.nominal_freq; ++ + if (!highest_perf || !nominal_perf) { + pr_debug("CPU%d: highest or nominal performance missing\n", cpu); + return 0; +@@ -665,8 +675,12 @@ static u64 get_max_boost_ratio(unsigned int cpu) + + return div_u64(highest_perf << SCHED_CAPACITY_SHIFT, nominal_perf); + } ++ + #else +-static inline u64 get_max_boost_ratio(unsigned int cpu) { return 0; } ++static inline u64 get_max_boost_ratio(unsigned int cpu, u64 *nominal_freq) ++{ ++ return 0; ++} + #endif + + static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) +@@ -676,9 +690,9 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) + struct acpi_cpufreq_data *data; + unsigned int cpu = policy->cpu; + struct cpuinfo_x86 *c = &cpu_data(cpu); ++ u64 max_boost_ratio, nominal_freq = 0; + unsigned int valid_states = 0; + unsigned int result = 0; +- u64 max_boost_ratio; + unsigned int i; + #ifdef CONFIG_SMP + static int blacklisted; +@@ -828,16 +842,20 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) + } + freq_table[valid_states].frequency = CPUFREQ_TABLE_END; + +- max_boost_ratio = get_max_boost_ratio(cpu); ++ max_boost_ratio = get_max_boost_ratio(cpu, &nominal_freq); + if (max_boost_ratio) { +- unsigned int freq = freq_table[0].frequency; ++ unsigned int freq = nominal_freq; + + /* +- * Because the loop above sorts the freq_table entries in the +- * descending order, freq is the maximum frequency in the table. +- * Assume that it corresponds to the CPPC nominal frequency and +- * use it to set cpuinfo.max_freq. ++ * The loop above sorts the freq_table entries in the ++ * descending order. If ACPI CPPC has not advertised ++ * the nominal frequency (this is possible in CPPC ++ * revisions prior to 3), then use the first entry in ++ * the pstate table as a proxy for nominal frequency. + */ ++ if (!freq) ++ freq = freq_table[0].frequency; ++ + policy->cpuinfo.max_freq = freq * max_boost_ratio >> SCHED_CAPACITY_SHIFT; + } else { + /* +diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c +index c6bdfc308e9908..9cef7152807626 100644 +--- a/drivers/cpufreq/s3c64xx-cpufreq.c ++++ b/drivers/cpufreq/s3c64xx-cpufreq.c +@@ -24,6 +24,7 @@ struct s3c64xx_dvfs { + unsigned int vddarm_max; + }; + ++#ifdef CONFIG_REGULATOR + static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = { + [0] = { 1000000, 1150000 }, + [1] = { 1050000, 1150000 }, +@@ -31,6 +32,7 @@ static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = { + [3] = { 1200000, 1350000 }, + [4] = { 1300000, 1350000 }, + }; ++#endif + + static struct cpufreq_frequency_table s3c64xx_freq_table[] = { + { 0, 0, 66000 }, +@@ -51,15 +53,16 @@ static struct cpufreq_frequency_table s3c64xx_freq_table[] = { + static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, + unsigned int index) + { +- struct s3c64xx_dvfs *dvfs; +- unsigned int old_freq, new_freq; ++ unsigned int new_freq = s3c64xx_freq_table[index].frequency; + int ret; + ++#ifdef CONFIG_REGULATOR ++ struct s3c64xx_dvfs *dvfs; ++ unsigned int old_freq; ++ + old_freq = clk_get_rate(policy->clk) / 1000; +- new_freq = s3c64xx_freq_table[index].frequency; + dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data]; + +-#ifdef CONFIG_REGULATOR + if (vddarm && new_freq > old_freq) { + ret = regulator_set_voltage(vddarm, + dvfs->vddarm_min, +diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h +index cff00fd2976520..d3515d1ea5c27e 100644 +--- a/drivers/crypto/hisilicon/sec2/sec.h ++++ b/drivers/crypto/hisilicon/sec2/sec.h +@@ -36,6 +36,7 @@ struct sec_aead_req { + u8 *a_ivin; + dma_addr_t a_ivin_dma; + struct aead_request *aead_req; ++ bool fallback; + }; + + /* SEC request of Crypto */ +@@ -89,9 +90,7 @@ struct sec_auth_ctx { + dma_addr_t a_key_dma; + u8 *a_key; + u8 a_key_len; +- u8 mac_len; + u8 a_alg; +- bool fallback; + struct crypto_shash *hash_tfm; + struct crypto_aead *fallback_aead_tfm; + }; +diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c +index 28c167e1be4263..32150e05a27955 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c ++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c +@@ -643,13 +643,15 @@ static int sec_skcipher_fbtfm_init(struct crypto_skcipher *tfm) + struct sec_cipher_ctx *c_ctx = &ctx->c_ctx; + + c_ctx->fallback = false; ++ ++ /* Currently, only XTS mode need fallback tfm when using 192bit key */ + if (likely(strncmp(alg, "xts", SEC_XTS_NAME_SZ))) + return 0; + + c_ctx->fbtfm = crypto_alloc_sync_skcipher(alg, 0, + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(c_ctx->fbtfm)) { +- pr_err("failed to alloc fallback tfm!\n"); ++ pr_err("failed to alloc xts mode fallback tfm!\n"); + return PTR_ERR(c_ctx->fbtfm); + } + +@@ -801,6 +803,7 @@ static int sec_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, + ret = sec_skcipher_aes_sm4_setkey(c_ctx, keylen, c_mode); + break; + default: ++ dev_err(dev, "sec c_alg err!\n"); + return -EINVAL; + } + +@@ -810,7 +813,7 @@ static int sec_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, + } + + memcpy(c_ctx->c_key, key, keylen); +- if (c_ctx->fallback) { ++ if (c_ctx->fallback && c_ctx->fbtfm) { + ret = crypto_sync_skcipher_setkey(c_ctx->fbtfm, key, keylen); + if (ret) { + dev_err(dev, "failed to set fallback skcipher key!\n"); +@@ -904,15 +907,14 @@ static int sec_aead_mac_init(struct sec_aead_req *req) + struct aead_request *aead_req = req->aead_req; + struct crypto_aead *tfm = crypto_aead_reqtfm(aead_req); + size_t authsize = crypto_aead_authsize(tfm); +- u8 *mac_out = req->out_mac; + struct scatterlist *sgl = aead_req->src; ++ u8 *mac_out = req->out_mac; + size_t copy_size; + off_t skip_size; + + /* Copy input mac */ + skip_size = aead_req->assoclen + aead_req->cryptlen - authsize; +- copy_size = sg_pcopy_to_buffer(sgl, sg_nents(sgl), mac_out, +- authsize, skip_size); ++ copy_size = sg_pcopy_to_buffer(sgl, sg_nents(sgl), mac_out, authsize, skip_size); + if (unlikely(copy_size != authsize)) + return -EINVAL; + +@@ -1075,10 +1077,7 @@ static int sec_aead_setauthsize(struct crypto_aead *aead, unsigned int authsize) + struct sec_ctx *ctx = crypto_tfm_ctx(tfm); + struct sec_auth_ctx *a_ctx = &ctx->a_ctx; + +- if (unlikely(a_ctx->fallback_aead_tfm)) +- return crypto_aead_setauthsize(a_ctx->fallback_aead_tfm, authsize); +- +- return 0; ++ return crypto_aead_setauthsize(a_ctx->fallback_aead_tfm, authsize); + } + + static int sec_aead_fallback_setkey(struct sec_auth_ctx *a_ctx, +@@ -1094,7 +1093,6 @@ static int sec_aead_fallback_setkey(struct sec_auth_ctx *a_ctx, + static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key, + const u32 keylen, const enum sec_hash_alg a_alg, + const enum sec_calg c_alg, +- const enum sec_mac_len mac_len, + const enum sec_cmode c_mode) + { + struct sec_ctx *ctx = crypto_aead_ctx(tfm); +@@ -1106,7 +1104,6 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key, + + ctx->a_ctx.a_alg = a_alg; + ctx->c_ctx.c_alg = c_alg; +- ctx->a_ctx.mac_len = mac_len; + c_ctx->c_mode = c_mode; + + if (c_mode == SEC_CMODE_CCM || c_mode == SEC_CMODE_GCM) { +@@ -1117,16 +1114,11 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key, + } + memcpy(c_ctx->c_key, key, keylen); + +- if (unlikely(a_ctx->fallback_aead_tfm)) { +- ret = sec_aead_fallback_setkey(a_ctx, tfm, key, keylen); +- if (ret) +- return ret; +- } +- +- return 0; ++ return sec_aead_fallback_setkey(a_ctx, tfm, key, keylen); + } + +- if (crypto_authenc_extractkeys(&keys, key, keylen)) ++ ret = crypto_authenc_extractkeys(&keys, key, keylen); ++ if (ret) + goto bad_key; + + ret = sec_aead_aes_set_key(c_ctx, &keys); +@@ -1141,9 +1133,15 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key, + goto bad_key; + } + +- if ((ctx->a_ctx.mac_len & SEC_SQE_LEN_RATE_MASK) || +- (ctx->a_ctx.a_key_len & SEC_SQE_LEN_RATE_MASK)) { +- dev_err(dev, "MAC or AUTH key length error!\n"); ++ if (ctx->a_ctx.a_key_len & SEC_SQE_LEN_RATE_MASK) { ++ ret = -EINVAL; ++ dev_err(dev, "AUTH key length error!\n"); ++ goto bad_key; ++ } ++ ++ ret = sec_aead_fallback_setkey(a_ctx, tfm, key, keylen); ++ if (ret) { ++ dev_err(dev, "set sec fallback key err!\n"); + goto bad_key; + } + +@@ -1151,31 +1149,23 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key, + + bad_key: + memzero_explicit(&keys, sizeof(struct crypto_authenc_keys)); +- return -EINVAL; ++ return ret; + } + + +-#define GEN_SEC_AEAD_SETKEY_FUNC(name, aalg, calg, maclen, cmode) \ +-static int sec_setkey_##name(struct crypto_aead *tfm, const u8 *key, \ +- u32 keylen) \ +-{ \ +- return sec_aead_setkey(tfm, key, keylen, aalg, calg, maclen, cmode);\ +-} +- +-GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha1, SEC_A_HMAC_SHA1, +- SEC_CALG_AES, SEC_HMAC_SHA1_MAC, SEC_CMODE_CBC) +-GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha256, SEC_A_HMAC_SHA256, +- SEC_CALG_AES, SEC_HMAC_SHA256_MAC, SEC_CMODE_CBC) +-GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha512, SEC_A_HMAC_SHA512, +- SEC_CALG_AES, SEC_HMAC_SHA512_MAC, SEC_CMODE_CBC) +-GEN_SEC_AEAD_SETKEY_FUNC(aes_ccm, 0, SEC_CALG_AES, +- SEC_HMAC_CCM_MAC, SEC_CMODE_CCM) +-GEN_SEC_AEAD_SETKEY_FUNC(aes_gcm, 0, SEC_CALG_AES, +- SEC_HMAC_GCM_MAC, SEC_CMODE_GCM) +-GEN_SEC_AEAD_SETKEY_FUNC(sm4_ccm, 0, SEC_CALG_SM4, +- SEC_HMAC_CCM_MAC, SEC_CMODE_CCM) +-GEN_SEC_AEAD_SETKEY_FUNC(sm4_gcm, 0, SEC_CALG_SM4, +- SEC_HMAC_GCM_MAC, SEC_CMODE_GCM) ++#define GEN_SEC_AEAD_SETKEY_FUNC(name, aalg, calg, cmode) \ ++static int sec_setkey_##name(struct crypto_aead *tfm, const u8 *key, u32 keylen) \ ++{ \ ++ return sec_aead_setkey(tfm, key, keylen, aalg, calg, cmode); \ ++} ++ ++GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha1, SEC_A_HMAC_SHA1, SEC_CALG_AES, SEC_CMODE_CBC) ++GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha256, SEC_A_HMAC_SHA256, SEC_CALG_AES, SEC_CMODE_CBC) ++GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha512, SEC_A_HMAC_SHA512, SEC_CALG_AES, SEC_CMODE_CBC) ++GEN_SEC_AEAD_SETKEY_FUNC(aes_ccm, 0, SEC_CALG_AES, SEC_CMODE_CCM) ++GEN_SEC_AEAD_SETKEY_FUNC(aes_gcm, 0, SEC_CALG_AES, SEC_CMODE_GCM) ++GEN_SEC_AEAD_SETKEY_FUNC(sm4_ccm, 0, SEC_CALG_SM4, SEC_CMODE_CCM) ++GEN_SEC_AEAD_SETKEY_FUNC(sm4_gcm, 0, SEC_CALG_SM4, SEC_CMODE_GCM) + + static int sec_aead_sgl_map(struct sec_ctx *ctx, struct sec_req *req) + { +@@ -1420,9 +1410,10 @@ static void sec_skcipher_callback(struct sec_ctx *ctx, struct sec_req *req, + static void set_aead_auth_iv(struct sec_ctx *ctx, struct sec_req *req) + { + struct aead_request *aead_req = req->aead_req.aead_req; +- struct sec_cipher_req *c_req = &req->c_req; ++ struct crypto_aead *tfm = crypto_aead_reqtfm(aead_req); ++ size_t authsize = crypto_aead_authsize(tfm); + struct sec_aead_req *a_req = &req->aead_req; +- size_t authsize = ctx->a_ctx.mac_len; ++ struct sec_cipher_req *c_req = &req->c_req; + u32 data_size = aead_req->cryptlen; + u8 flage = 0; + u8 cm, cl; +@@ -1463,10 +1454,8 @@ static void set_aead_auth_iv(struct sec_ctx *ctx, struct sec_req *req) + static void sec_aead_set_iv(struct sec_ctx *ctx, struct sec_req *req) + { + struct aead_request *aead_req = req->aead_req.aead_req; +- struct crypto_aead *tfm = crypto_aead_reqtfm(aead_req); +- size_t authsize = crypto_aead_authsize(tfm); +- struct sec_cipher_req *c_req = &req->c_req; + struct sec_aead_req *a_req = &req->aead_req; ++ struct sec_cipher_req *c_req = &req->c_req; + + memcpy(c_req->c_ivin, aead_req->iv, ctx->c_ctx.ivsize); + +@@ -1474,15 +1463,11 @@ static void sec_aead_set_iv(struct sec_ctx *ctx, struct sec_req *req) + /* + * CCM 16Byte Cipher_IV: {1B_Flage,13B_IV,2B_counter}, + * the counter must set to 0x01 ++ * CCM 16Byte Auth_IV: {1B_AFlage,13B_IV,2B_Ptext_length} + */ +- ctx->a_ctx.mac_len = authsize; +- /* CCM 16Byte Auth_IV: {1B_AFlage,13B_IV,2B_Ptext_length} */ + set_aead_auth_iv(ctx, req); +- } +- +- /* GCM 12Byte Cipher_IV == Auth_IV */ +- if (ctx->c_ctx.c_mode == SEC_CMODE_GCM) { +- ctx->a_ctx.mac_len = authsize; ++ } else if (ctx->c_ctx.c_mode == SEC_CMODE_GCM) { ++ /* GCM 12Byte Cipher_IV == Auth_IV */ + memcpy(a_req->a_ivin, c_req->c_ivin, SEC_AIV_SIZE); + } + } +@@ -1492,9 +1477,11 @@ static void sec_auth_bd_fill_xcm(struct sec_auth_ctx *ctx, int dir, + { + struct sec_aead_req *a_req = &req->aead_req; + struct aead_request *aq = a_req->aead_req; ++ struct crypto_aead *tfm = crypto_aead_reqtfm(aq); ++ size_t authsize = crypto_aead_authsize(tfm); + + /* C_ICV_Len is MAC size, 0x4 ~ 0x10 */ +- sec_sqe->type2.icvw_kmode |= cpu_to_le16((u16)ctx->mac_len); ++ sec_sqe->type2.icvw_kmode |= cpu_to_le16((u16)authsize); + + /* mode set to CCM/GCM, don't set {A_Alg, AKey_Len, MAC_Len} */ + sec_sqe->type2.a_key_addr = sec_sqe->type2.c_key_addr; +@@ -1518,9 +1505,11 @@ static void sec_auth_bd_fill_xcm_v3(struct sec_auth_ctx *ctx, int dir, + { + struct sec_aead_req *a_req = &req->aead_req; + struct aead_request *aq = a_req->aead_req; ++ struct crypto_aead *tfm = crypto_aead_reqtfm(aq); ++ size_t authsize = crypto_aead_authsize(tfm); + + /* C_ICV_Len is MAC size, 0x4 ~ 0x10 */ +- sqe3->c_icv_key |= cpu_to_le16((u16)ctx->mac_len << SEC_MAC_OFFSET_V3); ++ sqe3->c_icv_key |= cpu_to_le16((u16)authsize << SEC_MAC_OFFSET_V3); + + /* mode set to CCM/GCM, don't set {A_Alg, AKey_Len, MAC_Len} */ + sqe3->a_key_addr = sqe3->c_key_addr; +@@ -1544,11 +1533,12 @@ static void sec_auth_bd_fill_ex(struct sec_auth_ctx *ctx, int dir, + struct sec_aead_req *a_req = &req->aead_req; + struct sec_cipher_req *c_req = &req->c_req; + struct aead_request *aq = a_req->aead_req; ++ struct crypto_aead *tfm = crypto_aead_reqtfm(aq); ++ size_t authsize = crypto_aead_authsize(tfm); + + sec_sqe->type2.a_key_addr = cpu_to_le64(ctx->a_key_dma); + +- sec_sqe->type2.mac_key_alg = +- cpu_to_le32(ctx->mac_len / SEC_SQE_LEN_RATE); ++ sec_sqe->type2.mac_key_alg = cpu_to_le32(authsize / SEC_SQE_LEN_RATE); + + sec_sqe->type2.mac_key_alg |= + cpu_to_le32((u32)((ctx->a_key_len) / +@@ -1598,11 +1588,13 @@ static void sec_auth_bd_fill_ex_v3(struct sec_auth_ctx *ctx, int dir, + struct sec_aead_req *a_req = &req->aead_req; + struct sec_cipher_req *c_req = &req->c_req; + struct aead_request *aq = a_req->aead_req; ++ struct crypto_aead *tfm = crypto_aead_reqtfm(aq); ++ size_t authsize = crypto_aead_authsize(tfm); + + sqe3->a_key_addr = cpu_to_le64(ctx->a_key_dma); + + sqe3->auth_mac_key |= +- cpu_to_le32((u32)(ctx->mac_len / ++ cpu_to_le32((u32)(authsize / + SEC_SQE_LEN_RATE) << SEC_MAC_OFFSET_V3); + + sqe3->auth_mac_key |= +@@ -1653,9 +1645,9 @@ static void sec_aead_callback(struct sec_ctx *c, struct sec_req *req, int err) + { + struct aead_request *a_req = req->aead_req.aead_req; + struct crypto_aead *tfm = crypto_aead_reqtfm(a_req); ++ size_t authsize = crypto_aead_authsize(tfm); + struct sec_aead_req *aead_req = &req->aead_req; + struct sec_cipher_req *c_req = &req->c_req; +- size_t authsize = crypto_aead_authsize(tfm); + struct sec_qp_ctx *qp_ctx = req->qp_ctx; + struct aead_request *backlog_aead_req; + struct sec_req *backlog_req; +@@ -1668,11 +1660,8 @@ static void sec_aead_callback(struct sec_ctx *c, struct sec_req *req, int err) + if (!err && c_req->encrypt) { + struct scatterlist *sgl = a_req->dst; + +- sz = sg_pcopy_from_buffer(sgl, sg_nents(sgl), +- aead_req->out_mac, +- authsize, a_req->cryptlen + +- a_req->assoclen); +- ++ sz = sg_pcopy_from_buffer(sgl, sg_nents(sgl), aead_req->out_mac, ++ authsize, a_req->cryptlen + a_req->assoclen); + if (unlikely(sz != authsize)) { + dev_err(c->dev, "copy out mac err!\n"); + err = -EINVAL; +@@ -1881,8 +1870,10 @@ static void sec_aead_exit(struct crypto_aead *tfm) + + static int sec_aead_ctx_init(struct crypto_aead *tfm, const char *hash_name) + { ++ struct aead_alg *alg = crypto_aead_alg(tfm); + struct sec_ctx *ctx = crypto_aead_ctx(tfm); +- struct sec_auth_ctx *auth_ctx = &ctx->a_ctx; ++ struct sec_auth_ctx *a_ctx = &ctx->a_ctx; ++ const char *aead_name = alg->base.cra_name; + int ret; + + ret = sec_aead_init(tfm); +@@ -1891,11 +1882,20 @@ static int sec_aead_ctx_init(struct crypto_aead *tfm, const char *hash_name) + return ret; + } + +- auth_ctx->hash_tfm = crypto_alloc_shash(hash_name, 0, 0); +- if (IS_ERR(auth_ctx->hash_tfm)) { ++ a_ctx->hash_tfm = crypto_alloc_shash(hash_name, 0, 0); ++ if (IS_ERR(a_ctx->hash_tfm)) { + dev_err(ctx->dev, "aead alloc shash error!\n"); + sec_aead_exit(tfm); +- return PTR_ERR(auth_ctx->hash_tfm); ++ return PTR_ERR(a_ctx->hash_tfm); ++ } ++ ++ a_ctx->fallback_aead_tfm = crypto_alloc_aead(aead_name, 0, ++ CRYPTO_ALG_NEED_FALLBACK | CRYPTO_ALG_ASYNC); ++ if (IS_ERR(a_ctx->fallback_aead_tfm)) { ++ dev_err(ctx->dev, "aead driver alloc fallback tfm error!\n"); ++ crypto_free_shash(ctx->a_ctx.hash_tfm); ++ sec_aead_exit(tfm); ++ return PTR_ERR(a_ctx->fallback_aead_tfm); + } + + return 0; +@@ -1905,6 +1905,7 @@ static void sec_aead_ctx_exit(struct crypto_aead *tfm) + { + struct sec_ctx *ctx = crypto_aead_ctx(tfm); + ++ crypto_free_aead(ctx->a_ctx.fallback_aead_tfm); + crypto_free_shash(ctx->a_ctx.hash_tfm); + sec_aead_exit(tfm); + } +@@ -1931,7 +1932,6 @@ static int sec_aead_xcm_ctx_init(struct crypto_aead *tfm) + sec_aead_exit(tfm); + return PTR_ERR(a_ctx->fallback_aead_tfm); + } +- a_ctx->fallback = false; + + return 0; + } +@@ -1959,7 +1959,6 @@ static int sec_aead_sha512_ctx_init(struct crypto_aead *tfm) + return sec_aead_ctx_init(tfm, "sha512"); + } + +- + static int sec_skcipher_cryptlen_ckeck(struct sec_ctx *ctx, + struct sec_req *sreq) + { +@@ -2034,13 +2033,12 @@ static int sec_skcipher_soft_crypto(struct sec_ctx *ctx, + struct skcipher_request *sreq, bool encrypt) + { + struct sec_cipher_ctx *c_ctx = &ctx->c_ctx; ++ SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, c_ctx->fbtfm); + struct device *dev = ctx->dev; + int ret; + +- SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, c_ctx->fbtfm); +- + if (!c_ctx->fbtfm) { +- dev_err(dev, "failed to check fallback tfm\n"); ++ dev_err_ratelimited(dev, "the soft tfm isn't supported in the current system.\n"); + return -EINVAL; + } + +@@ -2202,21 +2200,20 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq) + { + struct aead_request *req = sreq->aead_req.aead_req; + struct crypto_aead *tfm = crypto_aead_reqtfm(req); +- size_t authsize = crypto_aead_authsize(tfm); ++ size_t sz = crypto_aead_authsize(tfm); + u8 c_mode = ctx->c_ctx.c_mode; + struct device *dev = ctx->dev; + int ret; + +- if (unlikely(req->cryptlen + req->assoclen > MAX_INPUT_DATA_LEN || +- req->assoclen > SEC_MAX_AAD_LEN)) { +- dev_err(dev, "aead input spec error!\n"); ++ /* Hardware does not handle cases where authsize is less than 4 bytes */ ++ if (unlikely(sz < MIN_MAC_LEN)) { ++ sreq->aead_req.fallback = true; + return -EINVAL; + } + +- if (unlikely((c_mode == SEC_CMODE_GCM && authsize < DES_BLOCK_SIZE) || +- (c_mode == SEC_CMODE_CCM && (authsize < MIN_MAC_LEN || +- authsize & MAC_LEN_MASK)))) { +- dev_err(dev, "aead input mac length error!\n"); ++ if (unlikely(req->cryptlen + req->assoclen > MAX_INPUT_DATA_LEN || ++ req->assoclen > SEC_MAX_AAD_LEN)) { ++ dev_err(dev, "aead input spec error!\n"); + return -EINVAL; + } + +@@ -2231,7 +2228,7 @@ static int sec_aead_spec_check(struct sec_ctx *ctx, struct sec_req *sreq) + if (sreq->c_req.encrypt) + sreq->c_req.c_len = req->cryptlen; + else +- sreq->c_req.c_len = req->cryptlen - authsize; ++ sreq->c_req.c_len = req->cryptlen - sz; + if (c_mode == SEC_CMODE_CBC) { + if (unlikely(sreq->c_req.c_len & (AES_BLOCK_SIZE - 1))) { + dev_err(dev, "aead crypto length error!\n"); +@@ -2257,9 +2254,8 @@ static int sec_aead_param_check(struct sec_ctx *ctx, struct sec_req *sreq) + + if (ctx->sec->qm.ver == QM_HW_V2) { + if (unlikely(!req->cryptlen || (!sreq->c_req.encrypt && +- req->cryptlen <= authsize))) { +- dev_err(dev, "Kunpeng920 not support 0 length!\n"); +- ctx->a_ctx.fallback = true; ++ req->cryptlen <= authsize))) { ++ sreq->aead_req.fallback = true; + return -EINVAL; + } + } +@@ -2287,16 +2283,9 @@ static int sec_aead_soft_crypto(struct sec_ctx *ctx, + bool encrypt) + { + struct sec_auth_ctx *a_ctx = &ctx->a_ctx; +- struct device *dev = ctx->dev; + struct aead_request *subreq; + int ret; + +- /* Kunpeng920 aead mode not support input 0 size */ +- if (!a_ctx->fallback_aead_tfm) { +- dev_err(dev, "aead fallback tfm is NULL!\n"); +- return -EINVAL; +- } +- + subreq = aead_request_alloc(a_ctx->fallback_aead_tfm, GFP_KERNEL); + if (!subreq) + return -ENOMEM; +@@ -2328,10 +2317,11 @@ static int sec_aead_crypto(struct aead_request *a_req, bool encrypt) + req->aead_req.aead_req = a_req; + req->c_req.encrypt = encrypt; + req->ctx = ctx; ++ req->aead_req.fallback = false; + + ret = sec_aead_param_check(ctx, req); + if (unlikely(ret)) { +- if (ctx->a_ctx.fallback) ++ if (req->aead_req.fallback) + return sec_aead_soft_crypto(ctx, a_req, encrypt); + return -EINVAL; + } +diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.h b/drivers/crypto/hisilicon/sec2/sec_crypto.h +index ee2edaf5058dfa..4d7f917fbaf1c4 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_crypto.h ++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.h +@@ -23,17 +23,6 @@ enum sec_hash_alg { + SEC_A_HMAC_SHA512 = 0x15, + }; + +-enum sec_mac_len { +- SEC_HMAC_CCM_MAC = 16, +- SEC_HMAC_GCM_MAC = 16, +- SEC_SM3_MAC = 32, +- SEC_HMAC_SM3_MAC = 32, +- SEC_HMAC_MD5_MAC = 16, +- SEC_HMAC_SHA1_MAC = 20, +- SEC_HMAC_SHA256_MAC = 32, +- SEC_HMAC_SHA512_MAC = 64, +-}; +- + enum sec_cmode { + SEC_CMODE_ECB = 0x0, + SEC_CMODE_CBC = 0x1, +diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c +index 98730aab287c3d..2bf315554f02a2 100644 +--- a/drivers/crypto/ixp4xx_crypto.c ++++ b/drivers/crypto/ixp4xx_crypto.c +@@ -470,6 +470,7 @@ static int init_ixp_crypto(struct device *dev) + return -ENODEV; + } + npe_id = npe_spec.args[0]; ++ of_node_put(npe_spec.np); + + ret = of_parse_phandle_with_fixed_args(np, "queue-rx", 1, 0, + &queue_spec); +@@ -478,6 +479,7 @@ static int init_ixp_crypto(struct device *dev) + return -ENODEV; + } + recv_qid = queue_spec.args[0]; ++ of_node_put(queue_spec.np); + + ret = of_parse_phandle_with_fixed_args(np, "queue-txready", 1, 0, + &queue_spec); +@@ -486,6 +488,7 @@ static int init_ixp_crypto(struct device *dev) + return -ENODEV; + } + send_qid = queue_spec.args[0]; ++ of_node_put(queue_spec.np); + } else { + /* + * Hardcoded engine when using platform data, this goes away +diff --git a/drivers/crypto/qce/aead.c b/drivers/crypto/qce/aead.c +index 97a530171f07a8..6f766bbb8cbb66 100644 +--- a/drivers/crypto/qce/aead.c ++++ b/drivers/crypto/qce/aead.c +@@ -786,7 +786,7 @@ static int qce_aead_register_one(const struct qce_aead_def *def, struct qce_devi + alg->init = qce_aead_init; + alg->exit = qce_aead_exit; + +- alg->base.cra_priority = 300; ++ alg->base.cra_priority = 275; + alg->base.cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_KERN_DRIVER_ONLY | +diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c +index d3780be44a763c..df4ae3377b6138 100644 +--- a/drivers/crypto/qce/core.c ++++ b/drivers/crypto/qce/core.c +@@ -48,16 +48,19 @@ static void qce_unregister_algs(struct qce_device *qce) + static int qce_register_algs(struct qce_device *qce) + { + const struct qce_algo_ops *ops; +- int i, ret = -ENODEV; ++ int i, j, ret = -ENODEV; + + for (i = 0; i < ARRAY_SIZE(qce_ops); i++) { + ops = qce_ops[i]; + ret = ops->register_algs(qce); +- if (ret) +- break; ++ if (ret) { ++ for (j = i - 1; j >= 0; j--) ++ ops->unregister_algs(qce); ++ return ret; ++ } + } + +- return ret; ++ return 0; + } + + static int qce_handle_request(struct crypto_async_request *async_req) +@@ -236,7 +239,7 @@ static int qce_crypto_probe(struct platform_device *pdev) + + ret = qce_check_version(qce); + if (ret) +- goto err_clks; ++ goto err_dma; + + spin_lock_init(&qce->lock); + tasklet_init(&qce->done_tasklet, qce_tasklet_req_done, +diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c +index 59159f5e64e522..18b15970e4081e 100644 +--- a/drivers/crypto/qce/sha.c ++++ b/drivers/crypto/qce/sha.c +@@ -480,7 +480,7 @@ static int qce_ahash_register_one(const struct qce_ahash_def *def, + + base = &alg->halg.base; + base->cra_blocksize = def->blocksize; +- base->cra_priority = 300; ++ base->cra_priority = 175; + base->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY; + base->cra_ctxsize = sizeof(struct qce_sha_ctx); + base->cra_alignmask = 0; +diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c +index 3d27cd5210ef50..4eff380dc45e6d 100644 +--- a/drivers/crypto/qce/skcipher.c ++++ b/drivers/crypto/qce/skcipher.c +@@ -461,7 +461,7 @@ static int qce_skcipher_register_one(const struct qce_skcipher_def *def, + alg->encrypt = qce_skcipher_encrypt; + alg->decrypt = qce_skcipher_decrypt; + +- alg->base.cra_priority = 300; ++ alg->base.cra_priority = 275; + alg->base.cra_flags = CRYPTO_ALG_ASYNC | + CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_KERN_DRIVER_ONLY; +diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c +index 69292d4a0c4419..560fe658b8942e 100644 +--- a/drivers/dma/ti/edma.c ++++ b/drivers/dma/ti/edma.c +@@ -217,7 +217,6 @@ struct edma_desc { + struct edma_cc; + + struct edma_tc { +- struct device_node *node; + u16 id; + }; + +@@ -2524,13 +2523,13 @@ static int edma_probe(struct platform_device *pdev) + if (ret || i == ecc->num_tc) + break; + +- ecc->tc_list[i].node = tc_args.np; + ecc->tc_list[i].id = i; + queue_priority_mapping[i][1] = tc_args.args[0]; + if (queue_priority_mapping[i][1] > lowest_priority) { + lowest_priority = queue_priority_mapping[i][1]; + info->default_queue = i; + } ++ of_node_put(tc_args.np); + } + + /* See if we have optional dma-channel-mask array */ +diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig +index 97ce31e667fca3..b4d83c08acef88 100644 +--- a/drivers/firmware/Kconfig ++++ b/drivers/firmware/Kconfig +@@ -139,7 +139,7 @@ config ISCSI_IBFT + select ISCSI_BOOT_SYSFS + select ISCSI_IBFT_FIND if X86 + depends on ACPI && SCSI && SCSI_LOWLEVEL +- default n ++ default n + help + This option enables support for detection and exposing of iSCSI + Boot Firmware Table (iBFT) via sysfs to userspace. If you wish to +diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c +index 332739f3eded57..8c86b3c1df0d7b 100644 +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -774,13 +774,15 @@ char * __init efi_md_typeattr_format(char *buf, size_t size, + EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO | + EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP | + EFI_MEMORY_NV | EFI_MEMORY_SP | EFI_MEMORY_CPU_CRYPTO | +- EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE)) ++ EFI_MEMORY_MORE_RELIABLE | EFI_MEMORY_HOT_PLUGGABLE | ++ EFI_MEMORY_RUNTIME)) + snprintf(pos, size, "|attr=0x%016llx]", + (unsigned long long)attr); + else + snprintf(pos, size, +- "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", ++ "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", + attr & EFI_MEMORY_RUNTIME ? "RUN" : "", ++ attr & EFI_MEMORY_HOT_PLUGGABLE ? "HP" : "", + attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "", + attr & EFI_MEMORY_CPU_CRYPTO ? "CC" : "", + attr & EFI_MEMORY_SP ? "SP" : "", +diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile +index 2c67f71f237537..f1a4f0154540b1 100644 +--- a/drivers/firmware/efi/libstub/Makefile ++++ b/drivers/firmware/efi/libstub/Makefile +@@ -7,7 +7,7 @@ + # + cflags-$(CONFIG_X86_32) := -march=i386 + cflags-$(CONFIG_X86_64) := -mcmodel=small +-cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \ ++cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -std=gnu11 \ + -fPIC -fno-strict-aliasing -mno-red-zone \ + -mno-mmx -mno-sse -fshort-wchar \ + -Wno-pointer-sign \ +diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c +index 724155b9e10dcf..de322e1b2cdac0 100644 +--- a/drivers/firmware/efi/libstub/randomalloc.c ++++ b/drivers/firmware/efi/libstub/randomalloc.c +@@ -24,6 +24,9 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md, + if (md->type != EFI_CONVENTIONAL_MEMORY) + return 0; + ++ if (md->attribute & EFI_MEMORY_HOT_PLUGGABLE) ++ return 0; ++ + if (efi_soft_reserve_enabled() && + (md->attribute & EFI_MEMORY_SP)) + return 0; +diff --git a/drivers/firmware/efi/libstub/relocate.c b/drivers/firmware/efi/libstub/relocate.c +index 8ee9eb2b90392d..c3c9c38c218411 100644 +--- a/drivers/firmware/efi/libstub/relocate.c ++++ b/drivers/firmware/efi/libstub/relocate.c +@@ -62,6 +62,9 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align, + if (desc->type != EFI_CONVENTIONAL_MEMORY) + continue; + ++ if (desc->attribute & EFI_MEMORY_HOT_PLUGGABLE) ++ continue; ++ + if (efi_soft_reserve_enabled() && + (desc->attribute & EFI_MEMORY_SP)) + continue; +diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c +index 24d6f6e08df8be..816b2b05fe4870 100644 +--- a/drivers/firmware/efi/sysfb_efi.c ++++ b/drivers/firmware/efi/sysfb_efi.c +@@ -93,6 +93,7 @@ void efifb_setup_from_dmi(struct screen_info *si, const char *opt) + _ret_; \ + }) + ++#ifdef CONFIG_EFI + static int __init efifb_set_system(const struct dmi_system_id *id) + { + struct efifb_dmi_info *info = id->driver_data; +@@ -348,7 +349,6 @@ static const struct fwnode_operations efifb_fwnode_ops = { + .add_links = efifb_add_links, + }; + +-#ifdef CONFIG_EFI + static struct fwnode_handle efifb_fwnode; + + __init void sysfb_apply_efi_quirks(void) +diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c +index 23047dc84ef1bc..4cd80d42bcc0de 100644 +--- a/drivers/gpio/gpio-aggregator.c ++++ b/drivers/gpio/gpio-aggregator.c +@@ -116,10 +116,15 @@ static ssize_t new_device_store(struct device_driver *driver, const char *buf, + struct platform_device *pdev; + int res, id; + ++ if (!try_module_get(THIS_MODULE)) ++ return -ENOENT; ++ + /* kernfs guarantees string termination, so count + 1 is safe */ + aggr = kzalloc(sizeof(*aggr) + count + 1, GFP_KERNEL); +- if (!aggr) +- return -ENOMEM; ++ if (!aggr) { ++ res = -ENOMEM; ++ goto put_module; ++ } + + memcpy(aggr->args, buf, count + 1); + +@@ -158,6 +163,7 @@ static ssize_t new_device_store(struct device_driver *driver, const char *buf, + } + + aggr->pdev = pdev; ++ module_put(THIS_MODULE); + return count; + + remove_table: +@@ -172,6 +178,8 @@ static ssize_t new_device_store(struct device_driver *driver, const char *buf, + kfree(aggr->lookups); + free_ga: + kfree(aggr); ++put_module: ++ module_put(THIS_MODULE); + return res; + } + +@@ -200,13 +208,19 @@ static ssize_t delete_device_store(struct device_driver *driver, + if (error) + return error; + ++ if (!try_module_get(THIS_MODULE)) ++ return -ENOENT; ++ + mutex_lock(&gpio_aggregator_lock); + aggr = idr_remove(&gpio_aggregator_idr, id); + mutex_unlock(&gpio_aggregator_lock); +- if (!aggr) ++ if (!aggr) { ++ module_put(THIS_MODULE); + return -ENOENT; ++ } + + gpio_aggregator_free(aggr); ++ module_put(THIS_MODULE); + return count; + } + static DRIVER_ATTR_WO(delete_device); +diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c +index d329a143f5ec94..0c97a8c95e06ce 100644 +--- a/drivers/gpio/gpio-bcm-kona.c ++++ b/drivers/gpio/gpio-bcm-kona.c +@@ -76,6 +76,22 @@ struct bcm_kona_gpio { + struct bcm_kona_gpio_bank { + int id; + int irq; ++ /* ++ * Used to keep track of lock/unlock operations for each GPIO in the ++ * bank. ++ * ++ * All GPIOs are locked by default (see bcm_kona_gpio_reset), and the ++ * unlock count for all GPIOs is 0 by default. Each unlock increments ++ * the counter, and each lock decrements the counter. ++ * ++ * The lock function only locks the GPIO once its unlock counter is ++ * down to 0. This is necessary because the GPIO is unlocked in two ++ * places in this driver: once for requested GPIOs, and once for ++ * requested IRQs. Since it is possible for a GPIO to be requested ++ * as both a GPIO and an IRQ, we need to ensure that we don't lock it ++ * too early. ++ */ ++ u8 gpio_unlock_count[GPIO_PER_BANK]; + /* Used in the interrupt handler */ + struct bcm_kona_gpio *kona_gpio; + }; +@@ -93,14 +109,24 @@ static void bcm_kona_gpio_lock_gpio(struct bcm_kona_gpio *kona_gpio, + u32 val; + unsigned long flags; + int bank_id = GPIO_BANK(gpio); ++ int bit = GPIO_BIT(gpio); ++ struct bcm_kona_gpio_bank *bank = &kona_gpio->banks[bank_id]; + +- raw_spin_lock_irqsave(&kona_gpio->lock, flags); ++ if (bank->gpio_unlock_count[bit] == 0) { ++ dev_err(kona_gpio->gpio_chip.parent, ++ "Unbalanced locks for GPIO %u\n", gpio); ++ return; ++ } + +- val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); +- val |= BIT(gpio); +- bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); ++ if (--bank->gpio_unlock_count[bit] == 0) { ++ raw_spin_lock_irqsave(&kona_gpio->lock, flags); + +- raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); ++ val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); ++ val |= BIT(bit); ++ bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); ++ ++ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); ++ } + } + + static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio, +@@ -109,14 +135,20 @@ static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio, + u32 val; + unsigned long flags; + int bank_id = GPIO_BANK(gpio); ++ int bit = GPIO_BIT(gpio); ++ struct bcm_kona_gpio_bank *bank = &kona_gpio->banks[bank_id]; + +- raw_spin_lock_irqsave(&kona_gpio->lock, flags); ++ if (bank->gpio_unlock_count[bit] == 0) { ++ raw_spin_lock_irqsave(&kona_gpio->lock, flags); + +- val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); +- val &= ~BIT(gpio); +- bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); ++ val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); ++ val &= ~BIT(bit); ++ bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); + +- raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); ++ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); ++ } ++ ++ ++bank->gpio_unlock_count[bit]; + } + + static int bcm_kona_gpio_get_dir(struct gpio_chip *chip, unsigned gpio) +@@ -367,6 +399,7 @@ static void bcm_kona_gpio_irq_mask(struct irq_data *d) + + kona_gpio = irq_data_get_irq_chip_data(d); + reg_base = kona_gpio->reg_base; ++ + raw_spin_lock_irqsave(&kona_gpio->lock, flags); + + val = readl(reg_base + GPIO_INT_MASK(bank_id)); +@@ -389,6 +422,7 @@ static void bcm_kona_gpio_irq_unmask(struct irq_data *d) + + kona_gpio = irq_data_get_irq_chip_data(d); + reg_base = kona_gpio->reg_base; ++ + raw_spin_lock_irqsave(&kona_gpio->lock, flags); + + val = readl(reg_base + GPIO_INT_MSKCLR(bank_id)); +@@ -484,15 +518,26 @@ static void bcm_kona_gpio_irq_handler(struct irq_desc *desc) + static int bcm_kona_gpio_irq_reqres(struct irq_data *d) + { + struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); ++ unsigned int gpio = d->hwirq; + +- return gpiochip_reqres_irq(&kona_gpio->gpio_chip, d->hwirq); ++ /* ++ * We need to unlock the GPIO before any other operations are performed ++ * on the relevant GPIO configuration registers ++ */ ++ bcm_kona_gpio_unlock_gpio(kona_gpio, gpio); ++ ++ return gpiochip_reqres_irq(&kona_gpio->gpio_chip, gpio); + } + + static void bcm_kona_gpio_irq_relres(struct irq_data *d) + { + struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); ++ unsigned int gpio = d->hwirq; ++ ++ /* Once we no longer use it, lock the GPIO again */ ++ bcm_kona_gpio_lock_gpio(kona_gpio, gpio); + +- gpiochip_relres_irq(&kona_gpio->gpio_chip, d->hwirq); ++ gpiochip_relres_irq(&kona_gpio->gpio_chip, gpio); + } + + static struct irq_chip bcm_gpio_irq_chip = { +@@ -630,7 +675,7 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev) + bank->irq = platform_get_irq(pdev, i); + bank->kona_gpio = kona_gpio; + if (bank->irq < 0) { +- dev_err(dev, "Couldn't get IRQ for bank %d", i); ++ dev_err(dev, "Couldn't get IRQ for bank %d\n", i); + ret = -ENOENT; + goto err_irq_domain; + } +diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c +index 853d9aa6b3b1f5..d456077c74f2f9 100644 +--- a/drivers/gpio/gpio-mxc.c ++++ b/drivers/gpio/gpio-mxc.c +@@ -445,8 +445,7 @@ static int mxc_gpio_probe(struct platform_device *pdev) + port->gc.request = gpiochip_generic_request; + port->gc.free = gpiochip_generic_free; + port->gc.to_irq = mxc_gpio_to_irq; +- port->gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 : +- pdev->id * 32; ++ port->gc.base = of_alias_get_id(np, "gpio") * 32; + + err = devm_gpiochip_add_data(&pdev->dev, &port->gc, port); + if (err) +diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c +index 4860bf3b7e002b..45f3836c4f0fab 100644 +--- a/drivers/gpio/gpio-pca953x.c ++++ b/drivers/gpio/gpio-pca953x.c +@@ -733,25 +733,6 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pendin + DECLARE_BITMAP(trigger, MAX_LINE); + int ret; + +- if (chip->driver_data & PCA_PCAL) { +- /* Read the current interrupt status from the device */ +- ret = pca953x_read_regs(chip, PCAL953X_INT_STAT, trigger); +- if (ret) +- return false; +- +- /* Check latched inputs and clear interrupt status */ +- ret = pca953x_read_regs(chip, chip->regs->input, cur_stat); +- if (ret) +- return false; +- +- /* Apply filter for rising/falling edge selection */ +- bitmap_replace(new_stat, chip->irq_trig_fall, chip->irq_trig_raise, cur_stat, gc->ngpio); +- +- bitmap_and(pending, new_stat, trigger, gc->ngpio); +- +- return !bitmap_empty(pending, gc->ngpio); +- } +- + ret = pca953x_read_regs(chip, chip->regs->input, cur_stat); + if (ret) + return false; +diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c +index f7b653314e7e54..8e2acf3b022f7b 100644 +--- a/drivers/gpio/gpio-rcar.c ++++ b/drivers/gpio/gpio-rcar.c +@@ -41,7 +41,7 @@ struct gpio_rcar_info { + + struct gpio_rcar_priv { + void __iomem *base; +- spinlock_t lock; ++ raw_spinlock_t lock; + struct device *dev; + struct gpio_chip gpio_chip; + struct irq_chip irq_chip; +@@ -121,7 +121,7 @@ static void gpio_rcar_config_interrupt_input_mode(struct gpio_rcar_priv *p, + * "Setting Level-Sensitive Interrupt Input Mode" + */ + +- spin_lock_irqsave(&p->lock, flags); ++ raw_spin_lock_irqsave(&p->lock, flags); + + /* Configure positive or negative logic in POSNEG */ + gpio_rcar_modify_bit(p, POSNEG, hwirq, !active_high_rising_edge); +@@ -140,7 +140,7 @@ static void gpio_rcar_config_interrupt_input_mode(struct gpio_rcar_priv *p, + if (!level_trigger) + gpio_rcar_write(p, INTCLR, BIT(hwirq)); + +- spin_unlock_irqrestore(&p->lock, flags); ++ raw_spin_unlock_irqrestore(&p->lock, flags); + } + + static int gpio_rcar_irq_set_type(struct irq_data *d, unsigned int type) +@@ -233,7 +233,7 @@ static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip, + * "Setting General Input Mode" + */ + +- spin_lock_irqsave(&p->lock, flags); ++ raw_spin_lock_irqsave(&p->lock, flags); + + /* Configure positive logic in POSNEG */ + gpio_rcar_modify_bit(p, POSNEG, gpio, false); +@@ -248,7 +248,7 @@ static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip, + if (p->info.has_outdtsel && output) + gpio_rcar_modify_bit(p, OUTDTSEL, gpio, false); + +- spin_unlock_irqrestore(&p->lock, flags); ++ raw_spin_unlock_irqrestore(&p->lock, flags); + } + + static int gpio_rcar_request(struct gpio_chip *chip, unsigned offset) +@@ -334,7 +334,7 @@ static int gpio_rcar_get_multiple(struct gpio_chip *chip, unsigned long *mask, + return 0; + } + +- spin_lock_irqsave(&p->lock, flags); ++ raw_spin_lock_irqsave(&p->lock, flags); + outputs = gpio_rcar_read(p, INOUTSEL); + m = outputs & bankmask; + if (m) +@@ -343,7 +343,7 @@ static int gpio_rcar_get_multiple(struct gpio_chip *chip, unsigned long *mask, + m = ~outputs & bankmask; + if (m) + val |= gpio_rcar_read(p, INDT) & m; +- spin_unlock_irqrestore(&p->lock, flags); ++ raw_spin_unlock_irqrestore(&p->lock, flags); + + bits[0] = val; + return 0; +@@ -354,9 +354,9 @@ static void gpio_rcar_set(struct gpio_chip *chip, unsigned offset, int value) + struct gpio_rcar_priv *p = gpiochip_get_data(chip); + unsigned long flags; + +- spin_lock_irqsave(&p->lock, flags); ++ raw_spin_lock_irqsave(&p->lock, flags); + gpio_rcar_modify_bit(p, OUTDT, offset, value); +- spin_unlock_irqrestore(&p->lock, flags); ++ raw_spin_unlock_irqrestore(&p->lock, flags); + } + + static void gpio_rcar_set_multiple(struct gpio_chip *chip, unsigned long *mask, +@@ -373,12 +373,12 @@ static void gpio_rcar_set_multiple(struct gpio_chip *chip, unsigned long *mask, + if (!bankmask) + return; + +- spin_lock_irqsave(&p->lock, flags); ++ raw_spin_lock_irqsave(&p->lock, flags); + val = gpio_rcar_read(p, OUTDT); + val &= ~bankmask; + val |= (bankmask & bits[0]); + gpio_rcar_write(p, OUTDT, val); +- spin_unlock_irqrestore(&p->lock, flags); ++ raw_spin_unlock_irqrestore(&p->lock, flags); + } + + static int gpio_rcar_direction_output(struct gpio_chip *chip, unsigned offset, +@@ -452,7 +452,12 @@ static int gpio_rcar_parse_dt(struct gpio_rcar_priv *p, unsigned int *npins) + p->info = *info; + + ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args); +- *npins = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK; ++ if (ret) { ++ *npins = RCAR_MAX_GPIO_PER_BANK; ++ } else { ++ *npins = args.args[2]; ++ of_node_put(args.np); ++ } + + if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) { + dev_warn(p->dev, "Invalid number of gpio lines %u, using %u\n", +@@ -491,7 +496,7 @@ static int gpio_rcar_probe(struct platform_device *pdev) + return -ENOMEM; + + p->dev = dev; +- spin_lock_init(&p->lock); ++ raw_spin_lock_init(&p->lock); + + /* Get device configuration from DT node */ + ret = gpio_rcar_parse_dt(p, &npins); +diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c +index dd4d58b4ae4983..2eec52d4f2b65e 100644 +--- a/drivers/gpio/gpio-stmpe.c ++++ b/drivers/gpio/gpio-stmpe.c +@@ -191,7 +191,7 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) + [REG_IE][CSB] = STMPE_IDX_IEGPIOR_CSB, + [REG_IE][MSB] = STMPE_IDX_IEGPIOR_MSB, + }; +- int i, j; ++ int ret, i, j; + + /* + * STMPE1600: to be able to get IRQ from pins, +@@ -199,8 +199,16 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) + * GPSR or GPCR registers + */ + if (stmpe->partnum == STMPE1600) { +- stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB]); +- stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB]); ++ ret = stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB]); ++ if (ret < 0) { ++ dev_err(stmpe->dev, "Failed to read GPMR_LSB: %d\n", ret); ++ goto err; ++ } ++ ret = stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB]); ++ if (ret < 0) { ++ dev_err(stmpe->dev, "Failed to read GPMR_CSB: %d\n", ret); ++ goto err; ++ } + } + + for (i = 0; i < CACHE_NR_REGS; i++) { +@@ -222,6 +230,7 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) + } + } + ++err: + mutex_unlock(&stmpe_gpio->irq_lock); + } + +diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c +index db616ae560a3ca..91259076d48a4e 100644 +--- a/drivers/gpio/gpio-xilinx.c ++++ b/drivers/gpio/gpio-xilinx.c +@@ -52,7 +52,6 @@ + * @dir: GPIO direction shadow register + * @gpio_lock: Lock used for synchronization + * @irq: IRQ used by GPIO device +- * @irqchip: IRQ chip + * @enable: GPIO IRQ enable/disable bitfield + * @rising_edge: GPIO IRQ rising edge enable/disable bitfield + * @falling_edge: GPIO IRQ falling edge enable/disable bitfield +@@ -66,7 +65,7 @@ struct xgpio_instance { + DECLARE_BITMAP(state, 64); + DECLARE_BITMAP(last_irq_read, 64); + DECLARE_BITMAP(dir, 64); +- spinlock_t gpio_lock; /* For serializing operations */ ++ raw_spinlock_t gpio_lock; /* For serializing operations */ + int irq; + struct irq_chip irqchip; + DECLARE_BITMAP(enable, 64); +@@ -179,14 +178,14 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) + struct xgpio_instance *chip = gpiochip_get_data(gc); + int bit = xgpio_to_bit(chip, gpio); + +- spin_lock_irqsave(&chip->gpio_lock, flags); ++ raw_spin_lock_irqsave(&chip->gpio_lock, flags); + + /* Write to GPIO signal and set its direction to output */ + __assign_bit(bit, chip->state, val); + + xgpio_write_ch(chip, XGPIO_DATA_OFFSET, bit, chip->state); + +- spin_unlock_irqrestore(&chip->gpio_lock, flags); ++ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); + } + + /** +@@ -210,7 +209,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, + bitmap_remap(hw_mask, mask, chip->sw_map, chip->hw_map, 64); + bitmap_remap(hw_bits, bits, chip->sw_map, chip->hw_map, 64); + +- spin_lock_irqsave(&chip->gpio_lock, flags); ++ raw_spin_lock_irqsave(&chip->gpio_lock, flags); + + bitmap_replace(state, chip->state, hw_bits, hw_mask, 64); + +@@ -218,7 +217,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, + + bitmap_copy(chip->state, state, 64); + +- spin_unlock_irqrestore(&chip->gpio_lock, flags); ++ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); + } + + /** +@@ -236,13 +235,13 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) + struct xgpio_instance *chip = gpiochip_get_data(gc); + int bit = xgpio_to_bit(chip, gpio); + +- spin_lock_irqsave(&chip->gpio_lock, flags); ++ raw_spin_lock_irqsave(&chip->gpio_lock, flags); + + /* Set the GPIO bit in shadow register and set direction as input */ + __set_bit(bit, chip->dir); + xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir); + +- spin_unlock_irqrestore(&chip->gpio_lock, flags); ++ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); + + return 0; + } +@@ -265,7 +264,7 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) + struct xgpio_instance *chip = gpiochip_get_data(gc); + int bit = xgpio_to_bit(chip, gpio); + +- spin_lock_irqsave(&chip->gpio_lock, flags); ++ raw_spin_lock_irqsave(&chip->gpio_lock, flags); + + /* Write state of GPIO signal */ + __assign_bit(bit, chip->state, val); +@@ -275,7 +274,7 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) + __clear_bit(bit, chip->dir); + xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir); + +- spin_unlock_irqrestore(&chip->gpio_lock, flags); ++ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); + + return 0; + } +@@ -405,7 +404,7 @@ static void xgpio_irq_mask(struct irq_data *irq_data) + int bit = xgpio_to_bit(chip, irq_offset); + u32 mask = BIT(bit / 32), temp; + +- spin_lock_irqsave(&chip->gpio_lock, flags); ++ raw_spin_lock_irqsave(&chip->gpio_lock, flags); + + __clear_bit(bit, chip->enable); + +@@ -415,7 +414,7 @@ static void xgpio_irq_mask(struct irq_data *irq_data) + temp &= ~mask; + xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, temp); + } +- spin_unlock_irqrestore(&chip->gpio_lock, flags); ++ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); + } + + /** +@@ -431,7 +430,7 @@ static void xgpio_irq_unmask(struct irq_data *irq_data) + u32 old_enable = xgpio_get_value32(chip->enable, bit); + u32 mask = BIT(bit / 32), val; + +- spin_lock_irqsave(&chip->gpio_lock, flags); ++ raw_spin_lock_irqsave(&chip->gpio_lock, flags); + + __set_bit(bit, chip->enable); + +@@ -450,7 +449,7 @@ static void xgpio_irq_unmask(struct irq_data *irq_data) + xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, val); + } + +- spin_unlock_irqrestore(&chip->gpio_lock, flags); ++ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); + } + + /** +@@ -515,7 +514,7 @@ static void xgpio_irqhandler(struct irq_desc *desc) + + chained_irq_enter(irqchip, desc); + +- spin_lock(&chip->gpio_lock); ++ raw_spin_lock(&chip->gpio_lock); + + xgpio_read_ch_all(chip, XGPIO_DATA_OFFSET, all); + +@@ -532,7 +531,7 @@ static void xgpio_irqhandler(struct irq_desc *desc) + bitmap_copy(chip->last_irq_read, all, 64); + bitmap_or(all, rising, falling, 64); + +- spin_unlock(&chip->gpio_lock); ++ raw_spin_unlock(&chip->gpio_lock); + + dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling); + +@@ -623,7 +622,7 @@ static int xgpio_probe(struct platform_device *pdev) + bitmap_set(chip->hw_map, 0, width[0]); + bitmap_set(chip->hw_map, 32, width[1]); + +- spin_lock_init(&chip->gpio_lock); ++ raw_spin_lock_init(&chip->gpio_lock); + + chip->gc.base = -1; + chip->gc.ngpio = bitmap_weight(chip->hw_map, 64); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index 4be8d2ca50f3a7..b11a98bee4f08e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -1202,6 +1202,17 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev) + if (amdgpu_sriov_vf(adev)) + return 0; + ++ /* resizing on Dell G5 SE platforms causes problems with runtime pm */ ++ if ((amdgpu_runtime_pm != 0) && ++ adev->pdev->vendor == PCI_VENDOR_ID_ATI && ++ adev->pdev->device == 0x731f && ++ adev->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) ++ return 0; ++ ++ /* PCI_EXT_CAP_ID_VNDR extended capability is located at 0x100 */ ++ if (!pci_find_ext_capability(adev->pdev, PCI_EXT_CAP_ID_VNDR)) ++ DRM_WARN("System can't access extended configuration space,please check!!\n"); ++ + /* skip if the bios has already enabled large BAR */ + if (adev->gmc.real_vram_size && + (pci_resource_len(adev->pdev, 0) >= adev->gmc.real_vram_size)) +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +index 4aba0e8c84f814..7008f6cb73f48c 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +@@ -885,6 +885,7 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev) + struct drm_device *dev = adev_to_drm(adev); + struct drm_connector *connector; + struct drm_connector_list_iter iter; ++ int i; + + drm_connector_list_iter_begin(dev, &iter); + drm_for_each_connector_iter(connector, &iter) { +@@ -906,6 +907,12 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev) + } + } + drm_connector_list_iter_end(&iter); ++ ++ /* Update reference counts for HPDs */ ++ for (i = DC_IRQ_SOURCE_HPD1; i <= adev->mode_info.num_hpd; i++) { ++ if (amdgpu_irq_get(adev, &adev->hpd_irq, i - DC_IRQ_SOURCE_HPD1)) ++ drm_err(dev, "DM_IRQ: Failed get HPD for source=%d)!\n", i); ++ } + } + + /** +@@ -921,6 +928,7 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev) + struct drm_device *dev = adev_to_drm(adev); + struct drm_connector *connector; + struct drm_connector_list_iter iter; ++ int i; + + drm_connector_list_iter_begin(dev, &iter); + drm_for_each_connector_iter(connector, &iter) { +@@ -937,4 +945,10 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev) + } + } + drm_connector_list_iter_end(&iter); ++ ++ /* Update reference counts for HPDs */ ++ for (i = DC_IRQ_SOURCE_HPD1; i <= adev->mode_info.num_hpd; i++) { ++ if (amdgpu_irq_put(adev, &adev->hpd_irq, i - DC_IRQ_SOURCE_HPD1)) ++ drm_err(dev, "DM_IRQ: Failed put HPD for source=%d!\n", i); ++ } + } +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c +index cc3b62f7339417..1fbd23922082ae 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c +@@ -1420,6 +1420,8 @@ int atomctrl_get_smc_sclk_range_table(struct pp_hwmgr *hwmgr, struct pp_atom_ctr + GetIndexIntoMasterTable(DATA, SMU_Info), + &size, &frev, &crev); + ++ if (!psmu_info) ++ return -EINVAL; + + for (i = 0; i < psmu_info->ucSclkEntryNum; i++) { + table->entry[i].ucVco_setting = psmu_info->asSclkFcwRangeEntry[i].ucVco_setting; +diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +index 31846510c1a92e..d3389fb374c9b8 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +@@ -1711,7 +1711,6 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu, + + gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity; + gpu_metrics->average_umc_activity = metrics.AverageUclkActivity; +- gpu_metrics->average_mm_activity = 0; + + /* Valid power data is available only from primary die */ + if (aldebaran_is_primary(smu)) { +diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c +index e465cc4879c9ff..fecc511d687c93 100644 +--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c ++++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c +@@ -160,6 +160,10 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms, + formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl, + kwb_conn->wb_layer->layer_type, + &n_formats); ++ if (!formats) { ++ kfree(kwb_conn); ++ return -ENOMEM; ++ } + + err = drm_writeback_connector_init(&kms->base, wb_conn, + &komeda_wb_connector_funcs, +diff --git a/drivers/gpu/drm/drm_dp_cec.c b/drivers/gpu/drm/drm_dp_cec.c +index 3ab2609f9ec745..3ec770d602da66 100644 +--- a/drivers/gpu/drm/drm_dp_cec.c ++++ b/drivers/gpu/drm/drm_dp_cec.c +@@ -310,16 +310,6 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) + if (!aux->transfer) + return; + +-#ifndef CONFIG_MEDIA_CEC_RC +- /* +- * CEC_CAP_RC is part of CEC_CAP_DEFAULTS, but it is stripped by +- * cec_allocate_adapter() if CONFIG_MEDIA_CEC_RC is undefined. +- * +- * Do this here as well to ensure the tests against cec_caps are +- * correct. +- */ +- cec_caps &= ~CEC_CAP_RC; +-#endif + cancel_delayed_work_sync(&aux->cec.unregister_work); + + mutex_lock(&aux->cec.lock); +@@ -336,7 +326,9 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) + num_las = CEC_MAX_LOG_ADDRS; + + if (aux->cec.adap) { +- if (aux->cec.adap->capabilities == cec_caps && ++ /* Check if the adapter properties have changed */ ++ if ((aux->cec.adap->capabilities & CEC_CAP_MONITOR_ALL) == ++ (cec_caps & CEC_CAP_MONITOR_ALL) && + aux->cec.adap->available_log_addrs == num_las) { + /* Unchanged, so just set the phys addr */ + cec_s_phys_addr_from_edid(aux->cec.adap, edid); +diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c +index 82960d5d4e7337..bc265aa0f692b0 100644 +--- a/drivers/gpu/drm/drm_fb_helper.c ++++ b/drivers/gpu/drm/drm_fb_helper.c +@@ -1407,14 +1407,14 @@ int drm_fb_helper_set_par(struct fb_info *info) + } + EXPORT_SYMBOL(drm_fb_helper_set_par); + +-static void pan_set(struct drm_fb_helper *fb_helper, int x, int y) ++static void pan_set(struct drm_fb_helper *fb_helper, int dx, int dy) + { + struct drm_mode_set *mode_set; + + mutex_lock(&fb_helper->client.modeset_mutex); + drm_client_for_each_modeset(mode_set, &fb_helper->client) { +- mode_set->x = x; +- mode_set->y = y; ++ mode_set->x += dx; ++ mode_set->y += dy; + } + mutex_unlock(&fb_helper->client.modeset_mutex); + } +@@ -1423,16 +1423,18 @@ static int pan_display_atomic(struct fb_var_screeninfo *var, + struct fb_info *info) + { + struct drm_fb_helper *fb_helper = info->par; +- int ret; ++ int ret, dx, dy; + +- pan_set(fb_helper, var->xoffset, var->yoffset); ++ dx = var->xoffset - info->var.xoffset; ++ dy = var->yoffset - info->var.yoffset; ++ pan_set(fb_helper, dx, dy); + + ret = drm_client_modeset_commit_locked(&fb_helper->client); + if (!ret) { + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + } else +- pan_set(fb_helper, info->var.xoffset, info->var.yoffset); ++ pan_set(fb_helper, -dx, -dy); + + return ret; + } +diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c +index e79bb93072dd8f..6776652ab10472 100644 +--- a/drivers/gpu/drm/drm_probe_helper.c ++++ b/drivers/gpu/drm/drm_probe_helper.c +@@ -805,6 +805,86 @@ void drm_kms_helper_poll_fini(struct drm_device *dev) + } + EXPORT_SYMBOL(drm_kms_helper_poll_fini); + ++static bool check_connector_changed(struct drm_connector *connector) ++{ ++ struct drm_device *dev = connector->dev; ++ enum drm_connector_status old_status; ++ u64 old_epoch_counter; ++ ++ /* Only handle HPD capable connectors. */ ++ drm_WARN_ON(dev, !(connector->polled & DRM_CONNECTOR_POLL_HPD)); ++ ++ drm_WARN_ON(dev, !mutex_is_locked(&dev->mode_config.mutex)); ++ ++ old_status = connector->status; ++ old_epoch_counter = connector->epoch_counter; ++ connector->status = drm_helper_probe_detect(connector, NULL, false); ++ ++ if (old_epoch_counter == connector->epoch_counter) { ++ drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Same epoch counter %llu\n", ++ connector->base.id, ++ connector->name, ++ connector->epoch_counter); ++ ++ return false; ++ } ++ ++ drm_dbg_kms(dev, "[CONNECTOR:%d:%s] status updated from %s to %s\n", ++ connector->base.id, ++ connector->name, ++ drm_get_connector_status_name(old_status), ++ drm_get_connector_status_name(connector->status)); ++ ++ drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Changed epoch counter %llu => %llu\n", ++ connector->base.id, ++ connector->name, ++ old_epoch_counter, ++ connector->epoch_counter); ++ ++ return true; ++} ++ ++/** ++ * drm_connector_helper_hpd_irq_event - hotplug processing ++ * @connector: drm_connector ++ * ++ * Drivers can use this helper function to run a detect cycle on a connector ++ * which has the DRM_CONNECTOR_POLL_HPD flag set in its &polled member. ++ * ++ * This helper function is useful for drivers which can track hotplug ++ * interrupts for a single connector. Drivers that want to send a ++ * hotplug event for all connectors or can't track hotplug interrupts ++ * per connector need to use drm_helper_hpd_irq_event(). ++ * ++ * This function must be called from process context with no mode ++ * setting locks held. ++ * ++ * Note that a connector can be both polled and probed from the hotplug ++ * handler, in case the hotplug interrupt is known to be unreliable. ++ * ++ * Returns: ++ * A boolean indicating whether the connector status changed or not ++ */ ++bool drm_connector_helper_hpd_irq_event(struct drm_connector *connector) ++{ ++ struct drm_device *dev = connector->dev; ++ bool changed; ++ ++ mutex_lock(&dev->mode_config.mutex); ++ changed = check_connector_changed(connector); ++ mutex_unlock(&dev->mode_config.mutex); ++ ++ if (changed) { ++ drm_kms_helper_hotplug_event(dev); ++ drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Sent hotplug event\n", ++ connector->base.id, ++ connector->name); ++ } ++ ++ return changed; ++} ++EXPORT_SYMBOL(drm_connector_helper_hpd_irq_event); ++ + /** + * drm_helper_hpd_irq_event - hotplug processing + * @dev: drm_device +@@ -818,9 +898,10 @@ EXPORT_SYMBOL(drm_kms_helper_poll_fini); + * interrupts for each connector. + * + * Drivers which support hotplug interrupts for each connector individually and +- * which have a more fine-grained detect logic should bypass this code and +- * directly call drm_kms_helper_hotplug_event() in case the connector state +- * changed. ++ * which have a more fine-grained detect logic can use ++ * drm_connector_helper_hpd_irq_event(). Alternatively, they should bypass this ++ * code and directly call drm_kms_helper_hotplug_event() in case the connector ++ * state changed. + * + * This function must be called from process context with no mode + * setting locks held. +@@ -832,9 +913,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev) + { + struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; +- enum drm_connector_status old_status; + bool changed = false; +- u64 old_epoch_counter; + + if (!dev->mode_config.poll_enabled) + return false; +@@ -846,33 +925,8 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev) + if (!(connector->polled & DRM_CONNECTOR_POLL_HPD)) + continue; + +- old_status = connector->status; +- +- old_epoch_counter = connector->epoch_counter; +- +- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Old epoch counter %llu\n", connector->base.id, +- connector->name, +- old_epoch_counter); +- +- connector->status = drm_helper_probe_detect(connector, NULL, false); +- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", +- connector->base.id, +- connector->name, +- drm_get_connector_status_name(old_status), +- drm_get_connector_status_name(connector->status)); +- +- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] New epoch counter %llu\n", +- connector->base.id, +- connector->name, +- connector->epoch_counter); +- +- /* +- * Check if epoch counter had changed, meaning that we need +- * to send a uevent. +- */ +- if (old_epoch_counter != connector->epoch_counter) ++ if (check_connector_changed(connector)) + changed = true; +- + } + drm_connector_list_iter_end(&conn_iter); + mutex_unlock(&dev->mode_config.mutex); +diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c +index 87da2278398ae5..1d04232293e58d 100644 +--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c +@@ -340,6 +340,7 @@ void *etnaviv_gem_vmap(struct drm_gem_object *obj) + static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj) + { + struct page **pages; ++ pgprot_t prot; + + lockdep_assert_held(&obj->lock); + +@@ -347,8 +348,19 @@ static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj) + if (IS_ERR(pages)) + return NULL; + +- return vmap(pages, obj->base.size >> PAGE_SHIFT, +- VM_MAP, pgprot_writecombine(PAGE_KERNEL)); ++ switch (obj->flags & ETNA_BO_CACHE_MASK) { ++ case ETNA_BO_CACHED: ++ prot = PAGE_KERNEL; ++ break; ++ case ETNA_BO_UNCACHED: ++ prot = pgprot_noncached(PAGE_KERNEL); ++ break; ++ case ETNA_BO_WC: ++ default: ++ prot = pgprot_writecombine(PAGE_KERNEL); ++ } ++ ++ return vmap(pages, obj->base.size >> PAGE_SHIFT, VM_MAP, prot); + } + + static inline enum dma_data_direction etnaviv_op_to_dma_dir(u32 op) +diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c +index b97b4b3b85e07d..ca92abc2701b5c 100644 +--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c ++++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c +@@ -98,8 +98,6 @@ static const u32 icl_sdr_y_plane_formats[] = { + DRM_FORMAT_Y216, + DRM_FORMAT_XYUV8888, + DRM_FORMAT_XVYU2101010, +- DRM_FORMAT_XVYU12_16161616, +- DRM_FORMAT_XVYU16161616, + }; + + static const u32 icl_sdr_uv_plane_formats[] = { +@@ -126,8 +124,6 @@ static const u32 icl_sdr_uv_plane_formats[] = { + DRM_FORMAT_Y216, + DRM_FORMAT_XYUV8888, + DRM_FORMAT_XVYU2101010, +- DRM_FORMAT_XVYU12_16161616, +- DRM_FORMAT_XVYU16161616, + }; + + static const u32 icl_hdr_plane_formats[] = { +diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +index f843a5040706ab..df3934a990d085 100644 +--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c ++++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +@@ -160,7 +160,7 @@ static int igt_ppgtt_alloc(void *arg) + return PTR_ERR(ppgtt); + + if (!ppgtt->vm.allocate_va_range) +- goto err_ppgtt_cleanup; ++ goto ppgtt_vm_put; + + /* + * While we only allocate the page tables here and so we could +@@ -228,7 +228,7 @@ static int igt_ppgtt_alloc(void *arg) + goto retry; + } + i915_gem_ww_ctx_fini(&ww); +- ++ppgtt_vm_put: + i915_vm_put(&ppgtt->vm); + return err; + } +diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c +index 621ff174dff3d3..0946a11835a478 100644 +--- a/drivers/gpu/drm/radeon/r300.c ++++ b/drivers/gpu/drm/radeon/r300.c +@@ -359,7 +359,8 @@ int r300_mc_wait_for_idle(struct radeon_device *rdev) + return -1; + } + +-static void r300_gpu_init(struct radeon_device *rdev) ++/* rs400_gpu_init also calls this! */ ++void r300_gpu_init(struct radeon_device *rdev) + { + uint32_t gb_tile_config, tmp; + +diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h +index 1e00f6b99f94b6..8f5e07834fcc60 100644 +--- a/drivers/gpu/drm/radeon/radeon_asic.h ++++ b/drivers/gpu/drm/radeon/radeon_asic.h +@@ -165,6 +165,7 @@ void r200_set_safe_registers(struct radeon_device *rdev); + */ + extern int r300_init(struct radeon_device *rdev); + extern void r300_fini(struct radeon_device *rdev); ++extern void r300_gpu_init(struct radeon_device *rdev); + extern int r300_suspend(struct radeon_device *rdev); + extern int r300_resume(struct radeon_device *rdev); + extern int r300_asic_reset(struct radeon_device *rdev, bool hard); +diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c +index 6383f7a34bd8cf..921076292356d5 100644 +--- a/drivers/gpu/drm/radeon/rs400.c ++++ b/drivers/gpu/drm/radeon/rs400.c +@@ -255,8 +255,22 @@ int rs400_mc_wait_for_idle(struct radeon_device *rdev) + + static void rs400_gpu_init(struct radeon_device *rdev) + { +- /* FIXME: is this correct ? */ +- r420_pipes_init(rdev); ++ /* Earlier code was calling r420_pipes_init and then ++ * rs400_mc_wait_for_idle(rdev). The problem is that ++ * at least on my Mobility Radeon Xpress 200M RC410 card ++ * that ends up in this code path ends up num_gb_pipes == 3 ++ * while the card seems to have only one pipe. With the ++ * r420 pipe initialization method. ++ * ++ * Problems shown up as HyperZ glitches, see: ++ * https://bugs.freedesktop.org/show_bug.cgi?id=110897 ++ * ++ * Delegating initialization to r300 code seems to work ++ * and results in proper pipe numbers. The rs400 cards ++ * are said to be not r400, but r300 kind of cards. ++ */ ++ r300_gpu_init(rdev); ++ + if (rs400_mc_wait_for_idle(rdev)) { + pr_warn("rs400: Failed to wait MC idle while programming pipes. Bad things might happen. %08x\n", + RREG32(RADEON_MC_STATUS)); +diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c +index b9ef35a35c857c..af1e361da8df93 100644 +--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c ++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c +@@ -916,9 +916,6 @@ static void cdn_dp_pd_event_work(struct work_struct *work) + { + struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device, + event_work); +- struct drm_connector *connector = &dp->connector; +- enum drm_connector_status old_status; +- + int ret; + + mutex_lock(&dp->lock); +@@ -980,11 +977,7 @@ static void cdn_dp_pd_event_work(struct work_struct *work) + + out: + mutex_unlock(&dp->lock); +- +- old_status = connector->status; +- connector->status = connector->funcs->detect(connector, false); +- if (old_status != connector->status) +- drm_kms_helper_hotplug_event(dp->drm_dev); ++ drm_connector_helper_hpd_irq_event(&dp->connector); + } + + static int cdn_dp_pd_event(struct notifier_block *nb, +diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler_trace.h b/drivers/gpu/drm/scheduler/gpu_scheduler_trace.h +index 877ce9b127f16b..caa5268c51ef1b 100644 +--- a/drivers/gpu/drm/scheduler/gpu_scheduler_trace.h ++++ b/drivers/gpu/drm/scheduler/gpu_scheduler_trace.h +@@ -21,7 +21,7 @@ + * + */ + +-#if !defined(_GPU_SCHED_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) ++#if !defined(_GPU_SCHED_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) + #define _GPU_SCHED_TRACE_H_ + + #include +@@ -123,7 +123,7 @@ TRACE_EVENT(drm_sched_job_wait_dep, + __entry->seqno) + ); + +-#endif ++#endif /* _GPU_SCHED_TRACE_H_ */ + + /* This part must be outside protection */ + #undef TRACE_INCLUDE_PATH +diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c +index f54517698710f4..ad559f5c114827 100644 +--- a/drivers/gpu/drm/tidss/tidss_dispc.c ++++ b/drivers/gpu/drm/tidss/tidss_dispc.c +@@ -596,7 +596,7 @@ void dispc_k2g_set_irqenable(struct dispc_device *dispc, dispc_irq_t mask) + { + dispc_irq_t old_mask = dispc_k2g_read_irqenable(dispc); + +- /* clear the irqstatus for newly enabled irqs */ ++ /* clear the irqstatus for irqs that will be enabled */ + dispc_k2g_clear_irqstatus(dispc, (mask ^ old_mask) & mask); + + dispc_k2g_vp_set_irqenable(dispc, 0, mask); +@@ -604,6 +604,9 @@ void dispc_k2g_set_irqenable(struct dispc_device *dispc, dispc_irq_t mask) + + dispc_write(dispc, DISPC_IRQENABLE_SET, (1 << 0) | (1 << 7)); + ++ /* clear the irqstatus for irqs that were disabled */ ++ dispc_k2g_clear_irqstatus(dispc, (mask ^ old_mask) & old_mask); ++ + /* flush posted write */ + dispc_k2g_read_irqenable(dispc); + } +@@ -676,24 +679,20 @@ static + void dispc_k3_clear_irqstatus(struct dispc_device *dispc, dispc_irq_t clearmask) + { + unsigned int i; +- u32 top_clear = 0; + + for (i = 0; i < dispc->feat->num_vps; ++i) { +- if (clearmask & DSS_IRQ_VP_MASK(i)) { ++ if (clearmask & DSS_IRQ_VP_MASK(i)) + dispc_k3_vp_write_irqstatus(dispc, i, clearmask); +- top_clear |= BIT(i); +- } + } + for (i = 0; i < dispc->feat->num_planes; ++i) { +- if (clearmask & DSS_IRQ_PLANE_MASK(i)) { ++ if (clearmask & DSS_IRQ_PLANE_MASK(i)) + dispc_k3_vid_write_irqstatus(dispc, i, clearmask); +- top_clear |= BIT(4 + i); +- } + } + if (dispc->feat->subrev == DISPC_K2G) + return; + +- dispc_write(dispc, DISPC_IRQSTATUS, top_clear); ++ /* always clear the top level irqstatus */ ++ dispc_write(dispc, DISPC_IRQSTATUS, dispc_read(dispc, DISPC_IRQSTATUS)); + + /* Flush posted writes */ + dispc_read(dispc, DISPC_IRQSTATUS); +@@ -739,7 +738,7 @@ static void dispc_k3_set_irqenable(struct dispc_device *dispc, + + old_mask = dispc_k3_read_irqenable(dispc); + +- /* clear the irqstatus for newly enabled irqs */ ++ /* clear the irqstatus for irqs that will be enabled */ + dispc_k3_clear_irqstatus(dispc, (old_mask ^ mask) & mask); + + for (i = 0; i < dispc->feat->num_vps; ++i) { +@@ -764,6 +763,9 @@ static void dispc_k3_set_irqenable(struct dispc_device *dispc, + if (main_disable) + dispc_write(dispc, DISPC_IRQENABLE_CLR, main_disable); + ++ /* clear the irqstatus for irqs that were disabled */ ++ dispc_k3_clear_irqstatus(dispc, (old_mask ^ mask) & old_mask); ++ + /* Flush posted writes */ + dispc_read(dispc, DISPC_IRQENABLE_SET); + } +diff --git a/drivers/gpu/drm/v3d/v3d_perfmon.c b/drivers/gpu/drm/v3d/v3d_perfmon.c +index 3de4cc692f44d8..d5bbbc0029d6be 100644 +--- a/drivers/gpu/drm/v3d/v3d_perfmon.c ++++ b/drivers/gpu/drm/v3d/v3d_perfmon.c +@@ -175,6 +175,7 @@ int v3d_perfmon_destroy_ioctl(struct drm_device *dev, void *data, + { + struct v3d_file_priv *v3d_priv = file_priv->driver_priv; + struct drm_v3d_perfmon_destroy *req = data; ++ struct v3d_dev *v3d = v3d_priv->v3d; + struct v3d_perfmon *perfmon; + + mutex_lock(&v3d_priv->perfmon.lock); +@@ -184,6 +185,10 @@ int v3d_perfmon_destroy_ioctl(struct drm_device *dev, void *data, + if (!perfmon) + return -EINVAL; + ++ /* If the active perfmon is being destroyed, stop it first */ ++ if (perfmon == v3d->active_perfmon) ++ v3d_perfmon_stop(v3d, perfmon, false); ++ + v3d_perfmon_put(perfmon); + + return 0; +diff --git a/drivers/hid/hid-appleir.c b/drivers/hid/hid-appleir.c +index 8deded1857254a..c45e5aa569d25f 100644 +--- a/drivers/hid/hid-appleir.c ++++ b/drivers/hid/hid-appleir.c +@@ -188,7 +188,7 @@ static int appleir_raw_event(struct hid_device *hid, struct hid_report *report, + static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 }; + unsigned long flags; + +- if (len != 5) ++ if (len != 5 || !(hid->claimed & HID_CLAIMED_INPUT)) + goto out; + + if (!memcmp(data, keydown, sizeof(keydown))) { +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 07c2e5e38fcbaa..90c7dded65fbc0 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1124,6 +1124,8 @@ static void hid_apply_multiplier(struct hid_device *hid, + while (multiplier_collection->parent_idx != -1 && + multiplier_collection->type != HID_COLLECTION_LOGICAL) + multiplier_collection = &hid->collection[multiplier_collection->parent_idx]; ++ if (multiplier_collection->type != HID_COLLECTION_LOGICAL) ++ multiplier_collection = NULL; + + effective_multiplier = hid_calculate_multiplier(hid, multiplier); + +diff --git a/drivers/hid/hid-google-hammer.c b/drivers/hid/hid-google-hammer.c +index 6a227e07f8943d..5f20925bdc21fe 100644 +--- a/drivers/hid/hid-google-hammer.c ++++ b/drivers/hid/hid-google-hammer.c +@@ -267,11 +267,13 @@ static int cbas_ec_remove(struct platform_device *pdev) + return 0; + } + ++#ifdef CONFIG_ACPI + static const struct acpi_device_id cbas_ec_acpi_ids[] = { + { "GOOG000B", 0 }, + { } + }; + MODULE_DEVICE_TABLE(acpi, cbas_ec_acpi_ids); ++#endif + + #ifdef CONFIG_OF + static const struct of_device_id cbas_ec_of_match[] = { +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 57e4ff1ab275d2..bc9ba011ff607e 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -1671,9 +1671,12 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) + break; + } + +- if (suffix) ++ if (suffix) { + hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, + "%s %s", hdev->name, suffix); ++ if (!hi->input->name) ++ return -ENOMEM; ++ } + + return 0; + } +@@ -2070,7 +2073,7 @@ static const struct hid_device_id mt_devices[] = { + I2C_DEVICE_ID_GOODIX_01E8) }, + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU, + HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX, +- I2C_DEVICE_ID_GOODIX_01E8) }, ++ I2C_DEVICE_ID_GOODIX_01E9) }, + + /* GoodTouch panels */ + { .driver_data = MT_CLS_NSMU, +diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c +index 6abd3e2a9094c2..3eeac701173916 100644 +--- a/drivers/hid/hid-sensor-hub.c ++++ b/drivers/hid/hid-sensor-hub.c +@@ -728,23 +728,30 @@ static int sensor_hub_probe(struct hid_device *hdev, + return ret; + } + ++static int sensor_hub_finalize_pending_fn(struct device *dev, void *data) ++{ ++ struct hid_sensor_hub_device *hsdev = dev->platform_data; ++ ++ if (hsdev->pending.status) ++ complete(&hsdev->pending.ready); ++ ++ return 0; ++} ++ + static void sensor_hub_remove(struct hid_device *hdev) + { + struct sensor_hub_data *data = hid_get_drvdata(hdev); + unsigned long flags; +- int i; + + hid_dbg(hdev, " hardware removed\n"); + hid_hw_close(hdev); + hid_hw_stop(hdev); ++ + spin_lock_irqsave(&data->lock, flags); +- for (i = 0; i < data->hid_sensor_client_cnt; ++i) { +- struct hid_sensor_hub_device *hsdev = +- data->hid_sensor_hub_client_devs[i].platform_data; +- if (hsdev->pending.status) +- complete(&hsdev->pending.ready); +- } ++ device_for_each_child(&hdev->dev, NULL, ++ sensor_hub_finalize_pending_fn); + spin_unlock_irqrestore(&data->lock, flags); ++ + mfd_remove_devices(&hdev->dev); + mutex_destroy(&data->mutex); + } +diff --git a/drivers/hid/intel-ish-hid/ishtp-hid.c b/drivers/hid/intel-ish-hid/ishtp-hid.c +index 14c271d7d8a947..0377dac3fc9a04 100644 +--- a/drivers/hid/intel-ish-hid/ishtp-hid.c ++++ b/drivers/hid/intel-ish-hid/ishtp-hid.c +@@ -261,12 +261,14 @@ int ishtp_hid_probe(unsigned int cur_hid_dev, + */ + void ishtp_hid_remove(struct ishtp_cl_data *client_data) + { ++ void *data; + int i; + + for (i = 0; i < client_data->num_hid_devices; ++i) { + if (client_data->hid_sensor_hubs[i]) { +- kfree(client_data->hid_sensor_hubs[i]->driver_data); ++ data = client_data->hid_sensor_hubs[i]->driver_data; + hid_destroy_device(client_data->hid_sensor_hubs[i]); ++ kfree(data); + client_data->hid_sensor_hubs[i] = NULL; + } + } +diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c +index 9a82cd124918f5..a5e6c16c883dca 100644 +--- a/drivers/hid/wacom_wac.c ++++ b/drivers/hid/wacom_wac.c +@@ -4882,6 +4882,10 @@ static const struct wacom_features wacom_features_0x94 = + HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ + .driver_data = (kernel_ulong_t)&wacom_features_##prod + ++#define PCI_DEVICE_WACOM(prod) \ ++ HID_DEVICE(BUS_PCI, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ ++ .driver_data = (kernel_ulong_t)&wacom_features_##prod ++ + #define USB_DEVICE_LENOVO(prod) \ + HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \ + .driver_data = (kernel_ulong_t)&wacom_features_##prod +@@ -5051,6 +5055,7 @@ const struct hid_device_id wacom_ids[] = { + + { USB_DEVICE_WACOM(HID_ANY_ID) }, + { I2C_DEVICE_WACOM(HID_ANY_ID) }, ++ { PCI_DEVICE_WACOM(HID_ANY_ID) }, + { BT_DEVICE_WACOM(HID_ANY_ID) }, + { } + }; +diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c +index 7802bbf5f9587f..59424103f6348a 100644 +--- a/drivers/hwmon/ad7314.c ++++ b/drivers/hwmon/ad7314.c +@@ -22,11 +22,13 @@ + */ + #define AD7314_TEMP_MASK 0x7FE0 + #define AD7314_TEMP_SHIFT 5 ++#define AD7314_LEADING_ZEROS_MASK BIT(15) + + /* + * ADT7301 and ADT7302 temperature masks + */ + #define ADT7301_TEMP_MASK 0x3FFF ++#define ADT7301_LEADING_ZEROS_MASK (BIT(15) | BIT(14)) + + enum ad7314_variant { + adt7301, +@@ -65,12 +67,20 @@ static ssize_t ad7314_temperature_show(struct device *dev, + return ret; + switch (spi_get_device_id(chip->spi_dev)->driver_data) { + case ad7314: ++ if (ret & AD7314_LEADING_ZEROS_MASK) { ++ /* Invalid read-out, leading zero part is missing */ ++ return -EIO; ++ } + data = (ret & AD7314_TEMP_MASK) >> AD7314_TEMP_SHIFT; + data = sign_extend32(data, 9); + + return sprintf(buf, "%d\n", 250 * data); + case adt7301: + case adt7302: ++ if (ret & ADT7301_LEADING_ZEROS_MASK) { ++ /* Invalid read-out, leading zero part is missing */ ++ return -EIO; ++ } + /* + * Documented as a 13 bit twos complement register + * with a sign bit - which is a 14 bit 2's complement +diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c +index 4414c6b3132382..fe2f95aa97a6ed 100644 +--- a/drivers/hwmon/ntc_thermistor.c ++++ b/drivers/hwmon/ntc_thermistor.c +@@ -174,40 +174,40 @@ static const struct ntc_compensation ncpXXwf104[] = { + }; + + static const struct ntc_compensation ncpXXxh103[] = { +- { .temp_c = -40, .ohm = 247565 }, +- { .temp_c = -35, .ohm = 181742 }, +- { .temp_c = -30, .ohm = 135128 }, +- { .temp_c = -25, .ohm = 101678 }, +- { .temp_c = -20, .ohm = 77373 }, +- { .temp_c = -15, .ohm = 59504 }, +- { .temp_c = -10, .ohm = 46222 }, +- { .temp_c = -5, .ohm = 36244 }, +- { .temp_c = 0, .ohm = 28674 }, +- { .temp_c = 5, .ohm = 22878 }, +- { .temp_c = 10, .ohm = 18399 }, +- { .temp_c = 15, .ohm = 14910 }, +- { .temp_c = 20, .ohm = 12169 }, ++ { .temp_c = -40, .ohm = 195652 }, ++ { .temp_c = -35, .ohm = 148171 }, ++ { .temp_c = -30, .ohm = 113347 }, ++ { .temp_c = -25, .ohm = 87559 }, ++ { .temp_c = -20, .ohm = 68237 }, ++ { .temp_c = -15, .ohm = 53650 }, ++ { .temp_c = -10, .ohm = 42506 }, ++ { .temp_c = -5, .ohm = 33892 }, ++ { .temp_c = 0, .ohm = 27219 }, ++ { .temp_c = 5, .ohm = 22021 }, ++ { .temp_c = 10, .ohm = 17926 }, ++ { .temp_c = 15, .ohm = 14674 }, ++ { .temp_c = 20, .ohm = 12081 }, + { .temp_c = 25, .ohm = 10000 }, +- { .temp_c = 30, .ohm = 8271 }, +- { .temp_c = 35, .ohm = 6883 }, +- { .temp_c = 40, .ohm = 5762 }, +- { .temp_c = 45, .ohm = 4851 }, +- { .temp_c = 50, .ohm = 4105 }, +- { .temp_c = 55, .ohm = 3492 }, +- { .temp_c = 60, .ohm = 2985 }, +- { .temp_c = 65, .ohm = 2563 }, +- { .temp_c = 70, .ohm = 2211 }, +- { .temp_c = 75, .ohm = 1915 }, +- { .temp_c = 80, .ohm = 1666 }, +- { .temp_c = 85, .ohm = 1454 }, +- { .temp_c = 90, .ohm = 1275 }, +- { .temp_c = 95, .ohm = 1121 }, +- { .temp_c = 100, .ohm = 990 }, +- { .temp_c = 105, .ohm = 876 }, +- { .temp_c = 110, .ohm = 779 }, +- { .temp_c = 115, .ohm = 694 }, +- { .temp_c = 120, .ohm = 620 }, +- { .temp_c = 125, .ohm = 556 }, ++ { .temp_c = 30, .ohm = 8315 }, ++ { .temp_c = 35, .ohm = 6948 }, ++ { .temp_c = 40, .ohm = 5834 }, ++ { .temp_c = 45, .ohm = 4917 }, ++ { .temp_c = 50, .ohm = 4161 }, ++ { .temp_c = 55, .ohm = 3535 }, ++ { .temp_c = 60, .ohm = 3014 }, ++ { .temp_c = 65, .ohm = 2586 }, ++ { .temp_c = 70, .ohm = 2228 }, ++ { .temp_c = 75, .ohm = 1925 }, ++ { .temp_c = 80, .ohm = 1669 }, ++ { .temp_c = 85, .ohm = 1452 }, ++ { .temp_c = 90, .ohm = 1268 }, ++ { .temp_c = 95, .ohm = 1110 }, ++ { .temp_c = 100, .ohm = 974 }, ++ { .temp_c = 105, .ohm = 858 }, ++ { .temp_c = 110, .ohm = 758 }, ++ { .temp_c = 115, .ohm = 672 }, ++ { .temp_c = 120, .ohm = 596 }, ++ { .temp_c = 125, .ohm = 531 }, + }; + + /* +diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c +index d0d386990af5eb..6366610a908276 100644 +--- a/drivers/hwmon/pmbus/pmbus.c ++++ b/drivers/hwmon/pmbus/pmbus.c +@@ -103,6 +103,8 @@ static int pmbus_identify(struct i2c_client *client, + if (pmbus_check_byte_register(client, 0, PMBUS_PAGE)) { + int page; + ++ info->pages = PMBUS_PAGES; ++ + for (page = 1; page < PMBUS_PAGES; page++) { + if (pmbus_set_page(client, page, 0xff) < 0) + break; +diff --git a/drivers/hwmon/xgene-hwmon.c b/drivers/hwmon/xgene-hwmon.c +index a64f768bf18187..60a8ff56c38e92 100644 +--- a/drivers/hwmon/xgene-hwmon.c ++++ b/drivers/hwmon/xgene-hwmon.c +@@ -719,7 +719,7 @@ static int xgene_hwmon_probe(struct platform_device *pdev) + goto out; + } + +- if (!ctx->pcc_comm_addr) { ++ if (IS_ERR_OR_NULL(ctx->pcc_comm_addr)) { + dev_err(&pdev->dev, + "Failed to ioremap PCC comm region\n"); + rc = -ENOMEM; +diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c +index 8dad239aba2cea..e7985db1f29b36 100644 +--- a/drivers/hwtracing/intel_th/pci.c ++++ b/drivers/hwtracing/intel_th/pci.c +@@ -329,6 +329,21 @@ static const struct pci_device_id intel_th_pci_id_table[] = { + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa824), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, ++ { ++ /* Arrow Lake */ ++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7724), ++ .driver_data = (kernel_ulong_t)&intel_th_2x, ++ }, ++ { ++ /* Panther Lake-H */ ++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe324), ++ .driver_data = (kernel_ulong_t)&intel_th_2x, ++ }, ++ { ++ /* Panther Lake-P/U */ ++ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe424), ++ .driver_data = (kernel_ulong_t)&intel_th_2x, ++ }, + { + /* Alder Lake CPU */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f), +diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c +index 73c808ef1bfe5b..d97694ac29ca90 100644 +--- a/drivers/i2c/busses/i2c-npcm7xx.c ++++ b/drivers/i2c/busses/i2c-npcm7xx.c +@@ -2305,6 +2305,13 @@ static int npcm_i2c_probe_bus(struct platform_device *pdev) + if (irq < 0) + return irq; + ++ /* ++ * Disable the interrupt to avoid the interrupt handler being triggered ++ * incorrectly by the asynchronous interrupt status since the machine ++ * might do a warm reset during the last smbus/i2c transfer session. ++ */ ++ npcm_i2c_int_enable(bus, false); ++ + ret = devm_request_irq(bus->dev, irq, npcm_i2c_bus_irq, 0, + dev_name(bus->dev), bus); + if (ret) +diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c +index 6ce05441178a3d..8b06f5d4a4c309 100644 +--- a/drivers/i2c/i2c-core-acpi.c ++++ b/drivers/i2c/i2c-core-acpi.c +@@ -327,6 +327,25 @@ static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = { + {} + }; + ++static const struct acpi_device_id i2c_acpi_force_100khz_device_ids[] = { ++ /* ++ * When a 400KHz freq is used on this model of ELAN touchpad in Linux, ++ * excessive smoothing (similar to when the touchpad's firmware detects ++ * a noisy signal) is sometimes applied. As some devices' (e.g, Lenovo ++ * V15 G4) ACPI tables specify a 400KHz frequency for this device and ++ * some I2C busses (e.g, Designware I2C) default to a 400KHz freq, ++ * force the speed to 100KHz as a workaround. ++ * ++ * For future investigation: This problem may be related to the default ++ * HCNT/LCNT values given by some busses' drivers, because they are not ++ * specified in the aforementioned devices' ACPI tables, and because ++ * the device works without issues on Windows at what is expected to be ++ * a 400KHz frequency. The root cause of the issue is not known. ++ */ ++ { "ELAN06FA", 0 }, ++ {} ++}; ++ + static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level, + void *data, void **return_value) + { +@@ -348,6 +367,9 @@ static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level, + if (acpi_match_device_ids(adev, i2c_acpi_force_400khz_device_ids) == 0) + lookup->force_speed = I2C_MAX_FAST_MODE_FREQ; + ++ if (acpi_match_device_ids(adev, i2c_acpi_force_100khz_device_ids) == 0) ++ lookup->force_speed = I2C_MAX_STANDARD_MODE_FREQ; ++ + return AE_OK; + } + +diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c +index 376e631e80d697..359272ce8e294c 100644 +--- a/drivers/idle/intel_idle.c ++++ b/drivers/idle/intel_idle.c +@@ -56,6 +56,7 @@ + #include + #include + #include ++#include + + #define INTEL_IDLE_VERSION "0.5.1" + +@@ -1335,6 +1336,9 @@ static void __init intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) + if (intel_idle_state_needs_timer_stop(state)) + state->flags |= CPUIDLE_FLAG_TIMER_STOP; + ++ if (cx->type > ACPI_STATE_C1 && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) ++ mark_tsc_unstable("TSC halts in idle"); ++ + state->enter = intel_idle; + state->enter_s2idle = intel_idle_s2idle; + } +diff --git a/drivers/iio/light/as73211.c b/drivers/iio/light/as73211.c +index 3ba2378df3ddba..744432b87497a0 100644 +--- a/drivers/iio/light/as73211.c ++++ b/drivers/iio/light/as73211.c +@@ -154,6 +154,12 @@ struct as73211_data { + BIT(AS73211_SCAN_INDEX_TEMP) | \ + AS73211_SCAN_MASK_COLOR) + ++static const unsigned long as73211_scan_masks[] = { ++ AS73211_SCAN_MASK_COLOR, ++ AS73211_SCAN_MASK_ALL, ++ 0 ++}; ++ + static const struct iio_chan_spec as73211_channels[] = { + { + .type = IIO_TEMP, +@@ -602,9 +608,12 @@ static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p) + + /* AS73211 starts reading at address 2 */ + ret = i2c_master_recv(data->client, +- (char *)&scan.chan[1], 3 * sizeof(scan.chan[1])); ++ (char *)&scan.chan[0], 3 * sizeof(scan.chan[0])); + if (ret < 0) + goto done; ++ ++ /* Avoid pushing uninitialized data */ ++ scan.chan[3] = 0; + } + + if (data_result) { +@@ -612,9 +621,15 @@ static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p) + * Saturate all channels (in case of overflows). Temperature channel + * is not affected by overflows. + */ +- scan.chan[1] = cpu_to_le16(U16_MAX); +- scan.chan[2] = cpu_to_le16(U16_MAX); +- scan.chan[3] = cpu_to_le16(U16_MAX); ++ if (*indio_dev->active_scan_mask == AS73211_SCAN_MASK_ALL) { ++ scan.chan[1] = cpu_to_le16(U16_MAX); ++ scan.chan[2] = cpu_to_le16(U16_MAX); ++ scan.chan[3] = cpu_to_le16(U16_MAX); ++ } else { ++ scan.chan[0] = cpu_to_le16(U16_MAX); ++ scan.chan[1] = cpu_to_le16(U16_MAX); ++ scan.chan[2] = cpu_to_le16(U16_MAX); ++ } + } + + iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); +@@ -684,6 +699,7 @@ static int as73211_probe(struct i2c_client *client) + indio_dev->channels = as73211_channels; + indio_dev->num_channels = ARRAY_SIZE(as73211_channels); + indio_dev->modes = INDIO_DIRECT_MODE; ++ indio_dev->available_scan_masks = as73211_scan_masks; + + ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR); + if (ret < 0) +diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c +index 541dbcf22d0ebf..13e4b2c40d835a 100644 +--- a/drivers/infiniband/hw/cxgb4/device.c ++++ b/drivers/infiniband/hw/cxgb4/device.c +@@ -1114,8 +1114,10 @@ static inline struct sk_buff *copy_gl_to_skb_pkt(const struct pkt_gl *gl, + * The math here assumes sizeof cpl_pass_accept_req >= sizeof + * cpl_rx_pkt. + */ +- skb = alloc_skb(gl->tot_len + sizeof(struct cpl_pass_accept_req) + +- sizeof(struct rss_header) - pktshift, GFP_ATOMIC); ++ skb = alloc_skb(size_add(gl->tot_len, ++ sizeof(struct cpl_pass_accept_req) + ++ sizeof(struct rss_header)) - pktshift, ++ GFP_ATOMIC); + if (unlikely(!skb)) + return NULL; + +diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c +index 53d83212cda818..67a1ef0260b241 100644 +--- a/drivers/infiniband/hw/mlx4/main.c ++++ b/drivers/infiniband/hw/mlx4/main.c +@@ -392,10 +392,10 @@ static int mlx4_ib_del_gid(const struct ib_gid_attr *attr, void **context) + } + spin_unlock_bh(&iboe->lock); + +- if (!ret && hw_update) { ++ if (gids) + ret = mlx4_ib_update_gids(gids, ibdev, attr->port_num); +- kfree(gids); +- } ++ ++ kfree(gids); + return ret; + } + +diff --git a/drivers/infiniband/hw/mlx5/counters.c b/drivers/infiniband/hw/mlx5/counters.c +index 1a0ecf439c0992..870a0891981164 100644 +--- a/drivers/infiniband/hw/mlx5/counters.c ++++ b/drivers/infiniband/hw/mlx5/counters.c +@@ -337,6 +337,7 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter, + struct ib_qp *qp) + { + struct mlx5_ib_dev *dev = to_mdev(qp->device); ++ bool new = false; + int err; + + if (!counter->id) { +@@ -351,6 +352,7 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter, + return err; + counter->id = + MLX5_GET(alloc_q_counter_out, out, counter_set_id); ++ new = true; + } + + err = mlx5_ib_qp_set_counter(qp, counter); +@@ -360,8 +362,10 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter, + return 0; + + fail_set_counter: +- mlx5_ib_counter_dealloc(counter); +- counter->id = 0; ++ if (new) { ++ mlx5_ib_counter_dealloc(counter); ++ counter->id = 0; ++ } + + return err; + } +diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c +index ef3585af402631..55e28733512409 100644 +--- a/drivers/infiniband/hw/mlx5/devx.c ++++ b/drivers/infiniband/hw/mlx5/devx.c +@@ -1317,7 +1317,6 @@ static int devx_handle_mkey_indirect(struct devx_obj *obj, + mkey->key = mlx5_idx_to_mkey( + MLX5_GET(create_mkey_out, out, mkey_index)) | key; + mkey->type = MLX5_MKEY_INDIRECT_DEVX; +- mkey->iova = MLX5_GET64(mkc, mkc, start_addr); + mkey->size = MLX5_GET64(mkc, mkc, len); + mkey->pd = MLX5_GET(mkc, mkc, pd); + devx_mr->ndescs = MLX5_GET(mkc, mkc, translations_octword_size); +diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c +index 191078b6e91293..768aba0987cce5 100644 +--- a/drivers/infiniband/hw/mlx5/mr.c ++++ b/drivers/infiniband/hw/mlx5/mr.c +@@ -916,12 +916,13 @@ static struct mlx5_cache_ent *mr_cache_ent_from_order(struct mlx5_ib_dev *dev, + } + + static void set_mr_fields(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr, +- u64 length, int access_flags) ++ u64 length, int access_flags, u64 iova) + { + mr->ibmr.lkey = mr->mmkey.key; + mr->ibmr.rkey = mr->mmkey.key; + mr->ibmr.length = length; + mr->ibmr.device = &dev->ib_dev; ++ mr->ibmr.iova = iova; + mr->access_flags = access_flags; + } + +@@ -979,11 +980,10 @@ static struct mlx5_ib_mr *alloc_cacheable_mr(struct ib_pd *pd, + + mr->ibmr.pd = pd; + mr->umem = umem; +- mr->mmkey.iova = iova; + mr->mmkey.size = umem->length; + mr->mmkey.pd = to_mpd(pd)->pdn; + mr->page_shift = order_base_2(page_size); +- set_mr_fields(dev, mr, umem->length, access_flags); ++ set_mr_fields(dev, mr, umem->length, access_flags, iova); + + return mr; + } +@@ -1093,7 +1093,7 @@ static void *mlx5_ib_create_xlt_wr(struct mlx5_ib_mr *mr, + wr->pd = mr->ibmr.pd; + wr->mkey = mr->mmkey.key; + wr->length = mr->mmkey.size; +- wr->virt_addr = mr->mmkey.iova; ++ wr->virt_addr = mr->ibmr.iova; + wr->access_flags = mr->access_flags; + wr->page_shift = mr->page_shift; + wr->xlt_size = sg->length; +@@ -1345,7 +1345,7 @@ static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, struct ib_umem *umem, + } + mr->mmkey.type = MLX5_MKEY_MR; + mr->umem = umem; +- set_mr_fields(dev, mr, umem->length, access_flags); ++ set_mr_fields(dev, mr, umem->length, access_flags, iova); + kvfree(in); + + mlx5_ib_dbg(dev, "mkey = 0x%x\n", mr->mmkey.key); +@@ -1392,7 +1392,7 @@ static struct ib_mr *mlx5_ib_get_dm_mr(struct ib_pd *pd, u64 start_addr, + + kfree(in); + +- set_mr_fields(dev, mr, length, acc); ++ set_mr_fields(dev, mr, length, acc, start_addr); + + return &mr->ibmr; + +@@ -1769,7 +1769,7 @@ static int umr_rereg_pas(struct mlx5_ib_mr *mr, struct ib_pd *pd, + } + + mr->ibmr.length = new_umem->length; +- mr->mmkey.iova = iova; ++ mr->ibmr.iova = iova; + mr->mmkey.size = new_umem->length; + mr->page_shift = order_base_2(page_size); + mr->umem = new_umem; +@@ -1840,7 +1840,7 @@ struct ib_mr *mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, + mr->umem = NULL; + atomic_sub(ib_umem_num_pages(umem), &dev->mdev->priv.reg_pages); + +- return create_real_mr(new_pd, umem, mr->mmkey.iova, ++ return create_real_mr(new_pd, umem, mr->ibmr.iova, + new_access_flags); + } + +diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c +index 66e53e895d341c..ec18f8dda94f9c 100644 +--- a/drivers/infiniband/hw/mlx5/odp.c ++++ b/drivers/infiniband/hw/mlx5/odp.c +@@ -430,7 +430,7 @@ static struct mlx5_ib_mr *implicit_get_child_mr(struct mlx5_ib_mr *imr, + mr->umem = &odp->umem; + mr->ibmr.lkey = mr->mmkey.key; + mr->ibmr.rkey = mr->mmkey.key; +- mr->mmkey.iova = idx * MLX5_IMR_MTT_SIZE; ++ mr->ibmr.iova = idx * MLX5_IMR_MTT_SIZE; + mr->parent = imr; + odp->private = mr; + +@@ -500,7 +500,7 @@ struct mlx5_ib_mr *mlx5_ib_alloc_implicit_mr(struct mlx5_ib_pd *pd, + } + + imr->ibmr.pd = &pd->ibpd; +- imr->mmkey.iova = 0; ++ imr->ibmr.iova = 0; + imr->umem = &umem_odp->umem; + imr->ibmr.lkey = imr->mmkey.key; + imr->ibmr.rkey = imr->mmkey.key; +@@ -732,24 +732,31 @@ static int pagefault_dmabuf_mr(struct mlx5_ib_mr *mr, size_t bcnt, + * >0: Number of pages mapped + */ + static int pagefault_mr(struct mlx5_ib_mr *mr, u64 io_virt, size_t bcnt, +- u32 *bytes_mapped, u32 flags) ++ u32 *bytes_mapped, u32 flags, bool permissive_fault) + { + struct ib_umem_odp *odp = to_ib_umem_odp(mr->umem); + +- if (unlikely(io_virt < mr->mmkey.iova)) ++ if (unlikely(io_virt < mr->ibmr.iova) && !permissive_fault) + return -EFAULT; + + if (mr->umem->is_dmabuf) + return pagefault_dmabuf_mr(mr, bcnt, bytes_mapped, flags); + + if (!odp->is_implicit_odp) { ++ u64 offset = io_virt < mr->ibmr.iova ? 0 : io_virt - mr->ibmr.iova; + u64 user_va; + +- if (check_add_overflow(io_virt - mr->mmkey.iova, +- (u64)odp->umem.address, &user_va)) ++ if (check_add_overflow(offset, (u64)odp->umem.address, ++ &user_va)) + return -EFAULT; +- if (unlikely(user_va >= ib_umem_end(odp) || +- ib_umem_end(odp) - user_va < bcnt)) ++ ++ if (permissive_fault) { ++ if (user_va < ib_umem_start(odp)) ++ user_va = ib_umem_start(odp); ++ if ((user_va + bcnt) > ib_umem_end(odp)) ++ bcnt = ib_umem_end(odp) - user_va; ++ } else if (unlikely(user_va >= ib_umem_end(odp) || ++ ib_umem_end(odp) - user_va < bcnt)) + return -EFAULT; + return pagefault_real_mr(mr, odp, user_va, bcnt, bytes_mapped, + flags); +@@ -814,8 +821,7 @@ static int get_indirect_num_descs(struct mlx5_core_mkey *mmkey) + /* + * Handle a single data segment in a page-fault WQE or RDMA region. + * +- * Returns number of OS pages retrieved on success. The caller may continue to +- * the next data segment. ++ * Returns zero on success. The caller may continue to the next data segment. + * Can return the following error codes: + * -EAGAIN to designate a temporary error. The caller will abort handling the + * page fault and resolve it. +@@ -828,7 +834,7 @@ static int pagefault_single_data_segment(struct mlx5_ib_dev *dev, + u32 *bytes_committed, + u32 *bytes_mapped) + { +- int npages = 0, ret, i, outlen, cur_outlen = 0, depth = 0; ++ int ret, i, outlen, cur_outlen = 0, depth = 0, pages_in_range; + struct pf_frame *head = NULL, *frame; + struct mlx5_core_mkey *mmkey; + struct mlx5_ib_mr *mr; +@@ -872,13 +878,20 @@ static int pagefault_single_data_segment(struct mlx5_ib_dev *dev, + case MLX5_MKEY_MR: + mr = container_of(mmkey, struct mlx5_ib_mr, mmkey); + +- ret = pagefault_mr(mr, io_virt, bcnt, bytes_mapped, 0); ++ pages_in_range = (ALIGN(io_virt + bcnt, PAGE_SIZE) - ++ (io_virt & PAGE_MASK)) >> ++ PAGE_SHIFT; ++ ret = pagefault_mr(mr, io_virt, bcnt, bytes_mapped, 0, false); + if (ret < 0) + goto end; + + mlx5_update_odp_stats(mr, faults, ret); + +- npages += ret; ++ if (ret < pages_in_range) { ++ ret = -EFAULT; ++ goto end; ++ } ++ + ret = 0; + break; + +@@ -971,7 +984,7 @@ static int pagefault_single_data_segment(struct mlx5_ib_dev *dev, + kfree(out); + + *bytes_committed = 0; +- return ret ? ret : npages; ++ return ret; + } + + /* +@@ -990,8 +1003,7 @@ static int pagefault_single_data_segment(struct mlx5_ib_dev *dev, + * the committed bytes). + * @receive_queue: receive WQE end of sg list + * +- * Returns the number of pages loaded if positive, zero for an empty WQE, or a +- * negative error code. ++ * Returns zero for success or a negative error code. + */ + static int pagefault_data_segments(struct mlx5_ib_dev *dev, + struct mlx5_pagefault *pfault, +@@ -999,7 +1011,7 @@ static int pagefault_data_segments(struct mlx5_ib_dev *dev, + void *wqe_end, u32 *bytes_mapped, + u32 *total_wqe_bytes, bool receive_queue) + { +- int ret = 0, npages = 0; ++ int ret = 0; + u64 io_virt; + u32 key; + u32 byte_count; +@@ -1055,10 +1067,9 @@ static int pagefault_data_segments(struct mlx5_ib_dev *dev, + bytes_mapped); + if (ret < 0) + break; +- npages += ret; + } + +- return ret < 0 ? ret : npages; ++ return ret; + } + + /* +@@ -1294,12 +1305,6 @@ static void mlx5_ib_mr_wqe_pfault_handler(struct mlx5_ib_dev *dev, + free_page((unsigned long)wqe_start); + } + +-static int pages_in_range(u64 address, u32 length) +-{ +- return (ALIGN(address + length, PAGE_SIZE) - +- (address & PAGE_MASK)) >> PAGE_SHIFT; +-} +- + static void mlx5_ib_mr_rdma_pfault_handler(struct mlx5_ib_dev *dev, + struct mlx5_pagefault *pfault) + { +@@ -1338,7 +1343,7 @@ static void mlx5_ib_mr_rdma_pfault_handler(struct mlx5_ib_dev *dev, + if (ret == -EAGAIN) { + /* We're racing with an invalidation, don't prefetch */ + prefetch_activated = 0; +- } else if (ret < 0 || pages_in_range(address, length) > ret) { ++ } else if (ret < 0) { + mlx5_ib_page_fault_resume(dev, pfault, 1); + if (ret != -ENOENT) + mlx5_ib_dbg(dev, "PAGE FAULT error %d. QP 0x%x, type: 0x%x\n", +@@ -1743,7 +1748,7 @@ static void mlx5_ib_prefetch_mr_work(struct work_struct *w) + for (i = 0; i < work->num_sge; ++i) { + ret = pagefault_mr(work->frags[i].mr, work->frags[i].io_virt, + work->frags[i].length, &bytes_mapped, +- work->pf_flags); ++ work->pf_flags, false); + if (ret <= 0) + continue; + mlx5_update_odp_stats(work->frags[i].mr, prefetch, ret); +@@ -1792,7 +1797,7 @@ static int mlx5_ib_prefetch_sg_list(struct ib_pd *pd, + if (!mr) + return -ENOENT; + ret = pagefault_mr(mr, sg_list[i].addr, sg_list[i].length, +- &bytes_mapped, pf_flags); ++ &bytes_mapped, pf_flags, false); + if (ret < 0) { + mlx5r_deref_odp_mkey(&mr->mmkey); + return ret; +diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c +index d2b4db783b2540..d58ed4a09cd939 100644 +--- a/drivers/infiniband/hw/mlx5/qp.c ++++ b/drivers/infiniband/hw/mlx5/qp.c +@@ -4461,6 +4461,8 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr, + + set_id = mlx5_ib_get_counters_id(dev, attr->port_num - 1); + MLX5_SET(dctc, dctc, counter_set_id, set_id); ++ ++ qp->port = attr->port_num; + } else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) { + struct mlx5_ib_modify_qp_resp resp = {}; + u32 out[MLX5_ST_SZ_DW(create_dct_out)] = {}; +@@ -4949,7 +4951,7 @@ static int mlx5_ib_dct_query_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *mqp, + } + + if (qp_attr_mask & IB_QP_PORT) +- qp_attr->port_num = MLX5_GET(dctc, dctc, port); ++ qp_attr->port_num = mqp->port; + if (qp_attr_mask & IB_QP_MIN_RNR_TIMER) + qp_attr->min_rnr_timer = MLX5_GET(dctc, dctc, min_rnr_nak); + if (qp_attr_mask & IB_QP_AV) { +diff --git a/drivers/leds/leds-lp8860.c b/drivers/leds/leds-lp8860.c +index 3c693d5e3b44cd..fe3e7dfb5fdd21 100644 +--- a/drivers/leds/leds-lp8860.c ++++ b/drivers/leds/leds-lp8860.c +@@ -267,7 +267,7 @@ static int lp8860_init(struct lp8860_led *led) + goto out; + } + +- reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs) / sizeof(lp8860_eeprom_disp_regs[0]); ++ reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs); + for (i = 0; i < reg_count; i++) { + ret = regmap_write(led->eeprom_regmap, + lp8860_eeprom_disp_regs[i].reg, +diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c +index 77213b79f84d95..6692de0af68f1c 100644 +--- a/drivers/leds/leds-netxbig.c ++++ b/drivers/leds/leds-netxbig.c +@@ -440,6 +440,7 @@ static int netxbig_leds_get_of_pdata(struct device *dev, + } + gpio_ext_pdev = of_find_device_by_node(gpio_ext_np); + if (!gpio_ext_pdev) { ++ of_node_put(gpio_ext_np); + dev_err(dev, "Failed to find platform device for gpio-ext\n"); + return -ENODEV; + } +diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig +index f45fb372e51be1..4440d026e5efd8 100644 +--- a/drivers/md/Kconfig ++++ b/drivers/md/Kconfig +@@ -16,6 +16,10 @@ if MD + config BLK_DEV_MD + tristate "RAID support" + select BLOCK_HOLDER_DEPRECATED if SYSFS ++ # BLOCK_LEGACY_AUTOLOAD requirement should be removed ++ # after relevant mdadm enhancements - to make "names=yes" ++ # the default - are widely available. ++ select BLOCK_LEGACY_AUTOLOAD + help + This driver lets you combine several hard disk partitions into one + logical block device. This can be used to simply append one +diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c +index 6e392f3cbd3731..abc13c8dc4ed49 100644 +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -53,6 +53,7 @@ struct convert_context { + struct bio *bio_out; + struct bvec_iter iter_out; + atomic_t cc_pending; ++ unsigned int tag_offset; + u64 cc_sector; + union { + struct skcipher_request *req; +@@ -1217,6 +1218,7 @@ static void crypt_convert_init(struct crypt_config *cc, + if (bio_out) + ctx->iter_out = bio_out->bi_iter; + ctx->cc_sector = sector + cc->iv_offset; ++ ctx->tag_offset = 0; + init_completion(&ctx->restart); + } + +@@ -1542,7 +1544,6 @@ static void crypt_free_req(struct crypt_config *cc, void *req, struct bio *base_ + static blk_status_t crypt_convert(struct crypt_config *cc, + struct convert_context *ctx, bool atomic, bool reset_pending) + { +- unsigned int tag_offset = 0; + unsigned int sector_step = cc->sector_size >> SECTOR_SHIFT; + int r; + +@@ -1565,9 +1566,9 @@ static blk_status_t crypt_convert(struct crypt_config *cc, + atomic_inc(&ctx->cc_pending); + + if (crypt_integrity_aead(cc)) +- r = crypt_convert_block_aead(cc, ctx, ctx->r.req_aead, tag_offset); ++ r = crypt_convert_block_aead(cc, ctx, ctx->r.req_aead, ctx->tag_offset); + else +- r = crypt_convert_block_skcipher(cc, ctx, ctx->r.req, tag_offset); ++ r = crypt_convert_block_skcipher(cc, ctx, ctx->r.req, ctx->tag_offset); + + switch (r) { + /* +@@ -1587,8 +1588,8 @@ static blk_status_t crypt_convert(struct crypt_config *cc, + * exit and continue processing in a workqueue + */ + ctx->r.req = NULL; ++ ctx->tag_offset++; + ctx->cc_sector += sector_step; +- tag_offset++; + return BLK_STS_DEV_RESOURCE; + } + } else { +@@ -1602,8 +1603,8 @@ static blk_status_t crypt_convert(struct crypt_config *cc, + */ + case -EINPROGRESS: + ctx->r.req = NULL; ++ ctx->tag_offset++; + ctx->cc_sector += sector_step; +- tag_offset++; + continue; + /* + * The request was already processed (synchronously). +@@ -1611,7 +1612,7 @@ static blk_status_t crypt_convert(struct crypt_config *cc, + case 0: + atomic_dec(&ctx->cc_pending); + ctx->cc_sector += sector_step; +- tag_offset++; ++ ctx->tag_offset++; + if (!atomic) + cond_resched(); + continue; +@@ -1993,7 +1994,6 @@ static void kcryptd_crypt_write_continue(struct work_struct *work) + struct crypt_config *cc = io->cc; + struct convert_context *ctx = &io->ctx; + int crypt_finished; +- sector_t sector = io->sector; + blk_status_t r; + + wait_for_completion(&ctx->restart); +@@ -2010,10 +2010,8 @@ static void kcryptd_crypt_write_continue(struct work_struct *work) + } + + /* Encryption was already finished, submit io now */ +- if (crypt_finished) { ++ if (crypt_finished) + kcryptd_crypt_write_io_submit(io, 0); +- io->sector = sector; +- } + + crypt_dec_pending(io); + } +@@ -2024,14 +2022,13 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) + struct convert_context *ctx = &io->ctx; + struct bio *clone; + int crypt_finished; +- sector_t sector = io->sector; + blk_status_t r; + + /* + * Prevent io from disappearing until this function completes. + */ + crypt_inc_pending(io); +- crypt_convert_init(cc, ctx, NULL, io->base_bio, sector); ++ crypt_convert_init(cc, ctx, NULL, io->base_bio, io->sector); + + clone = crypt_alloc_buffer(io, io->base_bio->bi_iter.bi_size); + if (unlikely(!clone)) { +@@ -2048,8 +2045,6 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) + io->ctx.iter_in = clone->bi_iter; + } + +- sector += bio_sectors(clone); +- + crypt_inc_pending(io); + r = crypt_convert(cc, ctx, + test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags), true); +@@ -2073,10 +2068,8 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io) + } + + /* Encryption was already finished, submit io now */ +- if (crypt_finished) { ++ if (crypt_finished) + kcryptd_crypt_write_io_submit(io, 0); +- io->sector = sector; +- } + + dec: + crypt_dec_pending(io); +diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c +index e9d1eef40c627d..798da504213684 100644 +--- a/drivers/media/dvb-frontends/cxd2841er.c ++++ b/drivers/media/dvb-frontends/cxd2841er.c +@@ -311,12 +311,8 @@ static int cxd2841er_set_reg_bits(struct cxd2841er_priv *priv, + + static u32 cxd2841er_calc_iffreq_xtal(enum cxd2841er_xtal xtal, u32 ifhz) + { +- u64 tmp; +- +- tmp = (u64) ifhz * 16777216; +- do_div(tmp, ((xtal == SONY_XTAL_24000) ? 48000000 : 41000000)); +- +- return (u32) tmp; ++ return div_u64(ifhz * 16777216ull, ++ (xtal == SONY_XTAL_24000) ? 48000000 : 41000000); + } + + static u32 cxd2841er_calc_iffreq(u32 ifhz) +diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c +index 9dc5d42b319939..ca831b4db48461 100644 +--- a/drivers/media/i2c/ccs/ccs-core.c ++++ b/drivers/media/i2c/ccs/ccs-core.c +@@ -3652,15 +3652,15 @@ static int ccs_probe(struct i2c_client *client) + out_cleanup: + ccs_cleanup(sensor); + ++out_free_ccs_limits: ++ kfree(sensor->ccs_limits); ++ + out_release_mdata: + kvfree(sensor->mdata.backing); + + out_release_sdata: + kvfree(sensor->sdata.backing); + +-out_free_ccs_limits: +- kfree(sensor->ccs_limits); +- + out_power_off: + ccs_power_off(&client->dev); + mutex_destroy(&sensor->mutex); +diff --git a/drivers/media/i2c/ccs/ccs-data.c b/drivers/media/i2c/ccs/ccs-data.c +index 08400edf77ced1..2591dba51e17e2 100644 +--- a/drivers/media/i2c/ccs/ccs-data.c ++++ b/drivers/media/i2c/ccs/ccs-data.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include "ccs-data-defs.h" + +@@ -97,7 +98,7 @@ ccs_data_parse_length_specifier(const struct __ccs_data_length_specifier *__len, + plen = ((size_t) + (__len3->length[0] & + ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1)) +- << 16) + (__len3->length[0] << 8) + __len3->length[1]; ++ << 16) + (__len3->length[1] << 8) + __len3->length[2]; + break; + } + default: +@@ -948,15 +949,15 @@ int ccs_data_parse(struct ccs_data_container *ccsdata, const void *data, + + rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, verbose); + if (rval) +- return rval; ++ goto out_cleanup; + + rval = bin_backing_alloc(&bin); + if (rval) +- return rval; ++ goto out_cleanup; + + rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, false); + if (rval) +- goto out_free; ++ goto out_cleanup; + + if (verbose && ccsdata->version) + print_ccs_data_version(dev, ccsdata->version); +@@ -965,15 +966,16 @@ int ccs_data_parse(struct ccs_data_container *ccsdata, const void *data, + rval = -EPROTO; + dev_dbg(dev, "parsing mismatch; base %p; now %p; end %p\n", + bin.base, bin.now, bin.end); +- goto out_free; ++ goto out_cleanup; + } + + ccsdata->backing = bin.base; + + return 0; + +-out_free: ++out_cleanup: + kvfree(bin.base); ++ memset(ccsdata, 0, sizeof(*ccsdata)); + + return rval; + } +diff --git a/drivers/media/i2c/imx412.c b/drivers/media/i2c/imx412.c +index 3d4d813923918a..5e7ccbc8dfecda 100644 +--- a/drivers/media/i2c/imx412.c ++++ b/drivers/media/i2c/imx412.c +@@ -540,7 +540,7 @@ static int imx412_update_exp_gain(struct imx412 *imx412, u32 exposure, u32 gain) + + lpfr = imx412->vblank + imx412->cur_mode->height; + +- dev_dbg(imx412->dev, "Set exp %u, analog gain %u, lpfr %u", ++ dev_dbg(imx412->dev, "Set exp %u, analog gain %u, lpfr %u\n", + exposure, gain, lpfr); + + ret = imx412_write_reg(imx412, IMX412_REG_HOLD, 1, 1); +@@ -587,7 +587,7 @@ static int imx412_set_ctrl(struct v4l2_ctrl *ctrl) + case V4L2_CID_VBLANK: + imx412->vblank = imx412->vblank_ctrl->val; + +- dev_dbg(imx412->dev, "Received vblank %u, new lpfr %u", ++ dev_dbg(imx412->dev, "Received vblank %u, new lpfr %u\n", + imx412->vblank, + imx412->vblank + imx412->cur_mode->height); + +@@ -606,7 +606,7 @@ static int imx412_set_ctrl(struct v4l2_ctrl *ctrl) + exposure = ctrl->val; + analog_gain = imx412->again_ctrl->val; + +- dev_dbg(imx412->dev, "Received exp %u, analog gain %u", ++ dev_dbg(imx412->dev, "Received exp %u, analog gain %u\n", + exposure, analog_gain); + + ret = imx412_update_exp_gain(imx412, exposure, analog_gain); +@@ -615,7 +615,7 @@ static int imx412_set_ctrl(struct v4l2_ctrl *ctrl) + + break; + default: +- dev_err(imx412->dev, "Invalid control %d", ctrl->id); ++ dev_err(imx412->dev, "Invalid control %d\n", ctrl->id); + ret = -EINVAL; + } + +@@ -796,14 +796,14 @@ static int imx412_start_streaming(struct imx412 *imx412) + ret = imx412_write_regs(imx412, reg_list->regs, + reg_list->num_of_regs); + if (ret) { +- dev_err(imx412->dev, "fail to write initial registers"); ++ dev_err(imx412->dev, "fail to write initial registers\n"); + return ret; + } + + /* Setup handler will write actual exposure and gain */ + ret = __v4l2_ctrl_handler_setup(imx412->sd.ctrl_handler); + if (ret) { +- dev_err(imx412->dev, "fail to setup handler"); ++ dev_err(imx412->dev, "fail to setup handler\n"); + return ret; + } + +@@ -814,7 +814,7 @@ static int imx412_start_streaming(struct imx412 *imx412) + ret = imx412_write_reg(imx412, IMX412_REG_MODE_SELECT, + 1, IMX412_MODE_STREAMING); + if (ret) { +- dev_err(imx412->dev, "fail to start streaming"); ++ dev_err(imx412->dev, "fail to start streaming\n"); + return ret; + } + +@@ -895,7 +895,7 @@ static int imx412_detect(struct imx412 *imx412) + return ret; + + if (val != IMX412_ID) { +- dev_err(imx412->dev, "chip id mismatch: %x!=%x", ++ dev_err(imx412->dev, "chip id mismatch: %x!=%x\n", + IMX412_ID, val); + return -ENXIO; + } +@@ -927,7 +927,7 @@ static int imx412_parse_hw_config(struct imx412 *imx412) + imx412->reset_gpio = devm_gpiod_get_optional(imx412->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(imx412->reset_gpio)) { +- dev_err(imx412->dev, "failed to get reset gpio %ld", ++ dev_err(imx412->dev, "failed to get reset gpio %ld\n", + PTR_ERR(imx412->reset_gpio)); + return PTR_ERR(imx412->reset_gpio); + } +@@ -935,13 +935,13 @@ static int imx412_parse_hw_config(struct imx412 *imx412) + /* Get sensor input clock */ + imx412->inclk = devm_clk_get(imx412->dev, NULL); + if (IS_ERR(imx412->inclk)) { +- dev_err(imx412->dev, "could not get inclk"); ++ dev_err(imx412->dev, "could not get inclk\n"); + return PTR_ERR(imx412->inclk); + } + + rate = clk_get_rate(imx412->inclk); + if (rate != IMX412_INCLK_RATE) { +- dev_err(imx412->dev, "inclk frequency mismatch"); ++ dev_err(imx412->dev, "inclk frequency mismatch\n"); + return -EINVAL; + } + +@@ -956,14 +956,14 @@ static int imx412_parse_hw_config(struct imx412 *imx412) + + if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX412_NUM_DATA_LANES) { + dev_err(imx412->dev, +- "number of CSI2 data lanes %d is not supported", ++ "number of CSI2 data lanes %d is not supported\n", + bus_cfg.bus.mipi_csi2.num_data_lanes); + ret = -EINVAL; + goto done_endpoint_free; + } + + if (!bus_cfg.nr_of_link_frequencies) { +- dev_err(imx412->dev, "no link frequencies defined"); ++ dev_err(imx412->dev, "no link frequencies defined\n"); + ret = -EINVAL; + goto done_endpoint_free; + } +@@ -1014,7 +1014,7 @@ static int imx412_power_on(struct device *dev) + + ret = clk_prepare_enable(imx412->inclk); + if (ret) { +- dev_err(imx412->dev, "fail to enable inclk"); ++ dev_err(imx412->dev, "fail to enable inclk\n"); + goto error_reset; + } + +@@ -1120,7 +1120,7 @@ static int imx412_init_controls(struct imx412 *imx412) + imx412->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + if (ctrl_hdlr->error) { +- dev_err(imx412->dev, "control init failed: %d", ++ dev_err(imx412->dev, "control init failed: %d\n", + ctrl_hdlr->error); + v4l2_ctrl_handler_free(ctrl_hdlr); + return ctrl_hdlr->error; +@@ -1153,7 +1153,7 @@ static int imx412_probe(struct i2c_client *client) + + ret = imx412_parse_hw_config(imx412); + if (ret) { +- dev_err(imx412->dev, "HW configuration is not supported"); ++ dev_err(imx412->dev, "HW configuration is not supported\n"); + return ret; + } + +@@ -1161,14 +1161,14 @@ static int imx412_probe(struct i2c_client *client) + + ret = imx412_power_on(imx412->dev); + if (ret) { +- dev_err(imx412->dev, "failed to power-on the sensor"); ++ dev_err(imx412->dev, "failed to power-on the sensor\n"); + goto error_mutex_destroy; + } + + /* Check module identity */ + ret = imx412_detect(imx412); + if (ret) { +- dev_err(imx412->dev, "failed to find sensor: %d", ret); ++ dev_err(imx412->dev, "failed to find sensor: %d\n", ret); + goto error_power_off; + } + +@@ -1178,7 +1178,7 @@ static int imx412_probe(struct i2c_client *client) + + ret = imx412_init_controls(imx412); + if (ret) { +- dev_err(imx412->dev, "failed to init controls: %d", ret); ++ dev_err(imx412->dev, "failed to init controls: %d\n", ret); + goto error_power_off; + } + +@@ -1190,14 +1190,14 @@ static int imx412_probe(struct i2c_client *client) + imx412->pad.flags = MEDIA_PAD_FL_SOURCE; + ret = media_entity_pads_init(&imx412->sd.entity, 1, &imx412->pad); + if (ret) { +- dev_err(imx412->dev, "failed to init entity pads: %d", ret); ++ dev_err(imx412->dev, "failed to init entity pads: %d\n", ret); + goto error_handler_free; + } + + ret = v4l2_async_register_subdev_sensor(&imx412->sd); + if (ret < 0) { + dev_err(imx412->dev, +- "failed to register async subdev: %d", ret); ++ "failed to register async subdev: %d\n", ret); + goto error_media_entity; + } + +diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c +index 13144e87f47a1b..077f54ba83275d 100644 +--- a/drivers/media/i2c/ov5640.c ++++ b/drivers/media/i2c/ov5640.c +@@ -1406,6 +1406,7 @@ static int ov5640_get_light_freq(struct ov5640_dev *sensor) + light_freq = 50; + } else { + /* 60Hz */ ++ light_freq = 60; + } + } + +diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c +index 2e0b315801e566..5bc9fafa72a4b1 100644 +--- a/drivers/media/i2c/ov9282.c ++++ b/drivers/media/i2c/ov9282.c +@@ -31,7 +31,7 @@ + /* Exposure control */ + #define OV9282_REG_EXPOSURE 0x3500 + #define OV9282_EXPOSURE_MIN 1 +-#define OV9282_EXPOSURE_OFFSET 12 ++#define OV9282_EXPOSURE_OFFSET 25 + #define OV9282_EXPOSURE_STEP 1 + #define OV9282_EXPOSURE_DEFAULT 0x0282 + +diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c +index 32b23329b03310..51467ddff185be 100644 +--- a/drivers/media/platform/exynos4-is/mipi-csis.c ++++ b/drivers/media/platform/exynos4-is/mipi-csis.c +@@ -942,13 +942,19 @@ static int s5pcsis_pm_resume(struct device *dev, bool runtime) + state->supplies); + goto unlock; + } +- clk_enable(state->clock[CSIS_CLK_GATE]); ++ ret = clk_enable(state->clock[CSIS_CLK_GATE]); ++ if (ret) { ++ phy_power_off(state->phy); ++ regulator_bulk_disable(CSIS_NUM_SUPPLIES, ++ state->supplies); ++ goto unlock; ++ } + } + if (state->flags & ST_STREAMING) + s5pcsis_start_stream(state); + + state->flags &= ~ST_SUSPENDED; +- unlock: ++unlock: + mutex_unlock(&state->lock); + return ret ? -EAGAIN : 0; + } +diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c +index 8ac844db0e8330..059e45aa03b7f2 100644 +--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c ++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c +@@ -1997,11 +1997,12 @@ static void mxc_jpeg_detach_pm_domains(struct mxc_jpeg_dev *jpeg) + int i; + + for (i = 0; i < jpeg->num_domains; i++) { +- if (jpeg->pd_dev[i] && !pm_runtime_suspended(jpeg->pd_dev[i])) ++ if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]) && ++ !pm_runtime_suspended(jpeg->pd_dev[i])) + pm_runtime_force_suspend(jpeg->pd_dev[i]); +- if (jpeg->pd_link[i] && !IS_ERR(jpeg->pd_link[i])) ++ if (!IS_ERR_OR_NULL(jpeg->pd_link[i])) + device_link_del(jpeg->pd_link[i]); +- if (jpeg->pd_dev[i] && !IS_ERR(jpeg->pd_dev[i])) ++ if (!IS_ERR_OR_NULL(jpeg->pd_dev[i])) + dev_pm_domain_detach(jpeg->pd_dev[i], true); + jpeg->pd_dev[i] = NULL; + jpeg->pd_link[i] = NULL; +diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c +index 58f9463f3b8ce5..a8d3ed5dc206f0 100644 +--- a/drivers/media/platform/marvell-ccic/mcam-core.c ++++ b/drivers/media/platform/marvell-ccic/mcam-core.c +@@ -935,7 +935,12 @@ static int mclk_enable(struct clk_hw *hw) + ret = pm_runtime_resume_and_get(cam->dev); + if (ret < 0) + return ret; +- clk_enable(cam->clk[0]); ++ ret = clk_enable(cam->clk[0]); ++ if (ret) { ++ pm_runtime_put(cam->dev); ++ return ret; ++ } ++ + mcam_reg_write(cam, REG_CLKCTRL, (mclk_src << 29) | mclk_div); + mcam_ctlr_power_up(cam); + +diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c +index e1d51fd3e7008e..e4c8e3f19626db 100644 +--- a/drivers/media/platform/s3c-camif/camif-core.c ++++ b/drivers/media/platform/s3c-camif/camif-core.c +@@ -532,10 +532,19 @@ static int s3c_camif_remove(struct platform_device *pdev) + static int s3c_camif_runtime_resume(struct device *dev) + { + struct camif_dev *camif = dev_get_drvdata(dev); ++ int ret; ++ ++ ret = clk_enable(camif->clock[CLK_GATE]); ++ if (ret) ++ return ret; + +- clk_enable(camif->clock[CLK_GATE]); + /* null op on s3c244x */ +- clk_enable(camif->clock[CLK_CAM]); ++ ret = clk_enable(camif->clock[CLK_CAM]); ++ if (ret) { ++ clk_disable(camif->clock[CLK_GATE]); ++ return ret; ++ } ++ + return 0; + } + +diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c +index 84949baf9f6b3c..c1343df0dbbab6 100644 +--- a/drivers/media/rc/iguanair.c ++++ b/drivers/media/rc/iguanair.c +@@ -197,8 +197,10 @@ static int iguanair_send(struct iguanair *ir, unsigned size) + if (rc) + return rc; + +- if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0) ++ if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0) { ++ usb_kill_urb(ir->urb_out); + return -ETIMEDOUT; ++ } + + return rc; + } +diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c +index dff7265a42ca20..c1621680ec570e 100644 +--- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c ++++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c +@@ -191,10 +191,11 @@ static int vidtv_start_streaming(struct vidtv_dvb *dvb) + + mux_args.mux_buf_sz = mux_buf_sz; + +- dvb->streaming = true; + dvb->mux = vidtv_mux_init(dvb->fe[0], dev, &mux_args); + if (!dvb->mux) + return -ENOMEM; ++ ++ dvb->streaming = true; + vidtv_mux_start_thread(dvb->mux); + + dev_dbg_ratelimited(dev, "Started streaming\n"); +@@ -205,6 +206,11 @@ static int vidtv_stop_streaming(struct vidtv_dvb *dvb) + { + struct device *dev = &dvb->pdev->dev; + ++ if (!dvb->streaming) { ++ dev_warn_ratelimited(dev, "No streaming. Skipping.\n"); ++ return 0; ++ } ++ + dvb->streaming = false; + vidtv_mux_stop_thread(dvb->mux); + vidtv_mux_destroy(dvb->mux); +diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c +index fe4d886442a415..220df46f56c57e 100644 +--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c ++++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c +@@ -373,6 +373,7 @@ static int lme2510_int_read(struct dvb_usb_adapter *adap) + struct dvb_usb_device *d = adap_to_d(adap); + struct lme2510_state *lme_int = adap_to_priv(adap); + struct usb_host_endpoint *ep; ++ int ret; + + lme_int->lme_urb = usb_alloc_urb(0, GFP_KERNEL); + +@@ -390,11 +391,20 @@ static int lme2510_int_read(struct dvb_usb_adapter *adap) + + /* Quirk of pipe reporting PIPE_BULK but behaves as interrupt */ + ep = usb_pipe_endpoint(d->udev, lme_int->lme_urb->pipe); ++ if (!ep) { ++ usb_free_urb(lme_int->lme_urb); ++ return -ENODEV; ++ } + + if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK) + lme_int->lme_urb->pipe = usb_rcvbulkpipe(d->udev, 0xa); + +- usb_submit_urb(lme_int->lme_urb, GFP_KERNEL); ++ ret = usb_submit_urb(lme_int->lme_urb, GFP_KERNEL); ++ if (ret) { ++ usb_free_urb(lme_int->lme_urb); ++ return ret; ++ } ++ + info("INT Interrupt Service Started"); + + return 0; +diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c +index 050d3342658282..b615d319196d1c 100644 +--- a/drivers/media/usb/uvc/uvc_ctrl.c ++++ b/drivers/media/usb/uvc/uvc_ctrl.c +@@ -1417,6 +1417,40 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain, + uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes); + } + ++static void uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl, ++ struct uvc_fh *new_handle) ++{ ++ lockdep_assert_held(&handle->chain->ctrl_mutex); ++ ++ if (new_handle) { ++ if (ctrl->handle) ++ dev_warn_ratelimited(&handle->stream->dev->udev->dev, ++ "UVC non compliance: Setting an async control with a pending operation."); ++ ++ if (new_handle == ctrl->handle) ++ return; ++ ++ if (ctrl->handle) { ++ WARN_ON(!ctrl->handle->pending_async_ctrls); ++ if (ctrl->handle->pending_async_ctrls) ++ ctrl->handle->pending_async_ctrls--; ++ } ++ ++ ctrl->handle = new_handle; ++ handle->pending_async_ctrls++; ++ return; ++ } ++ ++ /* Cannot clear the handle for a control not owned by us.*/ ++ if (WARN_ON(ctrl->handle != handle)) ++ return; ++ ++ ctrl->handle = NULL; ++ if (WARN_ON(!handle->pending_async_ctrls)) ++ return; ++ handle->pending_async_ctrls--; ++} ++ + void uvc_ctrl_status_event(struct uvc_video_chain *chain, + struct uvc_control *ctrl, const u8 *data) + { +@@ -1427,7 +1461,8 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain, + mutex_lock(&chain->ctrl_mutex); + + handle = ctrl->handle; +- ctrl->handle = NULL; ++ if (handle) ++ uvc_ctrl_set_handle(handle, ctrl, NULL); + + list_for_each_entry(mapping, &ctrl->info.mappings, list) { + s32 value = __uvc_ctrl_get_value(mapping, data); +@@ -1478,10 +1513,8 @@ bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain, + struct uvc_device *dev = chain->dev; + struct uvc_ctrl_work *w = &dev->async_ctrl; + +- if (list_empty(&ctrl->info.mappings)) { +- ctrl->handle = NULL; ++ if (list_empty(&ctrl->info.mappings)) + return false; +- } + + w->data = data; + w->urb = urb; +@@ -1511,13 +1544,13 @@ static void uvc_ctrl_send_events(struct uvc_fh *handle, + { + struct uvc_control_mapping *mapping; + struct uvc_control *ctrl; +- u32 changes = V4L2_EVENT_CTRL_CH_VALUE; + unsigned int i; + unsigned int j; + + for (i = 0; i < xctrls_count; ++i) { +- ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping); ++ u32 changes = V4L2_EVENT_CTRL_CH_VALUE; + ++ ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping); + if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) + /* Notification will be sent from an Interrupt event. */ + continue; +@@ -1647,7 +1680,10 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain) + } + + static int uvc_ctrl_commit_entity(struct uvc_device *dev, +- struct uvc_entity *entity, int rollback) ++ struct uvc_fh *handle, ++ struct uvc_entity *entity, ++ int rollback, ++ struct uvc_control **err_ctrl) + { + struct uvc_control *ctrl; + unsigned int i; +@@ -1689,30 +1725,64 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, + + ctrl->dirty = 0; + +- if (ret < 0) ++ if (ret < 0) { ++ if (err_ctrl) ++ *err_ctrl = ctrl; + return ret; ++ } ++ ++ if (!rollback && handle && ++ ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) ++ uvc_ctrl_set_handle(handle, ctrl, handle); + } + + return 0; + } + ++static int uvc_ctrl_find_ctrl_idx(struct uvc_entity *entity, ++ struct v4l2_ext_controls *ctrls, ++ struct uvc_control *uvc_control) ++{ ++ struct uvc_control_mapping *mapping = NULL; ++ struct uvc_control *ctrl_found = NULL; ++ unsigned int i; ++ ++ if (!entity) ++ return ctrls->count; ++ ++ for (i = 0; i < ctrls->count; i++) { ++ __uvc_find_control(entity, ctrls->controls[i].id, &mapping, ++ &ctrl_found, 0); ++ if (uvc_control == ctrl_found) ++ return i; ++ } ++ ++ return ctrls->count; ++} ++ + int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, +- const struct v4l2_ext_control *xctrls, +- unsigned int xctrls_count) ++ struct v4l2_ext_controls *ctrls) + { + struct uvc_video_chain *chain = handle->chain; ++ struct uvc_control *err_ctrl; + struct uvc_entity *entity; + int ret = 0; + + /* Find the control. */ + list_for_each_entry(entity, &chain->entities, chain) { +- ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback); +- if (ret < 0) ++ ret = uvc_ctrl_commit_entity(chain->dev, handle, entity, ++ rollback, &err_ctrl); ++ if (ret < 0) { ++ if (ctrls) ++ ctrls->error_idx = ++ uvc_ctrl_find_ctrl_idx(entity, ctrls, ++ err_ctrl); + goto done; ++ } + } + + if (!rollback) +- uvc_ctrl_send_events(handle, xctrls, xctrls_count); ++ uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count); + done: + mutex_unlock(&chain->ctrl_mutex); + return ret; +@@ -1836,9 +1906,6 @@ int uvc_ctrl_set(struct uvc_fh *handle, + mapping->set(mapping, value, + uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); + +- if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) +- ctrl->handle = handle; +- + ctrl->dirty = 1; + ctrl->modified = 1; + return 0; +@@ -2011,7 +2078,7 @@ static int uvc_ctrl_init_xu_ctrl(struct uvc_device *dev, + int uvc_xu_ctrl_query(struct uvc_video_chain *chain, + struct uvc_xu_control_query *xqry) + { +- struct uvc_entity *entity; ++ struct uvc_entity *entity, *iter; + struct uvc_control *ctrl; + unsigned int i; + bool found; +@@ -2021,16 +2088,16 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, + int ret; + + /* Find the extension unit. */ +- found = false; +- list_for_each_entry(entity, &chain->entities, chain) { +- if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT && +- entity->id == xqry->unit) { +- found = true; ++ entity = NULL; ++ list_for_each_entry(iter, &chain->entities, chain) { ++ if (UVC_ENTITY_TYPE(iter) == UVC_VC_EXTENSION_UNIT && ++ iter->id == xqry->unit) { ++ entity = iter; + break; + } + } + +- if (!found) { ++ if (!entity) { + uvc_dbg(chain->dev, CONTROL, "Extension unit %u not found\n", + xqry->unit); + return -ENOENT; +@@ -2167,7 +2234,7 @@ int uvc_ctrl_restore_values(struct uvc_device *dev) + ctrl->dirty = 1; + } + +- ret = uvc_ctrl_commit_entity(dev, entity, 0); ++ ret = uvc_ctrl_commit_entity(dev, NULL, entity, 0, NULL); + if (ret < 0) + return ret; + } +@@ -2520,6 +2587,30 @@ int uvc_ctrl_init_device(struct uvc_device *dev) + return 0; + } + ++void uvc_ctrl_cleanup_fh(struct uvc_fh *handle) ++{ ++ struct uvc_entity *entity; ++ ++ mutex_lock(&handle->chain->ctrl_mutex); ++ ++ if (!handle->pending_async_ctrls) { ++ mutex_unlock(&handle->chain->ctrl_mutex); ++ return; ++ } ++ ++ list_for_each_entry(entity, &handle->chain->dev->entities, list) { ++ unsigned int i; ++ for (i = 0; i < entity->ncontrols; ++i) { ++ if (entity->controls[i].handle != handle) ++ continue; ++ uvc_ctrl_set_handle(handle, &entity->controls[i], NULL); ++ } ++ } ++ ++ WARN_ON(handle->pending_async_ctrls); ++ mutex_unlock(&handle->chain->ctrl_mutex); ++} ++ + /* + * Cleanup device controls. + */ +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 1942b9e210cc0f..426b5cf3177620 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -1026,27 +1026,14 @@ static const u8 uvc_media_transport_input_guid[16] = + UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT; + static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING; + +-static struct uvc_entity *uvc_alloc_new_entity(struct uvc_device *dev, u16 type, +- u16 id, unsigned int num_pads, +- unsigned int extra_size) ++static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id, ++ unsigned int num_pads, unsigned int extra_size) + { + struct uvc_entity *entity; + unsigned int num_inputs; + unsigned int size; + unsigned int i; + +- /* Per UVC 1.1+ spec 3.7.2, the ID should be non-zero. */ +- if (id == 0) { +- dev_err(&dev->udev->dev, "Found Unit with invalid ID 0.\n"); +- return ERR_PTR(-EINVAL); +- } +- +- /* Per UVC 1.1+ spec 3.7.2, the ID is unique. */ +- if (uvc_entity_by_id(dev, id)) { +- dev_err(&dev->udev->dev, "Found multiple Units with ID %u\n", id); +- return ERR_PTR(-EINVAL); +- } +- + extra_size = roundup(extra_size, sizeof(*entity->pads)); + if (num_pads) + num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1; +@@ -1056,7 +1043,7 @@ static struct uvc_entity *uvc_alloc_new_entity(struct uvc_device *dev, u16 type, + + num_inputs; + entity = kzalloc(size, GFP_KERNEL); + if (entity == NULL) +- return ERR_PTR(-ENOMEM); ++ return NULL; + + entity->id = id; + entity->type = type; +@@ -1146,10 +1133,10 @@ static int uvc_parse_vendor_control(struct uvc_device *dev, + break; + } + +- unit = uvc_alloc_new_entity(dev, UVC_VC_EXTENSION_UNIT, +- buffer[3], p + 1, 2 * n); +- if (IS_ERR(unit)) +- return PTR_ERR(unit); ++ unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3], ++ p + 1, 2*n); ++ if (unit == NULL) ++ return -ENOMEM; + + memcpy(unit->guid, &buffer[4], 16); + unit->extension.bNumControls = buffer[20]; +@@ -1259,10 +1246,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- term = uvc_alloc_new_entity(dev, type | UVC_TERM_INPUT, +- buffer[3], 1, n + p); +- if (IS_ERR(term)) +- return PTR_ERR(term); ++ term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3], ++ 1, n + p); ++ if (term == NULL) ++ return -ENOMEM; + + if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) { + term->camera.bControlSize = n; +@@ -1318,10 +1305,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return 0; + } + +- term = uvc_alloc_new_entity(dev, type | UVC_TERM_OUTPUT, +- buffer[3], 1, 0); +- if (IS_ERR(term)) +- return PTR_ERR(term); ++ term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3], ++ 1, 0); ++ if (term == NULL) ++ return -ENOMEM; + + memcpy(term->baSourceID, &buffer[7], 1); + +@@ -1342,10 +1329,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], +- p + 1, 0); +- if (IS_ERR(unit)) +- return PTR_ERR(unit); ++ unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0); ++ if (unit == NULL) ++ return -ENOMEM; + + memcpy(unit->baSourceID, &buffer[5], p); + +@@ -1367,9 +1353,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], 2, n); +- if (IS_ERR(unit)) +- return PTR_ERR(unit); ++ unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n); ++ if (unit == NULL) ++ return -ENOMEM; + + memcpy(unit->baSourceID, &buffer[4], 1); + unit->processing.wMaxMultiplier = +@@ -1398,10 +1384,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev, + return -EINVAL; + } + +- unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], +- p + 1, n); +- if (IS_ERR(unit)) +- return PTR_ERR(unit); ++ unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n); ++ if (unit == NULL) ++ return -ENOMEM; + + memcpy(unit->guid, &buffer[4], 16); + unit->extension.bNumControls = buffer[20]; +@@ -1530,23 +1515,19 @@ static int uvc_gpio_parse(struct uvc_device *dev) + struct gpio_desc *gpio_privacy; + int irq; + +- gpio_privacy = devm_gpiod_get_optional(&dev->udev->dev, "privacy", ++ gpio_privacy = devm_gpiod_get_optional(&dev->intf->dev, "privacy", + GPIOD_IN); + if (IS_ERR_OR_NULL(gpio_privacy)) + return PTR_ERR_OR_ZERO(gpio_privacy); + + irq = gpiod_to_irq(gpio_privacy); +- if (irq < 0) { +- if (irq != EPROBE_DEFER) +- dev_err(&dev->udev->dev, +- "No IRQ for privacy GPIO (%d)\n", irq); +- return irq; +- } ++ if (irq < 0) ++ return dev_err_probe(&dev->intf->dev, irq, ++ "No IRQ for privacy GPIO\n"); + +- unit = uvc_alloc_new_entity(dev, UVC_EXT_GPIO_UNIT, +- UVC_EXT_GPIO_UNIT_ID, 0, 1); +- if (IS_ERR(unit)) +- return PTR_ERR(unit); ++ unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1); ++ if (!unit) ++ return -ENOMEM; + + unit->gpio.gpio_privacy = gpio_privacy; + unit->gpio.irq = irq; +@@ -1567,15 +1548,27 @@ static int uvc_gpio_parse(struct uvc_device *dev) + static int uvc_gpio_init_irq(struct uvc_device *dev) + { + struct uvc_entity *unit = dev->gpio_unit; ++ int ret; + + if (!unit || unit->gpio.irq < 0) + return 0; + +- return devm_request_threaded_irq(&dev->udev->dev, unit->gpio.irq, NULL, +- uvc_gpio_irq, +- IRQF_ONESHOT | IRQF_TRIGGER_FALLING | +- IRQF_TRIGGER_RISING, +- "uvc_privacy_gpio", dev); ++ ret = request_threaded_irq(unit->gpio.irq, NULL, uvc_gpio_irq, ++ IRQF_ONESHOT | IRQF_TRIGGER_FALLING | ++ IRQF_TRIGGER_RISING, ++ "uvc_privacy_gpio", dev); ++ ++ unit->gpio.initialized = !ret; ++ ++ return ret; ++} ++ ++static void uvc_gpio_deinit(struct uvc_device *dev) ++{ ++ if (!dev->gpio_unit || !dev->gpio_unit->gpio.initialized) ++ return; ++ ++ free_irq(dev->gpio_unit->gpio.irq, dev); + } + + /* ------------------------------------------------------------------------ +@@ -2168,6 +2161,8 @@ static void uvc_unregister_video(struct uvc_device *dev) + { + struct uvc_streaming *stream; + ++ uvc_gpio_deinit(dev); ++ + list_for_each_entry(stream, &dev->streams, list) { + /* Nothing to do here, continue. */ + if (!video_is_registered(&stream->vdev)) +diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c +index 21a907d32bb731..f1f58f2d820f87 100644 +--- a/drivers/media/usb/uvc/uvc_queue.c ++++ b/drivers/media/usb/uvc/uvc_queue.c +@@ -481,7 +481,8 @@ static void uvc_queue_buffer_complete(struct kref *ref) + + buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE; + vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused); +- vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE); ++ vb2_buffer_done(&buf->buf.vb2_buf, buf->error ? VB2_BUF_STATE_ERROR : ++ VB2_BUF_STATE_DONE); + } + + /* +diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c +index 3fa658b86c82bd..b38b898b4d3c92 100644 +--- a/drivers/media/usb/uvc/uvc_status.c ++++ b/drivers/media/usb/uvc/uvc_status.c +@@ -268,6 +268,7 @@ int uvc_status_init(struct uvc_device *dev) + dev->int_urb = usb_alloc_urb(0, GFP_KERNEL); + if (dev->int_urb == NULL) { + kfree(dev->status); ++ dev->status = NULL; + return -ENOMEM; + } + +diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c +index ab535e55015837..a86d470a9f98ff 100644 +--- a/drivers/media/usb/uvc/uvc_v4l2.c ++++ b/drivers/media/usb/uvc/uvc_v4l2.c +@@ -602,6 +602,8 @@ static int uvc_v4l2_release(struct file *file) + + uvc_dbg(stream->dev, CALLS, "%s\n", __func__); + ++ uvc_ctrl_cleanup_fh(handle); ++ + /* Only free resources if this is a privileged handle. */ + if (uvc_has_privileges(handle)) + uvc_queue_release(&stream->queue); +@@ -1102,7 +1104,7 @@ static int uvc_ioctl_s_try_ext_ctrls(struct uvc_fh *handle, + ctrls->error_idx = 0; + + if (ioctl == VIDIOC_S_EXT_CTRLS) +- return uvc_ctrl_commit(handle, ctrls->controls, ctrls->count); ++ return uvc_ctrl_commit(handle, ctrls); + else + return uvc_ctrl_rollback(handle); + } +diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h +index 1aa2cc98502d10..95af1591f1059c 100644 +--- a/drivers/media/usb/uvc/uvcvideo.h ++++ b/drivers/media/usb/uvc/uvcvideo.h +@@ -368,6 +368,7 @@ struct uvc_entity { + u8 *bmControls; + struct gpio_desc *gpio_privacy; + int irq; ++ bool initialized; + } gpio; + }; + +@@ -471,7 +472,11 @@ struct uvc_video_chain { + struct uvc_entity *processing; /* Processing unit */ + struct uvc_entity *selector; /* Selector unit */ + +- struct mutex ctrl_mutex; /* Protects ctrl.info */ ++ struct mutex ctrl_mutex; /* ++ * Protects ctrl.info, ++ * ctrl.handle and ++ * uvc_fh.pending_async_ctrls ++ */ + + struct v4l2_prio_state prio; /* V4L2 priority state */ + u32 caps; /* V4L2 chain-wide caps */ +@@ -723,6 +728,7 @@ struct uvc_fh { + struct uvc_video_chain *chain; + struct uvc_streaming *stream; + enum uvc_handle_state state; ++ unsigned int pending_async_ctrls; + }; + + struct uvc_driver { +@@ -886,17 +892,15 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain, + + int uvc_ctrl_begin(struct uvc_video_chain *chain); + int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, +- const struct v4l2_ext_control *xctrls, +- unsigned int xctrls_count); ++ struct v4l2_ext_controls *ctrls); + static inline int uvc_ctrl_commit(struct uvc_fh *handle, +- const struct v4l2_ext_control *xctrls, +- unsigned int xctrls_count) ++ struct v4l2_ext_controls *ctrls) + { +- return __uvc_ctrl_commit(handle, 0, xctrls, xctrls_count); ++ return __uvc_ctrl_commit(handle, 0, ctrls); + } + static inline int uvc_ctrl_rollback(struct uvc_fh *handle) + { +- return __uvc_ctrl_commit(handle, 1, NULL, 0); ++ return __uvc_ctrl_commit(handle, 1, NULL); + } + + int uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl); +@@ -908,6 +912,8 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id, + int uvc_xu_ctrl_query(struct uvc_video_chain *chain, + struct uvc_xu_control_query *xqry); + ++void uvc_ctrl_cleanup_fh(struct uvc_fh *handle); ++ + /* Utility functions */ + void uvc_simplify_fraction(u32 *numerator, u32 *denominator, + unsigned int n_terms, unsigned int threshold); +diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c +index b01474717dca92..541c99c24923b3 100644 +--- a/drivers/media/v4l2-core/v4l2-mc.c ++++ b/drivers/media/v4l2-core/v4l2-mc.c +@@ -321,7 +321,7 @@ int v4l2_create_fwnode_links_to_pad(struct v4l2_subdev *src_sd, + + sink_sd = media_entity_to_v4l2_subdev(sink->entity); + +- fwnode_graph_for_each_endpoint(dev_fwnode(src_sd->dev), endpoint) { ++ fwnode_graph_for_each_endpoint(src_sd->fwnode, endpoint) { + struct fwnode_handle *remote_ep; + int src_idx, sink_idx, ret; + struct media_pad *src; +diff --git a/drivers/memory/jedec_ddr.h b/drivers/memory/jedec_ddr.h +index e59ccbd982d025..6cd508478b1468 100644 +--- a/drivers/memory/jedec_ddr.h ++++ b/drivers/memory/jedec_ddr.h +@@ -112,6 +112,26 @@ + #define NUM_DDR_ADDR_TABLE_ENTRIES 11 + #define NUM_DDR_TIMING_TABLE_ENTRIES 4 + ++#define LPDDR2_MANID_SAMSUNG 1 ++#define LPDDR2_MANID_QIMONDA 2 ++#define LPDDR2_MANID_ELPIDA 3 ++#define LPDDR2_MANID_ETRON 4 ++#define LPDDR2_MANID_NANYA 5 ++#define LPDDR2_MANID_HYNIX 6 ++#define LPDDR2_MANID_MOSEL 7 ++#define LPDDR2_MANID_WINBOND 8 ++#define LPDDR2_MANID_ESMT 9 ++#define LPDDR2_MANID_SPANSION 11 ++#define LPDDR2_MANID_SST 12 ++#define LPDDR2_MANID_ZMOS 13 ++#define LPDDR2_MANID_INTEL 14 ++#define LPDDR2_MANID_NUMONYX 254 ++#define LPDDR2_MANID_MICRON 255 ++ ++#define LPDDR2_TYPE_S4 0 ++#define LPDDR2_TYPE_S2 1 ++#define LPDDR2_TYPE_NVM 2 ++ + /* Structure for DDR addressing info from the JEDEC spec */ + struct lpddr2_addressing { + u32 num_banks; +@@ -170,6 +190,33 @@ extern const struct lpddr2_timings + lpddr2_jedec_timings[NUM_DDR_TIMING_TABLE_ENTRIES]; + extern const struct lpddr2_min_tck lpddr2_jedec_min_tck; + ++/* Structure of MR8 */ ++union lpddr2_basic_config4 { ++ u32 value; ++ ++ struct { ++ unsigned int arch_type : 2; ++ unsigned int density : 4; ++ unsigned int io_width : 2; ++ } __packed; ++}; ++ ++/* ++ * Structure for information about LPDDR2 chip. All parameters are ++ * matching raw values of standard mode register bitfields or set to ++ * -ENOENT if info unavailable. ++ */ ++struct lpddr2_info { ++ int arch_type; ++ int density; ++ int io_width; ++ int manufacturer_id; ++ int revision_id1; ++ int revision_id2; ++}; ++ ++const char *lpddr2_jedec_manufacturer(unsigned int manufacturer_id); ++ + /* + * Structure for timings for LPDDR3 based on LPDDR2 plus additional fields. + * All parameters are in pico seconds(ps) excluding max_freq, min_freq which +diff --git a/drivers/memory/jedec_ddr_data.c b/drivers/memory/jedec_ddr_data.c +index ed601d813175e7..2cca4fa188f927 100644 +--- a/drivers/memory/jedec_ddr_data.c ++++ b/drivers/memory/jedec_ddr_data.c +@@ -131,3 +131,44 @@ const struct lpddr2_min_tck lpddr2_jedec_min_tck = { + .tFAW = 8 + }; + EXPORT_SYMBOL_GPL(lpddr2_jedec_min_tck); ++ ++const char *lpddr2_jedec_manufacturer(unsigned int manufacturer_id) ++{ ++ switch (manufacturer_id) { ++ case LPDDR2_MANID_SAMSUNG: ++ return "Samsung"; ++ case LPDDR2_MANID_QIMONDA: ++ return "Qimonda"; ++ case LPDDR2_MANID_ELPIDA: ++ return "Elpida"; ++ case LPDDR2_MANID_ETRON: ++ return "Etron"; ++ case LPDDR2_MANID_NANYA: ++ return "Nanya"; ++ case LPDDR2_MANID_HYNIX: ++ return "Hynix"; ++ case LPDDR2_MANID_MOSEL: ++ return "Mosel"; ++ case LPDDR2_MANID_WINBOND: ++ return "Winbond"; ++ case LPDDR2_MANID_ESMT: ++ return "ESMT"; ++ case LPDDR2_MANID_SPANSION: ++ return "Spansion"; ++ case LPDDR2_MANID_SST: ++ return "SST"; ++ case LPDDR2_MANID_ZMOS: ++ return "ZMOS"; ++ case LPDDR2_MANID_INTEL: ++ return "Intel"; ++ case LPDDR2_MANID_NUMONYX: ++ return "Numonyx"; ++ case LPDDR2_MANID_MICRON: ++ return "Micron"; ++ default: ++ break; ++ } ++ ++ return "invalid"; ++} ++EXPORT_SYMBOL_GPL(lpddr2_jedec_manufacturer); +diff --git a/drivers/memory/of_memory.c b/drivers/memory/of_memory.c +index 1791614f324b7d..755ce416fbbadb 100644 +--- a/drivers/memory/of_memory.c ++++ b/drivers/memory/of_memory.c +@@ -300,3 +300,90 @@ const struct lpddr3_timings + return NULL; + } + EXPORT_SYMBOL(of_lpddr3_get_ddr_timings); ++ ++/** ++ * of_lpddr2_get_info() - extracts information about the lpddr2 chip. ++ * @np: Pointer to device tree node containing lpddr2 info ++ * @dev: Device requesting info ++ * ++ * Populates lpddr2_info structure by extracting data from device ++ * tree node. Returns pointer to populated structure. If error ++ * happened while populating, returns NULL. If property is missing ++ * in a device-tree, then the corresponding value is set to -ENOENT. ++ */ ++const struct lpddr2_info ++*of_lpddr2_get_info(struct device_node *np, struct device *dev) ++{ ++ struct lpddr2_info *ret_info, info = {}; ++ struct property *prop; ++ const char *cp; ++ int err; ++ ++ err = of_property_read_u32(np, "revision-id1", &info.revision_id1); ++ if (err) ++ info.revision_id1 = -ENOENT; ++ ++ err = of_property_read_u32(np, "revision-id2", &info.revision_id2); ++ if (err) ++ info.revision_id2 = -ENOENT; ++ ++ err = of_property_read_u32(np, "io-width", &info.io_width); ++ if (err) ++ return NULL; ++ ++ info.io_width = 32 / info.io_width - 1; ++ ++ err = of_property_read_u32(np, "density", &info.density); ++ if (err) ++ return NULL; ++ ++ info.density = ffs(info.density) - 7; ++ ++ if (of_device_is_compatible(np, "jedec,lpddr2-s4")) ++ info.arch_type = LPDDR2_TYPE_S4; ++ else if (of_device_is_compatible(np, "jedec,lpddr2-s2")) ++ info.arch_type = LPDDR2_TYPE_S2; ++ else if (of_device_is_compatible(np, "jedec,lpddr2-nvm")) ++ info.arch_type = LPDDR2_TYPE_NVM; ++ else ++ return NULL; ++ ++ prop = of_find_property(np, "compatible", NULL); ++ for (cp = of_prop_next_string(prop, NULL); cp; ++ cp = of_prop_next_string(prop, cp)) { ++ ++#define OF_LPDDR2_VENDOR_CMP(compat, ID) \ ++ if (!of_compat_cmp(cp, compat ",", strlen(compat ","))) { \ ++ info.manufacturer_id = LPDDR2_MANID_##ID; \ ++ break; \ ++ } ++ ++ OF_LPDDR2_VENDOR_CMP("samsung", SAMSUNG) ++ OF_LPDDR2_VENDOR_CMP("qimonda", QIMONDA) ++ OF_LPDDR2_VENDOR_CMP("elpida", ELPIDA) ++ OF_LPDDR2_VENDOR_CMP("etron", ETRON) ++ OF_LPDDR2_VENDOR_CMP("nanya", NANYA) ++ OF_LPDDR2_VENDOR_CMP("hynix", HYNIX) ++ OF_LPDDR2_VENDOR_CMP("mosel", MOSEL) ++ OF_LPDDR2_VENDOR_CMP("winbond", WINBOND) ++ OF_LPDDR2_VENDOR_CMP("esmt", ESMT) ++ OF_LPDDR2_VENDOR_CMP("spansion", SPANSION) ++ OF_LPDDR2_VENDOR_CMP("sst", SST) ++ OF_LPDDR2_VENDOR_CMP("zmos", ZMOS) ++ OF_LPDDR2_VENDOR_CMP("intel", INTEL) ++ OF_LPDDR2_VENDOR_CMP("numonyx", NUMONYX) ++ OF_LPDDR2_VENDOR_CMP("micron", MICRON) ++ ++#undef OF_LPDDR2_VENDOR_CMP ++ } ++ ++ if (!info.manufacturer_id) ++ info.manufacturer_id = -ENOENT; ++ ++ ret_info = devm_kzalloc(dev, sizeof(*ret_info), GFP_KERNEL); ++ if (ret_info) ++ *ret_info = info; ++ ++ return ret_info; ++} ++EXPORT_SYMBOL(of_lpddr2_get_info); +diff --git a/drivers/memory/of_memory.h b/drivers/memory/of_memory.h +index 4a99b232ab0a8f..1c4e47fede8aec 100644 +--- a/drivers/memory/of_memory.h ++++ b/drivers/memory/of_memory.h +@@ -20,6 +20,9 @@ const struct lpddr3_min_tck *of_lpddr3_get_min_tck(struct device_node *np, + const struct lpddr3_timings * + of_lpddr3_get_ddr_timings(struct device_node *np_ddr, + struct device *dev, u32 device_type, u32 *nr_frequencies); ++ ++const struct lpddr2_info *of_lpddr2_get_info(struct device_node *np, ++ struct device *dev); + #else + static inline const struct lpddr2_min_tck + *of_get_min_tck(struct device_node *np, struct device *dev) +@@ -46,6 +49,12 @@ static inline const struct lpddr3_timings + { + return NULL; + } ++ ++static inline const struct lpddr2_info ++ *of_lpddr2_get_info(struct device_node *np, struct device *dev) ++{ ++ return NULL; ++} + #endif /* CONFIG_OF && CONFIG_DDR */ + + #endif /* __LINUX_MEMORY_OF_REG_ */ +diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig +index f9bae36c03a39d..7951764b4efeca 100644 +--- a/drivers/memory/tegra/Kconfig ++++ b/drivers/memory/tegra/Kconfig +@@ -16,6 +16,7 @@ config TEGRA20_EMC + depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST + select DEVFREQ_GOV_SIMPLE_ONDEMAND + select PM_DEVFREQ ++ select DDR + help + This driver is for the External Memory Controller (EMC) found on + Tegra20 chips. The EMC controls the external DRAM on the board. +diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c +index 6fc90f2160e938..636ed37a4f666a 100644 +--- a/drivers/memory/tegra/tegra20-emc.c ++++ b/drivers/memory/tegra/tegra20-emc.c +@@ -5,6 +5,7 @@ + * Author: Dmitry Osipenko + */ + ++#include + #include + #include + #include +@@ -27,11 +28,15 @@ + #include + #include + ++#include "../jedec_ddr.h" ++#include "../of_memory.h" ++ + #include "mc.h" + + #define EMC_INTSTATUS 0x000 + #define EMC_INTMASK 0x004 + #define EMC_DBG 0x008 ++#define EMC_ADR_CFG_0 0x010 + #define EMC_TIMING_CONTROL 0x028 + #define EMC_RC 0x02c + #define EMC_RFC 0x030 +@@ -68,6 +73,7 @@ + #define EMC_QUSE_EXTRA 0x0ac + #define EMC_ODT_WRITE 0x0b0 + #define EMC_ODT_READ 0x0b4 ++#define EMC_MRR 0x0ec + #define EMC_FBIO_CFG5 0x104 + #define EMC_FBIO_CFG6 0x114 + #define EMC_STAT_CONTROL 0x160 +@@ -94,6 +100,7 @@ + + #define EMC_REFRESH_OVERFLOW_INT BIT(3) + #define EMC_CLKCHANGE_COMPLETE_INT BIT(4) ++#define EMC_MRR_DIVLD_INT BIT(5) + + #define EMC_DBG_READ_MUX_ASSEMBLY BIT(0) + #define EMC_DBG_WRITE_MUX_ACTIVE BIT(1) +@@ -102,11 +109,25 @@ + #define EMC_DBG_CFG_PRIORITY BIT(24) + + #define EMC_FBIO_CFG5_DRAM_WIDTH_X16 BIT(4) ++#define EMC_FBIO_CFG5_DRAM_TYPE GENMASK(1, 0) ++ ++#define EMC_MRR_DEV_SELECTN GENMASK(31, 30) ++#define EMC_MRR_MRR_MA GENMASK(23, 16) ++#define EMC_MRR_MRR_DATA GENMASK(15, 0) ++ ++#define EMC_ADR_CFG_0_EMEM_NUMDEV GENMASK(25, 24) + + #define EMC_PWR_GATHER_CLEAR (1 << 8) + #define EMC_PWR_GATHER_DISABLE (2 << 8) + #define EMC_PWR_GATHER_ENABLE (3 << 8) + ++enum emc_dram_type { ++ DRAM_TYPE_RESERVED, ++ DRAM_TYPE_DDR1, ++ DRAM_TYPE_LPDDR2, ++ DRAM_TYPE_DDR2, ++}; ++ + static const u16 emc_timing_registers[] = { + EMC_RC, + EMC_RFC, +@@ -201,6 +222,14 @@ struct tegra_emc { + struct mutex rate_lock; + + struct devfreq_simple_ondemand_data ondemand_data; ++ ++ /* memory chip identity information */ ++ union lpddr2_basic_config4 basic_conf4; ++ unsigned int manufacturer_id; ++ unsigned int revision_id1; ++ unsigned int revision_id2; ++ ++ bool mrr_error; + }; + + static irqreturn_t tegra_emc_isr(int irq, void *data) +@@ -397,15 +426,19 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc, + if (!emc->timings) + return -ENOMEM; + +- emc->num_timings = child_count; + timing = emc->timings; + + for_each_child_of_node(node, child) { ++ if (of_node_name_eq(child, "lpddr2")) ++ continue; ++ + err = load_one_timing_from_dt(emc, timing++, child); + if (err) { + of_node_put(child); + return err; + } ++ ++ emc->num_timings++; + } + + sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings, +@@ -422,12 +455,18 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc, + } + + static struct device_node * +-tegra_emc_find_node_by_ram_code(struct device *dev) ++tegra_emc_find_node_by_ram_code(struct tegra_emc *emc) + { ++ struct device *dev = emc->dev; + struct device_node *np; + u32 value, ram_code; + int err; + ++ if (emc->mrr_error) { ++ dev_warn(dev, "memory timings skipped due to MRR error\n"); ++ return NULL; ++ } ++ + if (of_get_child_count(dev->of_node) == 0) { + dev_info_once(dev, "device-tree doesn't have memory timings\n"); + return NULL; +@@ -438,12 +477,53 @@ tegra_emc_find_node_by_ram_code(struct device *dev) + + ram_code = tegra_read_ram_code(); + +- for (np = of_find_node_by_name(dev->of_node, "emc-tables"); np; +- np = of_find_node_by_name(np, "emc-tables")) { ++ for_each_child_of_node(dev->of_node, np) { ++ if (!of_node_name_eq(np, "emc-tables")) ++ continue; + err = of_property_read_u32(np, "nvidia,ram-code", &value); + if (err || value != ram_code) { +- of_node_put(np); +- continue; ++ struct device_node *lpddr2_np; ++ bool cfg_mismatches = false; ++ ++ lpddr2_np = of_get_child_by_name(np, "lpddr2"); ++ if (lpddr2_np) { ++ const struct lpddr2_info *info; ++ ++ info = of_lpddr2_get_info(lpddr2_np, dev); ++ if (info) { ++ if (info->manufacturer_id >= 0 && ++ info->manufacturer_id != emc->manufacturer_id) ++ cfg_mismatches = true; ++ ++ if (info->revision_id1 >= 0 && ++ info->revision_id1 != emc->revision_id1) ++ cfg_mismatches = true; ++ ++ if (info->revision_id2 >= 0 && ++ info->revision_id2 != emc->revision_id2) ++ cfg_mismatches = true; ++ ++ if (info->density != emc->basic_conf4.density) ++ cfg_mismatches = true; ++ ++ if (info->io_width != emc->basic_conf4.io_width) ++ cfg_mismatches = true; ++ ++ if (info->arch_type != emc->basic_conf4.arch_type) ++ cfg_mismatches = true; ++ } else { ++ dev_err(dev, "failed to parse %pOF\n", lpddr2_np); ++ cfg_mismatches = true; ++ } ++ ++ of_node_put(lpddr2_np); ++ } else { ++ cfg_mismatches = true; ++ } ++ ++ if (cfg_mismatches) { ++ continue; ++ } + } + + return np; +@@ -455,10 +535,72 @@ tegra_emc_find_node_by_ram_code(struct device *dev) + return NULL; + } + ++static int emc_read_lpddr_mode_register(struct tegra_emc *emc, ++ unsigned int emem_dev, ++ unsigned int register_addr, ++ unsigned int *register_data) ++{ ++ u32 memory_dev = emem_dev ? 1 : 2; ++ u32 val, mr_mask = 0xff; ++ int err; ++ ++ /* clear data-valid interrupt status */ ++ writel_relaxed(EMC_MRR_DIVLD_INT, emc->regs + EMC_INTSTATUS); ++ ++ /* issue mode register read request */ ++ val = FIELD_PREP(EMC_MRR_DEV_SELECTN, memory_dev); ++ val |= FIELD_PREP(EMC_MRR_MRR_MA, register_addr); ++ ++ writel_relaxed(val, emc->regs + EMC_MRR); ++ ++ /* wait for the LPDDR2 data-valid interrupt */ ++ err = readl_relaxed_poll_timeout_atomic(emc->regs + EMC_INTSTATUS, val, ++ val & EMC_MRR_DIVLD_INT, ++ 1, 100); ++ if (err) { ++ dev_err(emc->dev, "mode register %u read failed: %d\n", ++ register_addr, err); ++ emc->mrr_error = true; ++ return err; ++ } ++ ++ /* read out mode register data */ ++ val = readl_relaxed(emc->regs + EMC_MRR); ++ *register_data = FIELD_GET(EMC_MRR_MRR_DATA, val) & mr_mask; ++ ++ return 0; ++} ++ ++static void emc_read_lpddr_sdram_info(struct tegra_emc *emc, ++ unsigned int emem_dev, ++ bool print_out) ++{ ++ /* these registers are standard for all LPDDR JEDEC memory chips */ ++ emc_read_lpddr_mode_register(emc, emem_dev, 5, &emc->manufacturer_id); ++ emc_read_lpddr_mode_register(emc, emem_dev, 6, &emc->revision_id1); ++ emc_read_lpddr_mode_register(emc, emem_dev, 7, &emc->revision_id2); ++ emc_read_lpddr_mode_register(emc, emem_dev, 8, &emc->basic_conf4.value); ++ ++ if (!print_out) ++ return; ++ ++ dev_info(emc->dev, "SDRAM[dev%u]: manufacturer: 0x%x (%s) rev1: 0x%x rev2: 0x%x prefetch: S%u density: %uMbit iowidth: %ubit\n", ++ emem_dev, emc->manufacturer_id, ++ lpddr2_jedec_manufacturer(emc->manufacturer_id), ++ emc->revision_id1, emc->revision_id2, ++ 4 >> emc->basic_conf4.arch_type, ++ 64 << emc->basic_conf4.density, ++ 32 >> emc->basic_conf4.io_width); ++} ++ + static int emc_setup_hw(struct tegra_emc *emc) + { ++ u32 emc_cfg, emc_dbg, emc_fbio, emc_adr_cfg; + u32 intmask = EMC_REFRESH_OVERFLOW_INT; +- u32 emc_cfg, emc_dbg, emc_fbio; ++ static bool print_sdram_info_once; ++ enum emc_dram_type dram_type; ++ const char *dram_type_str; ++ unsigned int emem_numdev; + + emc_cfg = readl_relaxed(emc->regs + EMC_CFG_2); + +@@ -496,7 +638,36 @@ static int emc_setup_hw(struct tegra_emc *emc) + else + emc->dram_bus_width = 32; + +- dev_info_once(emc->dev, "%ubit DRAM bus\n", emc->dram_bus_width); ++ dram_type = FIELD_GET(EMC_FBIO_CFG5_DRAM_TYPE, emc_fbio); ++ ++ switch (dram_type) { ++ case DRAM_TYPE_RESERVED: ++ dram_type_str = "INVALID"; ++ break; ++ case DRAM_TYPE_DDR1: ++ dram_type_str = "DDR1"; ++ break; ++ case DRAM_TYPE_LPDDR2: ++ dram_type_str = "LPDDR2"; ++ break; ++ case DRAM_TYPE_DDR2: ++ dram_type_str = "DDR2"; ++ break; ++ } ++ ++ emc_adr_cfg = readl_relaxed(emc->regs + EMC_ADR_CFG_0); ++ emem_numdev = FIELD_GET(EMC_ADR_CFG_0_EMEM_NUMDEV, emc_adr_cfg) + 1; ++ ++ dev_info_once(emc->dev, "%ubit DRAM bus, %u %s %s attached\n", ++ emc->dram_bus_width, emem_numdev, dram_type_str, ++ emem_numdev == 2 ? "devices" : "device"); ++ ++ if (dram_type == DRAM_TYPE_LPDDR2) { ++ while (emem_numdev--) ++ emc_read_lpddr_sdram_info(emc, emem_numdev, ++ !print_sdram_info_once); ++ print_sdram_info_once = true; ++ } + + return 0; + } +@@ -1049,14 +1220,6 @@ static int tegra_emc_probe(struct platform_device *pdev) + emc->clk_nb.notifier_call = tegra_emc_clk_change_notify; + emc->dev = &pdev->dev; + +- np = tegra_emc_find_node_by_ram_code(&pdev->dev); +- if (np) { +- err = tegra_emc_load_timings_from_dt(emc, np); +- of_node_put(np); +- if (err) +- return err; +- } +- + emc->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(emc->regs)) + return PTR_ERR(emc->regs); +@@ -1065,6 +1228,14 @@ static int tegra_emc_probe(struct platform_device *pdev) + if (err) + return err; + ++ np = tegra_emc_find_node_by_ram_code(emc); ++ if (np) { ++ err = tegra_emc_load_timings_from_dt(emc, np); ++ of_node_put(np); ++ if (err) ++ return err; ++ } ++ + err = devm_request_irq(&pdev->dev, irq, tegra_emc_isr, 0, + dev_name(&pdev->dev), emc); + if (err) { +diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c +index 9ffab9aafd81b1..15a6004218521a 100644 +--- a/drivers/mfd/lpc_ich.c ++++ b/drivers/mfd/lpc_ich.c +@@ -688,8 +688,9 @@ static const struct pci_device_id lpc_ich_ids[] = { + { PCI_VDEVICE(INTEL, 0x2917), LPC_ICH9ME}, + { PCI_VDEVICE(INTEL, 0x2918), LPC_ICH9}, + { PCI_VDEVICE(INTEL, 0x2919), LPC_ICH9M}, +- { PCI_VDEVICE(INTEL, 0x3197), LPC_GLK}, + { PCI_VDEVICE(INTEL, 0x2b9c), LPC_COUGARMOUNTAIN}, ++ { PCI_VDEVICE(INTEL, 0x3197), LPC_GLK}, ++ { PCI_VDEVICE(INTEL, 0x31e8), LPC_GLK}, + { PCI_VDEVICE(INTEL, 0x3a14), LPC_ICH10DO}, + { PCI_VDEVICE(INTEL, 0x3a16), LPC_ICH10R}, + { PCI_VDEVICE(INTEL, 0x3a18), LPC_ICH10}, +diff --git a/drivers/misc/eeprom/digsy_mtc_eeprom.c b/drivers/misc/eeprom/digsy_mtc_eeprom.c +index 4eddc5ba1af9c8..dfaedc0e350dbd 100644 +--- a/drivers/misc/eeprom/digsy_mtc_eeprom.c ++++ b/drivers/misc/eeprom/digsy_mtc_eeprom.c +@@ -60,7 +60,7 @@ static struct platform_device digsy_mtc_eeprom = { + }; + + static struct gpiod_lookup_table eeprom_spi_gpiod_table = { +- .dev_id = "spi_gpio", ++ .dev_id = "spi_gpio.1", + .table = { + GPIO_LOOKUP("gpio@b00", GPIO_EEPROM_CLK, + "sck", GPIO_ACTIVE_HIGH), +diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c +index 96c098d6fc2218..e83c1c7b34c258 100644 +--- a/drivers/misc/fastrpc.c ++++ b/drivers/misc/fastrpc.c +@@ -828,7 +828,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) + mmap_read_lock(current->mm); + vma = find_vma(current->mm, ctx->args[i].ptr); + if (vma) +- pages[i].addr += ctx->args[i].ptr - ++ pages[i].addr += (ctx->args[i].ptr & PAGE_MASK) - + vma->vm_start; + mmap_read_unlock(current->mm); + +diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h +index bbabfe49f9560b..3f8349fbbc3ae8 100644 +--- a/drivers/misc/mei/hw-me-regs.h ++++ b/drivers/misc/mei/hw-me-regs.h +@@ -117,6 +117,8 @@ + + #define MEI_DEV_ID_LNL_M 0xA870 /* Lunar Lake Point M */ + ++#define MEI_DEV_ID_PTL_P 0xE470 /* Panther Lake P */ ++ + /* + * MEI HW Section + */ +diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c +index 7b8e92bcaa98df..31012ea4c01adf 100644 +--- a/drivers/misc/mei/pci-me.c ++++ b/drivers/misc/mei/pci-me.c +@@ -123,6 +123,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = { + + {MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, MEI_ME_PCH15_CFG)}, + ++ {MEI_PCI_DEVICE(MEI_DEV_ID_PTL_P, MEI_ME_PCH15_CFG)}, ++ + /* required last entry */ + {0, } + }; +diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c +index eda2dbd965392d..a0cac8c87ef2f9 100644 +--- a/drivers/mmc/core/sdio.c ++++ b/drivers/mmc/core/sdio.c +@@ -443,6 +443,8 @@ static unsigned mmc_sdio_get_max_clock(struct mmc_card *card) + if (card->type == MMC_TYPE_SD_COMBO) + max_dtr = min(max_dtr, mmc_sd_get_max_clock(card)); + ++ max_dtr = min_not_zero(max_dtr, card->quirk_max_rate); ++ + return max_dtr; + } + +diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c +index 943fc7b7f4fb56..4b727754d8e3c0 100644 +--- a/drivers/mmc/host/sdhci-msm.c ++++ b/drivers/mmc/host/sdhci-msm.c +@@ -132,9 +132,18 @@ + /* Timeout value to avoid infinite waiting for pwr_irq */ + #define MSM_PWR_IRQ_TIMEOUT_MS 5000 + ++/* Max load for eMMC Vdd supply */ ++#define MMC_VMMC_MAX_LOAD_UA 570000 ++ + /* Max load for eMMC Vdd-io supply */ + #define MMC_VQMMC_MAX_LOAD_UA 325000 + ++/* Max load for SD Vdd supply */ ++#define SD_VMMC_MAX_LOAD_UA 800000 ++ ++/* Max load for SD Vdd-io supply */ ++#define SD_VQMMC_MAX_LOAD_UA 22000 ++ + #define msm_host_readl(msm_host, host, offset) \ + msm_host->var_ops->msm_readl_relaxed(host, offset) + +@@ -1399,11 +1408,48 @@ static int sdhci_msm_set_pincfg(struct sdhci_msm_host *msm_host, bool level) + return ret; + } + +-static int sdhci_msm_set_vmmc(struct mmc_host *mmc) ++static void msm_config_vmmc_regulator(struct mmc_host *mmc, bool hpm) ++{ ++ int load; ++ ++ if (!hpm) ++ load = 0; ++ else if (!mmc->card) ++ load = max(MMC_VMMC_MAX_LOAD_UA, SD_VMMC_MAX_LOAD_UA); ++ else if (mmc_card_mmc(mmc->card)) ++ load = MMC_VMMC_MAX_LOAD_UA; ++ else if (mmc_card_sd(mmc->card)) ++ load = SD_VMMC_MAX_LOAD_UA; ++ else ++ return; ++ ++ regulator_set_load(mmc->supply.vmmc, load); ++} ++ ++static void msm_config_vqmmc_regulator(struct mmc_host *mmc, bool hpm) ++{ ++ int load; ++ ++ if (!hpm) ++ load = 0; ++ else if (!mmc->card) ++ load = max(MMC_VQMMC_MAX_LOAD_UA, SD_VQMMC_MAX_LOAD_UA); ++ else if (mmc_card_sd(mmc->card)) ++ load = SD_VQMMC_MAX_LOAD_UA; ++ else ++ return; ++ ++ regulator_set_load(mmc->supply.vqmmc, load); ++} ++ ++static int sdhci_msm_set_vmmc(struct sdhci_msm_host *msm_host, ++ struct mmc_host *mmc, bool hpm) + { + if (IS_ERR(mmc->supply.vmmc)) + return 0; + ++ msm_config_vmmc_regulator(mmc, hpm); ++ + return mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, mmc->ios.vdd); + } + +@@ -1416,6 +1462,8 @@ static int msm_toggle_vqmmc(struct sdhci_msm_host *msm_host, + if (msm_host->vqmmc_enabled == level) + return 0; + ++ msm_config_vqmmc_regulator(mmc, level); ++ + if (level) { + /* Set the IO voltage regulator to default voltage level */ + if (msm_host->caps_0 & CORE_3_0V_SUPPORT) +@@ -1638,7 +1686,8 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) + } + + if (pwr_state) { +- ret = sdhci_msm_set_vmmc(mmc); ++ ret = sdhci_msm_set_vmmc(msm_host, mmc, ++ pwr_state & REQ_BUS_ON); + if (!ret) + ret = sdhci_msm_set_vqmmc(msm_host, mmc, + pwr_state & REQ_BUS_ON); +diff --git a/drivers/mtd/hyperbus/hbmc-am654.c b/drivers/mtd/hyperbus/hbmc-am654.c +index a3439b791eeb49..4b6cbee23fe893 100644 +--- a/drivers/mtd/hyperbus/hbmc-am654.c ++++ b/drivers/mtd/hyperbus/hbmc-am654.c +@@ -174,26 +174,30 @@ static int am654_hbmc_probe(struct platform_device *pdev) + priv->hbdev.np = of_get_next_child(np, NULL); + ret = of_address_to_resource(priv->hbdev.np, 0, &res); + if (ret) +- return ret; ++ goto put_node; + + if (of_property_read_bool(dev->of_node, "mux-controls")) { + struct mux_control *control = devm_mux_control_get(dev, NULL); + +- if (IS_ERR(control)) +- return PTR_ERR(control); ++ if (IS_ERR(control)) { ++ ret = PTR_ERR(control); ++ goto put_node; ++ } + + ret = mux_control_select(control, 1); + if (ret) { + dev_err(dev, "Failed to select HBMC mux\n"); +- return ret; ++ goto put_node; + } + priv->mux_ctrl = control; + } + + priv->hbdev.map.size = resource_size(&res); + priv->hbdev.map.virt = devm_ioremap_resource(dev, &res); +- if (IS_ERR(priv->hbdev.map.virt)) +- return PTR_ERR(priv->hbdev.map.virt); ++ if (IS_ERR(priv->hbdev.map.virt)) { ++ ret = PTR_ERR(priv->hbdev.map.virt); ++ goto disable_mux; ++ } + + priv->ctlr.dev = dev; + priv->ctlr.ops = &am654_hbmc_ops; +@@ -226,23 +230,24 @@ static int am654_hbmc_probe(struct platform_device *pdev) + disable_mux: + if (priv->mux_ctrl) + mux_control_deselect(priv->mux_ctrl); ++put_node: ++ of_node_put(priv->hbdev.np); + return ret; + } + +-static int am654_hbmc_remove(struct platform_device *pdev) ++static void am654_hbmc_remove(struct platform_device *pdev) + { + struct am654_hbmc_priv *priv = platform_get_drvdata(pdev); + struct am654_hbmc_device_priv *dev_priv = priv->hbdev.priv; +- int ret; + +- ret = hyperbus_unregister_device(&priv->hbdev); ++ hyperbus_unregister_device(&priv->hbdev); ++ + if (priv->mux_ctrl) + mux_control_deselect(priv->mux_ctrl); + + if (dev_priv->rx_chan) + dma_release_channel(dev_priv->rx_chan); +- +- return ret; ++ of_node_put(priv->hbdev.np); + } + + static const struct of_device_id am654_hbmc_dt_ids[] = { +@@ -256,7 +261,7 @@ MODULE_DEVICE_TABLE(of, am654_hbmc_dt_ids); + + static struct platform_driver am654_hbmc_platform_driver = { + .probe = am654_hbmc_probe, +- .remove = am654_hbmc_remove, ++ .remove_new = am654_hbmc_remove, + .driver = { + .name = "hbmc-am654", + .of_match_table = am654_hbmc_dt_ids, +diff --git a/drivers/mtd/hyperbus/hyperbus-core.c b/drivers/mtd/hyperbus/hyperbus-core.c +index 2f9fc4e17d53e6..4d8047d43e48e2 100644 +--- a/drivers/mtd/hyperbus/hyperbus-core.c ++++ b/drivers/mtd/hyperbus/hyperbus-core.c +@@ -126,16 +126,12 @@ int hyperbus_register_device(struct hyperbus_device *hbdev) + } + EXPORT_SYMBOL_GPL(hyperbus_register_device); + +-int hyperbus_unregister_device(struct hyperbus_device *hbdev) ++void hyperbus_unregister_device(struct hyperbus_device *hbdev) + { +- int ret = 0; +- + if (hbdev && hbdev->mtd) { +- ret = mtd_device_unregister(hbdev->mtd); ++ WARN_ON(mtd_device_unregister(hbdev->mtd)); + map_destroy(hbdev->mtd); + } +- +- return ret; + } + EXPORT_SYMBOL_GPL(hyperbus_unregister_device); + +diff --git a/drivers/mtd/hyperbus/rpc-if.c b/drivers/mtd/hyperbus/rpc-if.c +index dc164c18f8429f..cd0e577684ff04 100644 +--- a/drivers/mtd/hyperbus/rpc-if.c ++++ b/drivers/mtd/hyperbus/rpc-if.c +@@ -151,11 +151,12 @@ static int rpcif_hb_probe(struct platform_device *pdev) + static int rpcif_hb_remove(struct platform_device *pdev) + { + struct rpcif_hyperbus *hyperbus = platform_get_drvdata(pdev); +- int error = hyperbus_unregister_device(&hyperbus->hbdev); ++ ++ hyperbus_unregister_device(&hyperbus->hbdev); + + rpcif_disable_rpm(&hyperbus->rpc); + +- return error; ++ return 0; + } + + static struct platform_driver rpcif_platform_driver = { +diff --git a/drivers/mtd/nand/onenand/onenand_base.c b/drivers/mtd/nand/onenand/onenand_base.c +index 958bac54b19078..cdb25a02899649 100644 +--- a/drivers/mtd/nand/onenand/onenand_base.c ++++ b/drivers/mtd/nand/onenand/onenand_base.c +@@ -2911,6 +2911,7 @@ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len, + ret = ONENAND_IS_4KB_PAGE(this) ? + onenand_mlc_read_ops_nolock(mtd, from, &ops) : + onenand_read_ops_nolock(mtd, from, &ops); ++ *retlen = ops.retlen; + + /* Exit OTP access mode */ + this->command(mtd, ONENAND_CMD_RESET, 0, 0); +diff --git a/drivers/mtd/nand/raw/cadence-nand-controller.c b/drivers/mtd/nand/raw/cadence-nand-controller.c +index 0d72672f8b64d5..2d81970f2aa934 100644 +--- a/drivers/mtd/nand/raw/cadence-nand-controller.c ++++ b/drivers/mtd/nand/raw/cadence-nand-controller.c +@@ -469,6 +469,8 @@ struct cdns_nand_ctrl { + struct { + void __iomem *virt; + dma_addr_t dma; ++ dma_addr_t iova_dma; ++ u32 size; + } io; + + int irq; +@@ -1830,11 +1832,11 @@ static int cadence_nand_slave_dma_transfer(struct cdns_nand_ctrl *cdns_ctrl, + } + + if (dir == DMA_FROM_DEVICE) { +- src_dma = cdns_ctrl->io.dma; ++ src_dma = cdns_ctrl->io.iova_dma; + dst_dma = buf_dma; + } else { + src_dma = buf_dma; +- dst_dma = cdns_ctrl->io.dma; ++ dst_dma = cdns_ctrl->io.iova_dma; + } + + tx = dmaengine_prep_dma_memcpy(cdns_ctrl->dmac, dst_dma, src_dma, len, +@@ -1856,12 +1858,12 @@ static int cadence_nand_slave_dma_transfer(struct cdns_nand_ctrl *cdns_ctrl, + dma_async_issue_pending(cdns_ctrl->dmac); + wait_for_completion(&finished); + +- dma_unmap_single(cdns_ctrl->dev, buf_dma, len, dir); ++ dma_unmap_single(dma_dev->dev, buf_dma, len, dir); + + return 0; + + err_unmap: +- dma_unmap_single(cdns_ctrl->dev, buf_dma, len, dir); ++ dma_unmap_single(dma_dev->dev, buf_dma, len, dir); + + err: + dev_dbg(cdns_ctrl->dev, "Fall back to CPU I/O\n"); +@@ -2831,6 +2833,7 @@ cadence_nand_irq_cleanup(int irqnum, struct cdns_nand_ctrl *cdns_ctrl) + static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl) + { + dma_cap_mask_t mask; ++ struct dma_device *dma_dev = cdns_ctrl->dmac->device; + int ret; + + cdns_ctrl->cdma_desc = dma_alloc_coherent(cdns_ctrl->dev, +@@ -2866,15 +2869,24 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl) + dma_cap_set(DMA_MEMCPY, mask); + + if (cdns_ctrl->caps1->has_dma) { +- cdns_ctrl->dmac = dma_request_channel(mask, NULL, NULL); +- if (!cdns_ctrl->dmac) { +- dev_err(cdns_ctrl->dev, +- "Unable to get a DMA channel\n"); +- ret = -EBUSY; ++ cdns_ctrl->dmac = dma_request_chan_by_mask(&mask); ++ if (IS_ERR(cdns_ctrl->dmac)) { ++ ret = dev_err_probe(cdns_ctrl->dev, PTR_ERR(cdns_ctrl->dmac), ++ "%d: Failed to get a DMA channel\n", ret); + goto disable_irq; + } + } + ++ cdns_ctrl->io.iova_dma = dma_map_resource(dma_dev->dev, cdns_ctrl->io.dma, ++ cdns_ctrl->io.size, ++ DMA_BIDIRECTIONAL, 0); ++ ++ ret = dma_mapping_error(dma_dev->dev, cdns_ctrl->io.iova_dma); ++ if (ret) { ++ dev_err(cdns_ctrl->dev, "Failed to map I/O resource to DMA\n"); ++ goto dma_release_chnl; ++ } ++ + nand_controller_init(&cdns_ctrl->controller); + INIT_LIST_HEAD(&cdns_ctrl->chips); + +@@ -2885,18 +2897,22 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl) + if (ret) { + dev_err(cdns_ctrl->dev, "Failed to register MTD: %d\n", + ret); +- goto dma_release_chnl; ++ goto unmap_dma_resource; + } + + kfree(cdns_ctrl->buf); + cdns_ctrl->buf = kzalloc(cdns_ctrl->buf_size, GFP_KERNEL); + if (!cdns_ctrl->buf) { + ret = -ENOMEM; +- goto dma_release_chnl; ++ goto unmap_dma_resource; + } + + return 0; + ++unmap_dma_resource: ++ dma_unmap_resource(dma_dev->dev, cdns_ctrl->io.iova_dma, ++ cdns_ctrl->io.size, DMA_BIDIRECTIONAL, 0); ++ + dma_release_chnl: + if (cdns_ctrl->dmac) + dma_release_channel(cdns_ctrl->dmac); +@@ -2918,6 +2934,10 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl) + static void cadence_nand_remove(struct cdns_nand_ctrl *cdns_ctrl) + { + cadence_nand_chips_cleanup(cdns_ctrl); ++ if (cdns_ctrl->dmac) ++ dma_unmap_resource(cdns_ctrl->dmac->device->dev, ++ cdns_ctrl->io.iova_dma, cdns_ctrl->io.size, ++ DMA_BIDIRECTIONAL, 0); + cadence_nand_irq_cleanup(cdns_ctrl->irq, cdns_ctrl); + kfree(cdns_ctrl->buf); + dma_free_coherent(cdns_ctrl->dev, sizeof(struct cadence_nand_cdma_desc), +@@ -2986,7 +3006,9 @@ static int cadence_nand_dt_probe(struct platform_device *ofdev) + cdns_ctrl->io.virt = devm_platform_get_and_ioremap_resource(ofdev, 1, &res); + if (IS_ERR(cdns_ctrl->io.virt)) + return PTR_ERR(cdns_ctrl->io.virt); ++ + cdns_ctrl->io.dma = res->start; ++ cdns_ctrl->io.size = resource_size(res); + + dt->clk = devm_clk_get(cdns_ctrl->dev, "nf_clk"); + if (IS_ERR(dt->clk)) +diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c +index da87de02b2fcc4..38a243dfcf285c 100644 +--- a/drivers/net/caif/caif_virtio.c ++++ b/drivers/net/caif/caif_virtio.c +@@ -744,7 +744,7 @@ static int cfv_probe(struct virtio_device *vdev) + + if (cfv->vr_rx) + vdev->vringh_config->del_vrhs(cfv->vdev); +- if (cfv->vdev) ++ if (cfv->vq_tx) + vdev->config->del_vqs(cfv->vdev); + free_netdev(netdev); + return err; +diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c +index 86e95e9d65336e..c5d7093d541331 100644 +--- a/drivers/net/can/c_can/c_can_platform.c ++++ b/drivers/net/can/c_can/c_can_platform.c +@@ -395,15 +395,16 @@ static int c_can_plat_probe(struct platform_device *pdev) + if (ret) { + dev_err(&pdev->dev, "registering %s failed (err=%d)\n", + KBUILD_MODNAME, ret); +- goto exit_free_device; ++ goto exit_pm_runtime; + } + + dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", + KBUILD_MODNAME, priv->base, dev->irq); + return 0; + +-exit_free_device: ++exit_pm_runtime: + pm_runtime_disable(priv->device); ++exit_free_device: + free_c_can_dev(dev); + exit: + dev_err(&pdev->dev, "probe failed\n"); +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +index c52093589d7cf8..25349a2ae5cfe3 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +@@ -1294,7 +1294,9 @@ void aq_nic_deinit(struct aq_nic_s *self, bool link_down) + aq_ptp_ring_free(self); + aq_ptp_free(self); + +- if (likely(self->aq_fw_ops->deinit) && link_down) { ++ /* May be invoked during hot unplug. */ ++ if (pci_device_is_present(self->pdev) && ++ likely(self->aq_fw_ops->deinit) && link_down) { + mutex_lock(&self->fwreq_mutex); + self->aq_fw_ops->deinit(self->aq_hw); + mutex_unlock(&self->fwreq_mutex); +diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h +index 99a344175a7511..378c72bfbd9e53 100644 +--- a/drivers/net/ethernet/broadcom/bgmac.h ++++ b/drivers/net/ethernet/broadcom/bgmac.h +@@ -328,8 +328,7 @@ + #define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */ + #define BGMAC_RX_BUF_OFFSET (NET_SKB_PAD + NET_IP_ALIGN - \ + BGMAC_RX_FRAME_OFFSET) +-/* Jumbo frame size with FCS */ +-#define BGMAC_RX_MAX_FRAME_SIZE 9724 ++#define BGMAC_RX_MAX_FRAME_SIZE 1536 + #define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE) + #define BGMAC_RX_ALLOC_SIZE (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE + BGMAC_RX_BUF_OFFSET) + \ + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index 4fb1d2749c0637..7c51b9b593afc2 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -55,6 +55,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -18116,6 +18117,50 @@ static int tg3_resume(struct device *device) + + static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume); + ++/* Systems where ACPI _PTS (Prepare To Sleep) S5 will result in a fatal ++ * PCIe AER event on the tg3 device if the tg3 device is not, or cannot ++ * be, powered down. ++ */ ++static const struct dmi_system_id tg3_restart_aer_quirk_table[] = { ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R440"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R540"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R640"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R650"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R740"), ++ }, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R750"), ++ }, ++ }, ++ {} ++}; ++ + static void tg3_shutdown(struct pci_dev *pdev) + { + struct net_device *dev = pci_get_drvdata(pdev); +@@ -18132,6 +18177,19 @@ static void tg3_shutdown(struct pci_dev *pdev) + + if (system_state == SYSTEM_POWER_OFF) + tg3_power_down(tp); ++ else if (system_state == SYSTEM_RESTART && ++ dmi_first_match(tg3_restart_aer_quirk_table) && ++ pdev->current_state != PCI_D3cold && ++ pdev->current_state != PCI_UNKNOWN) { ++ /* Disable PCIe AER on the tg3 to avoid a fatal ++ * error during this system restart. ++ */ ++ pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL, ++ PCI_EXP_DEVCTL_CERE | ++ PCI_EXP_DEVCTL_NFERE | ++ PCI_EXP_DEVCTL_FERE | ++ PCI_EXP_DEVCTL_URRE); ++ } + + rtnl_unlock(); + +diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h +index d8d87213697cde..d3d1b9237d5945 100644 +--- a/drivers/net/ethernet/cadence/macb.h ++++ b/drivers/net/ethernet/cadence/macb.h +@@ -1258,6 +1258,8 @@ struct macb { + struct clk *rx_clk; + struct clk *tsu_clk; + struct net_device *dev; ++ /* Protects hw_stats and ethtool_stats */ ++ spinlock_t stats_lock; + union { + struct macb_stats macb; + struct gem_stats gem; +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index 4e7359657941d8..275baaaea0e12a 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -1892,10 +1892,12 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) + + if (status & MACB_BIT(ISR_ROVR)) { + /* We missed at least one packet */ ++ spin_lock(&bp->stats_lock); + if (macb_is_gem(bp)) + bp->hw_stats.gem.rx_overruns++; + else + bp->hw_stats.macb.rx_overruns++; ++ spin_unlock(&bp->stats_lock); + + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(queue, ISR, MACB_BIT(ISR_ROVR)); +@@ -2939,6 +2941,7 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) + if (!netif_running(bp->dev)) + return nstat; + ++ spin_lock_irq(&bp->stats_lock); + gem_update_stats(bp); + + nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors + +@@ -2968,6 +2971,7 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) + nstat->tx_aborted_errors = hwstat->tx_excessive_collisions; + nstat->tx_carrier_errors = hwstat->tx_carrier_sense_errors; + nstat->tx_fifo_errors = hwstat->tx_underrun; ++ spin_unlock_irq(&bp->stats_lock); + + return nstat; + } +@@ -2975,12 +2979,13 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) + static void gem_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data) + { +- struct macb *bp; ++ struct macb *bp = netdev_priv(dev); + +- bp = netdev_priv(dev); ++ spin_lock_irq(&bp->stats_lock); + gem_update_stats(bp); + memcpy(data, &bp->ethtool_stats, sizeof(u64) + * (GEM_STATS_LEN + QUEUE_STATS_LEN * MACB_MAX_QUEUES)); ++ spin_unlock_irq(&bp->stats_lock); + } + + static int gem_get_sset_count(struct net_device *dev, int sset) +@@ -3030,6 +3035,7 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev) + return gem_get_stats(bp); + + /* read stats from hardware */ ++ spin_lock_irq(&bp->stats_lock); + macb_update_stats(bp); + + /* Convert HW stats into netdevice stats */ +@@ -3063,6 +3069,7 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev) + nstat->tx_carrier_errors = hwstat->tx_carrier_errors; + nstat->tx_fifo_errors = hwstat->tx_underruns; + /* Don't know about heartbeat or window errors... */ ++ spin_unlock_irq(&bp->stats_lock); + + return nstat; + } +@@ -4802,6 +4809,7 @@ static int macb_probe(struct platform_device *pdev) + bp->usrio = macb_config->usrio; + + spin_lock_init(&bp->lock); ++ spin_lock_init(&bp->stats_lock); + + /* setup capabilities */ + macb_configure_caps(bp, macb_config); +diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c +index e842de6f66356b..afa92b44c8ebb1 100644 +--- a/drivers/net/ethernet/davicom/dm9000.c ++++ b/drivers/net/ethernet/davicom/dm9000.c +@@ -1773,10 +1773,11 @@ dm9000_drv_remove(struct platform_device *pdev) + + unregister_netdev(ndev); + dm9000_release_board(pdev, dm); +- free_netdev(ndev); /* free device structure */ + if (dm->power_supply) + regulator_disable(dm->power_supply); + ++ free_netdev(ndev); /* free device structure */ ++ + dev_dbg(&pdev->dev, "released and freed device\n"); + return 0; + } +diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h +index 8689d4a51fe541..6e44000bddf1ea 100644 +--- a/drivers/net/ethernet/emulex/benet/be.h ++++ b/drivers/net/ethernet/emulex/benet/be.h +@@ -563,7 +563,7 @@ struct be_adapter { + struct be_dma_mem mbox_mem_alloced; + + struct be_mcc_obj mcc_obj; +- struct mutex mcc_lock; /* For serializing mcc cmds to BE card */ ++ spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ + spinlock_t mcc_cq_lock; + + u16 cfg_num_rx_irqs; /* configured via set-channels */ +diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c +index b4f5e57d0285cb..88f69c486ed098 100644 +--- a/drivers/net/ethernet/emulex/benet/be_cmds.c ++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c +@@ -573,7 +573,7 @@ int be_process_mcc(struct be_adapter *adapter) + /* Wait till no more pending mcc requests are present */ + static int be_mcc_wait_compl(struct be_adapter *adapter) + { +-#define mcc_timeout 12000 /* 12s timeout */ ++#define mcc_timeout 120000 /* 12s timeout */ + int i, status = 0; + struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; + +@@ -587,7 +587,7 @@ static int be_mcc_wait_compl(struct be_adapter *adapter) + + if (atomic_read(&mcc_obj->q.used) == 0) + break; +- usleep_range(500, 1000); ++ udelay(100); + } + if (i == mcc_timeout) { + dev_err(&adapter->pdev->dev, "FW not responding\n"); +@@ -865,7 +865,7 @@ static bool use_mcc(struct be_adapter *adapter) + static int be_cmd_lock(struct be_adapter *adapter) + { + if (use_mcc(adapter)) { +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + return 0; + } else { + return mutex_lock_interruptible(&adapter->mbox_lock); +@@ -876,7 +876,7 @@ static int be_cmd_lock(struct be_adapter *adapter) + static void be_cmd_unlock(struct be_adapter *adapter) + { + if (use_mcc(adapter)) +- return mutex_unlock(&adapter->mcc_lock); ++ return spin_unlock_bh(&adapter->mcc_lock); + else + return mutex_unlock(&adapter->mbox_lock); + } +@@ -1046,7 +1046,7 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, + struct be_cmd_req_mac_query *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -1075,7 +1075,7 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, + } + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -1087,7 +1087,7 @@ int be_cmd_pmac_add(struct be_adapter *adapter, const u8 *mac_addr, + struct be_cmd_req_pmac_add *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -1112,7 +1112,7 @@ int be_cmd_pmac_add(struct be_adapter *adapter, const u8 *mac_addr, + } + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + + if (base_status(status) == MCC_STATUS_UNAUTHORIZED_REQUEST) + status = -EPERM; +@@ -1130,7 +1130,7 @@ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, u32 dom) + if (pmac_id == -1) + return 0; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -1150,7 +1150,7 @@ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, u32 dom) + status = be_mcc_notify_wait(adapter); + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -1413,7 +1413,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter, + struct be_dma_mem *q_mem = &rxq->dma_mem; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -1443,7 +1443,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter, + } + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -1507,7 +1507,7 @@ int be_cmd_rxq_destroy(struct be_adapter *adapter, struct be_queue_info *q) + struct be_cmd_req_q_destroy *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -1524,7 +1524,7 @@ int be_cmd_rxq_destroy(struct be_adapter *adapter, struct be_queue_info *q) + q->created = false; + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -1592,7 +1592,7 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) + struct be_cmd_req_hdr *hdr; + int status = 0; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -1620,7 +1620,7 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) + adapter->stats_cmd_sent = true; + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -1636,7 +1636,7 @@ int lancer_cmd_get_pport_stats(struct be_adapter *adapter, + CMD_SUBSYSTEM_ETH)) + return -EPERM; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -1659,7 +1659,7 @@ int lancer_cmd_get_pport_stats(struct be_adapter *adapter, + adapter->stats_cmd_sent = true; + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -1696,7 +1696,7 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u16 *link_speed, + struct be_cmd_req_link_status *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + if (link_status) + *link_status = LINK_DOWN; +@@ -1735,7 +1735,7 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u16 *link_speed, + } + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -1746,7 +1746,7 @@ int be_cmd_get_die_temperature(struct be_adapter *adapter) + struct be_cmd_req_get_cntl_addnl_attribs *req; + int status = 0; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -1761,7 +1761,7 @@ int be_cmd_get_die_temperature(struct be_adapter *adapter) + + status = be_mcc_notify(adapter); + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -1810,7 +1810,7 @@ int be_cmd_get_fat_dump(struct be_adapter *adapter, u32 buf_len, void *buf) + if (!get_fat_cmd.va) + return -ENOMEM; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + while (total_size) { + buf_size = min(total_size, (u32)60*1024); +@@ -1848,9 +1848,9 @@ int be_cmd_get_fat_dump(struct be_adapter *adapter, u32 buf_len, void *buf) + log_offset += buf_size; + } + err: ++ spin_unlock_bh(&adapter->mcc_lock); + dma_free_coherent(&adapter->pdev->dev, get_fat_cmd.size, + get_fat_cmd.va, get_fat_cmd.dma); +- mutex_unlock(&adapter->mcc_lock); + return status; + } + +@@ -1861,7 +1861,7 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter) + struct be_cmd_req_get_fw_version *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -1884,7 +1884,7 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter) + sizeof(adapter->fw_on_flash)); + } + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -1898,7 +1898,7 @@ static int __be_cmd_modify_eqd(struct be_adapter *adapter, + struct be_cmd_req_modify_eq_delay *req; + int status = 0, i; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -1921,7 +1921,7 @@ static int __be_cmd_modify_eqd(struct be_adapter *adapter, + + status = be_mcc_notify(adapter); + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -1948,7 +1948,7 @@ int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array, + struct be_cmd_req_vlan_config *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -1970,7 +1970,7 @@ int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array, + + status = be_mcc_notify_wait(adapter); + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -1981,7 +1981,7 @@ static int __be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value) + struct be_cmd_req_rx_filter *req = mem->va; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -2014,7 +2014,7 @@ static int __be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value) + + status = be_mcc_notify_wait(adapter); + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -2045,7 +2045,7 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc) + CMD_SUBSYSTEM_COMMON)) + return -EPERM; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -2065,7 +2065,7 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc) + status = be_mcc_notify_wait(adapter); + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + + if (base_status(status) == MCC_STATUS_FEATURE_NOT_SUPPORTED) + return -EOPNOTSUPP; +@@ -2084,7 +2084,7 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc) + CMD_SUBSYSTEM_COMMON)) + return -EPERM; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -2107,7 +2107,7 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc) + } + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -2188,7 +2188,7 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, + if (!(be_if_cap_flags(adapter) & BE_IF_FLAGS_RSS)) + return 0; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -2213,7 +2213,7 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, + + status = be_mcc_notify_wait(adapter); + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -2225,7 +2225,7 @@ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, + struct be_cmd_req_enable_disable_beacon *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -2246,7 +2246,7 @@ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, + status = be_mcc_notify_wait(adapter); + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -2257,7 +2257,7 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state) + struct be_cmd_req_get_beacon_state *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -2281,7 +2281,7 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state) + } + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -2305,7 +2305,7 @@ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter, + return -ENOMEM; + } + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -2327,7 +2327,7 @@ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter, + memcpy(data, resp->page_data + off, len); + } + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); + return status; + } +@@ -2344,7 +2344,7 @@ static int lancer_cmd_write_object(struct be_adapter *adapter, + void *ctxt = NULL; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + adapter->flash_status = 0; + + wrb = wrb_from_mccq(adapter); +@@ -2386,7 +2386,7 @@ static int lancer_cmd_write_object(struct be_adapter *adapter, + if (status) + goto err_unlock; + +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + + if (!wait_for_completion_timeout(&adapter->et_cmd_compl, + msecs_to_jiffies(60000))) +@@ -2405,7 +2405,7 @@ static int lancer_cmd_write_object(struct be_adapter *adapter, + return status; + + err_unlock: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -2459,7 +2459,7 @@ static int lancer_cmd_delete_object(struct be_adapter *adapter, + struct be_mcc_wrb *wrb; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -2477,7 +2477,7 @@ static int lancer_cmd_delete_object(struct be_adapter *adapter, + + status = be_mcc_notify_wait(adapter); + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -2490,7 +2490,7 @@ int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd, + struct lancer_cmd_resp_read_object *resp; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -2524,7 +2524,7 @@ int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd, + } + + err_unlock: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -2536,7 +2536,7 @@ static int be_cmd_write_flashrom(struct be_adapter *adapter, + struct be_cmd_write_flashrom *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + adapter->flash_status = 0; + + wrb = wrb_from_mccq(adapter); +@@ -2561,7 +2561,7 @@ static int be_cmd_write_flashrom(struct be_adapter *adapter, + if (status) + goto err_unlock; + +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + + if (!wait_for_completion_timeout(&adapter->et_cmd_compl, + msecs_to_jiffies(40000))) +@@ -2572,7 +2572,7 @@ static int be_cmd_write_flashrom(struct be_adapter *adapter, + return status; + + err_unlock: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -2583,7 +2583,7 @@ static int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, + struct be_mcc_wrb *wrb; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -2610,7 +2610,7 @@ static int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, + memcpy(flashed_crc, req->crc, 4); + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -3216,7 +3216,7 @@ int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, + struct be_cmd_req_acpi_wol_magic_config *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -3233,7 +3233,7 @@ int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, + status = be_mcc_notify_wait(adapter); + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -3248,7 +3248,7 @@ int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, + CMD_SUBSYSTEM_LOWLEVEL)) + return -EPERM; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -3271,7 +3271,7 @@ int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, + if (status) + goto err_unlock; + +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + + if (!wait_for_completion_timeout(&adapter->et_cmd_compl, + msecs_to_jiffies(SET_LB_MODE_TIMEOUT))) +@@ -3280,7 +3280,7 @@ int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, + return status; + + err_unlock: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -3297,7 +3297,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, + CMD_SUBSYSTEM_LOWLEVEL)) + return -EPERM; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -3323,7 +3323,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, + if (status) + goto err; + +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + + wait_for_completion(&adapter->et_cmd_compl); + resp = embedded_payload(wrb); +@@ -3331,7 +3331,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, + + return status; + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -3347,7 +3347,7 @@ int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern, + CMD_SUBSYSTEM_LOWLEVEL)) + return -EPERM; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -3381,7 +3381,7 @@ int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern, + } + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -3392,7 +3392,7 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter, + struct be_cmd_req_seeprom_read *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -3408,7 +3408,7 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter, + status = be_mcc_notify_wait(adapter); + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -3423,7 +3423,7 @@ int be_cmd_get_phy_info(struct be_adapter *adapter) + CMD_SUBSYSTEM_COMMON)) + return -EPERM; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -3468,7 +3468,7 @@ int be_cmd_get_phy_info(struct be_adapter *adapter) + } + dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -3478,7 +3478,7 @@ static int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain) + struct be_cmd_req_set_qos *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -3498,7 +3498,7 @@ static int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain) + status = be_mcc_notify_wait(adapter); + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -3610,7 +3610,7 @@ int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege, + struct be_cmd_req_get_fn_privileges *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -3642,7 +3642,7 @@ int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege, + } + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -3654,7 +3654,7 @@ int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges, + struct be_cmd_req_set_fn_privileges *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -3674,7 +3674,7 @@ int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges, + + status = be_mcc_notify_wait(adapter); + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -3706,7 +3706,7 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, + return -ENOMEM; + } + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -3770,7 +3770,7 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, + } + + out: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + dma_free_coherent(&adapter->pdev->dev, get_mac_list_cmd.size, + get_mac_list_cmd.va, get_mac_list_cmd.dma); + return status; +@@ -3830,7 +3830,7 @@ int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, + if (!cmd.va) + return -ENOMEM; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -3852,7 +3852,7 @@ int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, + + err: + dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -3888,7 +3888,7 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, + CMD_SUBSYSTEM_COMMON)) + return -EPERM; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -3929,7 +3929,7 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, + status = be_mcc_notify_wait(adapter); + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -3943,7 +3943,7 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid, + int status; + u16 vid; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -3990,7 +3990,7 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid, + } + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -4189,7 +4189,7 @@ int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter, + struct be_cmd_req_set_ext_fat_caps *req; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -4205,7 +4205,7 @@ int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter, + + status = be_mcc_notify_wait(adapter); + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -4683,7 +4683,7 @@ int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op) + if (iface == 0xFFFFFFFF) + return -1; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -4700,7 +4700,7 @@ int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op) + + status = be_mcc_notify_wait(adapter); + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -4734,7 +4734,7 @@ int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, + struct be_cmd_resp_get_iface_list *resp; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -4755,7 +4755,7 @@ int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg, + } + + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -4849,7 +4849,7 @@ int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain) + if (BEx_chip(adapter)) + return 0; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -4867,7 +4867,7 @@ int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain) + req->enable = 1; + status = be_mcc_notify_wait(adapter); + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -4940,7 +4940,7 @@ __be_cmd_set_logical_link_config(struct be_adapter *adapter, + u32 link_config = 0; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -4968,7 +4968,7 @@ __be_cmd_set_logical_link_config(struct be_adapter *adapter, + + status = be_mcc_notify_wait(adapter); + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -4999,8 +4999,7 @@ int be_cmd_set_features(struct be_adapter *adapter) + struct be_mcc_wrb *wrb; + int status; + +- if (mutex_lock_interruptible(&adapter->mcc_lock)) +- return -1; ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -5038,7 +5037,7 @@ int be_cmd_set_features(struct be_adapter *adapter) + dev_info(&adapter->pdev->dev, + "Adapter does not support HW error recovery\n"); + +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + +@@ -5052,7 +5051,7 @@ int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload, + struct be_cmd_resp_hdr *resp; + int status; + +- mutex_lock(&adapter->mcc_lock); ++ spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { +@@ -5075,7 +5074,7 @@ int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload, + memcpy(wrb_payload, resp, sizeof(*resp) + resp->response_length); + be_dws_le_to_cpu(wrb_payload, sizeof(*resp) + resp->response_length); + err: +- mutex_unlock(&adapter->mcc_lock); ++ spin_unlock_bh(&adapter->mcc_lock); + return status; + } + EXPORT_SYMBOL(be_roce_mcc_cmd); +diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c +index 13d5fe324d6c7f..c61dc7d05bcb45 100644 +--- a/drivers/net/ethernet/emulex/benet/be_main.c ++++ b/drivers/net/ethernet/emulex/benet/be_main.c +@@ -5673,8 +5673,8 @@ static int be_drv_init(struct be_adapter *adapter) + } + + mutex_init(&adapter->mbox_lock); +- mutex_init(&adapter->mcc_lock); + mutex_init(&adapter->rx_filter_lock); ++ spin_lock_init(&adapter->mcc_lock); + spin_lock_init(&adapter->mcc_cq_lock); + init_completion(&adapter->et_cmd_compl); + +diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c +index b51d54799669b9..612872c8c8e3c3 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc.c +@@ -121,6 +121,24 @@ static int enetc_ptp_parse(struct sk_buff *skb, u8 *udp, + return 0; + } + ++/** ++ * enetc_unwind_tx_frame() - Unwind the DMA mappings of a multi-buffer Tx frame ++ * @tx_ring: Pointer to the Tx ring on which the buffer descriptors are located ++ * @count: Number of Tx buffer descriptors which need to be unmapped ++ * @i: Index of the last successfully mapped Tx buffer descriptor ++ */ ++static void enetc_unwind_tx_frame(struct enetc_bdr *tx_ring, int count, int i) ++{ ++ while (count--) { ++ struct enetc_tx_swbd *tx_swbd = &tx_ring->tx_swbd[i]; ++ ++ enetc_free_tx_frame(tx_ring, tx_swbd); ++ if (i == 0) ++ i = tx_ring->bd_count; ++ i--; ++ } ++} ++ + static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb) + { + bool do_vlan, do_onestep_tstamp = false, do_twostep_tstamp = false; +@@ -210,9 +228,11 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb) + } + + if (do_onestep_tstamp) { +- u32 lo, hi, val; +- u64 sec, nsec; ++ __be32 new_sec_l, new_nsec; ++ u32 lo, hi, nsec, val; ++ __be16 new_sec_h; + u8 *data; ++ u64 sec; + + lo = enetc_rd_hot(hw, ENETC_SICTR0); + hi = enetc_rd_hot(hw, ENETC_SICTR1); +@@ -226,13 +246,38 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb) + /* Update originTimestamp field of Sync packet + * - 48 bits seconds field + * - 32 bits nanseconds field ++ * ++ * In addition, the UDP checksum needs to be updated ++ * by software after updating originTimestamp field, ++ * otherwise the hardware will calculate the wrong ++ * checksum when updating the correction field and ++ * update it to the packet. + */ + data = skb_mac_header(skb); +- *(__be16 *)(data + offset2) = +- htons((sec >> 32) & 0xffff); +- *(__be32 *)(data + offset2 + 2) = +- htonl(sec & 0xffffffff); +- *(__be32 *)(data + offset2 + 6) = htonl(nsec); ++ new_sec_h = htons((sec >> 32) & 0xffff); ++ new_sec_l = htonl(sec & 0xffffffff); ++ new_nsec = htonl(nsec); ++ if (udp) { ++ struct udphdr *uh = udp_hdr(skb); ++ __be32 old_sec_l, old_nsec; ++ __be16 old_sec_h; ++ ++ old_sec_h = *(__be16 *)(data + offset2); ++ inet_proto_csum_replace2(&uh->check, skb, old_sec_h, ++ new_sec_h, false); ++ ++ old_sec_l = *(__be32 *)(data + offset2 + 2); ++ inet_proto_csum_replace4(&uh->check, skb, old_sec_l, ++ new_sec_l, false); ++ ++ old_nsec = *(__be32 *)(data + offset2 + 6); ++ inet_proto_csum_replace4(&uh->check, skb, old_nsec, ++ new_nsec, false); ++ } ++ ++ *(__be16 *)(data + offset2) = new_sec_h; ++ *(__be32 *)(data + offset2 + 2) = new_sec_l; ++ *(__be32 *)(data + offset2 + 6) = new_nsec; + + /* Configure single-step register */ + val = ENETC_PM0_SINGLE_STEP_EN; +@@ -303,13 +348,7 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb) + dma_err: + dev_err(tx_ring->dev, "DMA map error"); + +- do { +- tx_swbd = &tx_ring->tx_swbd[i]; +- enetc_free_tx_frame(tx_ring, tx_swbd); +- if (i == 0) +- i = tx_ring->bd_count; +- i--; +- } while (count--); ++ enetc_unwind_tx_frame(tx_ring, count, i); + + return 0; + } +@@ -1304,7 +1343,7 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, + enetc_xdp_drop(rx_ring, orig_i, i); + tx_ring->stats.xdp_tx_drops++; + } else { +- tx_ring->stats.xdp_tx += xdp_tx_bd_cnt; ++ tx_ring->stats.xdp_tx++; + rx_ring->xdp.xdp_tx_in_flight += xdp_tx_bd_cnt; + xdp_tx_frm_cnt++; + /* The XDP_TX enqueue was successful, so we +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index 0a3cf22dc260b1..7b5585bc21d8f8 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -761,6 +761,8 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq, + struct fec_enet_private *fep = netdev_priv(ndev); + int hdr_len, total_len, data_left; + struct bufdesc *bdp = txq->bd.cur; ++ struct bufdesc *tmp_bdp; ++ struct bufdesc_ex *ebdp; + struct tso_t tso; + unsigned int index = 0; + int ret; +@@ -834,7 +836,34 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq, + return 0; + + err_release: +- /* TODO: Release all used data descriptors for TSO */ ++ /* Release all used data descriptors for TSO */ ++ tmp_bdp = txq->bd.cur; ++ ++ while (tmp_bdp != bdp) { ++ /* Unmap data buffers */ ++ if (tmp_bdp->cbd_bufaddr && ++ !IS_TSO_HEADER(txq, fec32_to_cpu(tmp_bdp->cbd_bufaddr))) ++ dma_unmap_single(&fep->pdev->dev, ++ fec32_to_cpu(tmp_bdp->cbd_bufaddr), ++ fec16_to_cpu(tmp_bdp->cbd_datlen), ++ DMA_TO_DEVICE); ++ ++ /* Clear standard buffer descriptor fields */ ++ tmp_bdp->cbd_sc = 0; ++ tmp_bdp->cbd_datlen = 0; ++ tmp_bdp->cbd_bufaddr = 0; ++ ++ /* Handle extended descriptor if enabled */ ++ if (fep->bufdesc_ex) { ++ ebdp = (struct bufdesc_ex *)tmp_bdp; ++ ebdp->cbd_esc = 0; ++ } ++ ++ tmp_bdp = fec_enet_get_nextdesc(tmp_bdp, &txq->bd); ++ } ++ ++ dev_kfree_skb_any(skb); ++ + return ret; + } + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.c b/drivers/net/ethernet/hisilicon/hns3/hnae3.c +index 9a63fbc6940831..b25fb400f4767e 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.c +@@ -40,6 +40,21 @@ EXPORT_SYMBOL(hnae3_unregister_ae_algo_prepare); + */ + static DEFINE_MUTEX(hnae3_common_lock); + ++/* ensure the drivers being unloaded one by one */ ++static DEFINE_MUTEX(hnae3_unload_lock); ++ ++void hnae3_acquire_unload_lock(void) ++{ ++ mutex_lock(&hnae3_unload_lock); ++} ++EXPORT_SYMBOL(hnae3_acquire_unload_lock); ++ ++void hnae3_release_unload_lock(void) ++{ ++ mutex_unlock(&hnae3_unload_lock); ++} ++EXPORT_SYMBOL(hnae3_release_unload_lock); ++ + static bool hnae3_client_match(enum hnae3_client_type client_type) + { + if (client_type == HNAE3_CLIENT_KNIC || +diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h +index f362a2fac3c297..fa16cdcee10db0 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h ++++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h +@@ -885,4 +885,6 @@ int hnae3_register_client(struct hnae3_client *client); + void hnae3_set_client_init_flag(struct hnae3_client *client, + struct hnae3_ae_dev *ae_dev, + unsigned int inited); ++void hnae3_acquire_unload_lock(void); ++void hnae3_release_unload_lock(void); + #endif +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +index d6bdcd9f285b0a..60592e8ddf3b81 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -5720,9 +5720,11 @@ module_init(hns3_init_module); + */ + static void __exit hns3_exit_module(void) + { ++ hnae3_acquire_unload_lock(); + pci_unregister_driver(&hns3_driver); + hnae3_unregister_client(&client); + hns3_dbg_unregister_debugfs(); ++ hnae3_release_unload_lock(); + } + module_exit(hns3_exit_module); + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index eb902e80a8158e..35411f9a143238 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -13300,9 +13300,11 @@ static int hclge_init(void) + + static void hclge_exit(void) + { ++ hnae3_acquire_unload_lock(); + hnae3_unregister_ae_algo_prepare(&ae_algo); + hnae3_unregister_ae_algo(&ae_algo); + destroy_workqueue(hclge_wq); ++ hnae3_release_unload_lock(); + } + module_init(hclge_init); + module_exit(hclge_exit); +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c +index 0f06f95b09bc28..4d4cea1f501577 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c +@@ -496,7 +496,7 @@ int hclge_ptp_init(struct hclge_dev *hdev) + + ret = hclge_ptp_get_cycle(hdev); + if (ret) +- return ret; ++ goto out; + } + + ret = hclge_ptp_int_en(hdev, true); +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index 5b861a2a3e73e4..7bb01eafba7459 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -3947,8 +3947,10 @@ static int hclgevf_init(void) + + static void hclgevf_exit(void) + { ++ hnae3_acquire_unload_lock(); + hnae3_unregister_ae_algo(&ae_algovf); + destroy_workqueue(hclgevf_wq); ++ hnae3_release_unload_lock(); + } + module_init(hclgevf_init); + module_exit(hclgevf_exit); +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c +index 40aeaa7bd739fa..d2757cc1161391 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c +@@ -324,7 +324,7 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = { + MVPP2_PRS_RI_VLAN_MASK), + /* Non IP flow, with vlan tag */ + MVPP2_DEF_FLOW(MVPP22_FLOW_ETHERNET, MVPP2_FL_NON_IP_TAG, +- MVPP22_CLS_HEK_OPT_VLAN, ++ MVPP22_CLS_HEK_TAGGED, + 0, 0), + }; + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +index 6fece284de0f35..26d91b080d3c48 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +@@ -177,17 +177,16 @@ static void mlx5_pps_out(struct work_struct *work) + } + } + +-static void mlx5_timestamp_overflow(struct work_struct *work) ++static long mlx5_timestamp_overflow(struct ptp_clock_info *ptp_info) + { +- struct delayed_work *dwork = to_delayed_work(work); + struct mlx5_core_dev *mdev; + struct mlx5_timer *timer; + struct mlx5_clock *clock; + unsigned long flags; + +- timer = container_of(dwork, struct mlx5_timer, overflow_work); +- clock = container_of(timer, struct mlx5_clock, timer); ++ clock = container_of(ptp_info, struct mlx5_clock, ptp_info); + mdev = container_of(clock, struct mlx5_core_dev, clock); ++ timer = &clock->timer; + + if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) + goto out; +@@ -198,7 +197,7 @@ static void mlx5_timestamp_overflow(struct work_struct *work) + write_sequnlock_irqrestore(&clock->lock, flags); + + out: +- schedule_delayed_work(&timer->overflow_work, timer->overflow_period); ++ return timer->overflow_period; + } + + static int mlx5_ptp_settime_real_time(struct mlx5_core_dev *mdev, +@@ -366,6 +365,7 @@ static int mlx5_ptp_adjfreq(struct ptp_clock_info *ptp, s32 delta) + timer->nominal_c_mult + diff; + mlx5_update_clock_info_page(mdev); + write_sequnlock_irqrestore(&clock->lock, flags); ++ ptp_schedule_worker(clock->ptp, timer->overflow_period); + + return 0; + } +@@ -616,6 +616,7 @@ static const struct ptp_clock_info mlx5_ptp_clock_info = { + .settime64 = mlx5_ptp_settime, + .enable = NULL, + .verify = NULL, ++ .do_aux_work = mlx5_timestamp_overflow, + }; + + static int mlx5_query_mtpps_pin_mode(struct mlx5_core_dev *mdev, u8 pin, +@@ -809,12 +810,11 @@ static void mlx5_init_overflow_period(struct mlx5_clock *clock) + do_div(ns, NSEC_PER_SEC / HZ); + timer->overflow_period = ns; + +- INIT_DELAYED_WORK(&timer->overflow_work, mlx5_timestamp_overflow); +- if (timer->overflow_period) +- schedule_delayed_work(&timer->overflow_work, 0); +- else ++ if (!timer->overflow_period) { ++ timer->overflow_period = HZ; + mlx5_core_warn(mdev, +- "invalid overflow period, overflow_work is not scheduled\n"); ++ "invalid overflow period, overflow_work is scheduled once per second\n"); ++ } + + if (clock_info) + clock_info->overflow_period = timer->overflow_period; +@@ -900,6 +900,9 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev) + + MLX5_NB_INIT(&clock->pps_nb, mlx5_pps_event, PPS_EVENT); + mlx5_eq_notifier_register(mdev, &clock->pps_nb); ++ ++ if (clock->ptp) ++ ptp_schedule_worker(clock->ptp, 0); + } + + void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) +@@ -916,7 +919,6 @@ void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) + } + + cancel_work_sync(&clock->pps_info.out_work); +- cancel_delayed_work_sync(&clock->timer.overflow_work); + + if (mdev->clock_info) { + free_page((unsigned long)mdev->clock_info); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mr.c b/drivers/net/ethernet/mellanox/mlx5/core/mr.c +index 174f71ed52800c..d239d559994fad 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/mr.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/mr.c +@@ -52,7 +52,6 @@ int mlx5_core_create_mkey(struct mlx5_core_dev *dev, + + mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); + mkey_index = MLX5_GET(create_mkey_out, lout, mkey_index); +- mkey->iova = MLX5_GET64(mkc, mkc, start_addr); + mkey->size = MLX5_GET64(mkc, mkc, len); + mkey->key = (u32)mlx5_mkey_variant(mkey->key) | mlx5_idx_to_mkey(mkey_index); + mkey->pd = MLX5_GET(mkc, mkc, pd); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +index 2fa84556bc20ee..4c78821f5edb36 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +@@ -474,7 +474,7 @@ irq_pool_alloc(struct mlx5_core_dev *dev, int start, int size, char *name, + pool->min_threshold = min_threshold * MLX5_EQ_REFS_PER_IRQ; + pool->max_threshold = max_threshold * MLX5_EQ_REFS_PER_IRQ; + mlx5_core_dbg(dev, "pool->name = %s, pool->size = %d, pool->start = %d", +- name, size, start); ++ name ? name : "mlx5_pcif_pool", size, start); + return pool; + } + +diff --git a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c +index 46245e0b24623d..43c84900369a36 100644 +--- a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c ++++ b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c +@@ -14,7 +14,6 @@ + #define MLXFW_FSM_STATE_WAIT_TIMEOUT_MS 30000 + #define MLXFW_FSM_STATE_WAIT_ROUNDS \ + (MLXFW_FSM_STATE_WAIT_TIMEOUT_MS / MLXFW_FSM_STATE_WAIT_CYCLE_MS) +-#define MLXFW_FSM_MAX_COMPONENT_SIZE (10 * (1 << 20)) + + static const int mlxfw_fsm_state_errno[] = { + [MLXFW_FSM_STATE_ERR_ERROR] = -EIO, +@@ -229,7 +228,6 @@ static int mlxfw_flash_component(struct mlxfw_dev *mlxfw_dev, + return err; + } + +- comp_max_size = min_t(u32, comp_max_size, MLXFW_FSM_MAX_COMPONENT_SIZE); + if (comp->data_size > comp_max_size) { + MLXFW_ERR_MSG(mlxfw_dev, extack, + "Component size is bigger than limit", -EINVAL); +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c +index 267590a0eee78c..c9a29716f1c7b0 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c +@@ -761,7 +761,9 @@ static void __mlxsw_sp_port_get_stats(struct net_device *dev, + err = mlxsw_sp_get_hw_stats_by_group(&hw_stats, &len, grp); + if (err) + return; +- mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl); ++ err = mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl); ++ if (err) ++ return; + for (i = 0; i < len; i++) { + data[data_index + i] = hw_stats[i].getter(ppcnt_pl); + if (!hw_stats[i].cells_bytes) +diff --git a/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c b/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c +index 2ec62c8d86e1c1..59486fe2ad18c2 100644 +--- a/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c ++++ b/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c +@@ -20,6 +20,8 @@ nfp_bpf_cmsg_alloc(struct nfp_app_bpf *bpf, unsigned int size) + struct sk_buff *skb; + + skb = nfp_app_ctrl_msg_alloc(bpf->app, size, GFP_KERNEL); ++ if (!skb) ++ return NULL; + skb_put(skb, size); + + return skb; +diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c +index b6e426d8014d12..183db093815cb8 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -3476,10 +3476,12 @@ static int sh_eth_suspend(struct device *dev) + + netif_device_detach(ndev); + ++ rtnl_lock(); + if (mdp->wol_enabled) + ret = sh_eth_wol_setup(ndev); + else + ret = sh_eth_close(ndev); ++ rtnl_unlock(); + + return ret; + } +@@ -3493,10 +3495,12 @@ static int sh_eth_resume(struct device *dev) + if (!netif_running(ndev)) + return 0; + ++ rtnl_lock(); + if (mdp->wol_enabled) + ret = sh_eth_wol_restore(ndev); + else + ret = sh_eth_open(ndev); ++ rtnl_unlock(); + + if (ret < 0) + return ret; +diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +index 4bd57b79a023b1..c2700fcfc10e2c 100644 +--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c ++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +@@ -1546,7 +1546,7 @@ void am65_cpsw_nuss_remove_tx_chns(struct am65_cpsw_common *common) + for (i = 0; i < common->tx_ch_num; i++) { + struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i]; + +- if (tx_chn->irq) ++ if (tx_chn->irq > 0) + devm_free_irq(dev, tx_chn->irq, tx_chn); + + netif_napi_del(&tx_chn->napi_tx); +diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c +index 10e3d69205a4f0..c51b39390c0158 100644 +--- a/drivers/net/geneve.c ++++ b/drivers/net/geneve.c +@@ -1960,21 +1960,9 @@ static void geneve_destroy_tunnels(struct net *net, struct list_head *head) + { + struct geneve_net *gn = net_generic(net, geneve_net_id); + struct geneve_dev *geneve, *next; +- struct net_device *dev, *aux; + +- /* gather any geneve devices that were moved into this ns */ +- for_each_netdev_safe(net, dev, aux) +- if (dev->rtnl_link_ops == &geneve_link_ops) +- unregister_netdevice_queue(dev, head); +- +- /* now gather any other geneve devices that were created in this ns */ +- list_for_each_entry_safe(geneve, next, &gn->geneve_list, next) { +- /* If geneve->dev is in the same netns, it was already added +- * to the list by the previous loop. +- */ +- if (!net_eq(dev_net(geneve->dev), net)) +- unregister_netdevice_queue(geneve->dev, head); +- } ++ list_for_each_entry_safe(geneve, next, &gn->geneve_list, next) ++ geneve_dellink(geneve->dev, head); + } + + static void __net_exit geneve_exit_batch_net(struct list_head *net_list) +diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c +index 2d306971d4fde6..8f76fd927ff4a2 100644 +--- a/drivers/net/gtp.c ++++ b/drivers/net/gtp.c +@@ -1414,11 +1414,6 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list, + list_for_each_entry(net, net_list, exit_list) { + struct gtp_net *gn = net_generic(net, gtp_net_id); + struct gtp_dev *gtp, *gtp_next; +- struct net_device *dev; +- +- for_each_netdev(net, dev) +- if (dev->rtnl_link_ops == >p_link_ops) +- gtp_dellink(dev, dev_to_kill); + + list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list) + gtp_dellink(gtp->dev, dev_to_kill); +diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c +index 498e5c8013efb3..0160a4f57ce929 100644 +--- a/drivers/net/loopback.c ++++ b/drivers/net/loopback.c +@@ -243,8 +243,22 @@ static netdev_tx_t blackhole_netdev_xmit(struct sk_buff *skb, + return NETDEV_TX_OK; + } + ++static int blackhole_neigh_output(struct neighbour *n, struct sk_buff *skb) ++{ ++ kfree_skb(skb); ++ return 0; ++} ++ ++static int blackhole_neigh_construct(struct net_device *dev, ++ struct neighbour *n) ++{ ++ n->output = blackhole_neigh_output; ++ return 0; ++} ++ + static const struct net_device_ops blackhole_netdev_ops = { + .ndo_start_xmit = blackhole_netdev_xmit, ++ .ndo_neigh_construct = blackhole_neigh_construct, + }; + + /* This is a dst-dummy device used specifically for invalidated +diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c +index feca55eef99381..ec1fc1d3ea361e 100644 +--- a/drivers/net/netdevsim/ipsec.c ++++ b/drivers/net/netdevsim/ipsec.c +@@ -39,10 +39,14 @@ static ssize_t nsim_dbg_netdev_ops_read(struct file *filp, + if (!sap->used) + continue; + +- p += scnprintf(p, bufsize - (p - buf), +- "sa[%i] %cx ipaddr=0x%08x %08x %08x %08x\n", +- i, (sap->rx ? 'r' : 't'), sap->ipaddr[0], +- sap->ipaddr[1], sap->ipaddr[2], sap->ipaddr[3]); ++ if (sap->xs->props.family == AF_INET6) ++ p += scnprintf(p, bufsize - (p - buf), ++ "sa[%i] %cx ipaddr=%pI6c\n", ++ i, (sap->rx ? 'r' : 't'), &sap->ipaddr); ++ else ++ p += scnprintf(p, bufsize - (p - buf), ++ "sa[%i] %cx ipaddr=%pI4\n", ++ i, (sap->rx ? 'r' : 't'), &sap->ipaddr[3]); + p += scnprintf(p, bufsize - (p - buf), + "sa[%i] spi=0x%08x proto=0x%x salt=0x%08x crypt=%d\n", + i, be32_to_cpu(sap->xs->id.spi), +diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h +index 793c86dc5a9c17..902c74a74c56d8 100644 +--- a/drivers/net/netdevsim/netdevsim.h ++++ b/drivers/net/netdevsim/netdevsim.h +@@ -97,6 +97,7 @@ struct netdevsim { + u32 sleep; + u32 __ports[2][NSIM_UDP_TUNNEL_N_PORTS]; + u32 (*ports)[NSIM_UDP_TUNNEL_N_PORTS]; ++ struct dentry *ddir; + struct debugfs_u32_array dfs_ports[2]; + } udp_ports; + +diff --git a/drivers/net/netdevsim/udp_tunnels.c b/drivers/net/netdevsim/udp_tunnels.c +index 02dc3123eb6c16..640b4983a9a0d1 100644 +--- a/drivers/net/netdevsim/udp_tunnels.c ++++ b/drivers/net/netdevsim/udp_tunnels.c +@@ -112,9 +112,11 @@ nsim_udp_tunnels_info_reset_write(struct file *file, const char __user *data, + struct net_device *dev = file->private_data; + struct netdevsim *ns = netdev_priv(dev); + +- memset(ns->udp_ports.ports, 0, sizeof(ns->udp_ports.__ports)); + rtnl_lock(); +- udp_tunnel_nic_reset_ntf(dev); ++ if (dev->reg_state == NETREG_REGISTERED) { ++ memset(ns->udp_ports.ports, 0, sizeof(ns->udp_ports.__ports)); ++ udp_tunnel_nic_reset_ntf(dev); ++ } + rtnl_unlock(); + + return count; +@@ -144,23 +146,23 @@ int nsim_udp_tunnels_info_create(struct nsim_dev *nsim_dev, + else + ns->udp_ports.ports = nsim_dev->udp_ports.__ports; + +- debugfs_create_u32("udp_ports_inject_error", 0600, +- ns->nsim_dev_port->ddir, ++ ns->udp_ports.ddir = debugfs_create_dir("udp_ports", ++ ns->nsim_dev_port->ddir); ++ ++ debugfs_create_u32("inject_error", 0600, ns->udp_ports.ddir, + &ns->udp_ports.inject_error); + + ns->udp_ports.dfs_ports[0].array = ns->udp_ports.ports[0]; + ns->udp_ports.dfs_ports[0].n_elements = NSIM_UDP_TUNNEL_N_PORTS; +- debugfs_create_u32_array("udp_ports_table0", 0400, +- ns->nsim_dev_port->ddir, ++ debugfs_create_u32_array("table0", 0400, ns->udp_ports.ddir, + &ns->udp_ports.dfs_ports[0]); + + ns->udp_ports.dfs_ports[1].array = ns->udp_ports.ports[1]; + ns->udp_ports.dfs_ports[1].n_elements = NSIM_UDP_TUNNEL_N_PORTS; +- debugfs_create_u32_array("udp_ports_table1", 0400, +- ns->nsim_dev_port->ddir, ++ debugfs_create_u32_array("table1", 0400, ns->udp_ports.ddir, + &ns->udp_ports.dfs_ports[1]); + +- debugfs_create_file("udp_ports_reset", 0200, ns->nsim_dev_port->ddir, ++ debugfs_create_file("reset", 0200, ns->udp_ports.ddir, + dev, &nsim_udp_tunnels_info_reset_fops); + + /* Note: it's not normal to allocate the info struct like this! +@@ -196,6 +198,9 @@ int nsim_udp_tunnels_info_create(struct nsim_dev *nsim_dev, + + void nsim_udp_tunnels_info_destroy(struct net_device *dev) + { ++ struct netdevsim *ns = netdev_priv(dev); ++ ++ debugfs_remove_recursive(ns->udp_ports.ddir); + kfree(dev->udp_tunnel_nic_info); + dev->udp_tunnel_nic_info = NULL; + } +diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c +index a3196c04caf68d..13269c4e87ddd5 100644 +--- a/drivers/net/phy/nxp-c45-tja11xx.c ++++ b/drivers/net/phy/nxp-c45-tja11xx.c +@@ -717,6 +717,8 @@ static int nxp_c45_soft_reset(struct phy_device *phydev) + if (ret) + return ret; + ++ usleep_range(2000, 2050); ++ + return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, + VEND1_DEVICE_CONTROL, ret, + !(ret & DEVICE_CONTROL_RESET), 20000, +diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c +index 590a8b2153392f..3e804800c509d5 100644 +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -72,6 +72,17 @@ + #define PPP_PROTO_LEN 2 + #define PPP_LCP_HDRLEN 4 + ++/* The filter instructions generated by libpcap are constructed ++ * assuming a four-byte PPP header on each packet, where the last ++ * 2 bytes are the protocol field defined in the RFC and the first ++ * byte of the first 2 bytes indicates the direction. ++ * The second byte is currently unused, but we still need to initialize ++ * it to prevent crafted BPF programs from reading them which would ++ * cause reading of uninitialized data. ++ */ ++#define PPP_FILTER_OUTBOUND_TAG 0x0100 ++#define PPP_FILTER_INBOUND_TAG 0x0000 ++ + /* + * An instance of /dev/ppp can be associated with either a ppp + * interface unit or a ppp channel. In both cases, file->private_data +@@ -1761,10 +1772,10 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) + + if (proto < 0x8000) { + #ifdef CONFIG_PPP_FILTER +- /* check if we should pass this packet */ +- /* the filter instructions are constructed assuming +- a four-byte PPP header on each packet */ +- *(u8 *)skb_push(skb, 2) = 1; ++ /* check if the packet passes the pass and active filters. ++ * See comment for PPP_FILTER_OUTBOUND_TAG above. ++ */ ++ *(__be16 *)skb_push(skb, 2) = htons(PPP_FILTER_OUTBOUND_TAG); + if (ppp->pass_filter && + bpf_prog_run(ppp->pass_filter, skb) == 0) { + if (ppp->debug & 1) +@@ -2481,14 +2492,13 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) + /* network protocol frame - give it to the kernel */ + + #ifdef CONFIG_PPP_FILTER +- /* check if the packet passes the pass and active filters */ +- /* the filter instructions are constructed assuming +- a four-byte PPP header on each packet */ + if (ppp->pass_filter || ppp->active_filter) { + if (skb_unclone(skb, GFP_ATOMIC)) + goto err; +- +- *(u8 *)skb_push(skb, 2) = 0; ++ /* Check if the packet passes the pass and active filters. ++ * See comment for PPP_FILTER_INBOUND_TAG above. ++ */ ++ *(__be16 *)skb_push(skb, 2) = htons(PPP_FILTER_INBOUND_TAG); + if (ppp->pass_filter && + bpf_prog_run(ppp->pass_filter, skb) == 0) { + if (ppp->debug & 1) +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index 5e5af71a85ac19..1e0adeb5e177cb 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -1166,6 +1166,13 @@ static int team_port_add(struct team *team, struct net_device *port_dev, + return -EBUSY; + } + ++ if (netdev_has_upper_dev(port_dev, dev)) { ++ NL_SET_ERR_MSG(extack, "Device is already a lower device of the team interface"); ++ netdev_err(dev, "Device %s is already a lower device of the team interface\n", ++ portname); ++ return -EBUSY; ++ } ++ + if (port_dev->features & NETIF_F_VLAN_CHALLENGED && + vlan_uses_dev(dev)) { + NL_SET_ERR_MSG(extack, "Device is VLAN challenged and team device has VLAN set up"); +@@ -2658,7 +2665,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) + ctx.data.u32_val = nla_get_u32(attr_data); + break; + case TEAM_OPTION_TYPE_STRING: +- if (nla_len(attr_data) > TEAM_STRING_MAX_LEN) { ++ if (nla_len(attr_data) > TEAM_STRING_MAX_LEN || ++ !memchr(nla_data(attr_data), '\0', ++ nla_len(attr_data))) { + err = -EINVAL; + goto team_put; + } +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index 959ca6b9cd138a..5c9e7d0beffa26 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -581,7 +581,7 @@ static inline bool tun_not_capable(struct tun_struct *tun) + struct net *net = dev_net(tun->dev); + + return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || +- (gid_valid(tun->group) && !in_egroup_p(tun->group))) && ++ (gid_valid(tun->group) && !in_egroup_p(tun->group))) && + !ns_capable(net->user_ns, CAP_NET_ADMIN); + } + +diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c +index 13a9a83b853800..8c2838cba77bc1 100644 +--- a/drivers/net/usb/gl620a.c ++++ b/drivers/net/usb/gl620a.c +@@ -179,9 +179,7 @@ static int genelink_bind(struct usbnet *dev, struct usb_interface *intf) + { + dev->hard_mtu = GL_RCV_BUF_SIZE; + dev->net->hard_header_len += 4; +- dev->in = usb_rcvbulkpipe(dev->udev, dev->driver_info->in); +- dev->out = usb_sndbulkpipe(dev->udev, dev->driver_info->out); +- return 0; ++ return usbnet_get_endpoints(dev, intf); + } + + static const struct driver_info genelink_info = { +diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c +index 17b87aba11d194..d5aa92660217cc 100644 +--- a/drivers/net/usb/rtl8150.c ++++ b/drivers/net/usb/rtl8150.c +@@ -71,6 +71,14 @@ + #define MSR_SPEED (1<<3) + #define MSR_LINK (1<<2) + ++/* USB endpoints */ ++enum rtl8150_usb_ep { ++ RTL8150_USB_EP_CONTROL = 0, ++ RTL8150_USB_EP_BULK_IN = 1, ++ RTL8150_USB_EP_BULK_OUT = 2, ++ RTL8150_USB_EP_INT_IN = 3, ++}; ++ + /* Interrupt pipe data */ + #define INT_TSR 0x00 + #define INT_RSR 0x01 +@@ -867,6 +875,13 @@ static int rtl8150_probe(struct usb_interface *intf, + struct usb_device *udev = interface_to_usbdev(intf); + rtl8150_t *dev; + struct net_device *netdev; ++ static const u8 bulk_ep_addr[] = { ++ RTL8150_USB_EP_BULK_IN | USB_DIR_IN, ++ RTL8150_USB_EP_BULK_OUT | USB_DIR_OUT, ++ 0}; ++ static const u8 int_ep_addr[] = { ++ RTL8150_USB_EP_INT_IN | USB_DIR_IN, ++ 0}; + + netdev = alloc_etherdev(sizeof(rtl8150_t)); + if (!netdev) +@@ -880,6 +895,13 @@ static int rtl8150_probe(struct usb_interface *intf, + return -ENOMEM; + } + ++ /* Verify that all required endpoints are present */ ++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || ++ !usb_check_int_endpoints(intf, int_ep_addr)) { ++ dev_err(&intf->dev, "couldn't find required endpoints\n"); ++ goto out; ++ } ++ + tasklet_setup(&dev->tl, rx_fixup); + spin_lock_init(&dev->rx_pool_lock); + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +index f03fc6f1f83331..2ca4fb4b949dd0 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -550,6 +550,11 @@ void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success) + struct ethhdr *eh; + u16 type; + ++ if (!ifp) { ++ brcmu_pkt_buf_free_skb(txp); ++ return; ++ } ++ + eh = (struct ethhdr *)(txp->data); + type = ntohs(eh->h_proto); + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +index 8580a275478918..42e7bc67e9143e 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +@@ -23427,6 +23427,9 @@ wlc_phy_iqcal_gainparams_nphy(struct brcms_phy *pi, u16 core_no, + break; + } + ++ if (WARN_ON(k == NPHY_IQCAL_NUMGAINS)) ++ return; ++ + params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1]; + params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2]; + params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3]; +diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +index 0b1c6bf729c3eb..eefd42ea535cd5 100644 +--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c ++++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +@@ -98,7 +98,7 @@ static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func, + size_t expected_size) + { + union acpi_object *obj; +- int ret = 0; ++ int ret; + + obj = iwl_acpi_get_dsm_object(dev, rev, func, NULL, guid); + if (IS_ERR(obj)) { +@@ -113,8 +113,10 @@ static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func, + } else if (obj->type == ACPI_TYPE_BUFFER) { + __le64 le_value = 0; + +- if (WARN_ON_ONCE(expected_size > sizeof(le_value))) +- return -EINVAL; ++ if (WARN_ON_ONCE(expected_size > sizeof(le_value))) { ++ ret = -EINVAL; ++ goto out; ++ } + + /* if the buffer size doesn't match the expected size */ + if (obj->buffer.length != expected_size) +@@ -135,8 +137,9 @@ static int iwl_acpi_get_dsm_integer(struct device *dev, int rev, int func, + } + + IWL_DEBUG_DEV_RADIO(dev, +- "ACPI: DSM method evaluated: func=%d, ret=%d\n", +- func, ret); ++ "ACPI: DSM method evaluated: func=%d, value=%lld\n", ++ func, *value); ++ ret = 0; + out: + ACPI_FREE(obj); + return ret; +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +index afa89deb7bc3a5..144aa1825286e9 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +@@ -1071,7 +1071,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, + + if (tlv_len != sizeof(*fseq_ver)) + goto invalid_tlv_len; +- IWL_INFO(drv, "TLV_FW_FSEQ_VERSION: %s\n", ++ IWL_INFO(drv, "TLV_FW_FSEQ_VERSION: %.32s\n", + fseq_ver->version); + } + break; +diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c +index 392632c3f1b1d4..e40569fc7edea1 100644 +--- a/drivers/net/wireless/mediatek/mt76/usb.c ++++ b/drivers/net/wireless/mediatek/mt76/usb.c +@@ -34,9 +34,9 @@ static int __mt76u_vendor_request(struct mt76_dev *dev, u8 req, + + ret = usb_control_msg(udev, pipe, req, req_type, val, + offset, buf, len, MT_VEND_REQ_TOUT_MS); +- if (ret == -ENODEV) ++ if (ret == -ENODEV || ret == -EPROTO) + set_bit(MT76_REMOVED, &dev->phy.state); +- if (ret >= 0 || ret == -ENODEV) ++ if (ret >= 0 || ret == -ENODEV || ret == -EPROTO) + return ret; + usleep_range(5000, 10000); + } +diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c +index ffd150ec181fab..1d6f46f5215395 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/base.c ++++ b/drivers/net/wireless/realtek/rtlwifi/base.c +@@ -452,8 +452,7 @@ static int _rtl_init_deferred_work(struct ieee80211_hw *hw) + /* <1> timer */ + timer_setup(&rtlpriv->works.watchdog_timer, + rtl_watch_dog_timer_callback, 0); +- timer_setup(&rtlpriv->works.dualmac_easyconcurrent_retrytimer, +- rtl_easy_concurrent_retrytimer_callback, 0); ++ + /* <2> work queue */ + rtlpriv->works.hw = hw; + rtlpriv->works.rtl_wq = wq; +@@ -576,9 +575,15 @@ static void rtl_free_entries_from_ack_queue(struct ieee80211_hw *hw, + + void rtl_deinit_core(struct ieee80211_hw *hw) + { ++ struct rtl_priv *rtlpriv = rtl_priv(hw); ++ + rtl_c2hcmd_launcher(hw, 0); + rtl_free_entries_from_scan_list(hw); + rtl_free_entries_from_ack_queue(hw, false); ++ if (rtlpriv->works.rtl_wq) { ++ destroy_workqueue(rtlpriv->works.rtl_wq); ++ rtlpriv->works.rtl_wq = NULL; ++ } + } + EXPORT_SYMBOL_GPL(rtl_deinit_core); + +@@ -1994,8 +1999,7 @@ void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb) + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + unsigned long flags; + +- struct rtl_bssid_entry *entry; +- bool entry_found = false; ++ struct rtl_bssid_entry *entry = NULL, *iter; + + /* check if it is scanning */ + if (!mac->act_scanning) +@@ -2008,10 +2012,10 @@ void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb) + + spin_lock_irqsave(&rtlpriv->locks.scan_list_lock, flags); + +- list_for_each_entry(entry, &rtlpriv->scan_list.list, list) { +- if (memcmp(entry->bssid, hdr->addr3, ETH_ALEN) == 0) { +- list_del_init(&entry->list); +- entry_found = true; ++ list_for_each_entry(iter, &rtlpriv->scan_list.list, list) { ++ if (memcmp(iter->bssid, hdr->addr3, ETH_ALEN) == 0) { ++ list_del_init(&iter->list); ++ entry = iter; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Update BSSID=%pM to scan list (total=%d)\n", + hdr->addr3, rtlpriv->scan_list.num); +@@ -2019,7 +2023,7 @@ void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb) + } + } + +- if (!entry_found) { ++ if (!entry) { + entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + + if (!entry) +@@ -2366,19 +2370,6 @@ static void rtl_c2hcmd_wq_callback(struct work_struct *work) + rtl_c2hcmd_launcher(hw, 1); + } + +-void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t) +-{ +- struct rtl_priv *rtlpriv = +- from_timer(rtlpriv, t, works.dualmac_easyconcurrent_retrytimer); +- struct ieee80211_hw *hw = rtlpriv->hw; +- struct rtl_priv *buddy_priv = rtlpriv->buddy_priv; +- +- if (buddy_priv == NULL) +- return; +- +- rtlpriv->cfg->ops->dualmac_easy_concurrent(hw); +-} +- + /********************************************************* + * + * frame process functions +@@ -2724,9 +2715,6 @@ MODULE_AUTHOR("Larry Finger "); + MODULE_LICENSE("GPL"); + MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); + +-struct rtl_global_var rtl_global_var = {}; +-EXPORT_SYMBOL_GPL(rtl_global_var); +- + static int __init rtl_core_module_init(void) + { + BUILD_BUG_ON(TX_PWR_BY_RATE_NUM_RATE < TX_PWR_BY_RATE_NUM_SECTION); +@@ -2740,10 +2728,6 @@ static int __init rtl_core_module_init(void) + /* add debugfs */ + rtl_debugfs_add_topdir(); + +- /* init some global vars */ +- INIT_LIST_HEAD(&rtl_global_var.glb_priv_list); +- spin_lock_init(&rtl_global_var.glb_list_lock); +- + return 0; + } + +diff --git a/drivers/net/wireless/realtek/rtlwifi/base.h b/drivers/net/wireless/realtek/rtlwifi/base.h +index 0e4f8a8ae3a5fc..f3a6a43a42eca8 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/base.h ++++ b/drivers/net/wireless/realtek/rtlwifi/base.h +@@ -124,8 +124,6 @@ int rtl_send_smps_action(struct ieee80211_hw *hw, + u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie); + void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); + u8 rtl_tid_to_ac(u8 tid); +-void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t); +-extern struct rtl_global_var rtl_global_var; + void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation); + + #endif +diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c +index 6d9f2a6233a210..925e4f807eb9f1 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/pci.c ++++ b/drivers/net/wireless/realtek/rtlwifi/pci.c +@@ -295,47 +295,6 @@ static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw) + return status; + } + +-static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw, +- struct rtl_priv **buddy_priv) +-{ +- struct rtl_priv *rtlpriv = rtl_priv(hw); +- struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +- bool find_buddy_priv = false; +- struct rtl_priv *tpriv; +- struct rtl_pci_priv *tpcipriv = NULL; +- +- if (!list_empty(&rtlpriv->glb_var->glb_priv_list)) { +- list_for_each_entry(tpriv, &rtlpriv->glb_var->glb_priv_list, +- list) { +- tpcipriv = (struct rtl_pci_priv *)tpriv->priv; +- rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, +- "pcipriv->ndis_adapter.funcnumber %x\n", +- pcipriv->ndis_adapter.funcnumber); +- rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, +- "tpcipriv->ndis_adapter.funcnumber %x\n", +- tpcipriv->ndis_adapter.funcnumber); +- +- if (pcipriv->ndis_adapter.busnumber == +- tpcipriv->ndis_adapter.busnumber && +- pcipriv->ndis_adapter.devnumber == +- tpcipriv->ndis_adapter.devnumber && +- pcipriv->ndis_adapter.funcnumber != +- tpcipriv->ndis_adapter.funcnumber) { +- find_buddy_priv = true; +- break; +- } +- } +- } +- +- rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, +- "find_buddy_priv %d\n", find_buddy_priv); +- +- if (find_buddy_priv) +- *buddy_priv = tpriv; +- +- return find_buddy_priv; +-} +- + static void rtl_pci_parse_configuration(struct pci_dev *pdev, + struct ieee80211_hw *hw) + { +@@ -444,11 +403,6 @@ static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw) + if (!rtlpriv->rtlhal.earlymode_enable) + return; + +- if (rtlpriv->dm.supp_phymode_switch && +- (rtlpriv->easy_concurrent_ctl.switch_in_process || +- (rtlpriv->buddy_priv && +- rtlpriv->buddy_priv->easy_concurrent_ctl.switch_in_process))) +- return; + /* we just use em for BE/BK/VI/VO */ + for (tid = 7; tid >= 0; tid--) { + u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(tid)]; +@@ -1703,8 +1657,6 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw) + synchronize_irq(rtlpci->pdev->irq); + tasklet_kill(&rtlpriv->works.irq_tasklet); + cancel_work_sync(&rtlpriv->works.lps_change_work); +- +- destroy_workqueue(rtlpriv->works.rtl_wq); + } + + static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) +@@ -2019,7 +1971,6 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, + pcipriv->ndis_adapter.amd_l1_patch); + + rtl_pci_parse_configuration(pdev, hw); +- list_add_tail(&rtlpriv->list, &rtlpriv->glb_var->glb_priv_list); + + return true; + } +@@ -2166,7 +2117,6 @@ int rtl_pci_probe(struct pci_dev *pdev, + rtlpriv->rtlhal.interface = INTF_PCI; + rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data); + rtlpriv->intf_ops = &rtl_pci_ops; +- rtlpriv->glb_var = &rtl_global_var; + rtl_efuse_ops_init(hw); + + /* MEM map */ +@@ -2217,7 +2167,7 @@ int rtl_pci_probe(struct pci_dev *pdev, + if (rtlpriv->cfg->ops->init_sw_vars(hw)) { + pr_err("Can't init_sw_vars\n"); + err = -ENODEV; +- goto fail3; ++ goto fail2; + } + rtlpriv->cfg->ops->init_sw_leds(hw); + +@@ -2235,14 +2185,14 @@ int rtl_pci_probe(struct pci_dev *pdev, + err = rtl_pci_init(hw, pdev); + if (err) { + pr_err("Failed to init PCI\n"); +- goto fail3; ++ goto fail4; + } + + err = ieee80211_register_hw(hw); + if (err) { + pr_err("Can't register mac80211 hw.\n"); + err = -ENODEV; +- goto fail3; ++ goto fail5; + } + rtlpriv->mac80211.mac80211_registered = 1; + +@@ -2265,16 +2215,19 @@ int rtl_pci_probe(struct pci_dev *pdev, + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + return 0; + +-fail3: +- pci_set_drvdata(pdev, NULL); ++fail5: ++ rtl_pci_deinit(hw); ++fail4: + rtl_deinit_core(hw); ++fail3: ++ wait_for_completion(&rtlpriv->firmware_loading_complete); ++ rtlpriv->cfg->ops->deinit_sw_vars(hw); + + fail2: + if (rtlpriv->io.pci_mem_start != 0) + pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); + + pci_release_regions(pdev); +- complete(&rtlpriv->firmware_loading_complete); + + fail1: + if (hw) +@@ -2325,7 +2278,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev) + if (rtlpci->using_msi) + pci_disable_msi(rtlpci->pdev); + +- list_del(&rtlpriv->list); + if (rtlpriv->io.pci_mem_start != 0) { + pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); + pci_release_regions(pdev); +@@ -2385,7 +2337,6 @@ const struct rtl_intf_ops rtl_pci_ops = { + .read_efuse_byte = read_efuse_byte, + .adapter_start = rtl_pci_start, + .adapter_stop = rtl_pci_stop, +- .check_buddy_priv = rtl_pci_check_buddy_priv, + .adapter_tx = rtl_pci_tx, + .flush = rtl_pci_flush, + .reset_trx_ring = rtl_pci_reset_trx_ring, +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +index 6d352a3161b8f7..60d97e73ca28e5 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +@@ -67,22 +67,23 @@ static void rtl92se_fw_cb(const struct firmware *firmware, void *context) + + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); +- complete(&rtlpriv->firmware_loading_complete); + if (!firmware) { + pr_err("Firmware %s not available\n", fw_name); + rtlpriv->max_fw_size = 0; +- return; ++ goto exit; + } + if (firmware->size > rtlpriv->max_fw_size) { + pr_err("Firmware is too big!\n"); + rtlpriv->max_fw_size = 0; + release_firmware(firmware); +- return; ++ goto exit; + } + pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware; + memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size); + pfirmware->sz_fw_tmpbufferlen = firmware->size; + release_firmware(firmware); ++exit: ++ complete(&rtlpriv->firmware_loading_complete); + } + + static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h +index c269942b3f4ab1..af8d17b9e012ca 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.h +@@ -197,9 +197,9 @@ enum rtl8821a_h2c_cmd { + + /* _MEDIA_STATUS_RPT_PARM_CMD1 */ + #define SET_H2CCMD_MSRRPT_PARM_OPMODE(__cmd, __value) \ +- u8p_replace_bits(__cmd + 1, __value, BIT(0)) ++ u8p_replace_bits(__cmd, __value, BIT(0)) + #define SET_H2CCMD_MSRRPT_PARM_MACID_IND(__cmd, __value) \ +- u8p_replace_bits(__cmd + 1, __value, BIT(1)) ++ u8p_replace_bits(__cmd, __value, BIT(1)) + + /* AP_OFFLOAD */ + #define SET_H2CCMD_AP_OFFLOAD_ON(__cmd, __value) \ +diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c +index a8eebafb9a7ee2..68dc0e6af6b1b5 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/usb.c ++++ b/drivers/net/wireless/realtek/rtlwifi/usb.c +@@ -679,11 +679,6 @@ static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw) + tasklet_kill(&rtlusb->rx_work_tasklet); + cancel_work_sync(&rtlpriv->works.lps_change_work); + +- if (rtlpriv->works.rtl_wq) { +- destroy_workqueue(rtlpriv->works.rtl_wq); +- rtlpriv->works.rtl_wq = NULL; +- } +- + skb_queue_purge(&rtlusb->rx_queue); + + while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) { +@@ -1073,19 +1068,22 @@ int rtl_usb_probe(struct usb_interface *intf, + err = ieee80211_register_hw(hw); + if (err) { + pr_err("Can't register mac80211 hw.\n"); +- goto error_out; ++ goto error_init_vars; + } + rtlpriv->mac80211.mac80211_registered = 1; + + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + return 0; + ++error_init_vars: ++ wait_for_completion(&rtlpriv->firmware_loading_complete); ++ rtlpriv->cfg->ops->deinit_sw_vars(hw); + error_out: ++ rtl_usb_deinit(hw); + rtl_deinit_core(hw); + error_out2: + _rtl_usb_io_handler_release(hw); + usb_put_dev(udev); +- complete(&rtlpriv->firmware_loading_complete); + kfree(rtlpriv->usb_data); + ieee80211_free_hw(hw); + return -ENODEV; +diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h +index 0bac788ccd6e31..a8b5db365a30e3 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h ++++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h +@@ -2300,7 +2300,6 @@ struct rtl_hal_ops { + u32 regaddr, u32 bitmask, u32 data); + void (*linked_set_reg)(struct ieee80211_hw *hw); + void (*chk_switch_dmdp)(struct ieee80211_hw *hw); +- void (*dualmac_easy_concurrent)(struct ieee80211_hw *hw); + void (*dualmac_switch_to_dmdp)(struct ieee80211_hw *hw); + bool (*phy_rf6052_config)(struct ieee80211_hw *hw); + void (*phy_rf6052_set_cck_txpower)(struct ieee80211_hw *hw, +@@ -2336,8 +2335,6 @@ struct rtl_intf_ops { + void (*read_efuse_byte)(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); + int (*adapter_start)(struct ieee80211_hw *hw); + void (*adapter_stop)(struct ieee80211_hw *hw); +- bool (*check_buddy_priv)(struct ieee80211_hw *hw, +- struct rtl_priv **buddy_priv); + + int (*adapter_tx)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, +@@ -2465,7 +2462,6 @@ struct rtl_works { + + /*timer */ + struct timer_list watchdog_timer; +- struct timer_list dualmac_easyconcurrent_retrytimer; + struct timer_list fw_clockoff_timer; + struct timer_list fast_antenna_training_timer; + /*task */ +@@ -2498,14 +2494,6 @@ struct rtl_debug { + #define MIMO_PS_DYNAMIC 1 + #define MIMO_PS_NOLIMIT 3 + +-struct rtl_dualmac_easy_concurrent_ctl { +- enum band_type currentbandtype_backfordmdp; +- bool close_bbandrf_for_dmsp; +- bool change_to_dmdp; +- bool change_to_dmsp; +- bool switch_in_process; +-}; +- + struct rtl_dmsp_ctl { + bool activescan_for_slaveofdmsp; + bool scan_for_anothermac_fordmsp; +@@ -2590,14 +2578,6 @@ struct dig_t { + u32 rssi_max; + }; + +-struct rtl_global_var { +- /* from this list we can get +- * other adapter's rtl_priv +- */ +- struct list_head glb_priv_list; +- spinlock_t glb_list_lock; +-}; +- + #define IN_4WAY_TIMEOUT_TIME (30 * MSEC_PER_SEC) /* 30 seconds */ + + struct rtl_btc_info { +@@ -2743,10 +2723,7 @@ struct rtl_scan_list { + struct rtl_priv { + struct ieee80211_hw *hw; + struct completion firmware_loading_complete; +- struct list_head list; + struct rtl_priv *buddy_priv; +- struct rtl_global_var *glb_var; +- struct rtl_dualmac_easy_concurrent_ctl easy_concurrent_ctl; + struct rtl_dmsp_ctl dmsp_ctl; + struct rtl_locks locks; + struct rtl_works works; +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index 5669f17b395f3a..7d664380c4771f 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -2552,24 +2552,24 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, + if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags) || + test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) { + ret = -EBUSY; +- goto out; ++ goto out_unlock; + } + + + ret = wl12xx_init_vif_data(wl, vif); + if (ret < 0) +- goto out; ++ goto out_unlock; + + wlvif->wl = wl; + role_type = wl12xx_get_role_type(wl, wlvif); + if (role_type == WL12XX_INVALID_ROLE_TYPE) { + ret = -EINVAL; +- goto out; ++ goto out_unlock; + } + + ret = wlcore_allocate_hw_queue_base(wl, wlvif); + if (ret < 0) +- goto out; ++ goto out_unlock; + + /* + * TODO: after the nvs issue will be solved, move this block +@@ -2584,7 +2584,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, + + ret = wl12xx_init_fw(wl); + if (ret < 0) +- goto out; ++ goto out_unlock; + } + + /* +diff --git a/drivers/net/wwan/iosm/iosm_ipc_pcie.c b/drivers/net/wwan/iosm/iosm_ipc_pcie.c +index 8b4222b137d147..968ca9ff21df12 100644 +--- a/drivers/net/wwan/iosm/iosm_ipc_pcie.c ++++ b/drivers/net/wwan/iosm/iosm_ipc_pcie.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + #include + + #include "iosm_ipc_imem.h" +@@ -18,6 +19,7 @@ MODULE_LICENSE("GPL v2"); + /* WWAN GUID */ + static guid_t wwan_acpi_guid = GUID_INIT(0xbad01b75, 0x22a8, 0x4f48, 0x87, 0x92, + 0xbd, 0xde, 0x94, 0x67, 0x74, 0x7d); ++static bool pci_registered; + + static void ipc_pcie_resources_release(struct iosm_pcie *ipc_pcie) + { +@@ -484,7 +486,6 @@ static struct pci_driver iosm_ipc_driver = { + }, + .id_table = iosm_ipc_ids, + }; +-module_pci_driver(iosm_ipc_driver); + + int ipc_pcie_addr_map(struct iosm_pcie *ipc_pcie, unsigned char *data, + size_t size, dma_addr_t *mapping, int direction) +@@ -566,3 +567,56 @@ void ipc_pcie_kfree_skb(struct iosm_pcie *ipc_pcie, struct sk_buff *skb) + IPC_CB(skb)->mapping = 0; + dev_kfree_skb(skb); + } ++ ++static int pm_notify(struct notifier_block *nb, unsigned long mode, void *_unused) ++{ ++ if (mode == PM_HIBERNATION_PREPARE || mode == PM_RESTORE_PREPARE) { ++ if (pci_registered) { ++ pci_unregister_driver(&iosm_ipc_driver); ++ pci_registered = false; ++ } ++ } else if (mode == PM_POST_HIBERNATION || mode == PM_POST_RESTORE) { ++ if (!pci_registered) { ++ int ret; ++ ++ ret = pci_register_driver(&iosm_ipc_driver); ++ if (ret) { ++ pr_err(KBUILD_MODNAME ": unable to re-register PCI driver: %d\n", ++ ret); ++ } else { ++ pci_registered = true; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static struct notifier_block pm_notifier = { ++ .notifier_call = pm_notify, ++}; ++ ++static int __init iosm_ipc_driver_init(void) ++{ ++ int ret; ++ ++ ret = pci_register_driver(&iosm_ipc_driver); ++ if (ret) ++ return ret; ++ ++ pci_registered = true; ++ ++ register_pm_notifier(&pm_notifier); ++ ++ return 0; ++} ++module_init(iosm_ipc_driver_init); ++ ++static void __exit iosm_ipc_driver_exit(void) ++{ ++ unregister_pm_notifier(&pm_notifier); ++ ++ if (pci_registered) ++ pci_unregister_driver(&iosm_ipc_driver); ++} ++module_exit(iosm_ipc_driver_exit); +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 93a19588ae92ac..7f744aa4d120c6 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -1585,7 +1585,13 @@ int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count) + + status = nvme_set_features(ctrl, NVME_FEAT_NUM_QUEUES, q_count, NULL, 0, + &result); +- if (status < 0) ++ ++ /* ++ * It's either a kernel error or the host observed a connection ++ * lost. In either case it's not possible communicate with the ++ * controller and thus enter the error code path. ++ */ ++ if (status < 0 || status == NVME_SC_HOST_PATH_ERROR) + return status; + + /* +@@ -2861,7 +2867,7 @@ int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, u8 csi, + static int nvme_get_effects_log(struct nvme_ctrl *ctrl, u8 csi, + struct nvme_effects_log **log) + { +- struct nvme_effects_log *cel = xa_load(&ctrl->cels, csi); ++ struct nvme_effects_log *old, *cel = xa_load(&ctrl->cels, csi); + int ret; + + if (cel) +@@ -2878,7 +2884,11 @@ static int nvme_get_effects_log(struct nvme_ctrl *ctrl, u8 csi, + return ret; + } + +- xa_store(&ctrl->cels, csi, cel, GFP_KERNEL); ++ old = xa_store(&ctrl->cels, csi, cel, GFP_KERNEL); ++ if (xa_is_err(old)) { ++ kfree(cel); ++ return xa_err(old); ++ } + out: + *log = cel; + return 0; +diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c +index 22ff0e617b8f07..f160e2b760d130 100644 +--- a/drivers/nvme/host/ioctl.c ++++ b/drivers/nvme/host/ioctl.c +@@ -183,8 +183,7 @@ static bool nvme_validate_passthru_nsid(struct nvme_ctrl *ctrl, + { + if (ns && nsid != ns->head->ns_id) { + dev_err(ctrl->device, +- "%s: nsid (%u) in cmd does not match nsid (%u)" +- "of namespace\n", ++ "%s: nsid (%u) in cmd does not match nsid (%u) of namespace\n", + current->comm, nsid, ns->head->ns_id); + return false; + } +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 04fedb27e35ad6..2eb692876f6959 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2975,7 +2975,9 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) + * because of high power consumption (> 2 Watt) in s2idle + * sleep. Only some boards with Intel CPU are affected. + */ +- if (dmi_match(DMI_BOARD_NAME, "GMxPXxx") || ++ if (dmi_match(DMI_BOARD_NAME, "DN50Z-140HC-YD") || ++ dmi_match(DMI_BOARD_NAME, "GMxPXxx") || ++ dmi_match(DMI_BOARD_NAME, "GXxMRXx") || + dmi_match(DMI_BOARD_NAME, "PH4PG31") || + dmi_match(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1") || + dmi_match(DMI_BOARD_NAME, "PH6PG01_PH6PG71")) +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index 809b03b86a0094..2bf2c775f74513 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -539,10 +539,16 @@ static void nvmet_tcp_queue_response(struct nvmet_req *req) + struct nvmet_tcp_cmd *cmd = + container_of(req, struct nvmet_tcp_cmd, req); + struct nvmet_tcp_queue *queue = cmd->queue; ++ enum nvmet_tcp_recv_state queue_state; ++ struct nvmet_tcp_cmd *queue_cmd; + struct nvme_sgl_desc *sgl; + u32 len; + +- if (unlikely(cmd == queue->cmd)) { ++ /* Pairs with store_release in nvmet_prepare_receive_pdu() */ ++ queue_state = smp_load_acquire(&queue->rcv_state); ++ queue_cmd = READ_ONCE(queue->cmd); ++ ++ if (unlikely(cmd == queue_cmd)) { + sgl = &cmd->req.cmd->common.dptr.sgl; + len = le32_to_cpu(sgl->length); + +@@ -551,7 +557,7 @@ static void nvmet_tcp_queue_response(struct nvmet_req *req) + * Avoid using helpers, this might happen before + * nvmet_req_init is completed. + */ +- if (queue->rcv_state == NVMET_TCP_RECV_PDU && ++ if (queue_state == NVMET_TCP_RECV_PDU && + len && len <= cmd->req.port->inline_data_size && + nvme_is_write(cmd->req.cmd)) + return; +@@ -806,8 +812,9 @@ static void nvmet_prepare_receive_pdu(struct nvmet_tcp_queue *queue) + { + queue->offset = 0; + queue->left = sizeof(struct nvme_tcp_hdr); +- queue->cmd = NULL; +- queue->rcv_state = NVMET_TCP_RECV_PDU; ++ WRITE_ONCE(queue->cmd, NULL); ++ /* Ensure rcv_state is visible only after queue->cmd is set */ ++ smp_store_release(&queue->rcv_state, NVMET_TCP_RECV_PDU); + } + + static void nvmet_tcp_free_crypto(struct nvmet_tcp_queue *queue) +diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c +index aa07b0d82b18e9..4ded50d6176e5a 100644 +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -1512,6 +1512,8 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) + return -EINVAL; + + if (cell->bit_offset || cell->nbits) { ++ if (len != BITS_TO_BYTES(cell->nbits) && len != cell->bytes) ++ return -EINVAL; + buf = nvmem_cell_prepare_write_buffer(cell, buf, len); + if (IS_ERR(buf)) + return PTR_ERR(buf); +diff --git a/drivers/nvmem/qcom-spmi-sdam.c b/drivers/nvmem/qcom-spmi-sdam.c +index 8499892044b7b2..729d9d879fd56c 100644 +--- a/drivers/nvmem/qcom-spmi-sdam.c ++++ b/drivers/nvmem/qcom-spmi-sdam.c +@@ -143,6 +143,7 @@ static int sdam_probe(struct platform_device *pdev) + sdam->sdam_config.id = NVMEM_DEVID_AUTO; + sdam->sdam_config.owner = THIS_MODULE; + sdam->sdam_config.stride = 1; ++ sdam->sdam_config.size = sdam->size; + sdam->sdam_config.word_size = 1; + sdam->sdam_config.reg_read = sdam_read; + sdam->sdam_config.reg_write = sdam_write; +diff --git a/drivers/of/base.c b/drivers/of/base.c +index 852e9724820fb8..2dc64503982630 100644 +--- a/drivers/of/base.c ++++ b/drivers/of/base.c +@@ -925,10 +925,10 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt + /* The path could begin with an alias */ + if (*path != '/') { + int len; +- const char *p = separator; ++ const char *p = strchrnul(path, '/'); + +- if (!p) +- p = strchrnul(path, '/'); ++ if (separator && separator < p) ++ p = separator; + len = p - path; + + /* of_aliases must not be NULL */ +@@ -1658,7 +1658,6 @@ int of_parse_phandle_with_args_map(const struct device_node *np, + * specifier into the out_args structure, keeping the + * bits specified in -map-pass-thru. + */ +- match_array = map - new_size; + for (i = 0; i < new_size; i++) { + __be32 val = *(map - new_size + i); + +@@ -1667,6 +1666,7 @@ int of_parse_phandle_with_args_map(const struct device_node *np, + val |= cpu_to_be32(out_args->args[i]) & pass[i]; + } + ++ initial_match_array[i] = val; + out_args->args[i] = be32_to_cpu(val); + } + out_args->args_count = list_size = new_size; +diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c +index 6ec668ae2d6fa1..8d6ca796d9ffac 100644 +--- a/drivers/of/of_reserved_mem.c ++++ b/drivers/of/of_reserved_mem.c +@@ -50,7 +50,8 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, + memblock_free(base, size); + } + +- kmemleak_ignore_phys(base); ++ if (!err) ++ kmemleak_ignore_phys(base); + + return err; + } +diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c +index de5a823f30310c..67aff871374d37 100644 +--- a/drivers/parport/parport_pc.c ++++ b/drivers/parport/parport_pc.c +@@ -2611,6 +2611,7 @@ enum parport_pc_pci_cards { + netmos_9815, + netmos_9901, + netmos_9865, ++ asix_ax99100, + quatech_sppxp100, + wch_ch382l, + brainboxes_uc146, +@@ -2676,6 +2677,7 @@ static struct parport_pc_pci { + /* netmos_9815 */ { 2, { { 0, 1 }, { 2, 3 }, } }, + /* netmos_9901 */ { 1, { { 0, -1 }, } }, + /* netmos_9865 */ { 1, { { 0, -1 }, } }, ++ /* asix_ax99100 */ { 1, { { 0, 1 }, } }, + /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, + /* wch_ch382l */ { 1, { { 2, -1 }, } }, + /* brainboxes_uc146 */ { 1, { { 3, -1 }, } }, +@@ -2766,6 +2768,9 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { + 0xA000, 0x1000, 0, 0, netmos_9865 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, + 0xA000, 0x2000, 0, 0, netmos_9865 }, ++ /* ASIX AX99100 PCIe to Multi I/O Controller */ ++ { PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_AX99100, ++ 0xA000, 0x2000, 0, 0, asix_ax99100 }, + /* Quatech SPPXP-100 Parallel port PCI ExpressCard */ + { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, +diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c +index aa1cf24a5a723d..c143ee1740ce72 100644 +--- a/drivers/pci/controller/pcie-rcar-ep.c ++++ b/drivers/pci/controller/pcie-rcar-ep.c +@@ -110,7 +110,7 @@ static int rcar_pcie_parse_outbound_ranges(struct rcar_pcie_endpoint *ep, + } + if (!devm_request_mem_region(&pdev->dev, res->start, + resource_size(res), +- outbound_name)) { ++ res->name)) { + dev_err(pcie->dev, "Cannot request memory region %s.\n", + outbound_name); + return -EIO; +diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c +index ecbb0fb3b653c7..64f9bae6d15b99 100644 +--- a/drivers/pci/endpoint/pci-epc-core.c ++++ b/drivers/pci/endpoint/pci-epc-core.c +@@ -740,7 +740,7 @@ void devm_pci_epc_destroy(struct device *dev, struct pci_epc *epc) + { + int r; + +- r = devres_destroy(dev, devm_pci_epc_release, devm_pci_epc_match, ++ r = devres_release(dev, devm_pci_epc_release, devm_pci_epc_match, + epc); + dev_WARN_ONCE(dev, r, "couldn't find PCI EPC resource\n"); + } +diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c +index 8aea1638087005..1de6c18317044d 100644 +--- a/drivers/pci/endpoint/pci-epf-core.c ++++ b/drivers/pci/endpoint/pci-epf-core.c +@@ -234,6 +234,7 @@ void pci_epf_remove_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf) + + mutex_lock(&epf_pf->lock); + clear_bit(epf_vf->vfunc_no, &epf_pf->vfunction_num_map); ++ epf_vf->epf_pf = NULL; + list_del(&epf_vf->list); + mutex_unlock(&epf_pf->lock); + } +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 24fde99c11a70e..a1f85120f97e67 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -6005,6 +6005,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2b, dpc_log_size); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2d, dpc_log_size); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2f, dpc_log_size); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a31, dpc_log_size); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xa72f, dpc_log_size); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xa73f, dpc_log_size); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0xa76e, dpc_log_size); + #endif +diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c +index ee0848fe843247..ca6101ef607620 100644 +--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c ++++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c +@@ -288,9 +288,9 @@ exynos5_usbdrd_pipe3_set_refclk(struct phy_usb_instance *inst) + reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; + + /* FSEL settings corresponding to reference clock */ +- reg &= ~PHYCLKRST_FSEL_PIPE_MASK | +- PHYCLKRST_MPLL_MULTIPLIER_MASK | +- PHYCLKRST_SSC_REFCLKSEL_MASK; ++ reg &= ~(PHYCLKRST_FSEL_PIPE_MASK | ++ PHYCLKRST_MPLL_MULTIPLIER_MASK | ++ PHYCLKRST_SSC_REFCLKSEL_MASK); + switch (phy_drd->extrefclk) { + case EXYNOS5_FSEL_50MHZ: + reg |= (PHYCLKRST_MPLL_MULTIPLIER_50M_REF | +@@ -332,9 +332,9 @@ exynos5_usbdrd_utmi_set_refclk(struct phy_usb_instance *inst) + reg &= ~PHYCLKRST_REFCLKSEL_MASK; + reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; + +- reg &= ~PHYCLKRST_FSEL_UTMI_MASK | +- PHYCLKRST_MPLL_MULTIPLIER_MASK | +- PHYCLKRST_SSC_REFCLKSEL_MASK; ++ reg &= ~(PHYCLKRST_FSEL_UTMI_MASK | ++ PHYCLKRST_MPLL_MULTIPLIER_MASK | ++ PHYCLKRST_SSC_REFCLKSEL_MASK); + reg |= PHYCLKRST_FSEL(phy_drd->extrefclk); + + return reg; +diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c +index ae3915ed9fefa8..98d263a9e66b62 100644 +--- a/drivers/phy/tegra/xusb-tegra186.c ++++ b/drivers/phy/tegra/xusb-tegra186.c +@@ -897,6 +897,7 @@ static int tegra186_utmi_phy_exit(struct phy *phy) + unsigned int index = lane->index; + struct device *dev = padctl->dev; + int err; ++ u32 reg; + + port = tegra_xusb_find_usb2_port(padctl, index); + if (!port) { +@@ -904,6 +905,16 @@ static int tegra186_utmi_phy_exit(struct phy *phy) + return -ENODEV; + } + ++ if (port->mode == USB_DR_MODE_OTG || ++ port->mode == USB_DR_MODE_PERIPHERAL) { ++ /* reset VBUS&ID OVERRIDE */ ++ reg = padctl_readl(padctl, USB2_VBUS_ID); ++ reg &= ~VBUS_OVERRIDE; ++ reg &= ~ID_OVERRIDE(~0); ++ reg |= ID_OVERRIDE_FLOATING; ++ padctl_writel(padctl, reg, USB2_VBUS_ID); ++ } ++ + if (port->supply && port->mode == USB_DR_MODE_HOST) { + err = regulator_disable(port->supply); + if (err) { +diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c +index 82516796a53b00..7ef80f517e76e8 100644 +--- a/drivers/platform/x86/acer-wmi.c ++++ b/drivers/platform/x86/acer-wmi.c +@@ -88,6 +88,7 @@ enum acer_wmi_event_ids { + WMID_HOTKEY_EVENT = 0x1, + WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5, + WMID_GAMING_TURBO_KEY_EVENT = 0x7, ++ WMID_AC_EVENT = 0x8, + }; + + static const struct key_entry acer_wmi_keymap[] __initconst = { +@@ -2067,6 +2068,9 @@ static void acer_wmi_notify(u32 value, void *context) + if (return_value.key_num == 0x4) + acer_toggle_turbo(); + break; ++ case WMID_AC_EVENT: ++ /* We ignore AC events here */ ++ break; + default: + pr_warn("Unknown function number - %d - %d\n", + return_value.function, return_value.key_num); +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index 99c19a0b915138..5e44a4338706ac 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -9766,6 +9766,7 @@ static const struct tpacpi_quirk battery_quirk_table[] __initconst = { + * Individual addressing is broken on models that expose the + * primary battery as BAT1. + */ ++ TPACPI_Q_LNV('G', '8', true), /* ThinkPad X131e */ + TPACPI_Q_LNV('8', 'F', true), /* Thinkpad X120e */ + TPACPI_Q_LNV('J', '7', true), /* B5400 */ + TPACPI_Q_LNV('J', 'I', true), /* Thinkpad 11e */ +diff --git a/drivers/power/supply/da9150-fg.c b/drivers/power/supply/da9150-fg.c +index 6e367826aae922..d5e1fbac87f22b 100644 +--- a/drivers/power/supply/da9150-fg.c ++++ b/drivers/power/supply/da9150-fg.c +@@ -247,9 +247,9 @@ static int da9150_fg_current_avg(struct da9150_fg *fg, + DA9150_QIF_SD_GAIN_SIZE); + da9150_fg_read_sync_end(fg); + +- div = (u64) (sd_gain * shunt_val * 65536ULL); ++ div = 65536ULL * sd_gain * shunt_val; + do_div(div, 1000000); +- res = (u64) (iavg * 1000000ULL); ++ res = 1000000ULL * iavg; + do_div(res, div); + + val->intval = (int) res; +diff --git a/drivers/pps/clients/pps-gpio.c b/drivers/pps/clients/pps-gpio.c +index 2f4b11b4dfcd91..bf3b6f1aa98425 100644 +--- a/drivers/pps/clients/pps-gpio.c ++++ b/drivers/pps/clients/pps-gpio.c +@@ -214,8 +214,8 @@ static int pps_gpio_probe(struct platform_device *pdev) + return -EINVAL; + } + +- dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n", +- data->irq); ++ dev_dbg(&data->pps->dev, "Registered IRQ %d as PPS source\n", ++ data->irq); + + return 0; + } +diff --git a/drivers/pps/clients/pps-ktimer.c b/drivers/pps/clients/pps-ktimer.c +index d33106bd7a290f..2f465549b843f7 100644 +--- a/drivers/pps/clients/pps-ktimer.c ++++ b/drivers/pps/clients/pps-ktimer.c +@@ -56,7 +56,7 @@ static struct pps_source_info pps_ktimer_info = { + + static void __exit pps_ktimer_exit(void) + { +- dev_info(pps->dev, "ktimer PPS source unregistered\n"); ++ dev_dbg(&pps->dev, "ktimer PPS source unregistered\n"); + + del_timer_sync(&ktimer); + pps_unregister_source(pps); +@@ -74,7 +74,7 @@ static int __init pps_ktimer_init(void) + timer_setup(&ktimer, pps_ktimer_event, 0); + mod_timer(&ktimer, jiffies + HZ); + +- dev_info(pps->dev, "ktimer PPS source registered\n"); ++ dev_dbg(&pps->dev, "ktimer PPS source registered\n"); + + return 0; + } +diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c +index d73c4c2ed4e13a..15c05cb629077b 100644 +--- a/drivers/pps/clients/pps-ldisc.c ++++ b/drivers/pps/clients/pps-ldisc.c +@@ -32,7 +32,7 @@ static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status) + pps_event(pps, &ts, status ? PPS_CAPTUREASSERT : + PPS_CAPTURECLEAR, NULL); + +- dev_dbg(pps->dev, "PPS %s at %lu\n", ++ dev_dbg(&pps->dev, "PPS %s at %lu\n", + status ? "assert" : "clear", jiffies); + } + +@@ -69,7 +69,7 @@ static int pps_tty_open(struct tty_struct *tty) + goto err_unregister; + } + +- dev_info(pps->dev, "source \"%s\" added\n", info.path); ++ dev_dbg(&pps->dev, "source \"%s\" added\n", info.path); + + return 0; + +@@ -89,7 +89,7 @@ static void pps_tty_close(struct tty_struct *tty) + if (WARN_ON(!pps)) + return; + +- dev_info(pps->dev, "removed\n"); ++ dev_info(&pps->dev, "removed\n"); + pps_unregister_source(pps); + } + +diff --git a/drivers/pps/clients/pps_parport.c b/drivers/pps/clients/pps_parport.c +index 53e9c304ae0a7a..c3f46efd64c324 100644 +--- a/drivers/pps/clients/pps_parport.c ++++ b/drivers/pps/clients/pps_parport.c +@@ -81,7 +81,7 @@ static void parport_irq(void *handle) + /* check the signal (no signal means the pulse is lost this time) */ + if (!signal_is_set(port)) { + local_irq_restore(flags); +- dev_err(dev->pps->dev, "lost the signal\n"); ++ dev_err(&dev->pps->dev, "lost the signal\n"); + goto out_assert; + } + +@@ -98,7 +98,7 @@ static void parport_irq(void *handle) + /* timeout */ + dev->cw_err++; + if (dev->cw_err >= CLEAR_WAIT_MAX_ERRORS) { +- dev_err(dev->pps->dev, "disabled clear edge capture after %d" ++ dev_err(&dev->pps->dev, "disabled clear edge capture after %d" + " timeouts\n", dev->cw_err); + dev->cw = 0; + dev->cw_err = 0; +diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c +index d9d566f70ed199..92d1b62ea239d7 100644 +--- a/drivers/pps/kapi.c ++++ b/drivers/pps/kapi.c +@@ -41,7 +41,7 @@ static void pps_add_offset(struct pps_ktime *ts, struct pps_ktime *offset) + static void pps_echo_client_default(struct pps_device *pps, int event, + void *data) + { +- dev_info(pps->dev, "echo %s %s\n", ++ dev_info(&pps->dev, "echo %s %s\n", + event & PPS_CAPTUREASSERT ? "assert" : "", + event & PPS_CAPTURECLEAR ? "clear" : ""); + } +@@ -112,7 +112,7 @@ struct pps_device *pps_register_source(struct pps_source_info *info, + goto kfree_pps; + } + +- dev_info(pps->dev, "new PPS source %s\n", info->name); ++ dev_dbg(&pps->dev, "new PPS source %s\n", info->name); + + return pps; + +@@ -166,7 +166,7 @@ void pps_event(struct pps_device *pps, struct pps_event_time *ts, int event, + /* check event type */ + BUG_ON((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0); + +- dev_dbg(pps->dev, "PPS event at %lld.%09ld\n", ++ dev_dbg(&pps->dev, "PPS event at %lld.%09ld\n", + (s64)ts->ts_real.tv_sec, ts->ts_real.tv_nsec); + + timespec_to_pps_ktime(&ts_real, ts->ts_real); +@@ -188,7 +188,7 @@ void pps_event(struct pps_device *pps, struct pps_event_time *ts, int event, + /* Save the time stamp */ + pps->assert_tu = ts_real; + pps->assert_sequence++; +- dev_dbg(pps->dev, "capture assert seq #%u\n", ++ dev_dbg(&pps->dev, "capture assert seq #%u\n", + pps->assert_sequence); + + captured = ~0; +@@ -202,7 +202,7 @@ void pps_event(struct pps_device *pps, struct pps_event_time *ts, int event, + /* Save the time stamp */ + pps->clear_tu = ts_real; + pps->clear_sequence++; +- dev_dbg(pps->dev, "capture clear seq #%u\n", ++ dev_dbg(&pps->dev, "capture clear seq #%u\n", + pps->clear_sequence); + + captured = ~0; +diff --git a/drivers/pps/kc.c b/drivers/pps/kc.c +index 50dc59af45be24..fbd23295afd7d9 100644 +--- a/drivers/pps/kc.c ++++ b/drivers/pps/kc.c +@@ -43,11 +43,11 @@ int pps_kc_bind(struct pps_device *pps, struct pps_bind_args *bind_args) + pps_kc_hardpps_mode = 0; + pps_kc_hardpps_dev = NULL; + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_info(pps->dev, "unbound kernel" ++ dev_info(&pps->dev, "unbound kernel" + " consumer\n"); + } else { + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_err(pps->dev, "selected kernel consumer" ++ dev_err(&pps->dev, "selected kernel consumer" + " is not bound\n"); + return -EINVAL; + } +@@ -57,11 +57,11 @@ int pps_kc_bind(struct pps_device *pps, struct pps_bind_args *bind_args) + pps_kc_hardpps_mode = bind_args->edge; + pps_kc_hardpps_dev = pps; + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_info(pps->dev, "bound kernel consumer: " ++ dev_info(&pps->dev, "bound kernel consumer: " + "edge=0x%x\n", bind_args->edge); + } else { + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_err(pps->dev, "another kernel consumer" ++ dev_err(&pps->dev, "another kernel consumer" + " is already bound\n"); + return -EINVAL; + } +@@ -83,7 +83,7 @@ void pps_kc_remove(struct pps_device *pps) + pps_kc_hardpps_mode = 0; + pps_kc_hardpps_dev = NULL; + spin_unlock_irq(&pps_kc_hardpps_lock); +- dev_info(pps->dev, "unbound kernel consumer" ++ dev_info(&pps->dev, "unbound kernel consumer" + " on device removal\n"); + } else + spin_unlock_irq(&pps_kc_hardpps_lock); +diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c +index 22a65ad4e46e6b..2d008e0d116ab5 100644 +--- a/drivers/pps/pps.c ++++ b/drivers/pps/pps.c +@@ -25,7 +25,7 @@ + * Local variables + */ + +-static dev_t pps_devt; ++static int pps_major; + static struct class *pps_class; + + static DEFINE_MUTEX(pps_idr_lock); +@@ -62,7 +62,7 @@ static int pps_cdev_pps_fetch(struct pps_device *pps, struct pps_fdata *fdata) + else { + unsigned long ticks; + +- dev_dbg(pps->dev, "timeout %lld.%09d\n", ++ dev_dbg(&pps->dev, "timeout %lld.%09d\n", + (long long) fdata->timeout.sec, + fdata->timeout.nsec); + ticks = fdata->timeout.sec * HZ; +@@ -80,7 +80,7 @@ static int pps_cdev_pps_fetch(struct pps_device *pps, struct pps_fdata *fdata) + + /* Check for pending signals */ + if (err == -ERESTARTSYS) { +- dev_dbg(pps->dev, "pending signal caught\n"); ++ dev_dbg(&pps->dev, "pending signal caught\n"); + return -EINTR; + } + +@@ -98,7 +98,7 @@ static long pps_cdev_ioctl(struct file *file, + + switch (cmd) { + case PPS_GETPARAMS: +- dev_dbg(pps->dev, "PPS_GETPARAMS\n"); ++ dev_dbg(&pps->dev, "PPS_GETPARAMS\n"); + + spin_lock_irq(&pps->lock); + +@@ -114,7 +114,7 @@ static long pps_cdev_ioctl(struct file *file, + break; + + case PPS_SETPARAMS: +- dev_dbg(pps->dev, "PPS_SETPARAMS\n"); ++ dev_dbg(&pps->dev, "PPS_SETPARAMS\n"); + + /* Check the capabilities */ + if (!capable(CAP_SYS_TIME)) +@@ -124,14 +124,14 @@ static long pps_cdev_ioctl(struct file *file, + if (err) + return -EFAULT; + if (!(params.mode & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR))) { +- dev_dbg(pps->dev, "capture mode unspecified (%x)\n", ++ dev_dbg(&pps->dev, "capture mode unspecified (%x)\n", + params.mode); + return -EINVAL; + } + + /* Check for supported capabilities */ + if ((params.mode & ~pps->info.mode) != 0) { +- dev_dbg(pps->dev, "unsupported capabilities (%x)\n", ++ dev_dbg(&pps->dev, "unsupported capabilities (%x)\n", + params.mode); + return -EINVAL; + } +@@ -144,7 +144,7 @@ static long pps_cdev_ioctl(struct file *file, + /* Restore the read only parameters */ + if ((params.mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) { + /* section 3.3 of RFC 2783 interpreted */ +- dev_dbg(pps->dev, "time format unspecified (%x)\n", ++ dev_dbg(&pps->dev, "time format unspecified (%x)\n", + params.mode); + pps->params.mode |= PPS_TSFMT_TSPEC; + } +@@ -165,7 +165,7 @@ static long pps_cdev_ioctl(struct file *file, + break; + + case PPS_GETCAP: +- dev_dbg(pps->dev, "PPS_GETCAP\n"); ++ dev_dbg(&pps->dev, "PPS_GETCAP\n"); + + err = put_user(pps->info.mode, iuarg); + if (err) +@@ -176,7 +176,7 @@ static long pps_cdev_ioctl(struct file *file, + case PPS_FETCH: { + struct pps_fdata fdata; + +- dev_dbg(pps->dev, "PPS_FETCH\n"); ++ dev_dbg(&pps->dev, "PPS_FETCH\n"); + + err = copy_from_user(&fdata, uarg, sizeof(struct pps_fdata)); + if (err) +@@ -206,7 +206,7 @@ static long pps_cdev_ioctl(struct file *file, + case PPS_KC_BIND: { + struct pps_bind_args bind_args; + +- dev_dbg(pps->dev, "PPS_KC_BIND\n"); ++ dev_dbg(&pps->dev, "PPS_KC_BIND\n"); + + /* Check the capabilities */ + if (!capable(CAP_SYS_TIME)) +@@ -218,7 +218,7 @@ static long pps_cdev_ioctl(struct file *file, + + /* Check for supported capabilities */ + if ((bind_args.edge & ~pps->info.mode) != 0) { +- dev_err(pps->dev, "unsupported capabilities (%x)\n", ++ dev_err(&pps->dev, "unsupported capabilities (%x)\n", + bind_args.edge); + return -EINVAL; + } +@@ -227,7 +227,7 @@ static long pps_cdev_ioctl(struct file *file, + if (bind_args.tsformat != PPS_TSFMT_TSPEC || + (bind_args.edge & ~PPS_CAPTUREBOTH) != 0 || + bind_args.consumer != PPS_KC_HARDPPS) { +- dev_err(pps->dev, "invalid kernel consumer bind" ++ dev_err(&pps->dev, "invalid kernel consumer bind" + " parameters (%x)\n", bind_args.edge); + return -EINVAL; + } +@@ -259,7 +259,7 @@ static long pps_cdev_compat_ioctl(struct file *file, + struct pps_fdata fdata; + int err; + +- dev_dbg(pps->dev, "PPS_FETCH\n"); ++ dev_dbg(&pps->dev, "PPS_FETCH\n"); + + err = copy_from_user(&compat, uarg, sizeof(struct pps_fdata_compat)); + if (err) +@@ -296,20 +296,36 @@ static long pps_cdev_compat_ioctl(struct file *file, + #define pps_cdev_compat_ioctl NULL + #endif + ++static struct pps_device *pps_idr_get(unsigned long id) ++{ ++ struct pps_device *pps; ++ ++ mutex_lock(&pps_idr_lock); ++ pps = idr_find(&pps_idr, id); ++ if (pps) ++ get_device(&pps->dev); ++ ++ mutex_unlock(&pps_idr_lock); ++ return pps; ++} ++ + static int pps_cdev_open(struct inode *inode, struct file *file) + { +- struct pps_device *pps = container_of(inode->i_cdev, +- struct pps_device, cdev); ++ struct pps_device *pps = pps_idr_get(iminor(inode)); ++ ++ if (!pps) ++ return -ENODEV; ++ + file->private_data = pps; +- kobject_get(&pps->dev->kobj); + return 0; + } + + static int pps_cdev_release(struct inode *inode, struct file *file) + { +- struct pps_device *pps = container_of(inode->i_cdev, +- struct pps_device, cdev); +- kobject_put(&pps->dev->kobj); ++ struct pps_device *pps = file->private_data; ++ ++ WARN_ON(pps->id != iminor(inode)); ++ put_device(&pps->dev); + return 0; + } + +@@ -332,22 +348,13 @@ static void pps_device_destruct(struct device *dev) + { + struct pps_device *pps = dev_get_drvdata(dev); + +- cdev_del(&pps->cdev); +- +- /* Now we can release the ID for re-use */ + pr_debug("deallocating pps%d\n", pps->id); +- mutex_lock(&pps_idr_lock); +- idr_remove(&pps_idr, pps->id); +- mutex_unlock(&pps_idr_lock); +- +- kfree(dev); + kfree(pps); + } + + int pps_register_cdev(struct pps_device *pps) + { + int err; +- dev_t devt; + + mutex_lock(&pps_idr_lock); + /* +@@ -364,40 +371,29 @@ int pps_register_cdev(struct pps_device *pps) + goto out_unlock; + } + pps->id = err; +- mutex_unlock(&pps_idr_lock); +- +- devt = MKDEV(MAJOR(pps_devt), pps->id); +- +- cdev_init(&pps->cdev, &pps_cdev_fops); +- pps->cdev.owner = pps->info.owner; + +- err = cdev_add(&pps->cdev, devt, 1); +- if (err) { +- pr_err("%s: failed to add char device %d:%d\n", +- pps->info.name, MAJOR(pps_devt), pps->id); ++ pps->dev.class = pps_class; ++ pps->dev.parent = pps->info.dev; ++ pps->dev.devt = MKDEV(pps_major, pps->id); ++ dev_set_drvdata(&pps->dev, pps); ++ dev_set_name(&pps->dev, "pps%d", pps->id); ++ err = device_register(&pps->dev); ++ if (err) + goto free_idr; +- } +- pps->dev = device_create(pps_class, pps->info.dev, devt, pps, +- "pps%d", pps->id); +- if (IS_ERR(pps->dev)) { +- err = PTR_ERR(pps->dev); +- goto del_cdev; +- } + + /* Override the release function with our own */ +- pps->dev->release = pps_device_destruct; ++ pps->dev.release = pps_device_destruct; + +- pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, +- MAJOR(pps_devt), pps->id); ++ pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, pps_major, ++ pps->id); + ++ get_device(&pps->dev); ++ mutex_unlock(&pps_idr_lock); + return 0; + +-del_cdev: +- cdev_del(&pps->cdev); +- + free_idr: +- mutex_lock(&pps_idr_lock); + idr_remove(&pps_idr, pps->id); ++ put_device(&pps->dev); + out_unlock: + mutex_unlock(&pps_idr_lock); + return err; +@@ -407,7 +403,13 @@ void pps_unregister_cdev(struct pps_device *pps) + { + pr_debug("unregistering pps%d\n", pps->id); + pps->lookup_cookie = NULL; +- device_destroy(pps_class, pps->dev->devt); ++ device_destroy(pps_class, pps->dev.devt); ++ ++ /* Now we can release the ID for re-use */ ++ mutex_lock(&pps_idr_lock); ++ idr_remove(&pps_idr, pps->id); ++ put_device(&pps->dev); ++ mutex_unlock(&pps_idr_lock); + } + + /* +@@ -427,6 +429,11 @@ void pps_unregister_cdev(struct pps_device *pps) + * so that it will not be used again, even if the pps device cannot + * be removed from the idr due to pending references holding the minor + * number in use. ++ * ++ * Since pps_idr holds a reference to the device, the returned ++ * pps_device is guaranteed to be valid until pps_unregister_cdev() is ++ * called on it. But after calling pps_unregister_cdev(), it may be ++ * freed at any time. + */ + struct pps_device *pps_lookup_dev(void const *cookie) + { +@@ -449,13 +456,11 @@ EXPORT_SYMBOL(pps_lookup_dev); + static void __exit pps_exit(void) + { + class_destroy(pps_class); +- unregister_chrdev_region(pps_devt, PPS_MAX_SOURCES); ++ __unregister_chrdev(pps_major, 0, PPS_MAX_SOURCES, "pps"); + } + + static int __init pps_init(void) + { +- int err; +- + pps_class = class_create(THIS_MODULE, "pps"); + if (IS_ERR(pps_class)) { + pr_err("failed to allocate class\n"); +@@ -463,8 +468,9 @@ static int __init pps_init(void) + } + pps_class->dev_groups = pps_groups; + +- err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps"); +- if (err < 0) { ++ pps_major = __register_chrdev(0, 0, PPS_MAX_SOURCES, "pps", ++ &pps_cdev_fops); ++ if (pps_major < 0) { + pr_err("failed to allocate char device region\n"); + goto remove_class; + } +@@ -477,8 +483,7 @@ static int __init pps_init(void) + + remove_class: + class_destroy(pps_class); +- +- return err; ++ return pps_major; + } + + subsys_initcall(pps_init); +diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c +index 8eb902fe73a981..6b360035679754 100644 +--- a/drivers/ptp/ptp_chardev.c ++++ b/drivers/ptp/ptp_chardev.c +@@ -4,6 +4,7 @@ + * + * Copyright (C) 2010 OMICRON electronics GmbH + */ ++#include + #include + #include + #include +@@ -124,6 +125,9 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) + struct timespec64 ts; + int enable, err = 0; + ++ if (in_compat_syscall() && cmd != PTP_ENABLE_PPS && cmd != PTP_ENABLE_PPS2) ++ arg = (unsigned long)compat_ptr(arg); ++ + switch (cmd) { + + case PTP_CLOCK_GETCAPS: +diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c +index 92dd1c6f54f4a6..2e4e425288b26e 100644 +--- a/drivers/ptp/ptp_clock.c ++++ b/drivers/ptp/ptp_clock.c +@@ -180,6 +180,11 @@ static void ptp_clock_release(struct device *dev) + kfree(ptp); + } + ++static int ptp_enable(struct ptp_clock_info *ptp, struct ptp_clock_request *request, int on) ++{ ++ return -EOPNOTSUPP; ++} ++ + static void ptp_aux_kworker(struct kthread_work *work) + { + struct ptp_clock *ptp = container_of(work, struct ptp_clock, +@@ -227,6 +232,9 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, + mutex_init(&ptp->n_vclocks_mux); + init_waitqueue_head(&ptp->tsev_wq); + ++ if (!ptp->info->enable) ++ ptp->info->enable = ptp_enable; ++ + if (ptp->info->do_aux_work) { + kthread_init_delayed_work(&ptp->aux_work, ptp_aux_kworker); + ptp->kworker = kthread_create_worker(0, "ptp%d", ptp->index); +diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c +index 7a4a06148515a8..22accc02224510 100644 +--- a/drivers/ptp/ptp_ocp.c ++++ b/drivers/ptp/ptp_ocp.c +@@ -1341,7 +1341,7 @@ ptp_ocp_complete(struct ptp_ocp *bp) + + pps = pps_lookup_dev(bp->ptp); + if (pps) +- ptp_ocp_symlink(bp, pps->dev, "pps"); ++ ptp_ocp_symlink(bp, &pps->dev, "pps"); + + if (device_add_groups(&bp->dev, timecard_groups)) + pr_err("device add groups failed\n"); +diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c +index 5ac2dc1e2abd8a..f9dfe7b12ec799 100644 +--- a/drivers/rapidio/devices/rio_mport_cdev.c ++++ b/drivers/rapidio/devices/rio_mport_cdev.c +@@ -1739,7 +1739,8 @@ static int rio_mport_add_riodev(struct mport_cdev_priv *priv, + err = rio_add_net(net); + if (err) { + rmcd_debug(RDEV, "failed to register net, err=%d", err); +- kfree(net); ++ put_device(&net->dev); ++ mport->net = NULL; + goto cleanup; + } + } +diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c +index fdcf742b2adbcb..c12941f71e2cba 100644 +--- a/drivers/rapidio/rio-scan.c ++++ b/drivers/rapidio/rio-scan.c +@@ -871,7 +871,10 @@ static struct rio_net *rio_scan_alloc_net(struct rio_mport *mport, + dev_set_name(&net->dev, "rnet_%d", net->id); + net->dev.parent = &mport->dev; + net->dev.release = rio_scan_release_dev; +- rio_add_net(net); ++ if (rio_add_net(net)) { ++ put_device(&net->dev); ++ net = NULL; ++ } + } + + return net; +diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c +index e12b681c72e5eb..a08905bab2797a 100644 +--- a/drivers/regulator/of_regulator.c ++++ b/drivers/regulator/of_regulator.c +@@ -435,7 +435,7 @@ int of_regulator_match(struct device *dev, struct device_node *node, + "failed to parse DT for regulator %pOFn\n", + child); + of_node_put(child); +- return -EINVAL; ++ goto err_put; + } + match->of_node = of_node_get(child); + count++; +@@ -444,6 +444,18 @@ int of_regulator_match(struct device *dev, struct device_node *node, + } + + return count; ++ ++err_put: ++ for (i = 0; i < num_matches; i++) { ++ struct of_regulator_match *match = &matches[i]; ++ ++ match->init_data = NULL; ++ if (match->of_node) { ++ of_node_put(match->of_node); ++ match->of_node = NULL; ++ } ++ } ++ return -EINVAL; + } + EXPORT_SYMBOL_GPL(of_regulator_match); + +diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c +index bf2e370907b735..89e080798e03f1 100644 +--- a/drivers/rtc/rtc-pcf85063.c ++++ b/drivers/rtc/rtc-pcf85063.c +@@ -320,7 +320,16 @@ static const struct rtc_class_ops pcf85063_rtc_ops = { + static int pcf85063_nvmem_read(void *priv, unsigned int offset, + void *val, size_t bytes) + { +- return regmap_read(priv, PCF85063_REG_RAM, val); ++ unsigned int tmp; ++ int ret; ++ ++ ret = regmap_read(priv, PCF85063_REG_RAM, &tmp); ++ if (ret < 0) ++ return ret; ++ ++ *(u8 *)val = tmp; ++ ++ return 0; + } + + static int pcf85063_nvmem_write(void *priv, unsigned int offset, +diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c +index f3d5c7f4c13d29..f01d942e1c1df0 100644 +--- a/drivers/s390/char/sclp_early.c ++++ b/drivers/s390/char/sclp_early.c +@@ -139,7 +139,7 @@ int __init sclp_early_get_core_info(struct sclp_core_info *info) + } + sclp_fill_core_info(info, sccb); + out: +- memblock_free_early((unsigned long)sccb, length); ++ memblock_free((unsigned long)sccb, length); + return rc; + } + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index 0c768c404d3d83..64163090f63a81 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -5497,8 +5497,7 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc) + if (!ioc->is_gen35_ioc && ioc->manu_pg11.EEDPTagMode == 0) { + pr_err("%s: overriding NVDATA EEDPTagMode setting\n", + ioc->name); +- ioc->manu_pg11.EEDPTagMode &= ~0x3; +- ioc->manu_pg11.EEDPTagMode |= 0x1; ++ ioc->manu_pg11.EEDPTagMode = 0x1; + mpt3sas_config_set_manufacturing_pg11(ioc, &mpi_reply, + &ioc->manu_pg11); + } +diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h +index 9cec49e6602cbb..a6ea7c77509260 100644 +--- a/drivers/scsi/qla2xxx/qla_def.h ++++ b/drivers/scsi/qla2xxx/qla_def.h +@@ -4029,6 +4029,8 @@ struct qla_hw_data { + uint32_t npiv_supported :1; + uint32_t pci_channel_io_perm_failure :1; + uint32_t fce_enabled :1; ++ uint32_t user_enabled_fce :1; ++ uint32_t fce_dump_buf_alloced :1; + uint32_t fac_supported :1; + + uint32_t chip_reset_done :1; +diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c +index 73695c6815facc..6939ef394a3298 100644 +--- a/drivers/scsi/qla2xxx/qla_dfs.c ++++ b/drivers/scsi/qla2xxx/qla_dfs.c +@@ -409,26 +409,31 @@ qla2x00_dfs_fce_show(struct seq_file *s, void *unused) + + mutex_lock(&ha->fce_mutex); + +- seq_puts(s, "FCE Trace Buffer\n"); +- seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr); +- seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma); +- seq_puts(s, "FCE Enable Registers\n"); +- seq_printf(s, "%08x %08x %08x %08x %08x %08x\n", +- ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4], +- ha->fce_mb[5], ha->fce_mb[6]); +- +- fce = (uint32_t *) ha->fce; +- fce_start = (unsigned long long) ha->fce_dma; +- for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) { +- if (cnt % 8 == 0) +- seq_printf(s, "\n%llx: ", +- (unsigned long long)((cnt * 4) + fce_start)); +- else +- seq_putc(s, ' '); +- seq_printf(s, "%08x", *fce++); +- } ++ if (ha->flags.user_enabled_fce) { ++ seq_puts(s, "FCE Trace Buffer\n"); ++ seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr); ++ seq_printf(s, "Base = %llx\n\n", (unsigned long long)ha->fce_dma); ++ seq_puts(s, "FCE Enable Registers\n"); ++ seq_printf(s, "%08x %08x %08x %08x %08x %08x\n", ++ ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4], ++ ha->fce_mb[5], ha->fce_mb[6]); ++ ++ fce = (uint32_t *)ha->fce; ++ fce_start = (unsigned long long)ha->fce_dma; ++ for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) { ++ if (cnt % 8 == 0) ++ seq_printf(s, "\n%llx: ", ++ (unsigned long long)((cnt * 4) + fce_start)); ++ else ++ seq_putc(s, ' '); ++ seq_printf(s, "%08x", *fce++); ++ } + +- seq_puts(s, "\nEnd\n"); ++ seq_puts(s, "\nEnd\n"); ++ } else { ++ seq_puts(s, "FCE Trace is currently not enabled\n"); ++ seq_puts(s, "\techo [ 1 | 0 ] > fce\n"); ++ } + + mutex_unlock(&ha->fce_mutex); + +@@ -467,7 +472,7 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file) + struct qla_hw_data *ha = vha->hw; + int rval; + +- if (ha->flags.fce_enabled) ++ if (ha->flags.fce_enabled || !ha->fce) + goto out; + + mutex_lock(&ha->fce_mutex); +@@ -488,11 +493,88 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file) + return single_release(inode, file); + } + ++static ssize_t ++qla2x00_dfs_fce_write(struct file *file, const char __user *buffer, ++ size_t count, loff_t *pos) ++{ ++ struct seq_file *s = file->private_data; ++ struct scsi_qla_host *vha = s->private; ++ struct qla_hw_data *ha = vha->hw; ++ char *buf; ++ int rc = 0; ++ unsigned long enable; ++ ++ if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && ++ !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) { ++ ql_dbg(ql_dbg_user, vha, 0xd034, ++ "this adapter does not support FCE."); ++ return -EINVAL; ++ } ++ ++ buf = memdup_user_nul(buffer, count); ++ if (IS_ERR(buf)) { ++ ql_dbg(ql_dbg_user, vha, 0xd037, ++ "fail to copy user buffer."); ++ return PTR_ERR(buf); ++ } ++ ++ enable = kstrtoul(buf, 0, 0); ++ rc = count; ++ ++ mutex_lock(&ha->fce_mutex); ++ ++ if (enable) { ++ if (ha->flags.user_enabled_fce) { ++ mutex_unlock(&ha->fce_mutex); ++ goto out_free; ++ } ++ ha->flags.user_enabled_fce = 1; ++ if (!ha->fce) { ++ rc = qla2x00_alloc_fce_trace(vha); ++ if (rc) { ++ ha->flags.user_enabled_fce = 0; ++ mutex_unlock(&ha->fce_mutex); ++ goto out_free; ++ } ++ ++ /* adjust fw dump buffer to take into account of this feature */ ++ if (!ha->flags.fce_dump_buf_alloced) ++ qla2x00_alloc_fw_dump(vha); ++ } ++ ++ if (!ha->flags.fce_enabled) ++ qla_enable_fce_trace(vha); ++ ++ ql_dbg(ql_dbg_user, vha, 0xd045, "User enabled FCE .\n"); ++ } else { ++ if (!ha->flags.user_enabled_fce) { ++ mutex_unlock(&ha->fce_mutex); ++ goto out_free; ++ } ++ ha->flags.user_enabled_fce = 0; ++ if (ha->flags.fce_enabled) { ++ qla2x00_disable_fce_trace(vha, NULL, NULL); ++ ha->flags.fce_enabled = 0; ++ } ++ ++ qla2x00_free_fce_trace(ha); ++ /* no need to re-adjust fw dump buffer */ ++ ++ ql_dbg(ql_dbg_user, vha, 0xd04f, "User disabled FCE .\n"); ++ } ++ ++ mutex_unlock(&ha->fce_mutex); ++out_free: ++ kfree(buf); ++ return rc; ++} ++ + static const struct file_operations dfs_fce_ops = { + .open = qla2x00_dfs_fce_open, + .read = seq_read, + .llseek = seq_lseek, + .release = qla2x00_dfs_fce_release, ++ .write = qla2x00_dfs_fce_write, + }; + + static int +@@ -578,8 +660,6 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha) + if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && + !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + goto out; +- if (!ha->fce) +- goto out; + + if (qla2x00_dfs_root) + goto create_dir; +diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h +index 18376b50e349b5..d1c290f3f56aa7 100644 +--- a/drivers/scsi/qla2xxx/qla_gbl.h ++++ b/drivers/scsi/qla2xxx/qla_gbl.h +@@ -11,6 +11,9 @@ + /* + * Global Function Prototypes in qla_init.c source file. + */ ++int qla2x00_alloc_fce_trace(scsi_qla_host_t *); ++void qla2x00_free_fce_trace(struct qla_hw_data *ha); ++void qla_enable_fce_trace(scsi_qla_host_t *); + extern int qla2x00_initialize_adapter(scsi_qla_host_t *); + extern int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport); + +diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c +index 214861459b413e..2053c560b580c3 100644 +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -2683,7 +2683,7 @@ qla83xx_nic_core_fw_load(scsi_qla_host_t *vha) + return rval; + } + +-static void qla_enable_fce_trace(scsi_qla_host_t *vha) ++void qla_enable_fce_trace(scsi_qla_host_t *vha) + { + int rval; + struct qla_hw_data *ha = vha->hw; +@@ -3719,25 +3719,24 @@ qla24xx_chip_diag(scsi_qla_host_t *vha) + return rval; + } + +-static void +-qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) ++int qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) + { + dma_addr_t tc_dma; + void *tc; + struct qla_hw_data *ha = vha->hw; + + if (!IS_FWI2_CAPABLE(ha)) +- return; ++ return -EINVAL; + + if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && + !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) +- return; ++ return -EINVAL; + + if (ha->fce) { + ql_dbg(ql_dbg_init, vha, 0x00bd, + "%s: FCE Mem is already allocated.\n", + __func__); +- return; ++ return -EIO; + } + + /* Allocate memory for Fibre Channel Event Buffer. */ +@@ -3747,7 +3746,7 @@ qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) + ql_log(ql_log_warn, vha, 0x00be, + "Unable to allocate (%d KB) for FCE.\n", + FCE_SIZE / 1024); +- return; ++ return -ENOMEM; + } + + ql_dbg(ql_dbg_init, vha, 0x00c0, +@@ -3756,6 +3755,16 @@ qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) + ha->fce_dma = tc_dma; + ha->fce = tc; + ha->fce_bufs = FCE_NUM_BUFFERS; ++ return 0; ++} ++ ++void qla2x00_free_fce_trace(struct qla_hw_data *ha) ++{ ++ if (!ha->fce) ++ return; ++ dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce, ha->fce_dma); ++ ha->fce = NULL; ++ ha->fce_dma = 0; + } + + static void +@@ -3846,9 +3855,10 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) + if (ha->tgt.atio_ring) + mq_size += ha->tgt.atio_q_length * sizeof(request_t); + +- qla2x00_alloc_fce_trace(vha); +- if (ha->fce) ++ if (ha->fce) { + fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE; ++ ha->flags.fce_dump_buf_alloced = 1; ++ } + qla2x00_alloc_eft_trace(vha); + if (ha->eft) + eft_size = EFT_SIZE; +diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c +index 9721984fd9bc68..c8be41d8eb247b 100644 +--- a/drivers/scsi/scsi_lib.c ++++ b/drivers/scsi/scsi_lib.c +@@ -1114,45 +1114,16 @@ static void scsi_cleanup_rq(struct request *rq) + /* Called before a request is prepared. See also scsi_mq_prep_fn(). */ + void scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd) + { +- void *buf = cmd->sense_buffer; +- void *prot = cmd->prot_sdb; + struct request *rq = scsi_cmd_to_rq(cmd); +- unsigned int flags = cmd->flags & SCMD_PRESERVED_FLAGS; +- unsigned long jiffies_at_alloc; +- int retries, to_clear; +- bool in_flight; +- int budget_token = cmd->budget_token; +- +- if (!blk_rq_is_passthrough(rq) && !(flags & SCMD_INITIALIZED)) { +- flags |= SCMD_INITIALIZED; ++ ++ if (!blk_rq_is_passthrough(rq) && !(cmd->flags & SCMD_INITIALIZED)) { ++ cmd->flags |= SCMD_INITIALIZED; + scsi_initialize_rq(rq); + } + +- jiffies_at_alloc = cmd->jiffies_at_alloc; +- retries = cmd->retries; +- in_flight = test_bit(SCMD_STATE_INFLIGHT, &cmd->state); +- /* +- * Zero out the cmd, except for the embedded scsi_request. Only clear +- * the driver-private command data if the LLD does not supply a +- * function to initialize that data. +- */ +- to_clear = sizeof(*cmd) - sizeof(cmd->req); +- if (!dev->host->hostt->init_cmd_priv) +- to_clear += dev->host->hostt->cmd_size; +- memset((char *)cmd + sizeof(cmd->req), 0, to_clear); +- + cmd->device = dev; +- cmd->sense_buffer = buf; +- cmd->prot_sdb = prot; +- cmd->flags = flags; + INIT_LIST_HEAD(&cmd->eh_entry); + INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler); +- cmd->jiffies_at_alloc = jiffies_at_alloc; +- cmd->retries = retries; +- if (in_flight) +- __set_bit(SCMD_STATE_INFLIGHT, &cmd->state); +- cmd->budget_token = budget_token; +- + } + + static blk_status_t scsi_setup_scsi_cmnd(struct scsi_device *sdev, +@@ -1539,10 +1510,28 @@ static blk_status_t scsi_prepare_cmd(struct request *req) + struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); + struct scsi_device *sdev = req->q->queuedata; + struct Scsi_Host *shost = sdev->host; ++ bool in_flight = test_bit(SCMD_STATE_INFLIGHT, &cmd->state); + struct scatterlist *sg; + + scsi_init_command(sdev, cmd); + ++ cmd->eh_eflags = 0; ++ cmd->allowed = 0; ++ cmd->prot_type = 0; ++ cmd->prot_flags = 0; ++ cmd->submitter = 0; ++ cmd->cmd_len = 0; ++ cmd->cmnd = NULL; ++ memset(&cmd->sdb, 0, sizeof(cmd->sdb)); ++ cmd->underflow = 0; ++ cmd->transfersize = 0; ++ cmd->host_scribble = NULL; ++ cmd->result = 0; ++ cmd->extra_len = 0; ++ cmd->state = 0; ++ if (in_flight) ++ __set_bit(SCMD_STATE_INFLIGHT, &cmd->state); ++ + cmd->prot_op = SCSI_PROT_NORMAL; + if (blk_rq_bytes(req)) + cmd->sc_data_direction = rq_dma_dir(req); +@@ -1679,6 +1668,13 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, + if (!scsi_host_queue_ready(q, shost, sdev, cmd)) + goto out_dec_target_busy; + ++ /* ++ * Only clear the driver-private command data if the LLD does not supply ++ * a function to initialize that data. ++ */ ++ if (shost->hostt->cmd_size && !shost->hostt->init_cmd_priv) ++ memset(cmd + 1, 0, shost->hostt->cmd_size); ++ + if (!(req->rq_flags & RQF_DONTPREP)) { + ret = scsi_prepare_cmd(req); + if (ret != BLK_STS_OK) +diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c +index 6a628a6b5a6d2e..73cf74678ad719 100644 +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -1854,6 +1854,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) + + length = scsi_bufflen(scmnd); + payload = (struct vmbus_packet_mpb_array *)&cmd_request->mpb; ++ payload->range.len = 0; + payload_sz = 0; + + if (sg_count) { +diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/scsi/ufs/ufs_bsg.c +index 39bf204c6ec3e4..16e8ddcf22fe4a 100644 +--- a/drivers/scsi/ufs/ufs_bsg.c ++++ b/drivers/scsi/ufs/ufs_bsg.c +@@ -213,6 +213,7 @@ int ufs_bsg_probe(struct ufs_hba *hba) + q = bsg_setup_queue(bsg_dev, dev_name(bsg_dev), ufs_bsg_request, NULL, 0); + if (IS_ERR(q)) { + ret = PTR_ERR(q); ++ device_del(bsg_dev); + goto out; + } + +diff --git a/drivers/slimbus/messaging.c b/drivers/slimbus/messaging.c +index e5ae26227bdbff..0deb4c291c6a40 100644 +--- a/drivers/slimbus/messaging.c ++++ b/drivers/slimbus/messaging.c +@@ -147,8 +147,9 @@ int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn) + } + + ret = ctrl->xfer_msg(ctrl, txn); +- +- if (!ret && need_tid && !txn->msg->comp) { ++ if (ret == -ETIMEDOUT) { ++ slim_free_txn_tid(ctrl, txn); ++ } else if (!ret && need_tid && !txn->msg->comp) { + unsigned long ms = txn->rl + HZ; + + timeout = wait_for_completion_timeout(txn->comp, +diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c +index 7c65ad3d1f8a38..56534d9a775133 100644 +--- a/drivers/soc/mediatek/mtk-devapc.c ++++ b/drivers/soc/mediatek/mtk-devapc.c +@@ -258,44 +258,44 @@ static int mtk_devapc_probe(struct platform_device *pdev) + return -EINVAL; + + devapc_irq = irq_of_parse_and_map(node, 0); +- if (!devapc_irq) +- return -EINVAL; +- +- ctx->infra_clk = devm_clk_get(&pdev->dev, "devapc-infra-clock"); +- if (IS_ERR(ctx->infra_clk)) +- return -EINVAL; ++ if (!devapc_irq) { ++ ret = -EINVAL; ++ goto err; ++ } + +- if (clk_prepare_enable(ctx->infra_clk)) +- return -EINVAL; ++ ctx->infra_clk = devm_clk_get_enabled(&pdev->dev, "devapc-infra-clock"); ++ if (IS_ERR(ctx->infra_clk)) { ++ ret = -EINVAL; ++ goto err; ++ } + + ret = devm_request_irq(&pdev->dev, devapc_irq, devapc_violation_irq, + IRQF_TRIGGER_NONE, "devapc", ctx); +- if (ret) { +- clk_disable_unprepare(ctx->infra_clk); +- return ret; +- } ++ if (ret) ++ goto err; + + platform_set_drvdata(pdev, ctx); + + start_devapc(ctx); + + return 0; ++ ++err: ++ iounmap(ctx->infra_base); ++ return ret; + } + +-static int mtk_devapc_remove(struct platform_device *pdev) ++static void mtk_devapc_remove(struct platform_device *pdev) + { + struct mtk_devapc_context *ctx = platform_get_drvdata(pdev); + + stop_devapc(ctx); +- +- clk_disable_unprepare(ctx->infra_clk); +- +- return 0; ++ iounmap(ctx->infra_base); + } + + static struct platform_driver mtk_devapc_driver = { + .probe = mtk_devapc_probe, +- .remove = mtk_devapc_remove, ++ .remove_new = mtk_devapc_remove, + .driver = { + .name = "mtk-devapc", + .of_match_table = mtk_devapc_dt_match, +diff --git a/drivers/soc/qcom/smem_state.c b/drivers/soc/qcom/smem_state.c +index e848cc9a3cf801..a8be3a2f33824f 100644 +--- a/drivers/soc/qcom/smem_state.c ++++ b/drivers/soc/qcom/smem_state.c +@@ -116,7 +116,8 @@ struct qcom_smem_state *qcom_smem_state_get(struct device *dev, + + if (args.args_count != 1) { + dev_err(dev, "invalid #qcom,smem-state-cells\n"); +- return ERR_PTR(-EINVAL); ++ state = ERR_PTR(-EINVAL); ++ goto put; + } + + state = of_node_to_state(args.np); +diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c +index d6ddb6fecff14a..5e39f1d50c4919 100644 +--- a/drivers/soc/qcom/socinfo.c ++++ b/drivers/soc/qcom/socinfo.c +@@ -617,7 +617,7 @@ static int qcom_socinfo_probe(struct platform_device *pdev) + if (!qs->attr.soc_id || !qs->attr.revision) + return -ENOMEM; + +- if (offsetof(struct socinfo, serial_num) <= item_size) { ++ if (offsetofend(struct socinfo, serial_num) <= item_size) { + qs->attr.serial_number = devm_kasprintf(&pdev->dev, GFP_KERNEL, + "%u", + le32_to_cpu(info->serial_num)); +diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c +index 435309b09227ea..fc10936ed33ba2 100644 +--- a/drivers/spi/spi-mxs.c ++++ b/drivers/spi/spi-mxs.c +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + + #define DRIVER_NAME "mxs-spi" + +@@ -252,7 +253,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, + desc = dmaengine_prep_slave_sg(ssp->dmach, + &dma_xfer[sg_count].sg, 1, + (flags & TXRX_WRITE) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, +- DMA_PREP_INTERRUPT | DMA_CTRL_ACK); ++ DMA_PREP_INTERRUPT | MXS_DMA_CTRL_WAIT4END); + + if (!desc) { + dev_err(ssp->dev, +diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c +index 78f31b61a2aac4..77ea6b5223483e 100644 +--- a/drivers/spi/spi-zynq-qspi.c ++++ b/drivers/spi/spi-zynq-qspi.c +@@ -379,12 +379,21 @@ static int zynq_qspi_setup_op(struct spi_device *spi) + { + struct spi_controller *ctlr = spi->master; + struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr); ++ int ret; + + if (ctlr->busy) + return -EBUSY; + +- clk_enable(qspi->refclk); +- clk_enable(qspi->pclk); ++ ret = clk_enable(qspi->refclk); ++ if (ret) ++ return ret; ++ ++ ret = clk_enable(qspi->pclk); ++ if (ret) { ++ clk_disable(qspi->refclk); ++ return ret; ++ } ++ + zynq_qspi_write(qspi, ZYNQ_QSPI_ENABLE_OFFSET, + ZYNQ_QSPI_ENABLE_ENABLE_MASK); + +diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c +index b677cf0e0c849e..386ff38821e2f5 100644 +--- a/drivers/staging/media/imx/imx-media-of.c ++++ b/drivers/staging/media/imx/imx-media-of.c +@@ -55,22 +55,18 @@ int imx_media_add_of_subdevs(struct imx_media_dev *imxmd, + break; + + ret = imx_media_of_add_csi(imxmd, csi_np); ++ of_node_put(csi_np); + if (ret) { + /* unavailable or already added is not an error */ + if (ret == -ENODEV || ret == -EEXIST) { +- of_node_put(csi_np); + continue; + } + + /* other error, can't continue */ +- goto err_out; ++ return ret; + } + } + + return 0; +- +-err_out: +- of_node_put(csi_np); +- return ret; + } + EXPORT_SYMBOL_GPL(imx_media_add_of_subdevs); +diff --git a/drivers/tee/optee/supp.c b/drivers/tee/optee/supp.c +index 322a543b8c278a..d0f397c9024201 100644 +--- a/drivers/tee/optee/supp.c ++++ b/drivers/tee/optee/supp.c +@@ -80,7 +80,6 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, + struct optee *optee = tee_get_drvdata(ctx->teedev); + struct optee_supp *supp = &optee->supp; + struct optee_supp_req *req; +- bool interruptable; + u32 ret; + + /* +@@ -111,36 +110,18 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, + /* + * Wait for supplicant to process and return result, once we've + * returned from wait_for_completion(&req->c) successfully we have +- * exclusive access again. ++ * exclusive access again. Allow the wait to be killable such that ++ * the wait doesn't turn into an indefinite state if the supplicant ++ * gets hung for some reason. + */ +- while (wait_for_completion_interruptible(&req->c)) { ++ if (wait_for_completion_killable(&req->c)) { + mutex_lock(&supp->mutex); +- interruptable = !supp->ctx; +- if (interruptable) { +- /* +- * There's no supplicant available and since the +- * supp->mutex currently is held none can +- * become available until the mutex released +- * again. +- * +- * Interrupting an RPC to supplicant is only +- * allowed as a way of slightly improving the user +- * experience in case the supplicant hasn't been +- * started yet. During normal operation the supplicant +- * will serve all requests in a timely manner and +- * interrupting then wouldn't make sense. +- */ +- if (req->in_queue) { +- list_del(&req->link); +- req->in_queue = false; +- } ++ if (req->in_queue) { ++ list_del(&req->link); ++ req->in_queue = false; + } + mutex_unlock(&supp->mutex); +- +- if (interruptable) { +- req->ret = TEEC_ERROR_COMMUNICATION; +- break; +- } ++ req->ret = TEEC_ERROR_COMMUNICATION; + } + + ret = req->ret; +diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h +index d9500a25e03abf..6e9d6c489813f4 100644 +--- a/drivers/tty/serial/8250/8250.h ++++ b/drivers/tty/serial/8250/8250.h +@@ -328,6 +328,7 @@ static inline int is_omap1510_8250(struct uart_8250_port *pt) + + #ifdef CONFIG_SERIAL_8250_DMA + extern int serial8250_tx_dma(struct uart_8250_port *); ++extern void serial8250_tx_dma_flush(struct uart_8250_port *); + extern int serial8250_rx_dma(struct uart_8250_port *); + extern void serial8250_rx_dma_flush(struct uart_8250_port *); + extern int serial8250_request_dma(struct uart_8250_port *); +@@ -360,6 +361,7 @@ static inline int serial8250_tx_dma(struct uart_8250_port *p) + { + return -1; + } ++static inline void serial8250_tx_dma_flush(struct uart_8250_port *p) { } + static inline int serial8250_rx_dma(struct uart_8250_port *p) + { + return -1; +diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c +index ec3cd723256fb1..7a92e3397908ef 100644 +--- a/drivers/tty/serial/8250/8250_dma.c ++++ b/drivers/tty/serial/8250/8250_dma.c +@@ -137,6 +137,22 @@ int serial8250_tx_dma(struct uart_8250_port *p) + return ret; + } + ++void serial8250_tx_dma_flush(struct uart_8250_port *p) ++{ ++ struct uart_8250_dma *dma = p->dma; ++ ++ if (!dma->tx_running) ++ return; ++ ++ /* ++ * kfifo_reset() has been called by the serial core, avoid ++ * advancing and underflowing in __dma_tx_complete(). ++ */ ++ dma->tx_size = 0; ++ ++ dmaengine_terminate_async(dma->rxchan); ++} ++ + int serial8250_rx_dma(struct uart_8250_port *p) + { + struct uart_8250_dma *dma = p->dma; +diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +index 1d842bb8d94695..9248d83489b1fd 100644 +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -66,6 +66,8 @@ static const struct pci_device_id pci_use_msi[] = { + 0xA000, 0x1000) }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922, + 0xA000, 0x1000) }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_AX99100, ++ 0xA000, 0x1000) }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_HP_3PAR, PCI_DEVICE_ID_HPE_PCI_SERIAL, + PCI_ANY_ID, PCI_ANY_ID) }, + { } +@@ -6299,6 +6301,14 @@ static const struct pci_device_id serial_pci_tbl[] = { + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, + 0xA000, 0x3004, + 0, 0, pbn_b0_bt_4_115200 }, ++ ++ /* ++ * ASIX AX99100 PCIe to Multi I/O Controller ++ */ ++ { PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_AX99100, ++ 0xA000, 0x1000, ++ 0, 0, pbn_b0_1_115200 }, ++ + /* Intel CE4100 */ + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, +diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c +index 2d595a646bb89c..be50781ef0b52e 100644 +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -2512,6 +2512,14 @@ static unsigned int npcm_get_divisor(struct uart_8250_port *up, + return DIV_ROUND_CLOSEST(port->uartclk, 16 * baud + 2) - 2; + } + ++static void serial8250_flush_buffer(struct uart_port *port) ++{ ++ struct uart_8250_port *up = up_to_u8250p(port); ++ ++ if (up->dma) ++ serial8250_tx_dma_flush(up); ++} ++ + static unsigned int serial8250_do_get_divisor(struct uart_port *port, + unsigned int baud, + unsigned int *frac) +@@ -3238,6 +3246,7 @@ static const struct uart_ops serial8250_pops = { + .break_ctl = serial8250_break_ctl, + .startup = serial8250_startup, + .shutdown = serial8250_shutdown, ++ .flush_buffer = serial8250_flush_buffer, + .set_termios = serial8250_set_termios, + .set_ldisc = serial8250_set_ldisc, + .pm = serial8250_pm, +diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c +index 6cd7bd7b6782d5..eb9c1e991024a5 100644 +--- a/drivers/tty/serial/sh-sci.c ++++ b/drivers/tty/serial/sh-sci.c +@@ -164,6 +164,7 @@ struct sci_port { + static struct sci_port sci_ports[SCI_NPORTS]; + static unsigned long sci_ports_in_use; + static struct uart_driver sci_uart_driver; ++static bool sci_uart_earlycon; + + static inline struct sci_port * + to_sci_port(struct uart_port *uart) +@@ -3319,6 +3320,7 @@ static int sci_probe_single(struct platform_device *dev, + static int sci_probe(struct platform_device *dev) + { + struct plat_sci_port *p; ++ struct resource *res; + struct sci_port *sp; + unsigned int dev_id; + int ret; +@@ -3348,6 +3350,26 @@ static int sci_probe(struct platform_device *dev) + } + + sp = &sci_ports[dev_id]; ++ ++ /* ++ * In case: ++ * - the probed port alias is zero (as the one used by earlycon), and ++ * - the earlycon is still active (e.g., "earlycon keep_bootcon" in ++ * bootargs) ++ * ++ * defer the probe of this serial. This is a debug scenario and the user ++ * must be aware of it. ++ * ++ * Except when the probed port is the same as the earlycon port. ++ */ ++ ++ res = platform_get_resource(dev, IORESOURCE_MEM, 0); ++ if (!res) ++ return -ENODEV; ++ ++ if (sci_uart_earlycon && sp == &sci_ports[0] && sp->port.mapbase != res->start) ++ return dev_err_probe(&dev->dev, -EBUSY, "sci_port[0] is used by earlycon!\n"); ++ + platform_set_drvdata(dev, sp); + + ret = sci_probe_single(dev, dev_id, p, sp); +@@ -3431,7 +3453,7 @@ sh_early_platform_init_buffer("earlyprintk", &sci_driver, + early_serial_buf, ARRAY_SIZE(early_serial_buf)); + #endif + #ifdef CONFIG_SERIAL_SH_SCI_EARLYCON +-static struct plat_sci_port port_cfg __initdata; ++static struct plat_sci_port port_cfg; + + static int __init early_console_setup(struct earlycon_device *device, + int type) +@@ -3446,6 +3468,7 @@ static int __init early_console_setup(struct earlycon_device *device, + port_cfg.type = type; + sci_ports[0].cfg = &port_cfg; + sci_ports[0].params = sci_probe_regmap(&port_cfg); ++ sci_uart_earlycon = true; + port_cfg.scscr = sci_serial_in(&sci_ports[0].port, SCSCR); + sci_serial_out(&sci_ports[0].port, SCSCR, + SCSCR_RE | SCSCR_TE | port_cfg.scscr); +diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c +index 815e3e26ee206c..4fb2f7bee91d14 100644 +--- a/drivers/tty/serial/xilinx_uartps.c ++++ b/drivers/tty/serial/xilinx_uartps.c +@@ -268,7 +268,7 @@ static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus) + continue; + } + +- if (uart_handle_sysrq_char(port, data)) ++ if (uart_prepare_sysrq_char(port, data)) + continue; + + if (is_rxbs_support) { +@@ -385,7 +385,7 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id) + !(readl(port->membase + CDNS_UART_CR) & CDNS_UART_CR_RX_DIS)) + cdns_uart_handle_rx(dev_id, isrstatus); + +- spin_unlock(&port->lock); ++ uart_unlock_and_check_sysrq(port); + return IRQ_HANDLED; + } + +@@ -1217,10 +1217,8 @@ static void cdns_uart_console_write(struct console *co, const char *s, + unsigned int imr, ctrl; + int locked = 1; + +- if (port->sysrq) +- locked = 0; +- else if (oops_in_progress) +- locked = spin_trylock_irqsave(&port->lock, flags); ++ if (oops_in_progress) ++ locked = uart_port_trylock_irqsave(port, &flags); + else + spin_lock_irqsave(&port->lock, flags); + +diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c +index 8f3b9a0a38e1dd..1443e9cf631a6e 100644 +--- a/drivers/usb/atm/cxacru.c ++++ b/drivers/usb/atm/cxacru.c +@@ -1131,7 +1131,10 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, + struct cxacru_data *instance; + struct usb_device *usb_dev = interface_to_usbdev(intf); + struct usb_host_endpoint *cmd_ep = usb_dev->ep_in[CXACRU_EP_CMD]; +- struct usb_endpoint_descriptor *in, *out; ++ static const u8 ep_addrs[] = { ++ CXACRU_EP_CMD + USB_DIR_IN, ++ CXACRU_EP_CMD + USB_DIR_OUT, ++ 0}; + int ret; + + /* instance init */ +@@ -1179,13 +1182,11 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, + } + + if (usb_endpoint_xfer_int(&cmd_ep->desc)) +- ret = usb_find_common_endpoints(intf->cur_altsetting, +- NULL, NULL, &in, &out); ++ ret = usb_check_int_endpoints(intf, ep_addrs); + else +- ret = usb_find_common_endpoints(intf->cur_altsetting, +- &in, &out, NULL, NULL); ++ ret = usb_check_bulk_endpoints(intf, ep_addrs); + +- if (ret) { ++ if (!ret) { + usb_err(usbatm_instance, "cxacru_bind: interface has incorrect endpoints\n"); + ret = -ENODEV; + goto fail; +diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c +index d8efa90479e234..13731e85980e27 100644 +--- a/drivers/usb/chipidea/ci_hdrc_imx.c ++++ b/drivers/usb/chipidea/ci_hdrc_imx.c +@@ -356,10 +356,9 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + if (PTR_ERR(data->pinctrl) == -ENODEV) + data->pinctrl = NULL; + else if (IS_ERR(data->pinctrl)) { +- if (PTR_ERR(data->pinctrl) != -EPROBE_DEFER) +- dev_err(dev, "pinctrl get failed, err=%ld\n", +- PTR_ERR(data->pinctrl)); +- return PTR_ERR(data->pinctrl); ++ ret = dev_err_probe(dev, PTR_ERR(data->pinctrl), ++ "pinctrl get failed\n"); ++ goto err_put; + } + + data->hsic_pad_regulator = +@@ -368,11 +367,9 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + /* no pad regualator is needed */ + data->hsic_pad_regulator = NULL; + } else if (IS_ERR(data->hsic_pad_regulator)) { +- if (PTR_ERR(data->hsic_pad_regulator) != -EPROBE_DEFER) +- dev_err(dev, +- "Get HSIC pad regulator error: %ld\n", +- PTR_ERR(data->hsic_pad_regulator)); +- return PTR_ERR(data->hsic_pad_regulator); ++ ret = dev_err_probe(dev, PTR_ERR(data->hsic_pad_regulator), ++ "Get HSIC pad regulator error\n"); ++ goto err_put; + } + + if (data->hsic_pad_regulator) { +@@ -380,7 +377,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + if (ret) { + dev_err(dev, + "Failed to enable HSIC pad regulator\n"); +- return ret; ++ goto err_put; + } + } + } +@@ -394,13 +391,14 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + dev_err(dev, + "pinctrl_hsic_idle lookup failed, err=%ld\n", + PTR_ERR(pinctrl_hsic_idle)); +- return PTR_ERR(pinctrl_hsic_idle); ++ ret = PTR_ERR(pinctrl_hsic_idle); ++ goto err_put; + } + + ret = pinctrl_select_state(data->pinctrl, pinctrl_hsic_idle); + if (ret) { + dev_err(dev, "hsic_idle select failed, err=%d\n", ret); +- return ret; ++ goto err_put; + } + + data->pinctrl_hsic_active = pinctrl_lookup_state(data->pinctrl, +@@ -409,7 +407,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + dev_err(dev, + "pinctrl_hsic_active lookup failed, err=%ld\n", + PTR_ERR(data->pinctrl_hsic_active)); +- return PTR_ERR(data->pinctrl_hsic_active); ++ ret = PTR_ERR(data->pinctrl_hsic_active); ++ goto err_put; + } + } + +@@ -465,9 +464,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + &pdata); + if (IS_ERR(data->ci_pdev)) { + ret = PTR_ERR(data->ci_pdev); +- if (ret != -EPROBE_DEFER) +- dev_err(dev, "ci_hdrc_add_device failed, err=%d\n", +- ret); ++ dev_err_probe(dev, ret, "ci_hdrc_add_device failed\n"); + goto err_clk; + } + +@@ -511,10 +508,12 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + if (pdata.flags & CI_HDRC_PMQOS) + cpu_latency_qos_remove_request(&data->pm_qos_req); + data->ci_pdev = NULL; ++err_put: ++ put_device(data->usbmisc_data->dev); + return ret; + } + +-static int ci_hdrc_imx_remove(struct platform_device *pdev) ++static void ci_hdrc_imx_remove(struct platform_device *pdev) + { + struct ci_hdrc_imx_data *data = platform_get_drvdata(pdev); + +@@ -534,8 +533,7 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) + if (data->hsic_pad_regulator) + regulator_disable(data->hsic_pad_regulator); + } +- +- return 0; ++ put_device(data->usbmisc_data->dev); + } + + static void ci_hdrc_imx_shutdown(struct platform_device *pdev) +@@ -681,7 +679,7 @@ static const struct dev_pm_ops ci_hdrc_imx_pm_ops = { + }; + static struct platform_driver ci_hdrc_imx_driver = { + .probe = ci_hdrc_imx_probe, +- .remove = ci_hdrc_imx_remove, ++ .remove_new = ci_hdrc_imx_remove, + .shutdown = ci_hdrc_imx_shutdown, + .driver = { + .name = "imx_usb", +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 4871d0f09f6bac..48be3c4f02a3c7 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -360,7 +360,7 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf) + static void acm_ctrl_irq(struct urb *urb) + { + struct acm *acm = urb->context; +- struct usb_cdc_notification *dr = urb->transfer_buffer; ++ struct usb_cdc_notification *dr; + unsigned int current_size = urb->actual_length; + unsigned int expected_size, copy_size, alloc_size; + int retval; +@@ -387,14 +387,25 @@ static void acm_ctrl_irq(struct urb *urb) + + usb_mark_last_busy(acm->dev); + +- if (acm->nb_index) ++ if (acm->nb_index == 0) { ++ /* ++ * The first chunk of a message must contain at least the ++ * notification header with the length field, otherwise we ++ * can't get an expected_size. ++ */ ++ if (current_size < sizeof(struct usb_cdc_notification)) { ++ dev_dbg(&acm->control->dev, "urb too short\n"); ++ goto exit; ++ } ++ dr = urb->transfer_buffer; ++ } else { + dr = (struct usb_cdc_notification *)acm->notification_buffer; +- ++ } + /* size = notification-header + (optional) data */ + expected_size = sizeof(struct usb_cdc_notification) + + le16_to_cpu(dr->wLength); + +- if (current_size < expected_size) { ++ if (acm->nb_index != 0 || current_size < expected_size) { + /* notification is transmitted fragmented, reassemble */ + if (acm->nb_size < expected_size) { + u8 *new_buffer; +@@ -1707,13 +1718,16 @@ static const struct usb_device_id acm_ids[] = { + { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, +- { USB_DEVICE(0x045b, 0x023c), /* Renesas USB Download mode */ ++ { USB_DEVICE(0x045b, 0x023c), /* Renesas R-Car H3 USB Download mode */ ++ .driver_info = DISABLE_ECHO, /* Don't echo banner */ ++ }, ++ { USB_DEVICE(0x045b, 0x0247), /* Renesas R-Car D3 USB Download mode */ + .driver_info = DISABLE_ECHO, /* Don't echo banner */ + }, +- { USB_DEVICE(0x045b, 0x0248), /* Renesas USB Download mode */ ++ { USB_DEVICE(0x045b, 0x0248), /* Renesas R-Car M3-N USB Download mode */ + .driver_info = DISABLE_ECHO, /* Don't echo banner */ + }, +- { USB_DEVICE(0x045b, 0x024D), /* Renesas USB Download mode */ ++ { USB_DEVICE(0x045b, 0x024D), /* Renesas R-Car E3 USB Download mode */ + .driver_info = DISABLE_ECHO, /* Don't echo banner */ + }, + { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */ +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 1a7a6161e68ff3..4ff49d0ff4dd44 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1803,6 +1803,17 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) + desc = intf->cur_altsetting; + hdev = interface_to_usbdev(intf); + ++ /* ++ * The USB 2.0 spec prohibits hubs from having more than one ++ * configuration or interface, and we rely on this prohibition. ++ * Refuse to accept a device that violates it. ++ */ ++ if (hdev->descriptor.bNumConfigurations > 1 || ++ hdev->actconfig->desc.bNumInterfaces > 1) { ++ dev_err(&intf->dev, "Invalid hub with more than one config or interface\n"); ++ return -EINVAL; ++ } ++ + /* + * Set default autosuspend delay as 0 to speedup bus suspend, + * based on the below considerations: +@@ -4636,7 +4647,6 @@ void usb_ep0_reinit(struct usb_device *udev) + EXPORT_SYMBOL_GPL(usb_ep0_reinit); + + #define usb_sndaddr0pipe() (PIPE_CONTROL << 30) +-#define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN) + + static int hub_set_address(struct usb_device *udev, int devnum) + { +@@ -4654,7 +4664,7 @@ static int hub_set_address(struct usb_device *udev, int devnum) + if (udev->state != USB_STATE_DEFAULT) + return -EINVAL; + if (hcd->driver->address_device) +- retval = hcd->driver->address_device(hcd, udev); ++ retval = hcd->driver->address_device(hcd, udev, USB_CTRL_SET_TIMEOUT); + else + retval = usb_control_msg(udev, usb_sndaddr0pipe(), + USB_REQ_SET_ADDRESS, 0, devnum, 0, +@@ -4737,7 +4747,7 @@ static int get_bMaxPacketSize0(struct usb_device *udev, + for (i = 0; i < GET_MAXPACKET0_TRIES; ++i) { + /* Start with invalid values in case the transfer fails */ + buf->bDescriptorType = buf->bMaxPacketSize0 = 0; +- rc = usb_control_msg(udev, usb_rcvaddr0pipe(), ++ rc = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, + USB_DT_DEVICE << 8, 0, + buf, size, +@@ -5960,6 +5970,36 @@ void usb_hub_cleanup(void) + usb_deregister(&hub_driver); + } /* usb_hub_cleanup() */ + ++/** ++ * hub_hc_release_resources - clear resources used by host controller ++ * @udev: pointer to device being released ++ * ++ * Context: task context, might sleep ++ * ++ * Function releases the host controller resources in correct order before ++ * making any operation on resuming usb device. The host controller resources ++ * allocated for devices in tree should be released starting from the last ++ * usb device in tree toward the root hub. This function is used only during ++ * resuming device when usb device require reinitialization – that is, when ++ * flag udev->reset_resume is set. ++ * ++ * This call is synchronous, and may not be used in an interrupt context. ++ */ ++static void hub_hc_release_resources(struct usb_device *udev) ++{ ++ struct usb_hub *hub = usb_hub_to_struct_hub(udev); ++ struct usb_hcd *hcd = bus_to_hcd(udev->bus); ++ int i; ++ ++ /* Release up resources for all children before this device */ ++ for (i = 0; i < udev->maxchild; i++) ++ if (hub->ports[i]->child) ++ hub_hc_release_resources(hub->ports[i]->child); ++ ++ if (hcd->driver->reset_device) ++ hcd->driver->reset_device(hcd, udev); ++} ++ + /** + * usb_reset_and_verify_device - perform a USB port reset to reinitialize a device + * @udev: device to reset (not in SUSPENDED or NOTATTACHED state) +@@ -6034,6 +6074,9 @@ static int usb_reset_and_verify_device(struct usb_device *udev) + bos = udev->bos; + udev->bos = NULL; + ++ if (udev->reset_resume) ++ hub_hc_release_resources(udev); ++ + mutex_lock(hcd->address0_mutex); + + for (i = 0; i < PORT_INIT_TRIES; ++i) { +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 6b21afb465fbca..a312363d584f92 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -338,6 +338,10 @@ static const struct usb_device_id usb_quirk_list[] = { + { USB_DEVICE(0x0638, 0x0a13), .driver_info = + USB_QUIRK_STRING_FETCH_255 }, + ++ /* Prolific Single-LUN Mass Storage Card Reader */ ++ { USB_DEVICE(0x067b, 0x2731), .driver_info = USB_QUIRK_DELAY_INIT | ++ USB_QUIRK_NO_LPM }, ++ + /* Saitek Cyborg Gold Joystick */ + { USB_DEVICE(0x06a3, 0x0006), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, +@@ -429,6 +433,9 @@ static const struct usb_device_id usb_quirk_list[] = { + { USB_DEVICE(0x0c45, 0x7056), .driver_info = + USB_QUIRK_IGNORE_REMOTE_WAKEUP }, + ++ /* Sony Xperia XZ1 Compact (lilac) smartphone in fastboot mode */ ++ { USB_DEVICE(0x0fce, 0x0dde), .driver_info = USB_QUIRK_NO_LPM }, ++ + /* Action Semiconductor flash disk */ + { USB_DEVICE(0x10d6, 0x2200), .driver_info = + USB_QUIRK_STRING_FETCH_255 }, +@@ -519,6 +526,9 @@ static const struct usb_device_id usb_quirk_list[] = { + /* Blackmagic Design UltraStudio SDI */ + { USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM }, + ++ /* Teclast disk */ ++ { USB_DEVICE(0x1f75, 0x0917), .driver_info = USB_QUIRK_NO_LPM }, ++ + /* Hauppauge HVR-950q */ + { USB_DEVICE(0x2040, 0x7200), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, +diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c +index 4422da56136522..7d8523398e1910 100644 +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -4613,6 +4613,7 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget) + spin_lock_irqsave(&hsotg->lock, flags); + + hsotg->driver = NULL; ++ hsotg->gadget.dev.of_node = NULL; + hsotg->gadget.speed = USB_SPEED_UNKNOWN; + hsotg->enabled = 0; + +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index f507f055f523c1..bb20d8dd187918 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -123,11 +123,24 @@ void dwc3_enable_susphy(struct dwc3 *dwc, bool enable) + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + } + +-void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode) ++void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy) + { ++ unsigned int hw_mode; + u32 reg; + + reg = dwc3_readl(dwc->regs, DWC3_GCTL); ++ ++ /* ++ * For DRD controllers, GUSB3PIPECTL.SUSPENDENABLE and ++ * GUSB2PHYCFG.SUSPHY should be cleared during mode switching, ++ * and they can be set after core initialization. ++ */ ++ hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); ++ if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD && !ignore_susphy) { ++ if (DWC3_GCTL_PRTCAP(reg) != mode) ++ dwc3_enable_susphy(dwc, false); ++ } ++ + reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG)); + reg |= DWC3_GCTL_PRTCAPDIR(mode); + dwc3_writel(dwc->regs, DWC3_GCTL, reg); +@@ -207,7 +220,7 @@ static void __dwc3_set_mode(struct work_struct *work) + + spin_lock_irqsave(&dwc->lock, flags); + +- dwc3_set_prtcap(dwc, desired_dr_role); ++ dwc3_set_prtcap(dwc, desired_dr_role, false); + + spin_unlock_irqrestore(&dwc->lock, flags); + +@@ -651,16 +664,7 @@ static int dwc3_phy_setup(struct dwc3 *dwc) + */ + reg &= ~DWC3_GUSB3PIPECTL_UX_EXIT_PX; + +- /* +- * Above DWC_usb3.0 1.94a, it is recommended to set +- * DWC3_GUSB3PIPECTL_SUSPHY to '0' during coreConsultant configuration. +- * So default value will be '0' when the core is reset. Application +- * needs to set it to '1' after the core initialization is completed. +- * +- * Similarly for DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be +- * cleared after power-on reset, and it can be set after core +- * initialization. +- */ ++ /* Ensure the GUSB3PIPECTL.SUSPENDENABLE is cleared prior to phy init. */ + reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; + + if (dwc->u2ss_inp3_quirk) +@@ -733,15 +737,7 @@ static int dwc3_phy_setup(struct dwc3 *dwc) + break; + } + +- /* +- * Above DWC_usb3.0 1.94a, it is recommended to set +- * DWC3_GUSB2PHYCFG_SUSPHY to '0' during coreConsultant configuration. +- * So default value will be '0' when the core is reset. Application +- * needs to set it to '1' after the core initialization is completed. +- * +- * Similarly for DRD controllers, GUSB2PHYCFG.SUSPHY must be cleared +- * after power-on reset, and it can be set after core initialization. +- */ ++ /* Ensure the GUSB2PHYCFG.SUSPHY is cleared prior to phy init. */ + reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; + + if (dwc->dis_enblslpm_quirk) +@@ -1158,6 +1154,25 @@ static int dwc3_core_init(struct dwc3 *dwc) + } + } + ++ /* ++ * Above DWC_usb3.0 1.94a, it is recommended to set ++ * DWC3_GUSB3PIPECTL_SUSPHY and DWC3_GUSB2PHYCFG_SUSPHY to '0' during ++ * coreConsultant configuration. So default value will be '0' when the ++ * core is reset. Application needs to set it to '1' after the core ++ * initialization is completed. ++ * ++ * Certain phy requires to be in P0 power state during initialization. ++ * Make sure GUSB3PIPECTL.SUSPENDENABLE and GUSB2PHYCFG.SUSPHY are clear ++ * prior to phy init to maintain in the P0 state. ++ * ++ * After phy initialization, some phy operations can only be executed ++ * while in lower P states. Ensure GUSB3PIPECTL.SUSPENDENABLE and ++ * GUSB2PHYCFG.SUSPHY are set soon after initialization to avoid ++ * blocking phy ops. ++ */ ++ if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) ++ dwc3_enable_susphy(dwc, true); ++ + return 0; + + err4: +@@ -1245,7 +1260,7 @@ static int dwc3_core_init_mode(struct dwc3 *dwc) + + switch (dwc->dr_mode) { + case USB_DR_MODE_PERIPHERAL: +- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); ++ dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE, false); + + if (dwc->usb2_phy) + otg_set_vbus(dwc->usb2_phy->otg, false); +@@ -1257,7 +1272,7 @@ static int dwc3_core_init_mode(struct dwc3 *dwc) + return dev_err_probe(dev, ret, "failed to initialize gadget\n"); + break; + case USB_DR_MODE_HOST: +- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST); ++ dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST, false); + + if (dwc->usb2_phy) + otg_set_vbus(dwc->usb2_phy->otg, true); +@@ -1300,7 +1315,7 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc) + } + + /* de-assert DRVVBUS for HOST and OTG mode */ +- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); ++ dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE, true); + } + + static void dwc3_get_properties(struct dwc3 *dwc) +@@ -1314,8 +1329,6 @@ static void dwc3_get_properties(struct dwc3 *dwc) + u8 tx_thr_num_pkt_prd = 0; + u8 tx_max_burst_prd = 0; + u8 tx_fifo_resize_max_num; +- const char *usb_psy_name; +- int ret; + + /* default to highest possible threshold */ + lpm_nyet_threshold = 0xf; +@@ -1348,13 +1361,6 @@ static void dwc3_get_properties(struct dwc3 *dwc) + else + dwc->sysdev = dwc->dev; + +- ret = device_property_read_string(dev, "usb-psy-name", &usb_psy_name); +- if (ret >= 0) { +- dwc->usb_psy = power_supply_get_by_name(usb_psy_name); +- if (!dwc->usb_psy) +- dev_err(dev, "couldn't get usb power supply\n"); +- } +- + dwc->has_lpm_erratum = device_property_read_bool(dev, + "snps,has-lpm-erratum"); + device_property_read_u8(dev, "snps,lpm-nyet-threshold", +@@ -1450,8 +1456,6 @@ static void dwc3_get_properties(struct dwc3 *dwc) + dwc->tx_thr_num_pkt_prd = tx_thr_num_pkt_prd; + dwc->tx_max_burst_prd = tx_max_burst_prd; + +- dwc->imod_interval = 0; +- + dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num; + } + +@@ -1469,21 +1473,19 @@ static void dwc3_check_params(struct dwc3 *dwc) + unsigned int hwparam_gen = + DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3); + +- /* Check for proper value of imod_interval */ +- if (dwc->imod_interval && !dwc3_has_imod(dwc)) { +- dev_warn(dwc->dev, "Interrupt moderation not supported\n"); +- dwc->imod_interval = 0; +- } +- + /* ++ * Enable IMOD for all supporting controllers. ++ * ++ * Particularly, DWC_usb3 v3.00a must enable this feature for ++ * the following reason: ++ * + * Workaround for STAR 9000961433 which affects only version + * 3.00a of the DWC_usb3 core. This prevents the controller + * interrupt from being masked while handling events. IMOD + * allows us to work around this issue. Enable it for the + * affected version. + */ +- if (!dwc->imod_interval && +- DWC3_VER_IS(DWC3, 300A)) ++ if (dwc3_has_imod((dwc))) + dwc->imod_interval = 1; + + /* Check the maximum_speed parameter */ +@@ -1564,6 +1566,23 @@ static void dwc3_check_params(struct dwc3 *dwc) + } + } + ++static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc) ++{ ++ struct power_supply *usb_psy; ++ const char *usb_psy_name; ++ int ret; ++ ++ ret = device_property_read_string(dwc->dev, "usb-psy-name", &usb_psy_name); ++ if (ret < 0) ++ return NULL; ++ ++ usb_psy = power_supply_get_by_name(usb_psy_name); ++ if (!usb_psy) ++ return ERR_PTR(-EPROBE_DEFER); ++ ++ return usb_psy; ++} ++ + static int dwc3_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -1608,6 +1627,10 @@ static int dwc3_probe(struct platform_device *pdev) + + dwc3_get_properties(dwc); + ++ dwc->usb_psy = dwc3_get_usb_power_supply(dwc); ++ if (IS_ERR(dwc->usb_psy)) ++ return dev_err_probe(dev, PTR_ERR(dwc->usb_psy), "couldn't get usb power supply\n"); ++ + dwc->reset = devm_reset_control_array_get_optional_shared(dev); + if (IS_ERR(dwc->reset)) + return PTR_ERR(dwc->reset); +@@ -1870,7 +1893,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) + if (ret) + return ret; + +- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); ++ dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE, true); + dwc3_gadget_resume(dwc); + break; + case DWC3_GCTL_PRTCAP_HOST: +@@ -1878,7 +1901,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) + ret = dwc3_core_init_for_resume(dwc); + if (ret) + return ret; +- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST); ++ dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST, true); + break; + } + /* Restore GUSB2PHYCFG bits that were modified in suspend */ +@@ -1903,7 +1926,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) + if (ret) + return ret; + +- dwc3_set_prtcap(dwc, dwc->current_dr_role); ++ dwc3_set_prtcap(dwc, dwc->current_dr_role, true); + + dwc3_otg_init(dwc); + if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST) { +diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h +index d4a37a1539d2cf..c2783d87e6c81e 100644 +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -1475,7 +1475,7 @@ struct dwc3_gadget_ep_cmd_params { + #define DWC3_HAS_OTG BIT(3) + + /* prototypes */ +-void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode); ++void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy); + void dwc3_set_mode(struct dwc3 *dwc, u32 mode); + u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type); + +diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c +index ba37bc72a22057..b3c6de3d232bd5 100644 +--- a/drivers/usb/dwc3/drd.c ++++ b/drivers/usb/dwc3/drd.c +@@ -173,7 +173,7 @@ void dwc3_otg_init(struct dwc3 *dwc) + * block "Initialize GCTL for OTG operation". + */ + /* GCTL.PrtCapDir=2'b11 */ +- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG); ++ dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG, true); + /* GUSB2PHYCFG0.SusPHY=0 */ + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); + reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; +@@ -585,7 +585,7 @@ int dwc3_drd_init(struct dwc3 *dwc) + + dwc3_drd_update(dwc); + } else { +- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG); ++ dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG, true); + + /* use OTG block to get ID event */ + irq = dwc3_otg_get_irq(dwc); +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index d39906248850a8..fda00639ff0cbf 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2457,11 +2457,39 @@ static void __dwc3_gadget_set_speed(struct dwc3 *dwc) + static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) + { + u32 reg; +- u32 timeout = 500; ++ u32 timeout = 2000; ++ u32 saved_config = 0; + + if (pm_runtime_suspended(dwc->dev)) + return 0; + ++ /* ++ * When operating in USB 2.0 speeds (HS/FS), ensure that ++ * GUSB2PHYCFG.ENBLSLPM and GUSB2PHYCFG.SUSPHY are cleared before starting ++ * or stopping the controller. This resolves timeout issues that occur ++ * during frequent role switches between host and device modes. ++ * ++ * Save and clear these settings, then restore them after completing the ++ * controller start or stop sequence. ++ * ++ * This solution was discovered through experimentation as it is not ++ * mentioned in the dwc3 programming guide. It has been tested on an ++ * Exynos platforms. ++ */ ++ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); ++ if (reg & DWC3_GUSB2PHYCFG_SUSPHY) { ++ saved_config |= DWC3_GUSB2PHYCFG_SUSPHY; ++ reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; ++ } ++ ++ if (reg & DWC3_GUSB2PHYCFG_ENBLSLPM) { ++ saved_config |= DWC3_GUSB2PHYCFG_ENBLSLPM; ++ reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM; ++ } ++ ++ if (saved_config) ++ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); ++ + reg = dwc3_readl(dwc->regs, DWC3_DCTL); + if (is_on) { + if (DWC3_VER_IS_WITHIN(DWC3, ANY, 187A)) { +@@ -2484,10 +2512,17 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) + dwc3_gadget_dctl_write_safe(dwc, reg); + + do { ++ usleep_range(1000, 2000); + reg = dwc3_readl(dwc->regs, DWC3_DSTS); + reg &= DWC3_DSTS_DEVCTRLHLT; + } while (--timeout && !(!is_on ^ !reg)); + ++ if (saved_config) { ++ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); ++ reg |= saved_config; ++ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); ++ } ++ + if (!timeout) + return -ETIMEDOUT; + +@@ -4262,14 +4297,18 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt) + reg &= ~DWC3_GEVNTSIZ_INTMASK; + dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), reg); + ++ evt->flags &= ~DWC3_EVENT_PENDING; ++ /* ++ * Add an explicit write memory barrier to make sure that the update of ++ * clearing DWC3_EVENT_PENDING is observed in dwc3_check_event_buf() ++ */ ++ wmb(); ++ + if (dwc->imod_interval) { + dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB); + dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), dwc->imod_interval); + } + +- /* Keep the clearing of DWC3_EVENT_PENDING at the end */ +- evt->flags &= ~DWC3_EVENT_PENDING; +- + return ret; + } + +diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c +index 94e86c38576095..96a955e16e25fa 100644 +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -1004,10 +1004,11 @@ static int set_config(struct usb_composite_dev *cdev, + else + usb_gadget_set_remote_wakeup(gadget, 0); + done: +- if (power <= USB_SELF_POWER_VBUS_MAX_DRAW) +- usb_gadget_set_selfpowered(gadget); +- else ++ if (power > USB_SELF_POWER_VBUS_MAX_DRAW || ++ (c && !(c->bmAttributes & USB_CONFIG_ATT_SELFPOWER))) + usb_gadget_clear_selfpowered(gadget); ++ else ++ usb_gadget_set_selfpowered(gadget); + + usb_gadget_vbus_draw(gadget, power); + if (result >= 0 && cdev->delayed_status) +@@ -2475,7 +2476,10 @@ void composite_suspend(struct usb_gadget *gadget) + + cdev->suspended = 1; + +- usb_gadget_set_selfpowered(gadget); ++ if (cdev->config && ++ cdev->config->bmAttributes & USB_CONFIG_ATT_SELFPOWER) ++ usb_gadget_set_selfpowered(gadget); ++ + usb_gadget_vbus_draw(gadget, 2); + } + +@@ -2504,8 +2508,11 @@ void composite_resume(struct usb_gadget *gadget) + else + maxpower = min(maxpower, 900U); + +- if (maxpower > USB_SELF_POWER_VBUS_MAX_DRAW) ++ if (maxpower > USB_SELF_POWER_VBUS_MAX_DRAW || ++ !(cdev->config->bmAttributes & USB_CONFIG_ATT_SELFPOWER)) + usb_gadget_clear_selfpowered(gadget); ++ else ++ usb_gadget_set_selfpowered(gadget); + + usb_gadget_vbus_draw(gadget, maxpower); + } +diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c +index 71a1a26e85c76b..3e8ea1bbe429a2 100644 +--- a/drivers/usb/gadget/function/f_midi.c ++++ b/drivers/usb/gadget/function/f_midi.c +@@ -282,7 +282,7 @@ f_midi_complete(struct usb_ep *ep, struct usb_request *req) + /* Our transmit completed. See if there's more to go. + * f_midi_transmit eats req, don't queue it again. */ + req->length = 0; +- f_midi_transmit(midi); ++ queue_work(system_highpri_wq, &midi->work); + return; + } + break; +@@ -999,11 +999,11 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) + } + + /* configure the endpoint descriptors ... */ +- ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports); +- ms_out_desc.bNumEmbMIDIJack = midi->in_ports; ++ ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports); ++ ms_out_desc.bNumEmbMIDIJack = midi->out_ports; + +- ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports); +- ms_in_desc.bNumEmbMIDIJack = midi->out_ports; ++ ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports); ++ ms_in_desc.bNumEmbMIDIJack = midi->in_ports; + + /* ... and add them to the list */ + endpoint_descriptor_index = i; +diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c +index de161ee0b1f9b5..934e4b2a049fff 100644 +--- a/drivers/usb/gadget/function/f_tcm.c ++++ b/drivers/usb/gadget/function/f_tcm.c +@@ -245,7 +245,6 @@ static int bot_send_write_request(struct usbg_cmd *cmd) + { + struct f_uas *fu = cmd->fu; + struct se_cmd *se_cmd = &cmd->se_cmd; +- struct usb_gadget *gadget = fuas_to_gadget(fu); + int ret; + + init_completion(&cmd->write_complete); +@@ -256,22 +255,6 @@ static int bot_send_write_request(struct usbg_cmd *cmd) + return -EINVAL; + } + +- if (!gadget->sg_supported) { +- cmd->data_buf = kmalloc(se_cmd->data_length, GFP_KERNEL); +- if (!cmd->data_buf) +- return -ENOMEM; +- +- fu->bot_req_out->buf = cmd->data_buf; +- } else { +- fu->bot_req_out->buf = NULL; +- fu->bot_req_out->num_sgs = se_cmd->t_data_nents; +- fu->bot_req_out->sg = se_cmd->t_data_sg; +- } +- +- fu->bot_req_out->complete = usbg_data_write_cmpl; +- fu->bot_req_out->length = se_cmd->data_length; +- fu->bot_req_out->context = cmd; +- + ret = usbg_prepare_w_request(cmd, fu->bot_req_out); + if (ret) + goto cleanup; +@@ -973,6 +956,7 @@ static void usbg_data_write_cmpl(struct usb_ep *ep, struct usb_request *req) + return; + + cleanup: ++ target_put_sess_cmd(se_cmd); + transport_generic_free_cmd(&cmd->se_cmd, 0); + } + +@@ -1065,8 +1049,7 @@ static void usbg_cmd_work(struct work_struct *work) + + out: + transport_send_check_condition_and_sense(se_cmd, +- TCM_UNSUPPORTED_SCSI_OPCODE, 1); +- transport_generic_free_cmd(&cmd->se_cmd, 0); ++ TCM_UNSUPPORTED_SCSI_OPCODE, 0); + } + + static struct usbg_cmd *usbg_get_cmd(struct f_uas *fu, +@@ -1194,8 +1177,7 @@ static void bot_cmd_work(struct work_struct *work) + + out: + transport_send_check_condition_and_sense(se_cmd, +- TCM_UNSUPPORTED_SCSI_OPCODE, 1); +- transport_generic_free_cmd(&cmd->se_cmd, 0); ++ TCM_UNSUPPORTED_SCSI_OPCODE, 0); + } + + static int bot_submit_command(struct f_uas *fu, +@@ -2018,43 +2000,39 @@ static int tcm_bind(struct usb_configuration *c, struct usb_function *f) + bot_intf_desc.bInterfaceNumber = iface; + uasp_intf_desc.bInterfaceNumber = iface; + fu->iface = iface; +- ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bi_desc, +- &uasp_bi_ep_comp_desc); ++ ep = usb_ep_autoconfig(gadget, &uasp_fs_bi_desc); + if (!ep) + goto ep_fail; + + fu->ep_in = ep; + +- ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc, +- &uasp_bo_ep_comp_desc); ++ ep = usb_ep_autoconfig(gadget, &uasp_fs_bo_desc); + if (!ep) + goto ep_fail; + fu->ep_out = ep; + +- ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc, +- &uasp_status_in_ep_comp_desc); ++ ep = usb_ep_autoconfig(gadget, &uasp_fs_status_desc); + if (!ep) + goto ep_fail; + fu->ep_status = ep; + +- ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc, +- &uasp_cmd_comp_desc); ++ ep = usb_ep_autoconfig(gadget, &uasp_fs_cmd_desc); + if (!ep) + goto ep_fail; + fu->ep_cmd = ep; + + /* Assume endpoint addresses are the same for both speeds */ +- uasp_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress; +- uasp_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress; ++ uasp_bi_desc.bEndpointAddress = uasp_fs_bi_desc.bEndpointAddress; ++ uasp_bo_desc.bEndpointAddress = uasp_fs_bo_desc.bEndpointAddress; + uasp_status_desc.bEndpointAddress = +- uasp_ss_status_desc.bEndpointAddress; +- uasp_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress; ++ uasp_fs_status_desc.bEndpointAddress; ++ uasp_cmd_desc.bEndpointAddress = uasp_fs_cmd_desc.bEndpointAddress; + +- uasp_fs_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress; +- uasp_fs_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress; +- uasp_fs_status_desc.bEndpointAddress = +- uasp_ss_status_desc.bEndpointAddress; +- uasp_fs_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress; ++ uasp_ss_bi_desc.bEndpointAddress = uasp_fs_bi_desc.bEndpointAddress; ++ uasp_ss_bo_desc.bEndpointAddress = uasp_fs_bo_desc.bEndpointAddress; ++ uasp_ss_status_desc.bEndpointAddress = ++ uasp_fs_status_desc.bEndpointAddress; ++ uasp_ss_cmd_desc.bEndpointAddress = uasp_fs_cmd_desc.bEndpointAddress; + + ret = usb_assign_descriptors(f, uasp_fs_function_desc, + uasp_hs_function_desc, uasp_ss_function_desc, +@@ -2098,9 +2076,14 @@ static void tcm_delayed_set_alt(struct work_struct *wq) + + static int tcm_get_alt(struct usb_function *f, unsigned intf) + { +- if (intf == bot_intf_desc.bInterfaceNumber) ++ struct f_uas *fu = to_f_uas(f); ++ ++ if (fu->iface != intf) ++ return -EOPNOTSUPP; ++ ++ if (fu->flags & USBG_IS_BOT) + return USB_G_ALT_INT_BBB; +- if (intf == uasp_intf_desc.bInterfaceNumber) ++ else if (fu->flags & USBG_IS_UAS) + return USB_G_ALT_INT_UAS; + + return -EOPNOTSUPP; +@@ -2110,6 +2093,9 @@ static int tcm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) + { + struct f_uas *fu = to_f_uas(f); + ++ if (fu->iface != intf) ++ return -EOPNOTSUPP; ++ + if ((alt == USB_G_ALT_INT_BBB) || (alt == USB_G_ALT_INT_UAS)) { + struct guas_setup_wq *work; + +diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c +index a10f41c4a3f2fd..d888741d3e2f97 100644 +--- a/drivers/usb/gadget/udc/renesas_usb3.c ++++ b/drivers/usb/gadget/udc/renesas_usb3.c +@@ -306,7 +306,7 @@ struct renesas_usb3_request { + struct list_head queue; + }; + +-#define USB3_EP_NAME_SIZE 8 ++#define USB3_EP_NAME_SIZE 16 + struct renesas_usb3_ep { + struct usb_ep ep; + struct renesas_usb3 *usb3; +diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c +index ef08d68b971492..04336c1d8dcb47 100644 +--- a/drivers/usb/host/pci-quirks.c ++++ b/drivers/usb/host/pci-quirks.c +@@ -948,6 +948,15 @@ static void quirk_usb_disable_ehci(struct pci_dev *pdev) + * booting from USB disk or using a usb keyboard + */ + hcc_params = readl(base + EHCI_HCC_PARAMS); ++ ++ /* LS7A EHCI controller doesn't have extended capabilities, the ++ * EECP (EHCI Extended Capabilities Pointer) field of HCCPARAMS ++ * register should be 0x0 but it reads as 0xa0. So clear it to ++ * avoid error messages on boot. ++ */ ++ if (pdev->vendor == PCI_VENDOR_ID_LOONGSON && pdev->device == 0x7a14) ++ hcc_params &= ~(0xffL << 8); ++ + offset = (hcc_params >> 8) & 0xff; + while (offset && --count) { + pci_read_config_dword(pdev, offset, &cap); +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index c44b66628a6dcf..db22ab0d88893a 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1761,6 +1761,8 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, + } + + command->status = 0; ++ /* set default timeout to 5000 ms */ ++ command->timeout_ms = XHCI_CMD_DEFAULT_TIMEOUT; + INIT_LIST_HEAD(&command->cmd_list); + return command; + } +@@ -2404,7 +2406,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) + * and our use of dma addresses in the trb_address_map radix tree needs + * TRB_SEGMENT_SIZE alignment, so we pick the greater alignment need. + */ +- if (xhci->quirks & XHCI_ZHAOXIN_TRB_FETCH) ++ if (xhci->quirks & XHCI_TRB_OVERFETCH) ++ /* Buggy HC prefetches beyond segment bounds - allocate dummy space at the end */ + xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, + TRB_SEGMENT_SIZE * 2, TRB_SEGMENT_SIZE * 2, xhci->page_size * 2); + else +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index 48a1cf5d9a1f61..18200d3662fe65 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -28,8 +28,8 @@ + #define SPARSE_CNTL_ENABLE 0xC12C + + /* Device for a quirk */ +-#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73 +-#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000 ++#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73 ++#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000 + #define PCI_DEVICE_ID_FRESCO_LOGIC_FL1009 0x1009 + #define PCI_DEVICE_ID_FRESCO_LOGIC_FL1100 0x1100 + #define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400 0x1400 +@@ -38,8 +38,10 @@ + #define PCI_DEVICE_ID_EJ168 0x7023 + #define PCI_DEVICE_ID_EJ188 0x7052 + +-#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31 +-#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 ++#define PCI_DEVICE_ID_VIA_VL805 0x3483 ++ ++#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31 ++#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 + #define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_XHCI 0x9cb1 + #define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5 + #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f +@@ -305,8 +307,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + pdev->device == 0x3432) + xhci->quirks |= XHCI_BROKEN_STREAMS; + +- if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) ++ if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == PCI_DEVICE_ID_VIA_VL805) { + xhci->quirks |= XHCI_LPM_SUPPORT; ++ xhci->quirks |= XHCI_TRB_OVERFETCH; ++ } + + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && + pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) { +@@ -354,11 +358,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + + if (pdev->device == 0x9202) { + xhci->quirks |= XHCI_RESET_ON_RESUME; +- xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH; ++ xhci->quirks |= XHCI_TRB_OVERFETCH; + } + + if (pdev->device == 0x9203) +- xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH; ++ xhci->quirks |= XHCI_TRB_OVERFETCH; + } + + if (pdev->vendor == PCI_DEVICE_ID_CADENCE && +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index f2b86872aa6bd6..64bf50ea62a49f 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -333,9 +333,10 @@ void xhci_ring_cmd_db(struct xhci_hcd *xhci) + readl(&xhci->dba->doorbell[0]); + } + +-static bool xhci_mod_cmd_timer(struct xhci_hcd *xhci, unsigned long delay) ++static bool xhci_mod_cmd_timer(struct xhci_hcd *xhci) + { +- return mod_delayed_work(system_wq, &xhci->cmd_timer, delay); ++ return mod_delayed_work(system_wq, &xhci->cmd_timer, ++ msecs_to_jiffies(xhci->current_cmd->timeout_ms)); + } + + static struct xhci_command *xhci_next_queued_cmd(struct xhci_hcd *xhci) +@@ -379,7 +380,8 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci, + if ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) && + !(xhci->xhc_state & XHCI_STATE_DYING)) { + xhci->current_cmd = cur_cmd; +- xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT); ++ if (cur_cmd) ++ xhci_mod_cmd_timer(xhci); + xhci_ring_cmd_db(xhci); + } + } +@@ -1922,7 +1924,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, + if (!list_is_singular(&xhci->cmd_list)) { + xhci->current_cmd = list_first_entry(&cmd->cmd_list, + struct xhci_command, cmd_list); +- xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT); ++ xhci_mod_cmd_timer(xhci); + } else if (xhci->current_cmd == cmd) { + xhci->current_cmd = NULL; + } +@@ -4503,7 +4505,7 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd, + /* if there are no other commands queued we start the timeout timer */ + if (list_empty(&xhci->cmd_list)) { + xhci->current_cmd = cmd; +- xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT); ++ xhci_mod_cmd_timer(xhci); + } + + list_add_tail(&cmd->cmd_list, &xhci->cmd_list); +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index c145a1ac1ababb..e9ebb6c7954fa6 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -4190,12 +4190,18 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) + return 0; + } + +-/* +- * Issue an Address Device command and optionally send a corresponding +- * SetAddress request to the device. ++/** ++ * xhci_setup_device - issues an Address Device command to assign a unique ++ * USB bus address. ++ * @hcd: USB host controller data structure. ++ * @udev: USB dev structure representing the connected device. ++ * @setup: Enum specifying setup mode: address only or with context. ++ * @timeout_ms: Max wait time (ms) for the command operation to complete. ++ * ++ * Return: 0 if successful; otherwise, negative error code. + */ + static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, +- enum xhci_setup_dev setup) ++ enum xhci_setup_dev setup, unsigned int timeout_ms) + { + const char *act = setup == SETUP_CONTEXT_ONLY ? "context" : "address"; + unsigned long flags; +@@ -4252,6 +4258,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, + } + + command->in_ctx = virt_dev->in_ctx; ++ command->timeout_ms = timeout_ms; + + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); + ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); +@@ -4380,14 +4387,16 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, + return ret; + } + +-static int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) ++static int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev, ++ unsigned int timeout_ms) + { +- return xhci_setup_device(hcd, udev, SETUP_CONTEXT_ADDRESS); ++ return xhci_setup_device(hcd, udev, SETUP_CONTEXT_ADDRESS, timeout_ms); + } + + static int xhci_enable_device(struct usb_hcd *hcd, struct usb_device *udev) + { +- return xhci_setup_device(hcd, udev, SETUP_CONTEXT_ONLY); ++ return xhci_setup_device(hcd, udev, SETUP_CONTEXT_ONLY, ++ XHCI_CMD_DEFAULT_TIMEOUT); + } + + /* +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index f76dae4ea429f5..b71e02ed9f0b32 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -563,6 +563,8 @@ struct xhci_command { + struct completion *completion; + union xhci_trb *command_trb; + struct list_head cmd_list; ++ /* xHCI command response timeout in milliseconds */ ++ unsigned int timeout_ms; + }; + + /* drop context bitmasks */ +@@ -1326,8 +1328,11 @@ struct xhci_td { + unsigned int num_trbs; + }; + +-/* xHCI command default timeout value */ +-#define XHCI_CMD_DEFAULT_TIMEOUT (5 * HZ) ++/* ++ * xHCI command default timeout value in milliseconds. ++ * USB 3.2 spec, section 9.2.6.1 ++ */ ++#define XHCI_CMD_DEFAULT_TIMEOUT 5000 + + /* command descriptor */ + struct xhci_cd { +@@ -1660,7 +1665,7 @@ struct xhci_hcd { + #define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(42) + #define XHCI_SUSPEND_RESUME_CLKS BIT_ULL(43) + #define XHCI_RESET_TO_DEFAULT BIT_ULL(44) +-#define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45) ++#define XHCI_TRB_OVERFETCH BIT_ULL(45) + #define XHCI_ZHAOXIN_HOST BIT_ULL(46) + #define XHCI_WRITE_64_HI_LO BIT_ULL(47) + #define XHCI_CDNS_SCTX_QUIRK BIT_ULL(48) +diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c +index 3af91b2b8f7690..df679908b8d210 100644 +--- a/drivers/usb/renesas_usbhs/common.c ++++ b/drivers/usb/renesas_usbhs/common.c +@@ -312,8 +312,10 @@ static int usbhsc_clk_get(struct device *dev, struct usbhs_priv *priv) + priv->clks[1] = of_clk_get(dev_of_node(dev), 1); + if (PTR_ERR(priv->clks[1]) == -ENOENT) + priv->clks[1] = NULL; +- else if (IS_ERR(priv->clks[1])) ++ else if (IS_ERR(priv->clks[1])) { ++ clk_put(priv->clks[0]); + return PTR_ERR(priv->clks[1]); ++ } + + return 0; + } +@@ -772,6 +774,8 @@ static int usbhs_remove(struct platform_device *pdev) + + dev_dbg(&pdev->dev, "usb remove\n"); + ++ flush_delayed_work(&priv->notify_hotplug_work); ++ + /* power off */ + if (!usbhs_get_dparam(priv, runtime_pwctrl)) + usbhsc_power_ctrl(priv, 0); +diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c +index 105132ae87acbc..e8e5723f541226 100644 +--- a/drivers/usb/renesas_usbhs/mod_gadget.c ++++ b/drivers/usb/renesas_usbhs/mod_gadget.c +@@ -1094,7 +1094,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) + goto usbhs_mod_gadget_probe_err_gpriv; + } + +- gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED); ++ gpriv->transceiver = devm_usb_get_phy(dev, USB_PHY_TYPE_UNDEFINED); + dev_info(dev, "%stransceiver found\n", + !IS_ERR(gpriv->transceiver) ? "" : "no "); + +diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c +index a327f8bc570439..917dffe9aee548 100644 +--- a/drivers/usb/roles/class.c ++++ b/drivers/usb/roles/class.c +@@ -354,14 +354,15 @@ usb_role_switch_register(struct device *parent, + dev_set_name(&sw->dev, "%s-role-switch", + desc->name ? desc->name : dev_name(parent)); + ++ sw->registered = true; ++ + ret = device_register(&sw->dev); + if (ret) { ++ sw->registered = false; + put_device(&sw->dev); + return ERR_PTR(ret); + } + +- sw->registered = true; +- + /* TODO: Symlinks for the host port and the device controller. */ + + return sw; +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 89e6a9afb80823..7ca07ba1a13999 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -619,15 +619,6 @@ static void option_instat_callback(struct urb *urb); + /* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */ + #define LUAT_PRODUCT_AIR720U 0x4e00 + +-/* MeiG Smart Technology products */ +-#define MEIGSMART_VENDOR_ID 0x2dee +-/* MeiG Smart SRM815/SRM825L based on Qualcomm 315 */ +-#define MEIGSMART_PRODUCT_SRM825L 0x4d22 +-/* MeiG Smart SLM320 based on UNISOC UIS8910 */ +-#define MEIGSMART_PRODUCT_SLM320 0x4d41 +-/* MeiG Smart SLM770A based on ASR1803 */ +-#define MEIGSMART_PRODUCT_SLM770A 0x4d57 +- + /* Device flags */ + + /* Highest interface number which can be used with NCTRL() and RSVD() */ +@@ -1367,15 +1358,15 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(2) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1063, 0xff), /* Telit LN920 (ECM) */ + .driver_info = NCTRL(0) | RSVD(1) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990 (rmnet) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990A (rmnet) */ + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990 (MBIM) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990A (MBIM) */ + .driver_info = NCTRL(0) | RSVD(1) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990 (RNDIS) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990A (RNDIS) */ + .driver_info = NCTRL(2) | RSVD(3) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990 (ECM) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990A (ECM) */ + .driver_info = NCTRL(0) | RSVD(1) }, +- { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990 (PCIe) */ ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990A (PCIe) */ + .driver_info = RSVD(0) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1080, 0xff), /* Telit FE990 (rmnet) */ + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, +@@ -1403,6 +1394,22 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(0) | NCTRL(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c8, 0xff), /* Telit FE910C04 (rmnet) */ + .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x60) }, /* Telit FN990B (rmnet) */ ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x40) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x30), ++ .driver_info = NCTRL(5) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x60) }, /* Telit FN990B (MBIM) */ ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x40) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x30), ++ .driver_info = NCTRL(6) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x60) }, /* Telit FN990B (RNDIS) */ ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x40) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x30), ++ .driver_info = NCTRL(6) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x60) }, /* Telit FN990B (ECM) */ ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x40) }, ++ { USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x30), ++ .driver_info = NCTRL(6) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), + .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), +@@ -2347,6 +2354,14 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a05, 0xff) }, /* Fibocom FM650-CN (NCM mode) */ + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff) }, /* Fibocom FM650-CN (RNDIS mode) */ + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a07, 0xff) }, /* Fibocom FM650-CN (MBIM mode) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d41, 0xff, 0, 0) }, /* MeiG Smart SLM320 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d57, 0xff, 0, 0) }, /* MeiG Smart SLM770A */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0, 0) }, /* MeiG Smart SRM815 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x02) }, /* MeiG Smart SLM828 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x03) }, /* MeiG Smart SLM828 */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM815 and SRM825L */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825L */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825L */ + { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ +@@ -2403,12 +2418,6 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0, 0) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) }, +- { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) }, + { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */ + .driver_info = NCTRL(1) }, + { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */ +diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c +index e047a15e67347b..ba899aa1ec941e 100644 +--- a/drivers/usb/typec/tcpm/tcpci.c ++++ b/drivers/usb/typec/tcpm/tcpci.c +@@ -26,6 +26,7 @@ + #define VPPS_NEW_MIN_PERCENT 95 + #define VPPS_VALID_MIN_MV 100 + #define VSINKDISCONNECT_PD_MIN_PERCENT 90 ++#define VPPS_SHUTDOWN_MIN_PERCENT 85 + + #define tcpc_presenting_rd(reg, cc) \ + (!(TCPC_ROLE_CTRL_DRP & (reg)) && \ +@@ -358,7 +359,8 @@ static int tcpci_enable_auto_vbus_discharge(struct tcpc_dev *dev, bool enable) + } + + static int tcpci_set_auto_vbus_discharge_threshold(struct tcpc_dev *dev, enum typec_pwr_opmode mode, +- bool pps_active, u32 requested_vbus_voltage_mv) ++ bool pps_active, u32 requested_vbus_voltage_mv, ++ u32 apdo_min_voltage_mv) + { + struct tcpci *tcpci = tcpc_to_tcpci(dev); + unsigned int pwr_ctrl, threshold = 0; +@@ -380,9 +382,12 @@ static int tcpci_set_auto_vbus_discharge_threshold(struct tcpc_dev *dev, enum ty + threshold = AUTO_DISCHARGE_DEFAULT_THRESHOLD_MV; + } else if (mode == TYPEC_PWR_MODE_PD) { + if (pps_active) +- threshold = ((VPPS_NEW_MIN_PERCENT * requested_vbus_voltage_mv / 100) - +- VSINKPD_MIN_IR_DROP_MV - VPPS_VALID_MIN_MV) * +- VSINKDISCONNECT_PD_MIN_PERCENT / 100; ++ /* ++ * To prevent disconnect when the source is in Current Limit Mode. ++ * Set the threshold to the lowest possible voltage vPpsShutdown (min) ++ */ ++ threshold = VPPS_SHUTDOWN_MIN_PERCENT * apdo_min_voltage_mv / 100 - ++ VSINKPD_MIN_IR_DROP_MV; + else + threshold = ((VSRC_NEW_MIN_PERCENT * requested_vbus_voltage_mv / 100) - + VSINKPD_MIN_IR_DROP_MV - VSRC_VALID_MIN_MV) * +diff --git a/drivers/usb/typec/tcpm/tcpci_rt1711h.c b/drivers/usb/typec/tcpm/tcpci_rt1711h.c +index 3291ca4948da78..9df13ce036c6d8 100644 +--- a/drivers/usb/typec/tcpm/tcpci_rt1711h.c ++++ b/drivers/usb/typec/tcpm/tcpci_rt1711h.c +@@ -217,6 +217,11 @@ static int rt1711h_probe(struct i2c_client *client, + { + int ret; + struct rt1711h_chip *chip; ++ const u16 alert_mask = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_DISCARDED | ++ TCPC_ALERT_TX_FAILED | TCPC_ALERT_RX_HARD_RST | ++ TCPC_ALERT_RX_STATUS | TCPC_ALERT_POWER_STATUS | ++ TCPC_ALERT_CC_STATUS | TCPC_ALERT_RX_BUF_OVF | ++ TCPC_ALERT_FAULT; + + ret = rt1711h_check_revision(client); + if (ret < 0) { +@@ -258,6 +263,12 @@ static int rt1711h_probe(struct i2c_client *client, + dev_name(chip->dev), chip); + if (ret < 0) + return ret; ++ ++ /* Enable alert interrupts */ ++ ret = rt1711h_write16(chip, TCPC_ALERT_MASK, alert_mask); ++ if (ret < 0) ++ return ret; ++ + enable_irq_wake(client->irq); + + return 0; +diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c +index 2104bb6e61f598..b645bbc0c57353 100644 +--- a/drivers/usb/typec/tcpm/tcpm.c ++++ b/drivers/usb/typec/tcpm/tcpm.c +@@ -2312,10 +2312,12 @@ static int tcpm_set_auto_vbus_discharge_threshold(struct tcpm_port *port, + return 0; + + ret = port->tcpc->set_auto_vbus_discharge_threshold(port->tcpc, mode, pps_active, +- requested_vbus_voltage); ++ requested_vbus_voltage, ++ port->pps_data.min_volt); + tcpm_log_force(port, +- "set_auto_vbus_discharge_threshold mode:%d pps_active:%c vbus:%u ret:%d", +- mode, pps_active ? 'y' : 'n', requested_vbus_voltage, ret); ++ "set_auto_vbus_discharge_threshold mode:%d pps_active:%c vbus:%u pps_apdo_min_volt:%u ret:%d", ++ mode, pps_active ? 'y' : 'n', requested_vbus_voltage, ++ port->pps_data.min_volt, ret); + + return ret; + } +@@ -4042,7 +4044,7 @@ static void run_state_machine(struct tcpm_port *port) + port->caps_count = 0; + port->pd_capable = true; + tcpm_set_state_cond(port, SRC_SEND_CAPABILITIES_TIMEOUT, +- PD_T_SEND_SOURCE_CAP); ++ PD_T_SENDER_RESPONSE); + } + break; + case SRC_SEND_CAPABILITIES_TIMEOUT: +diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c +index cb6458ec042cd5..979af06f22d837 100644 +--- a/drivers/usb/typec/ucsi/ucsi.c ++++ b/drivers/usb/typec/ucsi/ucsi.c +@@ -25,7 +25,7 @@ + * difficult to estimate the time it takes for the system to process the command + * before it is actually passed to the PPM. + */ +-#define UCSI_TIMEOUT_MS 5000 ++#define UCSI_TIMEOUT_MS 10000 + + /* + * UCSI_SWAP_TIMEOUT_MS - Timeout for role swap requests +diff --git a/drivers/vdpa/mlx5/core/resources.c b/drivers/vdpa/mlx5/core/resources.c +index 15e266d0e27a56..14d4314cdc295c 100644 +--- a/drivers/vdpa/mlx5/core/resources.c ++++ b/drivers/vdpa/mlx5/core/resources.c +@@ -215,7 +215,6 @@ int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, struct mlx5_core_mkey *mk + + mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); + mkey_index = MLX5_GET(create_mkey_out, lout, mkey_index); +- mkey->iova = MLX5_GET64(mkc, mkc, start_addr); + mkey->size = MLX5_GET64(mkc, mkc, len); + mkey->key |= mlx5_idx_to_mkey(mkey_index); + mkey->pd = MLX5_GET(mkc, mkc, pd); +diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c +index 82ac1569deb052..e45c15e210ffd8 100644 +--- a/drivers/vfio/pci/vfio_pci_rdwr.c ++++ b/drivers/vfio/pci/vfio_pci_rdwr.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + + #include + +diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c +index 5c5f944ca31e9d..2b268f4fc2f0a1 100644 +--- a/drivers/vfio/platform/vfio_platform_common.c ++++ b/drivers/vfio/platform/vfio_platform_common.c +@@ -393,6 +393,11 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region *reg, + + count = min_t(size_t, count, reg->size - off); + ++ if (off >= reg->size) ++ return -EINVAL; ++ ++ count = min_t(size_t, count, reg->size - off); ++ + if (!reg->ioaddr) { + reg->ioaddr = + ioremap(reg->addr, reg->size); +@@ -476,6 +481,11 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region *reg, + + count = min_t(size_t, count, reg->size - off); + ++ if (off >= reg->size) ++ return -EINVAL; ++ ++ count = min_t(size_t, count, reg->size - off); ++ + if (!reg->ioaddr) { + reg->ioaddr = + ioremap(reg->addr, reg->size); +diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c +index 0282d4eef139d4..3b16c3342cb77e 100644 +--- a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c ++++ b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c +@@ -102,6 +102,7 @@ struct device_node *dss_of_port_get_parent_device(struct device_node *port) + np = of_get_next_parent(np); + } + ++ of_node_put(np); + return NULL; + } + +diff --git a/drivers/virt/acrn/hsm.c b/drivers/virt/acrn/hsm.c +index af889cee66805d..26232dfbe78b5f 100644 +--- a/drivers/virt/acrn/hsm.c ++++ b/drivers/virt/acrn/hsm.c +@@ -49,7 +49,7 @@ static int pmcmd_ioctl(u64 cmd, void __user *uptr) + switch (cmd & PMCMD_TYPE_MASK) { + case ACRN_PMCMD_GET_PX_CNT: + case ACRN_PMCMD_GET_CX_CNT: +- pm_info = kmalloc(sizeof(u64), GFP_KERNEL); ++ pm_info = kzalloc(sizeof(u64), GFP_KERNEL); + if (!pm_info) + return -ENOMEM; + +@@ -64,7 +64,7 @@ static int pmcmd_ioctl(u64 cmd, void __user *uptr) + kfree(pm_info); + break; + case ACRN_PMCMD_GET_PX_DATA: +- px_data = kmalloc(sizeof(*px_data), GFP_KERNEL); ++ px_data = kzalloc(sizeof(*px_data), GFP_KERNEL); + if (!px_data) + return -ENOMEM; + +@@ -79,7 +79,7 @@ static int pmcmd_ioctl(u64 cmd, void __user *uptr) + kfree(px_data); + break; + case ACRN_PMCMD_GET_CX_DATA: +- cx_data = kmalloc(sizeof(*cx_data), GFP_KERNEL); ++ cx_data = kzalloc(sizeof(*cx_data), GFP_KERNEL); + if (!cx_data) + return -ENOMEM; + +diff --git a/fs/afs/cell.c b/fs/afs/cell.c +index 77571372888d9c..c04c7b5ec780d0 100644 +--- a/fs/afs/cell.c ++++ b/fs/afs/cell.c +@@ -161,6 +161,7 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net, + refcount_set(&cell->ref, 1); + atomic_set(&cell->active, 0); + INIT_WORK(&cell->manager, afs_manage_cell_work); ++ spin_lock_init(&cell->vs_lock); + cell->volumes = RB_ROOT; + INIT_HLIST_HEAD(&cell->proc_volumes); + seqlock_init(&cell->volume_lock); +diff --git a/fs/afs/dir.c b/fs/afs/dir.c +index cec18f9f8bd7ac..d4bd6efc8c447c 100644 +--- a/fs/afs/dir.c ++++ b/fs/afs/dir.c +@@ -1493,7 +1493,12 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry) + op->file[1].vnode = vnode; + } + +- return afs_do_sync_operation(op); ++ ret = afs_do_sync_operation(op); ++ ++ /* Not all systems that can host afs servers have ENOTEMPTY. */ ++ if (ret == -EEXIST) ++ ret = -ENOTEMPTY; ++ return ret; + + error: + return afs_put_operation(op); +diff --git a/fs/afs/internal.h b/fs/afs/internal.h +index 0c03877cdaf7e1..3918dfbd72a49b 100644 +--- a/fs/afs/internal.h ++++ b/fs/afs/internal.h +@@ -382,6 +382,7 @@ struct afs_cell { + unsigned int debug_id; + + /* The volumes belonging to this cell */ ++ spinlock_t vs_lock; /* Lock for server->volumes */ + struct rb_root volumes; /* Tree of volumes on this server */ + struct hlist_head proc_volumes; /* procfs volume list */ + seqlock_t volume_lock; /* For volumes */ +@@ -505,6 +506,7 @@ struct afs_server { + struct hlist_node addr4_link; /* Link in net->fs_addresses4 */ + struct hlist_node addr6_link; /* Link in net->fs_addresses6 */ + struct hlist_node proc_link; /* Link in net->fs_proc */ ++ struct list_head volumes; /* RCU list of afs_server_entry objects */ + struct work_struct initcb_work; /* Work for CB.InitCallBackState* */ + struct afs_server *gc_next; /* Next server in manager's list */ + time64_t unuse_time; /* Time at which last unused */ +@@ -553,12 +555,14 @@ struct afs_server { + */ + struct afs_server_entry { + struct afs_server *server; ++ struct afs_volume *volume; ++ struct list_head slink; /* Link in server->volumes */ + }; + + struct afs_server_list { + struct rcu_head rcu; +- afs_volid_t vids[AFS_MAXTYPES]; /* Volume IDs */ + refcount_t usage; ++ bool attached; /* T if attached to servers */ + unsigned char nr_servers; + unsigned char preferred; /* Preferred server */ + unsigned short vnovol_mask; /* Servers to be skipped due to VNOVOL */ +@@ -571,10 +575,9 @@ struct afs_server_list { + * Live AFS volume management. + */ + struct afs_volume { +- union { +- struct rcu_head rcu; +- afs_volid_t vid; /* volume ID */ +- }; ++ struct rcu_head rcu; ++ afs_volid_t vid; /* The volume ID of this volume */ ++ afs_volid_t vids[AFS_MAXTYPES]; /* All associated volume IDs */ + refcount_t ref; + time64_t update_at; /* Time at which to next update */ + struct afs_cell *cell; /* Cell to which belongs (pins ref) */ +@@ -1436,10 +1439,14 @@ static inline struct afs_server_list *afs_get_serverlist(struct afs_server_list + } + + extern void afs_put_serverlist(struct afs_net *, struct afs_server_list *); +-extern struct afs_server_list *afs_alloc_server_list(struct afs_cell *, struct key *, +- struct afs_vldb_entry *, +- u8); ++struct afs_server_list *afs_alloc_server_list(struct afs_volume *volume, ++ struct key *key, ++ struct afs_vldb_entry *vldb); + extern bool afs_annotate_server_list(struct afs_server_list *, struct afs_server_list *); ++void afs_attach_volume_to_servers(struct afs_volume *volume, struct afs_server_list *slist); ++void afs_reattach_volume_to_servers(struct afs_volume *volume, struct afs_server_list *slist, ++ struct afs_server_list *old); ++void afs_detach_volume_from_servers(struct afs_volume *volume, struct afs_server_list *slist); + + /* + * super.c +diff --git a/fs/afs/server.c b/fs/afs/server.c +index 34b47218129e90..5ee8a7518c5ecd 100644 +--- a/fs/afs/server.c ++++ b/fs/afs/server.c +@@ -236,6 +236,7 @@ static struct afs_server *afs_alloc_server(struct afs_cell *cell, + server->addr_version = alist->version; + server->uuid = *uuid; + rwlock_init(&server->fs_lock); ++ INIT_LIST_HEAD(&server->volumes); + INIT_WORK(&server->initcb_work, afs_server_init_callback_work); + init_waitqueue_head(&server->probe_wq); + INIT_LIST_HEAD(&server->probe_link); +diff --git a/fs/afs/server_list.c b/fs/afs/server_list.c +index b59896b1de0af2..89c75d934f79e1 100644 +--- a/fs/afs/server_list.c ++++ b/fs/afs/server_list.c +@@ -24,13 +24,13 @@ void afs_put_serverlist(struct afs_net *net, struct afs_server_list *slist) + /* + * Build a server list from a VLDB record. + */ +-struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, ++struct afs_server_list *afs_alloc_server_list(struct afs_volume *volume, + struct key *key, +- struct afs_vldb_entry *vldb, +- u8 type_mask) ++ struct afs_vldb_entry *vldb) + { + struct afs_server_list *slist; + struct afs_server *server; ++ unsigned int type_mask = 1 << volume->type; + int ret = -ENOMEM, nr_servers = 0, i, j; + + for (i = 0; i < vldb->nr_servers; i++) +@@ -44,15 +44,12 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, + refcount_set(&slist->usage, 1); + rwlock_init(&slist->lock); + +- for (i = 0; i < AFS_MAXTYPES; i++) +- slist->vids[i] = vldb->vid[i]; +- + /* Make sure a records exists for each server in the list. */ + for (i = 0; i < vldb->nr_servers; i++) { + if (!(vldb->fs_mask[i] & type_mask)) + continue; + +- server = afs_lookup_server(cell, key, &vldb->fs_server[i], ++ server = afs_lookup_server(volume->cell, key, &vldb->fs_server[i], + vldb->addr_version[i]); + if (IS_ERR(server)) { + ret = PTR_ERR(server); +@@ -70,8 +67,8 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, + break; + if (j < slist->nr_servers) { + if (slist->servers[j].server == server) { +- afs_put_server(cell->net, server, +- afs_server_trace_put_slist_isort); ++ afs_unuse_server(volume->cell->net, server, ++ afs_server_trace_put_slist_isort); + continue; + } + +@@ -81,6 +78,7 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, + } + + slist->servers[j].server = server; ++ slist->servers[j].volume = volume; + slist->nr_servers++; + } + +@@ -92,7 +90,7 @@ struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell, + return slist; + + error_2: +- afs_put_serverlist(cell->net, slist); ++ afs_put_serverlist(volume->cell->net, slist); + error: + return ERR_PTR(ret); + } +@@ -127,3 +125,99 @@ bool afs_annotate_server_list(struct afs_server_list *new, + + return true; + } ++ ++/* ++ * Attach a volume to the servers it is going to use. ++ */ ++void afs_attach_volume_to_servers(struct afs_volume *volume, struct afs_server_list *slist) ++{ ++ struct afs_server_entry *se, *pe; ++ struct afs_server *server; ++ struct list_head *p; ++ unsigned int i; ++ ++ spin_lock(&volume->cell->vs_lock); ++ ++ for (i = 0; i < slist->nr_servers; i++) { ++ se = &slist->servers[i]; ++ server = se->server; ++ ++ list_for_each(p, &server->volumes) { ++ pe = list_entry(p, struct afs_server_entry, slink); ++ if (volume->vid <= pe->volume->vid) ++ break; ++ } ++ list_add_tail_rcu(&se->slink, p); ++ } ++ ++ slist->attached = true; ++ spin_unlock(&volume->cell->vs_lock); ++} ++ ++/* ++ * Reattach a volume to the servers it is going to use when server list is ++ * replaced. We try to switch the attachment points to avoid rewalking the ++ * lists. ++ */ ++void afs_reattach_volume_to_servers(struct afs_volume *volume, struct afs_server_list *new, ++ struct afs_server_list *old) ++{ ++ unsigned int n = 0, o = 0; ++ ++ spin_lock(&volume->cell->vs_lock); ++ ++ while (n < new->nr_servers || o < old->nr_servers) { ++ struct afs_server_entry *pn = n < new->nr_servers ? &new->servers[n] : NULL; ++ struct afs_server_entry *po = o < old->nr_servers ? &old->servers[o] : NULL; ++ struct afs_server_entry *s; ++ struct list_head *p; ++ int diff; ++ ++ if (pn && po && pn->server == po->server) { ++ list_replace_rcu(&po->slink, &pn->slink); ++ n++; ++ o++; ++ continue; ++ } ++ ++ if (pn && po) ++ diff = memcmp(&pn->server->uuid, &po->server->uuid, ++ sizeof(pn->server->uuid)); ++ else ++ diff = pn ? -1 : 1; ++ ++ if (diff < 0) { ++ list_for_each(p, &pn->server->volumes) { ++ s = list_entry(p, struct afs_server_entry, slink); ++ if (volume->vid <= s->volume->vid) ++ break; ++ } ++ list_add_tail_rcu(&pn->slink, p); ++ n++; ++ } else { ++ list_del_rcu(&po->slink); ++ o++; ++ } ++ } ++ ++ spin_unlock(&volume->cell->vs_lock); ++} ++ ++/* ++ * Detach a volume from the servers it has been using. ++ */ ++void afs_detach_volume_from_servers(struct afs_volume *volume, struct afs_server_list *slist) ++{ ++ unsigned int i; ++ ++ if (!slist->attached) ++ return; ++ ++ spin_lock(&volume->cell->vs_lock); ++ ++ for (i = 0; i < slist->nr_servers; i++) ++ list_del_rcu(&slist->servers[i].slink); ++ ++ slist->attached = false; ++ spin_unlock(&volume->cell->vs_lock); ++} +diff --git a/fs/afs/vl_alias.c b/fs/afs/vl_alias.c +index 83cf1bfbe343ae..b2cc10df95308c 100644 +--- a/fs/afs/vl_alias.c ++++ b/fs/afs/vl_alias.c +@@ -126,7 +126,7 @@ static int afs_compare_volume_slists(const struct afs_volume *vol_a, + lb = rcu_dereference(vol_b->servers); + + for (i = 0; i < AFS_MAXTYPES; i++) +- if (la->vids[i] != lb->vids[i]) ++ if (vol_a->vids[i] != vol_b->vids[i]) + return 0; + + while (a < la->nr_servers && b < lb->nr_servers) { +diff --git a/fs/afs/volume.c b/fs/afs/volume.c +index 3d39ce5a23f228..a0c440324babac 100644 +--- a/fs/afs/volume.c ++++ b/fs/afs/volume.c +@@ -73,15 +73,11 @@ static void afs_remove_volume_from_cell(struct afs_volume *volume) + */ + static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, + struct afs_vldb_entry *vldb, +- unsigned long type_mask) ++ struct afs_server_list **_slist) + { + struct afs_server_list *slist; + struct afs_volume *volume; +- int ret = -ENOMEM, nr_servers = 0, i; +- +- for (i = 0; i < vldb->nr_servers; i++) +- if (vldb->fs_mask[i] & type_mask) +- nr_servers++; ++ int ret = -ENOMEM, i; + + volume = kzalloc(sizeof(struct afs_volume), GFP_KERNEL); + if (!volume) +@@ -100,13 +96,16 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, + rwlock_init(&volume->cb_v_break_lock); + memcpy(volume->name, vldb->name, vldb->name_len + 1); + +- slist = afs_alloc_server_list(params->cell, params->key, vldb, type_mask); ++ for (i = 0; i < AFS_MAXTYPES; i++) ++ volume->vids[i] = vldb->vid[i]; ++ ++ slist = afs_alloc_server_list(volume, params->key, vldb); + if (IS_ERR(slist)) { + ret = PTR_ERR(slist); + goto error_1; + } + +- refcount_set(&slist->usage, 1); ++ *_slist = slist; + rcu_assign_pointer(volume->servers, slist); + trace_afs_volume(volume->vid, 1, afs_volume_trace_alloc); + return volume; +@@ -122,17 +121,19 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, + * Look up or allocate a volume record. + */ + static struct afs_volume *afs_lookup_volume(struct afs_fs_context *params, +- struct afs_vldb_entry *vldb, +- unsigned long type_mask) ++ struct afs_vldb_entry *vldb) + { ++ struct afs_server_list *slist; + struct afs_volume *candidate, *volume; + +- candidate = afs_alloc_volume(params, vldb, type_mask); ++ candidate = afs_alloc_volume(params, vldb, &slist); + if (IS_ERR(candidate)) + return candidate; + + volume = afs_insert_volume_into_cell(params->cell, candidate); +- if (volume != candidate) ++ if (volume == candidate) ++ afs_attach_volume_to_servers(volume, slist); ++ else + afs_put_volume(params->net, candidate, afs_volume_trace_put_cell_dup); + return volume; + } +@@ -213,8 +214,7 @@ struct afs_volume *afs_create_volume(struct afs_fs_context *params) + goto error; + } + +- type_mask = 1UL << params->type; +- volume = afs_lookup_volume(params, vldb, type_mask); ++ volume = afs_lookup_volume(params, vldb); + + error: + kfree(vldb); +@@ -226,14 +226,17 @@ struct afs_volume *afs_create_volume(struct afs_fs_context *params) + */ + static void afs_destroy_volume(struct afs_net *net, struct afs_volume *volume) + { ++ struct afs_server_list *slist = rcu_access_pointer(volume->servers); ++ + _enter("%p", volume); + + #ifdef CONFIG_AFS_FSCACHE + ASSERTCMP(volume->cache, ==, NULL); + #endif + ++ afs_detach_volume_from_servers(volume, slist); + afs_remove_volume_from_cell(volume); +- afs_put_serverlist(net, rcu_access_pointer(volume->servers)); ++ afs_put_serverlist(net, slist); + afs_put_cell(volume->cell, afs_cell_trace_put_vol); + trace_afs_volume(volume->vid, refcount_read(&volume->ref), + afs_volume_trace_free); +@@ -352,8 +355,7 @@ static int afs_update_volume_status(struct afs_volume *volume, struct key *key) + } + + /* See if the volume's server list got updated. */ +- new = afs_alloc_server_list(volume->cell, key, +- vldb, (1 << volume->type)); ++ new = afs_alloc_server_list(volume, key, vldb); + if (IS_ERR(new)) { + ret = PTR_ERR(new); + goto error_vldb; +@@ -374,9 +376,11 @@ static int afs_update_volume_status(struct afs_volume *volume, struct key *key) + + volume->update_at = ktime_get_real_seconds() + afs_volume_record_life; + write_unlock(&volume->servers_lock); +- ret = 0; + ++ if (discard == old) ++ afs_reattach_volume_to_servers(volume, new, old); + afs_put_serverlist(volume->cell->net, discard); ++ ret = 0; + error_vldb: + kfree(vldb); + error: +diff --git a/fs/afs/xdr_fs.h b/fs/afs/xdr_fs.h +index 8ca8681645077d..cc5f143d21a347 100644 +--- a/fs/afs/xdr_fs.h ++++ b/fs/afs/xdr_fs.h +@@ -88,7 +88,7 @@ union afs_xdr_dir_block { + + struct { + struct afs_xdr_dir_hdr hdr; +- u8 alloc_ctrs[AFS_DIR_MAX_BLOCKS]; ++ u8 alloc_ctrs[AFS_DIR_BLOCKS_WITH_CTR]; + __be16 hashtable[AFS_DIR_HASHTBL_SIZE]; + } meta; + +diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c +index 88ea20e79ae270..b3bc46a112242a 100644 +--- a/fs/afs/yfsclient.c ++++ b/fs/afs/yfsclient.c +@@ -662,8 +662,9 @@ static int yfs_deliver_fs_remove_file2(struct afs_call *call) + static void yfs_done_fs_remove_file2(struct afs_call *call) + { + if (call->error == -ECONNABORTED && +- call->abort_code == RX_INVALID_OPERATION) { +- set_bit(AFS_SERVER_FL_NO_RM2, &call->server->flags); ++ (call->abort_code == RX_INVALID_OPERATION || ++ call->abort_code == RXGEN_OPCODE)) { ++ set_bit(AFS_SERVER_FL_NO_RM2, &call->op->server->flags); + call->op->flags |= AFS_OPERATION_DOWNGRADE; + } + } +diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c +index 250651cdce0a61..97097c34504448 100644 +--- a/fs/binfmt_flat.c ++++ b/fs/binfmt_flat.c +@@ -542,7 +542,7 @@ static int load_flat_file(struct linux_binprm *bprm, + * 28 bits (256 MB) is way more than reasonable in this case. + * If some top bits are set we have probable binary corruption. + */ +- if ((text_len | data_len | bss_len | stack_len | full_data) >> 28) { ++ if ((text_len | data_len | bss_len | stack_len | relocs | full_data) >> 28) { + pr_err("bad header\n"); + ret = -ENOEXEC; + goto err; +diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c +index 44160d4ad53e0d..0dd5a90feca34b 100644 +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -731,7 +731,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, + if (args->drop_cache) + btrfs_drop_extent_cache(inode, args->start, args->end - 1, 0); + +- if (args->start >= inode->disk_i_size && !args->replace_extent) ++ if (data_race(args->start >= inode->disk_i_size) && !args->replace_extent) + modify_tree = 0; + + update_refs = (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID); +@@ -1607,7 +1607,6 @@ static int btrfs_write_check(struct kiocb *iocb, struct iov_iter *from, + loff_t pos = iocb->ki_pos; + int ret; + loff_t oldsize; +- loff_t start_pos; + + if (iocb->ki_flags & IOCB_NOWAIT) { + size_t nocow_bytes = count; +@@ -1637,9 +1636,8 @@ static int btrfs_write_check(struct kiocb *iocb, struct iov_iter *from, + */ + update_time_for_write(inode); + +- start_pos = round_down(pos, fs_info->sectorsize); + oldsize = i_size_read(inode); +- if (start_pos > oldsize) { ++ if (pos > oldsize) { + /* Expand hole size to cover write data, preventing empty gap */ + loff_t end_pos = round_up(pos + count, fs_info->sectorsize); + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index a6b1dd83406007..d6e43c94436d4a 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -7698,8 +7698,6 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, + ret = -EAGAIN; + goto out; + } +- +- cond_resched(); + } + + btrfs_release_path(path); +@@ -11033,6 +11031,8 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file, + } + + start += len; ++ ++ cond_resched(); + } + + if (bsi.block_len) +diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c +index 87f302a413f9a9..887ae4a9c50c37 100644 +--- a/fs/btrfs/relocation.c ++++ b/fs/btrfs/relocation.c +@@ -4414,8 +4414,18 @@ int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans, + WARN_ON(!first_cow && level == 0); + + node = rc->backref_cache.path[level]; +- BUG_ON(node->bytenr != buf->start && +- node->new_bytenr != buf->start); ++ ++ /* ++ * If node->bytenr != buf->start and node->new_bytenr != ++ * buf->start then we've got the wrong backref node for what we ++ * expected to see here and the cache is incorrect. ++ */ ++ if (unlikely(node->bytenr != buf->start && node->new_bytenr != buf->start)) { ++ btrfs_err(fs_info, ++"bytenr %llu was found but our backref cache was expecting %llu or %llu", ++ buf->start, node->bytenr, node->new_bytenr); ++ return -EUCLEAN; ++ } + + btrfs_backref_drop_node_buffer(node); + atomic_inc(&cow->refs); +diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c +index 2fd0ee0e6e9310..5d8cf38cb9b9e9 100644 +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -1386,7 +1386,7 @@ static int btrfs_fill_super(struct super_block *sb, + + err = open_ctree(sb, fs_devices, (char *)data); + if (err) { +- btrfs_err(fs_info, "open_ctree failed"); ++ btrfs_err(fs_info, "open_ctree failed: %d", err); + return err; + } + +diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c +index a9b794c47159f8..4fb5e12c87d1bf 100644 +--- a/fs/btrfs/transaction.c ++++ b/fs/btrfs/transaction.c +@@ -295,8 +295,10 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info, + cur_trans = fs_info->running_transaction; + if (cur_trans) { + if (TRANS_ABORTED(cur_trans)) { ++ const int abort_error = cur_trans->aborted; ++ + spin_unlock(&fs_info->trans_lock); +- return cur_trans->aborted; ++ return abort_error; + } + if (btrfs_blocked_trans_types[cur_trans->state] & type) { + spin_unlock(&fs_info->trans_lock); +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index ee9a1e6550e3c5..7bce1ab86c4da3 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -5198,6 +5198,10 @@ receive_encrypted_standard(struct TCP_Server_Info *server, + next_buffer = (char *)cifs_buf_get(); + else + next_buffer = (char *)cifs_small_buf_get(); ++ if (!next_buffer) { ++ cifs_server_dbg(VFS, "No memory for (large) SMB response\n"); ++ return -1; ++ } + memcpy(next_buffer, buf + next_cmd, pdu_length - next_cmd); + } + +diff --git a/fs/exfat/balloc.c b/fs/exfat/balloc.c +index 144617066a2bfa..26808f0d3e9fff 100644 +--- a/fs/exfat/balloc.c ++++ b/fs/exfat/balloc.c +@@ -160,7 +160,7 @@ int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync) + return 0; + } + +-void exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync) ++int exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync) + { + int i, b; + unsigned int ent_idx; +@@ -169,13 +169,17 @@ void exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync) + struct exfat_mount_options *opts = &sbi->options; + + if (!is_valid_cluster(sbi, clu)) +- return; ++ return -EIO; + + ent_idx = CLUSTER_TO_BITMAP_ENT(clu); + i = BITMAP_OFFSET_SECTOR_INDEX(sb, ent_idx); + b = BITMAP_OFFSET_BIT_IN_SECTOR(sb, ent_idx); + ++ if (!test_bit_le(b, sbi->vol_amap[i]->b_data)) ++ return -EIO; ++ + clear_bit_le(b, sbi->vol_amap[i]->b_data); ++ + exfat_update_bh(sbi->vol_amap[i], sync); + + if (opts->discard) { +@@ -190,6 +194,8 @@ void exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync) + opts->discard = 0; + } + } ++ ++ return 0; + } + + /* +diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h +index 58816ee3162c47..e242d7758f7820 100644 +--- a/fs/exfat/exfat_fs.h ++++ b/fs/exfat/exfat_fs.h +@@ -420,7 +420,7 @@ int exfat_count_num_clusters(struct super_block *sb, + int exfat_load_bitmap(struct super_block *sb); + void exfat_free_bitmap(struct exfat_sb_info *sbi); + int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync); +-void exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync); ++int exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync); + unsigned int exfat_find_free_bitmap(struct super_block *sb, unsigned int clu); + int exfat_count_used_clusters(struct super_block *sb, unsigned int *ret_count); + int exfat_trim_fs(struct inode *inode, struct fstrim_range *range); +diff --git a/fs/exfat/fatent.c b/fs/exfat/fatent.c +index 8f07504e53458b..9c116a58544dab 100644 +--- a/fs/exfat/fatent.c ++++ b/fs/exfat/fatent.c +@@ -174,6 +174,7 @@ static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain + BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(clu)); + + if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { ++ int err; + unsigned int last_cluster = p_chain->dir + p_chain->size - 1; + do { + bool sync = false; +@@ -188,7 +189,9 @@ static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain + cur_cmap_i = next_cmap_i; + } + +- exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode))); ++ err = exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode))); ++ if (err) ++ break; + clu++; + num_clusters++; + } while (num_clusters < p_chain->size); +@@ -209,12 +212,13 @@ static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain + cur_cmap_i = next_cmap_i; + } + +- exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode))); ++ if (exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode)))) ++ break; + clu = n_clu; + num_clusters++; + + if (err) +- goto dec_used_clus; ++ break; + + if (num_clusters >= sbi->num_clusters - EXFAT_FIRST_CLUSTER) { + /* +@@ -228,7 +232,6 @@ static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain + } while (clu != EXFAT_EOF_CLUSTER); + } + +-dec_used_clus: + sbi->used_clusters -= num_clusters; + return 0; + } +diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c +index 2eecd8c737d0bf..da717e4d6aee7c 100644 +--- a/fs/f2fs/dir.c ++++ b/fs/f2fs/dir.c +@@ -199,7 +199,8 @@ static unsigned long dir_block_index(unsigned int level, + static struct f2fs_dir_entry *find_in_block(struct inode *dir, + struct page *dentry_page, + const struct f2fs_filename *fname, +- int *max_slots) ++ int *max_slots, ++ bool use_hash) + { + struct f2fs_dentry_block *dentry_blk; + struct f2fs_dentry_ptr d; +@@ -207,7 +208,7 @@ static struct f2fs_dir_entry *find_in_block(struct inode *dir, + dentry_blk = (struct f2fs_dentry_block *)page_address(dentry_page); + + make_dentry_ptr_block(dir, &d, dentry_blk); +- return f2fs_find_target_dentry(&d, fname, max_slots); ++ return f2fs_find_target_dentry(&d, fname, max_slots, use_hash); + } + + #ifdef CONFIG_UNICODE +@@ -284,7 +285,8 @@ static inline int f2fs_match_name(const struct inode *dir, + } + + struct f2fs_dir_entry *f2fs_find_target_dentry(const struct f2fs_dentry_ptr *d, +- const struct f2fs_filename *fname, int *max_slots) ++ const struct f2fs_filename *fname, int *max_slots, ++ bool use_hash) + { + struct f2fs_dir_entry *de; + unsigned long bit_pos = 0; +@@ -307,7 +309,7 @@ struct f2fs_dir_entry *f2fs_find_target_dentry(const struct f2fs_dentry_ptr *d, + continue; + } + +- if (de->hash_code == fname->hash) { ++ if (!use_hash || de->hash_code == fname->hash) { + res = f2fs_match_name(d->inode, fname, + d->filename[bit_pos], + le16_to_cpu(de->name_len)); +@@ -334,11 +336,12 @@ struct f2fs_dir_entry *f2fs_find_target_dentry(const struct f2fs_dentry_ptr *d, + static struct f2fs_dir_entry *find_in_level(struct inode *dir, + unsigned int level, + const struct f2fs_filename *fname, +- struct page **res_page) ++ struct page **res_page, ++ bool use_hash) + { + int s = GET_DENTRY_SLOTS(fname->disk_name.len); + unsigned int nbucket, nblock; +- unsigned int bidx, end_block; ++ unsigned int bidx, end_block, bucket_no; + struct page *dentry_page; + struct f2fs_dir_entry *de = NULL; + bool room = false; +@@ -347,8 +350,11 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, + nbucket = dir_buckets(level, F2FS_I(dir)->i_dir_level); + nblock = bucket_blocks(level); + ++ bucket_no = use_hash ? le32_to_cpu(fname->hash) % nbucket : 0; ++ ++start_find_bucket: + bidx = dir_block_index(level, F2FS_I(dir)->i_dir_level, +- le32_to_cpu(fname->hash) % nbucket); ++ bucket_no); + end_block = bidx + nblock; + + for (; bidx < end_block; bidx++) { +@@ -364,7 +370,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, + } + } + +- de = find_in_block(dir, dentry_page, fname, &max_slots); ++ de = find_in_block(dir, dentry_page, fname, &max_slots, use_hash); + if (IS_ERR(de)) { + *res_page = ERR_CAST(de); + de = NULL; +@@ -379,12 +385,18 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir, + f2fs_put_page(dentry_page, 0); + } + +- if (!de && room && F2FS_I(dir)->chash != fname->hash) { +- F2FS_I(dir)->chash = fname->hash; +- F2FS_I(dir)->clevel = level; +- } ++ if (de) ++ return de; + +- return de; ++ if (likely(use_hash)) { ++ if (room && F2FS_I(dir)->chash != fname->hash) { ++ F2FS_I(dir)->chash = fname->hash; ++ F2FS_I(dir)->clevel = level; ++ } ++ } else if (++bucket_no < nbucket) { ++ goto start_find_bucket; ++ } ++ return NULL; + } + + struct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir, +@@ -395,11 +407,15 @@ struct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir, + struct f2fs_dir_entry *de = NULL; + unsigned int max_depth; + unsigned int level; ++ bool use_hash = true; + + *res_page = NULL; + ++#if IS_ENABLED(CONFIG_UNICODE) ++start_find_entry: ++#endif + if (f2fs_has_inline_dentry(dir)) { +- de = f2fs_find_in_inline_dir(dir, fname, res_page); ++ de = f2fs_find_in_inline_dir(dir, fname, res_page, use_hash); + goto out; + } + +@@ -415,11 +431,18 @@ struct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir, + } + + for (level = 0; level < max_depth; level++) { +- de = find_in_level(dir, level, fname, res_page); ++ de = find_in_level(dir, level, fname, res_page, use_hash); + if (de || IS_ERR(*res_page)) + break; + } ++ + out: ++#if IS_ENABLED(CONFIG_UNICODE) ++ if (IS_CASEFOLDED(dir) && !de && use_hash) { ++ use_hash = false; ++ goto start_find_entry; ++ } ++#endif + /* This is to increase the speed of f2fs_create */ + if (!de) + F2FS_I(dir)->task = current; +diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h +index 856a44da7977c1..135927974e28c1 100644 +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -3325,7 +3325,8 @@ int f2fs_prepare_lookup(struct inode *dir, struct dentry *dentry, + struct f2fs_filename *fname); + void f2fs_free_filename(struct f2fs_filename *fname); + struct f2fs_dir_entry *f2fs_find_target_dentry(const struct f2fs_dentry_ptr *d, +- const struct f2fs_filename *fname, int *max_slots); ++ const struct f2fs_filename *fname, int *max_slots, ++ bool use_hash); + int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, + unsigned int start_pos, struct fscrypt_str *fstr); + void f2fs_do_make_empty_dir(struct inode *inode, struct inode *parent, +@@ -3926,7 +3927,8 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page); + int f2fs_recover_inline_data(struct inode *inode, struct page *npage); + struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir, + const struct f2fs_filename *fname, +- struct page **res_page); ++ struct page **res_page, ++ bool use_hash); + int f2fs_make_empty_inline_dir(struct inode *inode, struct inode *parent, + struct page *ipage); + int f2fs_add_inline_entry(struct inode *dir, const struct f2fs_filename *fname, +diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c +index b38ce5a7a2ef29..685a14309406d8 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -965,6 +965,13 @@ int f2fs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, + return err; + } + ++ /* ++ * wait for inflight dio, blocks should be removed after ++ * IO completion. ++ */ ++ if (attr->ia_size < old_size) ++ inode_dio_wait(inode); ++ + down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + filemap_invalidate_lock(inode->i_mapping); + +@@ -1790,6 +1797,12 @@ static long f2fs_fallocate(struct file *file, int mode, + if (ret) + goto out; + ++ /* ++ * wait for inflight dio, blocks should be removed after IO ++ * completion. ++ */ ++ inode_dio_wait(inode); ++ + if (mode & FALLOC_FL_PUNCH_HOLE) { + if (offset >= inode->i_size) + goto out; +diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c +index 6246ea2e1c6214..03d31ee7eb61a8 100644 +--- a/fs/f2fs/inline.c ++++ b/fs/f2fs/inline.c +@@ -335,7 +335,8 @@ int f2fs_recover_inline_data(struct inode *inode, struct page *npage) + + struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir, + const struct f2fs_filename *fname, +- struct page **res_page) ++ struct page **res_page, ++ bool use_hash) + { + struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); + struct f2fs_dir_entry *de; +@@ -352,7 +353,7 @@ struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir, + inline_dentry = inline_data_addr(dir, ipage); + + make_dentry_ptr_inline(dir, &d, inline_dentry); +- de = f2fs_find_target_dentry(&d, fname, NULL); ++ de = f2fs_find_target_dentry(&d, fname, NULL, use_hash); + unlock_page(ipage); + if (IS_ERR(de)) { + *res_page = ERR_CAST(de); +diff --git a/fs/file_table.c b/fs/file_table.c +index 6f297f9782fc50..e03ff9a2c2b1f3 100644 +--- a/fs/file_table.c ++++ b/fs/file_table.c +@@ -33,7 +33,7 @@ + #include "internal.h" + + /* sysctl tunables... */ +-struct files_stat_struct files_stat = { ++static struct files_stat_struct files_stat = { + .max_files = NR_FILE + }; + +@@ -75,22 +75,53 @@ unsigned long get_max_files(void) + } + EXPORT_SYMBOL_GPL(get_max_files); + ++#if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) ++ + /* + * Handle nr_files sysctl + */ +-#if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) +-int proc_nr_files(struct ctl_table *table, int write, +- void *buffer, size_t *lenp, loff_t *ppos) ++static int proc_nr_files(struct ctl_table *table, int write, void *buffer, ++ size_t *lenp, loff_t *ppos) + { + files_stat.nr_files = get_nr_files(); + return proc_doulongvec_minmax(table, write, buffer, lenp, ppos); + } +-#else +-int proc_nr_files(struct ctl_table *table, int write, +- void *buffer, size_t *lenp, loff_t *ppos) ++ ++static struct ctl_table fs_stat_sysctls[] = { ++ { ++ .procname = "file-nr", ++ .data = &files_stat, ++ .maxlen = sizeof(files_stat), ++ .mode = 0444, ++ .proc_handler = proc_nr_files, ++ }, ++ { ++ .procname = "file-max", ++ .data = &files_stat.max_files, ++ .maxlen = sizeof(files_stat.max_files), ++ .mode = 0644, ++ .proc_handler = proc_doulongvec_minmax, ++ .extra1 = SYSCTL_LONG_ZERO, ++ .extra2 = SYSCTL_LONG_MAX, ++ }, ++ { ++ .procname = "nr_open", ++ .data = &sysctl_nr_open, ++ .maxlen = sizeof(unsigned int), ++ .mode = 0644, ++ .proc_handler = proc_douintvec_minmax, ++ .extra1 = &sysctl_nr_open_min, ++ .extra2 = &sysctl_nr_open_max, ++ }, ++ { } ++}; ++ ++static int __init init_fs_stat_sysctls(void) + { +- return -ENOSYS; ++ register_sysctl_init("fs", fs_stat_sysctls); ++ return 0; + } ++fs_initcall(init_fs_stat_sysctls); + #endif + + static struct file *__alloc_file(int flags, const struct cred *cred) +diff --git a/fs/inode.c b/fs/inode.c +index c7ef50d0fe38bd..0a3a14b9ee46fa 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -67,11 +67,6 @@ const struct address_space_operations empty_aops = { + }; + EXPORT_SYMBOL(empty_aops); + +-/* +- * Statistics gathering.. +- */ +-struct inodes_stat_t inodes_stat; +- + static DEFINE_PER_CPU(unsigned long, nr_inodes); + static DEFINE_PER_CPU(unsigned long, nr_unused); + +@@ -106,13 +101,43 @@ long get_nr_dirty_inodes(void) + * Handle nr_inode sysctl + */ + #ifdef CONFIG_SYSCTL +-int proc_nr_inodes(struct ctl_table *table, int write, +- void *buffer, size_t *lenp, loff_t *ppos) ++/* ++ * Statistics gathering.. ++ */ ++static struct inodes_stat_t inodes_stat; ++ ++static int proc_nr_inodes(struct ctl_table *table, int write, void *buffer, ++ size_t *lenp, loff_t *ppos) + { + inodes_stat.nr_inodes = get_nr_inodes(); + inodes_stat.nr_unused = get_nr_inodes_unused(); + return proc_doulongvec_minmax(table, write, buffer, lenp, ppos); + } ++ ++static struct ctl_table inodes_sysctls[] = { ++ { ++ .procname = "inode-nr", ++ .data = &inodes_stat, ++ .maxlen = 2*sizeof(long), ++ .mode = 0444, ++ .proc_handler = proc_nr_inodes, ++ }, ++ { ++ .procname = "inode-state", ++ .data = &inodes_stat, ++ .maxlen = 7*sizeof(long), ++ .mode = 0444, ++ .proc_handler = proc_nr_inodes, ++ }, ++ { } ++}; ++ ++static int __init init_fs_inode_sysctls(void) ++{ ++ register_sysctl_init("fs", inodes_sysctls); ++ return 0; ++} ++early_initcall(init_fs_inode_sysctls); + #endif + + static int no_open(struct inode *inode, struct file *file) +diff --git a/fs/ksmbd/transport_ipc.c b/fs/ksmbd/transport_ipc.c +index d62ebbff1e0f4b..0d096a11ba30e0 100644 +--- a/fs/ksmbd/transport_ipc.c ++++ b/fs/ksmbd/transport_ipc.c +@@ -566,6 +566,9 @@ ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len) + struct ksmbd_spnego_authen_request *req; + struct ksmbd_spnego_authen_response *resp; + ++ if (blob_len > KSMBD_IPC_MAX_PAYLOAD) ++ return NULL; ++ + msg = ipc_msg_alloc(sizeof(struct ksmbd_spnego_authen_request) + + blob_len + 1); + if (!msg) +@@ -745,6 +748,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle + struct ksmbd_rpc_command *req; + struct ksmbd_rpc_command *resp; + ++ if (payload_sz > KSMBD_IPC_MAX_PAYLOAD) ++ return NULL; ++ + msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1); + if (!msg) + return NULL; +@@ -793,6 +799,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle + struct ksmbd_rpc_command *req; + struct ksmbd_rpc_command *resp; + ++ if (payload_sz > KSMBD_IPC_MAX_PAYLOAD) ++ return NULL; ++ + msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1); + if (!msg) + return NULL; +diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c +index 4269df0f0ffa56..4fed292de029fc 100644 +--- a/fs/nfs/flexfilelayout/flexfilelayout.c ++++ b/fs/nfs/flexfilelayout/flexfilelayout.c +@@ -836,6 +836,9 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, + struct nfs4_pnfs_ds *ds; + u32 ds_idx; + ++ if (NFS_SERVER(pgio->pg_inode)->flags & ++ (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR)) ++ pgio->pg_maxretrans = io_maxretrans; + retry: + ff_layout_pg_check_layout(pgio, req); + /* Use full layout for now */ +@@ -849,6 +852,8 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, + if (!pgio->pg_lseg) + goto out_nolseg; + } ++ /* Reset wb_nio, since getting layout segment was successful */ ++ req->wb_nio = 0; + + ds = ff_layout_get_ds_for_read(pgio, &ds_idx); + if (!ds) { +@@ -865,14 +870,24 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, + pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].rsize; + + pgio->pg_mirror_idx = ds_idx; +- +- if (NFS_SERVER(pgio->pg_inode)->flags & +- (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR)) +- pgio->pg_maxretrans = io_maxretrans; + return; + out_nolseg: +- if (pgio->pg_error < 0) +- return; ++ if (pgio->pg_error < 0) { ++ if (pgio->pg_error != -EAGAIN) ++ return; ++ /* Retry getting layout segment if lower layer returned -EAGAIN */ ++ if (pgio->pg_maxretrans && req->wb_nio++ > pgio->pg_maxretrans) { ++ if (NFS_SERVER(pgio->pg_inode)->flags & NFS_MOUNT_SOFTERR) ++ pgio->pg_error = -ETIMEDOUT; ++ else ++ pgio->pg_error = -EIO; ++ return; ++ } ++ pgio->pg_error = 0; ++ /* Sleep for 1 second before retrying */ ++ ssleep(1); ++ goto retry; ++ } + out_mds: + trace_pnfs_mds_fallback_pg_init_read(pgio->pg_inode, + 0, NFS4_MAX_UINT64, IOMODE_READ, +diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c +index eb347742e611bf..b57e3a631b975f 100644 +--- a/fs/nfs/nfs42proc.c ++++ b/fs/nfs/nfs42proc.c +@@ -541,7 +541,7 @@ static int nfs42_do_offload_cancel_async(struct file *dst, + .rpc_message = &msg, + .callback_ops = &nfs42_offload_cancel_ops, + .workqueue = nfsiod_workqueue, +- .flags = RPC_TASK_ASYNC, ++ .flags = RPC_TASK_ASYNC | RPC_TASK_MOVEABLE, + }; + int status; + +diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c +index 271e5f92ed0195..4d8a6f0537148c 100644 +--- a/fs/nfs/nfs42xdr.c ++++ b/fs/nfs/nfs42xdr.c +@@ -122,9 +122,11 @@ + decode_putfh_maxsz + \ + decode_offload_cancel_maxsz) + #define NFS4_enc_copy_notify_sz (compound_encode_hdr_maxsz + \ ++ encode_sequence_maxsz + \ + encode_putfh_maxsz + \ + encode_copy_notify_maxsz) + #define NFS4_dec_copy_notify_sz (compound_decode_hdr_maxsz + \ ++ decode_sequence_maxsz + \ + decode_putfh_maxsz + \ + decode_copy_notify_maxsz) + #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ +diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c +index 65d4511b7af08f..6c4fe9409611a4 100644 +--- a/fs/nfsd/nfs2acl.c ++++ b/fs/nfsd/nfs2acl.c +@@ -84,6 +84,8 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst *rqstp) + fail: + posix_acl_release(resp->acl_access); + posix_acl_release(resp->acl_default); ++ resp->acl_access = NULL; ++ resp->acl_default = NULL; + goto out; + } + +diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c +index a34a22e272ad53..e6bb621f1ffd78 100644 +--- a/fs/nfsd/nfs3acl.c ++++ b/fs/nfsd/nfs3acl.c +@@ -76,6 +76,8 @@ static __be32 nfsd3_proc_getacl(struct svc_rqst *rqstp) + fail: + posix_acl_release(resp->acl_access); + posix_acl_release(resp->acl_default); ++ resp->acl_access = NULL; ++ resp->acl_default = NULL; + goto out; + } + +diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c +index d2885dd4822dcd..272d3facfff9d3 100644 +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -1202,6 +1202,7 @@ static bool nfsd4_cb_sequence_done(struct rpc_task *task, struct nfsd4_callback + ret = false; + break; + case -NFS4ERR_DELAY: ++ cb->cb_seq_status = 1; + if (!rpc_restart_call(task)) + goto out; + +@@ -1409,8 +1410,11 @@ nfsd4_run_cb_work(struct work_struct *work) + nfsd4_process_cb_update(cb); + + clnt = clp->cl_cb_client; +- if (!clnt) { +- /* Callback channel broken, or client killed; give up: */ ++ if (!clnt || clp->cl_state == NFSD4_COURTESY) { ++ /* ++ * Callback channel broken, client killed or ++ * nfs4_client in courtesy state; give up. ++ */ + nfsd41_destroy_cb(cb); + return; + } +diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c +index cd363e2fc071d5..3d7e692f3e7f1b 100644 +--- a/fs/nilfs2/dir.c ++++ b/fs/nilfs2/dir.c +@@ -64,12 +64,6 @@ static inline unsigned int nilfs_chunk_size(struct inode *inode) + return inode->i_sb->s_blocksize; + } + +-static inline void nilfs_put_page(struct page *page) +-{ +- kunmap(page); +- put_page(page); +-} +- + /* + * Return the offset into page `page_nr' of the last valid + * byte in that page, plus one. +@@ -450,8 +444,7 @@ int nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr, ino_t *ino) + return 0; + } + +-/* Releases the page */ +-void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de, ++int nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de, + struct page *page, struct inode *inode) + { + unsigned int from = (char *)de - (char *)page_address(page); +@@ -461,12 +454,15 @@ void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de, + + lock_page(page); + err = nilfs_prepare_chunk(page, from, to); +- BUG_ON(err); ++ if (unlikely(err)) { ++ unlock_page(page); ++ return err; ++ } + de->inode = cpu_to_le64(inode->i_ino); + nilfs_set_de_type(de, inode); + nilfs_commit_chunk(page, mapping, from, to); +- nilfs_put_page(page); + dir->i_mtime = dir->i_ctime = current_time(dir); ++ return 0; + } + + /* +@@ -569,7 +565,7 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode) + + /* + * nilfs_delete_entry deletes a directory entry by merging it with the +- * previous entry. Page is up-to-date. Releases the page. ++ * previous entry. Page is up-to-date. + */ + int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page) + { +@@ -598,14 +594,16 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page) + from = (char *)pde - (char *)page_address(page); + lock_page(page); + err = nilfs_prepare_chunk(page, from, to); +- BUG_ON(err); ++ if (unlikely(err)) { ++ unlock_page(page); ++ goto out; ++ } + if (pde) + pde->rec_len = nilfs_rec_len_to_disk(to - from); + dir->inode = 0; + nilfs_commit_chunk(page, mapping, from, to); + inode->i_ctime = inode->i_mtime = current_time(inode); + out: +- nilfs_put_page(page); + return err; + } + +diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c +index 97c1beb00637d8..424949d86a41ed 100644 +--- a/fs/nilfs2/inode.c ++++ b/fs/nilfs2/inode.c +@@ -162,7 +162,7 @@ static int nilfs_writepages(struct address_space *mapping, + int err = 0; + + if (sb_rdonly(inode->i_sb)) { +- nilfs_clear_dirty_pages(mapping, false); ++ nilfs_clear_dirty_pages(mapping); + return -EROFS; + } + +@@ -185,7 +185,7 @@ static int nilfs_writepage(struct page *page, struct writeback_control *wbc) + * have dirty pages that try to be flushed in background. + * So, here we simply discard this dirty page. + */ +- nilfs_clear_dirty_page(page, false); ++ nilfs_clear_dirty_page(page); + unlock_page(page); + return -EROFS; + } +@@ -1265,7 +1265,7 @@ int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + if (size) { + if (phys && blkphy << blkbits == phys + size) { + /* The current extent goes on */ +- size += n << blkbits; ++ size += (u64)n << blkbits; + } else { + /* Terminate the current extent */ + ret = fiemap_fill_next_extent( +@@ -1278,14 +1278,14 @@ int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + flags = FIEMAP_EXTENT_MERGED; + logical = blkoff << blkbits; + phys = blkphy << blkbits; +- size = n << blkbits; ++ size = (u64)n << blkbits; + } + } else { + /* Start a new extent */ + flags = FIEMAP_EXTENT_MERGED; + logical = blkoff << blkbits; + phys = blkphy << blkbits; +- size = n << blkbits; ++ size = (u64)n << blkbits; + } + blkoff += n; + } +diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c +index bd3e0f9144ff0d..8156d2b5ec6ce1 100644 +--- a/fs/nilfs2/mdt.c ++++ b/fs/nilfs2/mdt.c +@@ -410,7 +410,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) + * have dirty pages that try to be flushed in background. + * So, here we simply discard this dirty page. + */ +- nilfs_clear_dirty_page(page, false); ++ nilfs_clear_dirty_page(page); + unlock_page(page); + return -EROFS; + } +@@ -632,10 +632,10 @@ void nilfs_mdt_restore_from_shadow_map(struct inode *inode) + if (mi->mi_palloc_cache) + nilfs_palloc_clear_cache(inode); + +- nilfs_clear_dirty_pages(inode->i_mapping, true); ++ nilfs_clear_dirty_pages(inode->i_mapping); + nilfs_copy_back_pages(inode->i_mapping, shadow->inode->i_mapping); + +- nilfs_clear_dirty_pages(ii->i_assoc_inode->i_mapping, true); ++ nilfs_clear_dirty_pages(ii->i_assoc_inode->i_mapping); + nilfs_copy_back_pages(ii->i_assoc_inode->i_mapping, + NILFS_I(shadow->inode)->i_assoc_inode->i_mapping); + +diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c +index 4f778bc24ef5e8..a81c24630e263e 100644 +--- a/fs/nilfs2/namei.c ++++ b/fs/nilfs2/namei.c +@@ -297,6 +297,7 @@ static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry) + set_nlink(inode, 1); + } + err = nilfs_delete_entry(de, page); ++ nilfs_put_page(page); + if (err) + goto out; + +@@ -405,7 +406,10 @@ static int nilfs_rename(struct user_namespace *mnt_userns, + err = PTR_ERR(new_de); + goto out_dir; + } +- nilfs_set_link(new_dir, new_de, new_page, old_inode); ++ err = nilfs_set_link(new_dir, new_de, new_page, old_inode); ++ nilfs_put_page(new_page); ++ if (unlikely(err)) ++ goto out_dir; + nilfs_mark_inode_dirty(new_dir); + new_inode->i_ctime = current_time(new_inode); + if (dir_de) +@@ -428,28 +432,27 @@ static int nilfs_rename(struct user_namespace *mnt_userns, + */ + old_inode->i_ctime = current_time(old_inode); + +- nilfs_delete_entry(old_de, old_page); +- +- if (dir_de) { +- nilfs_set_link(old_inode, dir_de, dir_page, new_dir); +- drop_nlink(old_dir); ++ err = nilfs_delete_entry(old_de, old_page); ++ if (likely(!err)) { ++ if (dir_de) { ++ err = nilfs_set_link(old_inode, dir_de, dir_page, ++ new_dir); ++ drop_nlink(old_dir); ++ } ++ nilfs_mark_inode_dirty(old_dir); + } +- nilfs_mark_inode_dirty(old_dir); + nilfs_mark_inode_dirty(old_inode); + +- err = nilfs_transaction_commit(old_dir->i_sb); +- return err; +- + out_dir: +- if (dir_de) { +- kunmap(dir_page); +- put_page(dir_page); +- } ++ if (dir_de) ++ nilfs_put_page(dir_page); + out_old: +- kunmap(old_page); +- put_page(old_page); ++ nilfs_put_page(old_page); + out: +- nilfs_transaction_abort(old_dir->i_sb); ++ if (likely(!err)) ++ err = nilfs_transaction_commit(old_dir->i_sb); ++ else ++ nilfs_transaction_abort(old_dir->i_sb); + return err; + } + +diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h +index 935fb5234c24d5..14ae1e3df83f2a 100644 +--- a/fs/nilfs2/nilfs.h ++++ b/fs/nilfs2/nilfs.h +@@ -240,8 +240,14 @@ nilfs_find_entry(struct inode *, const struct qstr *, struct page **); + extern int nilfs_delete_entry(struct nilfs_dir_entry *, struct page *); + extern int nilfs_empty_dir(struct inode *); + extern struct nilfs_dir_entry *nilfs_dotdot(struct inode *, struct page **); +-extern void nilfs_set_link(struct inode *, struct nilfs_dir_entry *, +- struct page *, struct inode *); ++int nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de, ++ struct page *page, struct inode *inode); ++ ++static inline void nilfs_put_page(struct page *page) ++{ ++ kunmap(page); ++ put_page(page); ++} + + /* file.c */ + extern int nilfs_sync_file(struct file *, loff_t, loff_t, int); +diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c +index d2d6d5c761e8db..ce5947cf4bd516 100644 +--- a/fs/nilfs2/page.c ++++ b/fs/nilfs2/page.c +@@ -354,9 +354,8 @@ void nilfs_copy_back_pages(struct address_space *dmap, + /** + * nilfs_clear_dirty_pages - discard dirty pages in address space + * @mapping: address space with dirty pages for discarding +- * @silent: suppress [true] or print [false] warning messages + */ +-void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent) ++void nilfs_clear_dirty_pages(struct address_space *mapping) + { + struct pagevec pvec; + unsigned int i; +@@ -377,7 +376,7 @@ void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent) + * was acquired. Skip processing in that case. + */ + if (likely(page->mapping == mapping)) +- nilfs_clear_dirty_page(page, silent); ++ nilfs_clear_dirty_page(page); + + unlock_page(page); + } +@@ -389,44 +388,54 @@ void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent) + /** + * nilfs_clear_dirty_page - discard dirty page + * @page: dirty page that will be discarded +- * @silent: suppress [true] or print [false] warning messages ++ * ++ * nilfs_clear_dirty_page() clears working states including dirty state for ++ * the page and its buffers. If the page has buffers, clear only if it is ++ * confirmed that none of the buffer heads are busy (none have valid ++ * references and none are locked). + */ +-void nilfs_clear_dirty_page(struct page *page, bool silent) ++void nilfs_clear_dirty_page(struct page *page) + { +- struct inode *inode = page->mapping->host; +- struct super_block *sb = inode->i_sb; +- + BUG_ON(!PageLocked(page)); + +- if (!silent) +- nilfs_warn(sb, "discard dirty page: offset=%lld, ino=%lu", +- page_offset(page), inode->i_ino); +- +- ClearPageUptodate(page); +- ClearPageMappedToDisk(page); +- ClearPageChecked(page); +- + if (page_has_buffers(page)) { +- struct buffer_head *bh, *head; ++ struct buffer_head *bh, *head = page_buffers(page); + const unsigned long clear_bits = + (BIT(BH_Uptodate) | BIT(BH_Dirty) | BIT(BH_Mapped) | + BIT(BH_Async_Write) | BIT(BH_NILFS_Volatile) | + BIT(BH_NILFS_Checked) | BIT(BH_NILFS_Redirected) | + BIT(BH_Delay)); ++ bool busy, invalidated = false; + +- bh = head = page_buffers(page); ++recheck_buffers: ++ busy = false; ++ bh = head; + do { +- lock_buffer(bh); +- if (!silent) +- nilfs_warn(sb, +- "discard dirty block: blocknr=%llu, size=%zu", +- (u64)bh->b_blocknr, bh->b_size); ++ if (atomic_read(&bh->b_count) | buffer_locked(bh)) { ++ busy = true; ++ break; ++ } ++ } while (bh = bh->b_this_page, bh != head); + ++ if (busy) { ++ if (invalidated) ++ return; ++ invalidate_bh_lrus(); ++ invalidated = true; ++ goto recheck_buffers; ++ } ++ ++ bh = head; ++ do { ++ lock_buffer(bh); + set_mask_bits(&bh->b_state, clear_bits, 0); + unlock_buffer(bh); + } while (bh = bh->b_this_page, bh != head); + } + ++ ClearPageUptodate(page); ++ ClearPageMappedToDisk(page); ++ ClearPageChecked(page); + __nilfs_clear_page_dirty(page); + } + +diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h +index 62b9bb469e92f3..a5b9b5a457ab29 100644 +--- a/fs/nilfs2/page.h ++++ b/fs/nilfs2/page.h +@@ -41,8 +41,8 @@ void nilfs_page_bug(struct page *); + + int nilfs_copy_dirty_pages(struct address_space *, struct address_space *); + void nilfs_copy_back_pages(struct address_space *, struct address_space *); +-void nilfs_clear_dirty_page(struct page *, bool); +-void nilfs_clear_dirty_pages(struct address_space *, bool); ++void nilfs_clear_dirty_page(struct page *page); ++void nilfs_clear_dirty_pages(struct address_space *mapping); + void nilfs_mapping_init(struct address_space *mapping, struct inode *inode); + unsigned int nilfs_page_count_clean_buffers(struct page *, unsigned int, + unsigned int); +diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c +index 75fd6e86f18a33..2f778234ecf2ce 100644 +--- a/fs/nilfs2/segment.c ++++ b/fs/nilfs2/segment.c +@@ -732,7 +732,6 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode, + } + if (!page_has_buffers(page)) + create_empty_buffers(page, i_blocksize(inode), 0); +- unlock_page(page); + + bh = head = page_buffers(page); + do { +@@ -742,11 +741,14 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode, + list_add_tail(&bh->b_assoc_buffers, listp); + ndirties++; + if (unlikely(ndirties >= nlimit)) { ++ unlock_page(page); + pagevec_release(&pvec); + cond_resched(); + return ndirties; + } + } while (bh = bh->b_this_page, bh != head); ++ ++ unlock_page(page); + } + pagevec_release(&pvec); + cond_resched(); +diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c +index c9797dd0678514..441818535bfc57 100644 +--- a/fs/ocfs2/dir.c ++++ b/fs/ocfs2/dir.c +@@ -1065,26 +1065,39 @@ int ocfs2_find_entry(const char *name, int namelen, + { + struct buffer_head *bh; + struct ocfs2_dir_entry *res_dir = NULL; ++ int ret = 0; + + if (ocfs2_dir_indexed(dir)) + return ocfs2_find_entry_dx(name, namelen, dir, lookup); + ++ if (unlikely(i_size_read(dir) <= 0)) { ++ ret = -EFSCORRUPTED; ++ mlog_errno(ret); ++ goto out; ++ } + /* + * The unindexed dir code only uses part of the lookup + * structure, so there's no reason to push it down further + * than this. + */ +- if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) ++ if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) { ++ if (unlikely(i_size_read(dir) > dir->i_sb->s_blocksize)) { ++ ret = -EFSCORRUPTED; ++ mlog_errno(ret); ++ goto out; ++ } + bh = ocfs2_find_entry_id(name, namelen, dir, &res_dir); +- else ++ } else { + bh = ocfs2_find_entry_el(name, namelen, dir, &res_dir); ++ } + + if (bh == NULL) + return -ENOENT; + + lookup->dl_leaf_bh = bh; + lookup->dl_entry = res_dir; +- return 0; ++out: ++ return ret; + } + + /* +@@ -2011,6 +2024,7 @@ int ocfs2_lookup_ino_from_name(struct inode *dir, const char *name, + * + * Return 0 if the name does not exist + * Return -EEXIST if the directory contains the name ++ * Return -EFSCORRUPTED if found corruption + * + * Callers should have i_mutex + a cluster lock on dir + */ +@@ -2024,9 +2038,12 @@ int ocfs2_check_dir_for_entry(struct inode *dir, + trace_ocfs2_check_dir_for_entry( + (unsigned long long)OCFS2_I(dir)->ip_blkno, namelen, name); + +- if (ocfs2_find_entry(name, namelen, dir, &lookup) == 0) { ++ ret = ocfs2_find_entry(name, namelen, dir, &lookup); ++ if (ret == 0) { + ret = -EEXIST; + mlog_errno(ret); ++ } else if (ret == -ENOENT) { ++ ret = 0; + } + + ocfs2_free_dir_lookup_result(&lookup); +diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c +index cc464c9560e25a..79e70aaa9a90d0 100644 +--- a/fs/ocfs2/quota_global.c ++++ b/fs/ocfs2/quota_global.c +@@ -749,6 +749,11 @@ static int ocfs2_release_dquot(struct dquot *dquot) + handle = ocfs2_start_trans(osb, + ocfs2_calc_qdel_credits(dquot->dq_sb, dquot->dq_id.type)); + if (IS_ERR(handle)) { ++ /* ++ * Mark dquot as inactive to avoid endless cycle in ++ * quota_release_workfn(). ++ */ ++ clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); + status = PTR_ERR(handle); + mlog_errno(status); + goto out_ilock; +diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c +index 5ef411a419e1af..25f745f4b63a15 100644 +--- a/fs/ocfs2/super.c ++++ b/fs/ocfs2/super.c +@@ -2346,7 +2346,7 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di, + mlog(ML_ERROR, "found superblock with incorrect block " + "size bits: found %u, should be 9, 10, 11, or 12\n", + blksz_bits); +- } else if ((1 << le32_to_cpu(blksz_bits)) != blksz) { ++ } else if ((1 << blksz_bits) != blksz) { + mlog(ML_ERROR, "found superblock with incorrect block " + "size: found %u, should be %u\n", 1 << blksz_bits, blksz); + } else if (le16_to_cpu(di->id2.i_super.s_major_rev_level) != +diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c +index f755a498582160..9aa4172c242a62 100644 +--- a/fs/ocfs2/symlink.c ++++ b/fs/ocfs2/symlink.c +@@ -64,7 +64,7 @@ static int ocfs2_fast_symlink_readpage(struct file *unused, struct page *page) + + if (status < 0) { + mlog_errno(status); +- return status; ++ goto out; + } + + fe = (struct ocfs2_dinode *) bh->b_data; +@@ -75,9 +75,10 @@ static int ocfs2_fast_symlink_readpage(struct file *unused, struct page *page) + memcpy(kaddr, link, len + 1); + kunmap_atomic(kaddr); + SetPageUptodate(page); ++out: + unlock_page(page); + brelse(bh); +- return 0; ++ return status; + } + + const struct address_space_operations ocfs2_fast_symlink_aops = { +diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c +index 1b508f5433846e..fa41db08848802 100644 +--- a/fs/orangefs/orangefs-debugfs.c ++++ b/fs/orangefs/orangefs-debugfs.c +@@ -393,9 +393,9 @@ static ssize_t orangefs_debug_write(struct file *file, + * Thwart users who try to jamb a ridiculous number + * of bytes into the debug file... + */ +- if (count > ORANGEFS_MAX_DEBUG_STRING_LEN + 1) { ++ if (count > ORANGEFS_MAX_DEBUG_STRING_LEN) { + silly = count; +- count = ORANGEFS_MAX_DEBUG_STRING_LEN + 1; ++ count = ORANGEFS_MAX_DEBUG_STRING_LEN; + } + + buf = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL); +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index 0ed70eff9cb9e8..5fc32483afed89 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -117,7 +117,7 @@ int ovl_copy_xattr(struct super_block *sb, struct dentry *old, + goto retry; + } + +- error = vfs_setxattr(&init_user_ns, new, name, value, size, 0); ++ error = ovl_do_setxattr(OVL_FS(sb), new, name, value, size, 0); + if (error) { + if (error != -EOPNOTSUPP || ovl_must_copy_xattr(name)) + break; +@@ -433,7 +433,7 @@ static int ovl_set_upper_fh(struct ovl_fs *ofs, struct dentry *upper, + if (IS_ERR(fh)) + return PTR_ERR(fh); + +- err = ovl_do_setxattr(ofs, index, OVL_XATTR_UPPER, fh->buf, fh->fb.len); ++ err = ovl_setxattr(ofs, index, OVL_XATTR_UPPER, fh->buf, fh->fb.len); + + kfree(fh); + return err; +@@ -474,7 +474,7 @@ static int ovl_create_index(struct dentry *dentry, struct dentry *origin, + if (err) + return err; + +- temp = ovl_create_temp(indexdir, OVL_CATTR(S_IFDIR | 0)); ++ temp = ovl_create_temp(ofs, indexdir, OVL_CATTR(S_IFDIR | 0)); + err = PTR_ERR(temp); + if (IS_ERR(temp)) + goto free_name; +@@ -487,12 +487,12 @@ static int ovl_create_index(struct dentry *dentry, struct dentry *origin, + if (IS_ERR(index)) { + err = PTR_ERR(index); + } else { +- err = ovl_do_rename(dir, temp, dir, index, 0); ++ err = ovl_do_rename(ofs, dir, temp, dir, index, 0); + dput(index); + } + out: + if (err) +- ovl_cleanup(dir, temp); ++ ovl_cleanup(ofs, dir, temp); + dput(temp); + free_name: + kfree(name.name); +@@ -519,6 +519,7 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c) + int err; + struct dentry *upper; + struct dentry *upperdir = ovl_dentry_upper(c->parent); ++ struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb); + struct inode *udir = d_inode(upperdir); + + /* Mark parent "impure" because it may now contain non-pure upper */ +@@ -535,8 +536,7 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c) + c->dentry->d_name.len); + err = PTR_ERR(upper); + if (!IS_ERR(upper)) { +- err = ovl_do_link(ovl_dentry_upper(c->dentry), udir, upper); +- dput(upper); ++ err = ovl_do_link(ofs, ovl_dentry_upper(c->dentry), udir, upper); + + if (!err) { + /* Restore timestamps on parent (best effort) */ +@@ -544,6 +544,7 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c) + ovl_dentry_set_upper_alias(c->dentry); + ovl_dentry_update_reval(c->dentry, upper); + } ++ dput(upper); + } + inode_unlock(udir); + if (err) +@@ -658,6 +659,7 @@ static void ovl_revert_cu_creds(struct ovl_cu_creds *cc) + */ + static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c) + { ++ struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb); + struct inode *inode; + struct inode *udir = d_inode(c->destdir), *wdir = d_inode(c->workdir); + struct dentry *temp, *upper; +@@ -679,7 +681,7 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c) + if (err) + goto unlock; + +- temp = ovl_create_temp(c->workdir, &cattr); ++ temp = ovl_create_temp(ofs, c->workdir, &cattr); + ovl_revert_cu_creds(&cc); + + err = PTR_ERR(temp); +@@ -701,7 +703,7 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c) + if (IS_ERR(upper)) + goto cleanup; + +- err = ovl_do_rename(wdir, temp, udir, upper, 0); ++ err = ovl_do_rename(ofs, wdir, temp, udir, upper, 0); + dput(upper); + if (err) + goto cleanup; +@@ -718,7 +720,7 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c) + return err; + + cleanup: +- ovl_cleanup(wdir, temp); ++ ovl_cleanup(ofs, wdir, temp); + dput(temp); + goto unlock; + } +@@ -726,6 +728,7 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c) + /* Copyup using O_TMPFILE which does not require cross dir locking */ + static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *c) + { ++ struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb); + struct inode *udir = d_inode(c->destdir); + struct dentry *temp, *upper; + struct ovl_cu_creds cc; +@@ -735,7 +738,7 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *c) + if (err) + return err; + +- temp = ovl_do_tmpfile(c->workdir, c->stat.mode); ++ temp = ovl_do_tmpfile(ofs, c->workdir, c->stat.mode); + ovl_revert_cu_creds(&cc); + + if (IS_ERR(temp)) +@@ -750,7 +753,7 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *c) + upper = lookup_one_len(c->destname.name, c->destdir, c->destname.len); + err = PTR_ERR(upper); + if (!IS_ERR(upper)) { +- err = ovl_do_link(temp, udir, upper); ++ err = ovl_do_link(ofs, temp, udir, upper); + dput(upper); + } + inode_unlock(udir); +@@ -868,12 +871,13 @@ static bool ovl_need_meta_copy_up(struct dentry *dentry, umode_t mode, + return true; + } + +-static ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value) ++static ssize_t ovl_getxattr_value(struct ovl_fs *ofs, struct dentry *dentry, ++ char *name, char **value) + { + ssize_t res; + char *buf; + +- res = vfs_getxattr(&init_user_ns, dentry, name, NULL, 0); ++ res = ovl_do_getxattr(ofs, dentry, name, NULL, 0); + if (res == -ENODATA || res == -EOPNOTSUPP) + res = 0; + +@@ -882,7 +886,7 @@ static ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value) + if (!buf) + return -ENOMEM; + +- res = vfs_getxattr(&init_user_ns, dentry, name, buf, res); ++ res = ovl_do_getxattr(ofs, dentry, name, buf, res); + if (res < 0) + kfree(buf); + else +@@ -909,8 +913,8 @@ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c) + return -EIO; + + if (c->stat.size) { +- err = cap_size = ovl_getxattr(upperpath.dentry, XATTR_NAME_CAPS, +- &capability); ++ err = cap_size = ovl_getxattr_value(ofs, upperpath.dentry, ++ XATTR_NAME_CAPS, &capability); + if (cap_size < 0) + goto out; + } +@@ -924,14 +928,14 @@ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c) + * don't want that to happen for normal copy-up operation. + */ + if (capability) { +- err = vfs_setxattr(&init_user_ns, upperpath.dentry, +- XATTR_NAME_CAPS, capability, cap_size, 0); ++ err = ovl_do_setxattr(ofs, upperpath.dentry, XATTR_NAME_CAPS, ++ capability, cap_size, 0); + if (err) + goto out_free; + } + + +- err = ovl_do_removexattr(ofs, upperpath.dentry, OVL_XATTR_METACOPY); ++ err = ovl_removexattr(ofs, upperpath.dentry, OVL_XATTR_METACOPY); + if (err) + goto out_free; + +diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c +index 519193ce7d575f..584b78f0bfa1a5 100644 +--- a/fs/overlayfs/dir.c ++++ b/fs/overlayfs/dir.c +@@ -23,15 +23,15 @@ MODULE_PARM_DESC(redirect_max, + + static int ovl_set_redirect(struct dentry *dentry, bool samedir); + +-int ovl_cleanup(struct inode *wdir, struct dentry *wdentry) ++int ovl_cleanup(struct ovl_fs *ofs, struct inode *wdir, struct dentry *wdentry) + { + int err; + + dget(wdentry); + if (d_is_dir(wdentry)) +- err = ovl_do_rmdir(wdir, wdentry); ++ err = ovl_do_rmdir(ofs, wdir, wdentry); + else +- err = ovl_do_unlink(wdir, wdentry); ++ err = ovl_do_unlink(ofs, wdir, wdentry); + dput(wdentry); + + if (err) { +@@ -42,7 +42,7 @@ int ovl_cleanup(struct inode *wdir, struct dentry *wdentry) + return err; + } + +-struct dentry *ovl_lookup_temp(struct dentry *workdir) ++struct dentry *ovl_lookup_temp(struct ovl_fs *ofs, struct dentry *workdir) + { + struct dentry *temp; + char name[20]; +@@ -70,11 +70,11 @@ static struct dentry *ovl_whiteout(struct ovl_fs *ofs) + struct inode *wdir = workdir->d_inode; + + if (!ofs->whiteout) { +- whiteout = ovl_lookup_temp(workdir); ++ whiteout = ovl_lookup_temp(ofs, workdir); + if (IS_ERR(whiteout)) + goto out; + +- err = ovl_do_whiteout(wdir, whiteout); ++ err = ovl_do_whiteout(ofs, wdir, whiteout); + if (err) { + dput(whiteout); + whiteout = ERR_PTR(err); +@@ -84,11 +84,11 @@ static struct dentry *ovl_whiteout(struct ovl_fs *ofs) + } + + if (ofs->share_whiteout) { +- whiteout = ovl_lookup_temp(workdir); ++ whiteout = ovl_lookup_temp(ofs, workdir); + if (IS_ERR(whiteout)) + goto out; + +- err = ovl_do_link(ofs->whiteout, wdir, whiteout); ++ err = ovl_do_link(ofs, ofs->whiteout, wdir, whiteout); + if (!err) + goto out; + +@@ -122,27 +122,28 @@ int ovl_cleanup_and_whiteout(struct ovl_fs *ofs, struct inode *dir, + if (d_is_dir(dentry)) + flags = RENAME_EXCHANGE; + +- err = ovl_do_rename(wdir, whiteout, dir, dentry, flags); ++ err = ovl_do_rename(ofs, wdir, whiteout, dir, dentry, flags); + if (err) + goto kill_whiteout; + if (flags) +- ovl_cleanup(wdir, dentry); ++ ovl_cleanup(ofs, wdir, dentry); + + out: + dput(whiteout); + return err; + + kill_whiteout: +- ovl_cleanup(wdir, whiteout); ++ ovl_cleanup(ofs, wdir, whiteout); + goto out; + } + +-int ovl_mkdir_real(struct inode *dir, struct dentry **newdentry, umode_t mode) ++int ovl_mkdir_real(struct ovl_fs *ofs, struct inode *dir, ++ struct dentry **newdentry, umode_t mode) + { + int err; + struct dentry *d, *dentry = *newdentry; + +- err = ovl_do_mkdir(dir, dentry, mode); ++ err = ovl_do_mkdir(ofs, dir, dentry, mode); + if (err) + return err; + +@@ -167,8 +168,8 @@ int ovl_mkdir_real(struct inode *dir, struct dentry **newdentry, umode_t mode) + return 0; + } + +-struct dentry *ovl_create_real(struct inode *dir, struct dentry *newdentry, +- struct ovl_cattr *attr) ++struct dentry *ovl_create_real(struct ovl_fs *ofs, struct inode *dir, ++ struct dentry *newdentry, struct ovl_cattr *attr) + { + int err; + +@@ -180,28 +181,28 @@ struct dentry *ovl_create_real(struct inode *dir, struct dentry *newdentry, + goto out; + + if (attr->hardlink) { +- err = ovl_do_link(attr->hardlink, dir, newdentry); ++ err = ovl_do_link(ofs, attr->hardlink, dir, newdentry); + } else { + switch (attr->mode & S_IFMT) { + case S_IFREG: +- err = ovl_do_create(dir, newdentry, attr->mode); ++ err = ovl_do_create(ofs, dir, newdentry, attr->mode); + break; + + case S_IFDIR: + /* mkdir is special... */ +- err = ovl_mkdir_real(dir, &newdentry, attr->mode); ++ err = ovl_mkdir_real(ofs, dir, &newdentry, attr->mode); + break; + + case S_IFCHR: + case S_IFBLK: + case S_IFIFO: + case S_IFSOCK: +- err = ovl_do_mknod(dir, newdentry, attr->mode, ++ err = ovl_do_mknod(ofs, dir, newdentry, attr->mode, + attr->rdev); + break; + + case S_IFLNK: +- err = ovl_do_symlink(dir, newdentry, attr->link); ++ err = ovl_do_symlink(ofs, dir, newdentry, attr->link); + break; + + default: +@@ -223,10 +224,11 @@ struct dentry *ovl_create_real(struct inode *dir, struct dentry *newdentry, + return newdentry; + } + +-struct dentry *ovl_create_temp(struct dentry *workdir, struct ovl_cattr *attr) ++struct dentry *ovl_create_temp(struct ovl_fs *ofs, struct dentry *workdir, ++ struct ovl_cattr *attr) + { +- return ovl_create_real(d_inode(workdir), ovl_lookup_temp(workdir), +- attr); ++ return ovl_create_real(ofs, d_inode(workdir), ++ ovl_lookup_temp(ofs, workdir), attr); + } + + static int ovl_set_opaque_xerr(struct dentry *dentry, struct dentry *upper, +@@ -329,7 +331,7 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode, + attr->mode &= ~current_umask(); + + inode_lock_nested(udir, I_MUTEX_PARENT); +- newdentry = ovl_create_real(udir, ++ newdentry = ovl_create_real(ofs, udir, + lookup_one_len(dentry->d_name.name, + upperdir, + dentry->d_name.len), +@@ -352,7 +354,7 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode, + return err; + + out_cleanup: +- ovl_cleanup(udir, newdentry); ++ ovl_cleanup(ofs, udir, newdentry); + dput(newdentry); + goto out_unlock; + } +@@ -360,6 +362,7 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode, + static struct dentry *ovl_clear_empty(struct dentry *dentry, + struct list_head *list) + { ++ struct ovl_fs *ofs = OVL_FS(dentry->d_sb); + struct dentry *workdir = ovl_workdir(dentry); + struct inode *wdir = workdir->d_inode; + struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent); +@@ -390,7 +393,7 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry, + if (upper->d_parent->d_inode != udir) + goto out_unlock; + +- opaquedir = ovl_create_temp(workdir, OVL_CATTR(stat.mode)); ++ opaquedir = ovl_create_temp(ofs, workdir, OVL_CATTR(stat.mode)); + err = PTR_ERR(opaquedir); + if (IS_ERR(opaquedir)) + goto out_unlock; +@@ -409,12 +412,12 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry, + if (err) + goto out_cleanup; + +- err = ovl_do_rename(wdir, opaquedir, udir, upper, RENAME_EXCHANGE); ++ err = ovl_do_rename(ofs, wdir, opaquedir, udir, upper, RENAME_EXCHANGE); + if (err) + goto out_cleanup; + +- ovl_cleanup_whiteouts(upper, list); +- ovl_cleanup(wdir, upper); ++ ovl_cleanup_whiteouts(ofs, upper, list); ++ ovl_cleanup(ofs, wdir, upper); + unlock_rename(workdir, upperdir); + + /* dentry's upper doesn't match now, get rid of it */ +@@ -423,7 +426,7 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry, + return opaquedir; + + out_cleanup: +- ovl_cleanup(wdir, opaquedir); ++ ovl_cleanup(ofs, wdir, opaquedir); + dput(opaquedir); + out_unlock: + unlock_rename(workdir, upperdir); +@@ -431,8 +434,8 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry, + return ERR_PTR(err); + } + +-static int ovl_set_upper_acl(struct dentry *upperdentry, const char *name, +- const struct posix_acl *acl) ++static int ovl_set_upper_acl(struct ovl_fs *ofs, struct dentry *upperdentry, ++ const char *name, const struct posix_acl *acl) + { + void *buffer; + size_t size; +@@ -450,7 +453,7 @@ static int ovl_set_upper_acl(struct dentry *upperdentry, const char *name, + if (err < 0) + goto out_free; + +- err = vfs_setxattr(&init_user_ns, upperdentry, name, buffer, size, XATTR_CREATE); ++ err = ovl_do_setxattr(ofs, upperdentry, name, buffer, size, XATTR_CREATE); + out_free: + kfree(buffer); + return err; +@@ -459,6 +462,7 @@ static int ovl_set_upper_acl(struct dentry *upperdentry, const char *name, + static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, + struct ovl_cattr *cattr) + { ++ struct ovl_fs *ofs = OVL_FS(dentry->d_sb); + struct dentry *workdir = ovl_workdir(dentry); + struct inode *wdir = workdir->d_inode; + struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent); +@@ -493,7 +497,7 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, + if (d_is_negative(upper) || !IS_WHITEOUT(d_inode(upper))) + goto out_dput; + +- newdentry = ovl_create_temp(workdir, cattr); ++ newdentry = ovl_create_temp(ofs, workdir, cattr); + err = PTR_ERR(newdentry); + if (IS_ERR(newdentry)) + goto out_dput; +@@ -515,13 +519,13 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, + goto out_cleanup; + } + if (!hardlink) { +- err = ovl_set_upper_acl(newdentry, XATTR_NAME_POSIX_ACL_ACCESS, +- acl); ++ err = ovl_set_upper_acl(ofs, newdentry, ++ XATTR_NAME_POSIX_ACL_ACCESS, acl); + if (err) + goto out_cleanup; + +- err = ovl_set_upper_acl(newdentry, XATTR_NAME_POSIX_ACL_DEFAULT, +- default_acl); ++ err = ovl_set_upper_acl(ofs, newdentry, ++ XATTR_NAME_POSIX_ACL_DEFAULT, default_acl); + if (err) + goto out_cleanup; + } +@@ -531,20 +535,20 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, + if (err) + goto out_cleanup; + +- err = ovl_do_rename(wdir, newdentry, udir, upper, ++ err = ovl_do_rename(ofs, wdir, newdentry, udir, upper, + RENAME_EXCHANGE); + if (err) + goto out_cleanup; + +- ovl_cleanup(wdir, upper); ++ ovl_cleanup(ofs, wdir, upper); + } else { +- err = ovl_do_rename(wdir, newdentry, udir, upper, 0); ++ err = ovl_do_rename(ofs, wdir, newdentry, udir, upper, 0); + if (err) + goto out_cleanup; + } + err = ovl_instantiate(dentry, inode, newdentry, hardlink); + if (err) { +- ovl_cleanup(udir, newdentry); ++ ovl_cleanup(ofs, udir, newdentry); + dput(newdentry); + } + out_dput: +@@ -559,7 +563,7 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, + return err; + + out_cleanup: +- ovl_cleanup(wdir, newdentry); ++ ovl_cleanup(ofs, wdir, newdentry); + dput(newdentry); + goto out_dput; + } +@@ -813,6 +817,7 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, + static int ovl_remove_upper(struct dentry *dentry, bool is_dir, + struct list_head *list) + { ++ struct ovl_fs *ofs = OVL_FS(dentry->d_sb); + struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent); + struct inode *dir = upperdir->d_inode; + struct dentry *upper; +@@ -839,9 +844,9 @@ static int ovl_remove_upper(struct dentry *dentry, bool is_dir, + goto out_dput_upper; + + if (is_dir) +- err = vfs_rmdir(&init_user_ns, dir, upper); ++ err = ovl_do_rmdir(ofs, dir, upper); + else +- err = vfs_unlink(&init_user_ns, dir, upper, NULL); ++ err = ovl_do_unlink(ofs, dir, upper); + ovl_dir_modified(dentry->d_parent, ovl_type_origin(dentry)); + + /* +@@ -1106,6 +1111,7 @@ static int ovl_rename(struct user_namespace *mnt_userns, struct inode *olddir, + bool samedir = olddir == newdir; + struct dentry *opaquedir = NULL; + const struct cred *old_cred = NULL; ++ struct ovl_fs *ofs = OVL_FS(old->d_sb); + LIST_HEAD(list); + + err = -EINVAL; +@@ -1262,13 +1268,13 @@ static int ovl_rename(struct user_namespace *mnt_userns, struct inode *olddir, + if (err) + goto out_dput; + +- err = ovl_do_rename(old_upperdir->d_inode, olddentry, ++ err = ovl_do_rename(ofs, old_upperdir->d_inode, olddentry, + new_upperdir->d_inode, newdentry, flags); + if (err) + goto out_dput; + + if (cleanup_whiteout) +- ovl_cleanup(old_upperdir->d_inode, newdentry); ++ ovl_cleanup(ofs, old_upperdir->d_inode, newdentry); + + if (overwrite && d_inode(new)) { + if (new_is_dir) +diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c +index 7961d6888c5205..aa8513aac4728b 100644 +--- a/fs/overlayfs/inode.c ++++ b/fs/overlayfs/inode.c +@@ -342,6 +342,7 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, + const void *value, size_t size, int flags) + { + int err; ++ struct ovl_fs *ofs = OVL_FS(dentry->d_sb); + struct dentry *upperdentry = ovl_i_dentry_upper(inode); + struct dentry *realdentry = upperdentry ?: ovl_dentry_lower(dentry); + const struct cred *old_cred; +@@ -367,12 +368,12 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, + } + + old_cred = ovl_override_creds(dentry->d_sb); +- if (value) +- err = vfs_setxattr(&init_user_ns, realdentry, name, value, size, +- flags); +- else { ++ if (value) { ++ err = ovl_do_setxattr(ofs, realdentry, name, value, size, ++ flags); ++ } else { + WARN_ON(flags != XATTR_REPLACE); +- err = vfs_removexattr(&init_user_ns, realdentry, name); ++ err = ovl_do_removexattr(ofs, realdentry, name); + } + revert_creds(old_cred); + +@@ -887,8 +888,8 @@ static int ovl_set_nlink_common(struct dentry *dentry, + if (WARN_ON(len >= sizeof(buf))) + return -EIO; + +- return ovl_do_setxattr(OVL_FS(inode->i_sb), ovl_dentry_upper(dentry), +- OVL_XATTR_NLINK, buf, len); ++ return ovl_setxattr(OVL_FS(inode->i_sb), ovl_dentry_upper(dentry), ++ OVL_XATTR_NLINK, buf, len); + } + + int ovl_set_nlink_upper(struct dentry *dentry) +@@ -913,7 +914,7 @@ unsigned int ovl_get_nlink(struct ovl_fs *ofs, struct dentry *lowerdentry, + if (!lowerdentry || !upperdentry || d_inode(lowerdentry)->i_nlink == 1) + return fallback; + +- err = ovl_do_getxattr(ofs, upperdentry, OVL_XATTR_NLINK, ++ err = ovl_getxattr(ofs, upperdentry, OVL_XATTR_NLINK, + &buf, sizeof(buf) - 1); + if (err < 0) + goto fail; +diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c +index 9c055d11a95de9..00d74311aa0d39 100644 +--- a/fs/overlayfs/namei.c ++++ b/fs/overlayfs/namei.c +@@ -111,7 +111,7 @@ static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *dentry, + int res, err; + struct ovl_fh *fh = NULL; + +- res = ovl_do_getxattr(ofs, dentry, ox, NULL, 0); ++ res = ovl_getxattr(ofs, dentry, ox, NULL, 0); + if (res < 0) { + if (res == -ENODATA || res == -EOPNOTSUPP) + return NULL; +@@ -125,7 +125,7 @@ static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *dentry, + if (!fh) + return ERR_PTR(-ENOMEM); + +- res = ovl_do_getxattr(ofs, dentry, ox, fh->buf, res); ++ res = ovl_getxattr(ofs, dentry, ox, fh->buf, res); + if (res < 0) + goto fail; + +@@ -464,7 +464,7 @@ int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, + + err = ovl_verify_fh(ofs, dentry, ox, fh); + if (set && err == -ENODATA) +- err = ovl_do_setxattr(ofs, dentry, ox, fh->buf, fh->fb.len); ++ err = ovl_setxattr(ofs, dentry, ox, fh->buf, fh->fb.len); + if (err) + goto fail; + +diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h +index a96b67586f817d..43b211cf437ccc 100644 +--- a/fs/overlayfs/overlayfs.h ++++ b/fs/overlayfs/overlayfs.h +@@ -122,7 +122,8 @@ static inline const char *ovl_xattr(struct ovl_fs *ofs, enum ovl_xattr ox) + return ovl_xattr_table[ox][ofs->config.userxattr]; + } + +-static inline int ovl_do_rmdir(struct inode *dir, struct dentry *dentry) ++static inline int ovl_do_rmdir(struct ovl_fs *ofs, ++ struct inode *dir, struct dentry *dentry) + { + int err = vfs_rmdir(&init_user_ns, dir, dentry); + +@@ -130,7 +131,8 @@ static inline int ovl_do_rmdir(struct inode *dir, struct dentry *dentry) + return err; + } + +-static inline int ovl_do_unlink(struct inode *dir, struct dentry *dentry) ++static inline int ovl_do_unlink(struct ovl_fs *ofs, struct inode *dir, ++ struct dentry *dentry) + { + int err = vfs_unlink(&init_user_ns, dir, dentry, NULL); + +@@ -138,8 +140,8 @@ static inline int ovl_do_unlink(struct inode *dir, struct dentry *dentry) + return err; + } + +-static inline int ovl_do_link(struct dentry *old_dentry, struct inode *dir, +- struct dentry *new_dentry) ++static inline int ovl_do_link(struct ovl_fs *ofs, struct dentry *old_dentry, ++ struct inode *dir, struct dentry *new_dentry) + { + int err = vfs_link(old_dentry, &init_user_ns, dir, new_dentry, NULL); + +@@ -147,7 +149,8 @@ static inline int ovl_do_link(struct dentry *old_dentry, struct inode *dir, + return err; + } + +-static inline int ovl_do_create(struct inode *dir, struct dentry *dentry, ++static inline int ovl_do_create(struct ovl_fs *ofs, ++ struct inode *dir, struct dentry *dentry, + umode_t mode) + { + int err = vfs_create(&init_user_ns, dir, dentry, mode, true); +@@ -156,7 +159,8 @@ static inline int ovl_do_create(struct inode *dir, struct dentry *dentry, + return err; + } + +-static inline int ovl_do_mkdir(struct inode *dir, struct dentry *dentry, ++static inline int ovl_do_mkdir(struct ovl_fs *ofs, ++ struct inode *dir, struct dentry *dentry, + umode_t mode) + { + int err = vfs_mkdir(&init_user_ns, dir, dentry, mode); +@@ -164,7 +168,8 @@ static inline int ovl_do_mkdir(struct inode *dir, struct dentry *dentry, + return err; + } + +-static inline int ovl_do_mknod(struct inode *dir, struct dentry *dentry, ++static inline int ovl_do_mknod(struct ovl_fs *ofs, ++ struct inode *dir, struct dentry *dentry, + umode_t mode, dev_t dev) + { + int err = vfs_mknod(&init_user_ns, dir, dentry, mode, dev); +@@ -173,7 +178,8 @@ static inline int ovl_do_mknod(struct inode *dir, struct dentry *dentry, + return err; + } + +-static inline int ovl_do_symlink(struct inode *dir, struct dentry *dentry, ++static inline int ovl_do_symlink(struct ovl_fs *ofs, ++ struct inode *dir, struct dentry *dentry, + const char *oldname) + { + int err = vfs_symlink(&init_user_ns, dir, dentry, oldname); +@@ -183,10 +189,9 @@ static inline int ovl_do_symlink(struct inode *dir, struct dentry *dentry, + } + + static inline ssize_t ovl_do_getxattr(struct ovl_fs *ofs, struct dentry *dentry, +- enum ovl_xattr ox, void *value, ++ const char *name, void *value, + size_t size) + { +- const char *name = ovl_xattr(ofs, ox); + int err = vfs_getxattr(&init_user_ns, dentry, name, value, size); + int len = (value && err > 0) ? err : 0; + +@@ -195,29 +200,48 @@ static inline ssize_t ovl_do_getxattr(struct ovl_fs *ofs, struct dentry *dentry, + return err; + } + ++static inline ssize_t ovl_getxattr(struct ovl_fs *ofs, struct dentry *dentry, ++ enum ovl_xattr ox, void *value, ++ size_t size) ++{ ++ return ovl_do_getxattr(ofs, dentry, ovl_xattr(ofs, ox), value, size); ++} ++ + static inline int ovl_do_setxattr(struct ovl_fs *ofs, struct dentry *dentry, +- enum ovl_xattr ox, const void *value, +- size_t size) ++ const char *name, const void *value, ++ size_t size, int flags) + { +- const char *name = ovl_xattr(ofs, ox); +- int err = vfs_setxattr(&init_user_ns, dentry, name, value, size, 0); +- pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, 0) = %i\n", +- dentry, name, min((int)size, 48), value, size, err); ++ int err = vfs_setxattr(&init_user_ns, dentry, name, value, size, flags); ++ ++ pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, %d) = %i\n", ++ dentry, name, min((int)size, 48), value, size, flags, err); + return err; + } + ++static inline int ovl_setxattr(struct ovl_fs *ofs, struct dentry *dentry, ++ enum ovl_xattr ox, const void *value, ++ size_t size) ++{ ++ return ovl_do_setxattr(ofs, dentry, ovl_xattr(ofs, ox), value, size, 0); ++} ++ + static inline int ovl_do_removexattr(struct ovl_fs *ofs, struct dentry *dentry, +- enum ovl_xattr ox) ++ const char *name) + { +- const char *name = ovl_xattr(ofs, ox); + int err = vfs_removexattr(&init_user_ns, dentry, name); + pr_debug("removexattr(%pd2, \"%s\") = %i\n", dentry, name, err); + return err; + } + +-static inline int ovl_do_rename(struct inode *olddir, struct dentry *olddentry, +- struct inode *newdir, struct dentry *newdentry, +- unsigned int flags) ++static inline int ovl_removexattr(struct ovl_fs *ofs, struct dentry *dentry, ++ enum ovl_xattr ox) ++{ ++ return ovl_do_removexattr(ofs, dentry, ovl_xattr(ofs, ox)); ++} ++ ++static inline int ovl_do_rename(struct ovl_fs *ofs, struct inode *olddir, ++ struct dentry *olddentry, struct inode *newdir, ++ struct dentry *newdentry, unsigned int flags) + { + int err; + struct renamedata rd = { +@@ -239,14 +263,16 @@ static inline int ovl_do_rename(struct inode *olddir, struct dentry *olddentry, + return err; + } + +-static inline int ovl_do_whiteout(struct inode *dir, struct dentry *dentry) ++static inline int ovl_do_whiteout(struct ovl_fs *ofs, ++ struct inode *dir, struct dentry *dentry) + { + int err = vfs_whiteout(&init_user_ns, dir, dentry); + pr_debug("whiteout(%pd2) = %i\n", dentry, err); + return err; + } + +-static inline struct dentry *ovl_do_tmpfile(struct dentry *dentry, umode_t mode) ++static inline struct dentry *ovl_do_tmpfile(struct ovl_fs *ofs, ++ struct dentry *dentry, umode_t mode) + { + struct dentry *ret = vfs_tmpfile(&init_user_ns, dentry, mode, 0); + int err = PTR_ERR_OR_ZERO(ret); +@@ -465,12 +491,13 @@ static inline int ovl_verify_upper(struct ovl_fs *ofs, struct dentry *index, + extern const struct file_operations ovl_dir_operations; + struct file *ovl_dir_real_file(const struct file *file, bool want_upper); + int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list); +-void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list); ++void ovl_cleanup_whiteouts(struct ovl_fs *ofs, struct dentry *upper, ++ struct list_head *list); + void ovl_cache_free(struct list_head *list); + void ovl_dir_cache_free(struct inode *inode); + int ovl_check_d_type_supported(struct path *realpath); +-int ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt, +- struct dentry *dentry, int level); ++int ovl_workdir_cleanup(struct ovl_fs *ofs, struct inode *dir, ++ struct vfsmount *mnt, struct dentry *dentry, int level); + int ovl_indexdir_cleanup(struct ovl_fs *ofs); + + /* +@@ -565,12 +592,15 @@ struct ovl_cattr { + + #define OVL_CATTR(m) (&(struct ovl_cattr) { .mode = (m) }) + +-int ovl_mkdir_real(struct inode *dir, struct dentry **newdentry, umode_t mode); +-struct dentry *ovl_create_real(struct inode *dir, struct dentry *newdentry, ++int ovl_mkdir_real(struct ovl_fs *ofs, struct inode *dir, ++ struct dentry **newdentry, umode_t mode); ++struct dentry *ovl_create_real(struct ovl_fs *ofs, ++ struct inode *dir, struct dentry *newdentry, ++ struct ovl_cattr *attr); ++int ovl_cleanup(struct ovl_fs *ofs, struct inode *dir, struct dentry *dentry); ++struct dentry *ovl_lookup_temp(struct ovl_fs *ofs, struct dentry *workdir); ++struct dentry *ovl_create_temp(struct ovl_fs *ofs, struct dentry *workdir, + struct ovl_cattr *attr); +-int ovl_cleanup(struct inode *dir, struct dentry *dentry); +-struct dentry *ovl_lookup_temp(struct dentry *workdir); +-struct dentry *ovl_create_temp(struct dentry *workdir, struct ovl_cattr *attr); + + /* file.c */ + extern const struct file_operations ovl_file_operations; +diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c +index 150fdf3bc68d4c..9c580ef8cd6fcf 100644 +--- a/fs/overlayfs/readdir.c ++++ b/fs/overlayfs/readdir.c +@@ -623,8 +623,8 @@ static struct ovl_dir_cache *ovl_cache_get_impure(struct path *path) + * Removing the "impure" xattr is best effort. + */ + if (!ovl_want_write(dentry)) { +- ovl_do_removexattr(ofs, ovl_dentry_upper(dentry), +- OVL_XATTR_IMPURE); ++ ovl_removexattr(ofs, ovl_dentry_upper(dentry), ++ OVL_XATTR_IMPURE); + ovl_drop_write(dentry); + } + ovl_clear_flag(OVL_IMPURE, d_inode(dentry)); +@@ -1001,7 +1001,8 @@ int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) + return err; + } + +-void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list) ++void ovl_cleanup_whiteouts(struct ovl_fs *ofs, struct dentry *upper, ++ struct list_head *list) + { + struct ovl_cache_entry *p; + +@@ -1020,7 +1021,7 @@ void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list) + continue; + } + if (dentry->d_inode) +- ovl_cleanup(upper->d_inode, dentry); ++ ovl_cleanup(ofs, upper->d_inode, dentry); + dput(dentry); + } + inode_unlock(upper->d_inode); +@@ -1064,7 +1065,8 @@ int ovl_check_d_type_supported(struct path *realpath) + + #define OVL_INCOMPATDIR_NAME "incompat" + +-static int ovl_workdir_cleanup_recurse(struct path *path, int level) ++static int ovl_workdir_cleanup_recurse(struct ovl_fs *ofs, struct path *path, ++ int level) + { + int err; + struct inode *dir = path->dentry->d_inode; +@@ -1115,7 +1117,7 @@ static int ovl_workdir_cleanup_recurse(struct path *path, int level) + if (IS_ERR(dentry)) + continue; + if (dentry->d_inode) +- err = ovl_workdir_cleanup(dir, path->mnt, dentry, level); ++ err = ovl_workdir_cleanup(ofs, dir, path->mnt, dentry, level); + dput(dentry); + if (err) + break; +@@ -1126,24 +1128,24 @@ static int ovl_workdir_cleanup_recurse(struct path *path, int level) + return err; + } + +-int ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt, +- struct dentry *dentry, int level) ++int ovl_workdir_cleanup(struct ovl_fs *ofs, struct inode *dir, ++ struct vfsmount *mnt, struct dentry *dentry, int level) + { + int err; + + if (!d_is_dir(dentry) || level > 1) { +- return ovl_cleanup(dir, dentry); ++ return ovl_cleanup(ofs, dir, dentry); + } + +- err = ovl_do_rmdir(dir, dentry); ++ err = ovl_do_rmdir(ofs, dir, dentry); + if (err) { + struct path path = { .mnt = mnt, .dentry = dentry }; + + inode_unlock(dir); +- err = ovl_workdir_cleanup_recurse(&path, level + 1); ++ err = ovl_workdir_cleanup_recurse(ofs, &path, level + 1); + inode_lock_nested(dir, I_MUTEX_PARENT); + if (!err) +- err = ovl_cleanup(dir, dentry); ++ err = ovl_cleanup(ofs, dir, dentry); + } + + return err; +@@ -1187,7 +1189,7 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs) + } + /* Cleanup leftover from index create/cleanup attempt */ + if (index->d_name.name[0] == '#') { +- err = ovl_workdir_cleanup(dir, path.mnt, index, 1); ++ err = ovl_workdir_cleanup(ofs, dir, path.mnt, index, 1); + if (err) + break; + goto next; +@@ -1197,7 +1199,7 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs) + goto next; + } else if (err == -ESTALE) { + /* Cleanup stale index entries */ +- err = ovl_cleanup(dir, index); ++ err = ovl_cleanup(ofs, dir, index); + } else if (err != -ENOENT) { + /* + * Abort mount to avoid corrupting the index if +@@ -1213,7 +1215,7 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs) + err = ovl_cleanup_and_whiteout(ofs, dir, index); + } else { + /* Cleanup orphan index entries */ +- err = ovl_cleanup(dir, index); ++ err = ovl_cleanup(ofs, dir, index); + } + + if (err) +diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c +index 5310271cf2e38c..2ad1f8652ce610 100644 +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -784,7 +784,7 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs, + goto out_unlock; + + retried = true; +- err = ovl_workdir_cleanup(dir, mnt, work, 0); ++ err = ovl_workdir_cleanup(ofs, dir, mnt, work, 0); + dput(work); + if (err == -EINVAL) { + work = ERR_PTR(err); +@@ -793,7 +793,7 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs, + goto retry; + } + +- err = ovl_mkdir_real(dir, &work, attr.ia_mode); ++ err = ovl_mkdir_real(ofs, dir, &work, attr.ia_mode); + if (err) + goto out_dput; + +@@ -815,13 +815,13 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs, + * allowed as upper are limited to "normal" ones, where checking + * for the above two errors is sufficient. + */ +- err = vfs_removexattr(&init_user_ns, work, +- XATTR_NAME_POSIX_ACL_DEFAULT); ++ err = ovl_do_removexattr(ofs, work, ++ XATTR_NAME_POSIX_ACL_DEFAULT); + if (err && err != -ENODATA && err != -EOPNOTSUPP) + goto out_dput; + +- err = vfs_removexattr(&init_user_ns, work, +- XATTR_NAME_POSIX_ACL_ACCESS); ++ err = ovl_do_removexattr(ofs, work, ++ XATTR_NAME_POSIX_ACL_ACCESS); + if (err && err != -ENODATA && err != -EOPNOTSUPP) + goto out_dput; + +@@ -1262,8 +1262,9 @@ static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs, + * Returns 1 if RENAME_WHITEOUT is supported, 0 if not supported and + * negative values if error is encountered. + */ +-static int ovl_check_rename_whiteout(struct dentry *workdir) ++static int ovl_check_rename_whiteout(struct ovl_fs *ofs) + { ++ struct dentry *workdir = ofs->workdir; + struct inode *dir = d_inode(workdir); + struct dentry *temp; + struct dentry *dest; +@@ -1273,12 +1274,12 @@ static int ovl_check_rename_whiteout(struct dentry *workdir) + + inode_lock_nested(dir, I_MUTEX_PARENT); + +- temp = ovl_create_temp(workdir, OVL_CATTR(S_IFREG | 0)); ++ temp = ovl_create_temp(ofs, workdir, OVL_CATTR(S_IFREG | 0)); + err = PTR_ERR(temp); + if (IS_ERR(temp)) + goto out_unlock; + +- dest = ovl_lookup_temp(workdir); ++ dest = ovl_lookup_temp(ofs, workdir); + err = PTR_ERR(dest); + if (IS_ERR(dest)) { + dput(temp); +@@ -1287,7 +1288,7 @@ static int ovl_check_rename_whiteout(struct dentry *workdir) + + /* Name is inline and stable - using snapshot as a copy helper */ + take_dentry_name_snapshot(&name, temp); +- err = ovl_do_rename(dir, temp, dir, dest, RENAME_WHITEOUT); ++ err = ovl_do_rename(ofs, dir, temp, dir, dest, RENAME_WHITEOUT); + if (err) { + if (err == -EINVAL) + err = 0; +@@ -1303,11 +1304,11 @@ static int ovl_check_rename_whiteout(struct dentry *workdir) + + /* Best effort cleanup of whiteout and temp file */ + if (err) +- ovl_cleanup(dir, whiteout); ++ ovl_cleanup(ofs, dir, whiteout); + dput(whiteout); + + cleanup_temp: +- ovl_cleanup(dir, temp); ++ ovl_cleanup(ofs, dir, temp); + release_dentry_name_snapshot(&name); + dput(temp); + dput(dest); +@@ -1318,7 +1319,8 @@ static int ovl_check_rename_whiteout(struct dentry *workdir) + return err; + } + +-static struct dentry *ovl_lookup_or_create(struct dentry *parent, ++static struct dentry *ovl_lookup_or_create(struct ovl_fs *ofs, ++ struct dentry *parent, + const char *name, umode_t mode) + { + size_t len = strlen(name); +@@ -1327,7 +1329,7 @@ static struct dentry *ovl_lookup_or_create(struct dentry *parent, + inode_lock_nested(parent->d_inode, I_MUTEX_PARENT); + child = lookup_one_len(name, parent, len); + if (!IS_ERR(child) && !child->d_inode) +- child = ovl_create_real(parent->d_inode, child, ++ child = ovl_create_real(ofs, parent->d_inode, child, + OVL_CATTR(mode)); + inode_unlock(parent->d_inode); + dput(parent); +@@ -1349,7 +1351,7 @@ static int ovl_create_volatile_dirty(struct ovl_fs *ofs) + const char *const *name = volatile_path; + + for (ctr = ARRAY_SIZE(volatile_path); ctr; ctr--, name++) { +- d = ovl_lookup_or_create(d, *name, ctr > 1 ? S_IFDIR : S_IFREG); ++ d = ovl_lookup_or_create(ofs, d, *name, ctr > 1 ? S_IFDIR : S_IFREG); + if (IS_ERR(d)) + return PTR_ERR(d); + } +@@ -1397,7 +1399,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs, + pr_warn("upper fs needs to support d_type.\n"); + + /* Check if upper/work fs supports O_TMPFILE */ +- temp = ovl_do_tmpfile(ofs->workdir, S_IFREG | 0); ++ temp = ovl_do_tmpfile(ofs, ofs->workdir, S_IFREG | 0); + ofs->tmpfile = !IS_ERR(temp); + if (ofs->tmpfile) + dput(temp); +@@ -1406,7 +1408,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs, + + + /* Check if upper/work fs supports RENAME_WHITEOUT */ +- err = ovl_check_rename_whiteout(ofs->workdir); ++ err = ovl_check_rename_whiteout(ofs); + if (err < 0) + goto out; + +@@ -1417,7 +1419,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs, + /* + * Check if upper/work fs supports (trusted|user).overlay.* xattr + */ +- err = ovl_do_setxattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE, "0", 1); ++ err = ovl_setxattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE, "0", 1); + if (err) { + pr_warn("failed to set xattr on upper\n"); + ofs->noxattr = true; +@@ -1438,7 +1440,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs, + pr_info("try mounting with 'userxattr' option\n"); + err = 0; + } else { +- ovl_do_removexattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE); ++ ovl_removexattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE); + } + + /* +diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c +index 747b47048b3aa8..8a9980ab2ad8fe 100644 +--- a/fs/overlayfs/util.c ++++ b/fs/overlayfs/util.c +@@ -586,7 +586,7 @@ bool ovl_check_origin_xattr(struct ovl_fs *ofs, struct dentry *dentry) + { + int res; + +- res = ovl_do_getxattr(ofs, dentry, OVL_XATTR_ORIGIN, NULL, 0); ++ res = ovl_getxattr(ofs, dentry, OVL_XATTR_ORIGIN, NULL, 0); + + /* Zero size value means "copied up but origin unknown" */ + if (res >= 0) +@@ -604,7 +604,7 @@ bool ovl_check_dir_xattr(struct super_block *sb, struct dentry *dentry, + if (!d_is_dir(dentry)) + return false; + +- res = ovl_do_getxattr(OVL_FS(sb), dentry, ox, &val, 1); ++ res = ovl_getxattr(OVL_FS(sb), dentry, ox, &val, 1); + if (res == 1 && val == 'y') + return true; + +@@ -644,7 +644,7 @@ int ovl_check_setxattr(struct ovl_fs *ofs, struct dentry *upperdentry, + if (ofs->noxattr) + return xerr; + +- err = ovl_do_setxattr(ofs, upperdentry, ox, value, size); ++ err = ovl_setxattr(ofs, upperdentry, ox, value, size); + + if (err == -EOPNOTSUPP) { + pr_warn("cannot set %s xattr on upper\n", ovl_xattr(ofs, ox)); +@@ -684,7 +684,7 @@ void ovl_check_protattr(struct inode *inode, struct dentry *upper) + char buf[OVL_PROTATTR_MAX+1]; + int res, n; + +- res = ovl_do_getxattr(ofs, upper, OVL_XATTR_PROTATTR, buf, ++ res = ovl_getxattr(ofs, upper, OVL_XATTR_PROTATTR, buf, + OVL_PROTATTR_MAX); + if (res < 0) + return; +@@ -740,7 +740,7 @@ int ovl_set_protattr(struct inode *inode, struct dentry *upper, + err = ovl_check_setxattr(ofs, upper, OVL_XATTR_PROTATTR, + buf, len, -EPERM); + } else if (inode->i_flags & OVL_PROT_I_FLAGS_MASK) { +- err = ovl_do_removexattr(ofs, upper, OVL_XATTR_PROTATTR); ++ err = ovl_removexattr(ofs, upper, OVL_XATTR_PROTATTR); + if (err == -EOPNOTSUPP || err == -ENODATA) + err = 0; + } +@@ -866,7 +866,7 @@ static void ovl_cleanup_index(struct dentry *dentry) + dir, index); + } else { + /* Cleanup orphan index entries */ +- err = ovl_cleanup(dir, index); ++ err = ovl_cleanup(ofs, dir, index); + } + + inode_unlock(dir); +@@ -983,7 +983,7 @@ int ovl_check_metacopy_xattr(struct ovl_fs *ofs, struct dentry *dentry) + if (!S_ISREG(d_inode(dentry)->i_mode)) + return 0; + +- res = ovl_do_getxattr(ofs, dentry, OVL_XATTR_METACOPY, NULL, 0); ++ res = ovl_getxattr(ofs, dentry, OVL_XATTR_METACOPY, NULL, 0); + if (res < 0) { + if (res == -ENODATA || res == -EOPNOTSUPP) + return 0; +@@ -1025,7 +1025,7 @@ char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct dentry *dentry, + int res; + char *s, *next, *buf = NULL; + +- res = ovl_do_getxattr(ofs, dentry, OVL_XATTR_REDIRECT, NULL, 0); ++ res = ovl_getxattr(ofs, dentry, OVL_XATTR_REDIRECT, NULL, 0); + if (res == -ENODATA || res == -EOPNOTSUPP) + return NULL; + if (res < 0) +@@ -1037,7 +1037,7 @@ char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct dentry *dentry, + if (!buf) + return ERR_PTR(-ENOMEM); + +- res = ovl_do_getxattr(ofs, dentry, OVL_XATTR_REDIRECT, buf, res); ++ res = ovl_getxattr(ofs, dentry, OVL_XATTR_REDIRECT, buf, res); + if (res < 0) + goto fail; + if (res == 0) +diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c +index 213ea008fe2db6..7c5d472b193f88 100644 +--- a/fs/proc/proc_sysctl.c ++++ b/fs/proc/proc_sysctl.c +@@ -29,6 +29,9 @@ static const struct inode_operations proc_sys_dir_operations; + const int sysctl_vals[] = { -1, 0, 1, 2, 4, 100, 200, 1000, 3000, INT_MAX }; + EXPORT_SYMBOL(sysctl_vals); + ++const unsigned long sysctl_long_vals[] = { 0, 1, LONG_MAX }; ++EXPORT_SYMBOL_GPL(sysctl_long_vals); ++ + /* Support for permanently empty directories */ + + struct ctl_table sysctl_mount_point[] = { +diff --git a/fs/pstore/blk.c b/fs/pstore/blk.c +index 6093088de49fd1..cb5fe2f28c708a 100644 +--- a/fs/pstore/blk.c ++++ b/fs/pstore/blk.c +@@ -89,7 +89,7 @@ static struct pstore_device_info *pstore_device_info; + _##name_ = check_size(name, alignsize); \ + else \ + _##name_ = 0; \ +- /* Synchronize module parameters with resuls. */ \ ++ /* Synchronize module parameters with results. */ \ + name = _##name_ / 1024; \ + dev->zone.name = _##name_; \ + } +@@ -121,7 +121,7 @@ static int __register_pstore_device(struct pstore_device_info *dev) + if (pstore_device_info) + return -EBUSY; + +- /* zero means not limit on which backends to attempt to store. */ ++ /* zero means no limit on which backends attempt to store. */ + if (!dev->flags) + dev->flags = UINT_MAX; + +diff --git a/fs/select.c b/fs/select.c +index 668a5200503aec..7ce67428582e6d 100644 +--- a/fs/select.c ++++ b/fs/select.c +@@ -787,7 +787,7 @@ static inline int get_sigset_argpack(struct sigset_argpack *to, + } + return 0; + Efault: +- user_access_end(); ++ user_read_access_end(); + return -EFAULT; + } + +@@ -1360,7 +1360,7 @@ static inline int get_compat_sigset_argpack(struct compat_sigset_argpack *to, + } + return 0; + Efault: +- user_access_end(); ++ user_read_access_end(); + return -EFAULT; + } + +diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c +index f31649080a881c..95a9ff9e239975 100644 +--- a/fs/squashfs/inode.c ++++ b/fs/squashfs/inode.c +@@ -48,6 +48,10 @@ static int squashfs_new_inode(struct super_block *sb, struct inode *inode, + gid_t i_gid; + int err; + ++ inode->i_ino = le32_to_cpu(sqsh_ino->inode_number); ++ if (inode->i_ino == 0) ++ return -EINVAL; ++ + err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->uid), &i_uid); + if (err) + return err; +@@ -58,7 +62,6 @@ static int squashfs_new_inode(struct super_block *sb, struct inode *inode, + + i_uid_write(inode, i_uid); + i_gid_write(inode, i_gid); +- inode->i_ino = le32_to_cpu(sqsh_ino->inode_number); + inode->i_mtime.tv_sec = le32_to_cpu(sqsh_ino->mtime); + inode->i_atime.tv_sec = inode->i_mtime.tv_sec; + inode->i_ctime.tv_sec = inode->i_mtime.tv_sec; +diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c +index fc718f6178f255..8386228131a297 100644 +--- a/fs/ubifs/debug.c ++++ b/fs/ubifs/debug.c +@@ -946,16 +946,20 @@ void ubifs_dump_tnc(struct ubifs_info *c) + + pr_err("\n"); + pr_err("(pid %d) start dumping TNC tree\n", current->pid); +- znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, NULL); +- level = znode->level; +- pr_err("== Level %d ==\n", level); +- while (znode) { +- if (level != znode->level) { +- level = znode->level; +- pr_err("== Level %d ==\n", level); ++ if (c->zroot.znode) { ++ znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, NULL); ++ level = znode->level; ++ pr_err("== Level %d ==\n", level); ++ while (znode) { ++ if (level != znode->level) { ++ level = znode->level; ++ pr_err("== Level %d ==\n", level); ++ } ++ ubifs_dump_znode(c, znode); ++ znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, znode); + } +- ubifs_dump_znode(c, znode); +- znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, znode); ++ } else { ++ pr_err("empty TNC tree in memory\n"); + } + pr_err("(pid %d) finish dumping TNC tree\n", current->pid); + } +diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c +index df64b902842ddd..3b36d5569d15d4 100644 +--- a/fs/xfs/xfs_inode.c ++++ b/fs/xfs/xfs_inode.c +@@ -1748,8 +1748,11 @@ xfs_inactive( + goto out; + + /* Try to clean out the cow blocks if there are any. */ +- if (xfs_inode_has_cow_data(ip)) +- xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF, true); ++ if (xfs_inode_has_cow_data(ip)) { ++ error = xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF, true); ++ if (error) ++ goto out; ++ } + + if (VFS_I(ip)->i_nlink != 0) { + /* +diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c +index b77673dd05581e..26b2c449f3c665 100644 +--- a/fs/xfs/xfs_qm_bhv.c ++++ b/fs/xfs/xfs_qm_bhv.c +@@ -19,28 +19,41 @@ + STATIC void + xfs_fill_statvfs_from_dquot( + struct kstatfs *statp, ++ struct xfs_inode *ip, + struct xfs_dquot *dqp) + { ++ struct xfs_dquot_res *blkres = &dqp->q_blk; + uint64_t limit; + +- limit = dqp->q_blk.softlimit ? +- dqp->q_blk.softlimit : +- dqp->q_blk.hardlimit; +- if (limit && statp->f_blocks > limit) { +- statp->f_blocks = limit; +- statp->f_bfree = statp->f_bavail = +- (statp->f_blocks > dqp->q_blk.reserved) ? +- (statp->f_blocks - dqp->q_blk.reserved) : 0; ++ if (XFS_IS_REALTIME_MOUNT(ip->i_mount) && ++ (ip->i_diflags & (XFS_DIFLAG_RTINHERIT | XFS_DIFLAG_REALTIME))) ++ blkres = &dqp->q_rtb; ++ ++ limit = blkres->softlimit ? ++ blkres->softlimit : ++ blkres->hardlimit; ++ if (limit) { ++ uint64_t remaining = 0; ++ ++ if (limit > blkres->reserved) ++ remaining = limit - blkres->reserved; ++ ++ statp->f_blocks = min(statp->f_blocks, limit); ++ statp->f_bfree = min(statp->f_bfree, remaining); ++ statp->f_bavail = min(statp->f_bavail, remaining); + } + + limit = dqp->q_ino.softlimit ? + dqp->q_ino.softlimit : + dqp->q_ino.hardlimit; +- if (limit && statp->f_files > limit) { +- statp->f_files = limit; +- statp->f_ffree = +- (statp->f_files > dqp->q_ino.reserved) ? +- (statp->f_files - dqp->q_ino.reserved) : 0; ++ if (limit) { ++ uint64_t remaining = 0; ++ ++ if (limit > dqp->q_ino.reserved) ++ remaining = limit - dqp->q_ino.reserved; ++ ++ statp->f_files = min(statp->f_files, limit); ++ statp->f_ffree = min(statp->f_ffree, remaining); + } + } + +@@ -61,7 +74,7 @@ xfs_qm_statvfs( + struct xfs_dquot *dqp; + + if (!xfs_qm_dqget(mp, ip->i_projid, XFS_DQTYPE_PROJ, false, &dqp)) { +- xfs_fill_statvfs_from_dquot(statp, dqp); ++ xfs_fill_statvfs_from_dquot(statp, ip, dqp); + xfs_qm_dqput(dqp); + } + } +diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c +index f4c25b07dc99d3..e48455e2b5f2fc 100644 +--- a/fs/xfs/xfs_super.c ++++ b/fs/xfs/xfs_super.c +@@ -837,12 +837,6 @@ xfs_fs_statfs( + ffree = statp->f_files - (icount - ifree); + statp->f_ffree = max_t(int64_t, ffree, 0); + +- +- if ((ip->i_diflags & XFS_DIFLAG_PROJINHERIT) && +- ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) == +- (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD)) +- xfs_qm_statvfs(ip, statp); +- + if (XFS_IS_REALTIME_MOUNT(mp) && + (ip->i_diflags & (XFS_DIFLAG_RTINHERIT | XFS_DIFLAG_REALTIME))) { + statp->f_blocks = sbp->sb_rblocks; +@@ -850,6 +844,11 @@ xfs_fs_statfs( + sbp->sb_frextents * sbp->sb_rextsize; + } + ++ if ((ip->i_diflags & XFS_DIFLAG_PROJINHERIT) && ++ ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) == ++ (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD)) ++ xfs_qm_statvfs(ip, statp); ++ + return 0; + } + +diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h +index 4132a76a3e2e40..57a504919e1f3e 100644 +--- a/include/asm-generic/vmlinux.lds.h ++++ b/include/asm-generic/vmlinux.lds.h +@@ -429,7 +429,7 @@ + . = ALIGN((align)); \ + .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \ + __start_rodata = .; \ +- *(.rodata) *(.rodata.*) \ ++ *(.rodata) *(.rodata.*) *(.data.rel.ro*) \ + SCHED_DATA \ + RO_AFTER_INIT_DATA /* Read only after init */ \ + . = ALIGN(8); \ +diff --git a/include/drm/drm_probe_helper.h b/include/drm/drm_probe_helper.h +index 8d3ed2834d345e..04c57564c397d0 100644 +--- a/include/drm/drm_probe_helper.h ++++ b/include/drm/drm_probe_helper.h +@@ -18,6 +18,7 @@ int drm_helper_probe_detect(struct drm_connector *connector, + void drm_kms_helper_poll_init(struct drm_device *dev); + void drm_kms_helper_poll_fini(struct drm_device *dev); + bool drm_helper_hpd_irq_event(struct drm_device *dev); ++bool drm_connector_helper_hpd_irq_event(struct drm_connector *connector); + void drm_kms_helper_hotplug_event(struct drm_device *dev); + + void drm_kms_helper_poll_disable(struct drm_device *dev); +diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h +index 45333fcf5082a7..e60fbdde9308bb 100644 +--- a/include/linux/cgroup-defs.h ++++ b/include/linux/cgroup-defs.h +@@ -71,9 +71,6 @@ enum { + + /* Cgroup is frozen. */ + CGRP_FROZEN, +- +- /* Control group has to be killed. */ +- CGRP_KILL, + }; + + /* cgroup_root->flags */ +@@ -407,6 +404,9 @@ struct cgroup { + + int nr_threaded_children; /* # of live threaded child cgroups */ + ++ /* sequence number for cgroup.kill, serialized by css_set_lock. */ ++ unsigned int kill_seq; ++ + struct kernfs_node *kn; /* cgroup kernfs entry */ + struct cgroup_file procs_file; /* handle for "cgroup.procs" */ + struct cgroup_file events_file; /* handle for "cgroup.events" */ +diff --git a/include/linux/efi.h b/include/linux/efi.h +index 7e396e31e0b775..5d832ff22dc28b 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -125,6 +125,7 @@ typedef struct { + #define EFI_MEMORY_RO ((u64)0x0000000000020000ULL) /* read-only */ + #define EFI_MEMORY_SP ((u64)0x0000000000040000ULL) /* soft reserved */ + #define EFI_MEMORY_CPU_CRYPTO ((u64)0x0000000000080000ULL) /* supports encryption */ ++#define EFI_MEMORY_HOT_PLUGGABLE BIT_ULL(20) /* supports unplugging at runtime */ + #define EFI_MEMORY_RUNTIME ((u64)0x8000000000000000ULL) /* range requires runtime mapping */ + #define EFI_MEMORY_DESCRIPTOR_VERSION 1 + +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 2ef0e48c89ec48..d011dc742e3ef6 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -78,10 +78,8 @@ extern void __init inode_init_early(void); + extern void __init files_init(void); + extern void __init files_maxfiles_init(void); + +-extern struct files_stat_struct files_stat; + extern unsigned long get_max_files(void); + extern unsigned int sysctl_nr_open; +-extern struct inodes_stat_t inodes_stat; + extern int leases_enable, lease_break_time; + extern int sysctl_protected_symlinks; + extern int sysctl_protected_hardlinks; +@@ -3670,12 +3668,8 @@ ssize_t simple_attr_write_signed(struct file *file, const char __user *buf, + size_t len, loff_t *ppos); + + struct ctl_table; +-int proc_nr_files(struct ctl_table *table, int write, +- void *buffer, size_t *lenp, loff_t *ppos); + int proc_nr_dentry(struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos); +-int proc_nr_inodes(struct ctl_table *table, int write, +- void *buffer, size_t *lenp, loff_t *ppos); + int __init list_bdev_fs_names(char *buf, size_t size); + + #define __FMODE_EXEC ((__force int) FMODE_EXEC) +diff --git a/include/linux/i8253.h b/include/linux/i8253.h +index 8336b2f6f83462..bf169cfef7f12d 100644 +--- a/include/linux/i8253.h ++++ b/include/linux/i8253.h +@@ -24,6 +24,7 @@ extern raw_spinlock_t i8253_lock; + extern bool i8253_clear_counter_on_shutdown; + extern struct clock_event_device i8253_clockevent; + extern void clockevent_i8253_init(bool oneshot); ++extern void clockevent_i8253_disable(void); + + extern void setup_pit_timer(void); + +diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h +index eae9f423bd6486..0f73f69e640352 100644 +--- a/include/linux/kallsyms.h ++++ b/include/linux/kallsyms.h +@@ -66,10 +66,10 @@ static inline void *dereference_symbol_descriptor(void *ptr) + + preempt_disable(); + mod = __module_address((unsigned long)ptr); +- preempt_enable(); + + if (mod) + ptr = dereference_module_function_descriptor(mod, ptr); ++ preempt_enable(); + #endif + return ptr; + } +diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h +index 7e2423ffaf593a..956a568c2dc2ad 100644 +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -796,6 +796,15 @@ static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, enum kvm_bus idx) + static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) + { + int num_vcpus = atomic_read(&kvm->online_vcpus); ++ ++ /* ++ * Explicitly verify the target vCPU is online, as the anti-speculation ++ * logic only limits the CPU's ability to speculate, e.g. given a "bad" ++ * index, clamping the index to 0 would return vCPU0, not NULL. ++ */ ++ if (i >= num_vcpus) ++ return NULL; ++ + i = array_index_nospec(i, num_vcpus); + + /* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu. */ +diff --git a/include/linux/memblock.h b/include/linux/memblock.h +index 307cab05d67ec5..41f95cf22cb81e 100644 +--- a/include/linux/memblock.h ++++ b/include/linux/memblock.h +@@ -442,18 +442,6 @@ static inline void *memblock_alloc_node(phys_addr_t size, + MEMBLOCK_ALLOC_ACCESSIBLE, nid); + } + +-static inline void memblock_free_early(phys_addr_t base, +- phys_addr_t size) +-{ +- memblock_free(base, size); +-} +- +-static inline void memblock_free_early_nid(phys_addr_t base, +- phys_addr_t size, int nid) +-{ +- memblock_free(base, size); +-} +- + static inline void memblock_free_late(phys_addr_t base, phys_addr_t size) + { + __memblock_free_late(base, size); +diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h +index 62d60a515b0385..ff47cff408aad4 100644 +--- a/include/linux/mlx5/driver.h ++++ b/include/linux/mlx5/driver.h +@@ -364,7 +364,6 @@ enum { + }; + + struct mlx5_core_mkey { +- u64 iova; + u64 size; + u32 key; + u32 pd; +@@ -686,7 +685,6 @@ struct mlx5_timer { + struct timecounter tc; + u32 nominal_c_mult; + unsigned long overflow_period; +- struct delayed_work overflow_work; + }; + + struct mlx5_clock { +diff --git a/include/linux/mtd/hyperbus.h b/include/linux/mtd/hyperbus.h +index 0ce612428aea27..bb6b7121a5427a 100644 +--- a/include/linux/mtd/hyperbus.h ++++ b/include/linux/mtd/hyperbus.h +@@ -89,9 +89,7 @@ int hyperbus_register_device(struct hyperbus_device *hbdev); + /** + * hyperbus_unregister_device - deregister HyperBus slave memory device + * @hbdev: hyperbus_device to be unregistered +- * +- * Return: 0 for success, others for failure. + */ +-int hyperbus_unregister_device(struct hyperbus_device *hbdev); ++void hyperbus_unregister_device(struct hyperbus_device *hbdev); + + #endif /* __LINUX_MTD_HYPERBUS_H__ */ +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 829ebde5d50d5b..179c569a55c42f 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2454,6 +2454,12 @@ struct net *dev_net(const struct net_device *dev) + return read_pnet(&dev->nd_net); + } + ++static inline ++struct net *dev_net_rcu(const struct net_device *dev) ++{ ++ return read_pnet_rcu(&dev->nd_net); ++} ++ + static inline + void dev_net_set(struct net_device *dev, struct net *net) + { +@@ -2960,6 +2966,8 @@ static inline struct net_device *first_net_device_rcu(struct net *net) + } + + int netdev_boot_setup_check(struct net_device *dev); ++struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, ++ const char *hwaddr); + struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type, + const char *hwaddr); + struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type); +diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h +index d1997eda6b1ad2..c2ddcdb26e5194 100644 +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -1743,6 +1743,10 @@ + #define PCI_SUBDEVICE_ID_AT_2700FX 0x2701 + #define PCI_SUBDEVICE_ID_AT_2701FX 0x2703 + ++#define PCI_VENDOR_ID_ASIX 0x125b ++#define PCI_DEVICE_ID_ASIX_AX99100 0x9100 ++#define PCI_DEVICE_ID_ASIX_AX99100_LB 0x9110 ++ + #define PCI_VENDOR_ID_ESS 0x125d + #define PCI_DEVICE_ID_ESS_ESS1968 0x1968 + #define PCI_DEVICE_ID_ESS_ESS1978 0x1978 +diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h +index 78c8ac4951b581..c7abce28ed2995 100644 +--- a/include/linux/pps_kernel.h ++++ b/include/linux/pps_kernel.h +@@ -56,8 +56,7 @@ struct pps_device { + + unsigned int id; /* PPS source unique ID */ + void const *lookup_cookie; /* For pps_lookup_dev() only */ +- struct cdev cdev; +- struct device *dev; ++ struct device dev; + struct fasync_struct *async_queue; /* fasync method */ + spinlock_t lock; + }; +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 9b3cfe685cb452..5d0a44e4db4b5d 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -874,9 +874,7 @@ struct task_struct { + unsigned sched_reset_on_fork:1; + unsigned sched_contributes_to_load:1; + unsigned sched_migrated:1; +-#ifdef CONFIG_PSI +- unsigned sched_psi_wake_requeue:1; +-#endif ++ unsigned sched_task_hot:1; + + /* Force alignment to the next boundary: */ + unsigned :0; +diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h +index 304f431178fd99..c19dd5a2c05c67 100644 +--- a/include/linux/sched/sysctl.h ++++ b/include/linux/sched/sysctl.h +@@ -7,20 +7,8 @@ + struct ctl_table; + + #ifdef CONFIG_DETECT_HUNG_TASK +- +-#ifdef CONFIG_SMP +-extern unsigned int sysctl_hung_task_all_cpu_backtrace; +-#else +-#define sysctl_hung_task_all_cpu_backtrace 0 +-#endif /* CONFIG_SMP */ +- +-extern int sysctl_hung_task_check_count; +-extern unsigned int sysctl_hung_task_panic; ++/* used for hung_task and block/ */ + extern unsigned long sysctl_hung_task_timeout_secs; +-extern unsigned long sysctl_hung_task_check_interval_secs; +-extern int sysctl_hung_task_warnings; +-int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, +- void *buffer, size_t *lenp, loff_t *ppos); + #else + /* Avoid need for ifdefs elsewhere in the code */ + enum { sysctl_hung_task_timeout_secs = 0 }; +diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h +index 0c2d008099151a..f254a7d851fe1f 100644 +--- a/include/linux/sched/task.h ++++ b/include/linux/sched/task.h +@@ -34,6 +34,7 @@ struct kernel_clone_args { + int io_thread; + struct cgroup *cgrp; + struct css_set *cset; ++ unsigned int kill_seq; + }; + + /* +diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h +index 32d79ef906e511..3fa5e2713aace2 100644 +--- a/include/linux/sysctl.h ++++ b/include/linux/sysctl.h +@@ -51,6 +51,12 @@ struct ctl_dir; + + extern const int sysctl_vals[]; + ++#define SYSCTL_LONG_ZERO ((void *)&sysctl_long_vals[0]) ++#define SYSCTL_LONG_ONE ((void *)&sysctl_long_vals[1]) ++#define SYSCTL_LONG_MAX ((void *)&sysctl_long_vals[2]) ++ ++extern const unsigned long sysctl_long_vals[]; ++ + typedef int proc_handler(struct ctl_table *ctl, int write, void *buffer, + size_t *lenp, loff_t *ppos); + +diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h +index aa43ef8a7aa34d..a0f092b3fb66c6 100644 +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -385,8 +385,9 @@ struct hc_driver { + * or bandwidth constraints. + */ + void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *); +- /* Returns the hardware-chosen device address */ +- int (*address_device)(struct usb_hcd *, struct usb_device *udev); ++ /* Set the hardware-chosen device address */ ++ int (*address_device)(struct usb_hcd *, struct usb_device *udev, ++ unsigned int timeout_ms); + /* prepares the hardware to send commands to the device */ + int (*enable_device)(struct usb_hcd *, struct usb_device *udev); + /* Notifies the HCD after a hub descriptor is fetched. +diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h +index bffc8d3e14ad64..0af213187e9fc7 100644 +--- a/include/linux/usb/tcpm.h ++++ b/include/linux/usb/tcpm.h +@@ -145,7 +145,8 @@ struct tcpc_dev { + void (*frs_sourcing_vbus)(struct tcpc_dev *dev); + int (*enable_auto_vbus_discharge)(struct tcpc_dev *dev, bool enable); + int (*set_auto_vbus_discharge_threshold)(struct tcpc_dev *dev, enum typec_pwr_opmode mode, +- bool pps_active, u32 requested_vbus_voltage); ++ bool pps_active, u32 requested_vbus_voltage, ++ u32 pps_apdo_min_voltage); + bool (*is_vbus_vsafe0v)(struct tcpc_dev *dev); + void (*set_partner_usb_comm_capable)(struct tcpc_dev *dev, bool enable); + }; +diff --git a/include/net/dst.h b/include/net/dst.h +index 827f99d577331a..bf0a9b0cc269cd 100644 +--- a/include/net/dst.h ++++ b/include/net/dst.h +@@ -433,6 +433,15 @@ static inline void dst_set_expires(struct dst_entry *dst, int timeout) + dst->expires = expires; + } + ++static inline unsigned int dst_dev_overhead(struct dst_entry *dst, ++ struct sk_buff *skb) ++{ ++ if (likely(dst)) ++ return LL_RESERVED_SPACE(dst->dev); ++ ++ return skb->mac_len; ++} ++ + INDIRECT_CALLABLE_DECLARE(int ip6_output(struct net *, struct sock *, + struct sk_buff *)); + INDIRECT_CALLABLE_DECLARE(int ip_output(struct net *, struct sock *, +diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h +index c8d1c5e187e4b8..8d0d0cf93a785a 100644 +--- a/include/net/flow_dissector.h ++++ b/include/net/flow_dissector.h +@@ -178,6 +178,22 @@ struct flow_dissector_key_ports { + }; + }; + ++/** ++ * struct flow_dissector_key_ports_range ++ * @tp: port number from packet ++ * @tp_min: min port number in range ++ * @tp_max: max port number in range ++ */ ++struct flow_dissector_key_ports_range { ++ union { ++ struct flow_dissector_key_ports tp; ++ struct { ++ struct flow_dissector_key_ports tp_min; ++ struct flow_dissector_key_ports tp_max; ++ }; ++ }; ++}; ++ + /** + * flow_dissector_key_icmp: + * type: ICMP type +diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h +index 7a2b0223a02c74..41f8dcd3505c12 100644 +--- a/include/net/flow_offload.h ++++ b/include/net/flow_offload.h +@@ -48,6 +48,10 @@ struct flow_match_ports { + struct flow_dissector_key_ports *key, *mask; + }; + ++struct flow_match_ports_range { ++ struct flow_dissector_key_ports_range *key, *mask; ++}; ++ + struct flow_match_icmp { + struct flow_dissector_key_icmp *key, *mask; + }; +@@ -94,6 +98,8 @@ void flow_rule_match_ip(const struct flow_rule *rule, + struct flow_match_ip *out); + void flow_rule_match_ports(const struct flow_rule *rule, + struct flow_match_ports *out); ++void flow_rule_match_ports_range(const struct flow_rule *rule, ++ struct flow_match_ports_range *out); + void flow_rule_match_tcp(const struct flow_rule *rule, + struct flow_match_tcp *out); + void flow_rule_match_icmp(const struct flow_rule *rule, +diff --git a/include/net/l3mdev.h b/include/net/l3mdev.h +index 031c661aa14df7..bdfa9d414360c7 100644 +--- a/include/net/l3mdev.h ++++ b/include/net/l3mdev.h +@@ -198,10 +198,12 @@ struct sk_buff *l3mdev_l3_out(struct sock *sk, struct sk_buff *skb, u16 proto) + if (netif_is_l3_slave(dev)) { + struct net_device *master; + ++ rcu_read_lock(); + master = netdev_master_upper_dev_get_rcu(dev); + if (master && master->l3mdev_ops->l3mdev_l3_out) + skb = master->l3mdev_ops->l3mdev_l3_out(master, sk, + skb, proto); ++ rcu_read_unlock(); + } + + return skb; +diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h +index d184b832166b64..ff9ecc76d622b5 100644 +--- a/include/net/net_namespace.h ++++ b/include/net/net_namespace.h +@@ -316,21 +316,30 @@ static inline int check_net(const struct net *net) + + typedef struct { + #ifdef CONFIG_NET_NS +- struct net *net; ++ struct net __rcu *net; + #endif + } possible_net_t; + + static inline void write_pnet(possible_net_t *pnet, struct net *net) + { + #ifdef CONFIG_NET_NS +- pnet->net = net; ++ rcu_assign_pointer(pnet->net, net); + #endif + } + + static inline struct net *read_pnet(const possible_net_t *pnet) + { + #ifdef CONFIG_NET_NS +- return pnet->net; ++ return rcu_dereference_protected(pnet->net, true); ++#else ++ return &init_net; ++#endif ++} ++ ++static inline struct net *read_pnet_rcu(const possible_net_t *pnet) ++{ ++#ifdef CONFIG_NET_NS ++ return rcu_dereference(pnet->net); + #else + return &init_net; + #endif +diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h +index d60a10cfc38237..8bc0d865338e4f 100644 +--- a/include/net/netns/ipv4.h ++++ b/include/net/netns/ipv4.h +@@ -84,6 +84,9 @@ struct netns_ipv4 { + int sysctl_icmp_ratelimit; + int sysctl_icmp_ratemask; + ++ u32 ip_rt_min_pmtu; ++ int ip_rt_mtu_expires; ++ + struct local_ports ip_local_ports; + + u8 sysctl_tcp_ecn; +diff --git a/include/net/route.h b/include/net/route.h +index 30610101ea14ff..036e3ee3b856b5 100644 +--- a/include/net/route.h ++++ b/include/net/route.h +@@ -357,10 +357,15 @@ static inline int inet_iif(const struct sk_buff *skb) + static inline int ip4_dst_hoplimit(const struct dst_entry *dst) + { + int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); +- struct net *net = dev_net(dst->dev); + +- if (hoplimit == 0) ++ if (hoplimit == 0) { ++ const struct net *net; ++ ++ rcu_read_lock(); ++ net = dev_net_rcu(dst->dev); + hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl); ++ rcu_read_unlock(); ++ } + return hoplimit; + } + +diff --git a/include/trace/events/oom.h b/include/trace/events/oom.h +index 26a11e4a2c361d..b799f3bcba8233 100644 +--- a/include/trace/events/oom.h ++++ b/include/trace/events/oom.h +@@ -7,6 +7,8 @@ + #include + #include + ++#define PG_COUNT_TO_KB(x) ((x) << (PAGE_SHIFT - 10)) ++ + TRACE_EVENT(oom_score_adj_update, + + TP_PROTO(struct task_struct *task), +@@ -72,19 +74,45 @@ TRACE_EVENT(reclaim_retry_zone, + ); + + TRACE_EVENT(mark_victim, +- TP_PROTO(int pid), ++ TP_PROTO(struct task_struct *task, uid_t uid), + +- TP_ARGS(pid), ++ TP_ARGS(task, uid), + + TP_STRUCT__entry( + __field(int, pid) ++ __string(comm, task->comm) ++ __field(unsigned long, total_vm) ++ __field(unsigned long, anon_rss) ++ __field(unsigned long, file_rss) ++ __field(unsigned long, shmem_rss) ++ __field(uid_t, uid) ++ __field(unsigned long, pgtables) ++ __field(short, oom_score_adj) + ), + + TP_fast_assign( +- __entry->pid = pid; ++ __entry->pid = task->pid; ++ __assign_str(comm, task->comm); ++ __entry->total_vm = PG_COUNT_TO_KB(task->mm->total_vm); ++ __entry->anon_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_ANONPAGES)); ++ __entry->file_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_FILEPAGES)); ++ __entry->shmem_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_SHMEMPAGES)); ++ __entry->uid = uid; ++ __entry->pgtables = mm_pgtables_bytes(task->mm) >> 10; ++ __entry->oom_score_adj = task->signal->oom_score_adj; + ), + +- TP_printk("pid=%d", __entry->pid) ++ TP_printk("pid=%d comm=%s total-vm=%lukB anon-rss=%lukB file-rss:%lukB shmem-rss:%lukB uid=%u pgtables=%lukB oom_score_adj=%hd", ++ __entry->pid, ++ __get_str(comm), ++ __entry->total_vm, ++ __entry->anon_rss, ++ __entry->file_rss, ++ __entry->shmem_rss, ++ __entry->uid, ++ __entry->pgtables, ++ __entry->oom_score_adj ++ ) + ); + + TRACE_EVENT(wake_reaper, +diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h +index bed20a89c14c1a..6128146bb133b7 100644 +--- a/include/uapi/linux/input-event-codes.h ++++ b/include/uapi/linux/input-event-codes.h +@@ -519,6 +519,7 @@ + #define KEY_NOTIFICATION_CENTER 0x1bc /* Show/hide the notification center */ + #define KEY_PICKUP_PHONE 0x1bd /* Answer incoming call */ + #define KEY_HANGUP_PHONE 0x1be /* Decline incoming call */ ++#define KEY_LINK_PHONE 0x1bf /* AL Phone Syncing */ + + #define KEY_DEL_EOL 0x1c0 + #define KEY_DEL_EOS 0x1c1 +diff --git a/include/uapi/linux/seg6_iptunnel.h b/include/uapi/linux/seg6_iptunnel.h +index eb815e0d0ac3e9..a9fa777f16de45 100644 +--- a/include/uapi/linux/seg6_iptunnel.h ++++ b/include/uapi/linux/seg6_iptunnel.h +@@ -35,6 +35,8 @@ enum { + SEG6_IPTUN_MODE_INLINE, + SEG6_IPTUN_MODE_ENCAP, + SEG6_IPTUN_MODE_L2ENCAP, ++ SEG6_IPTUN_MODE_ENCAP_RED, ++ SEG6_IPTUN_MODE_L2ENCAP_RED, + }; + + #endif +diff --git a/kernel/acct.c b/kernel/acct.c +index 2b5cc63eb295b8..c0c79bdb921959 100644 +--- a/kernel/acct.c ++++ b/kernel/acct.c +@@ -85,48 +85,50 @@ struct bsd_acct_struct { + atomic_long_t count; + struct rcu_head rcu; + struct mutex lock; +- int active; ++ bool active; ++ bool check_space; + unsigned long needcheck; + struct file *file; + struct pid_namespace *ns; + struct work_struct work; + struct completion done; ++ acct_t ac; + }; + +-static void do_acct_process(struct bsd_acct_struct *acct); ++static void fill_ac(struct bsd_acct_struct *acct); ++static void acct_write_process(struct bsd_acct_struct *acct); + + /* + * Check the amount of free space and suspend/resume accordingly. + */ +-static int check_free_space(struct bsd_acct_struct *acct) ++static bool check_free_space(struct bsd_acct_struct *acct) + { + struct kstatfs sbuf; + +- if (time_is_after_jiffies(acct->needcheck)) +- goto out; ++ if (!acct->check_space) ++ return acct->active; + + /* May block */ + if (vfs_statfs(&acct->file->f_path, &sbuf)) +- goto out; ++ return acct->active; + + if (acct->active) { + u64 suspend = sbuf.f_blocks * SUSPEND; + do_div(suspend, 100); + if (sbuf.f_bavail <= suspend) { +- acct->active = 0; ++ acct->active = false; + pr_info("Process accounting paused\n"); + } + } else { + u64 resume = sbuf.f_blocks * RESUME; + do_div(resume, 100); + if (sbuf.f_bavail >= resume) { +- acct->active = 1; ++ acct->active = true; + pr_info("Process accounting resumed\n"); + } + } + + acct->needcheck = jiffies + ACCT_TIMEOUT*HZ; +-out: + return acct->active; + } + +@@ -171,7 +173,11 @@ static void acct_pin_kill(struct fs_pin *pin) + { + struct bsd_acct_struct *acct = to_acct(pin); + mutex_lock(&acct->lock); +- do_acct_process(acct); ++ /* ++ * Fill the accounting struct with the exiting task's info ++ * before punting to the workqueue. ++ */ ++ fill_ac(acct); + schedule_work(&acct->work); + wait_for_completion(&acct->done); + cmpxchg(&acct->ns->bacct, pin, NULL); +@@ -184,6 +190,9 @@ static void close_work(struct work_struct *work) + { + struct bsd_acct_struct *acct = container_of(work, struct bsd_acct_struct, work); + struct file *file = acct->file; ++ ++ /* We were fired by acct_pin_kill() which holds acct->lock. */ ++ acct_write_process(acct); + if (file->f_op->flush) + file->f_op->flush(file, NULL); + __fput_sync(file); +@@ -216,6 +225,20 @@ static int acct_on(struct filename *pathname) + return -EACCES; + } + ++ /* Exclude kernel kernel internal filesystems. */ ++ if (file_inode(file)->i_sb->s_flags & (SB_NOUSER | SB_KERNMOUNT)) { ++ kfree(acct); ++ filp_close(file, NULL); ++ return -EINVAL; ++ } ++ ++ /* Exclude procfs and sysfs. */ ++ if (file_inode(file)->i_sb->s_iflags & SB_I_USERNS_VISIBLE) { ++ kfree(acct); ++ filp_close(file, NULL); ++ return -EINVAL; ++ } ++ + if (!(file->f_mode & FMODE_CAN_WRITE)) { + kfree(acct); + filp_close(file, NULL); +@@ -412,13 +435,27 @@ static u32 encode_float(u64 value) + * do_exit() or when switching to a different output file. + */ + +-static void fill_ac(acct_t *ac) ++static void fill_ac(struct bsd_acct_struct *acct) + { + struct pacct_struct *pacct = ¤t->signal->pacct; ++ struct file *file = acct->file; ++ acct_t *ac = &acct->ac; + u64 elapsed, run_time; + time64_t btime; + struct tty_struct *tty; + ++ lockdep_assert_held(&acct->lock); ++ ++ if (time_is_after_jiffies(acct->needcheck)) { ++ acct->check_space = false; ++ ++ /* Don't fill in @ac if nothing will be written. */ ++ if (!acct->active) ++ return; ++ } else { ++ acct->check_space = true; ++ } ++ + /* + * Fill the accounting struct with the needed info as recorded + * by the different kernel functions. +@@ -466,64 +503,61 @@ static void fill_ac(acct_t *ac) + ac->ac_majflt = encode_comp_t(pacct->ac_majflt); + ac->ac_exitcode = pacct->ac_exitcode; + spin_unlock_irq(¤t->sighand->siglock); +-} +-/* +- * do_acct_process does all actual work. Caller holds the reference to file. +- */ +-static void do_acct_process(struct bsd_acct_struct *acct) +-{ +- acct_t ac; +- unsigned long flim; +- const struct cred *orig_cred; +- struct file *file = acct->file; + +- /* +- * Accounting records are not subject to resource limits. +- */ +- flim = rlimit(RLIMIT_FSIZE); +- current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; +- /* Perform file operations on behalf of whoever enabled accounting */ +- orig_cred = override_creds(file->f_cred); +- +- /* +- * First check to see if there is enough free_space to continue +- * the process accounting system. +- */ +- if (!check_free_space(acct)) +- goto out; +- +- fill_ac(&ac); + /* we really need to bite the bullet and change layout */ +- ac.ac_uid = from_kuid_munged(file->f_cred->user_ns, orig_cred->uid); +- ac.ac_gid = from_kgid_munged(file->f_cred->user_ns, orig_cred->gid); ++ ac->ac_uid = from_kuid_munged(file->f_cred->user_ns, current_uid()); ++ ac->ac_gid = from_kgid_munged(file->f_cred->user_ns, current_gid()); + #if ACCT_VERSION == 1 || ACCT_VERSION == 2 + /* backward-compatible 16 bit fields */ +- ac.ac_uid16 = ac.ac_uid; +- ac.ac_gid16 = ac.ac_gid; ++ ac->ac_uid16 = ac->ac_uid; ++ ac->ac_gid16 = ac->ac_gid; + #elif ACCT_VERSION == 3 + { + struct pid_namespace *ns = acct->ns; + +- ac.ac_pid = task_tgid_nr_ns(current, ns); ++ ac->ac_pid = task_tgid_nr_ns(current, ns); + rcu_read_lock(); +- ac.ac_ppid = task_tgid_nr_ns(rcu_dereference(current->real_parent), +- ns); ++ ac->ac_ppid = task_tgid_nr_ns(rcu_dereference(current->real_parent), ns); + rcu_read_unlock(); + } + #endif ++} ++ ++static void acct_write_process(struct bsd_acct_struct *acct) ++{ ++ struct file *file = acct->file; ++ const struct cred *cred; ++ acct_t *ac = &acct->ac; ++ ++ /* Perform file operations on behalf of whoever enabled accounting */ ++ cred = override_creds(file->f_cred); ++ + /* +- * Get freeze protection. If the fs is frozen, just skip the write +- * as we could deadlock the system otherwise. ++ * First check to see if there is enough free_space to continue ++ * the process accounting system. Then get freeze protection. If ++ * the fs is frozen, just skip the write as we could deadlock ++ * the system otherwise. + */ +- if (file_start_write_trylock(file)) { ++ if (check_free_space(acct) && file_start_write_trylock(file)) { + /* it's been opened O_APPEND, so position is irrelevant */ + loff_t pos = 0; +- __kernel_write(file, &ac, sizeof(acct_t), &pos); ++ __kernel_write(file, ac, sizeof(acct_t), &pos); + file_end_write(file); + } +-out: ++ ++ revert_creds(cred); ++} ++ ++static void do_acct_process(struct bsd_acct_struct *acct) ++{ ++ unsigned long flim; ++ ++ /* Accounting records are not subject to resource limits. */ ++ flim = rlimit(RLIMIT_FSIZE); ++ current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; ++ fill_ac(acct); ++ acct_write_process(acct); + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim; +- revert_creds(orig_cred); + } + + /** +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 37aa1e319165f8..7fce461eae102e 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -1435,8 +1435,6 @@ int generic_map_update_batch(struct bpf_map *map, + return err; + } + +-#define MAP_LOOKUP_RETRIES 3 +- + int generic_map_lookup_batch(struct bpf_map *map, + const union bpf_attr *attr, + union bpf_attr __user *uattr) +@@ -1446,8 +1444,8 @@ int generic_map_lookup_batch(struct bpf_map *map, + void __user *values = u64_to_user_ptr(attr->batch.values); + void __user *keys = u64_to_user_ptr(attr->batch.keys); + void *buf, *buf_prevkey, *prev_key, *key, *value; +- int err, retry = MAP_LOOKUP_RETRIES; + u32 value_size, cp, max_count; ++ int err; + + if (attr->batch.elem_flags & ~BPF_F_LOCK) + return -EINVAL; +@@ -1493,14 +1491,8 @@ int generic_map_lookup_batch(struct bpf_map *map, + err = bpf_map_copy_value(map, key, value, + attr->batch.elem_flags); + +- if (err == -ENOENT) { +- if (retry) { +- retry--; +- continue; +- } +- err = -EINTR; +- break; +- } ++ if (err == -ENOENT) ++ goto next_key; + + if (err) + goto free_buf; +@@ -1515,12 +1507,12 @@ int generic_map_lookup_batch(struct bpf_map *map, + goto free_buf; + } + ++ cp++; ++next_key: + if (!prev_key) + prev_key = buf_prevkey; + + swap(prev_key, key); +- retry = MAP_LOOKUP_RETRIES; +- cp++; + cond_resched(); + } + +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index d031e0b8bf9f61..1e87257fe46924 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -3818,7 +3818,7 @@ static void __cgroup_kill(struct cgroup *cgrp) + lockdep_assert_held(&cgroup_mutex); + + spin_lock_irq(&css_set_lock); +- set_bit(CGRP_KILL, &cgrp->flags); ++ cgrp->kill_seq++; + spin_unlock_irq(&css_set_lock); + + css_task_iter_start(&cgrp->self, CSS_TASK_ITER_PROCS | CSS_TASK_ITER_THREADED, &it); +@@ -3834,10 +3834,6 @@ static void __cgroup_kill(struct cgroup *cgrp) + send_sig(SIGKILL, task, 0); + } + css_task_iter_end(&it); +- +- spin_lock_irq(&css_set_lock); +- clear_bit(CGRP_KILL, &cgrp->flags); +- spin_unlock_irq(&css_set_lock); + } + + static void cgroup_kill(struct cgroup *cgrp) +@@ -6202,6 +6198,10 @@ static int cgroup_css_set_fork(struct kernel_clone_args *kargs) + spin_lock_irq(&css_set_lock); + cset = task_css_set(current); + get_css_set(cset); ++ if (kargs->cgrp) ++ kargs->kill_seq = kargs->cgrp->kill_seq; ++ else ++ kargs->kill_seq = cset->dfl_cgrp->kill_seq; + spin_unlock_irq(&css_set_lock); + + if (!(kargs->flags & CLONE_INTO_CGROUP)) { +@@ -6369,6 +6369,7 @@ void cgroup_post_fork(struct task_struct *child, + struct kernel_clone_args *kargs) + __releases(&cgroup_threadgroup_rwsem) __releases(&cgroup_mutex) + { ++ unsigned int cgrp_kill_seq = 0; + unsigned long cgrp_flags = 0; + bool kill = false; + struct cgroup_subsys *ss; +@@ -6382,10 +6383,13 @@ void cgroup_post_fork(struct task_struct *child, + + /* init tasks are special, only link regular threads */ + if (likely(child->pid)) { +- if (kargs->cgrp) ++ if (kargs->cgrp) { + cgrp_flags = kargs->cgrp->flags; +- else ++ cgrp_kill_seq = kargs->cgrp->kill_seq; ++ } else { + cgrp_flags = cset->dfl_cgrp->flags; ++ cgrp_kill_seq = cset->dfl_cgrp->kill_seq; ++ } + + WARN_ON_ONCE(!list_empty(&child->cg_list)); + cset->nr_tasks++; +@@ -6420,7 +6424,7 @@ void cgroup_post_fork(struct task_struct *child, + * child down right after we finished preparing it for + * userspace. + */ +- kill = test_bit(CGRP_KILL, &cgrp_flags); ++ kill = kargs->kill_seq != cgrp_kill_seq; + } + + spin_unlock_irq(&css_set_lock); +diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c +index b28b8a5ef6381b..1d016767179f50 100644 +--- a/kernel/debug/kdb/kdb_io.c ++++ b/kernel/debug/kdb/kdb_io.c +@@ -577,6 +577,8 @@ static void kdb_msg_write(const char *msg, int msg_len) + continue; + if (c == dbg_io_ops->cons) + continue; ++ if (!c->write) ++ continue; + /* + * Set oops_in_progress to encourage the console drivers to + * disregard their internal spin locks: in the current calling +diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c +index 5c7ed5d5194247..59d44d8f6161da 100644 +--- a/kernel/dma/swiotlb.c ++++ b/kernel/dma/swiotlb.c +@@ -247,7 +247,7 @@ swiotlb_init(int verbose) + return; + + fail_free_mem: +- memblock_free_early(__pa(tlb), bytes); ++ memblock_free(__pa(tlb), bytes); + fail: + pr_warn("Cannot allocate buffer"); + } +diff --git a/kernel/events/core.c b/kernel/events/core.c +index fa6b18e05b8d9f..520a890a2a6f7d 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -5773,14 +5773,15 @@ static int _perf_event_period(struct perf_event *event, u64 value) + if (!value) + return -EINVAL; + +- if (event->attr.freq && value > sysctl_perf_event_sample_rate) +- return -EINVAL; +- +- if (perf_event_check_period(event, value)) +- return -EINVAL; +- +- if (!event->attr.freq && (value & (1ULL << 63))) +- return -EINVAL; ++ if (event->attr.freq) { ++ if (value > sysctl_perf_event_sample_rate) ++ return -EINVAL; ++ } else { ++ if (perf_event_check_period(event, value)) ++ return -EINVAL; ++ if (value & (1ULL << 63)) ++ return -EINVAL; ++ } + + event_function_call(event, __perf_event_period, &value); + +diff --git a/kernel/hung_task.c b/kernel/hung_task.c +index 9888e2bc8c7671..52501e5f765547 100644 +--- a/kernel/hung_task.c ++++ b/kernel/hung_task.c +@@ -63,7 +63,9 @@ static struct task_struct *watchdog_task; + * Should we dump all CPUs backtraces in a hung task event? + * Defaults to 0, can be changed via sysctl. + */ +-unsigned int __read_mostly sysctl_hung_task_all_cpu_backtrace; ++static unsigned int __read_mostly sysctl_hung_task_all_cpu_backtrace; ++#else ++#define sysctl_hung_task_all_cpu_backtrace 0 + #endif /* CONFIG_SMP */ + + /* +@@ -222,11 +224,13 @@ static long hung_timeout_jiffies(unsigned long last_checked, + MAX_SCHEDULE_TIMEOUT; + } + ++#ifdef CONFIG_SYSCTL + /* + * Process updating of timeout sysctl + */ +-int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, +- void *buffer, size_t *lenp, loff_t *ppos) ++static int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, ++ void __user *buffer, ++ size_t *lenp, loff_t *ppos) + { + int ret; + +@@ -241,6 +245,76 @@ int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, + return ret; + } + ++/* ++ * This is needed for proc_doulongvec_minmax of sysctl_hung_task_timeout_secs ++ * and hung_task_check_interval_secs ++ */ ++static const unsigned long hung_task_timeout_max = (LONG_MAX / HZ); ++static struct ctl_table hung_task_sysctls[] = { ++#ifdef CONFIG_SMP ++ { ++ .procname = "hung_task_all_cpu_backtrace", ++ .data = &sysctl_hung_task_all_cpu_backtrace, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_ONE, ++ }, ++#endif /* CONFIG_SMP */ ++ { ++ .procname = "hung_task_panic", ++ .data = &sysctl_hung_task_panic, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_ONE, ++ }, ++ { ++ .procname = "hung_task_check_count", ++ .data = &sysctl_hung_task_check_count, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ }, ++ { ++ .procname = "hung_task_timeout_secs", ++ .data = &sysctl_hung_task_timeout_secs, ++ .maxlen = sizeof(unsigned long), ++ .mode = 0644, ++ .proc_handler = proc_dohung_task_timeout_secs, ++ .extra2 = (void *)&hung_task_timeout_max, ++ }, ++ { ++ .procname = "hung_task_check_interval_secs", ++ .data = &sysctl_hung_task_check_interval_secs, ++ .maxlen = sizeof(unsigned long), ++ .mode = 0644, ++ .proc_handler = proc_dohung_task_timeout_secs, ++ .extra2 = (void *)&hung_task_timeout_max, ++ }, ++ { ++ .procname = "hung_task_warnings", ++ .data = &sysctl_hung_task_warnings, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = SYSCTL_NEG_ONE, ++ }, ++ {} ++}; ++ ++static void __init hung_task_sysctl_init(void) ++{ ++ register_sysctl_init("kernel", hung_task_sysctls); ++} ++#else ++#define hung_task_sysctl_init() do { } while (0) ++#endif /* CONFIG_SYSCTL */ ++ ++ + static atomic_t reset_hung_task = ATOMIC_INIT(0); + + void reset_hung_task_detector(void) +@@ -310,6 +384,7 @@ static int __init hung_task_init(void) + pm_notifier(hungtask_pm_notify, 0); + + watchdog_task = kthread_run(watchdog, NULL, "khungtaskd"); ++ hung_task_sysctl_init(); + + return 0; + } +diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h +index f1d83a8b441719..da1f282d5a1d1f 100644 +--- a/kernel/irq/internals.h ++++ b/kernel/irq/internals.h +@@ -429,10 +429,6 @@ static inline struct cpumask *irq_desc_get_pending_mask(struct irq_desc *desc) + { + return desc->pending_mask; + } +-static inline bool handle_enforce_irqctx(struct irq_data *data) +-{ +- return irqd_is_handle_enforce_irqctx(data); +-} + bool irq_fixup_move_pending(struct irq_desc *desc, bool force_clear); + #else /* CONFIG_GENERIC_PENDING_IRQ */ + static inline bool irq_can_move_pcntxt(struct irq_data *data) +@@ -459,11 +455,12 @@ static inline bool irq_fixup_move_pending(struct irq_desc *desc, bool fclear) + { + return false; + } ++#endif /* !CONFIG_GENERIC_PENDING_IRQ */ ++ + static inline bool handle_enforce_irqctx(struct irq_data *data) + { +- return false; ++ return irqd_is_handle_enforce_irqctx(data); + } +-#endif /* !CONFIG_GENERIC_PENDING_IRQ */ + + #if !defined(CONFIG_IRQ_DOMAIN) || !defined(CONFIG_IRQ_DOMAIN_HIERARCHY) + static inline int irq_domain_activate_irq(struct irq_data *data, bool reserve) +diff --git a/kernel/padata.c b/kernel/padata.c +index 39faea30d76a56..db45af7728cb21 100644 +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -47,6 +47,22 @@ struct padata_mt_job_state { + static void padata_free_pd(struct parallel_data *pd); + static void __init padata_mt_helper(struct work_struct *work); + ++static inline void padata_get_pd(struct parallel_data *pd) ++{ ++ refcount_inc(&pd->refcnt); ++} ++ ++static inline void padata_put_pd_cnt(struct parallel_data *pd, int cnt) ++{ ++ if (refcount_sub_and_test(cnt, &pd->refcnt)) ++ padata_free_pd(pd); ++} ++ ++static inline void padata_put_pd(struct parallel_data *pd) ++{ ++ padata_put_pd_cnt(pd, 1); ++} ++ + static int padata_index_to_cpu(struct parallel_data *pd, int cpu_index) + { + int cpu, target_cpu; +@@ -198,7 +214,7 @@ int padata_do_parallel(struct padata_shell *ps, + if ((pinst->flags & PADATA_RESET)) + goto out; + +- refcount_inc(&pd->refcnt); ++ padata_get_pd(pd); + padata->pd = pd; + padata->cb_cpu = *cb_cpu; + +@@ -328,8 +344,14 @@ static void padata_reorder(struct parallel_data *pd) + smp_mb(); + + reorder = per_cpu_ptr(pd->reorder_list, pd->cpu); +- if (!list_empty(&reorder->list) && padata_find_next(pd, false)) ++ if (!list_empty(&reorder->list) && padata_find_next(pd, false)) { ++ /* ++ * Other context(eg. the padata_serial_worker) can finish the request. ++ * To avoid UAF issue, add pd ref here, and put pd ref after reorder_work finish. ++ */ ++ padata_get_pd(pd); + queue_work(pinst->serial_wq, &pd->reorder_work); ++ } + } + + static void invoke_padata_reorder(struct work_struct *work) +@@ -340,6 +362,8 @@ static void invoke_padata_reorder(struct work_struct *work) + pd = container_of(work, struct parallel_data, reorder_work); + padata_reorder(pd); + local_bh_enable(); ++ /* Pairs with putting the reorder_work in the serial_wq */ ++ padata_put_pd(pd); + } + + static void padata_serial_worker(struct work_struct *serial_work) +@@ -372,8 +396,7 @@ static void padata_serial_worker(struct work_struct *serial_work) + } + local_bh_enable(); + +- if (refcount_sub_and_test(cnt, &pd->refcnt)) +- padata_free_pd(pd); ++ padata_put_pd_cnt(pd, cnt); + } + + /** +@@ -670,8 +693,7 @@ static int padata_replace(struct padata_instance *pinst) + synchronize_rcu(); + + list_for_each_entry_continue_reverse(ps, &pinst->pslist, list) +- if (refcount_dec_and_test(&ps->opd->refcnt)) +- padata_free_pd(ps->opd); ++ padata_put_pd(ps->opd); + + pinst->flags &= ~PADATA_RESET; + +@@ -959,7 +981,7 @@ static ssize_t padata_sysfs_store(struct kobject *kobj, struct attribute *attr, + + pinst = kobj2pinst(kobj); + pentry = attr2pentry(attr); +- if (pentry->show) ++ if (pentry->store) + ret = pentry->store(pinst, attr, buf, count); + + return ret; +@@ -1110,11 +1132,16 @@ void padata_free_shell(struct padata_shell *ps) + if (!ps) + return; + ++ /* ++ * Wait for all _do_serial calls to finish to avoid touching ++ * freed pd's and ps's. ++ */ ++ synchronize_rcu(); ++ + mutex_lock(&ps->pinst->lock); + list_del(&ps->list); + pd = rcu_dereference_protected(ps->pd, 1); +- if (refcount_dec_and_test(&pd->refcnt)) +- padata_free_pd(pd); ++ padata_put_pd(pd); + mutex_unlock(&ps->pinst->lock); + + kfree(ps); +diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c +index 9abc73d500fbfe..747c856411e390 100644 +--- a/kernel/power/hibernate.c ++++ b/kernel/power/hibernate.c +@@ -593,7 +593,11 @@ int hibernation_platform_enter(void) + + local_irq_disable(); + system_state = SYSTEM_SUSPEND; +- syscore_suspend(); ++ ++ error = syscore_suspend(); ++ if (error) ++ goto Enable_irqs; ++ + if (pm_wakeup_pending()) { + error = -EAGAIN; + goto Power_up; +@@ -605,6 +609,7 @@ int hibernation_platform_enter(void) + + Power_up: + syscore_resume(); ++ Enable_irqs: + system_state = SYSTEM_RUNNING; + local_irq_enable(); + +diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c +index 5e81d2a79d5cc9..113990f38436ed 100644 +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -403,7 +403,7 @@ static struct latched_seq clear_seq = { + /* record buffer */ + #define LOG_ALIGN __alignof__(unsigned long) + #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) +-#define LOG_BUF_LEN_MAX (u32)(1 << 31) ++#define LOG_BUF_LEN_MAX ((u32)1 << 31) + static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); + static char *log_buf = __log_buf; + static u32 log_buf_len = __LOG_BUF_LEN; +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index ed92b75f7e0246..70a7cf563f01e2 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -642,13 +642,15 @@ static void update_rq_clock_task(struct rq *rq, s64 delta) + #endif + #ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING + if (static_key_false((¶virt_steal_rq_enabled))) { +- steal = paravirt_steal_clock(cpu_of(rq)); ++ u64 prev_steal; ++ ++ steal = prev_steal = paravirt_steal_clock(cpu_of(rq)); + steal -= rq->prev_steal_time_rq; + + if (unlikely(steal > delta)) + steal = delta; + +- rq->prev_steal_time_rq += steal; ++ rq->prev_steal_time_rq = prev_steal; + delta -= steal; + } + #endif +@@ -1967,7 +1969,7 @@ static inline void enqueue_task(struct rq *rq, struct task_struct *p, int flags) + + if (!(flags & ENQUEUE_RESTORE)) { + sched_info_enqueue(rq, p); +- psi_enqueue(p, flags & ENQUEUE_WAKEUP); ++ psi_enqueue(p, (flags & ENQUEUE_WAKEUP) && !(flags & ENQUEUE_MIGRATED)); + } + + uclamp_rq_inc(rq, p); +@@ -8245,7 +8247,7 @@ SYSCALL_DEFINE0(sched_yield) + #if !defined(CONFIG_PREEMPTION) || defined(CONFIG_PREEMPT_DYNAMIC) + int __sched __cond_resched(void) + { +- if (should_resched(0)) { ++ if (should_resched(0) && !irqs_disabled()) { + preempt_schedule_common(); + return 1; + } +diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c +index 7f6bb37d3a2f73..e23a0fc96a7d28 100644 +--- a/kernel/sched/cpufreq_schedutil.c ++++ b/kernel/sched/cpufreq_schedutil.c +@@ -91,7 +91,7 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time) + + if (unlikely(sg_policy->limits_changed)) { + sg_policy->limits_changed = false; +- sg_policy->need_freq_update = true; ++ sg_policy->need_freq_update = cpufreq_driver_test_flags(CPUFREQ_NEED_UPDATE_LIMITS); + return true; + } + +@@ -104,7 +104,7 @@ static bool sugov_update_next_freq(struct sugov_policy *sg_policy, u64 time, + unsigned int next_freq) + { + if (sg_policy->need_freq_update) +- sg_policy->need_freq_update = cpufreq_driver_test_flags(CPUFREQ_NEED_UPDATE_LIMITS); ++ sg_policy->need_freq_update = false; + else if (sg_policy->next_freq == next_freq) + return false; + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 4056330d38887f..ea707ee9ddac11 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -3303,15 +3303,17 @@ static inline bool child_cfs_rq_on_list(struct cfs_rq *cfs_rq) + { + struct cfs_rq *prev_cfs_rq; + struct list_head *prev; ++ struct rq *rq = rq_of(cfs_rq); + + if (cfs_rq->on_list) { + prev = cfs_rq->leaf_cfs_rq_list.prev; + } else { +- struct rq *rq = rq_of(cfs_rq); +- + prev = rq->tmp_alone_branch; + } + ++ if (prev == &rq->leaf_cfs_rq_list) ++ return false; ++ + prev_cfs_rq = container_of(prev, struct cfs_rq, leaf_cfs_rq_list); + + return (prev_cfs_rq->tg->parent == cfs_rq->tg); +@@ -8022,6 +8024,8 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) + int tsk_cache_hot; + + lockdep_assert_rq_held(env->src_rq); ++ if (p->sched_task_hot) ++ p->sched_task_hot = 0; + + /* + * We do not migrate tasks that are: +@@ -8094,10 +8098,8 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) + + if (tsk_cache_hot <= 0 || + env->sd->nr_balance_failed > env->sd->cache_nice_tries) { +- if (tsk_cache_hot == 1) { +- schedstat_inc(env->sd->lb_hot_gained[env->idle]); +- schedstat_inc(p->stats.nr_forced_migrations); +- } ++ if (tsk_cache_hot == 1) ++ p->sched_task_hot = 1; + return 1; + } + +@@ -8112,6 +8114,12 @@ static void detach_task(struct task_struct *p, struct lb_env *env) + { + lockdep_assert_rq_held(env->src_rq); + ++ if (p->sched_task_hot) { ++ p->sched_task_hot = 0; ++ schedstat_inc(env->sd->lb_hot_gained[env->idle]); ++ schedstat_inc(p->stats.nr_forced_migrations); ++ } ++ + deactivate_task(env->src_rq, p, DEQUEUE_NOCLOCK); + set_task_cpu(p, env->dst_cpu); + } +@@ -8274,6 +8282,9 @@ static int detach_tasks(struct lb_env *env) + + continue; + next: ++ if (p->sched_task_hot) ++ schedstat_inc(p->stats.nr_failed_migrations_hot); ++ + list_move(&p->se.group_node, tasks); + } + +diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h +index 975703572bc0da..cee3100c74cd5b 100644 +--- a/kernel/sched/stats.h ++++ b/kernel/sched/stats.h +@@ -91,11 +91,9 @@ static inline void psi_enqueue(struct task_struct *p, bool wakeup) + if (p->in_memstall) + set |= TSK_MEMSTALL_RUNNING; + +- if (!wakeup || p->sched_psi_wake_requeue) { ++ if (!wakeup) { + if (p->in_memstall) + set |= TSK_MEMSTALL; +- if (p->sched_psi_wake_requeue) +- p->sched_psi_wake_requeue = 0; + } else { + if (p->in_iowait) + clear |= TSK_IOWAIT; +@@ -106,8 +104,6 @@ static inline void psi_enqueue(struct task_struct *p, bool wakeup) + + static inline void psi_dequeue(struct task_struct *p, bool sleep) + { +- int clear = TSK_RUNNING; +- + if (static_branch_likely(&psi_disabled)) + return; + +@@ -120,10 +116,7 @@ static inline void psi_dequeue(struct task_struct *p, bool sleep) + if (sleep) + return; + +- if (p->in_memstall) +- clear |= (TSK_MEMSTALL | TSK_MEMSTALL_RUNNING); +- +- psi_task_change(p, clear, 0); ++ psi_task_change(p, p->psi_flags, 0); + } + + static inline void psi_ttwu_dequeue(struct task_struct *p) +@@ -135,19 +128,12 @@ static inline void psi_ttwu_dequeue(struct task_struct *p) + * deregister its sleep-persistent psi states from the old + * queue, and let psi_enqueue() know it has to requeue. + */ +- if (unlikely(p->in_iowait || p->in_memstall)) { ++ if (unlikely(p->psi_flags)) { + struct rq_flags rf; + struct rq *rq; +- int clear = 0; +- +- if (p->in_iowait) +- clear |= TSK_IOWAIT; +- if (p->in_memstall) +- clear |= TSK_MEMSTALL; + + rq = __task_rq_lock(p, &rf); +- psi_task_change(p, clear, 0); +- p->sched_psi_wake_requeue = 1; ++ psi_task_change(p, p->psi_flags, 0); + __task_rq_unlock(rq, &rf); + } + } +diff --git a/kernel/sysctl.c b/kernel/sysctl.c +index 4554e80c42729b..eaf9dd6a2f12f4 100644 +--- a/kernel/sysctl.c ++++ b/kernel/sysctl.c +@@ -113,34 +113,23 @@ + static int sixty = 60; + #endif + +-static unsigned long zero_ul; +-static unsigned long one_ul = 1; +-static unsigned long long_max = LONG_MAX; + #ifdef CONFIG_PRINTK +-static int ten_thousand = 10000; ++static const int ten_thousand = 10000; + #endif + #ifdef CONFIG_PERF_EVENTS +-static int six_hundred_forty_kb = 640 * 1024; ++static const int six_hundred_forty_kb = 640 * 1024; + #endif + + /* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */ +-static unsigned long dirty_bytes_min = 2 * PAGE_SIZE; ++static const unsigned long dirty_bytes_min = 2 * PAGE_SIZE; + + /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ +-static int maxolduid = 65535; +-static int minolduid; ++static const int maxolduid = 65535; ++static const int minolduid; + + static int ngroups_max = NGROUPS_MAX; + static const int cap_last_cap = CAP_LAST_CAP; + +-/* +- * This is needed for proc_doulongvec_minmax of sysctl_hung_task_timeout_secs +- * and hung_task_check_interval_secs +- */ +-#ifdef CONFIG_DETECT_HUNG_TASK +-static unsigned long hung_task_timeout_max = (LONG_MAX/HZ); +-#endif +- + #ifdef CONFIG_INOTIFY_USER + #include + #endif +@@ -184,8 +173,8 @@ int sysctl_legacy_va_layout; + #endif + + #ifdef CONFIG_COMPACTION +-static int min_extfrag_threshold; +-static int max_extfrag_threshold = 1000; ++static const int min_extfrag_threshold; ++static const int max_extfrag_threshold = 1000; + #endif + + #endif /* CONFIG_SYSCTL */ +@@ -2203,8 +2192,8 @@ static struct ctl_table kern_table[] = { + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, +- .extra1 = &minolduid, +- .extra2 = &maxolduid, ++ .extra1 = (void *)&minolduid, ++ .extra2 = (void *)&maxolduid, + }, + { + .procname = "overflowgid", +@@ -2212,8 +2201,8 @@ static struct ctl_table kern_table[] = { + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, +- .extra1 = &minolduid, +- .extra2 = &maxolduid, ++ .extra1 = (void *)&minolduid, ++ .extra2 = (void *)&maxolduid, + }, + #ifdef CONFIG_S390 + { +@@ -2276,7 +2265,7 @@ static struct ctl_table kern_table[] = { + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, +- .extra2 = &ten_thousand, ++ .extra2 = (void *)&ten_thousand, + }, + { + .procname = "printk_devkmsg", +@@ -2510,60 +2499,6 @@ static struct ctl_table kern_table[] = { + .proc_handler = proc_dointvec, + }, + #endif +-#ifdef CONFIG_DETECT_HUNG_TASK +-#ifdef CONFIG_SMP +- { +- .procname = "hung_task_all_cpu_backtrace", +- .data = &sysctl_hung_task_all_cpu_backtrace, +- .maxlen = sizeof(int), +- .mode = 0644, +- .proc_handler = proc_dointvec_minmax, +- .extra1 = SYSCTL_ZERO, +- .extra2 = SYSCTL_ONE, +- }, +-#endif /* CONFIG_SMP */ +- { +- .procname = "hung_task_panic", +- .data = &sysctl_hung_task_panic, +- .maxlen = sizeof(int), +- .mode = 0644, +- .proc_handler = proc_dointvec_minmax, +- .extra1 = SYSCTL_ZERO, +- .extra2 = SYSCTL_ONE, +- }, +- { +- .procname = "hung_task_check_count", +- .data = &sysctl_hung_task_check_count, +- .maxlen = sizeof(int), +- .mode = 0644, +- .proc_handler = proc_dointvec_minmax, +- .extra1 = SYSCTL_ZERO, +- }, +- { +- .procname = "hung_task_timeout_secs", +- .data = &sysctl_hung_task_timeout_secs, +- .maxlen = sizeof(unsigned long), +- .mode = 0644, +- .proc_handler = proc_dohung_task_timeout_secs, +- .extra2 = &hung_task_timeout_max, +- }, +- { +- .procname = "hung_task_check_interval_secs", +- .data = &sysctl_hung_task_check_interval_secs, +- .maxlen = sizeof(unsigned long), +- .mode = 0644, +- .proc_handler = proc_dohung_task_timeout_secs, +- .extra2 = &hung_task_timeout_max, +- }, +- { +- .procname = "hung_task_warnings", +- .data = &sysctl_hung_task_warnings, +- .maxlen = sizeof(int), +- .mode = 0644, +- .proc_handler = proc_dointvec_minmax, +- .extra1 = SYSCTL_NEG_ONE, +- }, +-#endif + #ifdef CONFIG_RT_MUTEXES + { + .procname = "max_lock_depth", +@@ -2632,7 +2567,7 @@ static struct ctl_table kern_table[] = { + .mode = 0644, + .proc_handler = perf_event_max_stack_handler, + .extra1 = SYSCTL_ZERO, +- .extra2 = &six_hundred_forty_kb, ++ .extra2 = (void *)&six_hundred_forty_kb, + }, + { + .procname = "perf_event_max_contexts_per_stack", +@@ -2788,7 +2723,7 @@ static struct ctl_table vm_table[] = { + .maxlen = sizeof(dirty_background_bytes), + .mode = 0644, + .proc_handler = dirty_background_bytes_handler, +- .extra1 = &one_ul, ++ .extra1 = SYSCTL_LONG_ONE, + }, + { + .procname = "dirty_ratio", +@@ -2805,7 +2740,7 @@ static struct ctl_table vm_table[] = { + .maxlen = sizeof(vm_dirty_bytes), + .mode = 0644, + .proc_handler = dirty_bytes_handler, +- .extra1 = &dirty_bytes_min, ++ .extra1 = (void *)&dirty_bytes_min, + }, + { + .procname = "dirty_writeback_centisecs", +@@ -2921,8 +2856,8 @@ static struct ctl_table vm_table[] = { + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, +- .extra1 = &min_extfrag_threshold, +- .extra2 = &max_extfrag_threshold, ++ .extra1 = (void *)&min_extfrag_threshold, ++ .extra2 = (void *)&max_extfrag_threshold, + }, + { + .procname = "compact_unevictable_allowed", +@@ -3181,45 +3116,6 @@ static struct ctl_table vm_table[] = { + }; + + static struct ctl_table fs_table[] = { +- { +- .procname = "inode-nr", +- .data = &inodes_stat, +- .maxlen = 2*sizeof(long), +- .mode = 0444, +- .proc_handler = proc_nr_inodes, +- }, +- { +- .procname = "inode-state", +- .data = &inodes_stat, +- .maxlen = 7*sizeof(long), +- .mode = 0444, +- .proc_handler = proc_nr_inodes, +- }, +- { +- .procname = "file-nr", +- .data = &files_stat, +- .maxlen = sizeof(files_stat), +- .mode = 0444, +- .proc_handler = proc_nr_files, +- }, +- { +- .procname = "file-max", +- .data = &files_stat.max_files, +- .maxlen = sizeof(files_stat.max_files), +- .mode = 0644, +- .proc_handler = proc_doulongvec_minmax, +- .extra1 = &zero_ul, +- .extra2 = &long_max, +- }, +- { +- .procname = "nr_open", +- .data = &sysctl_nr_open, +- .maxlen = sizeof(unsigned int), +- .mode = 0644, +- .proc_handler = proc_dointvec_minmax, +- .extra1 = &sysctl_nr_open_min, +- .extra2 = &sysctl_nr_open_max, +- }, + { + .procname = "dentry-state", + .data = &dentry_stat, +@@ -3233,8 +3129,8 @@ static struct ctl_table fs_table[] = { + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, +- .extra1 = &minolduid, +- .extra2 = &maxolduid, ++ .extra1 = (void *)&minolduid, ++ .extra2 = (void *)&maxolduid, + }, + { + .procname = "overflowgid", +@@ -3242,8 +3138,8 @@ static struct ctl_table fs_table[] = { + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, +- .extra1 = &minolduid, +- .extra2 = &maxolduid, ++ .extra1 = (void *)&minolduid, ++ .extra2 = (void *)&maxolduid, + }, + #ifdef CONFIG_FILE_LOCKING + { +diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c +index 5aa8eec89e7811..32efc87c41f206 100644 +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -342,16 +342,18 @@ void clocksource_verify_percpu(struct clocksource *cs) + cpumask_clear(&cpus_ahead); + cpumask_clear(&cpus_behind); + cpus_read_lock(); +- preempt_disable(); ++ migrate_disable(); + clocksource_verify_choose_cpus(); +- if (cpumask_weight(&cpus_chosen) == 0) { +- preempt_enable(); ++ if (cpumask_empty(&cpus_chosen)) { ++ migrate_enable(); + cpus_read_unlock(); + pr_warn("Not enough CPUs to check clocksource '%s'.\n", cs->name); + return; + } + testcpu = smp_processor_id(); +- pr_warn("Checking clocksource %s synchronization from CPU %d to CPUs %*pbl.\n", cs->name, testcpu, cpumask_pr_args(&cpus_chosen)); ++ pr_info("Checking clocksource %s synchronization from CPU %d to CPUs %*pbl.\n", ++ cs->name, testcpu, cpumask_pr_args(&cpus_chosen)); ++ preempt_disable(); + for_each_cpu(cpu, &cpus_chosen) { + if (cpu == testcpu) + continue; +@@ -371,6 +373,7 @@ void clocksource_verify_percpu(struct clocksource *cs) + cs_nsec_min = cs_nsec; + } + preempt_enable(); ++ migrate_enable(); + cpus_read_unlock(); + if (!cpumask_empty(&cpus_ahead)) + pr_warn(" CPUs %*pbl ahead of CPU %d for clocksource %s.\n", +diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c +index 126754b61edc06..60acc3c76316f8 100644 +--- a/kernel/trace/bpf_trace.c ++++ b/kernel/trace/bpf_trace.c +@@ -799,7 +799,7 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type) + if (unlikely(is_global_init(current))) + return -EPERM; + +- if (irqs_disabled()) { ++ if (!preemptible()) { + /* Do an early check on signal validity. Otherwise, + * the error is lost in deferred irq_work. + */ +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 6ec08eca7f4bbb..80ccb29bf75208 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -510,6 +510,7 @@ static int function_stat_show(struct seq_file *m, void *v) + static struct trace_seq s; + unsigned long long avg; + unsigned long long stddev; ++ unsigned long long stddev_denom; + #endif + mutex_lock(&ftrace_profile_lock); + +@@ -531,23 +532,19 @@ static int function_stat_show(struct seq_file *m, void *v) + #ifdef CONFIG_FUNCTION_GRAPH_TRACER + seq_puts(m, " "); + +- /* Sample standard deviation (s^2) */ +- if (rec->counter <= 1) +- stddev = 0; +- else { +- /* +- * Apply Welford's method: +- * s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2) +- */ ++ /* ++ * Variance formula: ++ * s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2) ++ * Maybe Welford's method is better here? ++ * Divide only by 1000 for ns^2 -> us^2 conversion. ++ * trace_print_graph_duration will divide by 1000 again. ++ */ ++ stddev = 0; ++ stddev_denom = rec->counter * (rec->counter - 1) * 1000; ++ if (stddev_denom) { + stddev = rec->counter * rec->time_squared - + rec->time * rec->time; +- +- /* +- * Divide only 1000 for ns^2 -> us^2 conversion. +- * trace_print_graph_duration will divide 1000 again. +- */ +- stddev = div64_ul(stddev, +- rec->counter * (rec->counter - 1) * 1000); ++ stddev = div64_ul(stddev, stddev_denom); + } + + trace_seq_init(&s); +diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug +index 2025b624fbb677..db4f8ac489d419 100644 +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -1408,7 +1408,7 @@ config LOCKDEP_SMALL + config LOCKDEP_BITS + int "Bitsize for MAX_LOCKDEP_ENTRIES" + depends on LOCKDEP && !LOCKDEP_SMALL +- range 10 30 ++ range 10 24 + default 15 + help + Try increasing this value if you hit "BUG: MAX_LOCKDEP_ENTRIES too low!" message. +@@ -1424,7 +1424,7 @@ config LOCKDEP_CHAINS_BITS + config LOCKDEP_STACK_TRACE_BITS + int "Bitsize for MAX_STACK_TRACE_ENTRIES" + depends on LOCKDEP && !LOCKDEP_SMALL +- range 10 30 ++ range 10 26 + default 19 + help + Try increasing this value if you hit "BUG: MAX_STACK_TRACE_ENTRIES too low!" message. +@@ -1432,7 +1432,7 @@ config LOCKDEP_STACK_TRACE_BITS + config LOCKDEP_STACK_TRACE_HASH_BITS + int "Bitsize for STACK_TRACE_HASH_SIZE" + depends on LOCKDEP && !LOCKDEP_SMALL +- range 10 30 ++ range 10 26 + default 14 + help + Try increasing this value if you need large MAX_STACK_TRACE_ENTRIES. +@@ -1440,7 +1440,7 @@ config LOCKDEP_STACK_TRACE_HASH_BITS + config LOCKDEP_CIRCULAR_QUEUE_BITS + int "Bitsize for elements in circular_queue struct" + depends on LOCKDEP +- range 10 30 ++ range 10 26 + default 12 + help + Try increasing this value if you hit "lockdep bfs error:-1" warning due to __cq_enqueue() failure. +diff --git a/lib/Kconfig.kfence b/lib/Kconfig.kfence +index 912f252a41fc63..459dda9ef619b8 100644 +--- a/lib/Kconfig.kfence ++++ b/lib/Kconfig.kfence +@@ -45,6 +45,18 @@ config KFENCE_NUM_OBJECTS + pages are required; with one containing the object and two adjacent + ones used as guard pages. + ++config KFENCE_DEFERRABLE ++ bool "Use a deferrable timer to trigger allocations" ++ help ++ Use a deferrable timer to trigger allocations. This avoids forcing ++ CPU wake-ups if the system is idle, at the risk of a less predictable ++ sample interval. ++ ++ Warning: The KUnit test suite fails with this option enabled - due to ++ the unpredictability of the sample interval! ++ ++ Say N if you are unsure. ++ + config KFENCE_STATIC_KEYS + bool "Use static keys to set up allocations" if EXPERT + depends on JUMP_LABEL +diff --git a/lib/cpumask.c b/lib/cpumask.c +index c3c76b83338468..045779446a18d7 100644 +--- a/lib/cpumask.c ++++ b/lib/cpumask.c +@@ -188,7 +188,7 @@ EXPORT_SYMBOL(free_cpumask_var); + */ + void __init free_bootmem_cpumask_var(cpumask_var_t mask) + { +- memblock_free_early(__pa(mask), cpumask_size()); ++ memblock_free(__pa(mask), cpumask_size()); + } + #endif + +diff --git a/mm/kfence/core.c b/mm/kfence/core.c +index 3eab72fb3d8c9a..c49bc76b3a3892 100644 +--- a/mm/kfence/core.c ++++ b/mm/kfence/core.c +@@ -21,6 +21,9 @@ + #include + #include + #include ++#include ++#include ++#include + #include + #include + #include +@@ -89,6 +92,14 @@ module_param_cb(sample_interval, &sample_interval_param_ops, &kfence_sample_inte + static unsigned long kfence_skip_covered_thresh __read_mostly = 75; + module_param_named(skip_covered_thresh, kfence_skip_covered_thresh, ulong, 0644); + ++/* If true, use a deferrable timer. */ ++static bool kfence_deferrable __read_mostly = IS_ENABLED(CONFIG_KFENCE_DEFERRABLE); ++module_param_named(deferrable, kfence_deferrable, bool, 0444); ++ ++/* If true, check all canary bytes on panic. */ ++static bool kfence_check_on_panic __read_mostly; ++module_param_named(check_on_panic, kfence_check_on_panic, bool, 0444); ++ + /* The pool of pages used for guard pages and objects. */ + char *__kfence_pool __ro_after_init; + EXPORT_SYMBOL(__kfence_pool); /* Export for test modules. */ +@@ -693,8 +704,35 @@ static int kfence_debugfs_init(void) + + late_initcall(kfence_debugfs_init); + ++/* === Panic Notifier ====================================================== */ ++ ++static void kfence_check_all_canary(void) ++{ ++ int i; ++ ++ for (i = 0; i < CONFIG_KFENCE_NUM_OBJECTS; i++) { ++ struct kfence_metadata *meta = &kfence_metadata[i]; ++ ++ if (meta->state == KFENCE_OBJECT_ALLOCATED) ++ for_each_canary(meta, check_canary_byte); ++ } ++} ++ ++static int kfence_check_canary_callback(struct notifier_block *nb, ++ unsigned long reason, void *arg) ++{ ++ kfence_check_all_canary(); ++ return NOTIFY_OK; ++} ++ ++static struct notifier_block kfence_check_canary_notifier = { ++ .notifier_call = kfence_check_canary_callback, ++}; ++ + /* === Allocation Gate Timer ================================================ */ + ++static struct delayed_work kfence_timer; ++ + #ifdef CONFIG_KFENCE_STATIC_KEYS + /* Wait queue to wake up allocation-gate timer task. */ + static DECLARE_WAIT_QUEUE_HEAD(allocation_wait); +@@ -717,7 +755,6 @@ static DEFINE_IRQ_WORK(wake_up_kfence_timer_work, wake_up_kfence_timer); + * avoids IPIs, at the cost of not immediately capturing allocations if the + * instructions remain cached. + */ +-static struct delayed_work kfence_timer; + static void toggle_allocation_gate(struct work_struct *work) + { + if (!READ_ONCE(kfence_enabled)) +@@ -745,7 +782,6 @@ static void toggle_allocation_gate(struct work_struct *work) + queue_delayed_work(system_unbound_wq, &kfence_timer, + msecs_to_jiffies(kfence_sample_interval)); + } +-static DECLARE_DELAYED_WORK(kfence_timer, toggle_allocation_gate); + + /* === Public interface ===================================================== */ + +@@ -774,8 +810,18 @@ void __init kfence_init(void) + + if (!IS_ENABLED(CONFIG_KFENCE_STATIC_KEYS)) + static_branch_enable(&kfence_allocation_key); ++ ++ if (kfence_deferrable) ++ INIT_DEFERRABLE_WORK(&kfence_timer, toggle_allocation_gate); ++ else ++ INIT_DELAYED_WORK(&kfence_timer, toggle_allocation_gate); ++ ++ if (kfence_check_on_panic) ++ atomic_notifier_chain_register(&panic_notifier_list, &kfence_check_canary_notifier); ++ + WRITE_ONCE(kfence_enabled, true); + queue_delayed_work(system_unbound_wq, &kfence_timer, 0); ++ + pr_info("initialized - using %lu bytes for %d objects at 0x%p-0x%p\n", KFENCE_POOL_SIZE, + CONFIG_KFENCE_NUM_OBJECTS, (void *)__kfence_pool, + (void *)(__kfence_pool + KFENCE_POOL_SIZE)); +@@ -861,6 +907,7 @@ void *__kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags) + * properties (e.g. reside in DMAable memory). + */ + if ((flags & GFP_ZONEMASK) || ++ ((flags & __GFP_THISNODE) && num_online_nodes() > 1) || + (s->flags & (SLAB_CACHE_DMA | SLAB_CACHE_DMA32))) { + atomic_long_inc(&counters[KFENCE_COUNTER_SKIP_INCOMPAT]); + return NULL; +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index 6dd32ed164eaff..804f7be74a657a 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -1194,6 +1194,7 @@ int mem_cgroup_scan_tasks(struct mem_cgroup *memcg, + { + struct mem_cgroup *iter; + int ret = 0; ++ int i = 0; + + BUG_ON(memcg == root_mem_cgroup); + +@@ -1202,8 +1203,12 @@ int mem_cgroup_scan_tasks(struct mem_cgroup *memcg, + struct task_struct *task; + + css_task_iter_start(&iter->css, CSS_TASK_ITER_PROCS, &it); +- while (!ret && (task = css_task_iter_next(&it))) ++ while (!ret && (task = css_task_iter_next(&it))) { ++ /* Avoid potential softlockup warning */ ++ if ((++i & 1023) == 0) ++ cond_resched(); + ret = fn(task, arg); ++ } + css_task_iter_end(&it); + if (ret) { + mem_cgroup_iter_break(memcg, iter); +diff --git a/mm/memory.c b/mm/memory.c +index 4785aecca9a806..62fe3707ff92fa 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -2713,8 +2713,10 @@ static int __apply_to_page_range(struct mm_struct *mm, unsigned long addr, + next = pgd_addr_end(addr, end); + if (pgd_none(*pgd) && !create) + continue; +- if (WARN_ON_ONCE(pgd_leaf(*pgd))) +- return -EINVAL; ++ if (WARN_ON_ONCE(pgd_leaf(*pgd))) { ++ err = -EINVAL; ++ break; ++ } + if (!pgd_none(*pgd) && WARN_ON_ONCE(pgd_bad(*pgd))) { + if (!create) + continue; +diff --git a/mm/oom_kill.c b/mm/oom_kill.c +index 262f752d3d516c..5fd826f3f3da7e 100644 +--- a/mm/oom_kill.c ++++ b/mm/oom_kill.c +@@ -44,6 +44,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include "internal.h" +@@ -432,10 +434,15 @@ static void dump_tasks(struct oom_control *oc) + mem_cgroup_scan_tasks(oc->memcg, dump_task, oc); + else { + struct task_struct *p; ++ int i = 0; + + rcu_read_lock(); +- for_each_process(p) ++ for_each_process(p) { ++ /* Avoid potential softlockup warning */ ++ if ((++i & 1023) == 0) ++ touch_softlockup_watchdog(); + dump_task(p, oc); ++ } + rcu_read_unlock(); + } + } +@@ -725,6 +732,7 @@ static inline void queue_oom_reaper(struct task_struct *tsk) + */ + static void mark_oom_victim(struct task_struct *tsk) + { ++ const struct cred *cred; + struct mm_struct *mm = tsk->mm; + + WARN_ON(oom_killer_disabled); +@@ -746,7 +754,9 @@ static void mark_oom_victim(struct task_struct *tsk) + */ + __thaw_task(tsk); + atomic_inc(&oom_victims); +- trace_mark_victim(tsk->pid); ++ cred = get_task_cred(tsk); ++ trace_mark_victim(tsk, cred->uid.val); ++ put_cred(cred); + } + + /** +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index f0accb740cda2c..c177d3ab3bd04a 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -4967,6 +4967,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, + restart: + compaction_retries = 0; + no_progress_loops = 0; ++ compact_result = COMPACT_SKIPPED; + compact_priority = DEF_COMPACT_PRIORITY; + cpuset_mems_cookie = read_mems_allowed_begin(); + zonelist_iter_cookie = zonelist_iter_begin(); +diff --git a/mm/percpu.c b/mm/percpu.c +index e0a986818903dc..f58318cb04c02a 100644 +--- a/mm/percpu.c ++++ b/mm/percpu.c +@@ -2472,7 +2472,7 @@ struct pcpu_alloc_info * __init pcpu_alloc_alloc_info(int nr_groups, + */ + void __init pcpu_free_alloc_info(struct pcpu_alloc_info *ai) + { +- memblock_free_early(__pa(ai), ai->__ai_size); ++ memblock_free(__pa(ai), ai->__ai_size); + } + + /** +@@ -3134,7 +3134,7 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size, + out_free: + pcpu_free_alloc_info(ai); + if (areas) +- memblock_free_early(__pa(areas), areas_size); ++ memblock_free(__pa(areas), areas_size); + return rc; + } + #endif /* BUILD_EMBED_FIRST_CHUNK */ +@@ -3256,7 +3256,7 @@ int __init pcpu_page_first_chunk(size_t reserved_size, + free_fn(page_address(pages[j]), PAGE_SIZE); + rc = -ENOMEM; + out_free_ar: +- memblock_free_early(__pa(pages), pages_size); ++ memblock_free(__pa(pages), pages_size); + pcpu_free_alloc_info(ai); + return rc; + } +@@ -3286,7 +3286,7 @@ static void * __init pcpu_dfl_fc_alloc(unsigned int cpu, size_t size, + + static void __init pcpu_dfl_fc_free(void *ptr, size_t size) + { +- memblock_free_early(__pa(ptr), size); ++ memblock_free(__pa(ptr), size); + } + + void __init setup_per_cpu_areas(void) +diff --git a/mm/sparse.c b/mm/sparse.c +index 27092badd15bd1..df9f8459043ef9 100644 +--- a/mm/sparse.c ++++ b/mm/sparse.c +@@ -451,7 +451,7 @@ static void *sparsemap_buf_end __meminitdata; + static inline void __meminit sparse_buffer_free(unsigned long size) + { + WARN_ON(!sparsemap_buf || size == 0); +- memblock_free_early(__pa(sparsemap_buf), size); ++ memblock_free(__pa(sparsemap_buf), size); + } + + static void __init sparse_buffer_init(unsigned long size, int nid) +diff --git a/mm/vmalloc.c b/mm/vmalloc.c +index 3cb1f59d1b53ea..840e25cab9344d 100644 +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -556,13 +556,13 @@ static int vmap_small_pages_range_noflush(unsigned long addr, unsigned long end, + mask |= PGTBL_PGD_MODIFIED; + err = vmap_pages_p4d_range(pgd, addr, next, prot, pages, &nr, &mask); + if (err) +- return err; ++ break; + } while (pgd++, addr = next, addr != end); + + if (mask & ARCH_PAGE_TABLE_SYNC_MASK) + arch_sync_kernel_mappings(start, end); + +- return 0; ++ return err; + } + + /* +diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c +index abaa5d96ded245..eba36453a51ad8 100644 +--- a/net/8021q/vlan.c ++++ b/net/8021q/vlan.c +@@ -131,7 +131,8 @@ int vlan_check_real_dev(struct net_device *real_dev, + { + const char *name = real_dev->name; + +- if (real_dev->features & NETIF_F_VLAN_CHALLENGED) { ++ if (real_dev->features & NETIF_F_VLAN_CHALLENGED || ++ real_dev->type != ARPHRD_ETHER) { + pr_info("VLANs not supported on %s\n", name); + NL_SET_ERR_MSG_MOD(extack, "VLANs not supported on device"); + return -EOPNOTSUPP; +diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c +index 54e41fc709c378..651e01b86141e3 100644 +--- a/net/batman-adv/bat_v.c ++++ b/net/batman-adv/bat_v.c +@@ -113,8 +113,6 @@ static void + batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh) + { + ewma_throughput_init(&hardif_neigh->bat_v.throughput); +- INIT_WORK(&hardif_neigh->bat_v.metric_work, +- batadv_v_elp_throughput_metric_update); + } + + /** +diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c +index 5c5ddacd81cb72..e077440d0ec574 100644 +--- a/net/batman-adv/bat_v_elp.c ++++ b/net/batman-adv/bat_v_elp.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -27,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -42,6 +44,18 @@ + #include "routing.h" + #include "send.h" + ++/** ++ * struct batadv_v_metric_queue_entry - list of hardif neighbors which require ++ * and metric update ++ */ ++struct batadv_v_metric_queue_entry { ++ /** @hardif_neigh: hardif neighbor scheduled for metric update */ ++ struct batadv_hardif_neigh_node *hardif_neigh; ++ ++ /** @list: list node for metric_queue */ ++ struct list_head list; ++}; ++ + /** + * batadv_v_elp_start_timer() - restart timer for ELP periodic work + * @hard_iface: the interface for which the timer has to be reset +@@ -60,25 +74,36 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface) + /** + * batadv_v_elp_get_throughput() - get the throughput towards a neighbour + * @neigh: the neighbour for which the throughput has to be obtained ++ * @pthroughput: calculated throughput towards the given neighbour in multiples ++ * of 100kpbs (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc). + * +- * Return: The throughput towards the given neighbour in multiples of 100kpbs +- * (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc). ++ * Return: true when value behind @pthroughput was set + */ +-static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) ++static bool batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh, ++ u32 *pthroughput) + { + struct batadv_hard_iface *hard_iface = neigh->if_incoming; ++ struct net_device *soft_iface = hard_iface->soft_iface; + struct ethtool_link_ksettings link_settings; + struct net_device *real_netdev; + struct station_info sinfo; + u32 throughput; + int ret; + ++ /* don't query throughput when no longer associated with any ++ * batman-adv interface ++ */ ++ if (!soft_iface) ++ return false; ++ + /* if the user specified a customised value for this interface, then + * return it directly + */ + throughput = atomic_read(&hard_iface->bat_v.throughput_override); +- if (throughput != 0) +- return throughput; ++ if (throughput != 0) { ++ *pthroughput = throughput; ++ return true; ++ } + + /* if this is a wireless device, then ask its throughput through + * cfg80211 API +@@ -105,28 +130,39 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) + * possible to delete this neighbor. For now set + * the throughput metric to 0. + */ +- return 0; ++ *pthroughput = 0; ++ return true; + } + if (ret) + goto default_throughput; + +- if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) +- return sinfo.expected_throughput / 100; ++ if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) { ++ *pthroughput = sinfo.expected_throughput / 100; ++ return true; ++ } + + /* try to estimate the expected throughput based on reported tx + * rates + */ +- if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)) +- return cfg80211_calculate_bitrate(&sinfo.txrate) / 3; ++ if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)) { ++ *pthroughput = cfg80211_calculate_bitrate(&sinfo.txrate) / 3; ++ return true; ++ } + + goto default_throughput; + } + ++ /* only use rtnl_trylock because the elp worker will be cancelled while ++ * the rntl_lock is held. the cancel_delayed_work_sync() would otherwise ++ * wait forever when the elp work_item was started and it is then also ++ * trying to rtnl_lock ++ */ ++ if (!rtnl_trylock()) ++ return false; ++ + /* if not a wifi interface, check if this device provides data via + * ethtool (e.g. an Ethernet adapter) + */ +- memset(&link_settings, 0, sizeof(link_settings)); +- rtnl_lock(); + ret = __ethtool_get_link_ksettings(hard_iface->net_dev, &link_settings); + rtnl_unlock(); + if (ret == 0) { +@@ -137,13 +173,15 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) + hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX; + + throughput = link_settings.base.speed; +- if (throughput && throughput != SPEED_UNKNOWN) +- return throughput * 10; ++ if (throughput && throughput != SPEED_UNKNOWN) { ++ *pthroughput = throughput * 10; ++ return true; ++ } + } + + default_throughput: + if (!(hard_iface->bat_v.flags & BATADV_WARNING_DEFAULT)) { +- batadv_info(hard_iface->soft_iface, ++ batadv_info(soft_iface, + "WiFi driver or ethtool info does not provide information about link speeds on interface %s, therefore defaulting to hardcoded throughput values of %u.%1u Mbps. Consider overriding the throughput manually or checking your driver.\n", + hard_iface->net_dev->name, + BATADV_THROUGHPUT_DEFAULT_VALUE / 10, +@@ -152,31 +190,26 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) + } + + /* if none of the above cases apply, return the base_throughput */ +- return BATADV_THROUGHPUT_DEFAULT_VALUE; ++ *pthroughput = BATADV_THROUGHPUT_DEFAULT_VALUE; ++ return true; + } + + /** + * batadv_v_elp_throughput_metric_update() - worker updating the throughput + * metric of a single hop neighbour +- * @work: the work queue item ++ * @neigh: the neighbour to probe + */ +-void batadv_v_elp_throughput_metric_update(struct work_struct *work) ++static void ++batadv_v_elp_throughput_metric_update(struct batadv_hardif_neigh_node *neigh) + { +- struct batadv_hardif_neigh_node_bat_v *neigh_bat_v; +- struct batadv_hardif_neigh_node *neigh; +- +- neigh_bat_v = container_of(work, struct batadv_hardif_neigh_node_bat_v, +- metric_work); +- neigh = container_of(neigh_bat_v, struct batadv_hardif_neigh_node, +- bat_v); ++ u32 throughput; ++ bool valid; + +- ewma_throughput_add(&neigh->bat_v.throughput, +- batadv_v_elp_get_throughput(neigh)); ++ valid = batadv_v_elp_get_throughput(neigh, &throughput); ++ if (!valid) ++ return; + +- /* decrement refcounter to balance increment performed before scheduling +- * this task +- */ +- batadv_hardif_neigh_put(neigh); ++ ewma_throughput_add(&neigh->bat_v.throughput, throughput); + } + + /** +@@ -250,14 +283,16 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh) + */ + static void batadv_v_elp_periodic_work(struct work_struct *work) + { ++ struct batadv_v_metric_queue_entry *metric_entry; ++ struct batadv_v_metric_queue_entry *metric_safe; + struct batadv_hardif_neigh_node *hardif_neigh; + struct batadv_hard_iface *hard_iface; + struct batadv_hard_iface_bat_v *bat_v; + struct batadv_elp_packet *elp_packet; ++ struct list_head metric_queue; + struct batadv_priv *bat_priv; + struct sk_buff *skb; + u32 elp_interval; +- bool ret; + + bat_v = container_of(work, struct batadv_hard_iface_bat_v, elp_wq.work); + hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v); +@@ -293,6 +328,8 @@ static void batadv_v_elp_periodic_work(struct work_struct *work) + + atomic_inc(&hard_iface->bat_v.elp_seqno); + ++ INIT_LIST_HEAD(&metric_queue); ++ + /* The throughput metric is updated on each sent packet. This way, if a + * node is dead and no longer sends packets, batman-adv is still able to + * react timely to its death. +@@ -317,16 +354,28 @@ static void batadv_v_elp_periodic_work(struct work_struct *work) + + /* Reading the estimated throughput from cfg80211 is a task that + * may sleep and that is not allowed in an rcu protected +- * context. Therefore schedule a task for that. ++ * context. Therefore add it to metric_queue and process it ++ * outside rcu protected context. + */ +- ret = queue_work(batadv_event_workqueue, +- &hardif_neigh->bat_v.metric_work); +- +- if (!ret) ++ metric_entry = kzalloc(sizeof(*metric_entry), GFP_ATOMIC); ++ if (!metric_entry) { + batadv_hardif_neigh_put(hardif_neigh); ++ continue; ++ } ++ ++ metric_entry->hardif_neigh = hardif_neigh; ++ list_add(&metric_entry->list, &metric_queue); + } + rcu_read_unlock(); + ++ list_for_each_entry_safe(metric_entry, metric_safe, &metric_queue, list) { ++ batadv_v_elp_throughput_metric_update(metric_entry->hardif_neigh); ++ ++ batadv_hardif_neigh_put(metric_entry->hardif_neigh); ++ list_del(&metric_entry->list); ++ kfree(metric_entry); ++ } ++ + restart_timer: + batadv_v_elp_start_timer(hard_iface); + out: +diff --git a/net/batman-adv/bat_v_elp.h b/net/batman-adv/bat_v_elp.h +index 9e2740195fa2d4..c9cb0a30710045 100644 +--- a/net/batman-adv/bat_v_elp.h ++++ b/net/batman-adv/bat_v_elp.h +@@ -10,7 +10,6 @@ + #include "main.h" + + #include +-#include + + int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface); + void batadv_v_elp_iface_disable(struct batadv_hard_iface *hard_iface); +@@ -19,6 +18,5 @@ void batadv_v_elp_iface_activate(struct batadv_hard_iface *primary_iface, + void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface); + int batadv_v_elp_packet_recv(struct sk_buff *skb, + struct batadv_hard_iface *if_incoming); +-void batadv_v_elp_throughput_metric_update(struct work_struct *work); + + #endif /* _NET_BATMAN_ADV_BAT_V_ELP_H_ */ +diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h +index 2635763bbd67a5..e659623b7a331a 100644 +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -596,9 +596,6 @@ struct batadv_hardif_neigh_node_bat_v { + * neighbor + */ + unsigned long last_unicast_tx; +- +- /** @metric_work: work queue callback item for metric update */ +- struct work_struct metric_work; + }; + + /** +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 496634c359eb7e..2d451009a64779 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -632,7 +632,8 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) + test_bit(FLAG_HOLD_HCI_CONN, &chan->flags)) + hci_conn_hold(conn->hcon); + +- list_add(&chan->list, &conn->chan_l); ++ /* Append to the list since the order matters for ECRED */ ++ list_add_tail(&chan->list, &conn->chan_l); + } + + void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) +@@ -3971,7 +3972,11 @@ static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data) + { + struct l2cap_ecred_rsp_data *rsp = data; + +- if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags)) ++ /* Check if channel for outgoing connection or if it wasn't deferred ++ * since in those cases it must be skipped. ++ */ ++ if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags) || ++ !test_and_clear_bit(FLAG_DEFER_SETUP, &chan->flags)) + return; + + /* Reset ident so only one response is sent */ +diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c +index 57035e46f71518..441dedd8277f5e 100644 +--- a/net/bluetooth/l2cap_sock.c ++++ b/net/bluetooth/l2cap_sock.c +@@ -727,12 +727,12 @@ static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) + { + switch (chan->scid) { + case L2CAP_CID_ATT: +- if (mtu < L2CAP_LE_MIN_MTU) ++ if (mtu && mtu < L2CAP_LE_MIN_MTU) + return false; + break; + + default: +- if (mtu < L2CAP_DEFAULT_MIN_MTU) ++ if (mtu && mtu < L2CAP_DEFAULT_MIN_MTU) + return false; + } + +@@ -1876,7 +1876,8 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, + chan = l2cap_chan_create(); + if (!chan) { + sk_free(sk); +- sock->sk = NULL; ++ if (sock) ++ sock->sk = NULL; + return NULL; + } + +diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c +index da538c29c749f2..d8ba84828f2341 100644 +--- a/net/can/j1939/socket.c ++++ b/net/can/j1939/socket.c +@@ -1130,7 +1130,7 @@ static int j1939_sk_send_loop(struct j1939_priv *priv, struct sock *sk, + + todo_size = size; + +- while (todo_size) { ++ do { + struct j1939_sk_buff_cb *skcb; + + segment_size = min_t(size_t, J1939_MAX_TP_PACKET_SIZE, +@@ -1175,7 +1175,7 @@ static int j1939_sk_send_loop(struct j1939_priv *priv, struct sock *sk, + + todo_size -= segment_size; + session->total_queued_size += segment_size; +- } ++ } while (todo_size); + + switch (ret) { + case 0: /* OK */ +diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c +index a58f6f5dfcf8e4..76d625c668e05f 100644 +--- a/net/can/j1939/transport.c ++++ b/net/can/j1939/transport.c +@@ -382,8 +382,9 @@ sk_buff *j1939_session_skb_get_by_offset(struct j1939_session *session, + skb_queue_walk(&session->skb_queue, do_skb) { + do_skcb = j1939_skb_to_cb(do_skb); + +- if (offset_start >= do_skcb->offset && +- offset_start < (do_skcb->offset + do_skb->len)) { ++ if ((offset_start >= do_skcb->offset && ++ offset_start < (do_skcb->offset + do_skb->len)) || ++ (offset_start == 0 && do_skcb->offset == 0 && do_skb->len == 0)) { + skb = do_skb; + } + } +diff --git a/net/core/dev.c b/net/core/dev.c +index 15ed4a79be46ff..81f9fd0c5830a6 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -972,6 +972,12 @@ int netdev_get_name(struct net *net, char *name, int ifindex) + return ret; + } + ++static bool dev_addr_cmp(struct net_device *dev, unsigned short type, ++ const char *ha) ++{ ++ return dev->type == type && !memcmp(dev->dev_addr, ha, dev->addr_len); ++} ++ + /** + * dev_getbyhwaddr_rcu - find a device by its hardware address + * @net: the applicable net namespace +@@ -980,7 +986,7 @@ int netdev_get_name(struct net *net, char *name, int ifindex) + * + * Search for an interface by MAC address. Returns NULL if the device + * is not found or a pointer to the device. +- * The caller must hold RCU or RTNL. ++ * The caller must hold RCU. + * The returned device has not had its ref count increased + * and the caller must therefore be careful about locking + * +@@ -992,14 +998,39 @@ struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type, + struct net_device *dev; + + for_each_netdev_rcu(net, dev) +- if (dev->type == type && +- !memcmp(dev->dev_addr, ha, dev->addr_len)) ++ if (dev_addr_cmp(dev, type, ha)) + return dev; + + return NULL; + } + EXPORT_SYMBOL(dev_getbyhwaddr_rcu); + ++/** ++ * dev_getbyhwaddr() - find a device by its hardware address ++ * @net: the applicable net namespace ++ * @type: media type of device ++ * @ha: hardware address ++ * ++ * Similar to dev_getbyhwaddr_rcu(), but the owner needs to hold ++ * rtnl_lock. ++ * ++ * Context: rtnl_lock() must be held. ++ * Return: pointer to the net_device, or NULL if not found ++ */ ++struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, ++ const char *ha) ++{ ++ struct net_device *dev; ++ ++ ASSERT_RTNL(); ++ for_each_netdev(net, dev) ++ if (dev_addr_cmp(dev, type, ha)) ++ return dev; ++ ++ return NULL; ++} ++EXPORT_SYMBOL(dev_getbyhwaddr); ++ + struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type) + { + struct net_device *dev, *ret = NULL; +diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c +index d9a6cdc48cb2c4..24ace3f94b56eb 100644 +--- a/net/core/drop_monitor.c ++++ b/net/core/drop_monitor.c +@@ -1729,30 +1729,30 @@ static int __init init_net_drop_monitor(void) + return -ENOSPC; + } + +- rc = genl_register_family(&net_drop_monitor_family); +- if (rc) { +- pr_err("Could not create drop monitor netlink family\n"); +- return rc; ++ for_each_possible_cpu(cpu) { ++ net_dm_cpu_data_init(cpu); ++ net_dm_hw_cpu_data_init(cpu); + } +- WARN_ON(net_drop_monitor_family.mcgrp_offset != NET_DM_GRP_ALERT); + + rc = register_netdevice_notifier(&dropmon_net_notifier); + if (rc < 0) { + pr_crit("Failed to register netdevice notifier\n"); ++ return rc; ++ } ++ ++ rc = genl_register_family(&net_drop_monitor_family); ++ if (rc) { ++ pr_err("Could not create drop monitor netlink family\n"); + goto out_unreg; + } ++ WARN_ON(net_drop_monitor_family.mcgrp_offset != NET_DM_GRP_ALERT); + + rc = 0; + +- for_each_possible_cpu(cpu) { +- net_dm_cpu_data_init(cpu); +- net_dm_hw_cpu_data_init(cpu); +- } +- + goto out; + + out_unreg: +- genl_unregister_family(&net_drop_monitor_family); ++ WARN_ON(unregister_netdevice_notifier(&dropmon_net_notifier)); + out: + return rc; + } +@@ -1761,19 +1761,18 @@ static void exit_net_drop_monitor(void) + { + int cpu; + +- BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier)); +- + /* + * Because of the module_get/put we do in the trace state change path + * we are guaranteed not to have any current users when we get here + */ ++ BUG_ON(genl_unregister_family(&net_drop_monitor_family)); ++ ++ BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier)); + + for_each_possible_cpu(cpu) { + net_dm_hw_cpu_data_fini(cpu); + net_dm_cpu_data_fini(cpu); + } +- +- BUG_ON(genl_unregister_family(&net_drop_monitor_family)); + } + + module_init(init_net_drop_monitor); +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index a1efbd0f2ad323..ba437cfcbe90fa 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -725,23 +725,30 @@ __skb_flow_dissect_ports(const struct sk_buff *skb, + void *target_container, const void *data, + int nhoff, u8 ip_proto, int hlen) + { +- enum flow_dissector_key_id dissector_ports = FLOW_DISSECTOR_KEY_MAX; +- struct flow_dissector_key_ports *key_ports; ++ struct flow_dissector_key_ports_range *key_ports_range = NULL; ++ struct flow_dissector_key_ports *key_ports = NULL; ++ __be32 ports; + + if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS)) +- dissector_ports = FLOW_DISSECTOR_KEY_PORTS; +- else if (dissector_uses_key(flow_dissector, +- FLOW_DISSECTOR_KEY_PORTS_RANGE)) +- dissector_ports = FLOW_DISSECTOR_KEY_PORTS_RANGE; ++ key_ports = skb_flow_dissector_target(flow_dissector, ++ FLOW_DISSECTOR_KEY_PORTS, ++ target_container); + +- if (dissector_ports == FLOW_DISSECTOR_KEY_MAX) ++ if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS_RANGE)) ++ key_ports_range = skb_flow_dissector_target(flow_dissector, ++ FLOW_DISSECTOR_KEY_PORTS_RANGE, ++ target_container); ++ ++ if (!key_ports && !key_ports_range) + return; + +- key_ports = skb_flow_dissector_target(flow_dissector, +- dissector_ports, +- target_container); +- key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto, +- data, hlen); ++ ports = __skb_flow_get_ports(skb, nhoff, ip_proto, data, hlen); ++ ++ if (key_ports) ++ key_ports->ports = ports; ++ ++ if (key_ports_range) ++ key_ports_range->tp.ports = ports; + } + + static void +@@ -796,6 +803,7 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys, + struct flow_dissector *flow_dissector, + void *target_container) + { ++ struct flow_dissector_key_ports_range *key_ports_range = NULL; + struct flow_dissector_key_ports *key_ports = NULL; + struct flow_dissector_key_control *key_control; + struct flow_dissector_key_basic *key_basic; +@@ -840,20 +848,21 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys, + key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; + } + +- if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS)) ++ if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS)) { + key_ports = skb_flow_dissector_target(flow_dissector, + FLOW_DISSECTOR_KEY_PORTS, + target_container); +- else if (dissector_uses_key(flow_dissector, +- FLOW_DISSECTOR_KEY_PORTS_RANGE)) +- key_ports = skb_flow_dissector_target(flow_dissector, +- FLOW_DISSECTOR_KEY_PORTS_RANGE, +- target_container); +- +- if (key_ports) { + key_ports->src = flow_keys->sport; + key_ports->dst = flow_keys->dport; + } ++ if (dissector_uses_key(flow_dissector, ++ FLOW_DISSECTOR_KEY_PORTS_RANGE)) { ++ key_ports_range = skb_flow_dissector_target(flow_dissector, ++ FLOW_DISSECTOR_KEY_PORTS_RANGE, ++ target_container); ++ key_ports_range->tp.src = flow_keys->sport; ++ key_ports_range->tp.dst = flow_keys->dport; ++ } + + if (dissector_uses_key(flow_dissector, + FLOW_DISSECTOR_KEY_FLOW_LABEL)) { +diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c +index fb11103fa8afcd..d8f19f4080f4a3 100644 +--- a/net/core/flow_offload.c ++++ b/net/core/flow_offload.c +@@ -104,6 +104,13 @@ void flow_rule_match_ports(const struct flow_rule *rule, + } + EXPORT_SYMBOL(flow_rule_match_ports); + ++void flow_rule_match_ports_range(const struct flow_rule *rule, ++ struct flow_match_ports_range *out) ++{ ++ FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_PORTS_RANGE, out); ++} ++EXPORT_SYMBOL(flow_rule_match_ports_range); ++ + void flow_rule_match_tcp(const struct flow_rule *rule, + struct flow_match_tcp *out) + { +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index 6f3bd1a4ec8ca6..9549738b818428 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -3369,10 +3369,12 @@ static const struct seq_operations neigh_stat_seq_ops = { + static void __neigh_notify(struct neighbour *n, int type, int flags, + u32 pid) + { +- struct net *net = dev_net(n->dev); + struct sk_buff *skb; + int err = -ENOBUFS; ++ struct net *net; + ++ rcu_read_lock(); ++ net = dev_net_rcu(n->dev); + skb = nlmsg_new(neigh_nlmsg_size(), GFP_ATOMIC); + if (skb == NULL) + goto errout; +@@ -3385,10 +3387,11 @@ static void __neigh_notify(struct neighbour *n, int type, int flags, + goto errout; + } + rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); +- return; ++ goto out; + errout: +- if (err < 0) +- rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); ++ rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); ++out: ++ rcu_read_unlock(); + } + + void neigh_app_ns(struct neighbour *n) +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 17073429cc3650..d4c821d97b5455 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -5558,11 +5558,11 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) + skb->offload_fwd_mark = 0; + skb->offload_l3_fwd_mark = 0; + #endif ++ ipvs_reset(skb); + + if (!xnet) + return; + +- ipvs_reset(skb); + skb->mark = 0; + skb->tstamp = 0; + } +diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c +index ed20cbdd19315f..60ea97aaea7d99 100644 +--- a/net/core/sysctl_net_core.c ++++ b/net/core/sysctl_net_core.c +@@ -240,7 +240,7 @@ static int proc_do_dev_weight(struct ctl_table *table, int write, + int ret, weight; + + mutex_lock(&dev_weight_mutex); +- ret = proc_dointvec(table, write, buffer, lenp, ppos); ++ ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + if (!ret && write) { + weight = READ_ONCE(weight_p); + WRITE_ONCE(dev_rx_weight, weight * dev_weight_rx_bias); +@@ -351,6 +351,7 @@ static struct ctl_table net_core_table[] = { + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_do_dev_weight, ++ .extra1 = SYSCTL_ONE, + }, + { + .procname = "dev_weight_rx_bias", +@@ -358,6 +359,7 @@ static struct ctl_table net_core_table[] = { + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_do_dev_weight, ++ .extra1 = SYSCTL_ONE, + }, + { + .procname = "dev_weight_tx_bias", +@@ -365,6 +367,7 @@ static struct ctl_table net_core_table[] = { + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_do_dev_weight, ++ .extra1 = SYSCTL_ONE, + }, + { + .procname = "netdev_max_backlog", +diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c +index b3729bdafb602a..0ffcd0e873b601 100644 +--- a/net/ethtool/netlink.c ++++ b/net/ethtool/netlink.c +@@ -41,7 +41,7 @@ int ethnl_ops_begin(struct net_device *dev) + pm_runtime_get_sync(dev->dev.parent); + + if (!netif_device_present(dev) || +- dev->reg_state == NETREG_UNREGISTERING) { ++ dev->reg_state >= NETREG_UNREGISTERING) { + ret = -ENODEV; + goto err; + } +diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c +index 20d4c3f8d8750b..3de280a0dab2b1 100644 +--- a/net/hsr/hsr_forward.c ++++ b/net/hsr/hsr_forward.c +@@ -546,9 +546,12 @@ static int fill_frame_info(struct hsr_frame_info *frame, + frame->is_vlan = true; + + if (frame->is_vlan) { +- if (skb->mac_len < offsetofend(struct hsr_vlan_ethhdr, vlanhdr)) ++ /* Note: skb->mac_len might be wrong here. */ ++ if (!pskb_may_pull(skb, ++ skb_mac_offset(skb) + ++ offsetofend(struct hsr_vlan_ethhdr, vlanhdr))) + return -EINVAL; +- vlan_hdr = (struct hsr_vlan_ethhdr *)ethhdr; ++ vlan_hdr = (struct hsr_vlan_ethhdr *)skb_mac_header(skb); + proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto; + /* FIXME: */ + netdev_warn_once(skb->dev, "VLAN not yet supported"); +diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c +index 8ae9bd6f91c19c..ef693218867986 100644 +--- a/net/ipv4/arp.c ++++ b/net/ipv4/arp.c +@@ -637,10 +637,12 @@ static int arp_xmit_finish(struct net *net, struct sock *sk, struct sk_buff *skb + */ + void arp_xmit(struct sk_buff *skb) + { ++ rcu_read_lock(); + /* Send it off, maybe filter it using firewalling first. */ + NF_HOOK(NFPROTO_ARP, NF_ARP_OUT, +- dev_net(skb->dev), NULL, skb, NULL, skb->dev, ++ dev_net_rcu(skb->dev), NULL, skb, NULL, skb->dev, + arp_xmit_finish); ++ rcu_read_unlock(); + } + EXPORT_SYMBOL(arp_xmit); + +@@ -1007,7 +1009,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r, + if (mask && mask != htonl(0xFFFFFFFF)) + return -EINVAL; + if (!dev && (r->arp_flags & ATF_COM)) { +- dev = dev_getbyhwaddr_rcu(net, r->arp_ha.sa_family, ++ dev = dev_getbyhwaddr(net, r->arp_ha.sa_family, + r->arp_ha.sa_data); + if (!dev) + return -ENODEV; +diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c +index dcbc087fff1791..33e87b442b475e 100644 +--- a/net/ipv4/devinet.c ++++ b/net/ipv4/devinet.c +@@ -1316,10 +1316,11 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope) + __be32 addr = 0; + unsigned char localnet_scope = RT_SCOPE_HOST; + struct in_device *in_dev; +- struct net *net = dev_net(dev); ++ struct net *net; + int master_idx; + + rcu_read_lock(); ++ net = dev_net_rcu(dev); + in_dev = __in_dev_get_rcu(dev); + if (!in_dev) + goto no_in_dev; +diff --git a/net/ipv4/ipmr_base.c b/net/ipv4/ipmr_base.c +index c45cb7cb575908..8b5b6f196cdc44 100644 +--- a/net/ipv4/ipmr_base.c ++++ b/net/ipv4/ipmr_base.c +@@ -321,9 +321,6 @@ int mr_table_dump(struct mr_table *mrt, struct sk_buff *skb, + list_for_each_entry(mfc, &mrt->mfc_unres_queue, list) { + if (e < s_e) + goto next_entry2; +- if (filter->dev && +- !mr_mfc_uses_dev(mrt, mfc, filter->dev)) +- goto next_entry2; + + err = fill(mrt, skb, NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, mfc, RTM_NEWROUTE, flags); +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 35228018857877..a4884d434038e5 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -118,14 +118,15 @@ + + #define RT_GC_TIMEOUT (300*HZ) + ++#define DEFAULT_MIN_PMTU (512 + 20 + 20) ++#define DEFAULT_MTU_EXPIRES (10 * 60 * HZ) ++ + static int ip_rt_max_size; + static int ip_rt_redirect_number __read_mostly = 9; + static int ip_rt_redirect_load __read_mostly = HZ / 50; + static int ip_rt_redirect_silence __read_mostly = ((HZ / 50) << (9 + 1)); + static int ip_rt_error_cost __read_mostly = HZ; + static int ip_rt_error_burst __read_mostly = 5 * HZ; +-static int ip_rt_mtu_expires __read_mostly = 10 * 60 * HZ; +-static u32 ip_rt_min_pmtu __read_mostly = 512 + 20 + 20; + static int ip_rt_min_advmss __read_mostly = 256; + + static int ip_rt_gc_timeout __read_mostly = RT_GC_TIMEOUT; +@@ -400,7 +401,13 @@ static inline int ip_rt_proc_init(void) + + static inline bool rt_is_expired(const struct rtable *rth) + { +- return rth->rt_genid != rt_genid_ipv4(dev_net(rth->dst.dev)); ++ bool res; ++ ++ rcu_read_lock(); ++ res = rth->rt_genid != rt_genid_ipv4(dev_net_rcu(rth->dst.dev)); ++ rcu_read_unlock(); ++ ++ return res; + } + + void rt_cache_flush(struct net *net) +@@ -1016,9 +1023,9 @@ out: kfree_skb(skb); + static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) + { + struct dst_entry *dst = &rt->dst; +- struct net *net = dev_net(dst->dev); + struct fib_result res; + bool lock = false; ++ struct net *net; + u32 old_mtu; + + if (ip_mtu_locked(dst)) +@@ -1028,24 +1035,38 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) + if (old_mtu < mtu) + return; + +- if (mtu < ip_rt_min_pmtu) { ++ rcu_read_lock(); ++ net = dev_net_rcu(dst->dev); ++ if (mtu < net->ipv4.ip_rt_min_pmtu) { + lock = true; +- mtu = min(old_mtu, ip_rt_min_pmtu); ++ mtu = min(old_mtu, net->ipv4.ip_rt_min_pmtu); + } + + if (rt->rt_pmtu == mtu && !lock && +- time_before(jiffies, dst->expires - ip_rt_mtu_expires / 2)) +- return; ++ time_before(jiffies, dst->expires - net->ipv4.ip_rt_mtu_expires / 2)) ++ goto out; + +- rcu_read_lock(); + if (fib_lookup(net, fl4, &res, 0) == 0) { + struct fib_nh_common *nhc; + + fib_select_path(net, &res, fl4, NULL); ++#ifdef CONFIG_IP_ROUTE_MULTIPATH ++ if (fib_info_num_path(res.fi) > 1) { ++ int nhsel; ++ ++ for (nhsel = 0; nhsel < fib_info_num_path(res.fi); nhsel++) { ++ nhc = fib_info_nhc(res.fi, nhsel); ++ update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock, ++ jiffies + net->ipv4.ip_rt_mtu_expires); ++ } ++ goto out; ++ } ++#endif /* CONFIG_IP_ROUTE_MULTIPATH */ + nhc = FIB_RES_NHC(res); + update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock, +- jiffies + ip_rt_mtu_expires); ++ jiffies + net->ipv4.ip_rt_mtu_expires); + } ++out: + rcu_read_unlock(); + } + +@@ -3565,21 +3586,6 @@ static struct ctl_table ipv4_route_table[] = { + .mode = 0644, + .proc_handler = proc_dointvec, + }, +- { +- .procname = "mtu_expires", +- .data = &ip_rt_mtu_expires, +- .maxlen = sizeof(int), +- .mode = 0644, +- .proc_handler = proc_dointvec_jiffies, +- }, +- { +- .procname = "min_pmtu", +- .data = &ip_rt_min_pmtu, +- .maxlen = sizeof(int), +- .mode = 0644, +- .proc_handler = proc_dointvec_minmax, +- .extra1 = &ip_min_valid_pmtu, +- }, + { + .procname = "min_adv_mss", + .data = &ip_rt_min_advmss, +@@ -3592,13 +3598,28 @@ static struct ctl_table ipv4_route_table[] = { + + static const char ipv4_route_flush_procname[] = "flush"; + +-static struct ctl_table ipv4_route_flush_table[] = { ++static struct ctl_table ipv4_route_netns_table[] = { + { + .procname = ipv4_route_flush_procname, + .maxlen = sizeof(int), + .mode = 0200, + .proc_handler = ipv4_sysctl_rtcache_flush, + }, ++ { ++ .procname = "min_pmtu", ++ .data = &init_net.ipv4.ip_rt_min_pmtu, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = &ip_min_valid_pmtu, ++ }, ++ { ++ .procname = "mtu_expires", ++ .data = &init_net.ipv4.ip_rt_mtu_expires, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec_jiffies, ++ }, + { }, + }; + +@@ -3606,9 +3627,11 @@ static __net_init int sysctl_route_net_init(struct net *net) + { + struct ctl_table *tbl; + +- tbl = ipv4_route_flush_table; ++ tbl = ipv4_route_netns_table; + if (!net_eq(net, &init_net)) { +- tbl = kmemdup(tbl, sizeof(ipv4_route_flush_table), GFP_KERNEL); ++ int i; ++ ++ tbl = kmemdup(tbl, sizeof(ipv4_route_netns_table), GFP_KERNEL); + if (!tbl) + goto err_dup; + +@@ -3617,6 +3640,12 @@ static __net_init int sysctl_route_net_init(struct net *net) + if (tbl[0].procname != ipv4_route_flush_procname) + tbl[0].procname = NULL; + } ++ ++ /* Update the variables to point into the current struct net ++ * except for the first element flush ++ */ ++ for (i = 1; i < ARRAY_SIZE(ipv4_route_netns_table) - 1; i++) ++ tbl[i].data += (void *)net - (void *)&init_net; + } + tbl[0].extra1 = net; + +@@ -3626,7 +3655,7 @@ static __net_init int sysctl_route_net_init(struct net *net) + return 0; + + err_reg: +- if (tbl != ipv4_route_flush_table) ++ if (tbl != ipv4_route_netns_table) + kfree(tbl); + err_dup: + return -ENOMEM; +@@ -3638,7 +3667,7 @@ static __net_exit void sysctl_route_net_exit(struct net *net) + + tbl = net->ipv4.route_hdr->ctl_table_arg; + unregister_net_sysctl_table(net->ipv4.route_hdr); +- BUG_ON(tbl == ipv4_route_flush_table); ++ BUG_ON(tbl == ipv4_route_netns_table); + kfree(tbl); + } + +@@ -3648,6 +3677,18 @@ static __net_initdata struct pernet_operations sysctl_route_ops = { + }; + #endif + ++static __net_init int netns_ip_rt_init(struct net *net) ++{ ++ /* Set default value for namespaceified sysctls */ ++ net->ipv4.ip_rt_min_pmtu = DEFAULT_MIN_PMTU; ++ net->ipv4.ip_rt_mtu_expires = DEFAULT_MTU_EXPIRES; ++ return 0; ++} ++ ++static struct pernet_operations __net_initdata ip_rt_ops = { ++ .init = netns_ip_rt_init, ++}; ++ + static __net_init int rt_genid_init(struct net *net) + { + atomic_set(&net->ipv4.rt_genid, 0); +@@ -3753,6 +3794,7 @@ int __init ip_rt_init(void) + #ifdef CONFIG_SYSCTL + register_pernet_subsys(&sysctl_route_ops); + #endif ++ register_pernet_subsys(&ip_rt_ops); + register_pernet_subsys(&rt_genid_ops); + register_pernet_subsys(&ipv4_inetpeer_ops); + return 0; +diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c +index af4fc067f2a199..741a15799ab35a 100644 +--- a/net/ipv4/tcp_cubic.c ++++ b/net/ipv4/tcp_cubic.c +@@ -390,6 +390,10 @@ static void hystart_update(struct sock *sk, u32 delay) + if (after(tp->snd_una, ca->end_seq)) + bictcp_hystart_reset(sk); + ++ /* hystart triggers when cwnd is larger than some threshold */ ++ if (tcp_snd_cwnd(tp) < hystart_low_window) ++ return; ++ + if (hystart_detect & HYSTART_ACK_TRAIN) { + u32 now = bictcp_clock_us(sk); + +@@ -465,9 +469,7 @@ static void cubictcp_acked(struct sock *sk, const struct ack_sample *sample) + if (ca->delay_min == 0 || ca->delay_min > delay) + ca->delay_min = delay; + +- /* hystart triggers when cwnd is larger than some threshold */ +- if (!ca->found && tcp_in_slow_start(tp) && hystart && +- tcp_snd_cwnd(tp) >= hystart_low_window) ++ if (!ca->found && tcp_in_slow_start(tp) && hystart) + hystart_update(sk, delay); + } + +diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c +index d84b71f70766b2..061225d645e6b9 100644 +--- a/net/ipv4/tcp_minisocks.c ++++ b/net/ipv4/tcp_minisocks.c +@@ -725,12 +725,6 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, + + /* In sequence, PAWS is OK. */ + +- /* TODO: We probably should defer ts_recent change once +- * we take ownership of @req. +- */ +- if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt)) +- WRITE_ONCE(req->ts_recent, tmp_opt.rcv_tsval); +- + if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) { + /* Truncate SYN, it is out of window starting + at tcp_rsk(req)->rcv_isn + 1. */ +@@ -779,6 +773,10 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, + if (!child) + goto listen_overflow; + ++ if (own_req && tmp_opt.saw_tstamp && ++ !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt)) ++ tcp_sk(child)->rx_opt.ts_recent = tmp_opt.rcv_tsval; ++ + if (own_req && rsk_drop_req(req)) { + reqsk_queue_removed(&inet_csk(req->rsk_listener)->icsk_accept_queue, req); + inet_csk_reqsk_queue_drop_and_put(req->rsk_listener, req); +diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c +index 357d3be04f84cb..20267290f555c7 100644 +--- a/net/ipv4/tcp_offload.c ++++ b/net/ipv4/tcp_offload.c +@@ -11,12 +11,15 @@ + #include + #include + +-static void tcp_gso_tstamp(struct sk_buff *skb, unsigned int ts_seq, ++static void tcp_gso_tstamp(struct sk_buff *skb, struct sk_buff *gso_skb, + unsigned int seq, unsigned int mss) + { ++ u32 flags = skb_shinfo(gso_skb)->tx_flags & SKBTX_ANY_TSTAMP; ++ u32 ts_seq = skb_shinfo(gso_skb)->tskey; ++ + while (skb) { + if (before(ts_seq, seq + mss)) { +- skb_shinfo(skb)->tx_flags |= SKBTX_SW_TSTAMP; ++ skb_shinfo(skb)->tx_flags |= flags; + skb_shinfo(skb)->tskey = ts_seq; + return; + } +@@ -118,8 +121,8 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb, + th = tcp_hdr(skb); + seq = ntohl(th->seq); + +- if (unlikely(skb_shinfo(gso_skb)->tx_flags & SKBTX_SW_TSTAMP)) +- tcp_gso_tstamp(segs, skb_shinfo(gso_skb)->tskey, seq, mss); ++ if (unlikely(skb_shinfo(gso_skb)->tx_flags & SKBTX_ANY_TSTAMP)) ++ tcp_gso_tstamp(segs, gso_skb, seq, mss); + + newcheck = ~csum_fold((__force __wsum)((__force u32)th->check + + (__force u32)delta)); +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 138fef35e70718..51a12fa486b6b2 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -937,9 +937,9 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4, + const int hlen = skb_network_header_len(skb) + + sizeof(struct udphdr); + +- if (hlen + cork->gso_size > cork->fragsize) { ++ if (hlen + min(datalen, cork->gso_size) > cork->fragsize) { + kfree_skb(skb); +- return -EINVAL; ++ return -EMSGSIZE; + } + if (datalen > cork->gso_size * UDP_MAX_SEGMENTS) { + kfree_skb(skb); +diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c +index 19a413aad0636a..1a57dd8aa513ba 100644 +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -295,13 +295,17 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, + + /* clear destructor to avoid skb_segment assigning it to tail */ + copy_dtor = gso_skb->destructor == sock_wfree; +- if (copy_dtor) ++ if (copy_dtor) { + gso_skb->destructor = NULL; ++ gso_skb->sk = NULL; ++ } + + segs = skb_segment(gso_skb, features); + if (IS_ERR_OR_NULL(segs)) { +- if (copy_dtor) ++ if (copy_dtor) { + gso_skb->destructor = sock_wfree; ++ gso_skb->sk = sk; ++ } + return segs; + } + +diff --git a/net/ipv6/ila/ila_lwt.c b/net/ipv6/ila/ila_lwt.c +index 9d37f7164e732e..7397f764c66cca 100644 +--- a/net/ipv6/ila/ila_lwt.c ++++ b/net/ipv6/ila/ila_lwt.c +@@ -88,13 +88,15 @@ static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb) + goto drop; + } + +- if (ilwt->connected) { ++ /* cache only if we don't create a dst reference loop */ ++ if (ilwt->connected && orig_dst->lwtstate != dst->lwtstate) { + local_bh_disable(); + dst_cache_set_ip6(&ilwt->dst_cache, dst, &fl6.saddr); + local_bh_enable(); + } + } + ++ skb_dst_drop(skb); + skb_dst_set(skb, dst); + return dst_output(net, sk, skb); + +diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c +index 6e5d1ade48a89f..1d038a08409941 100644 +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -1731,21 +1731,19 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) + struct net_device *dev = idev->dev; + int hlen = LL_RESERVED_SPACE(dev); + int tlen = dev->needed_tailroom; +- struct net *net = dev_net(dev); + const struct in6_addr *saddr; + struct in6_addr addr_buf; + struct mld2_report *pmr; + struct sk_buff *skb; + unsigned int size; + struct sock *sk; +- int err; ++ struct net *net; + +- sk = net->ipv6.igmp_sk; + /* we assume size > sizeof(ra) here + * Also try to not allocate high-order pages for big MTU + */ + size = min_t(int, mtu, PAGE_SIZE / 2) + hlen + tlen; +- skb = sock_alloc_send_skb(sk, size, 1, &err); ++ skb = alloc_skb(size, GFP_KERNEL); + if (!skb) + return NULL; + +@@ -1753,6 +1751,12 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) + skb_reserve(skb, hlen); + skb_tailroom_reserve(skb, mtu, tlen); + ++ rcu_read_lock(); ++ ++ net = dev_net_rcu(dev); ++ sk = net->ipv6.igmp_sk; ++ skb_set_owner_w(skb, sk); ++ + if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { + /* : + * use unspecified address as the source address +@@ -1764,6 +1768,8 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) + + ip6_mc_hdr(sk, skb, dev, saddr, &mld2_all_mcr, NEXTHDR_HOP, 0); + ++ rcu_read_unlock(); ++ + skb_put_data(skb, ra, sizeof(ra)); + + skb_set_transport_header(skb, skb_tail_pointer(skb) - skb->data); +diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c +index d56e80741c5ba2..af584e879467eb 100644 +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -417,15 +417,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev, + { + int hlen = LL_RESERVED_SPACE(dev); + int tlen = dev->needed_tailroom; +- struct sock *sk = dev_net(dev)->ipv6.ndisc_sk; + struct sk_buff *skb; + + skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC); +- if (!skb) { +- ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n", +- __func__); ++ if (!skb) + return NULL; +- } + + skb->protocol = htons(ETH_P_IPV6); + skb->dev = dev; +@@ -436,7 +432,9 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev, + /* Manually assign socket ownership as we avoid calling + * sock_alloc_send_pskb() to bypass wmem buffer limits + */ +- skb_set_owner_w(skb, sk); ++ rcu_read_lock(); ++ skb_set_owner_w(skb, dev_net_rcu(dev)->ipv6.ndisc_sk); ++ rcu_read_unlock(); + + return skb; + } +@@ -473,16 +471,20 @@ static void ndisc_send_skb(struct sk_buff *skb, + const struct in6_addr *daddr, + const struct in6_addr *saddr) + { ++ struct icmp6hdr *icmp6h = icmp6_hdr(skb); + struct dst_entry *dst = skb_dst(skb); +- struct net *net = dev_net(skb->dev); +- struct sock *sk = net->ipv6.ndisc_sk; + struct inet6_dev *idev; ++ struct net *net; ++ struct sock *sk; + int err; +- struct icmp6hdr *icmp6h = icmp6_hdr(skb); + u8 type; + + type = icmp6h->icmp6_type; + ++ rcu_read_lock(); ++ ++ net = dev_net_rcu(skb->dev); ++ sk = net->ipv6.ndisc_sk; + if (!dst) { + struct flowi6 fl6; + int oif = skb->dev->ifindex; +@@ -490,6 +492,7 @@ static void ndisc_send_skb(struct sk_buff *skb, + icmpv6_flow_init(sk, &fl6, type, saddr, daddr, oif); + dst = icmp6_dst_alloc(skb->dev, &fl6); + if (IS_ERR(dst)) { ++ rcu_read_unlock(); + kfree_skb(skb); + return; + } +@@ -504,7 +507,6 @@ static void ndisc_send_skb(struct sk_buff *skb, + + ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, skb->len); + +- rcu_read_lock(); + idev = __in6_dev_get(dst->dev); + IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); + +@@ -1619,7 +1621,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) + bool ret; + + if (netif_is_l3_master(skb->dev)) { +- dev = __dev_get_by_index(dev_net(skb->dev), IPCB(skb)->iif); ++ dev = dev_get_by_index_rcu(dev_net(skb->dev), IPCB(skb)->iif); + if (!dev) + return; + } +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index b7f494cca3e5c0..94526436b91e83 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3184,13 +3184,18 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst) + { + struct net_device *dev = dst->dev; + unsigned int mtu = dst_mtu(dst); +- struct net *net = dev_net(dev); ++ struct net *net; + + mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); + ++ rcu_read_lock(); ++ ++ net = dev_net_rcu(dev); + if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss) + mtu = net->ipv6.sysctl.ip6_rt_min_advmss; + ++ rcu_read_unlock(); ++ + /* + * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and + * corresponding MSS is IPV6_MAXPLEN - tcp_header_size. +diff --git a/net/ipv6/rpl_iptunnel.c b/net/ipv6/rpl_iptunnel.c +index c1d0f947a7c870..6bf95aba0efcec 100644 +--- a/net/ipv6/rpl_iptunnel.c ++++ b/net/ipv6/rpl_iptunnel.c +@@ -125,7 +125,8 @@ static void rpl_destroy_state(struct lwtunnel_state *lwt) + } + + static int rpl_do_srh_inline(struct sk_buff *skb, const struct rpl_lwt *rlwt, +- const struct ipv6_rpl_sr_hdr *srh) ++ const struct ipv6_rpl_sr_hdr *srh, ++ struct dst_entry *cache_dst) + { + struct ipv6_rpl_sr_hdr *isrh, *csrh; + const struct ipv6hdr *oldhdr; +@@ -153,7 +154,7 @@ static int rpl_do_srh_inline(struct sk_buff *skb, const struct rpl_lwt *rlwt, + + hdrlen = ((csrh->hdrlen + 1) << 3); + +- err = skb_cow_head(skb, hdrlen + skb->mac_len); ++ err = skb_cow_head(skb, hdrlen + dst_dev_overhead(cache_dst, skb)); + if (unlikely(err)) { + kfree(buf); + return err; +@@ -186,7 +187,8 @@ static int rpl_do_srh_inline(struct sk_buff *skb, const struct rpl_lwt *rlwt, + return 0; + } + +-static int rpl_do_srh(struct sk_buff *skb, const struct rpl_lwt *rlwt) ++static int rpl_do_srh(struct sk_buff *skb, const struct rpl_lwt *rlwt, ++ struct dst_entry *cache_dst) + { + struct dst_entry *dst = skb_dst(skb); + struct rpl_iptunnel_encap *tinfo; +@@ -196,7 +198,7 @@ static int rpl_do_srh(struct sk_buff *skb, const struct rpl_lwt *rlwt) + + tinfo = rpl_encap_lwtunnel(dst->lwtstate); + +- return rpl_do_srh_inline(skb, rlwt, tinfo->srh); ++ return rpl_do_srh_inline(skb, rlwt, tinfo->srh, cache_dst); + } + + static int rpl_output(struct net *net, struct sock *sk, struct sk_buff *skb) +@@ -208,14 +210,14 @@ static int rpl_output(struct net *net, struct sock *sk, struct sk_buff *skb) + + rlwt = rpl_lwt_lwtunnel(orig_dst->lwtstate); + +- err = rpl_do_srh(skb, rlwt); +- if (unlikely(err)) +- goto drop; +- + local_bh_disable(); + dst = dst_cache_get(&rlwt->cache); + local_bh_enable(); + ++ err = rpl_do_srh(skb, rlwt, dst); ++ if (unlikely(err)) ++ goto drop; ++ + if (unlikely(!dst)) { + struct ipv6hdr *hdr = ipv6_hdr(skb); + struct flowi6 fl6; +@@ -230,25 +232,25 @@ static int rpl_output(struct net *net, struct sock *sk, struct sk_buff *skb) + dst = ip6_route_output(net, NULL, &fl6); + if (dst->error) { + err = dst->error; +- dst_release(dst); + goto drop; + } + + local_bh_disable(); + dst_cache_set_ip6(&rlwt->cache, dst, &fl6.saddr); + local_bh_enable(); ++ ++ err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); ++ if (unlikely(err)) ++ goto drop; + } + + skb_dst_drop(skb); + skb_dst_set(skb, dst); + +- err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); +- if (unlikely(err)) +- goto drop; +- + return dst_output(net, sk, skb); + + drop: ++ dst_release(dst); + kfree_skb(skb); + return err; + } +@@ -257,35 +259,49 @@ static int rpl_input(struct sk_buff *skb) + { + struct dst_entry *orig_dst = skb_dst(skb); + struct dst_entry *dst = NULL; ++ struct lwtunnel_state *lwtst; + struct rpl_lwt *rlwt; + int err; + +- rlwt = rpl_lwt_lwtunnel(orig_dst->lwtstate); ++ /* We cannot dereference "orig_dst" once ip6_route_input() or ++ * skb_dst_drop() is called. However, in order to detect a dst loop, we ++ * need the address of its lwtstate. So, save the address of lwtstate ++ * now and use it later as a comparison. ++ */ ++ lwtst = orig_dst->lwtstate; + +- err = rpl_do_srh(skb, rlwt); +- if (unlikely(err)) +- goto drop; ++ rlwt = rpl_lwt_lwtunnel(lwtst); + + local_bh_disable(); + dst = dst_cache_get(&rlwt->cache); ++ local_bh_enable(); ++ ++ err = rpl_do_srh(skb, rlwt, dst); ++ if (unlikely(err)) { ++ dst_release(dst); ++ goto drop; ++ } + + skb_dst_drop(skb); + + if (!dst) { + ip6_route_input(skb); + dst = skb_dst(skb); +- if (!dst->error) { ++ ++ /* cache only if we don't create a dst reference loop */ ++ if (!dst->error && lwtst != dst->lwtstate) { ++ local_bh_disable(); + dst_cache_set_ip6(&rlwt->cache, dst, + &ipv6_hdr(skb)->saddr); ++ local_bh_enable(); + } ++ ++ err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); ++ if (unlikely(err)) ++ goto drop; + } else { + skb_dst_set(skb, dst); + } +- local_bh_enable(); +- +- err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); +- if (unlikely(err)) +- goto drop; + + return dst_input(skb); + +diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c +index 135712649d25fa..4188c167548396 100644 +--- a/net/ipv6/seg6_iptunnel.c ++++ b/net/ipv6/seg6_iptunnel.c +@@ -36,9 +36,11 @@ static size_t seg6_lwt_headroom(struct seg6_iptunnel_encap *tuninfo) + case SEG6_IPTUN_MODE_INLINE: + break; + case SEG6_IPTUN_MODE_ENCAP: ++ case SEG6_IPTUN_MODE_ENCAP_RED: + head = sizeof(struct ipv6hdr); + break; + case SEG6_IPTUN_MODE_L2ENCAP: ++ case SEG6_IPTUN_MODE_L2ENCAP_RED: + return 0; + } + +@@ -122,8 +124,8 @@ static __be32 seg6_make_flowlabel(struct net *net, struct sk_buff *skb, + return flowlabel; + } + +-/* encapsulate an IPv6 packet within an outer IPv6 header with a given SRH */ +-int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) ++static int __seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, ++ int proto, struct dst_entry *cache_dst) + { + struct dst_entry *dst = skb_dst(skb); + struct net *net = dev_net(dst->dev); +@@ -135,7 +137,7 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) + hdrlen = (osrh->hdrlen + 1) << 3; + tot_len = hdrlen + sizeof(*hdr); + +- err = skb_cow_head(skb, tot_len + skb->mac_len); ++ err = skb_cow_head(skb, tot_len + dst_dev_overhead(cache_dst, skb)); + if (unlikely(err)) + return err; + +@@ -195,10 +197,135 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) + + return 0; + } ++ ++/* encapsulate an IPv6 packet within an outer IPv6 header with a given SRH */ ++int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) ++{ ++ return __seg6_do_srh_encap(skb, osrh, proto, NULL); ++} + EXPORT_SYMBOL_GPL(seg6_do_srh_encap); + +-/* insert an SRH within an IPv6 packet, just after the IPv6 header */ +-int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) ++/* encapsulate an IPv6 packet within an outer IPv6 header with reduced SRH */ ++static int seg6_do_srh_encap_red(struct sk_buff *skb, ++ struct ipv6_sr_hdr *osrh, int proto, ++ struct dst_entry *cache_dst) ++{ ++ __u8 first_seg = osrh->first_segment; ++ struct dst_entry *dst = skb_dst(skb); ++ struct net *net = dev_net(dst->dev); ++ struct ipv6hdr *hdr, *inner_hdr; ++ int hdrlen = ipv6_optlen(osrh); ++ int red_tlv_offset, tlv_offset; ++ struct ipv6_sr_hdr *isrh; ++ bool skip_srh = false; ++ __be32 flowlabel; ++ int tot_len, err; ++ int red_hdrlen; ++ int tlvs_len; ++ ++ if (first_seg > 0) { ++ red_hdrlen = hdrlen - sizeof(struct in6_addr); ++ } else { ++ /* NOTE: if tag/flags and/or other TLVs are introduced in the ++ * seg6_iptunnel infrastructure, they should be considered when ++ * deciding to skip the SRH. ++ */ ++ skip_srh = !sr_has_hmac(osrh); ++ ++ red_hdrlen = skip_srh ? 0 : hdrlen; ++ } ++ ++ tot_len = red_hdrlen + sizeof(struct ipv6hdr); ++ ++ err = skb_cow_head(skb, tot_len + dst_dev_overhead(cache_dst, skb)); ++ if (unlikely(err)) ++ return err; ++ ++ inner_hdr = ipv6_hdr(skb); ++ flowlabel = seg6_make_flowlabel(net, skb, inner_hdr); ++ ++ skb_push(skb, tot_len); ++ skb_reset_network_header(skb); ++ skb_mac_header_rebuild(skb); ++ hdr = ipv6_hdr(skb); ++ ++ /* based on seg6_do_srh_encap() */ ++ if (skb->protocol == htons(ETH_P_IPV6)) { ++ ip6_flow_hdr(hdr, ip6_tclass(ip6_flowinfo(inner_hdr)), ++ flowlabel); ++ hdr->hop_limit = inner_hdr->hop_limit; ++ } else { ++ ip6_flow_hdr(hdr, 0, flowlabel); ++ hdr->hop_limit = ip6_dst_hoplimit(skb_dst(skb)); ++ ++ memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); ++ IP6CB(skb)->iif = skb->skb_iif; ++ } ++ ++ /* no matter if we have to skip the SRH or not, the first segment ++ * always comes in the pushed IPv6 header. ++ */ ++ hdr->daddr = osrh->segments[first_seg]; ++ ++ if (skip_srh) { ++ hdr->nexthdr = proto; ++ ++ set_tun_src(net, dst->dev, &hdr->daddr, &hdr->saddr); ++ goto out; ++ } ++ ++ /* we cannot skip the SRH, slow path */ ++ ++ hdr->nexthdr = NEXTHDR_ROUTING; ++ isrh = (void *)hdr + sizeof(struct ipv6hdr); ++ ++ if (unlikely(!first_seg)) { ++ /* this is a very rare case; we have only one SID but ++ * we cannot skip the SRH since we are carrying some ++ * other info. ++ */ ++ memcpy(isrh, osrh, hdrlen); ++ goto srcaddr; ++ } ++ ++ tlv_offset = sizeof(*osrh) + (first_seg + 1) * sizeof(struct in6_addr); ++ red_tlv_offset = tlv_offset - sizeof(struct in6_addr); ++ ++ memcpy(isrh, osrh, red_tlv_offset); ++ ++ tlvs_len = hdrlen - tlv_offset; ++ if (unlikely(tlvs_len > 0)) { ++ const void *s = (const void *)osrh + tlv_offset; ++ void *d = (void *)isrh + red_tlv_offset; ++ ++ memcpy(d, s, tlvs_len); ++ } ++ ++ --isrh->first_segment; ++ isrh->hdrlen -= 2; ++ ++srcaddr: ++ isrh->nexthdr = proto; ++ set_tun_src(net, dst->dev, &hdr->daddr, &hdr->saddr); ++ ++#ifdef CONFIG_IPV6_SEG6_HMAC ++ if (unlikely(!skip_srh && sr_has_hmac(isrh))) { ++ err = seg6_push_hmac(net, &hdr->saddr, isrh); ++ if (unlikely(err)) ++ return err; ++ } ++#endif ++ ++out: ++ hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); ++ ++ skb_postpush_rcsum(skb, hdr, tot_len); ++ ++ return 0; ++} ++ ++static int __seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, ++ struct dst_entry *cache_dst) + { + struct ipv6hdr *hdr, *oldhdr; + struct ipv6_sr_hdr *isrh; +@@ -206,7 +333,7 @@ int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) + + hdrlen = (osrh->hdrlen + 1) << 3; + +- err = skb_cow_head(skb, hdrlen + skb->mac_len); ++ err = skb_cow_head(skb, hdrlen + dst_dev_overhead(cache_dst, skb)); + if (unlikely(err)) + return err; + +@@ -249,9 +376,8 @@ int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) + + return 0; + } +-EXPORT_SYMBOL_GPL(seg6_do_srh_inline); + +-static int seg6_do_srh(struct sk_buff *skb) ++static int seg6_do_srh(struct sk_buff *skb, struct dst_entry *cache_dst) + { + struct dst_entry *dst = skb_dst(skb); + struct seg6_iptunnel_encap *tinfo; +@@ -264,11 +390,12 @@ static int seg6_do_srh(struct sk_buff *skb) + if (skb->protocol != htons(ETH_P_IPV6)) + return -EINVAL; + +- err = seg6_do_srh_inline(skb, tinfo->srh); ++ err = __seg6_do_srh_inline(skb, tinfo->srh, cache_dst); + if (err) + return err; + break; + case SEG6_IPTUN_MODE_ENCAP: ++ case SEG6_IPTUN_MODE_ENCAP_RED: + err = iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6); + if (err) + return err; +@@ -280,7 +407,13 @@ static int seg6_do_srh(struct sk_buff *skb) + else + return -EINVAL; + +- err = seg6_do_srh_encap(skb, tinfo->srh, proto); ++ if (tinfo->mode == SEG6_IPTUN_MODE_ENCAP) ++ err = __seg6_do_srh_encap(skb, tinfo->srh, ++ proto, cache_dst); ++ else ++ err = seg6_do_srh_encap_red(skb, tinfo->srh, ++ proto, cache_dst); ++ + if (err) + return err; + +@@ -289,6 +422,7 @@ static int seg6_do_srh(struct sk_buff *skb) + skb->protocol = htons(ETH_P_IPV6); + break; + case SEG6_IPTUN_MODE_L2ENCAP: ++ case SEG6_IPTUN_MODE_L2ENCAP_RED: + if (!skb_mac_header_was_set(skb)) + return -EINVAL; + +@@ -298,7 +432,15 @@ static int seg6_do_srh(struct sk_buff *skb) + skb_mac_header_rebuild(skb); + skb_push(skb, skb->mac_len); + +- err = seg6_do_srh_encap(skb, tinfo->srh, IPPROTO_ETHERNET); ++ if (tinfo->mode == SEG6_IPTUN_MODE_L2ENCAP) ++ err = __seg6_do_srh_encap(skb, tinfo->srh, ++ IPPROTO_ETHERNET, ++ cache_dst); ++ else ++ err = seg6_do_srh_encap_red(skb, tinfo->srh, ++ IPPROTO_ETHERNET, ++ cache_dst); ++ + if (err) + return err; + +@@ -312,6 +454,13 @@ static int seg6_do_srh(struct sk_buff *skb) + return 0; + } + ++/* insert an SRH within an IPv6 packet, just after the IPv6 header */ ++int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) ++{ ++ return __seg6_do_srh_inline(skb, osrh, NULL); ++} ++EXPORT_SYMBOL_GPL(seg6_do_srh_inline); ++ + static int seg6_input_finish(struct net *net, struct sock *sk, + struct sk_buff *skb) + { +@@ -323,35 +472,49 @@ static int seg6_input_core(struct net *net, struct sock *sk, + { + struct dst_entry *orig_dst = skb_dst(skb); + struct dst_entry *dst = NULL; ++ struct lwtunnel_state *lwtst; + struct seg6_lwt *slwt; + int err; + +- err = seg6_do_srh(skb); +- if (unlikely(err)) +- goto drop; ++ /* We cannot dereference "orig_dst" once ip6_route_input() or ++ * skb_dst_drop() is called. However, in order to detect a dst loop, we ++ * need the address of its lwtstate. So, save the address of lwtstate ++ * now and use it later as a comparison. ++ */ ++ lwtst = orig_dst->lwtstate; + +- slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); ++ slwt = seg6_lwt_lwtunnel(lwtst); + + local_bh_disable(); + dst = dst_cache_get(&slwt->cache); ++ local_bh_enable(); ++ ++ err = seg6_do_srh(skb, dst); ++ if (unlikely(err)) { ++ dst_release(dst); ++ goto drop; ++ } + + skb_dst_drop(skb); + + if (!dst) { + ip6_route_input(skb); + dst = skb_dst(skb); +- if (!dst->error) { ++ ++ /* cache only if we don't create a dst reference loop */ ++ if (!dst->error && lwtst != dst->lwtstate) { ++ local_bh_disable(); + dst_cache_set_ip6(&slwt->cache, dst, + &ipv6_hdr(skb)->saddr); ++ local_bh_enable(); + } ++ ++ err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); ++ if (unlikely(err)) ++ goto drop; + } else { + skb_dst_set(skb, dst); + } +- local_bh_enable(); +- +- err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); +- if (unlikely(err)) +- goto drop; + + if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled)) + return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, +@@ -397,16 +560,16 @@ static int seg6_output_core(struct net *net, struct sock *sk, + struct seg6_lwt *slwt; + int err; + +- err = seg6_do_srh(skb); +- if (unlikely(err)) +- goto drop; +- + slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate); + + local_bh_disable(); + dst = dst_cache_get(&slwt->cache); + local_bh_enable(); + ++ err = seg6_do_srh(skb, dst); ++ if (unlikely(err)) ++ goto drop; ++ + if (unlikely(!dst)) { + struct ipv6hdr *hdr = ipv6_hdr(skb); + struct flowi6 fl6; +@@ -421,28 +584,28 @@ static int seg6_output_core(struct net *net, struct sock *sk, + dst = ip6_route_output(net, NULL, &fl6); + if (dst->error) { + err = dst->error; +- dst_release(dst); + goto drop; + } + + local_bh_disable(); + dst_cache_set_ip6(&slwt->cache, dst, &fl6.saddr); + local_bh_enable(); ++ ++ err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); ++ if (unlikely(err)) ++ goto drop; + } + + skb_dst_drop(skb); + skb_dst_set(skb, dst); + +- err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); +- if (unlikely(err)) +- goto drop; +- + if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled)) + return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, skb, + NULL, skb_dst(skb)->dev, dst_output); + + return dst_output(net, sk, skb); + drop: ++ dst_release(dst); + kfree_skb(skb); + return err; + } +@@ -516,6 +679,10 @@ static int seg6_build_state(struct net *net, struct nlattr *nla, + break; + case SEG6_IPTUN_MODE_L2ENCAP: + break; ++ case SEG6_IPTUN_MODE_ENCAP_RED: ++ break; ++ case SEG6_IPTUN_MODE_L2ENCAP_RED: ++ break; + default: + return -EINVAL; + } +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index c60162ea0aa8af..f05c09f7165a4c 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -1236,9 +1236,9 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6, + const int hlen = skb_network_header_len(skb) + + sizeof(struct udphdr); + +- if (hlen + cork->gso_size > cork->fragsize) { ++ if (hlen + min(datalen, cork->gso_size) > cork->fragsize) { + kfree_skb(skb); +- return -EINVAL; ++ return -EMSGSIZE; + } + if (datalen > cork->gso_size * UDP_MAX_SEGMENTS) { + kfree_skb(skb); +diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c +index 06fb8e6944b06a..7a0cae9a811148 100644 +--- a/net/llc/llc_s_ac.c ++++ b/net/llc/llc_s_ac.c +@@ -24,7 +24,7 @@ + #include + #include + #include +- ++#include + + /** + * llc_sap_action_unitdata_ind - forward UI PDU to network layer +@@ -40,6 +40,26 @@ int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb) + return 0; + } + ++static int llc_prepare_and_xmit(struct sk_buff *skb) ++{ ++ struct llc_sap_state_ev *ev = llc_sap_ev(skb); ++ struct sk_buff *nskb; ++ int rc; ++ ++ rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); ++ if (rc) ++ return rc; ++ ++ nskb = skb_clone(skb, GFP_ATOMIC); ++ if (!nskb) ++ return -ENOMEM; ++ ++ if (skb->sk) ++ skb_set_owner_w(nskb, skb->sk); ++ ++ return dev_queue_xmit(nskb); ++} ++ + /** + * llc_sap_action_send_ui - sends UI PDU resp to UNITDATA REQ to MAC layer + * @sap: SAP +@@ -52,17 +72,12 @@ int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb) + int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb) + { + struct llc_sap_state_ev *ev = llc_sap_ev(skb); +- int rc; + + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap, + ev->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_ui_cmd(skb); +- rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); +- if (likely(!rc)) { +- skb_get(skb); +- rc = dev_queue_xmit(skb); +- } +- return rc; ++ ++ return llc_prepare_and_xmit(skb); + } + + /** +@@ -77,17 +92,12 @@ int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb) + int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb) + { + struct llc_sap_state_ev *ev = llc_sap_ev(skb); +- int rc; + + llc_pdu_header_init(skb, LLC_PDU_TYPE_U_XID, ev->saddr.lsap, + ev->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0); +- rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); +- if (likely(!rc)) { +- skb_get(skb); +- rc = dev_queue_xmit(skb); +- } +- return rc; ++ ++ return llc_prepare_and_xmit(skb); + } + + /** +@@ -133,17 +143,12 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb) + int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb) + { + struct llc_sap_state_ev *ev = llc_sap_ev(skb); +- int rc; + + llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap, + ev->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_test_cmd(skb); +- rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); +- if (likely(!rc)) { +- skb_get(skb); +- rc = dev_queue_xmit(skb); +- } +- return rc; ++ ++ return llc_prepare_and_xmit(skb); + } + + int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb) +diff --git a/net/mptcp/options.c b/net/mptcp/options.c +index bdabc5e889b7d8..bbdee9a9b4424b 100644 +--- a/net/mptcp/options.c ++++ b/net/mptcp/options.c +@@ -103,7 +103,6 @@ static void mptcp_parse_option(const struct sk_buff *skb, + mp_opt->suboptions |= OPTION_MPTCP_DSS; + mp_opt->use_map = 1; + mp_opt->mpc_map = 1; +- mp_opt->use_ack = 0; + mp_opt->data_len = get_unaligned_be16(ptr); + ptr += 2; + } +@@ -152,11 +151,6 @@ static void mptcp_parse_option(const struct sk_buff *skb, + pr_debug("DSS\n"); + ptr++; + +- /* we must clear 'mpc_map' be able to detect MP_CAPABLE +- * map vs DSS map in mptcp_incoming_options(), and reconstruct +- * map info accordingly +- */ +- mp_opt->mpc_map = 0; + flags = (*ptr++) & MPTCP_DSS_FLAG_MASK; + mp_opt->data_fin = (flags & MPTCP_DSS_DATA_FIN) != 0; + mp_opt->dsn64 = (flags & MPTCP_DSS_DSN64) != 0; +@@ -361,8 +355,11 @@ void mptcp_get_options(const struct sk_buff *skb, + const unsigned char *ptr; + int length; + +- /* initialize option status */ +- mp_opt->suboptions = 0; ++ /* Ensure that casting the whole status to u32 is efficient and safe */ ++ BUILD_BUG_ON(sizeof_field(struct mptcp_options_received, status) != sizeof(u32)); ++ BUILD_BUG_ON(!IS_ALIGNED(offsetof(struct mptcp_options_received, status), ++ sizeof(u32))); ++ *(u32 *)&mp_opt->status = 0; + + length = (th->doff * 4) - sizeof(struct tcphdr); + ptr = (const unsigned char *)(th + 1); +diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c +index a7a46d99d5a39e..45708e67cccc23 100644 +--- a/net/mptcp/pm_netlink.c ++++ b/net/mptcp/pm_netlink.c +@@ -1406,11 +1406,6 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net, + struct sock *sk = (struct sock *)msk; + bool remove_subflow; + +- if (list_empty(&msk->conn_list)) { +- mptcp_pm_remove_anno_addr(msk, addr, false); +- goto next; +- } +- + lock_sock(sk); + remove_subflow = lookup_subflow_by_saddr(&msk->conn_list, addr); + mptcp_pm_remove_anno_addr(msk, addr, remove_subflow); +@@ -1418,7 +1413,6 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net, + mptcp_pm_remove_subflow(msk, &list); + release_sock(sk); + +-next: + sock_put(sk); + cond_resched(); + } +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index f337dd3323a01d..c6a11d6df516f2 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -133,6 +133,7 @@ static bool mptcp_try_coalesce(struct sock *sk, struct sk_buff *to, + int delta; + + if (MPTCP_SKB_CB(from)->offset || ++ ((to->len + from->len) > (sk->sk_rcvbuf >> 3)) || + !skb_try_coalesce(to, from, &fragstolen, &delta)) + return false; + +diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h +index 6026f0bcdea60f..83e93a7e9b40e2 100644 +--- a/net/mptcp/protocol.h ++++ b/net/mptcp/protocol.h +@@ -139,22 +139,24 @@ struct mptcp_options_received { + u32 subflow_seq; + u16 data_len; + __sum16 csum; +- u16 suboptions; ++ struct_group(status, ++ u16 suboptions; ++ u16 use_map:1, ++ dsn64:1, ++ data_fin:1, ++ use_ack:1, ++ ack64:1, ++ mpc_map:1, ++ reset_reason:4, ++ reset_transient:1, ++ echo:1, ++ backup:1, ++ deny_join_id0:1, ++ __unused:2; ++ ); ++ u8 join_id; + u32 token; + u32 nonce; +- u16 use_map:1, +- dsn64:1, +- data_fin:1, +- use_ack:1, +- ack64:1, +- mpc_map:1, +- reset_reason:4, +- reset_transient:1, +- echo:1, +- backup:1, +- deny_join_id0:1, +- __unused:2; +- u8 join_id; + u64 thmac; + u8 hmac[MPTCPOPT_HMAC_LEN]; + struct mptcp_addr_info addr; +diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h +index ef0f8f73826f53..4e0842df5234ea 100644 +--- a/net/ncsi/internal.h ++++ b/net/ncsi/internal.h +@@ -289,6 +289,7 @@ enum { + ncsi_dev_state_config_sp = 0x0301, + ncsi_dev_state_config_cis, + ncsi_dev_state_config_oem_gma, ++ ncsi_dev_state_config_apply_mac, + ncsi_dev_state_config_clear_vids, + ncsi_dev_state_config_svf, + ncsi_dev_state_config_ev, +@@ -322,6 +323,7 @@ struct ncsi_dev_priv { + #define NCSI_DEV_RESHUFFLE 4 + #define NCSI_DEV_RESET 8 /* Reset state of NC */ + unsigned int gma_flag; /* OEM GMA flag */ ++ struct sockaddr pending_mac; /* MAC address received from GMA */ + spinlock_t lock; /* Protect the NCSI device */ + unsigned int package_probe_id;/* Current ID during probe */ + unsigned int package_num; /* Number of packages */ +diff --git a/net/ncsi/ncsi-cmd.c b/net/ncsi/ncsi-cmd.c +index dda8b76b77988a..7be177f5517319 100644 +--- a/net/ncsi/ncsi-cmd.c ++++ b/net/ncsi/ncsi-cmd.c +@@ -269,7 +269,8 @@ static struct ncsi_cmd_handler { + { NCSI_PKT_CMD_GPS, 0, ncsi_cmd_handler_default }, + { NCSI_PKT_CMD_OEM, -1, ncsi_cmd_handler_oem }, + { NCSI_PKT_CMD_PLDM, 0, NULL }, +- { NCSI_PKT_CMD_GPUUID, 0, ncsi_cmd_handler_default } ++ { NCSI_PKT_CMD_GPUUID, 0, ncsi_cmd_handler_default }, ++ { NCSI_PKT_CMD_GMCMA, 0, ncsi_cmd_handler_default } + }; + + static struct ncsi_request *ncsi_alloc_command(struct ncsi_cmd_arg *nca) +diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c +index 30f55025303749..6ed1096a60a12c 100644 +--- a/net/ncsi/ncsi-manage.c ++++ b/net/ncsi/ncsi-manage.c +@@ -1038,17 +1038,34 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp) + : ncsi_dev_state_config_clear_vids; + break; + case ncsi_dev_state_config_oem_gma: +- nd->state = ncsi_dev_state_config_clear_vids; ++ nd->state = ncsi_dev_state_config_apply_mac; + +- nca.type = NCSI_PKT_CMD_OEM; + nca.package = np->id; + nca.channel = nc->id; + ndp->pending_req_num = 1; +- ret = ncsi_gma_handler(&nca, nc->version.mf_id); +- if (ret < 0) ++ if (nc->version.major >= 1 && nc->version.minor >= 2) { ++ nca.type = NCSI_PKT_CMD_GMCMA; ++ ret = ncsi_xmit_cmd(&nca); ++ } else { ++ nca.type = NCSI_PKT_CMD_OEM; ++ ret = ncsi_gma_handler(&nca, nc->version.mf_id); ++ } ++ if (ret < 0) { ++ nd->state = ncsi_dev_state_config_clear_vids; + schedule_work(&ndp->work); ++ } + + break; ++ case ncsi_dev_state_config_apply_mac: ++ rtnl_lock(); ++ ret = dev_set_mac_address(dev, &ndp->pending_mac, NULL); ++ rtnl_unlock(); ++ if (ret < 0) ++ netdev_warn(dev, "NCSI: 'Writing MAC address to device failed\n"); ++ ++ nd->state = ncsi_dev_state_config_clear_vids; ++ ++ fallthrough; + case ncsi_dev_state_config_clear_vids: + case ncsi_dev_state_config_svf: + case ncsi_dev_state_config_ev: +@@ -1368,6 +1385,12 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + nd->state = ncsi_dev_state_probe_package; + break; + case ncsi_dev_state_probe_package: ++ if (ndp->package_probe_id >= 8) { ++ /* Last package probed, finishing */ ++ ndp->flags |= NCSI_DEV_PROBED; ++ break; ++ } ++ + ndp->pending_req_num = 1; + + nca.type = NCSI_PKT_CMD_SP; +@@ -1484,13 +1507,8 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) + if (ret) + goto error; + +- /* Probe next package */ ++ /* Probe next package after receiving response */ + ndp->package_probe_id++; +- if (ndp->package_probe_id >= 8) { +- /* Probe finished */ +- ndp->flags |= NCSI_DEV_PROBED; +- break; +- } + nd->state = ncsi_dev_state_probe_package; + ndp->active_package = NULL; + break; +diff --git a/net/ncsi/ncsi-pkt.h b/net/ncsi/ncsi-pkt.h +index c9d1da34dc4dc5..f2f3b5c1b94126 100644 +--- a/net/ncsi/ncsi-pkt.h ++++ b/net/ncsi/ncsi-pkt.h +@@ -338,6 +338,14 @@ struct ncsi_rsp_gpuuid_pkt { + __be32 checksum; + }; + ++/* Get MC MAC Address */ ++struct ncsi_rsp_gmcma_pkt { ++ struct ncsi_rsp_pkt_hdr rsp; ++ unsigned char address_count; ++ unsigned char reserved[3]; ++ unsigned char addresses[][ETH_ALEN]; ++}; ++ + /* AEN: Link State Change */ + struct ncsi_aen_lsc_pkt { + struct ncsi_aen_pkt_hdr aen; /* AEN header */ +@@ -398,6 +406,7 @@ struct ncsi_aen_hncdsc_pkt { + #define NCSI_PKT_CMD_GPUUID 0x52 /* Get package UUID */ + #define NCSI_PKT_CMD_QPNPR 0x56 /* Query Pending NC PLDM request */ + #define NCSI_PKT_CMD_SNPR 0x57 /* Send NC PLDM Reply */ ++#define NCSI_PKT_CMD_GMCMA 0x58 /* Get MC MAC Address */ + + + /* NCSI packet responses */ +@@ -433,6 +442,7 @@ struct ncsi_aen_hncdsc_pkt { + #define NCSI_PKT_RSP_GPUUID (NCSI_PKT_CMD_GPUUID + 0x80) + #define NCSI_PKT_RSP_QPNPR (NCSI_PKT_CMD_QPNPR + 0x80) + #define NCSI_PKT_RSP_SNPR (NCSI_PKT_CMD_SNPR + 0x80) ++#define NCSI_PKT_RSP_GMCMA (NCSI_PKT_CMD_GMCMA + 0x80) + + /* NCSI response code/reason */ + #define NCSI_PKT_RSP_C_COMPLETED 0x0000 /* Command Completed */ +diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c +index f22d67cb04d371..4a8ce2949faeac 100644 +--- a/net/ncsi/ncsi-rsp.c ++++ b/net/ncsi/ncsi-rsp.c +@@ -628,16 +628,14 @@ static int ncsi_rsp_handler_snfc(struct ncsi_request *nr) + static int ncsi_rsp_handler_oem_gma(struct ncsi_request *nr, int mfr_id) + { + struct ncsi_dev_priv *ndp = nr->ndp; ++ struct sockaddr *saddr = &ndp->pending_mac; + struct net_device *ndev = ndp->ndev.dev; + struct ncsi_rsp_oem_pkt *rsp; +- struct sockaddr saddr; + u32 mac_addr_off = 0; +- int ret = 0; + + /* Get the response header */ + rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp); + +- saddr.sa_family = ndev->type; + ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; + if (mfr_id == NCSI_OEM_MFR_BCM_ID) + mac_addr_off = BCM_MAC_ADDR_OFFSET; +@@ -646,22 +644,17 @@ static int ncsi_rsp_handler_oem_gma(struct ncsi_request *nr, int mfr_id) + else if (mfr_id == NCSI_OEM_MFR_INTEL_ID) + mac_addr_off = INTEL_MAC_ADDR_OFFSET; + +- memcpy(saddr.sa_data, &rsp->data[mac_addr_off], ETH_ALEN); ++ saddr->sa_family = ndev->type; ++ memcpy(saddr->sa_data, &rsp->data[mac_addr_off], ETH_ALEN); + if (mfr_id == NCSI_OEM_MFR_BCM_ID || mfr_id == NCSI_OEM_MFR_INTEL_ID) +- eth_addr_inc((u8 *)saddr.sa_data); +- if (!is_valid_ether_addr((const u8 *)saddr.sa_data)) ++ eth_addr_inc((u8 *)saddr->sa_data); ++ if (!is_valid_ether_addr((const u8 *)saddr->sa_data)) + return -ENXIO; + + /* Set the flag for GMA command which should only be called once */ + ndp->gma_flag = 1; + +- rtnl_lock(); +- ret = dev_set_mac_address(ndev, &saddr, NULL); +- rtnl_unlock(); +- if (ret < 0) +- netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n"); +- +- return ret; ++ return 0; + } + + /* Response handler for Mellanox card */ +@@ -1093,6 +1086,42 @@ static int ncsi_rsp_handler_netlink(struct ncsi_request *nr) + return ret; + } + ++static int ncsi_rsp_handler_gmcma(struct ncsi_request *nr) ++{ ++ struct ncsi_dev_priv *ndp = nr->ndp; ++ struct sockaddr *saddr = &ndp->pending_mac; ++ struct net_device *ndev = ndp->ndev.dev; ++ struct ncsi_rsp_gmcma_pkt *rsp; ++ int i; ++ ++ rsp = (struct ncsi_rsp_gmcma_pkt *)skb_network_header(nr->rsp); ++ ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; ++ ++ netdev_info(ndev, "NCSI: Received %d provisioned MAC addresses\n", ++ rsp->address_count); ++ for (i = 0; i < rsp->address_count; i++) { ++ netdev_info(ndev, "NCSI: MAC address %d: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ i, rsp->addresses[i][0], rsp->addresses[i][1], ++ rsp->addresses[i][2], rsp->addresses[i][3], ++ rsp->addresses[i][4], rsp->addresses[i][5]); ++ } ++ ++ saddr->sa_family = ndev->type; ++ for (i = 0; i < rsp->address_count; i++) { ++ if (!is_valid_ether_addr(rsp->addresses[i])) { ++ netdev_warn(ndev, "NCSI: Unable to assign %pM to device\n", ++ rsp->addresses[i]); ++ continue; ++ } ++ memcpy(saddr->sa_data, rsp->addresses[i], ETH_ALEN); ++ netdev_warn(ndev, "NCSI: Will set MAC address to %pM\n", saddr->sa_data); ++ break; ++ } ++ ++ ndp->gma_flag = 1; ++ return 0; ++} ++ + static struct ncsi_rsp_handler { + unsigned char type; + int payload; +@@ -1129,7 +1158,8 @@ static struct ncsi_rsp_handler { + { NCSI_PKT_RSP_PLDM, -1, ncsi_rsp_handler_pldm }, + { NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid }, + { NCSI_PKT_RSP_QPNPR, -1, ncsi_rsp_handler_pldm }, +- { NCSI_PKT_RSP_SNPR, -1, ncsi_rsp_handler_pldm } ++ { NCSI_PKT_RSP_SNPR, -1, ncsi_rsp_handler_pldm }, ++ { NCSI_PKT_RSP_GMCMA, -1, ncsi_rsp_handler_gmcma }, + }; + + int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev, +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index e86cc6f4ce9db3..07fdd5f18f3c9b 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -4497,7 +4497,7 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr, + static int nft_set_desc_concat(struct nft_set_desc *desc, + const struct nlattr *nla) + { +- u32 num_regs = 0, key_num_regs = 0; ++ u32 len = 0, num_regs; + struct nlattr *attr; + int rem, err, i; + +@@ -4511,12 +4511,12 @@ static int nft_set_desc_concat(struct nft_set_desc *desc, + } + + for (i = 0; i < desc->field_count; i++) +- num_regs += DIV_ROUND_UP(desc->field_len[i], sizeof(u32)); ++ len += round_up(desc->field_len[i], sizeof(u32)); + +- key_num_regs = DIV_ROUND_UP(desc->klen, sizeof(u32)); +- if (key_num_regs != num_regs) ++ if (len != desc->klen) + return -EINVAL; + ++ num_regs = DIV_ROUND_UP(desc->klen, sizeof(u32)); + if (num_regs > NFT_REG32_COUNT) + return -E2BIG; + +diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c +index fbb9f3a6c84444..41d04fa12f67dd 100644 +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -278,6 +278,15 @@ static bool nft_flow_offload_skip(struct sk_buff *skb, int family) + return false; + } + ++static void flow_offload_ct_tcp(struct nf_conn *ct) ++{ ++ /* conntrack will not see all packets, disable tcp window validation. */ ++ spin_lock_bh(&ct->lock); ++ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; ++ ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; ++ spin_unlock_bh(&ct->lock); ++} ++ + static void nft_flow_offload_eval(const struct nft_expr *expr, + struct nft_regs *regs, + const struct nft_pktinfo *pkt) +@@ -332,11 +341,8 @@ static void nft_flow_offload_eval(const struct nft_expr *expr, + goto err_flow_alloc; + + flow_offload_route_init(flow, &route); +- +- if (tcph) { +- ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; +- ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; +- } ++ if (tcph) ++ flow_offload_ct_tcp(ct); + + ret = flow_offload_add(flowtable, flow); + if (ret < 0) +diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c +index 85b808fdcbc3af..93ebb703144aa0 100644 +--- a/net/nfc/nci/hci.c ++++ b/net/nfc/nci/hci.c +@@ -542,6 +542,8 @@ static u8 nci_hci_create_pipe(struct nci_dev *ndev, u8 dest_host, + + pr_debug("pipe created=%d\n", pipe); + ++ if (pipe >= NCI_HCI_MAX_PIPES) ++ pipe = NCI_HCI_INVALID_PIPE; + return pipe; + } + +diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c +index 0fc98e89a1149c..c28b56c3091690 100644 +--- a/net/openvswitch/datapath.c ++++ b/net/openvswitch/datapath.c +@@ -2058,6 +2058,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, + { + struct ovs_header *ovs_header; + struct ovs_vport_stats vport_stats; ++ struct net *net_vport; + int err; + + ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family, +@@ -2074,12 +2075,15 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, + nla_put_u32(skb, OVS_VPORT_ATTR_IFINDEX, vport->dev->ifindex)) + goto nla_put_failure; + +- if (!net_eq(net, dev_net(vport->dev))) { +- int id = peernet2id_alloc(net, dev_net(vport->dev), gfp); ++ rcu_read_lock(); ++ net_vport = dev_net_rcu(vport->dev); ++ if (!net_eq(net, net_vport)) { ++ int id = peernet2id_alloc(net, net_vport, GFP_ATOMIC); + + if (nla_put_s32(skb, OVS_VPORT_ATTR_NETNSID, id)) +- goto nla_put_failure; ++ goto nla_put_failure_unlock; + } ++ rcu_read_unlock(); + + ovs_vport_get_stats(vport, &vport_stats); + if (nla_put_64bit(skb, OVS_VPORT_ATTR_STATS, +@@ -2097,6 +2101,8 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, + genlmsg_end(skb, ovs_header); + return 0; + ++nla_put_failure_unlock: ++ rcu_read_unlock(); + nla_put_failure: + err = -EMSGSIZE; + error: +diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c +index 1d95ff34b13c93..f8cd085c423457 100644 +--- a/net/rose/af_rose.c ++++ b/net/rose/af_rose.c +@@ -396,15 +396,15 @@ static int rose_setsockopt(struct socket *sock, int level, int optname, + { + struct sock *sk = sock->sk; + struct rose_sock *rose = rose_sk(sk); +- int opt; ++ unsigned int opt; + + if (level != SOL_ROSE) + return -ENOPROTOOPT; + +- if (optlen < sizeof(int)) ++ if (optlen < sizeof(unsigned int)) + return -EINVAL; + +- if (copy_from_sockptr(&opt, optval, sizeof(int))) ++ if (copy_from_sockptr(&opt, optval, sizeof(unsigned int))) + return -EFAULT; + + switch (optname) { +@@ -413,31 +413,31 @@ static int rose_setsockopt(struct socket *sock, int level, int optname, + return 0; + + case ROSE_T1: +- if (opt < 1) ++ if (opt < 1 || opt > UINT_MAX / HZ) + return -EINVAL; + rose->t1 = opt * HZ; + return 0; + + case ROSE_T2: +- if (opt < 1) ++ if (opt < 1 || opt > UINT_MAX / HZ) + return -EINVAL; + rose->t2 = opt * HZ; + return 0; + + case ROSE_T3: +- if (opt < 1) ++ if (opt < 1 || opt > UINT_MAX / HZ) + return -EINVAL; + rose->t3 = opt * HZ; + return 0; + + case ROSE_HOLDBACK: +- if (opt < 1) ++ if (opt < 1 || opt > UINT_MAX / HZ) + return -EINVAL; + rose->hb = opt * HZ; + return 0; + + case ROSE_IDLE: +- if (opt < 0) ++ if (opt > UINT_MAX / (60 * HZ)) + return -EINVAL; + rose->idle = opt * 60 * HZ; + return 0; +@@ -700,11 +700,9 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + struct net_device *dev; + ax25_address *source; + ax25_uid_assoc *user; ++ int err = -EINVAL; + int n; + +- if (!sock_flag(sk, SOCK_ZAPPED)) +- return -EINVAL; +- + if (addr_len != sizeof(struct sockaddr_rose) && addr_len != sizeof(struct full_sockaddr_rose)) + return -EINVAL; + +@@ -717,8 +715,15 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS) + return -EINVAL; + +- if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) +- return -EADDRNOTAVAIL; ++ lock_sock(sk); ++ ++ if (!sock_flag(sk, SOCK_ZAPPED)) ++ goto out_release; ++ ++ err = -EADDRNOTAVAIL; ++ dev = rose_dev_get(&addr->srose_addr); ++ if (!dev) ++ goto out_release; + + source = &addr->srose_call; + +@@ -729,7 +734,8 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + } else { + if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) { + dev_put(dev); +- return -EACCES; ++ err = -EACCES; ++ goto out_release; + } + rose->source_call = *source; + } +@@ -751,8 +757,10 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + rose_insert_socket(sk); + + sock_reset_flag(sk, SOCK_ZAPPED); +- +- return 0; ++ err = 0; ++out_release: ++ release_sock(sk); ++ return err; + } + + static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) +diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c +index f06ddbed3fed63..1525773e94aa17 100644 +--- a/net/rose/rose_timer.c ++++ b/net/rose/rose_timer.c +@@ -122,6 +122,10 @@ static void rose_heartbeat_expiry(struct timer_list *t) + struct rose_sock *rose = rose_sk(sk); + + bh_lock_sock(sk); ++ if (sock_owned_by_user(sk)) { ++ sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ/20); ++ goto out; ++ } + switch (rose->state) { + case ROSE_STATE_0: + /* Magic here: If we listen() and a new link dies before it +@@ -152,6 +156,7 @@ static void rose_heartbeat_expiry(struct timer_list *t) + } + + rose_start_heartbeat(sk); ++out: + bh_unlock_sock(sk); + sock_put(sk); + } +@@ -162,6 +167,10 @@ static void rose_timer_expiry(struct timer_list *t) + struct sock *sk = &rose->sock; + + bh_lock_sock(sk); ++ if (sock_owned_by_user(sk)) { ++ sk_reset_timer(sk, &rose->timer, jiffies + HZ/20); ++ goto out; ++ } + switch (rose->state) { + case ROSE_STATE_1: /* T1 */ + case ROSE_STATE_4: /* T2 */ +@@ -182,6 +191,7 @@ static void rose_timer_expiry(struct timer_list *t) + } + break; + } ++out: + bh_unlock_sock(sk); + sock_put(sk); + } +@@ -192,6 +202,10 @@ static void rose_idletimer_expiry(struct timer_list *t) + struct sock *sk = &rose->sock; + + bh_lock_sock(sk); ++ if (sock_owned_by_user(sk)) { ++ sk_reset_timer(sk, &rose->idletimer, jiffies + HZ/20); ++ goto out; ++ } + rose_clear_queues(sk); + + rose_write_internal(sk, ROSE_CLEAR_REQUEST); +@@ -207,6 +221,7 @@ static void rose_idletimer_expiry(struct timer_list *t) + sk->sk_state_change(sk); + sock_set_flag(sk, SOCK_DEAD); + } ++out: + bh_unlock_sock(sk); + sock_put(sk); + } +diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c +index 057612c97a3728..35842b51a24e27 100644 +--- a/net/sched/cls_flower.c ++++ b/net/sched/cls_flower.c +@@ -62,13 +62,7 @@ struct fl_flow_key { + struct flow_dissector_key_ip ip; + struct flow_dissector_key_ip enc_ip; + struct flow_dissector_key_enc_opts enc_opts; +- union { +- struct flow_dissector_key_ports tp; +- struct { +- struct flow_dissector_key_ports tp_min; +- struct flow_dissector_key_ports tp_max; +- }; +- } tp_range; ++ struct flow_dissector_key_ports_range tp_range; + struct flow_dissector_key_ct ct; + struct flow_dissector_key_hash hash; + } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */ +diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c +index bf8af9f3f3dce5..516874d943cd94 100644 +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -1603,6 +1603,10 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, + q = qdisc_lookup(dev, tcm->tcm_handle); + if (!q) + goto create_n_graft; ++ if (q->parent != tcm->tcm_parent) { ++ NL_SET_ERR_MSG(extack, "Cannot move an existing qdisc to a different parent"); ++ return -EINVAL; ++ } + if (n->nlmsg_flags & NLM_F_EXCL) { + NL_SET_ERR_MSG(extack, "Exclusivity flag on, cannot override"); + return -EEXIST; +diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c +index eeb418165755ef..8429d7f8aba4c2 100644 +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -643,6 +643,63 @@ static bool cake_ddst(int flow_mode) + return (flow_mode & CAKE_FLOW_DUAL_DST) == CAKE_FLOW_DUAL_DST; + } + ++static void cake_dec_srchost_bulk_flow_count(struct cake_tin_data *q, ++ struct cake_flow *flow, ++ int flow_mode) ++{ ++ if (likely(cake_dsrc(flow_mode) && ++ q->hosts[flow->srchost].srchost_bulk_flow_count)) ++ q->hosts[flow->srchost].srchost_bulk_flow_count--; ++} ++ ++static void cake_inc_srchost_bulk_flow_count(struct cake_tin_data *q, ++ struct cake_flow *flow, ++ int flow_mode) ++{ ++ if (likely(cake_dsrc(flow_mode) && ++ q->hosts[flow->srchost].srchost_bulk_flow_count < CAKE_QUEUES)) ++ q->hosts[flow->srchost].srchost_bulk_flow_count++; ++} ++ ++static void cake_dec_dsthost_bulk_flow_count(struct cake_tin_data *q, ++ struct cake_flow *flow, ++ int flow_mode) ++{ ++ if (likely(cake_ddst(flow_mode) && ++ q->hosts[flow->dsthost].dsthost_bulk_flow_count)) ++ q->hosts[flow->dsthost].dsthost_bulk_flow_count--; ++} ++ ++static void cake_inc_dsthost_bulk_flow_count(struct cake_tin_data *q, ++ struct cake_flow *flow, ++ int flow_mode) ++{ ++ if (likely(cake_ddst(flow_mode) && ++ q->hosts[flow->dsthost].dsthost_bulk_flow_count < CAKE_QUEUES)) ++ q->hosts[flow->dsthost].dsthost_bulk_flow_count++; ++} ++ ++static u16 cake_get_flow_quantum(struct cake_tin_data *q, ++ struct cake_flow *flow, ++ int flow_mode) ++{ ++ u16 host_load = 1; ++ ++ if (cake_dsrc(flow_mode)) ++ host_load = max(host_load, ++ q->hosts[flow->srchost].srchost_bulk_flow_count); ++ ++ if (cake_ddst(flow_mode)) ++ host_load = max(host_load, ++ q->hosts[flow->dsthost].dsthost_bulk_flow_count); ++ ++ /* The shifted prandom_u32() is a way to apply dithering to avoid ++ * accumulating roundoff errors ++ */ ++ return (q->flow_quantum * quantum_div[host_load] + ++ (prandom_u32() >> 16)) >> 16; ++} ++ + static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb, + int flow_mode, u16 flow_override, u16 host_override) + { +@@ -789,10 +846,8 @@ static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb, + allocate_dst = cake_ddst(flow_mode); + + if (q->flows[outer_hash + k].set == CAKE_SET_BULK) { +- if (allocate_src) +- q->hosts[q->flows[reduced_hash].srchost].srchost_bulk_flow_count--; +- if (allocate_dst) +- q->hosts[q->flows[reduced_hash].dsthost].dsthost_bulk_flow_count--; ++ cake_dec_srchost_bulk_flow_count(q, &q->flows[outer_hash + k], flow_mode); ++ cake_dec_dsthost_bulk_flow_count(q, &q->flows[outer_hash + k], flow_mode); + } + found: + /* reserve queue for future packets in same flow */ +@@ -817,9 +872,10 @@ static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb, + q->hosts[outer_hash + k].srchost_tag = srchost_hash; + found_src: + srchost_idx = outer_hash + k; +- if (q->flows[reduced_hash].set == CAKE_SET_BULK) +- q->hosts[srchost_idx].srchost_bulk_flow_count++; + q->flows[reduced_hash].srchost = srchost_idx; ++ ++ if (q->flows[reduced_hash].set == CAKE_SET_BULK) ++ cake_inc_srchost_bulk_flow_count(q, &q->flows[reduced_hash], flow_mode); + } + + if (allocate_dst) { +@@ -840,9 +896,10 @@ static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb, + q->hosts[outer_hash + k].dsthost_tag = dsthost_hash; + found_dst: + dsthost_idx = outer_hash + k; +- if (q->flows[reduced_hash].set == CAKE_SET_BULK) +- q->hosts[dsthost_idx].dsthost_bulk_flow_count++; + q->flows[reduced_hash].dsthost = dsthost_idx; ++ ++ if (q->flows[reduced_hash].set == CAKE_SET_BULK) ++ cake_inc_dsthost_bulk_flow_count(q, &q->flows[reduced_hash], flow_mode); + } + } + +@@ -1855,10 +1912,6 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + + /* flowchain */ + if (!flow->set || flow->set == CAKE_SET_DECAYING) { +- struct cake_host *srchost = &b->hosts[flow->srchost]; +- struct cake_host *dsthost = &b->hosts[flow->dsthost]; +- u16 host_load = 1; +- + if (!flow->set) { + list_add_tail(&flow->flowchain, &b->new_flows); + } else { +@@ -1868,18 +1921,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + flow->set = CAKE_SET_SPARSE; + b->sparse_flow_count++; + +- if (cake_dsrc(q->flow_mode)) +- host_load = max(host_load, srchost->srchost_bulk_flow_count); +- +- if (cake_ddst(q->flow_mode)) +- host_load = max(host_load, dsthost->dsthost_bulk_flow_count); +- +- flow->deficit = (b->flow_quantum * +- quantum_div[host_load]) >> 16; ++ flow->deficit = cake_get_flow_quantum(b, flow, q->flow_mode); + } else if (flow->set == CAKE_SET_SPARSE_WAIT) { +- struct cake_host *srchost = &b->hosts[flow->srchost]; +- struct cake_host *dsthost = &b->hosts[flow->dsthost]; +- + /* this flow was empty, accounted as a sparse flow, but actually + * in the bulk rotation. + */ +@@ -1887,12 +1930,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + b->sparse_flow_count--; + b->bulk_flow_count++; + +- if (cake_dsrc(q->flow_mode)) +- srchost->srchost_bulk_flow_count++; +- +- if (cake_ddst(q->flow_mode)) +- dsthost->dsthost_bulk_flow_count++; +- ++ cake_inc_srchost_bulk_flow_count(b, flow, q->flow_mode); ++ cake_inc_dsthost_bulk_flow_count(b, flow, q->flow_mode); + } + + if (q->buffer_used > q->buffer_max_used) +@@ -1949,13 +1988,11 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) + { + struct cake_sched_data *q = qdisc_priv(sch); + struct cake_tin_data *b = &q->tins[q->cur_tin]; +- struct cake_host *srchost, *dsthost; + ktime_t now = ktime_get(); + struct cake_flow *flow; + struct list_head *head; + bool first_flow = true; + struct sk_buff *skb; +- u16 host_load; + u64 delay; + u32 len; + +@@ -2055,11 +2092,6 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) + q->cur_flow = flow - b->flows; + first_flow = false; + +- /* triple isolation (modified DRR++) */ +- srchost = &b->hosts[flow->srchost]; +- dsthost = &b->hosts[flow->dsthost]; +- host_load = 1; +- + /* flow isolation (DRR++) */ + if (flow->deficit <= 0) { + /* Keep all flows with deficits out of the sparse and decaying +@@ -2071,11 +2103,8 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) + b->sparse_flow_count--; + b->bulk_flow_count++; + +- if (cake_dsrc(q->flow_mode)) +- srchost->srchost_bulk_flow_count++; +- +- if (cake_ddst(q->flow_mode)) +- dsthost->dsthost_bulk_flow_count++; ++ cake_inc_srchost_bulk_flow_count(b, flow, q->flow_mode); ++ cake_inc_dsthost_bulk_flow_count(b, flow, q->flow_mode); + + flow->set = CAKE_SET_BULK; + } else { +@@ -2087,19 +2116,7 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) + } + } + +- if (cake_dsrc(q->flow_mode)) +- host_load = max(host_load, srchost->srchost_bulk_flow_count); +- +- if (cake_ddst(q->flow_mode)) +- host_load = max(host_load, dsthost->dsthost_bulk_flow_count); +- +- WARN_ON(host_load > CAKE_QUEUES); +- +- /* The shifted prandom_u32() is a way to apply dithering to +- * avoid accumulating roundoff errors +- */ +- flow->deficit += (b->flow_quantum * quantum_div[host_load] + +- (prandom_u32() >> 16)) >> 16; ++ flow->deficit += cake_get_flow_quantum(b, flow, q->flow_mode); + list_move_tail(&flow->flowchain, &b->old_flows); + + goto retry; +@@ -2123,11 +2140,8 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) + if (flow->set == CAKE_SET_BULK) { + b->bulk_flow_count--; + +- if (cake_dsrc(q->flow_mode)) +- srchost->srchost_bulk_flow_count--; +- +- if (cake_ddst(q->flow_mode)) +- dsthost->dsthost_bulk_flow_count--; ++ cake_dec_srchost_bulk_flow_count(b, flow, q->flow_mode); ++ cake_dec_dsthost_bulk_flow_count(b, flow, q->flow_mode); + + b->decaying_flow_count++; + } else if (flow->set == CAKE_SET_SPARSE || +@@ -2145,12 +2159,8 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) + else if (flow->set == CAKE_SET_BULK) { + b->bulk_flow_count--; + +- if (cake_dsrc(q->flow_mode)) +- srchost->srchost_bulk_flow_count--; +- +- if (cake_ddst(q->flow_mode)) +- dsthost->dsthost_bulk_flow_count--; +- ++ cake_dec_srchost_bulk_flow_count(b, flow, q->flow_mode); ++ cake_dec_dsthost_bulk_flow_count(b, flow, q->flow_mode); + } else + b->decaying_flow_count--; + +diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c +index e1040421b79797..af5f2ab69b8d26 100644 +--- a/net/sched/sch_fifo.c ++++ b/net/sched/sch_fifo.c +@@ -39,6 +39,9 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch, + { + unsigned int prev_backlog; + ++ if (unlikely(READ_ONCE(sch->limit) == 0)) ++ return qdisc_drop(skb, sch, to_free); ++ + if (likely(sch->q.qlen < sch->limit)) + return qdisc_enqueue_tail(skb, sch); + +diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c +index f459e34684ad36..22f5d9421f6a61 100644 +--- a/net/sched/sch_netem.c ++++ b/net/sched/sch_netem.c +@@ -739,9 +739,9 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch) + if (err != NET_XMIT_SUCCESS) { + if (net_xmit_drop_count(err)) + qdisc_qstats_drop(sch); +- qdisc_tree_reduce_backlog(sch, 1, pkt_len); + sch->qstats.backlog -= pkt_len; + sch->q.qlen--; ++ qdisc_tree_reduce_backlog(sch, 1, pkt_len); + } + goto tfifo_dequeue; + } +diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c +index ef0f264932e1f3..2a642dfbc94a13 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -2209,7 +2209,7 @@ static int smc_accept(struct socket *sock, struct socket *new_sock, + release_sock(clcsk); + } else if (!atomic_read(&smc_sk(nsk)->conn.bytes_to_rcv)) { + lock_sock(nsk); +- smc_rx_wait(smc_sk(nsk), &timeo, smc_rx_data_available); ++ smc_rx_wait(smc_sk(nsk), &timeo, 0, smc_rx_data_available); + release_sock(nsk); + } + } +diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c +index 5b63c250ba6042..81cf611eae750b 100644 +--- a/net/smc/smc_rx.c ++++ b/net/smc/smc_rx.c +@@ -175,22 +175,23 @@ static int smc_rx_splice(struct pipe_inode_info *pipe, char *src, size_t len, + return bytes; + } + +-static int smc_rx_data_available_and_no_splice_pend(struct smc_connection *conn) ++static int smc_rx_data_available_and_no_splice_pend(struct smc_connection *conn, size_t peeked) + { +- return atomic_read(&conn->bytes_to_rcv) && ++ return smc_rx_data_available(conn, peeked) && + !atomic_read(&conn->splice_pending); + } + + /* blocks rcvbuf consumer until >=len bytes available or timeout or interrupted + * @smc smc socket + * @timeo pointer to max seconds to wait, pointer to value 0 for no timeout ++ * @peeked number of bytes already peeked + * @fcrit add'l criterion to evaluate as function pointer + * Returns: + * 1 if at least 1 byte available in rcvbuf or if socket error/shutdown. + * 0 otherwise (nothing in rcvbuf nor timeout, e.g. interrupted). + */ +-int smc_rx_wait(struct smc_sock *smc, long *timeo, +- int (*fcrit)(struct smc_connection *conn)) ++int smc_rx_wait(struct smc_sock *smc, long *timeo, size_t peeked, ++ int (*fcrit)(struct smc_connection *conn, size_t baseline)) + { + DEFINE_WAIT_FUNC(wait, woken_wake_function); + struct smc_connection *conn = &smc->conn; +@@ -199,7 +200,7 @@ int smc_rx_wait(struct smc_sock *smc, long *timeo, + struct sock *sk = &smc->sk; + int rc; + +- if (fcrit(conn)) ++ if (fcrit(conn, peeked)) + return 1; + sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); + add_wait_queue(sk_sleep(sk), &wait); +@@ -208,7 +209,7 @@ int smc_rx_wait(struct smc_sock *smc, long *timeo, + cflags->peer_conn_abort || + READ_ONCE(sk->sk_shutdown) & RCV_SHUTDOWN || + conn->killed || +- fcrit(conn), ++ fcrit(conn, peeked), + &wait); + remove_wait_queue(sk_sleep(sk), &wait); + sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); +@@ -259,11 +260,11 @@ static int smc_rx_recv_urg(struct smc_sock *smc, struct msghdr *msg, int len, + return -EAGAIN; + } + +-static bool smc_rx_recvmsg_data_available(struct smc_sock *smc) ++static bool smc_rx_recvmsg_data_available(struct smc_sock *smc, size_t peeked) + { + struct smc_connection *conn = &smc->conn; + +- if (smc_rx_data_available(conn)) ++ if (smc_rx_data_available(conn, peeked)) + return true; + else if (conn->urg_state == SMC_URG_VALID) + /* we received a single urgent Byte - skip */ +@@ -281,10 +282,10 @@ static bool smc_rx_recvmsg_data_available(struct smc_sock *smc) + int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, + struct pipe_inode_info *pipe, size_t len, int flags) + { +- size_t copylen, read_done = 0, read_remaining = len; ++ size_t copylen, read_done = 0, read_remaining = len, peeked_bytes = 0; + size_t chunk_len, chunk_off, chunk_len_sum; + struct smc_connection *conn = &smc->conn; +- int (*func)(struct smc_connection *conn); ++ int (*func)(struct smc_connection *conn, size_t baseline); + union smc_host_cursor cons; + int readable, chunk; + char *rcvbuf_base; +@@ -321,14 +322,14 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, + if (conn->killed) + break; + +- if (smc_rx_recvmsg_data_available(smc)) ++ if (smc_rx_recvmsg_data_available(smc, peeked_bytes)) + goto copy; + + if (sk->sk_shutdown & RCV_SHUTDOWN) { + /* smc_cdc_msg_recv_action() could have run after + * above smc_rx_recvmsg_data_available() + */ +- if (smc_rx_recvmsg_data_available(smc)) ++ if (smc_rx_recvmsg_data_available(smc, peeked_bytes)) + goto copy; + break; + } +@@ -362,26 +363,28 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, + } + } + +- if (!smc_rx_data_available(conn)) { +- smc_rx_wait(smc, &timeo, smc_rx_data_available); ++ if (!smc_rx_data_available(conn, peeked_bytes)) { ++ smc_rx_wait(smc, &timeo, peeked_bytes, smc_rx_data_available); + continue; + } + + copy: + /* initialize variables for 1st iteration of subsequent loop */ + /* could be just 1 byte, even after waiting on data above */ +- readable = atomic_read(&conn->bytes_to_rcv); ++ readable = smc_rx_data_available(conn, peeked_bytes); + splbytes = atomic_read(&conn->splice_pending); + if (!readable || (msg && splbytes)) { + if (splbytes) + func = smc_rx_data_available_and_no_splice_pend; + else + func = smc_rx_data_available; +- smc_rx_wait(smc, &timeo, func); ++ smc_rx_wait(smc, &timeo, peeked_bytes, func); + continue; + } + + smc_curs_copy(&cons, &conn->local_tx_ctrl.cons, conn); ++ if ((flags & MSG_PEEK) && peeked_bytes) ++ smc_curs_add(conn->rmb_desc->len, &cons, peeked_bytes); + /* subsequent splice() calls pick up where previous left */ + if (splbytes) + smc_curs_add(conn->rmb_desc->len, &cons, splbytes); +@@ -418,6 +421,8 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, + } + read_remaining -= chunk_len; + read_done += chunk_len; ++ if (flags & MSG_PEEK) ++ peeked_bytes += chunk_len; + + if (chunk_len_sum == copylen) + break; /* either on 1st or 2nd iteration */ +diff --git a/net/smc/smc_rx.h b/net/smc/smc_rx.h +index db823c97d824ea..994f5e42d1ba26 100644 +--- a/net/smc/smc_rx.h ++++ b/net/smc/smc_rx.h +@@ -21,11 +21,11 @@ void smc_rx_init(struct smc_sock *smc); + + int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, + struct pipe_inode_info *pipe, size_t len, int flags); +-int smc_rx_wait(struct smc_sock *smc, long *timeo, +- int (*fcrit)(struct smc_connection *conn)); +-static inline int smc_rx_data_available(struct smc_connection *conn) ++int smc_rx_wait(struct smc_sock *smc, long *timeo, size_t peeked, ++ int (*fcrit)(struct smc_connection *conn, size_t baseline)); ++static inline int smc_rx_data_available(struct smc_connection *conn, size_t peeked) + { +- return atomic_read(&conn->bytes_to_rcv); ++ return atomic_read(&conn->bytes_to_rcv) - peeked; + } + + #endif /* SMC_RX_H */ +diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c +index 8c9597b9a3f2e2..95aab48d32e674 100644 +--- a/net/sunrpc/cache.c ++++ b/net/sunrpc/cache.c +@@ -1659,12 +1659,14 @@ static void remove_cache_proc_entries(struct cache_detail *cd) + } + } + +-#ifdef CONFIG_PROC_FS + static int create_cache_proc_entries(struct cache_detail *cd, struct net *net) + { + struct proc_dir_entry *p; + struct sunrpc_net *sn; + ++ if (!IS_ENABLED(CONFIG_PROC_FS)) ++ return 0; ++ + sn = net_generic(net, sunrpc_net_id); + cd->procfs = proc_mkdir(cd->name, sn->proc_net_rpc); + if (cd->procfs == NULL) +@@ -1692,12 +1694,6 @@ static int create_cache_proc_entries(struct cache_detail *cd, struct net *net) + remove_cache_proc_entries(cd); + return -ENOMEM; + } +-#else /* CONFIG_PROC_FS */ +-static int create_cache_proc_entries(struct cache_detail *cd, struct net *net) +-{ +- return 0; +-} +-#endif + + void __init cache_initialize(void) + { +diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c +index 86d1e782b8fca7..b09c4a17b283e2 100644 +--- a/net/tipc/crypto.c ++++ b/net/tipc/crypto.c +@@ -2304,8 +2304,8 @@ static bool tipc_crypto_key_rcv(struct tipc_crypto *rx, struct tipc_msg *hdr) + keylen = ntohl(*((__be32 *)(data + TIPC_AEAD_ALG_NAME))); + + /* Verify the supplied size values */ +- if (unlikely(size != keylen + sizeof(struct tipc_aead_key) || +- keylen > TIPC_AEAD_KEY_SIZE_MAX)) { ++ if (unlikely(keylen > TIPC_AEAD_KEY_SIZE_MAX || ++ size != keylen + sizeof(struct tipc_aead_key))) { + pr_debug("%s: invalid MSG_CRYPTO key size\n", rx->name); + goto exit; + } +diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c +index 943d58b07a559d..29ce6cc7b40113 100644 +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -113,12 +113,14 @@ + static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr); + static void vsock_sk_destruct(struct sock *sk); + static int vsock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); ++static void vsock_close(struct sock *sk, long timeout); + + /* Protocol family. */ + static struct proto vsock_proto = { + .name = "AF_VSOCK", + .owner = THIS_MODULE, + .obj_size = sizeof(struct vsock_sock), ++ .close = vsock_close, + }; + + /* The default peer timeout indicates how long we will wait for a peer response +@@ -328,7 +330,10 @@ EXPORT_SYMBOL_GPL(vsock_find_connected_socket); + + void vsock_remove_sock(struct vsock_sock *vsk) + { +- vsock_remove_bound(vsk); ++ /* Transport reassignment must not remove the binding. */ ++ if (sock_flag(sk_vsock(vsk), SOCK_DEAD)) ++ vsock_remove_bound(vsk); ++ + vsock_remove_connected(vsk); + } + EXPORT_SYMBOL_GPL(vsock_remove_sock); +@@ -800,39 +805,44 @@ static bool sock_type_connectible(u16 type) + + static void __vsock_release(struct sock *sk, int level) + { +- if (sk) { +- struct sock *pending; +- struct vsock_sock *vsk; ++ struct vsock_sock *vsk; ++ struct sock *pending; + +- vsk = vsock_sk(sk); +- pending = NULL; /* Compiler warning. */ ++ vsk = vsock_sk(sk); ++ pending = NULL; /* Compiler warning. */ + +- /* When "level" is SINGLE_DEPTH_NESTING, use the nested +- * version to avoid the warning "possible recursive locking +- * detected". When "level" is 0, lock_sock_nested(sk, level) +- * is the same as lock_sock(sk). +- */ +- lock_sock_nested(sk, level); ++ /* When "level" is SINGLE_DEPTH_NESTING, use the nested ++ * version to avoid the warning "possible recursive locking ++ * detected". When "level" is 0, lock_sock_nested(sk, level) ++ * is the same as lock_sock(sk). ++ */ ++ lock_sock_nested(sk, level); + +- if (vsk->transport) +- vsk->transport->release(vsk); +- else if (sock_type_connectible(sk->sk_type)) +- vsock_remove_sock(vsk); ++ /* Indicate to vsock_remove_sock() that the socket is being released and ++ * can be removed from the bound_table. Unlike transport reassignment ++ * case, where the socket must remain bound despite vsock_remove_sock() ++ * being called from the transport release() callback. ++ */ ++ sock_set_flag(sk, SOCK_DEAD); + +- sock_orphan(sk); +- sk->sk_shutdown = SHUTDOWN_MASK; ++ if (vsk->transport) ++ vsk->transport->release(vsk); ++ else if (sock_type_connectible(sk->sk_type)) ++ vsock_remove_sock(vsk); + +- skb_queue_purge(&sk->sk_receive_queue); ++ sock_orphan(sk); ++ sk->sk_shutdown = SHUTDOWN_MASK; + +- /* Clean up any sockets that never were accepted. */ +- while ((pending = vsock_dequeue_accept(sk)) != NULL) { +- __vsock_release(pending, SINGLE_DEPTH_NESTING); +- sock_put(pending); +- } ++ skb_queue_purge(&sk->sk_receive_queue); + +- release_sock(sk); +- sock_put(sk); ++ /* Clean up any sockets that never were accepted. */ ++ while ((pending = vsock_dequeue_accept(sk)) != NULL) { ++ __vsock_release(pending, SINGLE_DEPTH_NESTING); ++ sock_put(pending); + } ++ ++ release_sock(sk); ++ sock_put(sk); + } + + static void vsock_sk_destruct(struct sock *sk) +@@ -899,9 +909,22 @@ s64 vsock_stream_has_space(struct vsock_sock *vsk) + } + EXPORT_SYMBOL_GPL(vsock_stream_has_space); + ++/* Dummy callback required by sockmap. ++ * See unconditional call of saved_close() in sock_map_close(). ++ */ ++static void vsock_close(struct sock *sk, long timeout) ++{ ++} ++ + static int vsock_release(struct socket *sock) + { +- __vsock_release(sock->sk, 0); ++ struct sock *sk = sock->sk; ++ ++ if (!sk) ++ return 0; ++ ++ sk->sk_prot->close(sk, 0); ++ __vsock_release(sk, 0); + sock->sk = NULL; + sock->state = SS_FREE; + +@@ -1386,6 +1409,11 @@ static int vsock_connect(struct socket *sock, struct sockaddr *addr, + if (err < 0) + goto out; + ++ /* sk_err might have been set as a result of an earlier ++ * (failed) connect attempt. ++ */ ++ sk->sk_err = 0; ++ + /* Mark sock as connecting and set the error code to in + * progress in case this is a non-blocking connect. + */ +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 457b197e31722c..a7f91b584ee0cc 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -3800,6 +3800,11 @@ static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags) + if (flags[flag]) + *mntrflags |= (1<bss_list, list) { + struct cfg80211_bss *res = &intbss->pub; + const struct cfg80211_bss_ies *ies; ++ const struct element *ssid_elem; ++ struct cfg80211_colocated_ap *entry; ++ u32 s_ssid_tmp; ++ int ret; + + ies = rcu_access_pointer(res->ies); + count += cfg80211_parse_colocated_ap(ies, + &coloc_ap_list); ++ ++ /* In case the scan request specified a specific BSSID ++ * and the BSS is found and operating on 6GHz band then ++ * add this AP to the collocated APs list. ++ * This is relevant for ML probe requests when the lower ++ * band APs have not been discovered. ++ */ ++ if (is_broadcast_ether_addr(rdev_req->bssid) || ++ !ether_addr_equal(rdev_req->bssid, res->bssid) || ++ res->channel->band != NL80211_BAND_6GHZ) ++ continue; ++ ++ ret = cfg80211_calc_short_ssid(ies, &ssid_elem, ++ &s_ssid_tmp); ++ if (ret) ++ continue; ++ ++ entry = kzalloc(sizeof(*entry), GFP_ATOMIC); ++ if (!entry) ++ continue; ++ ++ memcpy(entry->bssid, res->bssid, ETH_ALEN); ++ entry->short_ssid = s_ssid_tmp; ++ memcpy(entry->ssid, ssid_elem->data, ++ ssid_elem->datalen); ++ entry->ssid_len = ssid_elem->datalen; ++ entry->short_ssid_valid = true; ++ entry->center_freq = res->channel->center_freq; ++ ++ list_add_tail(&entry->list, &coloc_ap_list); ++ count++; + } + spin_unlock_bh(&rdev->bss_lock); + } +diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c +index 49dd788859d8b6..6f6a18dc375b79 100644 +--- a/net/xfrm/xfrm_replay.c ++++ b/net/xfrm/xfrm_replay.c +@@ -714,10 +714,12 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff + oseq += skb_shinfo(skb)->gso_segs; + } + +- if (unlikely(xo->seq.low < replay_esn->oseq)) { +- XFRM_SKB_CB(skb)->seq.output.hi = ++oseq_hi; +- xo->seq.hi = oseq_hi; +- replay_esn->oseq_hi = oseq_hi; ++ if (unlikely(oseq < replay_esn->oseq)) { ++ replay_esn->oseq_hi = ++oseq_hi; ++ if (xo->seq.low < replay_esn->oseq) { ++ XFRM_SKB_CB(skb)->seq.output.hi = oseq_hi; ++ xo->seq.hi = oseq_hi; ++ } + if (replay_esn->oseq_hi == 0) { + replay_esn->oseq--; + replay_esn->oseq_hi--; +diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c +index c089e9cdaf3283..1825a2935bd82a 100644 +--- a/samples/landlock/sandboxer.c ++++ b/samples/landlock/sandboxer.c +@@ -65,6 +65,9 @@ static int parse_path(char *env_path, const char ***const path_list) + } + } + *path_list = malloc(num_paths * sizeof(**path_list)); ++ if (!*path_list) ++ return -1; ++ + for (i = 0; i < num_paths; i++) + (*path_list)[i] = strsep(&env_path, ENV_PATH_TOKEN); + +@@ -99,6 +102,10 @@ static int populate_ruleset(const char *const env_var, const int ruleset_fd, + env_path_name = strdup(env_path_name); + unsetenv(env_var); + num_paths = parse_path(env_path_name, &path_list); ++ if (num_paths < 0) { ++ fprintf(stderr, "Failed to allocate memory\n"); ++ goto out_free_name; ++ } + if (num_paths == 1 && path_list[0][0] == '\0') { + /* + * Allows to not use all possible restrictions (e.g. use +diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn +index 6881a0c96bc131..6760008b6b383e 100644 +--- a/scripts/Makefile.extrawarn ++++ b/scripts/Makefile.extrawarn +@@ -37,6 +37,10 @@ KBUILD_CFLAGS += -Wno-missing-field-initializers + KBUILD_CFLAGS += -Wno-sign-compare + KBUILD_CFLAGS += -Wno-type-limits + ++ifdef CONFIG_CC_IS_CLANG ++KBUILD_CFLAGS += -Wno-enum-enum-conversion ++endif ++ + KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1 + + else +@@ -54,7 +58,6 @@ KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare + KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access) + KBUILD_CFLAGS += $(call cc-disable-warning, cast-function-type-strict) + KBUILD_CFLAGS += -Wno-enum-compare-conditional +-KBUILD_CFLAGS += -Wno-enum-enum-conversion + endif + + endif +diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c +index 4827c5abe5b71f..0c4d780fbbd836 100644 +--- a/scripts/genksyms/genksyms.c ++++ b/scripts/genksyms/genksyms.c +@@ -241,6 +241,7 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type, + "unchanged\n"); + } + sym->is_declared = 1; ++ free_list(defn, NULL); + return sym; + } else if (!sym->is_declared) { + if (sym->is_override && flag_preserve) { +@@ -249,6 +250,7 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type, + print_type_name(type, name); + fprintf(stderr, " modversion change\n"); + sym->is_declared = 1; ++ free_list(defn, NULL); + return sym; + } else { + status = is_unknown_symbol(sym) ? +@@ -256,6 +258,7 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type, + } + } else { + error_with_pos("redefinition of %s", name); ++ free_list(defn, NULL); + return sym; + } + break; +@@ -271,11 +274,15 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type, + break; + } + } ++ ++ free_list(sym->defn, NULL); ++ free(sym->name); ++ free(sym); + --nsyms; + } + + sym = xmalloc(sizeof(*sym)); +- sym->name = name; ++ sym->name = xstrdup(name); + sym->type = type; + sym->defn = defn; + sym->expansion_trail = NULL; +@@ -482,7 +489,7 @@ static void read_reference(FILE *f) + defn = def; + def = read_node(f); + } +- subsym = add_reference_symbol(xstrdup(sym->string), sym->tag, ++ subsym = add_reference_symbol(sym->string, sym->tag, + defn, is_extern); + subsym->is_override = is_override; + free_node(sym); +diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h +index 21ed2ec2d98ca8..5621533dcb8e43 100644 +--- a/scripts/genksyms/genksyms.h ++++ b/scripts/genksyms/genksyms.h +@@ -32,7 +32,7 @@ struct string_list { + + struct symbol { + struct symbol *hash_next; +- const char *name; ++ char *name; + enum symbol_type type; + struct string_list *defn; + struct symbol *expansion_trail; +diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y +index 8e9b5e69e8f01d..689cb6bb40b657 100644 +--- a/scripts/genksyms/parse.y ++++ b/scripts/genksyms/parse.y +@@ -152,14 +152,19 @@ simple_declaration: + ; + + init_declarator_list_opt: +- /* empty */ { $$ = NULL; } +- | init_declarator_list ++ /* empty */ { $$ = NULL; } ++ | init_declarator_list { free_list(decl_spec, NULL); $$ = $1; } + ; + + init_declarator_list: + init_declarator + { struct string_list *decl = *$1; + *$1 = NULL; ++ ++ /* avoid sharing among multiple init_declarators */ ++ if (decl_spec) ++ decl_spec = copy_list_range(decl_spec, NULL); ++ + add_symbol(current_name, + is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern); + current_name = NULL; +@@ -170,6 +175,11 @@ init_declarator_list: + *$3 = NULL; + free_list(*$2, NULL); + *$2 = decl_spec; ++ ++ /* avoid sharing among multiple init_declarators */ ++ if (decl_spec) ++ decl_spec = copy_list_range(decl_spec, NULL); ++ + add_symbol(current_name, + is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern); + current_name = NULL; +@@ -472,12 +482,12 @@ enumerator_list: + enumerator: + IDENT + { +- const char *name = strdup((*$1)->string); ++ const char *name = (*$1)->string; + add_symbol(name, SYM_ENUM_CONST, NULL, 0); + } + | IDENT '=' EXPRESSION_PHRASE + { +- const char *name = strdup((*$1)->string); ++ const char *name = (*$1)->string; + struct string_list *expr = copy_list_range(*$3, *$2); + add_symbol(name, SYM_ENUM_CONST, expr, 0); + } +diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c +index 5d84b44a2a2a71..ab1c41eb6d035a 100644 +--- a/scripts/kconfig/conf.c ++++ b/scripts/kconfig/conf.c +@@ -838,6 +838,9 @@ int main(int ac, char **av) + break; + } + ++ if (conf_errors()) ++ exit(1); ++ + if (sync_kconfig) { + name = getenv("KCONFIG_NOSILENTUPDATE"); + if (name && *name) { +@@ -898,6 +901,9 @@ int main(int ac, char **av) + break; + } + ++ if (sym_dep_errors()) ++ exit(1); ++ + if (input_mode == savedefconfig) { + if (conf_write_defconfig(defconfig_file)) { + fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n", +diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c +index 797c8bad3837a5..06d98ca4b612fe 100644 +--- a/scripts/kconfig/confdata.c ++++ b/scripts/kconfig/confdata.c +@@ -173,6 +173,13 @@ static void conf_message(const char *fmt, ...) + static const char *conf_filename; + static int conf_lineno, conf_warnings; + ++bool conf_errors(void) ++{ ++ if (conf_warnings) ++ return getenv("KCONFIG_WERROR"); ++ return false; ++} ++ + static void conf_warning(const char *fmt, ...) + { + va_list ap; +@@ -348,10 +355,12 @@ int conf_read_simple(const char *name, int def) + FILE *in = NULL; + char *line = NULL; + size_t line_asize = 0; +- char *p, *p2; ++ char *p, *p2, *val; + struct symbol *sym; + int i, def_flags; ++ const char *warn_unknown, *sym_name; + ++ warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS"); + if (name) { + in = zconf_fopen(name); + } else { +@@ -384,10 +393,12 @@ int conf_read_simple(const char *name, int def) + + *p = '\0'; + +- in = zconf_fopen(env); ++ name = env; ++ ++ in = zconf_fopen(name); + if (in) { + conf_message("using defaults found in %s", +- env); ++ name); + goto load; + } + +@@ -426,71 +437,34 @@ int conf_read_simple(const char *name, int def) + + while (compat_getline(&line, &line_asize, in) != -1) { + conf_lineno++; +- sym = NULL; + if (line[0] == '#') { +- if (memcmp(line + 2, CONFIG_, strlen(CONFIG_))) ++ if (line[1] != ' ') ++ continue; ++ p = line + 2; ++ if (memcmp(p, CONFIG_, strlen(CONFIG_))) + continue; +- p = strchr(line + 2 + strlen(CONFIG_), ' '); ++ sym_name = p + strlen(CONFIG_); ++ p = strchr(sym_name, ' '); + if (!p) + continue; + *p++ = 0; + if (strncmp(p, "is not set", 10)) + continue; +- if (def == S_DEF_USER) { +- sym = sym_find(line + 2 + strlen(CONFIG_)); +- if (!sym) { +- conf_set_changed(true); +- continue; +- } +- } else { +- sym = sym_lookup(line + 2 + strlen(CONFIG_), 0); +- if (sym->type == S_UNKNOWN) +- sym->type = S_BOOLEAN; +- } +- if (sym->flags & def_flags) { +- conf_warning("override: reassigning to symbol %s", sym->name); +- } +- switch (sym->type) { +- case S_BOOLEAN: +- case S_TRISTATE: +- sym->def[def].tri = no; +- sym->flags |= def_flags; +- break; +- default: +- ; +- } ++ ++ val = "n"; + } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) { +- p = strchr(line + strlen(CONFIG_), '='); ++ sym_name = line + strlen(CONFIG_); ++ p = strchr(sym_name, '='); + if (!p) + continue; + *p++ = 0; ++ val = p; + p2 = strchr(p, '\n'); + if (p2) { + *p2-- = 0; + if (*p2 == '\r') + *p2 = 0; + } +- +- sym = sym_find(line + strlen(CONFIG_)); +- if (!sym) { +- if (def == S_DEF_AUTO) +- /* +- * Reading from include/config/auto.conf +- * If CONFIG_FOO previously existed in +- * auto.conf but it is missing now, +- * include/config/FOO must be touched. +- */ +- conf_touch_dep(line + strlen(CONFIG_)); +- else +- conf_set_changed(true); +- continue; +- } +- +- if (sym->flags & def_flags) { +- conf_warning("override: reassigning to symbol %s", sym->name); +- } +- if (conf_set_sym_val(sym, def, def_flags, p)) +- continue; + } else { + if (line[0] != '\r' && line[0] != '\n') + conf_warning("unexpected data: %.*s", +@@ -499,6 +473,31 @@ int conf_read_simple(const char *name, int def) + continue; + } + ++ sym = sym_find(sym_name); ++ if (!sym) { ++ if (def == S_DEF_AUTO) { ++ /* ++ * Reading from include/config/auto.conf. ++ * If CONFIG_FOO previously existed in auto.conf ++ * but it is missing now, include/config/FOO ++ * must be touched. ++ */ ++ conf_touch_dep(sym_name); ++ } else { ++ if (warn_unknown) ++ conf_warning("unknown symbol: %s", sym_name); ++ ++ conf_set_changed(true); ++ } ++ continue; ++ } ++ ++ if (sym->flags & def_flags) ++ conf_warning("override: reassigning to symbol %s", sym->name); ++ ++ if (conf_set_sym_val(sym, def, def_flags, val)) ++ continue; ++ + if (sym && sym_is_choice_value(sym)) { + struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); + switch (sym->def[def].tri) { +@@ -521,6 +520,7 @@ int conf_read_simple(const char *name, int def) + } + free(line); + fclose(in); ++ + return 0; + } + +diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h +index a11626bdc421c4..d7783bc0a4f799 100644 +--- a/scripts/kconfig/lkc_proto.h ++++ b/scripts/kconfig/lkc_proto.h +@@ -12,6 +12,7 @@ void conf_set_changed(bool val); + bool conf_get_changed(void); + void conf_set_changed_callback(void (*fn)(void)); + void conf_set_message_callback(void (*fn)(const char *s)); ++bool conf_errors(void); + + /* symbol.c */ + extern struct symbol * symbol_hash[SYMBOL_HASHSIZE]; +@@ -22,6 +23,7 @@ const char * sym_escape_string_value(const char *in); + struct symbol ** sym_re_search(const char *pattern); + const char * sym_type_name(enum symbol_type type); + void sym_calc_value(struct symbol *sym); ++bool sym_dep_errors(void); + enum symbol_type sym_get_type(struct symbol *sym); + bool sym_tristate_within_range(struct symbol *sym,tristate tri); + bool sym_set_tristate_value(struct symbol *sym,tristate tri); +diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c +index f9786621a178ea..d1e9c06456ae69 100644 +--- a/scripts/kconfig/symbol.c ++++ b/scripts/kconfig/symbol.c +@@ -40,6 +40,7 @@ static struct symbol symbol_empty = { + + struct symbol *modules_sym; + static tristate modules_val; ++static int sym_warnings; + + enum symbol_type sym_get_type(struct symbol *sym) + { +@@ -320,6 +321,15 @@ static void sym_warn_unmet_dep(struct symbol *sym) + " Selected by [m]:\n"); + + fputs(str_get(&gs), stderr); ++ str_free(&gs); ++ sym_warnings++; ++} ++ ++bool sym_dep_errors(void) ++{ ++ if (sym_warnings) ++ return getenv("KCONFIG_WERROR"); ++ return false; + } + + void sym_calc_value(struct symbol *sym) +diff --git a/security/landlock/fs.c b/security/landlock/fs.c +index c5749301b37d67..a3d99bba5f1e79 100644 +--- a/security/landlock/fs.c ++++ b/security/landlock/fs.c +@@ -261,6 +261,18 @@ unmask_layers(const struct landlock_rule *const rule, + return false; + } + ++/* ++ * Allows access to pseudo filesystems that will never be mountable (e.g. ++ * sockfs, pipefs), but can still be reachable through ++ * /proc//fd/ ++ */ ++static inline bool is_nouser_or_private(const struct dentry *dentry) ++{ ++ return (dentry->d_sb->s_flags & SB_NOUSER) || ++ (d_is_positive(dentry) && ++ unlikely(IS_PRIVATE(d_backing_inode(dentry)))); ++} ++ + static int check_access_path(const struct landlock_ruleset *const domain, + const struct path *const path, + const access_mask_t access_request) +@@ -274,14 +286,7 @@ static int check_access_path(const struct landlock_ruleset *const domain, + return 0; + if (WARN_ON_ONCE(!domain || !path)) + return 0; +- /* +- * Allows access to pseudo filesystems that will never be mountable +- * (e.g. sockfs, pipefs), but can still be reachable through +- * /proc//fd/ . +- */ +- if ((path->dentry->d_sb->s_flags & SB_NOUSER) || +- (d_is_positive(path->dentry) && +- unlikely(IS_PRIVATE(d_backing_inode(path->dentry))))) ++ if (is_nouser_or_private(path->dentry)) + return 0; + if (WARN_ON_ONCE(domain->num_layers < 1)) + return -EACCES; +@@ -360,6 +365,38 @@ static inline int current_check_access_path(const struct path *const path, + return check_access_path(dom, path, access_request); + } + ++static inline access_mask_t get_mode_access(const umode_t mode) ++{ ++ switch (mode & S_IFMT) { ++ case S_IFLNK: ++ return LANDLOCK_ACCESS_FS_MAKE_SYM; ++ case S_IFDIR: ++ return LANDLOCK_ACCESS_FS_MAKE_DIR; ++ case S_IFCHR: ++ return LANDLOCK_ACCESS_FS_MAKE_CHAR; ++ case S_IFBLK: ++ return LANDLOCK_ACCESS_FS_MAKE_BLOCK; ++ case S_IFIFO: ++ return LANDLOCK_ACCESS_FS_MAKE_FIFO; ++ case S_IFSOCK: ++ return LANDLOCK_ACCESS_FS_MAKE_SOCK; ++ case S_IFREG: ++ case 0: ++ /* A zero mode translates to S_IFREG. */ ++ default: ++ /* Treats weird files as regular files. */ ++ return LANDLOCK_ACCESS_FS_MAKE_REG; ++ } ++} ++ ++static inline access_mask_t maybe_remove(const struct dentry *const dentry) ++{ ++ if (d_is_negative(dentry)) ++ return 0; ++ return d_is_dir(dentry) ? LANDLOCK_ACCESS_FS_REMOVE_DIR : ++ LANDLOCK_ACCESS_FS_REMOVE_FILE; ++} ++ + /* Inode hooks */ + + static void hook_inode_free_security(struct inode *const inode) +@@ -553,31 +590,6 @@ static int hook_sb_pivotroot(const struct path *const old_path, + + /* Path hooks */ + +-static inline access_mask_t get_mode_access(const umode_t mode) +-{ +- switch (mode & S_IFMT) { +- case S_IFLNK: +- return LANDLOCK_ACCESS_FS_MAKE_SYM; +- case 0: +- /* A zero mode translates to S_IFREG. */ +- case S_IFREG: +- return LANDLOCK_ACCESS_FS_MAKE_REG; +- case S_IFDIR: +- return LANDLOCK_ACCESS_FS_MAKE_DIR; +- case S_IFCHR: +- return LANDLOCK_ACCESS_FS_MAKE_CHAR; +- case S_IFBLK: +- return LANDLOCK_ACCESS_FS_MAKE_BLOCK; +- case S_IFIFO: +- return LANDLOCK_ACCESS_FS_MAKE_FIFO; +- case S_IFSOCK: +- return LANDLOCK_ACCESS_FS_MAKE_SOCK; +- default: +- WARN_ON_ONCE(1); +- return 0; +- } +-} +- + /* + * Creating multiple links or renaming may lead to privilege escalations if not + * handled properly. Indeed, we must be sure that the source doesn't gain more +@@ -606,14 +618,6 @@ static int hook_path_link(struct dentry *const old_dentry, + get_mode_access(d_backing_inode(old_dentry)->i_mode)); + } + +-static inline access_mask_t maybe_remove(const struct dentry *const dentry) +-{ +- if (d_is_negative(dentry)) +- return 0; +- return d_is_dir(dentry) ? LANDLOCK_ACCESS_FS_REMOVE_DIR : +- LANDLOCK_ACCESS_FS_REMOVE_FILE; +-} +- + static int hook_path_rename(const struct path *const old_dir, + struct dentry *const old_dentry, + const struct path *const new_dir, +diff --git a/security/safesetid/securityfs.c b/security/safesetid/securityfs.c +index 25310468bcddff..8e1ffd70b18ab4 100644 +--- a/security/safesetid/securityfs.c ++++ b/security/safesetid/securityfs.c +@@ -143,6 +143,9 @@ static ssize_t handle_policy_update(struct file *file, + char *buf, *p, *end; + int err; + ++ if (len >= KMALLOC_MAX_SIZE) ++ return -EINVAL; ++ + pol = kmalloc(sizeof(struct setid_ruleset), GFP_KERNEL); + if (!pol) + return -ENOMEM; +diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c +index 9a66e5826f25aa..cb8184122b9208 100644 +--- a/security/tomoyo/common.c ++++ b/security/tomoyo/common.c +@@ -2673,7 +2673,7 @@ ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head, + + if (head->w.avail >= head->writebuf_size - 1) { + const int len = head->writebuf_size * 2; +- char *cp = kzalloc(len, GFP_NOFS); ++ char *cp = kzalloc(len, GFP_NOFS | __GFP_NOWARN); + + if (!cp) { + error = -ENOMEM; +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index 6913d113bb4ea6..16c7fbb84276ac 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2212,6 +2212,8 @@ static const struct snd_pci_quirk power_save_denylist[] = { + SND_PCI_QUIRK(0x1631, 0xe017, "Packard Bell NEC IMEDIA 5204", 0), + /* KONTRON SinglePC may cause a stall at runtime resume */ + SND_PCI_QUIRK(0x1734, 0x1232, "KONTRON SinglePC", 0), ++ /* Dell ALC3271 */ ++ SND_PCI_QUIRK(0x1028, 0x0962, "Dell ALC3271", 0), + {} + }; + #endif /* CONFIG_PM */ +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index 520144df017446..59f6d70689dfc0 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -1098,6 +1098,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { + SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), + SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO), ++ SND_PCI_QUIRK(0x103c, 0x8231, "HP ProBook 450 G4", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE), +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index e4ab772f2331d6..6440a79f4d480b 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -3770,6 +3770,7 @@ static void alc225_init(struct hda_codec *codec) + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + + msleep(75); ++ alc_update_coef_idx(codec, 0x4a, 3 << 10, 0); + alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ + } + } +@@ -3824,6 +3825,79 @@ static void alc225_shutup(struct hda_codec *codec) + } + } + ++static void alc222_init(struct hda_codec *codec) ++{ ++ struct alc_spec *spec = codec->spec; ++ hda_nid_t hp_pin = alc_get_hp_pin(spec); ++ bool hp1_pin_sense, hp2_pin_sense; ++ ++ if (!hp_pin) ++ return; ++ ++ msleep(30); ++ ++ hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin); ++ hp2_pin_sense = snd_hda_jack_detect(codec, 0x14); ++ ++ if (hp1_pin_sense || hp2_pin_sense) { ++ msleep(2); ++ ++ if (hp1_pin_sense) ++ snd_hda_codec_write(codec, hp_pin, 0, ++ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); ++ if (hp2_pin_sense) ++ snd_hda_codec_write(codec, 0x14, 0, ++ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); ++ msleep(75); ++ ++ if (hp1_pin_sense) ++ snd_hda_codec_write(codec, hp_pin, 0, ++ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); ++ if (hp2_pin_sense) ++ snd_hda_codec_write(codec, 0x14, 0, ++ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); ++ ++ msleep(75); ++ } ++} ++ ++static void alc222_shutup(struct hda_codec *codec) ++{ ++ struct alc_spec *spec = codec->spec; ++ hda_nid_t hp_pin = alc_get_hp_pin(spec); ++ bool hp1_pin_sense, hp2_pin_sense; ++ ++ if (!hp_pin) ++ hp_pin = 0x21; ++ ++ hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin); ++ hp2_pin_sense = snd_hda_jack_detect(codec, 0x14); ++ ++ if (hp1_pin_sense || hp2_pin_sense) { ++ msleep(2); ++ ++ if (hp1_pin_sense) ++ snd_hda_codec_write(codec, hp_pin, 0, ++ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); ++ if (hp2_pin_sense) ++ snd_hda_codec_write(codec, 0x14, 0, ++ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); ++ ++ msleep(75); ++ ++ if (hp1_pin_sense) ++ snd_hda_codec_write(codec, hp_pin, 0, ++ AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); ++ if (hp2_pin_sense) ++ snd_hda_codec_write(codec, 0x14, 0, ++ AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); ++ ++ msleep(75); ++ } ++ alc_auto_setup_eapd(codec, false); ++ alc_shutup_pins(codec); ++} ++ + static void alc_default_init(struct hda_codec *codec) + { + struct alc_spec *spec = codec->spec; +@@ -9517,6 +9591,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), + SND_PCI_QUIRK(0x17aa, 0x9e56, "Lenovo ZhaoYang CF4620Z", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0x1849, 0x0269, "Positivo Master C6400", ALC269VB_FIXUP_ASUS_ZENBOOK), + SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK), + SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS), +@@ -10372,8 +10447,11 @@ static int patch_alc269(struct hda_codec *codec) + spec->codec_variant = ALC269_TYPE_ALC300; + spec->gen.mixer_nid = 0; /* no loopback on ALC300 */ + break; ++ case 0x10ec0222: + case 0x10ec0623: + spec->codec_variant = ALC269_TYPE_ALC623; ++ spec->shutup = alc222_shutup; ++ spec->init_hook = alc222_init; + break; + case 0x10ec0700: + case 0x10ec0701: +diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c +index ca3b1c00fa7875..fe4763805df941 100644 +--- a/sound/soc/codecs/es8328.c ++++ b/sound/soc/codecs/es8328.c +@@ -234,7 +234,6 @@ static const struct snd_kcontrol_new es8328_right_line_controls = + + /* Left Mixer */ + static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { +- SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL17, 7, 1, 0), + SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL17, 6, 1, 0), + SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL18, 7, 1, 0), + SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL18, 6, 1, 0), +@@ -244,7 +243,6 @@ static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { + static const struct snd_kcontrol_new es8328_right_mixer_controls[] = { + SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL19, 7, 1, 0), + SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL19, 6, 1, 0), +- SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL20, 7, 1, 0), + SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL20, 6, 1, 0), + }; + +@@ -337,10 +335,10 @@ static const struct snd_soc_dapm_widget es8328_dapm_widgets[] = { + SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ES8328_DACPOWER, + ES8328_DACPOWER_LDAC_OFF, 1), + +- SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, ++ SND_SOC_DAPM_MIXER("Left Mixer", ES8328_DACCONTROL17, 7, 0, + &es8328_left_mixer_controls[0], + ARRAY_SIZE(es8328_left_mixer_controls)), +- SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, ++ SND_SOC_DAPM_MIXER("Right Mixer", ES8328_DACCONTROL20, 7, 0, + &es8328_right_mixer_controls[0], + ARRAY_SIZE(es8328_right_mixer_controls)), + +@@ -419,19 +417,14 @@ static const struct snd_soc_dapm_route es8328_dapm_routes[] = { + { "Right Line Mux", "PGA", "Right PGA Mux" }, + { "Right Line Mux", "Differential", "Differential Mux" }, + +- { "Left Out 1", NULL, "Left DAC" }, +- { "Right Out 1", NULL, "Right DAC" }, +- { "Left Out 2", NULL, "Left DAC" }, +- { "Right Out 2", NULL, "Right DAC" }, +- +- { "Left Mixer", "Playback Switch", "Left DAC" }, ++ { "Left Mixer", NULL, "Left DAC" }, + { "Left Mixer", "Left Bypass Switch", "Left Line Mux" }, + { "Left Mixer", "Right Playback Switch", "Right DAC" }, + { "Left Mixer", "Right Bypass Switch", "Right Line Mux" }, + + { "Right Mixer", "Left Playback Switch", "Left DAC" }, + { "Right Mixer", "Left Bypass Switch", "Left Line Mux" }, +- { "Right Mixer", "Playback Switch", "Right DAC" }, ++ { "Right Mixer", NULL, "Right DAC" }, + { "Right Mixer", "Right Bypass Switch", "Right Line Mux" }, + + { "DAC DIG", NULL, "DAC STM" }, +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index 8706fef8ccce81..721b9971fd7445 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -1102,7 +1102,22 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { + BYT_RT5640_SSP0_AIF2 | + BYT_RT5640_MCLK_EN), + }, +- { /* Vexia Edu Atla 10 tablet */ ++ { ++ /* Vexia Edu Atla 10 tablet 5V version */ ++ .matches = { ++ /* Having all 3 of these not set is somewhat unique */ ++ DMI_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "To be filled by O.E.M."), ++ DMI_MATCH(DMI_BOARD_NAME, "To be filled by O.E.M."), ++ /* Above strings are too generic, also match on BIOS date */ ++ DMI_MATCH(DMI_BIOS_DATE, "05/14/2015"), ++ }, ++ .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | ++ BYT_RT5640_JD_NOT_INV | ++ BYT_RT5640_SSP0_AIF1 | ++ BYT_RT5640_MCLK_EN), ++ }, ++ { /* Vexia Edu Atla 10 tablet 9V version */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), +diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c +index 2e33a1fa0a6f46..b6a7011b4e3b19 100644 +--- a/sound/soc/sh/rz-ssi.c ++++ b/sound/soc/sh/rz-ssi.c +@@ -243,8 +243,7 @@ static void rz_ssi_stream_quit(struct rz_ssi_priv *ssi, + static int rz_ssi_clk_setup(struct rz_ssi_priv *ssi, unsigned int rate, + unsigned int channels) + { +- static s8 ckdv[16] = { 1, 2, 4, 8, 16, 32, 64, 128, +- 6, 12, 24, 48, 96, -1, -1, -1 }; ++ static u8 ckdv[] = { 1, 2, 4, 8, 16, 32, 64, 128, 6, 12, 24, 48, 96 }; + unsigned int channel_bits = 32; /* System Word Length */ + unsigned long bclk_rate = rate * channels * channel_bits; + unsigned int div; +@@ -488,6 +487,8 @@ static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) + sample_space = strm->fifo_sample_size; + ssifsr = rz_ssi_reg_readl(ssi, SSIFSR); + sample_space -= (ssifsr >> SSIFSR_TDC_SHIFT) & SSIFSR_TDC_MASK; ++ if (sample_space < 0) ++ return -EINVAL; + + /* Only add full frames at a time */ + while (frames_left && (sample_space >= runtime->channels)) { +diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c +index dd8d13f3fd1219..e885af039b92fc 100644 +--- a/sound/soc/sunxi/sun4i-spdif.c ++++ b/sound/soc/sunxi/sun4i-spdif.c +@@ -175,6 +175,7 @@ struct sun4i_spdif_quirks { + unsigned int reg_dac_txdata; + bool has_reset; + unsigned int val_fctl_ftx; ++ unsigned int mclk_multiplier; + }; + + struct sun4i_spdif_dev { +@@ -311,6 +312,7 @@ static int sun4i_spdif_hw_params(struct snd_pcm_substream *substream, + default: + return -EINVAL; + } ++ mclk *= host->quirks->mclk_multiplier; + + ret = clk_set_rate(host->spdif_clk, mclk); + if (ret < 0) { +@@ -345,6 +347,7 @@ static int sun4i_spdif_hw_params(struct snd_pcm_substream *substream, + default: + return -EINVAL; + } ++ mclk_div *= host->quirks->mclk_multiplier; + + reg_val = 0; + reg_val |= SUN4I_SPDIF_TXCFG_ASS; +@@ -427,24 +430,28 @@ static struct snd_soc_dai_driver sun4i_spdif_dai = { + static const struct sun4i_spdif_quirks sun4i_a10_spdif_quirks = { + .reg_dac_txdata = SUN4I_SPDIF_TXFIFO, + .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, ++ .mclk_multiplier = 1, + }; + + static const struct sun4i_spdif_quirks sun6i_a31_spdif_quirks = { + .reg_dac_txdata = SUN4I_SPDIF_TXFIFO, + .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, + .has_reset = true, ++ .mclk_multiplier = 1, + }; + + static const struct sun4i_spdif_quirks sun8i_h3_spdif_quirks = { + .reg_dac_txdata = SUN8I_SPDIF_TXFIFO, + .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, + .has_reset = true, ++ .mclk_multiplier = 4, + }; + + static const struct sun4i_spdif_quirks sun50i_h6_spdif_quirks = { + .reg_dac_txdata = SUN8I_SPDIF_TXFIFO, + .val_fctl_ftx = SUN50I_H6_SPDIF_FCTL_FTX, + .has_reset = true, ++ .mclk_multiplier = 1, + }; + + static const struct of_device_id sun4i_spdif_of_match[] = { +diff --git a/sound/usb/midi.c b/sound/usb/midi.c +index 9a361b202a09d9..a56c1a69b422a1 100644 +--- a/sound/usb/midi.c ++++ b/sound/usb/midi.c +@@ -1145,7 +1145,7 @@ static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) + { + struct usbmidi_out_port *port = substream->runtime->private_data; + +- cancel_work_sync(&port->ep->work); ++ flush_work(&port->ep->work); + return substream_open(substream, 0, 0); + } + +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 1c13d5275fa3ae..10430c76475b5f 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1502,6 +1502,7 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs, + case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */ + subs->stream_offset_adj = 2; + break; ++ case USB_ID(0x2b73, 0x000a): /* Pioneer DJM-900NXS2 */ + case USB_ID(0x2b73, 0x0013): /* Pioneer DJM-450 */ + pioneer_djm_set_format_quirk(subs, 0x0082); + break; +@@ -1934,6 +1935,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x2d95, 0x8021, /* VIVO USB-C-XE710 HEADSET */ + QUIRK_FLAG_CTL_MSG_DELAY_1M), ++ DEVICE_FLG(0x2fc6, 0xf0b7, /* iBasso DC07 Pro */ ++ QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */ + QUIRK_FLAG_IGNORE_CTL_ERROR), + DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */ +diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c +index c3292afa883ee8..b8f0c0298f14a3 100644 +--- a/sound/usb/usx2y/usbusx2y.c ++++ b/sound/usb/usx2y/usbusx2y.c +@@ -151,6 +151,12 @@ static int snd_usx2y_card_used[SNDRV_CARDS]; + static void snd_usx2y_card_private_free(struct snd_card *card); + static void usx2y_unlinkseq(struct snd_usx2y_async_seq *s); + ++#ifdef USX2Y_NRPACKS_VARIABLE ++int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */ ++module_param(nrpacks, int, 0444); ++MODULE_PARM_DESC(nrpacks, "Number of packets per URB."); ++#endif ++ + /* + * pipe 4 is used for switching the lamps, setting samplerate, volumes .... + */ +@@ -433,6 +439,11 @@ static int snd_usx2y_probe(struct usb_interface *intf, + struct snd_card *card; + int err; + ++#ifdef USX2Y_NRPACKS_VARIABLE ++ if (nrpacks < 0 || nrpacks > USX2Y_NRPACKS_MAX) ++ return -EINVAL; ++#endif ++ + if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 || + (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 && + le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 && +diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h +index 8d82f5cc2fe1c8..0538c457921e67 100644 +--- a/sound/usb/usx2y/usbusx2y.h ++++ b/sound/usb/usx2y/usbusx2y.h +@@ -7,6 +7,32 @@ + + #define NRURBS 2 + ++/* Default value used for nr of packs per urb. ++ * 1 to 4 have been tested ok on uhci. ++ * To use 3 on ohci, you'd need a patch: ++ * look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on ++ * "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425" ++ * ++ * 1, 2 and 4 work out of the box on ohci, if I recall correctly. ++ * Bigger is safer operation, smaller gives lower latencies. ++ */ ++#define USX2Y_NRPACKS 4 ++ ++#define USX2Y_NRPACKS_MAX 1024 ++ ++/* If your system works ok with this module's parameter ++ * nrpacks set to 1, you might as well comment ++ * this define out, and thereby produce smaller, faster code. ++ * You'd also set USX2Y_NRPACKS to 1 then. ++ */ ++#define USX2Y_NRPACKS_VARIABLE 1 ++ ++#ifdef USX2Y_NRPACKS_VARIABLE ++extern int nrpacks; ++#define nr_of_packs() nrpacks ++#else ++#define nr_of_packs() USX2Y_NRPACKS ++#endif + + #define URBS_ASYNC_SEQ 10 + #define URB_DATA_LEN_ASYNC_SEQ 32 +diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c +index c39cc6851e2d73..a6ed4f0230b7fa 100644 +--- a/sound/usb/usx2y/usbusx2yaudio.c ++++ b/sound/usb/usx2y/usbusx2yaudio.c +@@ -28,33 +28,6 @@ + #include "usx2y.h" + #include "usbusx2y.h" + +-/* Default value used for nr of packs per urb. +- * 1 to 4 have been tested ok on uhci. +- * To use 3 on ohci, you'd need a patch: +- * look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on +- * "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425" +- * +- * 1, 2 and 4 work out of the box on ohci, if I recall correctly. +- * Bigger is safer operation, smaller gives lower latencies. +- */ +-#define USX2Y_NRPACKS 4 +- +-/* If your system works ok with this module's parameter +- * nrpacks set to 1, you might as well comment +- * this define out, and thereby produce smaller, faster code. +- * You'd also set USX2Y_NRPACKS to 1 then. +- */ +-#define USX2Y_NRPACKS_VARIABLE 1 +- +-#ifdef USX2Y_NRPACKS_VARIABLE +-static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */ +-#define nr_of_packs() nrpacks +-module_param(nrpacks, int, 0444); +-MODULE_PARM_DESC(nrpacks, "Number of packets per URB."); +-#else +-#define nr_of_packs() USX2Y_NRPACKS +-#endif +- + static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs) + { + struct urb *urb = subs->completed_urb; +diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c +index fd67496a947f3c..fc922cfdadaa67 100644 +--- a/tools/bootconfig/main.c ++++ b/tools/bootconfig/main.c +@@ -225,7 +225,7 @@ static int load_xbc_from_initrd(int fd, char **buf) + /* Wrong Checksum */ + rcsum = xbc_calc_checksum(*buf, size); + if (csum != rcsum) { +- pr_err("checksum error: %d != %d\n", csum, rcsum); ++ pr_err("checksum error: %u != %u\n", csum, rcsum); + return -EINVAL; + } + +@@ -393,7 +393,7 @@ static int apply_xbc(const char *path, const char *xbc_path) + printf("Apply %s to %s\n", xbc_path, path); + printf("\tNumber of nodes: %d\n", ret); + printf("\tSize: %u bytes\n", (unsigned int)size); +- printf("\tChecksum: %d\n", (unsigned int)csum); ++ printf("\tChecksum: %u\n", (unsigned int)csum); + + /* TODO: Check the options by schema */ + xbc_destroy_all(); +diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c +index 8907d4238818cd..2adf55f4874300 100644 +--- a/tools/lib/bpf/linker.c ++++ b/tools/lib/bpf/linker.c +@@ -568,17 +568,15 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename, + } + obj->elf = elf_begin(obj->fd, ELF_C_READ_MMAP, NULL); + if (!obj->elf) { +- err = -errno; + pr_warn_elf("failed to parse ELF file '%s'", filename); +- return err; ++ return -EINVAL; + } + + /* Sanity check ELF file high-level properties */ + ehdr = elf64_getehdr(obj->elf); + if (!ehdr) { +- err = -errno; + pr_warn_elf("failed to get ELF header for %s", filename); +- return err; ++ return -EINVAL; + } + if (ehdr->e_ident[EI_DATA] != host_endianness) { + err = -EOPNOTSUPP; +@@ -594,9 +592,8 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename, + } + + if (elf_getshdrstrndx(obj->elf, &obj->shstrs_sec_idx)) { +- err = -errno; + pr_warn_elf("failed to get SHSTRTAB section index for %s", filename); +- return err; ++ return -EINVAL; + } + + scn = NULL; +@@ -606,26 +603,23 @@ static int linker_load_obj_file(struct bpf_linker *linker, const char *filename, + + shdr = elf64_getshdr(scn); + if (!shdr) { +- err = -errno; + pr_warn_elf("failed to get section #%zu header for %s", + sec_idx, filename); +- return err; ++ return -EINVAL; + } + + sec_name = elf_strptr(obj->elf, obj->shstrs_sec_idx, shdr->sh_name); + if (!sec_name) { +- err = -errno; + pr_warn_elf("failed to get section #%zu name for %s", + sec_idx, filename); +- return err; ++ return -EINVAL; + } + + data = elf_getdata(scn, 0); + if (!data) { +- err = -errno; + pr_warn_elf("failed to get section #%zu (%s) data from %s", + sec_idx, sec_name, filename); +- return err; ++ return -EINVAL; + } + + sec = add_src_sec(obj, sec_name); +@@ -2601,14 +2595,14 @@ int bpf_linker__finalize(struct bpf_linker *linker) + + /* Finalize ELF layout */ + if (elf_update(linker->elf, ELF_C_NULL) < 0) { +- err = -errno; ++ err = -EINVAL; + pr_warn_elf("failed to finalize ELF layout"); + return libbpf_err(err); + } + + /* Write out final ELF contents */ + if (elf_update(linker->elf, ELF_C_WRITE) < 0) { +- err = -errno; ++ err = -EINVAL; + pr_warn_elf("failed to write ELF contents"); + return libbpf_err(err); + } +diff --git a/tools/perf/bench/epoll-wait.c b/tools/perf/bench/epoll-wait.c +index 79d13dbc0a47b2..110d67586373f9 100644 +--- a/tools/perf/bench/epoll-wait.c ++++ b/tools/perf/bench/epoll-wait.c +@@ -406,7 +406,12 @@ static int cmpworker(const void *p1, const void *p2) + + struct worker *w1 = (struct worker *) p1; + struct worker *w2 = (struct worker *) p2; +- return w1->tid > w2->tid; ++ ++ if (w1->tid > w2->tid) ++ return 1; ++ if (w1->tid < w2->tid) ++ return -1; ++ return 0; + } + + int bench_epoll_wait(int argc, const char **argv) +diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c +index 6583ad9cc7deb2..c52b321e22ccf1 100644 +--- a/tools/perf/builtin-report.c ++++ b/tools/perf/builtin-report.c +@@ -1308,7 +1308,7 @@ int cmd_report(int argc, const char **argv) + OPT_STRING(0, "objdump", &report.annotation_opts.objdump_path, "path", + "objdump binary to use for disassembly and annotations"), + OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, +- "Disable symbol demangling"), ++ "Symbol demangling. Enabled by default, use --no-demangle to disable."), + OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, + "Enable kernel symbol demangling"), + OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"), +diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c +index 6fdd401ec9c561..b318ce937e629c 100644 +--- a/tools/perf/builtin-top.c ++++ b/tools/perf/builtin-top.c +@@ -807,7 +807,7 @@ static void perf_event__process_sample(struct perf_tool *tool, + * invalid --vmlinux ;-) + */ + if (!machine->kptr_restrict_warned && !top->vmlinux_warned && +- __map__is_kernel(al.map) && map__has_symbols(al.map)) { ++ __map__is_kernel(al.map) && !map__has_symbols(al.map)) { + if (symbol_conf.vmlinux_name) { + char serr[256]; + dso__strerror_load(al.map->dso, serr, sizeof(serr)); +diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c +index 65f94597590efd..c569e090fa976a 100644 +--- a/tools/perf/builtin-trace.c ++++ b/tools/perf/builtin-trace.c +@@ -1813,8 +1813,12 @@ static int trace__read_syscall_info(struct trace *trace, int id) + return PTR_ERR(sc->tp_format); + } + ++ /* ++ * The tracepoint format contains __syscall_nr field, so it's one more ++ * than the actual number of syscall arguments. ++ */ + if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ? +- RAW_SYSCALL_ARGS_NUM : sc->tp_format->format.nr_fields)) ++ RAW_SYSCALL_ARGS_NUM : sc->tp_format->format.nr_fields - 1)) + return -ENOMEM; + + sc->args = sc->tp_format->format.fields; +diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c +index ce74bc367e9c4f..41b889ab4d6ab6 100644 +--- a/tools/perf/util/bpf-event.c ++++ b/tools/perf/util/bpf-event.c +@@ -300,7 +300,10 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session, + } + + info_node->info_linear = info_linear; +- perf_env__insert_bpf_prog_info(env, info_node); ++ if (!perf_env__insert_bpf_prog_info(env, info_node)) { ++ free(info_linear); ++ free(info_node); ++ } + info_linear = NULL; + + /* +@@ -488,7 +491,10 @@ static void perf_env__add_bpf_info(struct perf_env *env, u32 id) + info_node = malloc(sizeof(struct bpf_prog_info_node)); + if (info_node) { + info_node->info_linear = info_linear; +- perf_env__insert_bpf_prog_info(env, info_node); ++ if (!perf_env__insert_bpf_prog_info(env, info_node)) { ++ free(info_linear); ++ free(info_node); ++ } + } else + free(info_linear); + +diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c +index d3d67ce70f5565..6903accf3a5c43 100644 +--- a/tools/perf/util/env.c ++++ b/tools/perf/util/env.c +@@ -18,15 +18,19 @@ struct perf_env perf_env; + #include "bpf-event.h" + #include + +-void perf_env__insert_bpf_prog_info(struct perf_env *env, ++bool perf_env__insert_bpf_prog_info(struct perf_env *env, + struct bpf_prog_info_node *info_node) + { ++ bool ret; ++ + down_write(&env->bpf_progs.lock); +- __perf_env__insert_bpf_prog_info(env, info_node); ++ ret = __perf_env__insert_bpf_prog_info(env, info_node); + up_write(&env->bpf_progs.lock); ++ ++ return ret; + } + +-void __perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info_node *info_node) ++bool __perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info_node *info_node) + { + __u32 prog_id = info_node->info_linear->info.id; + struct bpf_prog_info_node *node; +@@ -44,13 +48,14 @@ void __perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info + p = &(*p)->rb_right; + } else { + pr_debug("duplicated bpf prog info %u\n", prog_id); +- return; ++ return false; + } + } + + rb_link_node(&info_node->rb_node, parent, p); + rb_insert_color(&info_node->rb_node, &env->bpf_progs.infos); + env->bpf_progs.infos_cnt++; ++ return true; + } + + struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env, +diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h +index 192318054e12f7..5385104ca989a1 100644 +--- a/tools/perf/util/env.h ++++ b/tools/perf/util/env.h +@@ -163,9 +163,9 @@ const char *perf_env__raw_arch(struct perf_env *env); + int perf_env__nr_cpus_avail(struct perf_env *env); + + void perf_env__init(struct perf_env *env); +-void __perf_env__insert_bpf_prog_info(struct perf_env *env, ++bool __perf_env__insert_bpf_prog_info(struct perf_env *env, + struct bpf_prog_info_node *info_node); +-void perf_env__insert_bpf_prog_info(struct perf_env *env, ++bool perf_env__insert_bpf_prog_info(struct perf_env *env, + struct bpf_prog_info_node *info_node); + struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env, + __u32 prog_id); +diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c +index 8b0a8ac7afefd7..3e18acb7193249 100644 +--- a/tools/perf/util/header.c ++++ b/tools/perf/util/header.c +@@ -3073,7 +3073,10 @@ static int process_bpf_prog_info(struct feat_fd *ff, void *data __maybe_unused) + /* after reading from file, translate offset to address */ + bpf_program__bpil_offs_to_addr(info_linear); + info_node->info_linear = info_linear; +- __perf_env__insert_bpf_prog_info(env, info_node); ++ if (!__perf_env__insert_bpf_prog_info(env, info_node)) { ++ free(info_linear); ++ free(info_node); ++ } + } + + up_write(&env->bpf_progs.lock); +@@ -3120,7 +3123,8 @@ static int process_bpf_btf(struct feat_fd *ff, void *data __maybe_unused) + if (__do_read(ff, node->data, data_size)) + goto out; + +- __perf_env__insert_btf(env, node); ++ if (!__perf_env__insert_btf(env, node)) ++ free(node); + node = NULL; + } + +diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c +index ae6af354a81db5..08a399b0be286c 100644 +--- a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c ++++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c +@@ -33,7 +33,7 @@ static int mperf_get_count_percent(unsigned int self_id, double *percent, + unsigned int cpu); + static int mperf_get_count_freq(unsigned int id, unsigned long long *count, + unsigned int cpu); +-static struct timespec time_start, time_end; ++static struct timespec *time_start, *time_end; + + static cstate_t mperf_cstates[MPERF_CSTATE_COUNT] = { + { +@@ -174,7 +174,7 @@ static int mperf_get_count_percent(unsigned int id, double *percent, + dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n", + mperf_cstates[id].name, mperf_diff, tsc_diff); + } else if (max_freq_mode == MAX_FREQ_SYSFS) { +- timediff = max_frequency * timespec_diff_us(time_start, time_end); ++ timediff = max_frequency * timespec_diff_us(time_start[cpu], time_end[cpu]); + *percent = 100.0 * mperf_diff / timediff; + dprint("%s: MAXFREQ - mperf_diff: %llu, time_diff: %llu\n", + mperf_cstates[id].name, mperf_diff, timediff); +@@ -207,7 +207,7 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count, + if (max_freq_mode == MAX_FREQ_TSC_REF) { + /* Calculate max_freq from TSC count */ + tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu]; +- time_diff = timespec_diff_us(time_start, time_end); ++ time_diff = timespec_diff_us(time_start[cpu], time_end[cpu]); + max_frequency = tsc_diff / time_diff; + } + +@@ -226,9 +226,8 @@ static int mperf_start(void) + { + int cpu; + +- clock_gettime(CLOCK_REALTIME, &time_start); +- + for (cpu = 0; cpu < cpu_count; cpu++) { ++ clock_gettime(CLOCK_REALTIME, &time_start[cpu]); + mperf_get_tsc(&tsc_at_measure_start[cpu]); + mperf_init_stats(cpu); + } +@@ -243,9 +242,9 @@ static int mperf_stop(void) + for (cpu = 0; cpu < cpu_count; cpu++) { + mperf_measure_stats(cpu); + mperf_get_tsc(&tsc_at_measure_end[cpu]); ++ clock_gettime(CLOCK_REALTIME, &time_end[cpu]); + } + +- clock_gettime(CLOCK_REALTIME, &time_end); + return 0; + } + +@@ -349,6 +348,8 @@ struct cpuidle_monitor *mperf_register(void) + aperf_current_count = calloc(cpu_count, sizeof(unsigned long long)); + tsc_at_measure_start = calloc(cpu_count, sizeof(unsigned long long)); + tsc_at_measure_end = calloc(cpu_count, sizeof(unsigned long long)); ++ time_start = calloc(cpu_count, sizeof(struct timespec)); ++ time_end = calloc(cpu_count, sizeof(struct timespec)); + mperf_monitor.name_len = strlen(mperf_monitor.name); + return &mperf_monitor; + } +@@ -361,6 +362,8 @@ void mperf_unregister(void) + free(aperf_current_count); + free(tsc_at_measure_start); + free(tsc_at_measure_end); ++ free(time_start); ++ free(time_end); + free(is_valid); + } + +diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl +index 99e17a0a13649f..aecea16cbd02f1 100755 +--- a/tools/testing/ktest/ktest.pl ++++ b/tools/testing/ktest/ktest.pl +@@ -2399,6 +2399,11 @@ sub get_version { + return if ($have_version); + doprint "$make kernelrelease ... "; + $version = `$make -s kernelrelease | tail -1`; ++ if (!length($version)) { ++ run_command "$make allnoconfig" or return 0; ++ doprint "$make kernelrelease ... "; ++ $version = `$make -s kernelrelease | tail -1`; ++ } + chomp($version); + doprint "$version\n"; + $have_version = 1; +@@ -2939,8 +2944,6 @@ sub run_bisect_test { + + my $failed = 0; + my $result; +- my $output; +- my $ret; + + $in_bisect = 1; + +diff --git a/tools/testing/selftests/bpf/test_tc_tunnel.sh b/tools/testing/selftests/bpf/test_tc_tunnel.sh +index 38c6e9f16f41e6..88488779792ff7 100755 +--- a/tools/testing/selftests/bpf/test_tc_tunnel.sh ++++ b/tools/testing/selftests/bpf/test_tc_tunnel.sh +@@ -295,6 +295,7 @@ else + client_connect + verify_data + server_listen ++ wait_for_port ${port} ${netcat_opt} + fi + + # bpf_skb_net_shrink does not take tunnel flags yet, cannot update L3. +diff --git a/tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh b/tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh +index 185b02d2d4cd14..7af78990b5bb60 100755 +--- a/tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh ++++ b/tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh +@@ -142,7 +142,7 @@ function pre_ethtool { + } + + function check_table { +- local path=$NSIM_DEV_DFS/ports/$port/udp_ports_table$1 ++ local path=$NSIM_DEV_DFS/ports/$port/udp_ports/table$1 + local -n expected=$2 + local last=$3 + +@@ -212,7 +212,7 @@ function check_tables { + } + + function print_table { +- local path=$NSIM_DEV_DFS/ports/$port/udp_ports_table$1 ++ local path=$NSIM_DEV_DFS/ports/$port/udp_ports/table$1 + read -a have < $path + + tree $NSIM_DEV_DFS/ +@@ -640,7 +640,7 @@ for port in 0 1; do + NSIM_NETDEV=`get_netdev_name old_netdevs` + ifconfig $NSIM_NETDEV up + +- echo 110 > $NSIM_DEV_DFS/ports/$port/udp_ports_inject_error ++ echo 110 > $NSIM_DEV_DFS/ports/$port/udp_ports/inject_error + + msg="1 - create VxLANs v6" + exp0=( 0 0 0 0 ) +@@ -662,7 +662,7 @@ for port in 0 1; do + new_geneve gnv0 20000 + + msg="2 - destroy GENEVE" +- echo 2 > $NSIM_DEV_DFS/ports/$port/udp_ports_inject_error ++ echo 2 > $NSIM_DEV_DFS/ports/$port/udp_ports/inject_error + exp1=( `mke 20000 2` 0 0 0 ) + del_dev gnv0 + +@@ -763,7 +763,7 @@ for port in 0 1; do + msg="create VxLANs v4" + new_vxlan vxlan0 10000 $NSIM_NETDEV + +- echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports_reset ++ echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset + check_tables + + msg="NIC device goes down" +@@ -774,7 +774,7 @@ for port in 0 1; do + fi + check_tables + +- echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports_reset ++ echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset + check_tables + + msg="NIC device goes up again" +@@ -788,7 +788,7 @@ for port in 0 1; do + del_dev vxlan0 + check_tables + +- echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports_reset ++ echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset + check_tables + + msg="destroy NIC" +@@ -895,7 +895,7 @@ msg="vacate VxLAN in overflow table" + exp0=( `mke 10000 1` `mke 10004 1` 0 `mke 10003 1` ) + del_dev vxlan2 + +-echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports_reset ++echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset + check_tables + + msg="tunnels destroyed 2" +diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h +index a6ea2bd63a8316..af65a83d1422a8 100644 +--- a/tools/testing/selftests/kselftest_harness.h ++++ b/tools/testing/selftests/kselftest_harness.h +@@ -701,33 +701,33 @@ + /* Report with actual signedness to avoid weird output. */ \ + switch (is_signed_type(__exp) * 2 + is_signed_type(__seen)) { \ + case 0: { \ +- unsigned long long __exp_print = (uintptr_t)__exp; \ +- unsigned long long __seen_print = (uintptr_t)__seen; \ +- __TH_LOG("Expected %s (%llu) %s %s (%llu)", \ ++ uintmax_t __exp_print = (uintmax_t)__exp; \ ++ uintmax_t __seen_print = (uintmax_t)__seen; \ ++ __TH_LOG("Expected %s (%ju) %s %s (%ju)", \ + _expected_str, __exp_print, #_t, \ + _seen_str, __seen_print); \ + break; \ + } \ + case 1: { \ +- unsigned long long __exp_print = (uintptr_t)__exp; \ +- long long __seen_print = (intptr_t)__seen; \ +- __TH_LOG("Expected %s (%llu) %s %s (%lld)", \ ++ uintmax_t __exp_print = (uintmax_t)__exp; \ ++ intmax_t __seen_print = (intmax_t)__seen; \ ++ __TH_LOG("Expected %s (%ju) %s %s (%jd)", \ + _expected_str, __exp_print, #_t, \ + _seen_str, __seen_print); \ + break; \ + } \ + case 2: { \ +- long long __exp_print = (intptr_t)__exp; \ +- unsigned long long __seen_print = (uintptr_t)__seen; \ +- __TH_LOG("Expected %s (%lld) %s %s (%llu)", \ ++ intmax_t __exp_print = (intmax_t)__exp; \ ++ uintmax_t __seen_print = (uintmax_t)__seen; \ ++ __TH_LOG("Expected %s (%jd) %s %s (%ju)", \ + _expected_str, __exp_print, #_t, \ + _seen_str, __seen_print); \ + break; \ + } \ + case 3: { \ +- long long __exp_print = (intptr_t)__exp; \ +- long long __seen_print = (intptr_t)__seen; \ +- __TH_LOG("Expected %s (%lld) %s %s (%lld)", \ ++ intmax_t __exp_print = (intmax_t)__exp; \ ++ intmax_t __seen_print = (intmax_t)__seen; \ ++ __TH_LOG("Expected %s (%jd) %s %s (%jd)", \ + _expected_str, __exp_print, #_t, \ + _seen_str, __seen_print); \ + break; \ +diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c +index ea988b3d6b2edc..47fc4392f412ec 100644 +--- a/tools/testing/selftests/landlock/fs_test.c ++++ b/tools/testing/selftests/landlock/fs_test.c +@@ -1767,8 +1767,7 @@ static void test_execute(struct __test_metadata *const _metadata, const int err, + ASSERT_EQ(1, WIFEXITED(status)); + ASSERT_EQ(err ? 2 : 0, WEXITSTATUS(status)) + { +- TH_LOG("Unexpected return code for \"%s\": %s", path, +- strerror(errno)); ++ TH_LOG("Unexpected return code for \"%s\"", path); + }; + } + +diff --git a/tools/testing/selftests/net/ipsec.c b/tools/testing/selftests/net/ipsec.c +index c5be3f390849b0..ae3da27b00973a 100644 +--- a/tools/testing/selftests/net/ipsec.c ++++ b/tools/testing/selftests/net/ipsec.c +@@ -189,7 +189,8 @@ static int rtattr_pack(struct nlmsghdr *nh, size_t req_sz, + + attr->rta_len = RTA_LENGTH(size); + attr->rta_type = rta_type; +- memcpy(RTA_DATA(attr), payload, size); ++ if (payload) ++ memcpy(RTA_DATA(attr), payload, size); + + return 0; + } +diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh +index 84c05e533056de..33f4fb34ac9b24 100755 +--- a/tools/testing/selftests/net/pmtu.sh ++++ b/tools/testing/selftests/net/pmtu.sh +@@ -26,6 +26,15 @@ + # - pmtu_ipv6 + # Same as pmtu_ipv4, except for locked PMTU tests, using IPv6 + # ++# - pmtu_ipv4_dscp_icmp_exception ++# Set up the same network topology as pmtu_ipv4, but use non-default ++# routing table in A. A fib-rule is used to jump to this routing table ++# based on DSCP. Send ICMPv4 packets with the expected DSCP value and ++# verify that ECN doesn't interfere with the creation of PMTU exceptions. ++# ++# - pmtu_ipv4_dscp_udp_exception ++# Same as pmtu_ipv4_dscp_icmp_exception, but use UDP instead of ICMP. ++# + # - pmtu_ipv4_vxlan4_exception + # Set up the same network topology as pmtu_ipv4, create a VXLAN tunnel + # over IPv4 between A and B, routed via R1. On the link between R1 and B, +@@ -188,6 +197,12 @@ + # + # - pmtu_ipv6_route_change + # Same as above but with IPv6 ++# ++# - pmtu_ipv4_mp_exceptions ++# Use the same topology as in pmtu_ipv4, but add routeable addresses ++# on host A and B on lo reachable via both routers. Host A and B ++# addresses have multipath routes to each other, b_r1 mtu = 1500. ++# Check that PMTU exceptions are created for both paths. + + # Kselftest framework requirement - SKIP code is 4. + ksft_skip=4 +@@ -203,6 +218,8 @@ which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping) + tests=" + pmtu_ipv4_exception ipv4: PMTU exceptions 1 + pmtu_ipv6_exception ipv6: PMTU exceptions 1 ++ pmtu_ipv4_dscp_icmp_exception ICMPv4 with DSCP and ECN: PMTU exceptions 1 ++ pmtu_ipv4_dscp_udp_exception UDPv4 with DSCP and ECN: PMTU exceptions 1 + pmtu_ipv4_vxlan4_exception IPv4 over vxlan4: PMTU exceptions 1 + pmtu_ipv6_vxlan4_exception IPv6 over vxlan4: PMTU exceptions 1 + pmtu_ipv4_vxlan6_exception IPv4 over vxlan6: PMTU exceptions 1 +@@ -255,7 +272,8 @@ tests=" + list_flush_ipv4_exception ipv4: list and flush cached exceptions 1 + list_flush_ipv6_exception ipv6: list and flush cached exceptions 1 + pmtu_ipv4_route_change ipv4: PMTU exception w/route replace 1 +- pmtu_ipv6_route_change ipv6: PMTU exception w/route replace 1" ++ pmtu_ipv6_route_change ipv6: PMTU exception w/route replace 1 ++ pmtu_ipv4_mp_exceptions ipv4: PMTU multipath nh exceptions 1" + + NS_A="ns-A" + NS_B="ns-B" +@@ -323,6 +341,9 @@ routes_nh=" + B 6 default 61 + " + ++policy_mark=0x04 ++rt_table=main ++ + veth4_a_addr="192.168.1.1" + veth4_b_addr="192.168.1.2" + veth4_c_addr="192.168.2.10" +@@ -339,6 +360,9 @@ tunnel6_a_addr="fd00:2::a" + tunnel6_b_addr="fd00:2::b" + tunnel6_mask="64" + ++host4_a_addr="192.168.99.99" ++host4_b_addr="192.168.88.88" ++ + dummy6_0_prefix="fc00:1000::" + dummy6_1_prefix="fc00:1001::" + dummy6_mask="64" +@@ -346,6 +370,7 @@ dummy6_mask="64" + err_buf= + tcpdump_pids= + nettest_pids= ++socat_pids= + + err() { + err_buf="${err_buf}${1} +@@ -725,7 +750,7 @@ setup_routing_old() { + + ns_name="$(nsname ${ns})" + +- ip -n ${ns_name} route add ${addr} via ${gw} ++ ip -n "${ns_name}" route add "${addr}" table "${rt_table}" via "${gw}" + + ns=""; addr=""; gw="" + done +@@ -755,7 +780,7 @@ setup_routing_new() { + + ns_name="$(nsname ${ns})" + +- ip -n ${ns_name} -${fam} route add ${addr} nhid ${nhid} ++ ip -n "${ns_name}" -"${fam}" route add "${addr}" table "${rt_table}" nhid "${nhid}" + + ns=""; fam=""; addr=""; nhid="" + done +@@ -800,6 +825,24 @@ setup_routing() { + return 0 + } + ++setup_policy_routing() { ++ setup_routing ++ ++ ip -netns "${NS_A}" -4 rule add dsfield "${policy_mark}" \ ++ table "${rt_table}" ++ ++ # Set the IPv4 Don't Fragment bit with tc, since socat doesn't seem to ++ # have an option do to it. ++ tc -netns "${NS_A}" qdisc replace dev veth_A-R1 root prio ++ tc -netns "${NS_A}" qdisc replace dev veth_A-R2 root prio ++ tc -netns "${NS_A}" filter add dev veth_A-R1 \ ++ protocol ipv4 flower ip_proto udp \ ++ action pedit ex munge ip df set 0x40 pipe csum ip and udp ++ tc -netns "${NS_A}" filter add dev veth_A-R2 \ ++ protocol ipv4 flower ip_proto udp \ ++ action pedit ex munge ip df set 0x40 pipe csum ip and udp ++} ++ + setup_bridge() { + run_cmd ${ns_a} ip link add br0 type bridge || return $ksft_skip + run_cmd ${ns_a} ip link set br0 up +@@ -874,6 +917,52 @@ setup_ovs_bridge() { + run_cmd ip route add ${prefix6}:${b_r1}::1 via ${prefix6}:${a_r1}::2 + } + ++setup_multipath_new() { ++ # Set up host A with multipath routes to host B host4_b_addr ++ run_cmd ${ns_a} ip addr add ${host4_a_addr} dev lo ++ run_cmd ${ns_a} ip nexthop add id 401 via ${prefix4}.${a_r1}.2 dev veth_A-R1 ++ run_cmd ${ns_a} ip nexthop add id 402 via ${prefix4}.${a_r2}.2 dev veth_A-R2 ++ run_cmd ${ns_a} ip nexthop add id 403 group 401/402 ++ run_cmd ${ns_a} ip route add ${host4_b_addr} src ${host4_a_addr} nhid 403 ++ ++ # Set up host B with multipath routes to host A host4_a_addr ++ run_cmd ${ns_b} ip addr add ${host4_b_addr} dev lo ++ run_cmd ${ns_b} ip nexthop add id 401 via ${prefix4}.${b_r1}.2 dev veth_B-R1 ++ run_cmd ${ns_b} ip nexthop add id 402 via ${prefix4}.${b_r2}.2 dev veth_B-R2 ++ run_cmd ${ns_b} ip nexthop add id 403 group 401/402 ++ run_cmd ${ns_b} ip route add ${host4_a_addr} src ${host4_b_addr} nhid 403 ++} ++ ++setup_multipath_old() { ++ # Set up host A with multipath routes to host B host4_b_addr ++ run_cmd ${ns_a} ip addr add ${host4_a_addr} dev lo ++ run_cmd ${ns_a} ip route add ${host4_b_addr} \ ++ src ${host4_a_addr} \ ++ nexthop via ${prefix4}.${a_r1}.2 weight 1 \ ++ nexthop via ${prefix4}.${a_r2}.2 weight 1 ++ ++ # Set up host B with multipath routes to host A host4_a_addr ++ run_cmd ${ns_b} ip addr add ${host4_b_addr} dev lo ++ run_cmd ${ns_b} ip route add ${host4_a_addr} \ ++ src ${host4_b_addr} \ ++ nexthop via ${prefix4}.${b_r1}.2 weight 1 \ ++ nexthop via ${prefix4}.${b_r2}.2 weight 1 ++} ++ ++setup_multipath() { ++ if [ "$USE_NH" = "yes" ]; then ++ setup_multipath_new ++ else ++ setup_multipath_old ++ fi ++ ++ # Set up routers with routes to dummies ++ run_cmd ${ns_r1} ip route add ${host4_a_addr} via ${prefix4}.${a_r1}.1 ++ run_cmd ${ns_r2} ip route add ${host4_a_addr} via ${prefix4}.${a_r2}.1 ++ run_cmd ${ns_r1} ip route add ${host4_b_addr} via ${prefix4}.${b_r1}.1 ++ run_cmd ${ns_r2} ip route add ${host4_b_addr} via ${prefix4}.${b_r2}.1 ++} ++ + setup() { + [ "$(id -u)" -ne 0 ] && echo " need to run as root" && return $ksft_skip + +@@ -905,6 +994,11 @@ cleanup() { + done + nettest_pids= + ++ for pid in ${socat_pids}; do ++ kill "${pid}" ++ done ++ socat_pids= ++ + for n in ${NS_A} ${NS_B} ${NS_C} ${NS_R1} ${NS_R2}; do + ip netns del ${n} 2> /dev/null + done +@@ -950,17 +1044,15 @@ link_get_mtu() { + } + + route_get_dst_exception() { +- ns_cmd="${1}" +- dst="${2}" ++ ns_cmd="${1}"; shift + +- ${ns_cmd} ip route get "${dst}" ++ ${ns_cmd} ip route get "$@" + } + + route_get_dst_pmtu_from_exception() { +- ns_cmd="${1}" +- dst="${2}" ++ ns_cmd="${1}"; shift + +- mtu_parse "$(route_get_dst_exception "${ns_cmd}" ${dst})" ++ mtu_parse "$(route_get_dst_exception "${ns_cmd}" "$@")" + } + + check_pmtu_value() { +@@ -1070,6 +1162,95 @@ test_pmtu_ipv6_exception() { + test_pmtu_ipvX 6 + } + ++test_pmtu_ipv4_dscp_icmp_exception() { ++ rt_table=100 ++ ++ setup namespaces policy_routing || return $ksft_skip ++ trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ ++ "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \ ++ "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \ ++ "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2 ++ ++ # Set up initial MTU values ++ mtu "${ns_a}" veth_A-R1 2000 ++ mtu "${ns_r1}" veth_R1-A 2000 ++ mtu "${ns_r1}" veth_R1-B 1400 ++ mtu "${ns_b}" veth_B-R1 1400 ++ ++ mtu "${ns_a}" veth_A-R2 2000 ++ mtu "${ns_r2}" veth_R2-A 2000 ++ mtu "${ns_r2}" veth_R2-B 1500 ++ mtu "${ns_b}" veth_B-R2 1500 ++ ++ len=$((2000 - 20 - 8)) # Fills MTU of veth_A-R1 ++ ++ dst1="${prefix4}.${b_r1}.1" ++ dst2="${prefix4}.${b_r2}.1" ++ ++ # Create route exceptions ++ dsfield=${policy_mark} # No ECN bit set (Not-ECT) ++ run_cmd "${ns_a}" ping -q -M want -Q "${dsfield}" -c 1 -w 1 -s "${len}" "${dst1}" ++ ++ dsfield=$(printf "%#x" $((policy_mark + 0x02))) # ECN=2 (ECT(0)) ++ run_cmd "${ns_a}" ping -q -M want -Q "${dsfield}" -c 1 -w 1 -s "${len}" "${dst2}" ++ ++ # Check that exceptions have been created with the correct PMTU ++ pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" dsfield "${policy_mark}")" ++ check_pmtu_value "1400" "${pmtu_1}" "exceeding MTU" || return 1 ++ ++ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" dsfield "${policy_mark}")" ++ check_pmtu_value "1500" "${pmtu_2}" "exceeding MTU" || return 1 ++} ++ ++test_pmtu_ipv4_dscp_udp_exception() { ++ rt_table=100 ++ ++ if ! which socat > /dev/null 2>&1; then ++ echo "'socat' command not found; skipping tests" ++ return $ksft_skip ++ fi ++ ++ setup namespaces policy_routing || return $ksft_skip ++ trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ ++ "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \ ++ "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \ ++ "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2 ++ ++ # Set up initial MTU values ++ mtu "${ns_a}" veth_A-R1 2000 ++ mtu "${ns_r1}" veth_R1-A 2000 ++ mtu "${ns_r1}" veth_R1-B 1400 ++ mtu "${ns_b}" veth_B-R1 1400 ++ ++ mtu "${ns_a}" veth_A-R2 2000 ++ mtu "${ns_r2}" veth_R2-A 2000 ++ mtu "${ns_r2}" veth_R2-B 1500 ++ mtu "${ns_b}" veth_B-R2 1500 ++ ++ len=$((2000 - 20 - 8)) # Fills MTU of veth_A-R1 ++ ++ dst1="${prefix4}.${b_r1}.1" ++ dst2="${prefix4}.${b_r2}.1" ++ ++ # Create route exceptions ++ run_cmd_bg "${ns_b}" socat UDP-LISTEN:50000 OPEN:/dev/null,wronly=1 ++ socat_pids="${socat_pids} $!" ++ ++ dsfield=${policy_mark} # No ECN bit set (Not-ECT) ++ run_cmd "${ns_a}" socat OPEN:/dev/zero,rdonly=1,readbytes="${len}" \ ++ UDP:"${dst1}":50000,tos="${dsfield}" ++ ++ dsfield=$(printf "%#x" $((policy_mark + 0x02))) # ECN=2 (ECT(0)) ++ run_cmd "${ns_a}" socat OPEN:/dev/zero,rdonly=1,readbytes="${len}" \ ++ UDP:"${dst2}":50000,tos="${dsfield}" ++ ++ # Check that exceptions have been created with the correct PMTU ++ pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" dsfield "${policy_mark}")" ++ check_pmtu_value "1400" "${pmtu_1}" "exceeding MTU" || return 1 ++ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" dsfield "${policy_mark}")" ++ check_pmtu_value "1500" "${pmtu_2}" "exceeding MTU" || return 1 ++} ++ + test_pmtu_ipvX_over_vxlanY_or_geneveY_exception() { + type=${1} + family=${2} +@@ -2072,6 +2253,36 @@ test_pmtu_ipv6_route_change() { + test_pmtu_ipvX_route_change 6 + } + ++test_pmtu_ipv4_mp_exceptions() { ++ setup namespaces routing multipath || return $ksft_skip ++ ++ trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ ++ "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \ ++ "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \ ++ "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2 ++ ++ # Set up initial MTU values ++ mtu "${ns_a}" veth_A-R1 2000 ++ mtu "${ns_r1}" veth_R1-A 2000 ++ mtu "${ns_r1}" veth_R1-B 1500 ++ mtu "${ns_b}" veth_B-R1 1500 ++ ++ mtu "${ns_a}" veth_A-R2 2000 ++ mtu "${ns_r2}" veth_R2-A 2000 ++ mtu "${ns_r2}" veth_R2-B 1500 ++ mtu "${ns_b}" veth_B-R2 1500 ++ ++ # Ping and expect two nexthop exceptions for two routes ++ run_cmd ${ns_a} ping -q -M want -i 0.1 -c 1 -s 1800 "${host4_b_addr}" ++ ++ # Check that exceptions have been created with the correct PMTU ++ pmtu_a_R1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${host4_b_addr}" oif veth_A-R1)" ++ pmtu_a_R2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${host4_b_addr}" oif veth_A-R2)" ++ ++ check_pmtu_value "1500" "${pmtu_a_R1}" "exceeding MTU (veth_A-R1)" || return 1 ++ check_pmtu_value "1500" "${pmtu_a_R2}" "exceeding MTU (veth_A-R2)" || return 1 ++} ++ + usage() { + echo + echo "$0 [OPTIONS] [TEST]..." +diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh +index cbf166df57da7e..a3597b3e579fed 100755 +--- a/tools/testing/selftests/net/rtnetlink.sh ++++ b/tools/testing/selftests/net/rtnetlink.sh +@@ -813,10 +813,10 @@ kci_test_ipsec_offload() + # does driver have correct offload info + diff $sysfsf - << EOF + SA count=2 tx=3 +-sa[0] tx ipaddr=0x00000000 00000000 00000000 00000000 ++sa[0] tx ipaddr=$dstip + sa[0] spi=0x00000009 proto=0x32 salt=0x61626364 crypt=1 + sa[0] key=0x34333231 38373635 32313039 36353433 +-sa[1] rx ipaddr=0x00000000 00000000 00000000 037ba8c0 ++sa[1] rx ipaddr=$srcip + sa[1] spi=0x00000009 proto=0x32 salt=0x61626364 crypt=1 + sa[1] key=0x34333231 38373635 32313039 36353433 + EOF +diff --git a/tools/testing/selftests/net/udpgso.c b/tools/testing/selftests/net/udpgso.c +index b02080d09fbc05..d0fba50bd6ef08 100644 +--- a/tools/testing/selftests/net/udpgso.c ++++ b/tools/testing/selftests/net/udpgso.c +@@ -94,6 +94,19 @@ struct testcase testcases_v4[] = { + .gso_len = CONST_MSS_V4, + .r_num_mss = 1, + }, ++ { ++ /* datalen <= MSS < gso_len: will fall back to no GSO */ ++ .tlen = CONST_MSS_V4, ++ .gso_len = CONST_MSS_V4 + 1, ++ .r_num_mss = 0, ++ .r_len_last = CONST_MSS_V4, ++ }, ++ { ++ /* MSS < datalen < gso_len: fail */ ++ .tlen = CONST_MSS_V4 + 1, ++ .gso_len = CONST_MSS_V4 + 2, ++ .tfail = true, ++ }, + { + /* send a single MSS + 1B */ + .tlen = CONST_MSS_V4 + 1, +@@ -197,6 +210,19 @@ struct testcase testcases_v6[] = { + .gso_len = CONST_MSS_V6, + .r_num_mss = 1, + }, ++ { ++ /* datalen <= MSS < gso_len: will fall back to no GSO */ ++ .tlen = CONST_MSS_V6, ++ .gso_len = CONST_MSS_V6 + 1, ++ .r_num_mss = 0, ++ .r_len_last = CONST_MSS_V6, ++ }, ++ { ++ /* MSS < datalen < gso_len: fail */ ++ .tlen = CONST_MSS_V6 + 1, ++ .gso_len = CONST_MSS_V6 + 2, ++ .tfail = true ++ }, + { + /* send a single MSS + 1B */ + .tlen = CONST_MSS_V6 + 1,