mirror of
https://github.com/armbian/build.git
synced 2025-08-15 15:46:58 +02:00
12511 lines
420 KiB
Diff
12511 lines
420 KiB
Diff
diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
|
|
index dc3a3f709feaa6..bac4d0b51d8a1b 100644
|
|
--- a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
|
|
+++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
|
|
@@ -58,8 +58,7 @@ properties:
|
|
fsl,phy-tx-vboost-level-microvolt:
|
|
description:
|
|
Adjust the boosted transmit launch pk-pk differential amplitude
|
|
- minimum: 880
|
|
- maximum: 1120
|
|
+ enum: [844, 1008, 1156]
|
|
|
|
fsl,phy-comp-dis-tune-percent:
|
|
description:
|
|
diff --git a/Documentation/devicetree/bindings/regulator/mediatek,mt6357-regulator.yaml b/Documentation/devicetree/bindings/regulator/mediatek,mt6357-regulator.yaml
|
|
index 6327bb2f6ee080..698266c09e2535 100644
|
|
--- a/Documentation/devicetree/bindings/regulator/mediatek,mt6357-regulator.yaml
|
|
+++ b/Documentation/devicetree/bindings/regulator/mediatek,mt6357-regulator.yaml
|
|
@@ -33,7 +33,7 @@ patternProperties:
|
|
|
|
"^ldo-v(camio18|aud28|aux18|io18|io28|rf12|rf18|cn18|cn28|fe28)$":
|
|
type: object
|
|
- $ref: fixed-regulator.yaml#
|
|
+ $ref: regulator.yaml#
|
|
unevaluatedProperties: false
|
|
description:
|
|
Properties for single fixed LDO regulator.
|
|
@@ -112,7 +112,6 @@ examples:
|
|
regulator-enable-ramp-delay = <220>;
|
|
};
|
|
mt6357_vfe28_reg: ldo-vfe28 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vfe28";
|
|
regulator-min-microvolt = <2800000>;
|
|
regulator-max-microvolt = <2800000>;
|
|
@@ -125,14 +124,12 @@ examples:
|
|
regulator-enable-ramp-delay = <110>;
|
|
};
|
|
mt6357_vrf18_reg: ldo-vrf18 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vrf18";
|
|
regulator-min-microvolt = <1800000>;
|
|
regulator-max-microvolt = <1800000>;
|
|
regulator-enable-ramp-delay = <110>;
|
|
};
|
|
mt6357_vrf12_reg: ldo-vrf12 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vrf12";
|
|
regulator-min-microvolt = <1200000>;
|
|
regulator-max-microvolt = <1200000>;
|
|
@@ -157,14 +154,12 @@ examples:
|
|
regulator-enable-ramp-delay = <264>;
|
|
};
|
|
mt6357_vcn28_reg: ldo-vcn28 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vcn28";
|
|
regulator-min-microvolt = <2800000>;
|
|
regulator-max-microvolt = <2800000>;
|
|
regulator-enable-ramp-delay = <264>;
|
|
};
|
|
mt6357_vcn18_reg: ldo-vcn18 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vcn18";
|
|
regulator-min-microvolt = <1800000>;
|
|
regulator-max-microvolt = <1800000>;
|
|
@@ -183,7 +178,6 @@ examples:
|
|
regulator-enable-ramp-delay = <264>;
|
|
};
|
|
mt6357_vcamio_reg: ldo-vcamio18 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vcamio";
|
|
regulator-min-microvolt = <1800000>;
|
|
regulator-max-microvolt = <1800000>;
|
|
@@ -212,28 +206,24 @@ examples:
|
|
regulator-always-on;
|
|
};
|
|
mt6357_vaux18_reg: ldo-vaux18 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vaux18";
|
|
regulator-min-microvolt = <1800000>;
|
|
regulator-max-microvolt = <1800000>;
|
|
regulator-enable-ramp-delay = <264>;
|
|
};
|
|
mt6357_vaud28_reg: ldo-vaud28 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vaud28";
|
|
regulator-min-microvolt = <2800000>;
|
|
regulator-max-microvolt = <2800000>;
|
|
regulator-enable-ramp-delay = <264>;
|
|
};
|
|
mt6357_vio28_reg: ldo-vio28 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vio28";
|
|
regulator-min-microvolt = <2800000>;
|
|
regulator-max-microvolt = <2800000>;
|
|
regulator-enable-ramp-delay = <264>;
|
|
};
|
|
mt6357_vio18_reg: ldo-vio18 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vio18";
|
|
regulator-min-microvolt = <1800000>;
|
|
regulator-max-microvolt = <1800000>;
|
|
diff --git a/Documentation/devicetree/bindings/usb/cypress,hx3.yaml b/Documentation/devicetree/bindings/usb/cypress,hx3.yaml
|
|
index 47add0d85fb891..02349bbb0d46ff 100644
|
|
--- a/Documentation/devicetree/bindings/usb/cypress,hx3.yaml
|
|
+++ b/Documentation/devicetree/bindings/usb/cypress,hx3.yaml
|
|
@@ -14,9 +14,22 @@ allOf:
|
|
|
|
properties:
|
|
compatible:
|
|
- enum:
|
|
- - usb4b4,6504
|
|
- - usb4b4,6506
|
|
+ oneOf:
|
|
+ - enum:
|
|
+ - usb4b4,6504
|
|
+ - usb4b4,6506
|
|
+ - items:
|
|
+ - enum:
|
|
+ - usb4b4,6500
|
|
+ - usb4b4,6508
|
|
+ - const: usb4b4,6504
|
|
+ - items:
|
|
+ - enum:
|
|
+ - usb4b4,6502
|
|
+ - usb4b4,6503
|
|
+ - usb4b4,6507
|
|
+ - usb4b4,650a
|
|
+ - const: usb4b4,6506
|
|
|
|
reg: true
|
|
|
|
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
|
index dc275ab60e5344..7376a924e9aca1 100644
|
|
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
|
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
|
@@ -773,6 +773,8 @@ patternProperties:
|
|
description: Linux-specific binding
|
|
"^linx,.*":
|
|
description: Linx Technologies
|
|
+ "^liontron,.*":
|
|
+ description: Shenzhen Liontron Technology Co., Ltd
|
|
"^liteon,.*":
|
|
description: LITE-ON Technology Corp.
|
|
"^litex,.*":
|
|
diff --git a/Makefile b/Makefile
|
|
index c9a1e2286b3a79..9625d9072c7781 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,7 +1,7 @@
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
VERSION = 6
|
|
PATCHLEVEL = 6
|
|
-SUBLEVEL = 93
|
|
+SUBLEVEL = 94
|
|
EXTRAVERSION =
|
|
NAME = Pinguïn Aangedreven
|
|
|
|
diff --git a/arch/arm/boot/dts/microchip/at91sam9263ek.dts b/arch/arm/boot/dts/microchip/at91sam9263ek.dts
|
|
index ce8baff6a9f4e0..e42e1a75a715db 100644
|
|
--- a/arch/arm/boot/dts/microchip/at91sam9263ek.dts
|
|
+++ b/arch/arm/boot/dts/microchip/at91sam9263ek.dts
|
|
@@ -152,7 +152,7 @@ nand_controller: nand-controller {
|
|
nand@3 {
|
|
reg = <0x3 0x0 0x800000>;
|
|
rb-gpios = <&pioA 22 GPIO_ACTIVE_HIGH>;
|
|
- cs-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>;
|
|
+ cs-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
|
|
nand-bus-width = <8>;
|
|
nand-ecc-mode = "soft";
|
|
nand-on-flash-bbt;
|
|
diff --git a/arch/arm/boot/dts/microchip/tny_a9263.dts b/arch/arm/boot/dts/microchip/tny_a9263.dts
|
|
index 62b7d9f9a926c5..c8b6318aaa838c 100644
|
|
--- a/arch/arm/boot/dts/microchip/tny_a9263.dts
|
|
+++ b/arch/arm/boot/dts/microchip/tny_a9263.dts
|
|
@@ -64,7 +64,7 @@ nand_controller: nand-controller {
|
|
nand@3 {
|
|
reg = <0x3 0x0 0x800000>;
|
|
rb-gpios = <&pioA 22 GPIO_ACTIVE_HIGH>;
|
|
- cs-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>;
|
|
+ cs-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
|
|
nand-bus-width = <8>;
|
|
nand-ecc-mode = "soft";
|
|
nand-on-flash-bbt;
|
|
diff --git a/arch/arm/boot/dts/microchip/usb_a9263.dts b/arch/arm/boot/dts/microchip/usb_a9263.dts
|
|
index 45745915b2e160..454176ce6d3fff 100644
|
|
--- a/arch/arm/boot/dts/microchip/usb_a9263.dts
|
|
+++ b/arch/arm/boot/dts/microchip/usb_a9263.dts
|
|
@@ -58,7 +58,7 @@ usb1: gadget@fff78000 {
|
|
};
|
|
|
|
spi0: spi@fffa4000 {
|
|
- cs-gpios = <&pioB 15 GPIO_ACTIVE_HIGH>;
|
|
+ cs-gpios = <&pioA 5 GPIO_ACTIVE_LOW>;
|
|
status = "okay";
|
|
flash@0 {
|
|
compatible = "atmel,at45", "atmel,dataflash";
|
|
@@ -84,7 +84,7 @@ nand_controller: nand-controller {
|
|
nand@3 {
|
|
reg = <0x3 0x0 0x800000>;
|
|
rb-gpios = <&pioA 22 GPIO_ACTIVE_HIGH>;
|
|
- cs-gpios = <&pioA 15 GPIO_ACTIVE_HIGH>;
|
|
+ cs-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
|
|
nand-bus-width = <8>;
|
|
nand-ecc-mode = "soft";
|
|
nand-on-flash-bbt;
|
|
diff --git a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
|
|
index 950adb63af7016..b8f160cfe8e156 100644
|
|
--- a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
|
|
+++ b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
|
|
@@ -213,12 +213,6 @@ sleep_clk: sleep_clk {
|
|
};
|
|
};
|
|
|
|
- sfpb_mutex: hwmutex {
|
|
- compatible = "qcom,sfpb-mutex";
|
|
- syscon = <&sfpb_wrapper_mutex 0x604 0x4>;
|
|
- #hwlock-cells = <1>;
|
|
- };
|
|
-
|
|
smem {
|
|
compatible = "qcom,smem";
|
|
memory-region = <&smem_region>;
|
|
@@ -322,9 +316,10 @@ tlmm_pinmux: pinctrl@800000 {
|
|
pinctrl-0 = <&ps_hold>;
|
|
};
|
|
|
|
- sfpb_wrapper_mutex: syscon@1200000 {
|
|
- compatible = "syscon";
|
|
- reg = <0x01200000 0x8000>;
|
|
+ sfpb_mutex: hwmutex@1200600 {
|
|
+ compatible = "qcom,sfpb-mutex";
|
|
+ reg = <0x01200600 0x100>;
|
|
+ #hwlock-cells = <1>;
|
|
};
|
|
|
|
intc: interrupt-controller@2000000 {
|
|
@@ -343,6 +338,8 @@ timer@200a000 {
|
|
<1 3 0x301>;
|
|
reg = <0x0200a000 0x100>;
|
|
clock-frequency = <27000000>;
|
|
+ clocks = <&sleep_clk>;
|
|
+ clock-names = "sleep";
|
|
cpu-offset = <0x80000>;
|
|
};
|
|
|
|
diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
|
|
index 080019aa6fcd89..fcf287edd0e5e6 100644
|
|
--- a/arch/arm/mach-aspeed/Kconfig
|
|
+++ b/arch/arm/mach-aspeed/Kconfig
|
|
@@ -2,7 +2,6 @@
|
|
menuconfig ARCH_ASPEED
|
|
bool "Aspeed BMC architectures"
|
|
depends on (CPU_LITTLE_ENDIAN && ARCH_MULTI_V5) || ARCH_MULTI_V6 || ARCH_MULTI_V7
|
|
- select SRAM
|
|
select WATCHDOG
|
|
select ASPEED_WATCHDOG
|
|
select MFD_SYSCON
|
|
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
|
|
index 658c6a61ab6fb8..4ecba0690938c3 100644
|
|
--- a/arch/arm64/Kconfig
|
|
+++ b/arch/arm64/Kconfig
|
|
@@ -304,9 +304,9 @@ config ARCH_MMAP_RND_BITS_MAX
|
|
default 24 if ARM64_VA_BITS=39
|
|
default 27 if ARM64_VA_BITS=42
|
|
default 30 if ARM64_VA_BITS=47
|
|
- default 29 if ARM64_VA_BITS=48 && ARM64_64K_PAGES
|
|
- default 31 if ARM64_VA_BITS=48 && ARM64_16K_PAGES
|
|
- default 33 if ARM64_VA_BITS=48
|
|
+ default 29 if (ARM64_VA_BITS=48 || ARM64_VA_BITS=52) && ARM64_64K_PAGES
|
|
+ default 31 if (ARM64_VA_BITS=48 || ARM64_VA_BITS=52) && ARM64_16K_PAGES
|
|
+ default 33 if (ARM64_VA_BITS=48 || ARM64_VA_BITS=52)
|
|
default 14 if ARM64_64K_PAGES
|
|
default 16 if ARM64_16K_PAGES
|
|
default 18
|
|
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts b/arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts
|
|
index 905c98cb080d2f..a6e6860bf01843 100644
|
|
--- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts
|
|
+++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-kit.dts
|
|
@@ -124,6 +124,7 @@ &sai5 {
|
|
assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
|
|
assigned-clock-rates = <24576000>;
|
|
#sound-dai-cells = <0>;
|
|
+ fsl,sai-mclk-direction-output;
|
|
status = "okay";
|
|
};
|
|
|
|
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi
|
|
index f264102bdb2748..8ab0e45f2ad31c 100644
|
|
--- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi
|
|
+++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi
|
|
@@ -231,6 +231,7 @@ eeprom@50 {
|
|
rtc: rtc@51 {
|
|
compatible = "nxp,pcf85263";
|
|
reg = <0x51>;
|
|
+ quartz-load-femtofarads = <12500>;
|
|
};
|
|
};
|
|
|
|
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts b/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts
|
|
index 35b8d2060cd99a..dfa08be33a4f20 100644
|
|
--- a/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts
|
|
+++ b/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts
|
|
@@ -126,6 +126,7 @@ &sai5 {
|
|
assigned-clock-parents = <&clk IMX8MN_AUDIO_PLL1_OUT>;
|
|
assigned-clock-rates = <24576000>;
|
|
#sound-dai-cells = <0>;
|
|
+ fsl,sai-mclk-direction-output;
|
|
status = "okay";
|
|
};
|
|
|
|
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi
|
|
index 90073b16536f40..1760062e6ffcfd 100644
|
|
--- a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi
|
|
+++ b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi
|
|
@@ -240,6 +240,7 @@ eeprom@50 {
|
|
rtc: rtc@51 {
|
|
compatible = "nxp,pcf85263";
|
|
reg = <0x51>;
|
|
+ quartz-load-femtofarads = <12500>;
|
|
};
|
|
};
|
|
|
|
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
|
|
index e5da9080478084..24380f8a008501 100644
|
|
--- a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
|
|
+++ b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
|
|
@@ -192,6 +192,7 @@ eeprom@50 {
|
|
rtc: rtc@51 {
|
|
compatible = "nxp,pcf85263";
|
|
reg = <0x51>;
|
|
+ quartz-load-femtofarads = <12500>;
|
|
};
|
|
};
|
|
|
|
diff --git a/arch/arm64/boot/dts/mediatek/mt6357.dtsi b/arch/arm64/boot/dts/mediatek/mt6357.dtsi
|
|
index 5fafa842d312f3..dca4e5c3d8e210 100644
|
|
--- a/arch/arm64/boot/dts/mediatek/mt6357.dtsi
|
|
+++ b/arch/arm64/boot/dts/mediatek/mt6357.dtsi
|
|
@@ -60,7 +60,6 @@ mt6357_vpa_reg: buck-vpa {
|
|
};
|
|
|
|
mt6357_vfe28_reg: ldo-vfe28 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vfe28";
|
|
regulator-min-microvolt = <2800000>;
|
|
regulator-max-microvolt = <2800000>;
|
|
@@ -75,7 +74,6 @@ mt6357_vxo22_reg: ldo-vxo22 {
|
|
};
|
|
|
|
mt6357_vrf18_reg: ldo-vrf18 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vrf18";
|
|
regulator-min-microvolt = <1800000>;
|
|
regulator-max-microvolt = <1800000>;
|
|
@@ -83,7 +81,6 @@ mt6357_vrf18_reg: ldo-vrf18 {
|
|
};
|
|
|
|
mt6357_vrf12_reg: ldo-vrf12 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vrf12";
|
|
regulator-min-microvolt = <1200000>;
|
|
regulator-max-microvolt = <1200000>;
|
|
@@ -112,7 +109,6 @@ mt6357_vcn33_wifi_reg: ldo-vcn33-wifi {
|
|
};
|
|
|
|
mt6357_vcn28_reg: ldo-vcn28 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vcn28";
|
|
regulator-min-microvolt = <2800000>;
|
|
regulator-max-microvolt = <2800000>;
|
|
@@ -120,7 +116,6 @@ mt6357_vcn28_reg: ldo-vcn28 {
|
|
};
|
|
|
|
mt6357_vcn18_reg: ldo-vcn18 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vcn18";
|
|
regulator-min-microvolt = <1800000>;
|
|
regulator-max-microvolt = <1800000>;
|
|
@@ -142,7 +137,6 @@ mt6357_vcamd_reg: ldo-vcamd {
|
|
};
|
|
|
|
mt6357_vcamio_reg: ldo-vcamio18 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vcamio";
|
|
regulator-min-microvolt = <1800000>;
|
|
regulator-max-microvolt = <1800000>;
|
|
@@ -175,7 +169,6 @@ mt6357_vsram_proc_reg: ldo-vsram-proc {
|
|
};
|
|
|
|
mt6357_vaux18_reg: ldo-vaux18 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vaux18";
|
|
regulator-min-microvolt = <1800000>;
|
|
regulator-max-microvolt = <1800000>;
|
|
@@ -183,7 +176,6 @@ mt6357_vaux18_reg: ldo-vaux18 {
|
|
};
|
|
|
|
mt6357_vaud28_reg: ldo-vaud28 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vaud28";
|
|
regulator-min-microvolt = <2800000>;
|
|
regulator-max-microvolt = <2800000>;
|
|
@@ -191,7 +183,6 @@ mt6357_vaud28_reg: ldo-vaud28 {
|
|
};
|
|
|
|
mt6357_vio28_reg: ldo-vio28 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vio28";
|
|
regulator-min-microvolt = <2800000>;
|
|
regulator-max-microvolt = <2800000>;
|
|
@@ -199,7 +190,6 @@ mt6357_vio28_reg: ldo-vio28 {
|
|
};
|
|
|
|
mt6357_vio18_reg: ldo-vio18 {
|
|
- compatible = "regulator-fixed";
|
|
regulator-name = "vio18";
|
|
regulator-min-microvolt = <1800000>;
|
|
regulator-max-microvolt = <1800000>;
|
|
diff --git a/arch/arm64/boot/dts/mediatek/mt6359.dtsi b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
|
|
index 8e1b8c85c6ede9..779d6dfb55c003 100644
|
|
--- a/arch/arm64/boot/dts/mediatek/mt6359.dtsi
|
|
+++ b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
|
|
@@ -18,6 +18,8 @@ mt6359codec: mt6359codec {
|
|
};
|
|
|
|
regulators {
|
|
+ compatible = "mediatek,mt6359-regulator";
|
|
+
|
|
mt6359_vs1_buck_reg: buck_vs1 {
|
|
regulator-name = "vs1";
|
|
regulator-min-microvolt = <800000>;
|
|
@@ -296,7 +298,7 @@ mt6359_vsram_others_sshub_ldo: ldo_vsram_others_sshub {
|
|
};
|
|
};
|
|
|
|
- mt6359rtc: mt6359rtc {
|
|
+ mt6359rtc: rtc {
|
|
compatible = "mediatek,mt6358-rtc";
|
|
};
|
|
};
|
|
diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
|
|
index 7ba30209ba9a9a..22604d3abde3bd 100644
|
|
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
|
|
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
|
|
@@ -617,22 +617,6 @@ power-domain@MT8195_POWER_DOMAIN_VPPSYS0 {
|
|
#size-cells = <0>;
|
|
#power-domain-cells = <1>;
|
|
|
|
- power-domain@MT8195_POWER_DOMAIN_VDEC1 {
|
|
- reg = <MT8195_POWER_DOMAIN_VDEC1>;
|
|
- clocks = <&vdecsys CLK_VDEC_LARB1>;
|
|
- clock-names = "vdec1-0";
|
|
- mediatek,infracfg = <&infracfg_ao>;
|
|
- #power-domain-cells = <0>;
|
|
- };
|
|
-
|
|
- power-domain@MT8195_POWER_DOMAIN_VENC_CORE1 {
|
|
- reg = <MT8195_POWER_DOMAIN_VENC_CORE1>;
|
|
- clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>;
|
|
- clock-names = "venc1-larb";
|
|
- mediatek,infracfg = <&infracfg_ao>;
|
|
- #power-domain-cells = <0>;
|
|
- };
|
|
-
|
|
power-domain@MT8195_POWER_DOMAIN_VDOSYS0 {
|
|
reg = <MT8195_POWER_DOMAIN_VDOSYS0>;
|
|
clocks = <&topckgen CLK_TOP_CFG_VDO0>,
|
|
@@ -678,15 +662,25 @@ power-domain@MT8195_POWER_DOMAIN_VDEC0 {
|
|
clocks = <&vdecsys_soc CLK_VDEC_SOC_LARB1>;
|
|
clock-names = "vdec0-0";
|
|
mediatek,infracfg = <&infracfg_ao>;
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
#power-domain-cells = <0>;
|
|
- };
|
|
|
|
- power-domain@MT8195_POWER_DOMAIN_VDEC2 {
|
|
- reg = <MT8195_POWER_DOMAIN_VDEC2>;
|
|
- clocks = <&vdecsys_core1 CLK_VDEC_CORE1_LARB1>;
|
|
- clock-names = "vdec2-0";
|
|
- mediatek,infracfg = <&infracfg_ao>;
|
|
- #power-domain-cells = <0>;
|
|
+ power-domain@MT8195_POWER_DOMAIN_VDEC1 {
|
|
+ reg = <MT8195_POWER_DOMAIN_VDEC1>;
|
|
+ clocks = <&vdecsys CLK_VDEC_LARB1>;
|
|
+ clock-names = "vdec1-0";
|
|
+ mediatek,infracfg = <&infracfg_ao>;
|
|
+ #power-domain-cells = <0>;
|
|
+ };
|
|
+
|
|
+ power-domain@MT8195_POWER_DOMAIN_VDEC2 {
|
|
+ reg = <MT8195_POWER_DOMAIN_VDEC2>;
|
|
+ clocks = <&vdecsys_core1 CLK_VDEC_CORE1_LARB1>;
|
|
+ clock-names = "vdec2-0";
|
|
+ mediatek,infracfg = <&infracfg_ao>;
|
|
+ #power-domain-cells = <0>;
|
|
+ };
|
|
};
|
|
|
|
power-domain@MT8195_POWER_DOMAIN_VENC {
|
|
@@ -694,7 +688,17 @@ power-domain@MT8195_POWER_DOMAIN_VENC {
|
|
clocks = <&vencsys CLK_VENC_LARB>;
|
|
clock-names = "venc0-larb";
|
|
mediatek,infracfg = <&infracfg_ao>;
|
|
+ #address-cells = <1>;
|
|
+ #size-cells = <0>;
|
|
#power-domain-cells = <0>;
|
|
+
|
|
+ power-domain@MT8195_POWER_DOMAIN_VENC_CORE1 {
|
|
+ reg = <MT8195_POWER_DOMAIN_VENC_CORE1>;
|
|
+ clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>;
|
|
+ clock-names = "venc1-larb";
|
|
+ mediatek,infracfg = <&infracfg_ao>;
|
|
+ #power-domain-cells = <0>;
|
|
+ };
|
|
};
|
|
|
|
power-domain@MT8195_POWER_DOMAIN_VDOSYS1 {
|
|
diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
|
|
index 2b3bb5d0af17bd..f0b7949df92c05 100644
|
|
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
|
|
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
|
|
@@ -621,9 +621,7 @@ uartb: serial@3110000 {
|
|
reg-shift = <2>;
|
|
interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
|
|
clocks = <&bpmp TEGRA186_CLK_UARTB>;
|
|
- clock-names = "serial";
|
|
resets = <&bpmp TEGRA186_RESET_UARTB>;
|
|
- reset-names = "serial";
|
|
status = "disabled";
|
|
};
|
|
|
|
@@ -633,9 +631,7 @@ uartd: serial@3130000 {
|
|
reg-shift = <2>;
|
|
interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
|
|
clocks = <&bpmp TEGRA186_CLK_UARTD>;
|
|
- clock-names = "serial";
|
|
resets = <&bpmp TEGRA186_RESET_UARTD>;
|
|
- reset-names = "serial";
|
|
status = "disabled";
|
|
};
|
|
|
|
@@ -645,9 +641,7 @@ uarte: serial@3140000 {
|
|
reg-shift = <2>;
|
|
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
|
|
clocks = <&bpmp TEGRA186_CLK_UARTE>;
|
|
- clock-names = "serial";
|
|
resets = <&bpmp TEGRA186_RESET_UARTE>;
|
|
- reset-names = "serial";
|
|
status = "disabled";
|
|
};
|
|
|
|
@@ -657,9 +651,7 @@ uartf: serial@3150000 {
|
|
reg-shift = <2>;
|
|
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
|
|
clocks = <&bpmp TEGRA186_CLK_UARTF>;
|
|
- clock-names = "serial";
|
|
resets = <&bpmp TEGRA186_RESET_UARTF>;
|
|
- reset-names = "serial";
|
|
status = "disabled";
|
|
};
|
|
|
|
@@ -1236,9 +1228,7 @@ uartc: serial@c280000 {
|
|
reg-shift = <2>;
|
|
interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
|
|
clocks = <&bpmp TEGRA186_CLK_UARTC>;
|
|
- clock-names = "serial";
|
|
resets = <&bpmp TEGRA186_RESET_UARTC>;
|
|
- reset-names = "serial";
|
|
status = "disabled";
|
|
};
|
|
|
|
@@ -1248,9 +1238,7 @@ uartg: serial@c290000 {
|
|
reg-shift = <2>;
|
|
interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
|
|
clocks = <&bpmp TEGRA186_CLK_UARTG>;
|
|
- clock-names = "serial";
|
|
resets = <&bpmp TEGRA186_RESET_UARTG>;
|
|
- reset-names = "serial";
|
|
status = "disabled";
|
|
};
|
|
|
|
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
|
|
index 33f92b77cd9d9e..c3695077478514 100644
|
|
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
|
|
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
|
|
@@ -766,9 +766,7 @@ uartd: serial@3130000 {
|
|
reg-shift = <2>;
|
|
interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
|
|
clocks = <&bpmp TEGRA194_CLK_UARTD>;
|
|
- clock-names = "serial";
|
|
resets = <&bpmp TEGRA194_RESET_UARTD>;
|
|
- reset-names = "serial";
|
|
status = "disabled";
|
|
};
|
|
|
|
@@ -778,9 +776,7 @@ uarte: serial@3140000 {
|
|
reg-shift = <2>;
|
|
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
|
|
clocks = <&bpmp TEGRA194_CLK_UARTE>;
|
|
- clock-names = "serial";
|
|
resets = <&bpmp TEGRA194_RESET_UARTE>;
|
|
- reset-names = "serial";
|
|
status = "disabled";
|
|
};
|
|
|
|
@@ -790,9 +786,7 @@ uartf: serial@3150000 {
|
|
reg-shift = <2>;
|
|
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
|
|
clocks = <&bpmp TEGRA194_CLK_UARTF>;
|
|
- clock-names = "serial";
|
|
resets = <&bpmp TEGRA194_RESET_UARTF>;
|
|
- reset-names = "serial";
|
|
status = "disabled";
|
|
};
|
|
|
|
@@ -817,9 +811,7 @@ uarth: serial@3170000 {
|
|
reg-shift = <2>;
|
|
interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
|
|
clocks = <&bpmp TEGRA194_CLK_UARTH>;
|
|
- clock-names = "serial";
|
|
resets = <&bpmp TEGRA194_RESET_UARTH>;
|
|
- reset-names = "serial";
|
|
status = "disabled";
|
|
};
|
|
|
|
@@ -1616,9 +1608,7 @@ uartc: serial@c280000 {
|
|
reg-shift = <2>;
|
|
interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
|
|
clocks = <&bpmp TEGRA194_CLK_UARTC>;
|
|
- clock-names = "serial";
|
|
resets = <&bpmp TEGRA194_RESET_UARTC>;
|
|
- reset-names = "serial";
|
|
status = "disabled";
|
|
};
|
|
|
|
@@ -1628,9 +1618,7 @@ uartg: serial@c290000 {
|
|
reg-shift = <2>;
|
|
interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
|
|
clocks = <&bpmp TEGRA194_CLK_UARTG>;
|
|
- clock-names = "serial";
|
|
resets = <&bpmp TEGRA194_RESET_UARTG>;
|
|
- reset-names = "serial";
|
|
status = "disabled";
|
|
};
|
|
|
|
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
|
|
index 5c2894fcfa4a08..5498e84bfead01 100644
|
|
--- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
|
|
+++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
|
|
@@ -985,9 +985,6 @@ &sound {
|
|
"VA DMIC0", "MIC BIAS1",
|
|
"VA DMIC1", "MIC BIAS1",
|
|
"VA DMIC2", "MIC BIAS3",
|
|
- "VA DMIC0", "VA MIC BIAS1",
|
|
- "VA DMIC1", "VA MIC BIAS1",
|
|
- "VA DMIC2", "VA MIC BIAS3",
|
|
"TX SWR_ADC1", "ADC2_OUTPUT";
|
|
|
|
wcd-playback-dai-link {
|
|
diff --git a/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts b/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts
|
|
index 2ed39d402d3f6a..d687cfadee6a16 100644
|
|
--- a/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts
|
|
+++ b/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts
|
|
@@ -155,6 +155,7 @@ &blsp1_dma {
|
|
* BAM DMA interconnects support is in place.
|
|
*/
|
|
/delete-property/ clocks;
|
|
+ /delete-property/ clock-names;
|
|
};
|
|
|
|
&blsp1_uart2 {
|
|
@@ -167,6 +168,7 @@ &blsp2_dma {
|
|
* BAM DMA interconnects support is in place.
|
|
*/
|
|
/delete-property/ clocks;
|
|
+ /delete-property/ clock-names;
|
|
};
|
|
|
|
&blsp2_uart1 {
|
|
diff --git a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
|
|
index 3c47410ba94c0b..8221da390e1aa6 100644
|
|
--- a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
|
|
+++ b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
|
|
@@ -107,6 +107,7 @@ &qusb2phy0 {
|
|
status = "okay";
|
|
|
|
vdd-supply = <&vreg_l1b_0p925>;
|
|
+ vdda-pll-supply = <&vreg_l10a_1p8>;
|
|
vdda-phy-dpdm-supply = <&vreg_l7b_3p125>;
|
|
};
|
|
|
|
@@ -404,6 +405,8 @@ &sdhc_1 {
|
|
&sdhc_2 {
|
|
status = "okay";
|
|
|
|
+ cd-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
|
|
+
|
|
vmmc-supply = <&vreg_l5b_2p95>;
|
|
vqmmc-supply = <&vreg_l2b_2p95>;
|
|
};
|
|
diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
|
|
index d37a433130b98f..5948b401165ce9 100644
|
|
--- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
|
|
+++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts
|
|
@@ -135,8 +135,6 @@ vdda_pll_cc_ebi23:
|
|
vdda_sp_sensor:
|
|
vdda_ufs1_core:
|
|
vdda_ufs2_core:
|
|
- vdda_usb1_ss_core:
|
|
- vdda_usb2_ss_core:
|
|
vreg_l1a_0p875: ldo1 {
|
|
regulator-min-microvolt = <880000>;
|
|
regulator-max-microvolt = <880000>;
|
|
@@ -157,6 +155,7 @@ vreg_l3a_1p0: ldo3 {
|
|
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
|
|
};
|
|
|
|
+ vdda_usb1_ss_core:
|
|
vdd_wcss_cx:
|
|
vdd_wcss_mx:
|
|
vdda_wcss_pll:
|
|
@@ -383,8 +382,8 @@ &ufs_mem_phy {
|
|
};
|
|
|
|
&sdhc_2 {
|
|
- pinctrl-names = "default";
|
|
pinctrl-0 = <&sdc2_clk_state &sdc2_cmd_state &sdc2_data_state &sd_card_det_n_state>;
|
|
+ pinctrl-names = "default";
|
|
cd-gpios = <&tlmm 126 GPIO_ACTIVE_LOW>;
|
|
vmmc-supply = <&vreg_l21a_2p95>;
|
|
vqmmc-supply = <&vddpx_2>;
|
|
@@ -418,16 +417,9 @@ &usb_1_qmpphy {
|
|
status = "okay";
|
|
};
|
|
|
|
-&wifi {
|
|
- vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>;
|
|
- vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
|
|
- vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
|
|
- vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
|
|
- status = "okay";
|
|
-};
|
|
-
|
|
&tlmm {
|
|
- gpio-reserved-ranges = <0 4>, <27 4>, <81 4>, <85 4>;
|
|
+ gpio-reserved-ranges = <27 4>, /* SPI (eSE - embedded Secure Element) */
|
|
+ <85 4>; /* SPI (fingerprint reader) */
|
|
|
|
sdc2_clk_state: sdc2-clk-state {
|
|
pins = "sdc2_clk";
|
|
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
|
|
index 21bbffc4e5a284..c9a7d1b75c658d 100644
|
|
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
|
|
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
|
|
@@ -601,7 +601,7 @@ cpu7_opp8: opp-1632000000 {
|
|
};
|
|
|
|
cpu7_opp9: opp-1747200000 {
|
|
- opp-hz = /bits/ 64 <1708800000>;
|
|
+ opp-hz = /bits/ 64 <1747200000>;
|
|
opp-peak-kBps = <5412000 42393600>;
|
|
};
|
|
|
|
diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
|
|
index 5376c0a00fab65..215782b1970df9 100644
|
|
--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
|
|
+++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
|
|
@@ -1754,11 +1754,11 @@ cryptobam: dma-controller@1dc4000 {
|
|
interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
|
|
#dma-cells = <1>;
|
|
qcom,ee = <0>;
|
|
+ qcom,num-ees = <4>;
|
|
+ num-channels = <16>;
|
|
qcom,controlled-remotely;
|
|
iommus = <&apps_smmu 0x594 0x0011>,
|
|
<&apps_smmu 0x596 0x0011>;
|
|
- /* FIXME: Probing BAM DMA causes some abort and system hang */
|
|
- status = "fail";
|
|
};
|
|
|
|
crypto: crypto@1dfa000 {
|
|
@@ -1770,8 +1770,6 @@ crypto: crypto@1dfa000 {
|
|
<&apps_smmu 0x596 0x0011>;
|
|
interconnects = <&aggre2_noc MASTER_CRYPTO 0 &mc_virt SLAVE_EBI1 0>;
|
|
interconnect-names = "memory";
|
|
- /* FIXME: dependency BAM DMA is disabled */
|
|
- status = "disabled";
|
|
};
|
|
|
|
ipa: ipa@1e40000 {
|
|
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso
|
|
index e6f53377ecd90c..99f62574bc3c2a 100644
|
|
--- a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso
|
|
+++ b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ard-audio-da7212.dtso
|
|
@@ -108,7 +108,7 @@ sound_clk_pins: sound-clk {
|
|
};
|
|
|
|
tpu0_pins: tpu0 {
|
|
- groups = "tpu_to0_a";
|
|
+ groups = "tpu_to0_b";
|
|
function = "tpu";
|
|
};
|
|
};
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
|
|
index 115c14c0a3c68c..396a6636073b51 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
|
|
@@ -251,14 +251,6 @@ &uart2 {
|
|
status = "okay";
|
|
};
|
|
|
|
-&usb_host0_ehci {
|
|
- status = "okay";
|
|
-};
|
|
-
|
|
-&usb_host0_ohci {
|
|
- status = "okay";
|
|
-};
|
|
-
|
|
&vopb {
|
|
status = "okay";
|
|
};
|
|
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
|
|
index 93189f83064006..c30354268c8f5e 100644
|
|
--- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
|
|
+++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
|
|
@@ -486,9 +486,12 @@ &saradc {
|
|
&sdhci {
|
|
bus-width = <8>;
|
|
max-frequency = <200000000>;
|
|
+ mmc-hs200-1_8v;
|
|
non-removable;
|
|
pinctrl-names = "default";
|
|
- pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>;
|
|
+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
|
|
+ vmmc-supply = <&vcc_3v3>;
|
|
+ vqmmc-supply = <&vcc_1v8>;
|
|
status = "okay";
|
|
};
|
|
|
|
diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
|
|
index 57befcce93b976..0523bd0da80c72 100644
|
|
--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
|
|
+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
|
|
@@ -436,6 +436,8 @@ sdhci0: mmc@4f80000 {
|
|
interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
|
|
mmc-ddr-1_8v;
|
|
mmc-hs200-1_8v;
|
|
+ ti,clkbuf-sel = <0x7>;
|
|
+ ti,trm-icp = <0x8>;
|
|
ti,otap-del-sel-legacy = <0x0>;
|
|
ti,otap-del-sel-mmc-hs = <0x0>;
|
|
ti,otap-del-sel-sd-hs = <0x0>;
|
|
@@ -446,8 +448,9 @@ sdhci0: mmc@4f80000 {
|
|
ti,otap-del-sel-ddr50 = <0x5>;
|
|
ti,otap-del-sel-ddr52 = <0x5>;
|
|
ti,otap-del-sel-hs200 = <0x5>;
|
|
- ti,otap-del-sel-hs400 = <0x0>;
|
|
- ti,trm-icp = <0x8>;
|
|
+ ti,itap-del-sel-legacy = <0xa>;
|
|
+ ti,itap-del-sel-mmc-hs = <0x1>;
|
|
+ ti,itap-del-sel-ddr52 = <0x0>;
|
|
dma-coherent;
|
|
};
|
|
|
|
@@ -458,18 +461,22 @@ sdhci1: mmc@4fa0000 {
|
|
clocks = <&k3_clks 48 0>, <&k3_clks 48 1>;
|
|
clock-names = "clk_ahb", "clk_xin";
|
|
interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
|
|
+ ti,clkbuf-sel = <0x7>;
|
|
+ ti,trm-icp = <0x8>;
|
|
ti,otap-del-sel-legacy = <0x0>;
|
|
ti,otap-del-sel-mmc-hs = <0x0>;
|
|
ti,otap-del-sel-sd-hs = <0x0>;
|
|
- ti,otap-del-sel-sdr12 = <0x0>;
|
|
- ti,otap-del-sel-sdr25 = <0x0>;
|
|
+ ti,otap-del-sel-sdr12 = <0xf>;
|
|
+ ti,otap-del-sel-sdr25 = <0xf>;
|
|
ti,otap-del-sel-sdr50 = <0x8>;
|
|
ti,otap-del-sel-sdr104 = <0x7>;
|
|
ti,otap-del-sel-ddr50 = <0x4>;
|
|
ti,otap-del-sel-ddr52 = <0x4>;
|
|
ti,otap-del-sel-hs200 = <0x7>;
|
|
- ti,clkbuf-sel = <0x7>;
|
|
- ti,trm-icp = <0x8>;
|
|
+ ti,itap-del-sel-legacy = <0xa>;
|
|
+ ti,itap-del-sel-sd-hs = <0x1>;
|
|
+ ti,itap-del-sel-sdr12 = <0xa>;
|
|
+ ti,itap-del-sel-sdr25 = <0x1>;
|
|
dma-coherent;
|
|
};
|
|
|
|
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
|
|
index fe5207ac7d85d1..90ae8e948671d6 100644
|
|
--- a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
|
|
+++ b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
|
|
@@ -557,6 +557,7 @@ &usb1 {
|
|
&ospi1 {
|
|
pinctrl-names = "default";
|
|
pinctrl-0 = <&mcu_fss0_ospi1_pins_default>;
|
|
+ status = "okay";
|
|
|
|
flash@0 {
|
|
compatible = "jedec,spi-nor";
|
|
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
|
|
index ccacb65683b5b0..952d2c72628ef4 100644
|
|
--- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
|
|
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
|
|
@@ -183,6 +183,17 @@ vsys_3v3: fixedregulator-vsys3v3 {
|
|
regulator-boot-on;
|
|
};
|
|
|
|
+ vsys_5v0: fixedregulator-vsys5v0 {
|
|
+ /* Output of LM61460 */
|
|
+ compatible = "regulator-fixed";
|
|
+ regulator-name = "vsys_5v0";
|
|
+ regulator-min-microvolt = <5000000>;
|
|
+ regulator-max-microvolt = <5000000>;
|
|
+ vin-supply = <&vusb_main>;
|
|
+ regulator-always-on;
|
|
+ regulator-boot-on;
|
|
+ };
|
|
+
|
|
vdd_mmc1: fixedregulator-sd {
|
|
compatible = "regulator-fixed";
|
|
pinctrl-names = "default";
|
|
@@ -210,6 +221,56 @@ vdd_sd_dv_alt: gpio-regulator-tps659411 {
|
|
<3300000 0x1>;
|
|
};
|
|
|
|
+ vdd_sd_dv: gpio-regulator-TLV71033 {
|
|
+ compatible = "regulator-gpio";
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&vdd_sd_dv_pins_default>;
|
|
+ regulator-name = "tlv71033";
|
|
+ regulator-min-microvolt = <1800000>;
|
|
+ regulator-max-microvolt = <3300000>;
|
|
+ regulator-boot-on;
|
|
+ vin-supply = <&vsys_5v0>;
|
|
+ gpios = <&main_gpio0 118 GPIO_ACTIVE_HIGH>;
|
|
+ states = <1800000 0x0>,
|
|
+ <3300000 0x1>;
|
|
+ };
|
|
+
|
|
+ transceiver1: can-phy1 {
|
|
+ compatible = "ti,tcan1042";
|
|
+ #phy-cells = <0>;
|
|
+ max-bitrate = <5000000>;
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&mcu_mcan0_gpio_pins_default>;
|
|
+ standby-gpios = <&wkup_gpio0 3 GPIO_ACTIVE_HIGH>;
|
|
+ };
|
|
+
|
|
+ transceiver2: can-phy2 {
|
|
+ compatible = "ti,tcan1042";
|
|
+ #phy-cells = <0>;
|
|
+ max-bitrate = <5000000>;
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&main_mcan0_gpio_pins_default>;
|
|
+ standby-gpios = <&main_gpio0 65 GPIO_ACTIVE_HIGH>;
|
|
+ };
|
|
+
|
|
+ transceiver3: can-phy3 {
|
|
+ compatible = "ti,tcan1042";
|
|
+ #phy-cells = <0>;
|
|
+ max-bitrate = <5000000>;
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&main_mcan5_gpio_pins_default>;
|
|
+ standby-gpios = <&main_gpio0 66 GPIO_ACTIVE_HIGH>;
|
|
+ };
|
|
+
|
|
+ transceiver4: can-phy4 {
|
|
+ compatible = "ti,tcan1042";
|
|
+ #phy-cells = <0>;
|
|
+ max-bitrate = <5000000>;
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&main_mcan9_gpio_pins_default>;
|
|
+ standby-gpios = <&main_gpio0 67 GPIO_ACTIVE_HIGH>;
|
|
+ };
|
|
+
|
|
dp_pwr_3v3: fixedregulator-dp-prw {
|
|
compatible = "regulator-fixed";
|
|
regulator-name = "dp-pwr";
|
|
@@ -286,6 +347,15 @@ tfp410_out: endpoint {
|
|
};
|
|
};
|
|
};
|
|
+
|
|
+ csi_mux: mux-controller {
|
|
+ compatible = "gpio-mux";
|
|
+ #mux-state-cells = <1>;
|
|
+ mux-gpios = <&main_gpio0 88 GPIO_ACTIVE_HIGH>;
|
|
+ idle-state = <0>;
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&main_csi_mux_sel_pins_default>;
|
|
+ };
|
|
};
|
|
|
|
&main_pmx0 {
|
|
@@ -352,6 +422,51 @@ J721E_IOPAD(0x214, PIN_OUTPUT, 4) /* (V4) MCAN1_TX.USB1_DRVVBUS */
|
|
>;
|
|
};
|
|
|
|
+ main_csi_mux_sel_pins_default: main-csi-mux-sel-default-pins {
|
|
+ pinctrl-single,pins = <
|
|
+ J721E_IOPAD(0x164, PIN_OUTPUT, 7) /* (V29) RGMII5_TD2 */
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ main_mcan0_pins_default: main-mcan0-default-pins {
|
|
+ pinctrl-single,pins = <
|
|
+ J721E_IOPAD(0x208, PIN_INPUT, 0) /* (W5) MCAN0_RX */
|
|
+ J721E_IOPAD(0x20c, PIN_OUTPUT, 0) /* (W6) MCAN0_TX */
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ main_mcan0_gpio_pins_default: main-mcan0-gpio-default-pins {
|
|
+ pinctrl-single,pins = <
|
|
+ J721E_IOPAD(0x108, PIN_INPUT, 7) /* (AD27) PRG0_PRU1_GPO2.GPIO0_65 */
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ main_mcan5_pins_default: main-mcan5-default-pins {
|
|
+ pinctrl-single,pins = <
|
|
+ J721E_IOPAD(0x050, PIN_INPUT, 6) /* (AE21) PRG1_PRU0_GPO18.MCAN5_RX */
|
|
+ J721E_IOPAD(0x04c, PIN_OUTPUT, 6) /* (AJ21) PRG1_PRU0_GPO17.MCAN5_TX */
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ main_mcan5_gpio_pins_default: main-mcan5-gpio-default-pins {
|
|
+ pinctrl-single,pins = <
|
|
+ J721E_IOPAD(0x10c, PIN_INPUT, 7) /* (AC25) PRG0_PRU1_GPO3.GPIO0_66 */
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ main_mcan9_pins_default: main-mcan9-default-pins {
|
|
+ pinctrl-single,pins = <
|
|
+ J721E_IOPAD(0x0d0, PIN_INPUT, 6) /* (AC27) PRG0_PRU0_GPO8.MCAN9_RX */
|
|
+ J721E_IOPAD(0x0cc, PIN_OUTPUT, 6) /* (AC28) PRG0_PRU0_GPO7.MCAN9_TX */
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ main_mcan9_gpio_pins_default: main-mcan9-gpio-default-pins {
|
|
+ pinctrl-single,pins = <
|
|
+ J721E_IOPAD(0x110, PIN_INPUT, 7) /* (AD29) PRG0_PRU1_GPO4.GPIO0_67 */
|
|
+ >;
|
|
+ };
|
|
+
|
|
dp0_pins_default: dp0-default-pins {
|
|
pinctrl-single,pins = <
|
|
J721E_IOPAD(0x1c4, PIN_INPUT, 5) /* SPI0_CS1.DP0_HPD */
|
|
@@ -511,6 +626,12 @@ J721E_WKUP_IOPAD(0xd4, PIN_OUTPUT, 7) /* (G26) WKUP_GPIO0_9 */
|
|
>;
|
|
};
|
|
|
|
+ vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
|
|
+ pinctrl-single,pins = <
|
|
+ J721E_IOPAD(0x1dc, PIN_OUTPUT, 7) /* (Y1) SPI1_CLK.GPIO0_118 */
|
|
+ >;
|
|
+ };
|
|
+
|
|
wkup_uart0_pins_default: wkup-uart0-default-pins {
|
|
pinctrl-single,pins = <
|
|
J721E_WKUP_IOPAD(0xa0, PIN_INPUT, 0) /* (J29) WKUP_UART0_RXD */
|
|
@@ -534,6 +655,19 @@ J721E_WKUP_IOPAD(0xfc, PIN_INPUT_PULLUP, 0) /* (H24) WKUP_I2C0_SDA */
|
|
>;
|
|
};
|
|
|
|
+ mcu_mcan0_pins_default: mcu-mcan0-default-pins {
|
|
+ pinctrl-single,pins = <
|
|
+ J721E_WKUP_IOPAD(0x0ac, PIN_INPUT, 0) /* (C29) MCU_MCAN0_RX */
|
|
+ J721E_WKUP_IOPAD(0x0a8, PIN_OUTPUT, 0) /* (D29) MCU_MCAN0_TX */
|
|
+ >;
|
|
+ };
|
|
+
|
|
+ mcu_mcan0_gpio_pins_default: mcu-mcan0-gpio-default-pins {
|
|
+ pinctrl-single,pins = <
|
|
+ J721E_WKUP_IOPAD(0x0bc, PIN_INPUT, 7) /* (F27) WKUP_GPIO0_3 */
|
|
+ >;
|
|
+ };
|
|
+
|
|
/* Reset for M.2 M Key slot on PCIe1 */
|
|
mkey_reset_pins_default: mkey-reset-pns-default-pins {
|
|
pinctrl-single,pins = <
|
|
@@ -707,14 +841,14 @@ i2c-mux@70 {
|
|
reg = <0x70>;
|
|
|
|
/* CSI0 I2C */
|
|
- i2c@0 {
|
|
+ cam0_i2c: i2c@0 {
|
|
#address-cells = <1>;
|
|
#size-cells = <0>;
|
|
reg = <0>;
|
|
};
|
|
|
|
/* CSI1 I2C */
|
|
- i2c@1 {
|
|
+ cam1_i2c: i2c@1 {
|
|
#address-cells = <1>;
|
|
#size-cells = <0>;
|
|
reg = <1>;
|
|
@@ -942,6 +1076,34 @@ &pcie1_rc {
|
|
num-lanes = <2>;
|
|
};
|
|
|
|
+&mcu_mcan0 {
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&mcu_mcan0_pins_default>;
|
|
+ phys = <&transceiver1>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&main_mcan0 {
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&main_mcan0_pins_default>;
|
|
+ phys = <&transceiver2>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&main_mcan5 {
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&main_mcan5_pins_default>;
|
|
+ phys = <&transceiver3>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
+&main_mcan9 {
|
|
+ pinctrl-names = "default";
|
|
+ pinctrl-0 = <&main_mcan9_pins_default>;
|
|
+ phys = <&transceiver4>;
|
|
+ status = "okay";
|
|
+};
|
|
+
|
|
&ufs_wrapper {
|
|
status = "disabled";
|
|
};
|
|
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
|
|
index 60af93c04b45a7..a4fc913d1e4943 100644
|
|
--- a/arch/arm64/configs/defconfig
|
|
+++ b/arch/arm64/configs/defconfig
|
|
@@ -1412,6 +1412,9 @@ CONFIG_PHY_HISTB_COMBPHY=y
|
|
CONFIG_PHY_HISI_INNO_USB2=y
|
|
CONFIG_PHY_MVEBU_CP110_COMPHY=y
|
|
CONFIG_PHY_MTK_TPHY=y
|
|
+CONFIG_PHY_MTK_HDMI=m
|
|
+CONFIG_PHY_MTK_MIPI_DSI=m
|
|
+CONFIG_PHY_MTK_DP=m
|
|
CONFIG_PHY_QCOM_EDP=m
|
|
CONFIG_PHY_QCOM_EUSB2_REPEATER=m
|
|
CONFIG_PHY_QCOM_PCIE2=m
|
|
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
|
|
index 1cdae1b4f03bee..b04575ea3a355e 100644
|
|
--- a/arch/arm64/include/asm/esr.h
|
|
+++ b/arch/arm64/include/asm/esr.h
|
|
@@ -366,12 +366,14 @@
|
|
/*
|
|
* ISS values for SME traps
|
|
*/
|
|
-
|
|
-#define ESR_ELx_SME_ISS_SME_DISABLED 0
|
|
-#define ESR_ELx_SME_ISS_ILL 1
|
|
-#define ESR_ELx_SME_ISS_SM_DISABLED 2
|
|
-#define ESR_ELx_SME_ISS_ZA_DISABLED 3
|
|
-#define ESR_ELx_SME_ISS_ZT_DISABLED 4
|
|
+#define ESR_ELx_SME_ISS_SMTC_MASK GENMASK(2, 0)
|
|
+#define ESR_ELx_SME_ISS_SMTC(esr) ((esr) & ESR_ELx_SME_ISS_SMTC_MASK)
|
|
+
|
|
+#define ESR_ELx_SME_ISS_SMTC_SME_DISABLED 0
|
|
+#define ESR_ELx_SME_ISS_SMTC_ILL 1
|
|
+#define ESR_ELx_SME_ISS_SMTC_SM_DISABLED 2
|
|
+#define ESR_ELx_SME_ISS_SMTC_ZA_DISABLED 3
|
|
+#define ESR_ELx_SME_ISS_SMTC_ZT_DISABLED 4
|
|
|
|
/* ISS field definitions for MOPS exceptions */
|
|
#define ESR_ELx_MOPS_ISS_MEM_INST (UL(1) << 24)
|
|
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
|
|
index 7415c63b41874d..c4840ea6d137f0 100644
|
|
--- a/arch/arm64/include/asm/fpsimd.h
|
|
+++ b/arch/arm64/include/asm/fpsimd.h
|
|
@@ -6,6 +6,7 @@
|
|
#define __ASM_FP_H
|
|
|
|
#include <asm/errno.h>
|
|
+#include <asm/percpu.h>
|
|
#include <asm/ptrace.h>
|
|
#include <asm/processor.h>
|
|
#include <asm/sigcontext.h>
|
|
@@ -69,6 +70,8 @@ struct cpu_fp_state {
|
|
enum fp_type to_save;
|
|
};
|
|
|
|
+DECLARE_PER_CPU(struct cpu_fp_state, fpsimd_last_state);
|
|
+
|
|
extern void fpsimd_bind_state_to_cpu(struct cpu_fp_state *fp_state);
|
|
|
|
extern void fpsimd_flush_task_state(struct task_struct *target);
|
|
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
|
|
index 0fc94207e69a8e..5e8204d250b437 100644
|
|
--- a/arch/arm64/kernel/entry-common.c
|
|
+++ b/arch/arm64/kernel/entry-common.c
|
|
@@ -359,20 +359,16 @@ static bool cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
|
|
* As per the ABI exit SME streaming mode and clear the SVE state not
|
|
* shared with FPSIMD on syscall entry.
|
|
*/
|
|
-static inline void fp_user_discard(void)
|
|
+static inline void fpsimd_syscall_enter(void)
|
|
{
|
|
- /*
|
|
- * If SME is active then exit streaming mode. If ZA is active
|
|
- * then flush the SVE registers but leave userspace access to
|
|
- * both SVE and SME enabled, otherwise disable SME for the
|
|
- * task and fall through to disabling SVE too. This means
|
|
- * that after a syscall we never have any streaming mode
|
|
- * register state to track, if this changes the KVM code will
|
|
- * need updating.
|
|
- */
|
|
+ /* Ensure PSTATE.SM is clear, but leave PSTATE.ZA as-is. */
|
|
if (system_supports_sme())
|
|
sme_smstop_sm();
|
|
|
|
+ /*
|
|
+ * The CPU is not in streaming mode. If non-streaming SVE is not
|
|
+ * supported, there is no SVE state that needs to be discarded.
|
|
+ */
|
|
if (!system_supports_sve())
|
|
return;
|
|
|
|
@@ -382,6 +378,33 @@ static inline void fp_user_discard(void)
|
|
sve_vq_minus_one = sve_vq_from_vl(task_get_sve_vl(current)) - 1;
|
|
sve_flush_live(true, sve_vq_minus_one);
|
|
}
|
|
+
|
|
+ /*
|
|
+ * Any live non-FPSIMD SVE state has been zeroed. Allow
|
|
+ * fpsimd_save_user_state() to lazily discard SVE state until either
|
|
+ * the live state is unbound or fpsimd_syscall_exit() is called.
|
|
+ */
|
|
+ __this_cpu_write(fpsimd_last_state.to_save, FP_STATE_FPSIMD);
|
|
+}
|
|
+
|
|
+static __always_inline void fpsimd_syscall_exit(void)
|
|
+{
|
|
+ if (!system_supports_sve())
|
|
+ return;
|
|
+
|
|
+ /*
|
|
+ * The current task's user FPSIMD/SVE/SME state is now bound to this
|
|
+ * CPU. The fpsimd_last_state.to_save value is either:
|
|
+ *
|
|
+ * - FP_STATE_FPSIMD, if the state has not been reloaded on this CPU
|
|
+ * since fpsimd_syscall_enter().
|
|
+ *
|
|
+ * - FP_STATE_CURRENT, if the state has been reloaded on this CPU at
|
|
+ * any point.
|
|
+ *
|
|
+ * Reset this to FP_STATE_CURRENT to stop lazy discarding.
|
|
+ */
|
|
+ __this_cpu_write(fpsimd_last_state.to_save, FP_STATE_CURRENT);
|
|
}
|
|
|
|
UNHANDLED(el1t, 64, sync)
|
|
@@ -673,10 +696,11 @@ static void noinstr el0_svc(struct pt_regs *regs)
|
|
{
|
|
enter_from_user_mode(regs);
|
|
cortex_a76_erratum_1463225_svc_handler();
|
|
- fp_user_discard();
|
|
+ fpsimd_syscall_enter();
|
|
local_daif_restore(DAIF_PROCCTX);
|
|
do_el0_svc(regs);
|
|
exit_to_user_mode(regs);
|
|
+ fpsimd_syscall_exit();
|
|
}
|
|
|
|
static void noinstr el0_fpac(struct pt_regs *regs, unsigned long esr)
|
|
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
|
|
index bd4f6c6ee0f318..a1e0cc5353fb12 100644
|
|
--- a/arch/arm64/kernel/fpsimd.c
|
|
+++ b/arch/arm64/kernel/fpsimd.c
|
|
@@ -119,7 +119,7 @@
|
|
* whatever is in the FPSIMD registers is not saved to memory, but discarded.
|
|
*/
|
|
|
|
-static DEFINE_PER_CPU(struct cpu_fp_state, fpsimd_last_state);
|
|
+DEFINE_PER_CPU(struct cpu_fp_state, fpsimd_last_state);
|
|
|
|
__ro_after_init struct vl_info vl_info[ARM64_VEC_MAX] = {
|
|
#ifdef CONFIG_ARM64_SVE
|
|
@@ -473,12 +473,15 @@ static void fpsimd_save(void)
|
|
return;
|
|
|
|
/*
|
|
- * If a task is in a syscall the ABI allows us to only
|
|
- * preserve the state shared with FPSIMD so don't bother
|
|
- * saving the full SVE state in that case.
|
|
+ * Save SVE state if it is live.
|
|
+ *
|
|
+ * The syscall ABI discards live SVE state at syscall entry. When
|
|
+ * entering a syscall, fpsimd_syscall_enter() sets to_save to
|
|
+ * FP_STATE_FPSIMD to allow the SVE state to be lazily discarded until
|
|
+ * either new SVE state is loaded+bound or fpsimd_syscall_exit() is
|
|
+ * called prior to a return to userspace.
|
|
*/
|
|
- if ((last->to_save == FP_STATE_CURRENT && test_thread_flag(TIF_SVE) &&
|
|
- !in_syscall(current_pt_regs())) ||
|
|
+ if ((last->to_save == FP_STATE_CURRENT && test_thread_flag(TIF_SVE)) ||
|
|
last->to_save == FP_STATE_SVE) {
|
|
save_sve_regs = true;
|
|
save_ffr = true;
|
|
@@ -1514,7 +1517,7 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
|
|
* If this not a trap due to SME being disabled then something
|
|
* is being used in the wrong mode, report as SIGILL.
|
|
*/
|
|
- if (ESR_ELx_ISS(esr) != ESR_ELx_SME_ISS_SME_DISABLED) {
|
|
+ if (ESR_ELx_SME_ISS_SMTC(esr) != ESR_ELx_SME_ISS_SMTC_SME_DISABLED) {
|
|
force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0);
|
|
return;
|
|
}
|
|
@@ -1538,6 +1541,8 @@ void do_sme_acc(unsigned long esr, struct pt_regs *regs)
|
|
sme_set_vq(vq_minus_one);
|
|
|
|
fpsimd_bind_task_to_cpu();
|
|
+ } else {
|
|
+ fpsimd_flush_task_state(current);
|
|
}
|
|
|
|
put_cpu_fpsimd_context();
|
|
@@ -1803,7 +1808,7 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state)
|
|
get_cpu_fpsimd_context();
|
|
|
|
current->thread.uw.fpsimd_state = *state;
|
|
- if (test_thread_flag(TIF_SVE))
|
|
+ if (current->thread.fp_type == FP_STATE_SVE)
|
|
fpsimd_to_sve(current);
|
|
|
|
task_fpsimd_load();
|
|
diff --git a/arch/arm64/xen/hypercall.S b/arch/arm64/xen/hypercall.S
|
|
index 9d01361696a145..ae551b8571374f 100644
|
|
--- a/arch/arm64/xen/hypercall.S
|
|
+++ b/arch/arm64/xen/hypercall.S
|
|
@@ -83,7 +83,26 @@ HYPERCALL3(vcpu_op);
|
|
HYPERCALL1(platform_op_raw);
|
|
HYPERCALL2(multicall);
|
|
HYPERCALL2(vm_assist);
|
|
-HYPERCALL3(dm_op);
|
|
+
|
|
+SYM_FUNC_START(HYPERVISOR_dm_op)
|
|
+ mov x16, #__HYPERVISOR_dm_op; \
|
|
+ /*
|
|
+ * dm_op hypercalls are issued by the userspace. The kernel needs to
|
|
+ * enable access to TTBR0_EL1 as the hypervisor would issue stage 1
|
|
+ * translations to user memory via AT instructions. Since AT
|
|
+ * instructions are not affected by the PAN bit (ARMv8.1), we only
|
|
+ * need the explicit uaccess_enable/disable if the TTBR0 PAN emulation
|
|
+ * is enabled (it implies that hardware UAO and PAN disabled).
|
|
+ */
|
|
+ uaccess_ttbr0_enable x6, x7, x8
|
|
+ hvc XEN_IMM
|
|
+
|
|
+ /*
|
|
+ * Disable userspace access from kernel once the hyp call completed.
|
|
+ */
|
|
+ uaccess_ttbr0_disable x6, x7
|
|
+ ret
|
|
+SYM_FUNC_END(HYPERVISOR_dm_op);
|
|
|
|
SYM_FUNC_START(privcmd_call)
|
|
mov x16, x0
|
|
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
|
|
index 382f656c29eaee..9f5603e01a6889 100644
|
|
--- a/arch/m68k/mac/config.c
|
|
+++ b/arch/m68k/mac/config.c
|
|
@@ -801,7 +801,7 @@ static void __init mac_identify(void)
|
|
}
|
|
|
|
macintosh_config = mac_data_table;
|
|
- for (m = macintosh_config; m->ident != -1; m++) {
|
|
+ for (m = &mac_data_table[1]; m->ident != -1; m++) {
|
|
if (m->ident == model) {
|
|
macintosh_config = m;
|
|
break;
|
|
diff --git a/arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts b/arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts
|
|
index c7ea4f1c0bb21f..6c277ab83d4b94 100644
|
|
--- a/arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts
|
|
+++ b/arch/mips/boot/dts/loongson/loongson64c_4core_ls7a.dts
|
|
@@ -29,6 +29,7 @@ msi: msi-controller@2ff00000 {
|
|
compatible = "loongson,pch-msi-1.0";
|
|
reg = <0 0x2ff00000 0 0x8>;
|
|
interrupt-controller;
|
|
+ #interrupt-cells = <1>;
|
|
msi-controller;
|
|
loongson,msi-base-vec = <64>;
|
|
loongson,msi-num-vecs = <64>;
|
|
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
|
|
index 2919433be35574..b7629122680b1e 100644
|
|
--- a/arch/powerpc/kernel/Makefile
|
|
+++ b/arch/powerpc/kernel/Makefile
|
|
@@ -165,7 +165,7 @@ endif
|
|
|
|
obj64-$(CONFIG_PPC_TRANSACTIONAL_MEM) += tm.o
|
|
|
|
-ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC_CORE)(CONFIG_PPC_BOOK3S),)
|
|
+ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC_CORE)$(CONFIG_PPC_BOOK3S),)
|
|
obj-y += ppc_save_regs.o
|
|
endif
|
|
|
|
diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c
|
|
index ef5c2d25ec3976..61552bbb1ea8a3 100644
|
|
--- a/arch/powerpc/kexec/crash.c
|
|
+++ b/arch/powerpc/kexec/crash.c
|
|
@@ -356,7 +356,10 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
|
|
if (TRAP(regs) == INTERRUPT_SYSTEM_RESET)
|
|
is_via_system_reset = 1;
|
|
|
|
- crash_smp_send_stop();
|
|
+ if (IS_ENABLED(CONFIG_SMP))
|
|
+ crash_smp_send_stop();
|
|
+ else
|
|
+ crash_kexec_prepare();
|
|
|
|
crash_save_cpu(regs, crashing_cpu);
|
|
|
|
diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c
|
|
index 0b6365d85d1171..dc6f75d3ac6ef7 100644
|
|
--- a/arch/powerpc/platforms/book3s/vas-api.c
|
|
+++ b/arch/powerpc/platforms/book3s/vas-api.c
|
|
@@ -521,6 +521,15 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma)
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ /*
|
|
+ * Map complete page to the paste address. So the user
|
|
+ * space should pass 0ULL to the offset parameter.
|
|
+ */
|
|
+ if (vma->vm_pgoff) {
|
|
+ pr_debug("Page offset unsupported to map paste address\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
/* Ensure instance has an open send window */
|
|
if (!txwin) {
|
|
pr_err("No send window open?\n");
|
|
diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c
|
|
index 877720c645151f..35471b679638a8 100644
|
|
--- a/arch/powerpc/platforms/powernv/memtrace.c
|
|
+++ b/arch/powerpc/platforms/powernv/memtrace.c
|
|
@@ -48,11 +48,15 @@ static ssize_t memtrace_read(struct file *filp, char __user *ubuf,
|
|
static int memtrace_mmap(struct file *filp, struct vm_area_struct *vma)
|
|
{
|
|
struct memtrace_entry *ent = filp->private_data;
|
|
+ unsigned long ent_nrpages = ent->size >> PAGE_SHIFT;
|
|
+ unsigned long vma_nrpages = vma_pages(vma);
|
|
|
|
- if (ent->size < vma->vm_end - vma->vm_start)
|
|
+ /* The requested page offset should be within object's page count */
|
|
+ if (vma->vm_pgoff >= ent_nrpages)
|
|
return -EINVAL;
|
|
|
|
- if (vma->vm_pgoff << PAGE_SHIFT >= ent->size)
|
|
+ /* The requested mapping range should remain within the bounds */
|
|
+ if (vma_nrpages > ent_nrpages - vma->vm_pgoff)
|
|
return -EINVAL;
|
|
|
|
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
|
diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c
|
|
index be43278109f4e8..a71d33cd81d3d1 100644
|
|
--- a/arch/riscv/kvm/vcpu_sbi.c
|
|
+++ b/arch/riscv/kvm/vcpu_sbi.c
|
|
@@ -103,9 +103,9 @@ void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
|
|
struct kvm_vcpu *tmp;
|
|
|
|
kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
|
|
- spin_lock(&vcpu->arch.mp_state_lock);
|
|
+ spin_lock(&tmp->arch.mp_state_lock);
|
|
WRITE_ONCE(tmp->arch.mp_state.mp_state, KVM_MP_STATE_STOPPED);
|
|
- spin_unlock(&vcpu->arch.mp_state_lock);
|
|
+ spin_unlock(&tmp->arch.mp_state_lock);
|
|
}
|
|
kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP);
|
|
|
|
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
|
|
index 62ee557d4b4996..a40c7ff91caf03 100644
|
|
--- a/arch/s390/net/bpf_jit_comp.c
|
|
+++ b/arch/s390/net/bpf_jit_comp.c
|
|
@@ -587,17 +587,15 @@ static void bpf_jit_prologue(struct bpf_jit *jit, struct bpf_prog *fp,
|
|
}
|
|
/* Setup stack and backchain */
|
|
if (is_first_pass(jit) || (jit->seen & SEEN_STACK)) {
|
|
- if (is_first_pass(jit) || (jit->seen & SEEN_FUNC))
|
|
- /* lgr %w1,%r15 (backchain) */
|
|
- EMIT4(0xb9040000, REG_W1, REG_15);
|
|
+ /* lgr %w1,%r15 (backchain) */
|
|
+ EMIT4(0xb9040000, REG_W1, REG_15);
|
|
/* la %bfp,STK_160_UNUSED(%r15) (BPF frame pointer) */
|
|
EMIT4_DISP(0x41000000, BPF_REG_FP, REG_15, STK_160_UNUSED);
|
|
/* aghi %r15,-STK_OFF */
|
|
EMIT4_IMM(0xa70b0000, REG_15, -(STK_OFF + stack_depth));
|
|
- if (is_first_pass(jit) || (jit->seen & SEEN_FUNC))
|
|
- /* stg %w1,152(%r15) (backchain) */
|
|
- EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0,
|
|
- REG_15, 152);
|
|
+ /* stg %w1,152(%r15) (backchain) */
|
|
+ EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0,
|
|
+ REG_15, 152);
|
|
}
|
|
}
|
|
|
|
diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h
|
|
index bae83810505bf5..a541411d9226ef 100644
|
|
--- a/arch/x86/include/asm/mwait.h
|
|
+++ b/arch/x86/include/asm/mwait.h
|
|
@@ -108,13 +108,10 @@ static __always_inline void __sti_mwait(unsigned long eax, unsigned long ecx)
|
|
static __always_inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
|
|
{
|
|
if (static_cpu_has_bug(X86_BUG_MONITOR) || !current_set_polling_and_test()) {
|
|
- if (static_cpu_has_bug(X86_BUG_CLFLUSH_MONITOR)) {
|
|
- mb();
|
|
- clflush((void *)¤t_thread_info()->flags);
|
|
- mb();
|
|
- }
|
|
+ const void *addr = ¤t_thread_info()->flags;
|
|
|
|
- __monitor((void *)¤t_thread_info()->flags, 0, 0);
|
|
+ alternative_input("", "clflush (%[addr])", X86_BUG_CLFLUSH_MONITOR, [addr] "a" (addr));
|
|
+ __monitor(addr, 0, 0);
|
|
|
|
if (!need_resched()) {
|
|
if (ecx & 1) {
|
|
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
|
|
index 067e31fb9e165d..b6e43dad577a3c 100644
|
|
--- a/arch/x86/kernel/cpu/common.c
|
|
+++ b/arch/x86/kernel/cpu/common.c
|
|
@@ -1066,17 +1066,18 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
|
|
c->x86_capability[CPUID_D_1_EAX] = eax;
|
|
}
|
|
|
|
- /* AMD-defined flags: level 0x80000001 */
|
|
+ /*
|
|
+ * Check if extended CPUID leaves are implemented: Max extended
|
|
+ * CPUID leaf must be in the 0x80000001-0x8000ffff range.
|
|
+ */
|
|
eax = cpuid_eax(0x80000000);
|
|
- c->extended_cpuid_level = eax;
|
|
+ c->extended_cpuid_level = ((eax & 0xffff0000) == 0x80000000) ? eax : 0;
|
|
|
|
- if ((eax & 0xffff0000) == 0x80000000) {
|
|
- if (eax >= 0x80000001) {
|
|
- cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
|
|
+ if (c->extended_cpuid_level >= 0x80000001) {
|
|
+ cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
|
|
|
|
- c->x86_capability[CPUID_8000_0001_ECX] = ecx;
|
|
- c->x86_capability[CPUID_8000_0001_EDX] = edx;
|
|
- }
|
|
+ c->x86_capability[CPUID_8000_0001_ECX] = ecx;
|
|
+ c->x86_capability[CPUID_8000_0001_EDX] = edx;
|
|
}
|
|
|
|
if (c->extended_cpuid_level >= 0x80000007) {
|
|
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
|
|
index 5b47c320f17a6d..fc539346599cb1 100644
|
|
--- a/arch/x86/kernel/cpu/microcode/core.c
|
|
+++ b/arch/x86/kernel/cpu/microcode/core.c
|
|
@@ -703,6 +703,8 @@ static int load_late_locked(void)
|
|
return load_late_stop_cpus(true);
|
|
case UCODE_NFOUND:
|
|
return -ENOENT;
|
|
+ case UCODE_OK:
|
|
+ return 0;
|
|
default:
|
|
return -EBADFD;
|
|
}
|
|
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
|
|
index 2d6aa5d2e3d77e..6839440a4b31e3 100644
|
|
--- a/arch/x86/kernel/cpu/mtrr/generic.c
|
|
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
|
|
@@ -582,7 +582,7 @@ static void get_fixed_ranges(mtrr_type *frs)
|
|
|
|
void mtrr_save_fixed_ranges(void *info)
|
|
{
|
|
- if (boot_cpu_has(X86_FEATURE_MTRR))
|
|
+ if (mtrr_state.have_fixed)
|
|
get_fixed_ranges(mtrr_state.fixed_ranges);
|
|
}
|
|
|
|
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
|
|
index e2fab3ceb09fb7..9a101150376db7 100644
|
|
--- a/arch/x86/kernel/ioport.c
|
|
+++ b/arch/x86/kernel/ioport.c
|
|
@@ -33,8 +33,9 @@ void io_bitmap_share(struct task_struct *tsk)
|
|
set_tsk_thread_flag(tsk, TIF_IO_BITMAP);
|
|
}
|
|
|
|
-static void task_update_io_bitmap(struct task_struct *tsk)
|
|
+static void task_update_io_bitmap(void)
|
|
{
|
|
+ struct task_struct *tsk = current;
|
|
struct thread_struct *t = &tsk->thread;
|
|
|
|
if (t->iopl_emul == 3 || t->io_bitmap) {
|
|
@@ -54,7 +55,12 @@ void io_bitmap_exit(struct task_struct *tsk)
|
|
struct io_bitmap *iobm = tsk->thread.io_bitmap;
|
|
|
|
tsk->thread.io_bitmap = NULL;
|
|
- task_update_io_bitmap(tsk);
|
|
+ /*
|
|
+ * Don't touch the TSS when invoked on a failed fork(). TSS
|
|
+ * reflects the state of @current and not the state of @tsk.
|
|
+ */
|
|
+ if (tsk == current)
|
|
+ task_update_io_bitmap();
|
|
if (iobm && refcount_dec_and_test(&iobm->refcnt))
|
|
kfree(iobm);
|
|
}
|
|
@@ -192,8 +198,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
|
|
}
|
|
|
|
t->iopl_emul = level;
|
|
- task_update_io_bitmap(current);
|
|
-
|
|
+ task_update_io_bitmap();
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
|
|
index 419353904173ff..33c235e9d0d3fb 100644
|
|
--- a/arch/x86/kernel/process.c
|
|
+++ b/arch/x86/kernel/process.c
|
|
@@ -180,6 +180,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
|
|
frame->ret_addr = (unsigned long) ret_from_fork_asm;
|
|
p->thread.sp = (unsigned long) fork_frame;
|
|
p->thread.io_bitmap = NULL;
|
|
+ clear_tsk_thread_flag(p, TIF_IO_BITMAP);
|
|
p->thread.iopl_warn = 0;
|
|
memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
|
|
|
|
@@ -468,6 +469,11 @@ void native_tss_update_io_bitmap(void)
|
|
} else {
|
|
struct io_bitmap *iobm = t->io_bitmap;
|
|
|
|
+ if (WARN_ON_ONCE(!iobm)) {
|
|
+ clear_thread_flag(TIF_IO_BITMAP);
|
|
+ native_tss_invalidate_io_bitmap();
|
|
+ }
|
|
+
|
|
/*
|
|
* Only copy bitmap data when the sequence number differs. The
|
|
* update time is accounted to the incoming task.
|
|
@@ -923,13 +929,10 @@ static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c)
|
|
static __cpuidle void mwait_idle(void)
|
|
{
|
|
if (!current_set_polling_and_test()) {
|
|
- if (this_cpu_has(X86_BUG_CLFLUSH_MONITOR)) {
|
|
- mb(); /* quirk */
|
|
- clflush((void *)¤t_thread_info()->flags);
|
|
- mb(); /* quirk */
|
|
- }
|
|
+ const void *addr = ¤t_thread_info()->flags;
|
|
|
|
- __monitor((void *)¤t_thread_info()->flags, 0, 0);
|
|
+ alternative_input("", "clflush (%[addr])", X86_BUG_CLFLUSH_MONITOR, [addr] "a" (addr));
|
|
+ __monitor(addr, 0, 0);
|
|
if (!need_resched()) {
|
|
__sti_mwait(0, 0);
|
|
raw_local_irq_disable();
|
|
diff --git a/crypto/lrw.c b/crypto/lrw.c
|
|
index 59260aefed2807..5536ec7bf18f14 100644
|
|
--- a/crypto/lrw.c
|
|
+++ b/crypto/lrw.c
|
|
@@ -322,7 +322,7 @@ static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb)
|
|
|
|
err = crypto_grab_skcipher(spawn, skcipher_crypto_instance(inst),
|
|
cipher_name, 0, mask);
|
|
- if (err == -ENOENT) {
|
|
+ if (err == -ENOENT && memcmp(cipher_name, "ecb(", 4)) {
|
|
err = -ENAMETOOLONG;
|
|
if (snprintf(ecb_name, CRYPTO_MAX_ALG_NAME, "ecb(%s)",
|
|
cipher_name) >= CRYPTO_MAX_ALG_NAME)
|
|
@@ -356,7 +356,7 @@ static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb)
|
|
/* Alas we screwed up the naming so we have to mangle the
|
|
* cipher name.
|
|
*/
|
|
- if (!strncmp(cipher_name, "ecb(", 4)) {
|
|
+ if (!memcmp(cipher_name, "ecb(", 4)) {
|
|
int len;
|
|
|
|
len = strscpy(ecb_name, cipher_name + 4, sizeof(ecb_name));
|
|
diff --git a/crypto/xts.c b/crypto/xts.c
|
|
index 038f60dd512d9f..97fd0fb8757c23 100644
|
|
--- a/crypto/xts.c
|
|
+++ b/crypto/xts.c
|
|
@@ -363,7 +363,7 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb)
|
|
|
|
err = crypto_grab_skcipher(&ctx->spawn, skcipher_crypto_instance(inst),
|
|
cipher_name, 0, mask);
|
|
- if (err == -ENOENT) {
|
|
+ if (err == -ENOENT && memcmp(cipher_name, "ecb(", 4)) {
|
|
err = -ENAMETOOLONG;
|
|
if (snprintf(name, CRYPTO_MAX_ALG_NAME, "ecb(%s)",
|
|
cipher_name) >= CRYPTO_MAX_ALG_NAME)
|
|
@@ -397,7 +397,7 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb)
|
|
/* Alas we screwed up the naming so we have to mangle the
|
|
* cipher name.
|
|
*/
|
|
- if (!strncmp(cipher_name, "ecb(", 4)) {
|
|
+ if (!memcmp(cipher_name, "ecb(", 4)) {
|
|
int len;
|
|
|
|
len = strscpy(name, cipher_name + 4, sizeof(name));
|
|
diff --git a/drivers/acpi/acpica/exserial.c b/drivers/acpi/acpica/exserial.c
|
|
index 5241f4c01c7655..89a4ac447a2bea 100644
|
|
--- a/drivers/acpi/acpica/exserial.c
|
|
+++ b/drivers/acpi/acpica/exserial.c
|
|
@@ -201,6 +201,12 @@ acpi_ex_read_serial_bus(union acpi_operand_object *obj_desc,
|
|
function = ACPI_READ;
|
|
break;
|
|
|
|
+ case ACPI_ADR_SPACE_FIXED_HARDWARE:
|
|
+
|
|
+ buffer_length = ACPI_FFH_INPUT_BUFFER_SIZE;
|
|
+ function = ACPI_READ;
|
|
+ break;
|
|
+
|
|
default:
|
|
return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
|
|
}
|
|
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
|
|
index 6b18f8bc7be353..71e0d64a7792e9 100644
|
|
--- a/drivers/acpi/apei/Kconfig
|
|
+++ b/drivers/acpi/apei/Kconfig
|
|
@@ -23,6 +23,7 @@ config ACPI_APEI_GHES
|
|
select ACPI_HED
|
|
select IRQ_WORK
|
|
select GENERIC_ALLOCATOR
|
|
+ select ARM_SDE_INTERFACE if ARM64
|
|
help
|
|
Generic Hardware Error Source provides a way to report
|
|
platform hardware errors (such as that from chipset). It
|
|
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
|
|
index 3aadc632d7dd53..2abf20736702c0 100644
|
|
--- a/drivers/acpi/apei/ghes.c
|
|
+++ b/drivers/acpi/apei/ghes.c
|
|
@@ -1523,7 +1523,7 @@ void __init acpi_ghes_init(void)
|
|
{
|
|
int rc;
|
|
|
|
- sdei_init();
|
|
+ acpi_sdei_init();
|
|
|
|
if (acpi_disabled)
|
|
return;
|
|
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
|
|
index ed02a2a9970aa3..10d531427ba77d 100644
|
|
--- a/drivers/acpi/cppc_acpi.c
|
|
+++ b/drivers/acpi/cppc_acpi.c
|
|
@@ -461,7 +461,7 @@ bool cppc_allow_fast_switch(void)
|
|
struct cpc_desc *cpc_ptr;
|
|
int cpu;
|
|
|
|
- for_each_possible_cpu(cpu) {
|
|
+ for_each_present_cpu(cpu) {
|
|
cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
|
|
desired_reg = &cpc_ptr->cpc_regs[DESIRED_PERF];
|
|
if (!CPC_IN_SYSTEM_MEMORY(desired_reg) &&
|
|
diff --git a/drivers/acpi/osi.c b/drivers/acpi/osi.c
|
|
index d4405e1ca9b971..ae9620757865b1 100644
|
|
--- a/drivers/acpi/osi.c
|
|
+++ b/drivers/acpi/osi.c
|
|
@@ -42,7 +42,6 @@ static struct acpi_osi_entry
|
|
osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = {
|
|
{"Module Device", true},
|
|
{"Processor Device", true},
|
|
- {"3.0 _SCP Extensions", true},
|
|
{"Processor Aggregator Device", true},
|
|
};
|
|
|
|
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
|
|
index d9d339b8b57108..d1dae47f3534b8 100644
|
|
--- a/drivers/base/power/domain.c
|
|
+++ b/drivers/base/power/domain.c
|
|
@@ -2856,7 +2856,7 @@ struct device *genpd_dev_pm_attach_by_id(struct device *dev,
|
|
/* Verify that the index is within a valid range. */
|
|
num_domains = of_count_phandle_with_args(dev->of_node, "power-domains",
|
|
"#power-domain-cells");
|
|
- if (index >= num_domains)
|
|
+ if (num_domains < 0 || index >= num_domains)
|
|
return NULL;
|
|
|
|
/* Allocate and register device on the genpd bus. */
|
|
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
|
|
index 343d3c966e7a7b..baa31194cf20d5 100644
|
|
--- a/drivers/base/power/main.c
|
|
+++ b/drivers/base/power/main.c
|
|
@@ -897,6 +897,8 @@ static void __device_resume(struct device *dev, pm_message_t state, bool async)
|
|
if (!dev->power.is_suspended)
|
|
goto Complete;
|
|
|
|
+ dev->power.is_suspended = false;
|
|
+
|
|
if (dev->power.direct_complete) {
|
|
/* Match the pm_runtime_disable() in __device_suspend(). */
|
|
pm_runtime_enable(dev);
|
|
@@ -952,7 +954,6 @@ static void __device_resume(struct device *dev, pm_message_t state, bool async)
|
|
|
|
End:
|
|
error = dpm_run_callback(callback, dev, state, info);
|
|
- dev->power.is_suspended = false;
|
|
|
|
device_unlock(dev);
|
|
dpm_watchdog_clear(&wd);
|
|
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
|
|
index 7a552387129ef0..9c6f79d8605329 100644
|
|
--- a/drivers/bluetooth/hci_qca.c
|
|
+++ b/drivers/bluetooth/hci_qca.c
|
|
@@ -2307,14 +2307,14 @@ static int qca_serdev_probe(struct serdev_device *serdev)
|
|
|
|
qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
|
|
GPIOD_OUT_LOW);
|
|
- if (IS_ERR(qcadev->bt_en) &&
|
|
- (data->soc_type == QCA_WCN6750 ||
|
|
- data->soc_type == QCA_WCN6855)) {
|
|
- dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n");
|
|
- return PTR_ERR(qcadev->bt_en);
|
|
- }
|
|
+ if (IS_ERR(qcadev->bt_en))
|
|
+ return dev_err_probe(&serdev->dev,
|
|
+ PTR_ERR(qcadev->bt_en),
|
|
+ "failed to acquire BT_EN gpio\n");
|
|
|
|
- if (!qcadev->bt_en)
|
|
+ if (!qcadev->bt_en &&
|
|
+ (data->soc_type == QCA_WCN6750 ||
|
|
+ data->soc_type == QCA_WCN6855))
|
|
power_ctrl_enabled = false;
|
|
|
|
qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl",
|
|
diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
|
|
index 2f6d5002e43d58..b405ee330af1fc 100644
|
|
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
|
|
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
|
|
@@ -905,8 +905,10 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
|
|
|
|
error_cleanup_dev:
|
|
kfree(mc_dev->regions);
|
|
- kfree(mc_bus);
|
|
- kfree(mc_dev);
|
|
+ if (mc_bus)
|
|
+ kfree(mc_bus);
|
|
+ else
|
|
+ kfree(mc_dev);
|
|
|
|
return error;
|
|
}
|
|
diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
|
|
index 4d411408e4afef..cc4ca336ac13a3 100644
|
|
--- a/drivers/clk/bcm/clk-raspberrypi.c
|
|
+++ b/drivers/clk/bcm/clk-raspberrypi.c
|
|
@@ -271,6 +271,8 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
|
|
init.name = devm_kasprintf(rpi->dev, GFP_KERNEL,
|
|
"fw-clk-%s",
|
|
rpi_firmware_clk_names[id]);
|
|
+ if (!init.name)
|
|
+ return ERR_PTR(-ENOMEM);
|
|
init.ops = &raspberrypi_firmware_clk_ops;
|
|
init.flags = CLK_GET_RATE_NOCACHE;
|
|
|
|
diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c
|
|
index acba9f99d960c7..eca36bd3ba5c94 100644
|
|
--- a/drivers/clk/qcom/camcc-sm6350.c
|
|
+++ b/drivers/clk/qcom/camcc-sm6350.c
|
|
@@ -1694,6 +1694,9 @@ static struct clk_branch camcc_sys_tmr_clk = {
|
|
|
|
static struct gdsc bps_gdsc = {
|
|
.gdscr = 0x6004,
|
|
+ .en_rest_wait_val = 0x2,
|
|
+ .en_few_wait_val = 0x2,
|
|
+ .clk_dis_wait_val = 0xf,
|
|
.pd = {
|
|
.name = "bps_gdsc",
|
|
},
|
|
@@ -1703,6 +1706,9 @@ static struct gdsc bps_gdsc = {
|
|
|
|
static struct gdsc ipe_0_gdsc = {
|
|
.gdscr = 0x7004,
|
|
+ .en_rest_wait_val = 0x2,
|
|
+ .en_few_wait_val = 0x2,
|
|
+ .clk_dis_wait_val = 0xf,
|
|
.pd = {
|
|
.name = "ipe_0_gdsc",
|
|
},
|
|
@@ -1712,6 +1718,9 @@ static struct gdsc ipe_0_gdsc = {
|
|
|
|
static struct gdsc ife_0_gdsc = {
|
|
.gdscr = 0x9004,
|
|
+ .en_rest_wait_val = 0x2,
|
|
+ .en_few_wait_val = 0x2,
|
|
+ .clk_dis_wait_val = 0xf,
|
|
.pd = {
|
|
.name = "ife_0_gdsc",
|
|
},
|
|
@@ -1720,6 +1729,9 @@ static struct gdsc ife_0_gdsc = {
|
|
|
|
static struct gdsc ife_1_gdsc = {
|
|
.gdscr = 0xa004,
|
|
+ .en_rest_wait_val = 0x2,
|
|
+ .en_few_wait_val = 0x2,
|
|
+ .clk_dis_wait_val = 0xf,
|
|
.pd = {
|
|
.name = "ife_1_gdsc",
|
|
},
|
|
@@ -1728,6 +1740,9 @@ static struct gdsc ife_1_gdsc = {
|
|
|
|
static struct gdsc ife_2_gdsc = {
|
|
.gdscr = 0xb004,
|
|
+ .en_rest_wait_val = 0x2,
|
|
+ .en_few_wait_val = 0x2,
|
|
+ .clk_dis_wait_val = 0xf,
|
|
.pd = {
|
|
.name = "ife_2_gdsc",
|
|
},
|
|
@@ -1736,6 +1751,9 @@ static struct gdsc ife_2_gdsc = {
|
|
|
|
static struct gdsc titan_top_gdsc = {
|
|
.gdscr = 0x14004,
|
|
+ .en_rest_wait_val = 0x2,
|
|
+ .en_few_wait_val = 0x2,
|
|
+ .clk_dis_wait_val = 0xf,
|
|
.pd = {
|
|
.name = "titan_top_gdsc",
|
|
},
|
|
diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c
|
|
index ddacb4f76eca5f..ea98a63746f0f1 100644
|
|
--- a/drivers/clk/qcom/dispcc-sm6350.c
|
|
+++ b/drivers/clk/qcom/dispcc-sm6350.c
|
|
@@ -680,6 +680,9 @@ static struct clk_branch disp_cc_xo_clk = {
|
|
|
|
static struct gdsc mdss_gdsc = {
|
|
.gdscr = 0x1004,
|
|
+ .en_rest_wait_val = 0x2,
|
|
+ .en_few_wait_val = 0x2,
|
|
+ .clk_dis_wait_val = 0xf,
|
|
.pd = {
|
|
.name = "mdss_gdsc",
|
|
},
|
|
diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c
|
|
index b45f97c07eeb6f..e4a44377b75f74 100644
|
|
--- a/drivers/clk/qcom/gcc-msm8939.c
|
|
+++ b/drivers/clk/qcom/gcc-msm8939.c
|
|
@@ -432,7 +432,7 @@ static const struct parent_map gcc_xo_gpll0_gpll1a_gpll6_sleep_map[] = {
|
|
{ P_XO, 0 },
|
|
{ P_GPLL0, 1 },
|
|
{ P_GPLL1_AUX, 2 },
|
|
- { P_GPLL6, 2 },
|
|
+ { P_GPLL6, 3 },
|
|
{ P_SLEEP_CLK, 6 },
|
|
};
|
|
|
|
@@ -1100,7 +1100,7 @@ static struct clk_rcg2 jpeg0_clk_src = {
|
|
};
|
|
|
|
static const struct freq_tbl ftbl_gcc_camss_mclk0_1_clk[] = {
|
|
- F(24000000, P_GPLL0, 1, 1, 45),
|
|
+ F(24000000, P_GPLL6, 1, 1, 45),
|
|
F(66670000, P_GPLL0, 12, 0, 0),
|
|
{ }
|
|
};
|
|
diff --git a/drivers/clk/qcom/gcc-sm6350.c b/drivers/clk/qcom/gcc-sm6350.c
|
|
index 428cd99dcdcbe5..4031613c6236fb 100644
|
|
--- a/drivers/clk/qcom/gcc-sm6350.c
|
|
+++ b/drivers/clk/qcom/gcc-sm6350.c
|
|
@@ -2320,6 +2320,9 @@ static struct clk_branch gcc_video_xo_clk = {
|
|
|
|
static struct gdsc usb30_prim_gdsc = {
|
|
.gdscr = 0x1a004,
|
|
+ .en_rest_wait_val = 0x2,
|
|
+ .en_few_wait_val = 0x2,
|
|
+ .clk_dis_wait_val = 0xf,
|
|
.pd = {
|
|
.name = "usb30_prim_gdsc",
|
|
},
|
|
@@ -2328,6 +2331,9 @@ static struct gdsc usb30_prim_gdsc = {
|
|
|
|
static struct gdsc ufs_phy_gdsc = {
|
|
.gdscr = 0x3a004,
|
|
+ .en_rest_wait_val = 0x2,
|
|
+ .en_few_wait_val = 0x2,
|
|
+ .clk_dis_wait_val = 0xf,
|
|
.pd = {
|
|
.name = "ufs_phy_gdsc",
|
|
},
|
|
diff --git a/drivers/clk/qcom/gpucc-sm6350.c b/drivers/clk/qcom/gpucc-sm6350.c
|
|
index 0bcbba2a294365..86c8ad5b55bac4 100644
|
|
--- a/drivers/clk/qcom/gpucc-sm6350.c
|
|
+++ b/drivers/clk/qcom/gpucc-sm6350.c
|
|
@@ -412,6 +412,9 @@ static struct clk_branch gpu_cc_gx_vsense_clk = {
|
|
static struct gdsc gpu_cx_gdsc = {
|
|
.gdscr = 0x106c,
|
|
.gds_hw_ctrl = 0x1540,
|
|
+ .en_rest_wait_val = 0x2,
|
|
+ .en_few_wait_val = 0x2,
|
|
+ .clk_dis_wait_val = 0x8,
|
|
.pd = {
|
|
.name = "gpu_cx_gdsc",
|
|
},
|
|
@@ -422,6 +425,9 @@ static struct gdsc gpu_cx_gdsc = {
|
|
static struct gdsc gpu_gx_gdsc = {
|
|
.gdscr = 0x100c,
|
|
.clamp_io_ctrl = 0x1508,
|
|
+ .en_rest_wait_val = 0x2,
|
|
+ .en_few_wait_val = 0x2,
|
|
+ .clk_dis_wait_val = 0x2,
|
|
.pd = {
|
|
.name = "gpu_gx_gdsc",
|
|
.power_on = gdsc_gx_do_nothing_enable,
|
|
diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c
|
|
index 229473855c5b38..bc762ba87a19b6 100644
|
|
--- a/drivers/counter/interrupt-cnt.c
|
|
+++ b/drivers/counter/interrupt-cnt.c
|
|
@@ -3,12 +3,14 @@
|
|
* Copyright (c) 2021 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
|
|
*/
|
|
|
|
+#include <linux/cleanup.h>
|
|
#include <linux/counter.h>
|
|
#include <linux/gpio/consumer.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/irq.h>
|
|
#include <linux/mod_devicetable.h>
|
|
#include <linux/module.h>
|
|
+#include <linux/mutex.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/types.h>
|
|
|
|
@@ -19,6 +21,7 @@ struct interrupt_cnt_priv {
|
|
struct gpio_desc *gpio;
|
|
int irq;
|
|
bool enabled;
|
|
+ struct mutex lock;
|
|
struct counter_signal signals;
|
|
struct counter_synapse synapses;
|
|
struct counter_count cnts;
|
|
@@ -41,6 +44,8 @@ static int interrupt_cnt_enable_read(struct counter_device *counter,
|
|
{
|
|
struct interrupt_cnt_priv *priv = counter_priv(counter);
|
|
|
|
+ guard(mutex)(&priv->lock);
|
|
+
|
|
*enable = priv->enabled;
|
|
|
|
return 0;
|
|
@@ -51,6 +56,8 @@ static int interrupt_cnt_enable_write(struct counter_device *counter,
|
|
{
|
|
struct interrupt_cnt_priv *priv = counter_priv(counter);
|
|
|
|
+ guard(mutex)(&priv->lock);
|
|
+
|
|
if (priv->enabled == enable)
|
|
return 0;
|
|
|
|
@@ -227,6 +234,8 @@ static int interrupt_cnt_probe(struct platform_device *pdev)
|
|
if (ret)
|
|
return ret;
|
|
|
|
+ mutex_init(&priv->lock);
|
|
+
|
|
ret = devm_counter_add(dev, counter);
|
|
if (ret < 0)
|
|
return dev_err_probe(dev, ret, "Failed to add counter\n");
|
|
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
|
|
index 0615e7fa20ad7e..0bfced81cc17e1 100644
|
|
--- a/drivers/cpufreq/acpi-cpufreq.c
|
|
+++ b/drivers/cpufreq/acpi-cpufreq.c
|
|
@@ -659,7 +659,7 @@ static u64 get_max_boost_ratio(unsigned int cpu, u64 *nominal_freq)
|
|
nominal_perf = perf_caps.nominal_perf;
|
|
|
|
if (nominal_freq)
|
|
- *nominal_freq = perf_caps.nominal_freq;
|
|
+ *nominal_freq = perf_caps.nominal_freq * 1000;
|
|
|
|
if (!highest_perf || !nominal_perf) {
|
|
pr_debug("CPU%d: highest or nominal performance missing\n", cpu);
|
|
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
|
|
index d2cf9619018b1a..70434601f99bed 100644
|
|
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
|
|
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
|
|
@@ -275,13 +275,16 @@ static int sun8i_ce_cipher_prepare(struct crypto_engine *engine, void *async_req
|
|
} else {
|
|
if (nr_sgs > 0)
|
|
dma_unmap_sg(ce->dev, areq->src, ns, DMA_TO_DEVICE);
|
|
- dma_unmap_sg(ce->dev, areq->dst, nd, DMA_FROM_DEVICE);
|
|
+
|
|
+ if (nr_sgd > 0)
|
|
+ dma_unmap_sg(ce->dev, areq->dst, nd, DMA_FROM_DEVICE);
|
|
}
|
|
|
|
theend_iv:
|
|
if (areq->iv && ivsize > 0) {
|
|
- if (rctx->addr_iv)
|
|
+ if (!dma_mapping_error(ce->dev, rctx->addr_iv))
|
|
dma_unmap_single(ce->dev, rctx->addr_iv, rctx->ivlen, DMA_TO_DEVICE);
|
|
+
|
|
offset = areq->cryptlen - ivsize;
|
|
if (rctx->op_dir & CE_DECRYPTION) {
|
|
memcpy(areq->iv, chan->backup_iv, ivsize);
|
|
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
|
|
index d358334e598115..ebc857ed10e11e 100644
|
|
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
|
|
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
|
|
@@ -343,9 +343,8 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
|
u32 common;
|
|
u64 byte_count;
|
|
__le32 *bf;
|
|
- void *buf = NULL;
|
|
+ void *buf, *result;
|
|
int j, i, todo;
|
|
- void *result = NULL;
|
|
u64 bs;
|
|
int digestsize;
|
|
dma_addr_t addr_res, addr_pad;
|
|
@@ -365,14 +364,14 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
|
buf = kzalloc(bs * 2, GFP_KERNEL | GFP_DMA);
|
|
if (!buf) {
|
|
err = -ENOMEM;
|
|
- goto theend;
|
|
+ goto err_out;
|
|
}
|
|
bf = (__le32 *)buf;
|
|
|
|
result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA);
|
|
if (!result) {
|
|
err = -ENOMEM;
|
|
- goto theend;
|
|
+ goto err_free_buf;
|
|
}
|
|
|
|
flow = rctx->flow;
|
|
@@ -398,7 +397,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
|
if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
|
|
dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs);
|
|
err = -EINVAL;
|
|
- goto theend;
|
|
+ goto err_free_result;
|
|
}
|
|
|
|
len = areq->nbytes;
|
|
@@ -411,7 +410,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
|
if (len > 0) {
|
|
dev_err(ce->dev, "remaining len %d\n", len);
|
|
err = -EINVAL;
|
|
- goto theend;
|
|
+ goto err_unmap_src;
|
|
}
|
|
addr_res = dma_map_single(ce->dev, result, digestsize, DMA_FROM_DEVICE);
|
|
cet->t_dst[0].addr = cpu_to_le32(addr_res);
|
|
@@ -419,7 +418,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
|
if (dma_mapping_error(ce->dev, addr_res)) {
|
|
dev_err(ce->dev, "DMA map dest\n");
|
|
err = -EINVAL;
|
|
- goto theend;
|
|
+ goto err_unmap_src;
|
|
}
|
|
|
|
byte_count = areq->nbytes;
|
|
@@ -441,7 +440,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
|
}
|
|
if (!j) {
|
|
err = -EINVAL;
|
|
- goto theend;
|
|
+ goto err_unmap_result;
|
|
}
|
|
|
|
addr_pad = dma_map_single(ce->dev, buf, j * 4, DMA_TO_DEVICE);
|
|
@@ -450,7 +449,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
|
if (dma_mapping_error(ce->dev, addr_pad)) {
|
|
dev_err(ce->dev, "DMA error on padding SG\n");
|
|
err = -EINVAL;
|
|
- goto theend;
|
|
+ goto err_unmap_result;
|
|
}
|
|
|
|
if (ce->variant->hash_t_dlen_in_bits)
|
|
@@ -463,16 +462,25 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
|
err = sun8i_ce_run_task(ce, flow, crypto_ahash_alg_name(tfm));
|
|
|
|
dma_unmap_single(ce->dev, addr_pad, j * 4, DMA_TO_DEVICE);
|
|
- dma_unmap_sg(ce->dev, areq->src, ns, DMA_TO_DEVICE);
|
|
+
|
|
+err_unmap_result:
|
|
dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE);
|
|
+ if (!err)
|
|
+ memcpy(areq->result, result, algt->alg.hash.base.halg.digestsize);
|
|
|
|
+err_unmap_src:
|
|
+ dma_unmap_sg(ce->dev, areq->src, ns, DMA_TO_DEVICE);
|
|
|
|
- memcpy(areq->result, result, algt->alg.hash.base.halg.digestsize);
|
|
-theend:
|
|
- kfree(buf);
|
|
+err_free_result:
|
|
kfree(result);
|
|
+
|
|
+err_free_buf:
|
|
+ kfree(buf);
|
|
+
|
|
+err_out:
|
|
local_bh_disable();
|
|
crypto_finalize_hash_request(engine, breq, err);
|
|
local_bh_enable();
|
|
+
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
|
|
index 93d4985def87a7..65cc1278ee1555 100644
|
|
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
|
|
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
|
|
@@ -293,8 +293,8 @@ struct sun8i_ce_hash_tfm_ctx {
|
|
* @flow: the flow to use for this request
|
|
*/
|
|
struct sun8i_ce_hash_reqctx {
|
|
- struct ahash_request fallback_req;
|
|
int flow;
|
|
+ struct ahash_request fallback_req; // keep at the end
|
|
};
|
|
|
|
/*
|
|
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
|
|
index 7fa359725ec75f..9b18fb46a2c89f 100644
|
|
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
|
|
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
|
|
@@ -141,7 +141,7 @@ static int sun8i_ss_setup_ivs(struct skcipher_request *areq)
|
|
|
|
/* we need to copy all IVs from source in case DMA is bi-directionnal */
|
|
while (sg && len) {
|
|
- if (sg_dma_len(sg) == 0) {
|
|
+ if (sg->length == 0) {
|
|
sg = sg_next(sg);
|
|
continue;
|
|
}
|
|
diff --git a/drivers/crypto/marvell/cesa/cipher.c b/drivers/crypto/marvell/cesa/cipher.c
|
|
index 0f37dfd42d8509..3876e3ce822f44 100644
|
|
--- a/drivers/crypto/marvell/cesa/cipher.c
|
|
+++ b/drivers/crypto/marvell/cesa/cipher.c
|
|
@@ -459,6 +459,9 @@ static int mv_cesa_skcipher_queue_req(struct skcipher_request *req,
|
|
struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req);
|
|
struct mv_cesa_engine *engine;
|
|
|
|
+ if (!req->cryptlen)
|
|
+ return 0;
|
|
+
|
|
ret = mv_cesa_skcipher_req_init(req, tmpl);
|
|
if (ret)
|
|
return ret;
|
|
diff --git a/drivers/crypto/marvell/cesa/hash.c b/drivers/crypto/marvell/cesa/hash.c
|
|
index f150861ceaf695..6815eddc906812 100644
|
|
--- a/drivers/crypto/marvell/cesa/hash.c
|
|
+++ b/drivers/crypto/marvell/cesa/hash.c
|
|
@@ -663,7 +663,7 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
|
|
if (ret)
|
|
goto err_free_tdma;
|
|
|
|
- if (iter.src.sg) {
|
|
+ if (iter.base.len > iter.src.op_offset) {
|
|
/*
|
|
* Add all the new data, inserting an operation block and
|
|
* launch command between each full SRAM block-worth of
|
|
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
|
|
index 418e1774af1e5e..d99cf81358c54e 100644
|
|
--- a/drivers/dma/ti/k3-udma.c
|
|
+++ b/drivers/dma/ti/k3-udma.c
|
|
@@ -5537,7 +5537,8 @@ static int udma_probe(struct platform_device *pdev)
|
|
uc->config.dir = DMA_MEM_TO_MEM;
|
|
uc->name = devm_kasprintf(dev, GFP_KERNEL, "%s chan%d",
|
|
dev_name(dev), i);
|
|
-
|
|
+ if (!uc->name)
|
|
+ return -ENOMEM;
|
|
vchan_init(&uc->vc, &ud->ddev);
|
|
/* Use custom vchan completion handling */
|
|
tasklet_setup(&uc->vc.task, udma_vchan_complete);
|
|
diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c
|
|
index 67a46abe07da9e..068597e8fce95a 100644
|
|
--- a/drivers/edac/i10nm_base.c
|
|
+++ b/drivers/edac/i10nm_base.c
|
|
@@ -99,7 +99,7 @@ static u32 offsets_demand2_spr[] = {0x22c70, 0x22d80, 0x22f18, 0x22d58, 0x22c64,
|
|
static u32 offsets_demand_spr_hbm0[] = {0x2a54, 0x2a60, 0x2b10, 0x2a58, 0x2a5c, 0x0ee0};
|
|
static u32 offsets_demand_spr_hbm1[] = {0x2e54, 0x2e60, 0x2f10, 0x2e58, 0x2e5c, 0x0fb0};
|
|
|
|
-static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable,
|
|
+static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable, u32 *rrl_ctl,
|
|
u32 *offsets_scrub, u32 *offsets_demand,
|
|
u32 *offsets_demand2)
|
|
{
|
|
@@ -112,10 +112,10 @@ static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable
|
|
|
|
if (enable) {
|
|
/* Save default configurations */
|
|
- imc->chan[chan].retry_rd_err_log_s = s;
|
|
- imc->chan[chan].retry_rd_err_log_d = d;
|
|
+ rrl_ctl[0] = s;
|
|
+ rrl_ctl[1] = d;
|
|
if (offsets_demand2)
|
|
- imc->chan[chan].retry_rd_err_log_d2 = d2;
|
|
+ rrl_ctl[2] = d2;
|
|
|
|
s &= ~RETRY_RD_ERR_LOG_NOOVER_UC;
|
|
s |= RETRY_RD_ERR_LOG_EN;
|
|
@@ -129,25 +129,25 @@ static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable
|
|
}
|
|
} else {
|
|
/* Restore default configurations */
|
|
- if (imc->chan[chan].retry_rd_err_log_s & RETRY_RD_ERR_LOG_UC)
|
|
+ if (rrl_ctl[0] & RETRY_RD_ERR_LOG_UC)
|
|
s |= RETRY_RD_ERR_LOG_UC;
|
|
- if (imc->chan[chan].retry_rd_err_log_s & RETRY_RD_ERR_LOG_NOOVER)
|
|
+ if (rrl_ctl[0] & RETRY_RD_ERR_LOG_NOOVER)
|
|
s |= RETRY_RD_ERR_LOG_NOOVER;
|
|
- if (!(imc->chan[chan].retry_rd_err_log_s & RETRY_RD_ERR_LOG_EN))
|
|
+ if (!(rrl_ctl[0] & RETRY_RD_ERR_LOG_EN))
|
|
s &= ~RETRY_RD_ERR_LOG_EN;
|
|
- if (imc->chan[chan].retry_rd_err_log_d & RETRY_RD_ERR_LOG_UC)
|
|
+ if (rrl_ctl[1] & RETRY_RD_ERR_LOG_UC)
|
|
d |= RETRY_RD_ERR_LOG_UC;
|
|
- if (imc->chan[chan].retry_rd_err_log_d & RETRY_RD_ERR_LOG_NOOVER)
|
|
+ if (rrl_ctl[1] & RETRY_RD_ERR_LOG_NOOVER)
|
|
d |= RETRY_RD_ERR_LOG_NOOVER;
|
|
- if (!(imc->chan[chan].retry_rd_err_log_d & RETRY_RD_ERR_LOG_EN))
|
|
+ if (!(rrl_ctl[1] & RETRY_RD_ERR_LOG_EN))
|
|
d &= ~RETRY_RD_ERR_LOG_EN;
|
|
|
|
if (offsets_demand2) {
|
|
- if (imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_UC)
|
|
+ if (rrl_ctl[2] & RETRY_RD_ERR_LOG_UC)
|
|
d2 |= RETRY_RD_ERR_LOG_UC;
|
|
- if (!(imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_NOOVER))
|
|
+ if (!(rrl_ctl[2] & RETRY_RD_ERR_LOG_NOOVER))
|
|
d2 &= ~RETRY_RD_ERR_LOG_NOOVER;
|
|
- if (!(imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_EN))
|
|
+ if (!(rrl_ctl[2] & RETRY_RD_ERR_LOG_EN))
|
|
d2 &= ~RETRY_RD_ERR_LOG_EN;
|
|
}
|
|
}
|
|
@@ -161,6 +161,7 @@ static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable
|
|
static void enable_retry_rd_err_log(bool enable)
|
|
{
|
|
int i, j, imc_num, chan_num;
|
|
+ struct skx_channel *chan;
|
|
struct skx_imc *imc;
|
|
struct skx_dev *d;
|
|
|
|
@@ -175,8 +176,9 @@ static void enable_retry_rd_err_log(bool enable)
|
|
if (!imc->mbase)
|
|
continue;
|
|
|
|
+ chan = d->imc[i].chan;
|
|
for (j = 0; j < chan_num; j++)
|
|
- __enable_retry_rd_err_log(imc, j, enable,
|
|
+ __enable_retry_rd_err_log(imc, j, enable, chan[j].rrl_ctl[0],
|
|
res_cfg->offsets_scrub,
|
|
res_cfg->offsets_demand,
|
|
res_cfg->offsets_demand2);
|
|
@@ -190,12 +192,13 @@ static void enable_retry_rd_err_log(bool enable)
|
|
if (!imc->mbase || !imc->hbm_mc)
|
|
continue;
|
|
|
|
+ chan = d->imc[i].chan;
|
|
for (j = 0; j < chan_num; j++) {
|
|
- __enable_retry_rd_err_log(imc, j, enable,
|
|
+ __enable_retry_rd_err_log(imc, j, enable, chan[j].rrl_ctl[0],
|
|
res_cfg->offsets_scrub_hbm0,
|
|
res_cfg->offsets_demand_hbm0,
|
|
NULL);
|
|
- __enable_retry_rd_err_log(imc, j, enable,
|
|
+ __enable_retry_rd_err_log(imc, j, enable, chan[j].rrl_ctl[1],
|
|
res_cfg->offsets_scrub_hbm1,
|
|
res_cfg->offsets_demand_hbm1,
|
|
NULL);
|
|
diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c
|
|
index d47f0055217e43..9e43aed72bd9fa 100644
|
|
--- a/drivers/edac/skx_common.c
|
|
+++ b/drivers/edac/skx_common.c
|
|
@@ -115,6 +115,7 @@ EXPORT_SYMBOL_GPL(skx_adxl_get);
|
|
|
|
void skx_adxl_put(void)
|
|
{
|
|
+ adxl_component_count = 0;
|
|
kfree(adxl_values);
|
|
kfree(adxl_msg);
|
|
}
|
|
diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h
|
|
index 5acfef8fd3d362..2ea4d1d1fbef26 100644
|
|
--- a/drivers/edac/skx_common.h
|
|
+++ b/drivers/edac/skx_common.h
|
|
@@ -80,6 +80,9 @@
|
|
*/
|
|
#define MCACOD_EXT_MEM_ERR 0x280
|
|
|
|
+/* Max RRL register sets per {,sub-,pseudo-}channel. */
|
|
+#define NUM_RRL_SET 3
|
|
+
|
|
/*
|
|
* Each cpu socket contains some pci devices that provide global
|
|
* information, and also some that are local to each of the two
|
|
@@ -118,9 +121,11 @@ struct skx_dev {
|
|
struct skx_channel {
|
|
struct pci_dev *cdev;
|
|
struct pci_dev *edev;
|
|
- u32 retry_rd_err_log_s;
|
|
- u32 retry_rd_err_log_d;
|
|
- u32 retry_rd_err_log_d2;
|
|
+ /*
|
|
+ * Two groups of RRL control registers per channel to save default RRL
|
|
+ * settings of two {sub-,pseudo-}channels in Linux RRL control mode.
|
|
+ */
|
|
+ u32 rrl_ctl[2][NUM_RRL_SET];
|
|
struct skx_dimm {
|
|
u8 close_pg;
|
|
u8 bank_xor_enable;
|
|
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
|
|
index 3f2f22e47bfa1a..8ecffdce94b166 100644
|
|
--- a/drivers/firmware/Kconfig
|
|
+++ b/drivers/firmware/Kconfig
|
|
@@ -40,7 +40,6 @@ config ARM_SCPI_POWER_DOMAIN
|
|
config ARM_SDE_INTERFACE
|
|
bool "ARM Software Delegated Exception Interface (SDEI)"
|
|
depends on ARM64
|
|
- depends on ACPI_APEI_GHES
|
|
help
|
|
The Software Delegated Exception Interface (SDEI) is an ARM
|
|
standard for registering callbacks from the platform firmware
|
|
diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
|
|
index 3e8051fe829657..71e2a9a89f6ada 100644
|
|
--- a/drivers/firmware/arm_sdei.c
|
|
+++ b/drivers/firmware/arm_sdei.c
|
|
@@ -1062,13 +1062,12 @@ static bool __init sdei_present_acpi(void)
|
|
return true;
|
|
}
|
|
|
|
-void __init sdei_init(void)
|
|
+void __init acpi_sdei_init(void)
|
|
{
|
|
struct platform_device *pdev;
|
|
int ret;
|
|
|
|
- ret = platform_driver_register(&sdei_driver);
|
|
- if (ret || !sdei_present_acpi())
|
|
+ if (!sdei_present_acpi())
|
|
return;
|
|
|
|
pdev = platform_device_register_simple(sdei_driver.driver.name,
|
|
@@ -1081,6 +1080,12 @@ void __init sdei_init(void)
|
|
}
|
|
}
|
|
|
|
+static int __init sdei_init(void)
|
|
+{
|
|
+ return platform_driver_register(&sdei_driver);
|
|
+}
|
|
+arch_initcall(sdei_init);
|
|
+
|
|
int sdei_event_handler(struct pt_regs *regs,
|
|
struct sdei_registered_event *arg)
|
|
{
|
|
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
|
|
index 3dc2f9aaf08db0..492d09b6048bd5 100644
|
|
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
|
|
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
|
|
@@ -561,6 +561,7 @@ efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image,
|
|
* @image: EFI loaded image protocol
|
|
* @soft_limit: preferred address for loading the initrd
|
|
* @hard_limit: upper limit address for loading the initrd
|
|
+ * @out: pointer to store the address of the initrd table
|
|
*
|
|
* Return: status code
|
|
*/
|
|
diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
|
|
index 2328ca58bba61f..d6701d81cf6807 100644
|
|
--- a/drivers/firmware/psci/psci.c
|
|
+++ b/drivers/firmware/psci/psci.c
|
|
@@ -759,8 +759,10 @@ int __init psci_dt_init(void)
|
|
|
|
np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
|
|
|
|
- if (!np || !of_device_is_available(np))
|
|
+ if (!np || !of_device_is_available(np)) {
|
|
+ of_node_put(np);
|
|
return -ENODEV;
|
|
+ }
|
|
|
|
init_fn = (psci_initcall_t)matched_np->data;
|
|
ret = init_fn(np);
|
|
diff --git a/drivers/fpga/tests/fpga-mgr-test.c b/drivers/fpga/tests/fpga-mgr-test.c
|
|
index 6acec55b60ce9a..bfe25c0c0c1c38 100644
|
|
--- a/drivers/fpga/tests/fpga-mgr-test.c
|
|
+++ b/drivers/fpga/tests/fpga-mgr-test.c
|
|
@@ -253,6 +253,7 @@ static void fpga_mgr_test_img_load_sgt(struct kunit *test)
|
|
img_buf = init_test_buffer(test, IMAGE_SIZE);
|
|
|
|
sgt = kunit_kzalloc(test, sizeof(*sgt), GFP_KERNEL);
|
|
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sgt);
|
|
ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
|
|
KUNIT_ASSERT_EQ(test, ret, 0);
|
|
sg_init_one(sgt->sgl, img_buf, IMAGE_SIZE);
|
|
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
|
|
index 9189864c236a7e..d4edddaa23dd3e 100644
|
|
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
|
|
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
|
|
@@ -610,21 +610,15 @@ static void dm_crtc_high_irq(void *interrupt_params)
|
|
spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
|
|
|
|
if (acrtc->dm_irq_params.stream &&
|
|
- acrtc->dm_irq_params.vrr_params.supported) {
|
|
- bool replay_en = acrtc->dm_irq_params.stream->link->replay_settings.replay_feature_enabled;
|
|
- bool psr_en = acrtc->dm_irq_params.stream->link->psr_settings.psr_feature_enabled;
|
|
- bool fs_active_var_en = acrtc->dm_irq_params.freesync_config.state == VRR_STATE_ACTIVE_VARIABLE;
|
|
-
|
|
+ acrtc->dm_irq_params.vrr_params.supported &&
|
|
+ acrtc->dm_irq_params.freesync_config.state ==
|
|
+ VRR_STATE_ACTIVE_VARIABLE) {
|
|
mod_freesync_handle_v_update(adev->dm.freesync_module,
|
|
acrtc->dm_irq_params.stream,
|
|
&acrtc->dm_irq_params.vrr_params);
|
|
|
|
- /* update vmin_vmax only if freesync is enabled, or only if PSR and REPLAY are disabled */
|
|
- if (fs_active_var_en || (!fs_active_var_en && !replay_en && !psr_en)) {
|
|
- dc_stream_adjust_vmin_vmax(adev->dm.dc,
|
|
- acrtc->dm_irq_params.stream,
|
|
- &acrtc->dm_irq_params.vrr_params.adjust);
|
|
- }
|
|
+ dc_stream_adjust_vmin_vmax(adev->dm.dc, acrtc->dm_irq_params.stream,
|
|
+ &acrtc->dm_irq_params.vrr_params.adjust);
|
|
}
|
|
|
|
/*
|
|
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c
|
|
index 1fbd23922082ae..7e37354a03411d 100644
|
|
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c
|
|
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c
|
|
@@ -144,6 +144,10 @@ int atomctrl_initialize_mc_reg_table(
|
|
vram_info = (ATOM_VRAM_INFO_HEADER_V2_1 *)
|
|
smu_atom_get_data_table(hwmgr->adev,
|
|
GetIndexIntoMasterTable(DATA, VRAM_Info), &size, &frev, &crev);
|
|
+ if (!vram_info) {
|
|
+ pr_err("Could not retrieve the VramInfo table!");
|
|
+ return -EINVAL;
|
|
+ }
|
|
|
|
if (module_index >= vram_info->ucNumOfVRAMModule) {
|
|
pr_err("Invalid VramInfo table.");
|
|
@@ -181,6 +185,10 @@ int atomctrl_initialize_mc_reg_table_v2_2(
|
|
vram_info = (ATOM_VRAM_INFO_HEADER_V2_2 *)
|
|
smu_atom_get_data_table(hwmgr->adev,
|
|
GetIndexIntoMasterTable(DATA, VRAM_Info), &size, &frev, &crev);
|
|
+ if (!vram_info) {
|
|
+ pr_err("Could not retrieve the VramInfo table!");
|
|
+ return -EINVAL;
|
|
+ }
|
|
|
|
if (module_index >= vram_info->ucNumOfVRAMModule) {
|
|
pr_err("Invalid VramInfo table.");
|
|
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
|
|
index c41ffd0bc04941..d458a4f37ac8fa 100644
|
|
--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
|
|
+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
|
|
@@ -962,7 +962,11 @@ static int lt9611uxc_probe(struct i2c_client *client)
|
|
}
|
|
}
|
|
|
|
- return lt9611uxc_audio_init(dev, lt9611uxc);
|
|
+ ret = lt9611uxc_audio_init(dev, lt9611uxc);
|
|
+ if (ret)
|
|
+ goto err_remove_bridge;
|
|
+
|
|
+ return 0;
|
|
|
|
err_remove_bridge:
|
|
free_irq(client->irq, lt9611uxc);
|
|
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
|
|
index 8b41a07c3641f5..ef4fa70119de1a 100644
|
|
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
|
|
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
|
|
@@ -431,7 +431,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
|
|
|
|
ret = drmm_mode_config_init(drm);
|
|
if (ret)
|
|
- goto put_mutex_dev;
|
|
+ return ret;
|
|
|
|
drm->mode_config.min_width = 64;
|
|
drm->mode_config.min_height = 64;
|
|
@@ -449,8 +449,11 @@ static int mtk_drm_kms_init(struct drm_device *drm)
|
|
for (i = 0; i < private->data->mmsys_dev_num; i++) {
|
|
drm->dev_private = private->all_drm_private[i];
|
|
ret = component_bind_all(private->all_drm_private[i]->dev, drm);
|
|
- if (ret)
|
|
- goto put_mutex_dev;
|
|
+ if (ret) {
|
|
+ while (--i >= 0)
|
|
+ component_unbind_all(private->all_drm_private[i]->dev, drm);
|
|
+ return ret;
|
|
+ }
|
|
}
|
|
|
|
/*
|
|
@@ -532,9 +535,6 @@ static int mtk_drm_kms_init(struct drm_device *drm)
|
|
err_component_unbind:
|
|
for (i = 0; i < private->data->mmsys_dev_num; i++)
|
|
component_unbind_all(private->all_drm_private[i]->dev, drm);
|
|
-put_mutex_dev:
|
|
- for (i = 0; i < private->data->mmsys_dev_num; i++)
|
|
- put_device(private->all_drm_private[i]->mutex_dev);
|
|
|
|
return ret;
|
|
}
|
|
@@ -608,8 +608,10 @@ static int mtk_drm_bind(struct device *dev)
|
|
return 0;
|
|
|
|
drm = drm_dev_alloc(&mtk_drm_driver, dev);
|
|
- if (IS_ERR(drm))
|
|
- return PTR_ERR(drm);
|
|
+ if (IS_ERR(drm)) {
|
|
+ ret = PTR_ERR(drm);
|
|
+ goto err_put_dev;
|
|
+ }
|
|
|
|
private->drm_master = true;
|
|
drm->dev_private = private;
|
|
@@ -635,18 +637,31 @@ static int mtk_drm_bind(struct device *dev)
|
|
drm_dev_put(drm);
|
|
for (i = 0; i < private->data->mmsys_dev_num; i++)
|
|
private->all_drm_private[i]->drm = NULL;
|
|
+err_put_dev:
|
|
+ for (i = 0; i < private->data->mmsys_dev_num; i++) {
|
|
+ /* For device_find_child in mtk_drm_get_all_priv() */
|
|
+ put_device(private->all_drm_private[i]->dev);
|
|
+ }
|
|
+ put_device(private->mutex_dev);
|
|
return ret;
|
|
}
|
|
|
|
static void mtk_drm_unbind(struct device *dev)
|
|
{
|
|
struct mtk_drm_private *private = dev_get_drvdata(dev);
|
|
+ int i;
|
|
|
|
/* for multi mmsys dev, unregister drm dev in mmsys master */
|
|
if (private->drm_master) {
|
|
drm_dev_unregister(private->drm);
|
|
mtk_drm_kms_deinit(private->drm);
|
|
drm_dev_put(private->drm);
|
|
+
|
|
+ for (i = 0; i < private->data->mmsys_dev_num; i++) {
|
|
+ /* For device_find_child in mtk_drm_get_all_priv() */
|
|
+ put_device(private->all_drm_private[i]->dev);
|
|
+ }
|
|
+ put_device(private->mutex_dev);
|
|
}
|
|
private->mtk_drm_bound = false;
|
|
private->drm_master = false;
|
|
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
|
|
index 095f634ff7c799..27441e57163004 100644
|
|
--- a/drivers/gpu/drm/meson/meson_drv.c
|
|
+++ b/drivers/gpu/drm/meson/meson_drv.c
|
|
@@ -168,7 +168,7 @@ static const struct meson_drm_soc_attr meson_drm_soc_attrs[] = {
|
|
/* S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz */
|
|
{
|
|
.limits = {
|
|
- .max_hdmi_phy_freq = 1650000,
|
|
+ .max_hdmi_phy_freq = 1650000000,
|
|
},
|
|
.attrs = (const struct soc_device_attribute []) {
|
|
{ .soc_id = "GXL (S805*)", },
|
|
diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
|
|
index 3f9345c14f31c1..be4b0e4df6e13e 100644
|
|
--- a/drivers/gpu/drm/meson/meson_drv.h
|
|
+++ b/drivers/gpu/drm/meson/meson_drv.h
|
|
@@ -37,7 +37,7 @@ struct meson_drm_match_data {
|
|
};
|
|
|
|
struct meson_drm_soc_limits {
|
|
- unsigned int max_hdmi_phy_freq;
|
|
+ unsigned long long max_hdmi_phy_freq;
|
|
};
|
|
|
|
struct meson_drm {
|
|
diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
|
|
index c4686568c9ca5d..0b7e8e0ba4fc13 100644
|
|
--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
|
|
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
|
|
@@ -70,12 +70,12 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi,
|
|
{
|
|
struct meson_drm *priv = encoder_hdmi->priv;
|
|
int vic = drm_match_cea_mode(mode);
|
|
- unsigned int phy_freq;
|
|
- unsigned int vclk_freq;
|
|
- unsigned int venc_freq;
|
|
- unsigned int hdmi_freq;
|
|
+ unsigned long long phy_freq;
|
|
+ unsigned long long vclk_freq;
|
|
+ unsigned long long venc_freq;
|
|
+ unsigned long long hdmi_freq;
|
|
|
|
- vclk_freq = mode->clock;
|
|
+ vclk_freq = mode->clock * 1000ULL;
|
|
|
|
/* For 420, pixel clock is half unlike venc clock */
|
|
if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
|
|
@@ -107,7 +107,8 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi,
|
|
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
|
venc_freq /= 2;
|
|
|
|
- dev_dbg(priv->dev, "vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n",
|
|
+ dev_dbg(priv->dev,
|
|
+ "phy:%lluHz vclk=%lluHz venc=%lluHz hdmi=%lluHz enci=%d\n",
|
|
phy_freq, vclk_freq, venc_freq, hdmi_freq,
|
|
priv->venc.hdmi_use_enci);
|
|
|
|
@@ -122,10 +123,11 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri
|
|
struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);
|
|
struct meson_drm *priv = encoder_hdmi->priv;
|
|
bool is_hdmi2_sink = display_info->hdmi.scdc.supported;
|
|
- unsigned int phy_freq;
|
|
- unsigned int vclk_freq;
|
|
- unsigned int venc_freq;
|
|
- unsigned int hdmi_freq;
|
|
+ unsigned long long clock = mode->clock * 1000ULL;
|
|
+ unsigned long long phy_freq;
|
|
+ unsigned long long vclk_freq;
|
|
+ unsigned long long venc_freq;
|
|
+ unsigned long long hdmi_freq;
|
|
int vic = drm_match_cea_mode(mode);
|
|
enum drm_mode_status status;
|
|
|
|
@@ -144,12 +146,12 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri
|
|
if (status != MODE_OK)
|
|
return status;
|
|
|
|
- return meson_vclk_dmt_supported_freq(priv, mode->clock);
|
|
+ return meson_vclk_dmt_supported_freq(priv, clock);
|
|
/* Check against supported VIC modes */
|
|
} else if (!meson_venc_hdmi_supported_vic(vic))
|
|
return MODE_BAD;
|
|
|
|
- vclk_freq = mode->clock;
|
|
+ vclk_freq = clock;
|
|
|
|
/* For 420, pixel clock is half unlike venc clock */
|
|
if (drm_mode_is_420_only(display_info, mode) ||
|
|
@@ -179,7 +181,8 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri
|
|
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
|
venc_freq /= 2;
|
|
|
|
- dev_dbg(priv->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n",
|
|
+ dev_dbg(priv->dev,
|
|
+ "%s: vclk:%lluHz phy=%lluHz venc=%lluHz hdmi=%lluHz\n",
|
|
__func__, phy_freq, vclk_freq, venc_freq, hdmi_freq);
|
|
|
|
return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq);
|
|
diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
|
|
index 2a82119eb58ed8..dfe0c28a0f054c 100644
|
|
--- a/drivers/gpu/drm/meson/meson_vclk.c
|
|
+++ b/drivers/gpu/drm/meson/meson_vclk.c
|
|
@@ -110,7 +110,7 @@
|
|
#define HDMI_PLL_LOCK BIT(31)
|
|
#define HDMI_PLL_LOCK_G12A (3 << 30)
|
|
|
|
-#define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001)
|
|
+#define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST_ULL((_freq) * 1000ULL, 1001ULL)
|
|
|
|
/* VID PLL Dividers */
|
|
enum {
|
|
@@ -360,11 +360,11 @@ enum {
|
|
};
|
|
|
|
struct meson_vclk_params {
|
|
- unsigned int pll_freq;
|
|
- unsigned int phy_freq;
|
|
- unsigned int vclk_freq;
|
|
- unsigned int venc_freq;
|
|
- unsigned int pixel_freq;
|
|
+ unsigned long long pll_freq;
|
|
+ unsigned long long phy_freq;
|
|
+ unsigned long long vclk_freq;
|
|
+ unsigned long long venc_freq;
|
|
+ unsigned long long pixel_freq;
|
|
unsigned int pll_od1;
|
|
unsigned int pll_od2;
|
|
unsigned int pll_od3;
|
|
@@ -372,11 +372,11 @@ struct meson_vclk_params {
|
|
unsigned int vclk_div;
|
|
} params[] = {
|
|
[MESON_VCLK_HDMI_ENCI_54000] = {
|
|
- .pll_freq = 4320000,
|
|
- .phy_freq = 270000,
|
|
- .vclk_freq = 54000,
|
|
- .venc_freq = 54000,
|
|
- .pixel_freq = 54000,
|
|
+ .pll_freq = 4320000000,
|
|
+ .phy_freq = 270000000,
|
|
+ .vclk_freq = 54000000,
|
|
+ .venc_freq = 54000000,
|
|
+ .pixel_freq = 54000000,
|
|
.pll_od1 = 4,
|
|
.pll_od2 = 4,
|
|
.pll_od3 = 1,
|
|
@@ -384,11 +384,11 @@ struct meson_vclk_params {
|
|
.vclk_div = 1,
|
|
},
|
|
[MESON_VCLK_HDMI_DDR_54000] = {
|
|
- .pll_freq = 4320000,
|
|
- .phy_freq = 270000,
|
|
- .vclk_freq = 54000,
|
|
- .venc_freq = 54000,
|
|
- .pixel_freq = 27000,
|
|
+ .pll_freq = 4320000000,
|
|
+ .phy_freq = 270000000,
|
|
+ .vclk_freq = 54000000,
|
|
+ .venc_freq = 54000000,
|
|
+ .pixel_freq = 27000000,
|
|
.pll_od1 = 4,
|
|
.pll_od2 = 4,
|
|
.pll_od3 = 1,
|
|
@@ -396,11 +396,11 @@ struct meson_vclk_params {
|
|
.vclk_div = 1,
|
|
},
|
|
[MESON_VCLK_HDMI_DDR_148500] = {
|
|
- .pll_freq = 2970000,
|
|
- .phy_freq = 742500,
|
|
- .vclk_freq = 148500,
|
|
- .venc_freq = 148500,
|
|
- .pixel_freq = 74250,
|
|
+ .pll_freq = 2970000000,
|
|
+ .phy_freq = 742500000,
|
|
+ .vclk_freq = 148500000,
|
|
+ .venc_freq = 148500000,
|
|
+ .pixel_freq = 74250000,
|
|
.pll_od1 = 4,
|
|
.pll_od2 = 1,
|
|
.pll_od3 = 1,
|
|
@@ -408,11 +408,11 @@ struct meson_vclk_params {
|
|
.vclk_div = 1,
|
|
},
|
|
[MESON_VCLK_HDMI_74250] = {
|
|
- .pll_freq = 2970000,
|
|
- .phy_freq = 742500,
|
|
- .vclk_freq = 74250,
|
|
- .venc_freq = 74250,
|
|
- .pixel_freq = 74250,
|
|
+ .pll_freq = 2970000000,
|
|
+ .phy_freq = 742500000,
|
|
+ .vclk_freq = 74250000,
|
|
+ .venc_freq = 74250000,
|
|
+ .pixel_freq = 74250000,
|
|
.pll_od1 = 2,
|
|
.pll_od2 = 2,
|
|
.pll_od3 = 2,
|
|
@@ -420,11 +420,11 @@ struct meson_vclk_params {
|
|
.vclk_div = 1,
|
|
},
|
|
[MESON_VCLK_HDMI_148500] = {
|
|
- .pll_freq = 2970000,
|
|
- .phy_freq = 1485000,
|
|
- .vclk_freq = 148500,
|
|
- .venc_freq = 148500,
|
|
- .pixel_freq = 148500,
|
|
+ .pll_freq = 2970000000,
|
|
+ .phy_freq = 1485000000,
|
|
+ .vclk_freq = 148500000,
|
|
+ .venc_freq = 148500000,
|
|
+ .pixel_freq = 148500000,
|
|
.pll_od1 = 1,
|
|
.pll_od2 = 2,
|
|
.pll_od3 = 2,
|
|
@@ -432,11 +432,11 @@ struct meson_vclk_params {
|
|
.vclk_div = 1,
|
|
},
|
|
[MESON_VCLK_HDMI_297000] = {
|
|
- .pll_freq = 5940000,
|
|
- .phy_freq = 2970000,
|
|
- .venc_freq = 297000,
|
|
- .vclk_freq = 297000,
|
|
- .pixel_freq = 297000,
|
|
+ .pll_freq = 5940000000,
|
|
+ .phy_freq = 2970000000,
|
|
+ .venc_freq = 297000000,
|
|
+ .vclk_freq = 297000000,
|
|
+ .pixel_freq = 297000000,
|
|
.pll_od1 = 2,
|
|
.pll_od2 = 1,
|
|
.pll_od3 = 1,
|
|
@@ -444,11 +444,11 @@ struct meson_vclk_params {
|
|
.vclk_div = 2,
|
|
},
|
|
[MESON_VCLK_HDMI_594000] = {
|
|
- .pll_freq = 5940000,
|
|
- .phy_freq = 5940000,
|
|
- .venc_freq = 594000,
|
|
- .vclk_freq = 594000,
|
|
- .pixel_freq = 594000,
|
|
+ .pll_freq = 5940000000,
|
|
+ .phy_freq = 5940000000,
|
|
+ .venc_freq = 594000000,
|
|
+ .vclk_freq = 594000000,
|
|
+ .pixel_freq = 594000000,
|
|
.pll_od1 = 1,
|
|
.pll_od2 = 1,
|
|
.pll_od3 = 2,
|
|
@@ -456,11 +456,11 @@ struct meson_vclk_params {
|
|
.vclk_div = 1,
|
|
},
|
|
[MESON_VCLK_HDMI_594000_YUV420] = {
|
|
- .pll_freq = 5940000,
|
|
- .phy_freq = 2970000,
|
|
- .venc_freq = 594000,
|
|
- .vclk_freq = 594000,
|
|
- .pixel_freq = 297000,
|
|
+ .pll_freq = 5940000000,
|
|
+ .phy_freq = 2970000000,
|
|
+ .venc_freq = 594000000,
|
|
+ .vclk_freq = 594000000,
|
|
+ .pixel_freq = 297000000,
|
|
.pll_od1 = 2,
|
|
.pll_od2 = 1,
|
|
.pll_od3 = 1,
|
|
@@ -617,16 +617,16 @@ static void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m,
|
|
3 << 20, pll_od_to_reg(od3) << 20);
|
|
}
|
|
|
|
-#define XTAL_FREQ 24000
|
|
+#define XTAL_FREQ (24 * 1000 * 1000)
|
|
|
|
static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv,
|
|
- unsigned int pll_freq)
|
|
+ unsigned long long pll_freq)
|
|
{
|
|
/* The GXBB PLL has a /2 pre-multiplier */
|
|
if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
|
|
- pll_freq /= 2;
|
|
+ pll_freq = DIV_ROUND_DOWN_ULL(pll_freq, 2);
|
|
|
|
- return pll_freq / XTAL_FREQ;
|
|
+ return DIV_ROUND_DOWN_ULL(pll_freq, XTAL_FREQ);
|
|
}
|
|
|
|
#define HDMI_FRAC_MAX_GXBB 4096
|
|
@@ -635,12 +635,13 @@ static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv,
|
|
|
|
static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv,
|
|
unsigned int m,
|
|
- unsigned int pll_freq)
|
|
+ unsigned long long pll_freq)
|
|
{
|
|
- unsigned int parent_freq = XTAL_FREQ;
|
|
+ unsigned long long parent_freq = XTAL_FREQ;
|
|
unsigned int frac_max = HDMI_FRAC_MAX_GXL;
|
|
unsigned int frac_m;
|
|
unsigned int frac;
|
|
+ u32 remainder;
|
|
|
|
/* The GXBB PLL has a /2 pre-multiplier and a larger FRAC width */
|
|
if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
|
|
@@ -652,11 +653,11 @@ static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv,
|
|
frac_max = HDMI_FRAC_MAX_G12A;
|
|
|
|
/* We can have a perfect match !*/
|
|
- if (pll_freq / m == parent_freq &&
|
|
- pll_freq % m == 0)
|
|
+ if (div_u64_rem(pll_freq, m, &remainder) == parent_freq &&
|
|
+ remainder == 0)
|
|
return 0;
|
|
|
|
- frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq);
|
|
+ frac = mul_u64_u64_div_u64(pll_freq, frac_max, parent_freq);
|
|
frac_m = m * frac_max;
|
|
if (frac_m > frac)
|
|
return frac_max;
|
|
@@ -666,7 +667,7 @@ static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv,
|
|
}
|
|
|
|
static bool meson_hdmi_pll_validate_params(struct meson_drm *priv,
|
|
- unsigned int m,
|
|
+ unsigned long long m,
|
|
unsigned int frac)
|
|
{
|
|
if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
|
|
@@ -694,7 +695,7 @@ static bool meson_hdmi_pll_validate_params(struct meson_drm *priv,
|
|
}
|
|
|
|
static bool meson_hdmi_pll_find_params(struct meson_drm *priv,
|
|
- unsigned int freq,
|
|
+ unsigned long long freq,
|
|
unsigned int *m,
|
|
unsigned int *frac,
|
|
unsigned int *od)
|
|
@@ -706,7 +707,7 @@ static bool meson_hdmi_pll_find_params(struct meson_drm *priv,
|
|
continue;
|
|
*frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od);
|
|
|
|
- DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d\n",
|
|
+ DRM_DEBUG_DRIVER("PLL params for %lluHz: m=%x frac=%x od=%d\n",
|
|
freq, *m, *frac, *od);
|
|
|
|
if (meson_hdmi_pll_validate_params(priv, *m, *frac))
|
|
@@ -718,7 +719,7 @@ static bool meson_hdmi_pll_find_params(struct meson_drm *priv,
|
|
|
|
/* pll_freq is the frequency after the OD dividers */
|
|
enum drm_mode_status
|
|
-meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq)
|
|
+meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned long long freq)
|
|
{
|
|
unsigned int od, m, frac;
|
|
|
|
@@ -741,7 +742,7 @@ EXPORT_SYMBOL_GPL(meson_vclk_dmt_supported_freq);
|
|
|
|
/* pll_freq is the frequency after the OD dividers */
|
|
static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
|
|
- unsigned int pll_freq)
|
|
+ unsigned long long pll_freq)
|
|
{
|
|
unsigned int od, m, frac, od1, od2, od3;
|
|
|
|
@@ -756,7 +757,7 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
|
|
od1 = od / od2;
|
|
}
|
|
|
|
- DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n",
|
|
+ DRM_DEBUG_DRIVER("PLL params for %lluHz: m=%x frac=%x od=%d/%d/%d\n",
|
|
pll_freq, m, frac, od1, od2, od3);
|
|
|
|
meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
|
|
@@ -764,17 +765,48 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
|
|
return;
|
|
}
|
|
|
|
- DRM_ERROR("Fatal, unable to find parameters for PLL freq %d\n",
|
|
+ DRM_ERROR("Fatal, unable to find parameters for PLL freq %lluHz\n",
|
|
pll_freq);
|
|
}
|
|
|
|
+static bool meson_vclk_freqs_are_matching_param(unsigned int idx,
|
|
+ unsigned long long phy_freq,
|
|
+ unsigned long long vclk_freq)
|
|
+{
|
|
+ DRM_DEBUG_DRIVER("i = %d vclk_freq = %lluHz alt = %lluHz\n",
|
|
+ idx, params[idx].vclk_freq,
|
|
+ FREQ_1000_1001(params[idx].vclk_freq));
|
|
+ DRM_DEBUG_DRIVER("i = %d phy_freq = %lluHz alt = %lluHz\n",
|
|
+ idx, params[idx].phy_freq,
|
|
+ FREQ_1000_1001(params[idx].phy_freq));
|
|
+
|
|
+ /* Match strict frequency */
|
|
+ if (phy_freq == params[idx].phy_freq &&
|
|
+ vclk_freq == params[idx].vclk_freq)
|
|
+ return true;
|
|
+
|
|
+ /* Match 1000/1001 variant: vclk deviation has to be less than 1kHz
|
|
+ * (drm EDID is defined in 1kHz steps, so everything smaller must be
|
|
+ * rounding error) and the PHY freq deviation has to be less than
|
|
+ * 10kHz (as the TMDS clock is 10 times the pixel clock, so anything
|
|
+ * smaller must be rounding error as well).
|
|
+ */
|
|
+ if (abs(vclk_freq - FREQ_1000_1001(params[idx].vclk_freq)) < 1000 &&
|
|
+ abs(phy_freq - FREQ_1000_1001(params[idx].phy_freq)) < 10000)
|
|
+ return true;
|
|
+
|
|
+ /* no match */
|
|
+ return false;
|
|
+}
|
|
+
|
|
enum drm_mode_status
|
|
-meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq,
|
|
- unsigned int vclk_freq)
|
|
+meson_vclk_vic_supported_freq(struct meson_drm *priv,
|
|
+ unsigned long long phy_freq,
|
|
+ unsigned long long vclk_freq)
|
|
{
|
|
int i;
|
|
|
|
- DRM_DEBUG_DRIVER("phy_freq = %d vclk_freq = %d\n",
|
|
+ DRM_DEBUG_DRIVER("phy_freq = %lluHz vclk_freq = %lluHz\n",
|
|
phy_freq, vclk_freq);
|
|
|
|
/* Check against soc revision/package limits */
|
|
@@ -785,19 +817,7 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq,
|
|
}
|
|
|
|
for (i = 0 ; params[i].pixel_freq ; ++i) {
|
|
- DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n",
|
|
- i, params[i].pixel_freq,
|
|
- FREQ_1000_1001(params[i].pixel_freq));
|
|
- DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n",
|
|
- i, params[i].phy_freq,
|
|
- FREQ_1000_1001(params[i].phy_freq/10)*10);
|
|
- /* Match strict frequency */
|
|
- if (phy_freq == params[i].phy_freq &&
|
|
- vclk_freq == params[i].vclk_freq)
|
|
- return MODE_OK;
|
|
- /* Match 1000/1001 variant */
|
|
- if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) &&
|
|
- vclk_freq == FREQ_1000_1001(params[i].vclk_freq))
|
|
+ if (meson_vclk_freqs_are_matching_param(i, phy_freq, vclk_freq))
|
|
return MODE_OK;
|
|
}
|
|
|
|
@@ -805,8 +825,9 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq,
|
|
}
|
|
EXPORT_SYMBOL_GPL(meson_vclk_vic_supported_freq);
|
|
|
|
-static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
|
|
- unsigned int od1, unsigned int od2, unsigned int od3,
|
|
+static void meson_vclk_set(struct meson_drm *priv,
|
|
+ unsigned long long pll_base_freq, unsigned int od1,
|
|
+ unsigned int od2, unsigned int od3,
|
|
unsigned int vid_pll_div, unsigned int vclk_div,
|
|
unsigned int hdmi_tx_div, unsigned int venc_div,
|
|
bool hdmi_use_enci, bool vic_alternate_clock)
|
|
@@ -826,15 +847,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
|
|
meson_hdmi_pll_generic_set(priv, pll_base_freq);
|
|
} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
|
|
switch (pll_base_freq) {
|
|
- case 2970000:
|
|
+ case 2970000000:
|
|
m = 0x3d;
|
|
frac = vic_alternate_clock ? 0xd02 : 0xe00;
|
|
break;
|
|
- case 4320000:
|
|
+ case 4320000000:
|
|
m = vic_alternate_clock ? 0x59 : 0x5a;
|
|
frac = vic_alternate_clock ? 0xe8f : 0;
|
|
break;
|
|
- case 5940000:
|
|
+ case 5940000000:
|
|
m = 0x7b;
|
|
frac = vic_alternate_clock ? 0xa05 : 0xc00;
|
|
break;
|
|
@@ -844,15 +865,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
|
|
} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
|
|
meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
|
|
switch (pll_base_freq) {
|
|
- case 2970000:
|
|
+ case 2970000000:
|
|
m = 0x7b;
|
|
frac = vic_alternate_clock ? 0x281 : 0x300;
|
|
break;
|
|
- case 4320000:
|
|
+ case 4320000000:
|
|
m = vic_alternate_clock ? 0xb3 : 0xb4;
|
|
frac = vic_alternate_clock ? 0x347 : 0;
|
|
break;
|
|
- case 5940000:
|
|
+ case 5940000000:
|
|
m = 0xf7;
|
|
frac = vic_alternate_clock ? 0x102 : 0x200;
|
|
break;
|
|
@@ -861,15 +882,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
|
|
meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
|
|
} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
|
|
switch (pll_base_freq) {
|
|
- case 2970000:
|
|
+ case 2970000000:
|
|
m = 0x7b;
|
|
frac = vic_alternate_clock ? 0x140b4 : 0x18000;
|
|
break;
|
|
- case 4320000:
|
|
+ case 4320000000:
|
|
m = vic_alternate_clock ? 0xb3 : 0xb4;
|
|
frac = vic_alternate_clock ? 0x1a3ee : 0;
|
|
break;
|
|
- case 5940000:
|
|
+ case 5940000000:
|
|
m = 0xf7;
|
|
frac = vic_alternate_clock ? 0x8148 : 0x10000;
|
|
break;
|
|
@@ -1025,14 +1046,14 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
|
|
}
|
|
|
|
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
|
- unsigned int phy_freq, unsigned int vclk_freq,
|
|
- unsigned int venc_freq, unsigned int dac_freq,
|
|
+ unsigned long long phy_freq, unsigned long long vclk_freq,
|
|
+ unsigned long long venc_freq, unsigned long long dac_freq,
|
|
bool hdmi_use_enci)
|
|
{
|
|
bool vic_alternate_clock = false;
|
|
- unsigned int freq;
|
|
- unsigned int hdmi_tx_div;
|
|
- unsigned int venc_div;
|
|
+ unsigned long long freq;
|
|
+ unsigned long long hdmi_tx_div;
|
|
+ unsigned long long venc_div;
|
|
|
|
if (target == MESON_VCLK_TARGET_CVBS) {
|
|
meson_venci_cvbs_clock_config(priv);
|
|
@@ -1052,27 +1073,25 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
|
return;
|
|
}
|
|
|
|
- hdmi_tx_div = vclk_freq / dac_freq;
|
|
+ hdmi_tx_div = DIV_ROUND_DOWN_ULL(vclk_freq, dac_freq);
|
|
|
|
if (hdmi_tx_div == 0) {
|
|
- pr_err("Fatal Error, invalid HDMI-TX freq %d\n",
|
|
+ pr_err("Fatal Error, invalid HDMI-TX freq %lluHz\n",
|
|
dac_freq);
|
|
return;
|
|
}
|
|
|
|
- venc_div = vclk_freq / venc_freq;
|
|
+ venc_div = DIV_ROUND_DOWN_ULL(vclk_freq, venc_freq);
|
|
|
|
if (venc_div == 0) {
|
|
- pr_err("Fatal Error, invalid HDMI venc freq %d\n",
|
|
+ pr_err("Fatal Error, invalid HDMI venc freq %lluHz\n",
|
|
venc_freq);
|
|
return;
|
|
}
|
|
|
|
for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
|
|
- if ((phy_freq == params[freq].phy_freq ||
|
|
- phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) &&
|
|
- (vclk_freq == params[freq].vclk_freq ||
|
|
- vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) {
|
|
+ if (meson_vclk_freqs_are_matching_param(freq, phy_freq,
|
|
+ vclk_freq)) {
|
|
if (vclk_freq != params[freq].vclk_freq)
|
|
vic_alternate_clock = true;
|
|
else
|
|
@@ -1098,7 +1117,8 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
|
}
|
|
|
|
if (!params[freq].pixel_freq) {
|
|
- pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq);
|
|
+ pr_err("Fatal Error, invalid HDMI vclk freq %lluHz\n",
|
|
+ vclk_freq);
|
|
return;
|
|
}
|
|
|
|
diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h
|
|
index 60617aaf18dd1c..7ac55744e57494 100644
|
|
--- a/drivers/gpu/drm/meson/meson_vclk.h
|
|
+++ b/drivers/gpu/drm/meson/meson_vclk.h
|
|
@@ -20,17 +20,18 @@ enum {
|
|
};
|
|
|
|
/* 27MHz is the CVBS Pixel Clock */
|
|
-#define MESON_VCLK_CVBS 27000
|
|
+#define MESON_VCLK_CVBS (27 * 1000 * 1000)
|
|
|
|
enum drm_mode_status
|
|
-meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq);
|
|
+meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned long long freq);
|
|
enum drm_mode_status
|
|
-meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq,
|
|
- unsigned int vclk_freq);
|
|
+meson_vclk_vic_supported_freq(struct meson_drm *priv,
|
|
+ unsigned long long phy_freq,
|
|
+ unsigned long long vclk_freq);
|
|
|
|
void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
|
|
- unsigned int phy_freq, unsigned int vclk_freq,
|
|
- unsigned int venc_freq, unsigned int dac_freq,
|
|
+ unsigned long long phy_freq, unsigned long long vclk_freq,
|
|
+ unsigned long long venc_freq, unsigned long long dac_freq,
|
|
bool hdmi_use_enci);
|
|
|
|
#endif /* __MESON_VCLK_H */
|
|
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
|
|
index 70d8ad065bfa1d..4c8fe83dd6101b 100644
|
|
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
|
|
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
|
|
@@ -705,7 +705,7 @@ static int rcar_du_vsps_init(struct rcar_du_device *rcdu)
|
|
ret = of_parse_phandle_with_fixed_args(np, vsps_prop_name,
|
|
cells, i, &args);
|
|
if (ret < 0)
|
|
- goto error;
|
|
+ goto done;
|
|
|
|
/*
|
|
* Add the VSP to the list or update the corresponding existing
|
|
@@ -743,13 +743,11 @@ static int rcar_du_vsps_init(struct rcar_du_device *rcdu)
|
|
vsp->dev = rcdu;
|
|
|
|
ret = rcar_du_vsp_init(vsp, vsps[i].np, vsps[i].crtcs_mask);
|
|
- if (ret < 0)
|
|
- goto error;
|
|
+ if (ret)
|
|
+ goto done;
|
|
}
|
|
|
|
- return 0;
|
|
-
|
|
-error:
|
|
+done:
|
|
for (i = 0; i < ARRAY_SIZE(vsps); ++i)
|
|
of_node_put(vsps[i].np);
|
|
|
|
diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
|
|
index d6424abd3c45d3..8930460ba62823 100644
|
|
--- a/drivers/gpu/drm/tegra/rgb.c
|
|
+++ b/drivers/gpu/drm/tegra/rgb.c
|
|
@@ -190,6 +190,11 @@ static const struct drm_encoder_helper_funcs tegra_rgb_encoder_helper_funcs = {
|
|
.atomic_check = tegra_rgb_encoder_atomic_check,
|
|
};
|
|
|
|
+static void tegra_dc_of_node_put(void *data)
|
|
+{
|
|
+ of_node_put(data);
|
|
+}
|
|
+
|
|
int tegra_dc_rgb_probe(struct tegra_dc *dc)
|
|
{
|
|
struct device_node *np;
|
|
@@ -197,7 +202,14 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc)
|
|
int err;
|
|
|
|
np = of_get_child_by_name(dc->dev->of_node, "rgb");
|
|
- if (!np || !of_device_is_available(np))
|
|
+ if (!np)
|
|
+ return -ENODEV;
|
|
+
|
|
+ err = devm_add_action_or_reset(dc->dev, tegra_dc_of_node_put, np);
|
|
+ if (err < 0)
|
|
+ return err;
|
|
+
|
|
+ if (!of_device_is_available(np))
|
|
return -ENODEV;
|
|
|
|
rgb = devm_kzalloc(dc->dev, sizeof(*rgb), GFP_KERNEL);
|
|
diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_output.c b/drivers/gpu/drm/vc4/tests/vc4_mock_output.c
|
|
index e70d7c3076acf1..f0ddc223c1f839 100644
|
|
--- a/drivers/gpu/drm/vc4/tests/vc4_mock_output.c
|
|
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock_output.c
|
|
@@ -75,24 +75,30 @@ int vc4_mock_atomic_add_output(struct kunit *test,
|
|
int ret;
|
|
|
|
encoder = vc4_find_encoder_by_type(drm, type);
|
|
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder);
|
|
+ if (!encoder)
|
|
+ return -ENODEV;
|
|
|
|
crtc = vc4_find_crtc_for_encoder(test, drm, encoder);
|
|
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
|
|
+ if (!crtc)
|
|
+ return -ENODEV;
|
|
|
|
output = encoder_to_vc4_dummy_output(encoder);
|
|
conn = &output->connector;
|
|
conn_state = drm_atomic_get_connector_state(state, conn);
|
|
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
|
|
+ if (IS_ERR(conn_state))
|
|
+ return PTR_ERR(conn_state);
|
|
|
|
ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
|
|
- KUNIT_EXPECT_EQ(test, ret, 0);
|
|
+ if (ret)
|
|
+ return ret;
|
|
|
|
crtc_state = drm_atomic_get_crtc_state(state, crtc);
|
|
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
|
|
+ if (IS_ERR(crtc_state))
|
|
+ return PTR_ERR(crtc_state);
|
|
|
|
ret = drm_atomic_set_mode_for_crtc(crtc_state, &default_mode);
|
|
- KUNIT_EXPECT_EQ(test, ret, 0);
|
|
+ if (ret)
|
|
+ return ret;
|
|
|
|
crtc_state->active = true;
|
|
|
|
@@ -113,26 +119,32 @@ int vc4_mock_atomic_del_output(struct kunit *test,
|
|
int ret;
|
|
|
|
encoder = vc4_find_encoder_by_type(drm, type);
|
|
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder);
|
|
+ if (!encoder)
|
|
+ return -ENODEV;
|
|
|
|
crtc = vc4_find_crtc_for_encoder(test, drm, encoder);
|
|
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
|
|
+ if (!crtc)
|
|
+ return -ENODEV;
|
|
|
|
crtc_state = drm_atomic_get_crtc_state(state, crtc);
|
|
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
|
|
+ if (IS_ERR(crtc_state))
|
|
+ return PTR_ERR(crtc_state);
|
|
|
|
crtc_state->active = false;
|
|
|
|
ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
|
|
- KUNIT_ASSERT_EQ(test, ret, 0);
|
|
+ if (ret)
|
|
+ return ret;
|
|
|
|
output = encoder_to_vc4_dummy_output(encoder);
|
|
conn = &output->connector;
|
|
conn_state = drm_atomic_get_connector_state(state, conn);
|
|
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
|
|
+ if (IS_ERR(conn_state))
|
|
+ return PTR_ERR(conn_state);
|
|
|
|
ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
|
|
- KUNIT_ASSERT_EQ(test, ret, 0);
|
|
+ if (ret)
|
|
+ return ret;
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
|
|
index 61e500b8c9da23..894c484f99e950 100644
|
|
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
|
|
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
|
|
@@ -201,7 +201,7 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
|
|
i++;
|
|
}
|
|
|
|
- vkms_state->active_planes = kcalloc(i, sizeof(plane), GFP_KERNEL);
|
|
+ vkms_state->active_planes = kcalloc(i, sizeof(*vkms_state->active_planes), GFP_KERNEL);
|
|
if (!vkms_state->active_planes)
|
|
return -ENOMEM;
|
|
vkms_state->num_active_planes = i;
|
|
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
|
|
index 5fef0b31c11798..b129ce873af3f2 100644
|
|
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
|
|
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
|
|
@@ -4083,6 +4083,23 @@ static int vmw_execbuf_tie_context(struct vmw_private *dev_priv,
|
|
return 0;
|
|
}
|
|
|
|
+/*
|
|
+ * DMA fence callback to remove a seqno_waiter
|
|
+ */
|
|
+struct seqno_waiter_rm_context {
|
|
+ struct dma_fence_cb base;
|
|
+ struct vmw_private *dev_priv;
|
|
+};
|
|
+
|
|
+static void seqno_waiter_rm_cb(struct dma_fence *f, struct dma_fence_cb *cb)
|
|
+{
|
|
+ struct seqno_waiter_rm_context *ctx =
|
|
+ container_of(cb, struct seqno_waiter_rm_context, base);
|
|
+
|
|
+ vmw_seqno_waiter_remove(ctx->dev_priv);
|
|
+ kfree(ctx);
|
|
+}
|
|
+
|
|
int vmw_execbuf_process(struct drm_file *file_priv,
|
|
struct vmw_private *dev_priv,
|
|
void __user *user_commands, void *kernel_commands,
|
|
@@ -4263,6 +4280,15 @@ int vmw_execbuf_process(struct drm_file *file_priv,
|
|
} else {
|
|
/* Link the fence with the FD created earlier */
|
|
fd_install(out_fence_fd, sync_file->file);
|
|
+ struct seqno_waiter_rm_context *ctx =
|
|
+ kmalloc(sizeof(*ctx), GFP_KERNEL);
|
|
+ ctx->dev_priv = dev_priv;
|
|
+ vmw_seqno_waiter_add(dev_priv);
|
|
+ if (dma_fence_add_callback(&fence->base, &ctx->base,
|
|
+ seqno_waiter_rm_cb) < 0) {
|
|
+ vmw_seqno_waiter_remove(dev_priv);
|
|
+ kfree(ctx);
|
|
+ }
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c
|
|
index 0fb210e40a4127..9eafff0b6ea4c3 100644
|
|
--- a/drivers/hid/hid-hyperv.c
|
|
+++ b/drivers/hid/hid-hyperv.c
|
|
@@ -192,7 +192,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
|
|
goto cleanup;
|
|
|
|
input_device->report_desc_size = le16_to_cpu(
|
|
- desc->desc[0].wDescriptorLength);
|
|
+ desc->rpt_desc.wDescriptorLength);
|
|
if (input_device->report_desc_size == 0) {
|
|
input_device->dev_info_status = -EINVAL;
|
|
goto cleanup;
|
|
@@ -210,7 +210,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
|
|
|
|
memcpy(input_device->report_desc,
|
|
((unsigned char *)desc) + desc->bLength,
|
|
- le16_to_cpu(desc->desc[0].wDescriptorLength));
|
|
+ le16_to_cpu(desc->rpt_desc.wDescriptorLength));
|
|
|
|
/* Send the ack */
|
|
memset(&ack, 0, sizeof(struct mousevsc_prt_msg));
|
|
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
|
|
index 257dd73e37bf57..a8e8da002b9bbd 100644
|
|
--- a/drivers/hid/usbhid/hid-core.c
|
|
+++ b/drivers/hid/usbhid/hid-core.c
|
|
@@ -982,12 +982,11 @@ static int usbhid_parse(struct hid_device *hid)
|
|
struct usb_host_interface *interface = intf->cur_altsetting;
|
|
struct usb_device *dev = interface_to_usbdev (intf);
|
|
struct hid_descriptor *hdesc;
|
|
+ struct hid_class_descriptor *hcdesc;
|
|
u32 quirks = 0;
|
|
unsigned int rsize = 0;
|
|
char *rdesc;
|
|
- int ret, n;
|
|
- int num_descriptors;
|
|
- size_t offset = offsetof(struct hid_descriptor, desc);
|
|
+ int ret;
|
|
|
|
quirks = hid_lookup_quirk(hid);
|
|
|
|
@@ -1009,20 +1008,19 @@ static int usbhid_parse(struct hid_device *hid)
|
|
return -ENODEV;
|
|
}
|
|
|
|
- if (hdesc->bLength < sizeof(struct hid_descriptor)) {
|
|
- dbg_hid("hid descriptor is too short\n");
|
|
+ if (!hdesc->bNumDescriptors ||
|
|
+ hdesc->bLength != sizeof(*hdesc) +
|
|
+ (hdesc->bNumDescriptors - 1) * sizeof(*hcdesc)) {
|
|
+ dbg_hid("hid descriptor invalid, bLen=%hhu bNum=%hhu\n",
|
|
+ hdesc->bLength, hdesc->bNumDescriptors);
|
|
return -EINVAL;
|
|
}
|
|
|
|
hid->version = le16_to_cpu(hdesc->bcdHID);
|
|
hid->country = hdesc->bCountryCode;
|
|
|
|
- num_descriptors = min_t(int, hdesc->bNumDescriptors,
|
|
- (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
|
|
-
|
|
- for (n = 0; n < num_descriptors; n++)
|
|
- if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
|
|
- rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
|
|
+ if (hdesc->rpt_desc.bDescriptorType == HID_DT_REPORT)
|
|
+ rsize = le16_to_cpu(hdesc->rpt_desc.wDescriptorLength);
|
|
|
|
if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
|
|
dbg_hid("weird size of report descriptor (%u)\n", rsize);
|
|
@@ -1050,6 +1048,11 @@ static int usbhid_parse(struct hid_device *hid)
|
|
goto err;
|
|
}
|
|
|
|
+ if (hdesc->bNumDescriptors > 1)
|
|
+ hid_warn(intf,
|
|
+ "%u unsupported optional hid class descriptors\n",
|
|
+ (int)(hdesc->bNumDescriptors - 1));
|
|
+
|
|
hid->quirks |= quirks;
|
|
|
|
return 0;
|
|
diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c
|
|
index f20b864c1bb201..ce2f14a62754ee 100644
|
|
--- a/drivers/hwmon/asus-ec-sensors.c
|
|
+++ b/drivers/hwmon/asus-ec-sensors.c
|
|
@@ -888,6 +888,10 @@ static int asus_ec_hwmon_read_string(struct device *dev,
|
|
{
|
|
struct ec_sensors_data *state = dev_get_drvdata(dev);
|
|
int sensor_index = find_ec_sensor_index(state, type, channel);
|
|
+
|
|
+ if (sensor_index < 0)
|
|
+ return sensor_index;
|
|
+
|
|
*str = get_sensor_info(state, sensor_index)->label;
|
|
|
|
return 0;
|
|
diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
|
|
index 6ba01397574182..84cdde6f0e4db2 100644
|
|
--- a/drivers/hwtracing/coresight/coresight-config.h
|
|
+++ b/drivers/hwtracing/coresight/coresight-config.h
|
|
@@ -228,7 +228,7 @@ struct cscfg_feature_csdev {
|
|
* @feats_csdev:references to the device features to enable.
|
|
*/
|
|
struct cscfg_config_csdev {
|
|
- const struct cscfg_config_desc *config_desc;
|
|
+ struct cscfg_config_desc *config_desc;
|
|
struct coresight_device *csdev;
|
|
bool enabled;
|
|
struct list_head node;
|
|
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
|
|
index 11138a9762b015..30a561d874819b 100644
|
|
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
|
|
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
|
|
@@ -867,6 +867,25 @@ void cscfg_csdev_reset_feats(struct coresight_device *csdev)
|
|
}
|
|
EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats);
|
|
|
|
+static bool cscfg_config_desc_get(struct cscfg_config_desc *config_desc)
|
|
+{
|
|
+ if (!atomic_fetch_inc(&config_desc->active_cnt)) {
|
|
+ /* must ensure that config cannot be unloaded in use */
|
|
+ if (unlikely(cscfg_owner_get(config_desc->load_owner))) {
|
|
+ atomic_dec(&config_desc->active_cnt);
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static void cscfg_config_desc_put(struct cscfg_config_desc *config_desc)
|
|
+{
|
|
+ if (!atomic_dec_return(&config_desc->active_cnt))
|
|
+ cscfg_owner_put(config_desc->load_owner);
|
|
+}
|
|
+
|
|
/*
|
|
* This activate configuration for either perf or sysfs. Perf can have multiple
|
|
* active configs, selected per event, sysfs is limited to one.
|
|
@@ -890,22 +909,17 @@ static int _cscfg_activate_config(unsigned long cfg_hash)
|
|
if (config_desc->available == false)
|
|
return -EBUSY;
|
|
|
|
- /* must ensure that config cannot be unloaded in use */
|
|
- err = cscfg_owner_get(config_desc->load_owner);
|
|
- if (err)
|
|
+ if (!cscfg_config_desc_get(config_desc)) {
|
|
+ err = -EINVAL;
|
|
break;
|
|
+ }
|
|
+
|
|
/*
|
|
* increment the global active count - control changes to
|
|
* active configurations
|
|
*/
|
|
atomic_inc(&cscfg_mgr->sys_active_cnt);
|
|
|
|
- /*
|
|
- * mark the descriptor as active so enable config on a
|
|
- * device instance will use it
|
|
- */
|
|
- atomic_inc(&config_desc->active_cnt);
|
|
-
|
|
err = 0;
|
|
dev_dbg(cscfg_device(), "Activate config %s.\n", config_desc->name);
|
|
break;
|
|
@@ -920,9 +934,8 @@ static void _cscfg_deactivate_config(unsigned long cfg_hash)
|
|
|
|
list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
|
|
if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
|
|
- atomic_dec(&config_desc->active_cnt);
|
|
atomic_dec(&cscfg_mgr->sys_active_cnt);
|
|
- cscfg_owner_put(config_desc->load_owner);
|
|
+ cscfg_config_desc_put(config_desc);
|
|
dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name);
|
|
break;
|
|
}
|
|
@@ -1047,7 +1060,7 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
|
|
unsigned long cfg_hash, int preset)
|
|
{
|
|
struct cscfg_config_csdev *config_csdev_active = NULL, *config_csdev_item;
|
|
- const struct cscfg_config_desc *config_desc;
|
|
+ struct cscfg_config_desc *config_desc;
|
|
unsigned long flags;
|
|
int err = 0;
|
|
|
|
@@ -1062,8 +1075,8 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
|
|
spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
|
|
list_for_each_entry(config_csdev_item, &csdev->config_csdev_list, node) {
|
|
config_desc = config_csdev_item->config_desc;
|
|
- if ((atomic_read(&config_desc->active_cnt)) &&
|
|
- ((unsigned long)config_desc->event_ea->var == cfg_hash)) {
|
|
+ if (((unsigned long)config_desc->event_ea->var == cfg_hash) &&
|
|
+ cscfg_config_desc_get(config_desc)) {
|
|
config_csdev_active = config_csdev_item;
|
|
csdev->active_cscfg_ctxt = (void *)config_csdev_active;
|
|
break;
|
|
@@ -1097,7 +1110,11 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
|
|
err = -EBUSY;
|
|
spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
|
|
}
|
|
+
|
|
+ if (err)
|
|
+ cscfg_config_desc_put(config_desc);
|
|
}
|
|
+
|
|
return err;
|
|
}
|
|
EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config);
|
|
@@ -1136,8 +1153,10 @@ void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
|
|
spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
|
|
|
|
/* true if there was an enabled active config */
|
|
- if (config_csdev)
|
|
+ if (config_csdev) {
|
|
cscfg_csdev_disable_config(config_csdev);
|
|
+ cscfg_config_desc_put(config_csdev->config_desc);
|
|
+ }
|
|
}
|
|
EXPORT_SYMBOL_GPL(cscfg_csdev_disable_active_config);
|
|
|
|
diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c
|
|
index 0e6baf017bfd1e..f631351eef97b9 100644
|
|
--- a/drivers/iio/adc/ad7124.c
|
|
+++ b/drivers/iio/adc/ad7124.c
|
|
@@ -300,9 +300,9 @@ static int ad7124_get_3db_filter_freq(struct ad7124_state *st,
|
|
|
|
switch (st->channels[channel].cfg.filter_type) {
|
|
case AD7124_SINC3_FILTER:
|
|
- return DIV_ROUND_CLOSEST(fadc * 230, 1000);
|
|
+ return DIV_ROUND_CLOSEST(fadc * 272, 1000);
|
|
case AD7124_SINC4_FILTER:
|
|
- return DIV_ROUND_CLOSEST(fadc * 262, 1000);
|
|
+ return DIV_ROUND_CLOSEST(fadc * 230, 1000);
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
diff --git a/drivers/iio/filter/admv8818.c b/drivers/iio/filter/admv8818.c
|
|
index d85b7d3de86604..cc8ce0fe74e7c6 100644
|
|
--- a/drivers/iio/filter/admv8818.c
|
|
+++ b/drivers/iio/filter/admv8818.c
|
|
@@ -14,6 +14,7 @@
|
|
#include <linux/mod_devicetable.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/notifier.h>
|
|
+#include <linux/property.h>
|
|
#include <linux/regmap.h>
|
|
#include <linux/spi/spi.h>
|
|
#include <linux/units.h>
|
|
@@ -70,6 +71,16 @@
|
|
#define ADMV8818_HPF_WR0_MSK GENMASK(7, 4)
|
|
#define ADMV8818_LPF_WR0_MSK GENMASK(3, 0)
|
|
|
|
+#define ADMV8818_BAND_BYPASS 0
|
|
+#define ADMV8818_BAND_MIN 1
|
|
+#define ADMV8818_BAND_MAX 4
|
|
+#define ADMV8818_BAND_CORNER_LOW 0
|
|
+#define ADMV8818_BAND_CORNER_HIGH 1
|
|
+
|
|
+#define ADMV8818_STATE_MIN 0
|
|
+#define ADMV8818_STATE_MAX 15
|
|
+#define ADMV8818_NUM_STATES 16
|
|
+
|
|
enum {
|
|
ADMV8818_BW_FREQ,
|
|
ADMV8818_CENTER_FREQ
|
|
@@ -90,20 +101,24 @@ struct admv8818_state {
|
|
struct mutex lock;
|
|
unsigned int filter_mode;
|
|
u64 cf_hz;
|
|
+ u64 lpf_margin_hz;
|
|
+ u64 hpf_margin_hz;
|
|
};
|
|
|
|
-static const unsigned long long freq_range_hpf[4][2] = {
|
|
+static const unsigned long long freq_range_hpf[5][2] = {
|
|
+ {0ULL, 0ULL}, /* bypass */
|
|
{1750000000ULL, 3550000000ULL},
|
|
{3400000000ULL, 7250000000ULL},
|
|
{6600000000, 12000000000},
|
|
{12500000000, 19900000000}
|
|
};
|
|
|
|
-static const unsigned long long freq_range_lpf[4][2] = {
|
|
+static const unsigned long long freq_range_lpf[5][2] = {
|
|
+ {U64_MAX, U64_MAX}, /* bypass */
|
|
{2050000000ULL, 3850000000ULL},
|
|
{3350000000ULL, 7250000000ULL},
|
|
{7000000000, 13000000000},
|
|
- {12550000000, 18500000000}
|
|
+ {12550000000, 18850000000}
|
|
};
|
|
|
|
static const struct regmap_config admv8818_regmap_config = {
|
|
@@ -121,44 +136,59 @@ static const char * const admv8818_modes[] = {
|
|
|
|
static int __admv8818_hpf_select(struct admv8818_state *st, u64 freq)
|
|
{
|
|
- unsigned int hpf_step = 0, hpf_band = 0, i, j;
|
|
- u64 freq_step;
|
|
- int ret;
|
|
+ int band, state, ret;
|
|
+ unsigned int hpf_state = ADMV8818_STATE_MIN, hpf_band = ADMV8818_BAND_BYPASS;
|
|
+ u64 freq_error, min_freq_error, freq_corner, freq_step;
|
|
|
|
- if (freq < freq_range_hpf[0][0])
|
|
+ if (freq < freq_range_hpf[ADMV8818_BAND_MIN][ADMV8818_BAND_CORNER_LOW])
|
|
goto hpf_write;
|
|
|
|
- if (freq > freq_range_hpf[3][1]) {
|
|
- hpf_step = 15;
|
|
- hpf_band = 4;
|
|
-
|
|
+ if (freq >= freq_range_hpf[ADMV8818_BAND_MAX][ADMV8818_BAND_CORNER_HIGH]) {
|
|
+ hpf_state = ADMV8818_STATE_MAX;
|
|
+ hpf_band = ADMV8818_BAND_MAX;
|
|
goto hpf_write;
|
|
}
|
|
|
|
- for (i = 0; i < 4; i++) {
|
|
- freq_step = div_u64((freq_range_hpf[i][1] -
|
|
- freq_range_hpf[i][0]), 15);
|
|
+ /* Close HPF frequency gap between 12 and 12.5 GHz */
|
|
+ if (freq >= 12000ULL * HZ_PER_MHZ && freq < 12500ULL * HZ_PER_MHZ) {
|
|
+ hpf_state = ADMV8818_STATE_MAX;
|
|
+ hpf_band = 3;
|
|
+ goto hpf_write;
|
|
+ }
|
|
|
|
- if (freq > freq_range_hpf[i][0] &&
|
|
- (freq < freq_range_hpf[i][1] + freq_step)) {
|
|
- hpf_band = i + 1;
|
|
+ min_freq_error = U64_MAX;
|
|
+ for (band = ADMV8818_BAND_MIN; band <= ADMV8818_BAND_MAX; band++) {
|
|
+ /*
|
|
+ * This (and therefore all other ranges) have a corner
|
|
+ * frequency higher than the target frequency.
|
|
+ */
|
|
+ if (freq_range_hpf[band][ADMV8818_BAND_CORNER_LOW] > freq)
|
|
+ break;
|
|
|
|
- for (j = 1; j <= 16; j++) {
|
|
- if (freq < (freq_range_hpf[i][0] + (freq_step * j))) {
|
|
- hpf_step = j - 1;
|
|
- break;
|
|
- }
|
|
+ freq_step = freq_range_hpf[band][ADMV8818_BAND_CORNER_HIGH] -
|
|
+ freq_range_hpf[band][ADMV8818_BAND_CORNER_LOW];
|
|
+ freq_step = div_u64(freq_step, ADMV8818_NUM_STATES - 1);
|
|
+
|
|
+ for (state = ADMV8818_STATE_MIN; state <= ADMV8818_STATE_MAX; state++) {
|
|
+ freq_corner = freq_range_hpf[band][ADMV8818_BAND_CORNER_LOW] +
|
|
+ freq_step * state;
|
|
+
|
|
+ /*
|
|
+ * This (and therefore all other states) have a corner
|
|
+ * frequency higher than the target frequency.
|
|
+ */
|
|
+ if (freq_corner > freq)
|
|
+ break;
|
|
+
|
|
+ freq_error = freq - freq_corner;
|
|
+ if (freq_error < min_freq_error) {
|
|
+ min_freq_error = freq_error;
|
|
+ hpf_state = state;
|
|
+ hpf_band = band;
|
|
}
|
|
- break;
|
|
}
|
|
}
|
|
|
|
- /* Close HPF frequency gap between 12 and 12.5 GHz */
|
|
- if (freq >= 12000 * HZ_PER_MHZ && freq <= 12500 * HZ_PER_MHZ) {
|
|
- hpf_band = 3;
|
|
- hpf_step = 15;
|
|
- }
|
|
-
|
|
hpf_write:
|
|
ret = regmap_update_bits(st->regmap, ADMV8818_REG_WR0_SW,
|
|
ADMV8818_SW_IN_SET_WR0_MSK |
|
|
@@ -170,7 +200,7 @@ static int __admv8818_hpf_select(struct admv8818_state *st, u64 freq)
|
|
|
|
return regmap_update_bits(st->regmap, ADMV8818_REG_WR0_FILTER,
|
|
ADMV8818_HPF_WR0_MSK,
|
|
- FIELD_PREP(ADMV8818_HPF_WR0_MSK, hpf_step));
|
|
+ FIELD_PREP(ADMV8818_HPF_WR0_MSK, hpf_state));
|
|
}
|
|
|
|
static int admv8818_hpf_select(struct admv8818_state *st, u64 freq)
|
|
@@ -186,31 +216,52 @@ static int admv8818_hpf_select(struct admv8818_state *st, u64 freq)
|
|
|
|
static int __admv8818_lpf_select(struct admv8818_state *st, u64 freq)
|
|
{
|
|
- unsigned int lpf_step = 0, lpf_band = 0, i, j;
|
|
- u64 freq_step;
|
|
- int ret;
|
|
+ int band, state, ret;
|
|
+ unsigned int lpf_state = ADMV8818_STATE_MIN, lpf_band = ADMV8818_BAND_BYPASS;
|
|
+ u64 freq_error, min_freq_error, freq_corner, freq_step;
|
|
|
|
- if (freq > freq_range_lpf[3][1])
|
|
+ if (freq > freq_range_lpf[ADMV8818_BAND_MAX][ADMV8818_BAND_CORNER_HIGH])
|
|
goto lpf_write;
|
|
|
|
- if (freq < freq_range_lpf[0][0]) {
|
|
- lpf_band = 1;
|
|
-
|
|
+ if (freq < freq_range_lpf[ADMV8818_BAND_MIN][ADMV8818_BAND_CORNER_LOW]) {
|
|
+ lpf_state = ADMV8818_STATE_MIN;
|
|
+ lpf_band = ADMV8818_BAND_MIN;
|
|
goto lpf_write;
|
|
}
|
|
|
|
- for (i = 0; i < 4; i++) {
|
|
- if (freq > freq_range_lpf[i][0] && freq < freq_range_lpf[i][1]) {
|
|
- lpf_band = i + 1;
|
|
- freq_step = div_u64((freq_range_lpf[i][1] - freq_range_lpf[i][0]), 15);
|
|
+ min_freq_error = U64_MAX;
|
|
+ for (band = ADMV8818_BAND_MAX; band >= ADMV8818_BAND_MIN; --band) {
|
|
+ /*
|
|
+ * At this point the highest corner frequency of
|
|
+ * all remaining ranges is below the target.
|
|
+ * LPF corner should be >= the target.
|
|
+ */
|
|
+ if (freq > freq_range_lpf[band][ADMV8818_BAND_CORNER_HIGH])
|
|
+ break;
|
|
+
|
|
+ freq_step = freq_range_lpf[band][ADMV8818_BAND_CORNER_HIGH] -
|
|
+ freq_range_lpf[band][ADMV8818_BAND_CORNER_LOW];
|
|
+ freq_step = div_u64(freq_step, ADMV8818_NUM_STATES - 1);
|
|
+
|
|
+ for (state = ADMV8818_STATE_MAX; state >= ADMV8818_STATE_MIN; --state) {
|
|
+
|
|
+ freq_corner = freq_range_lpf[band][ADMV8818_BAND_CORNER_LOW] +
|
|
+ state * freq_step;
|
|
|
|
- for (j = 0; j <= 15; j++) {
|
|
- if (freq < (freq_range_lpf[i][0] + (freq_step * j))) {
|
|
- lpf_step = j;
|
|
- break;
|
|
- }
|
|
+ /*
|
|
+ * At this point all other states in range will
|
|
+ * place the corner frequency below the target
|
|
+ * LPF corner should >= the target.
|
|
+ */
|
|
+ if (freq > freq_corner)
|
|
+ break;
|
|
+
|
|
+ freq_error = freq_corner - freq;
|
|
+ if (freq_error < min_freq_error) {
|
|
+ min_freq_error = freq_error;
|
|
+ lpf_state = state;
|
|
+ lpf_band = band;
|
|
}
|
|
- break;
|
|
}
|
|
}
|
|
|
|
@@ -225,7 +276,7 @@ static int __admv8818_lpf_select(struct admv8818_state *st, u64 freq)
|
|
|
|
return regmap_update_bits(st->regmap, ADMV8818_REG_WR0_FILTER,
|
|
ADMV8818_LPF_WR0_MSK,
|
|
- FIELD_PREP(ADMV8818_LPF_WR0_MSK, lpf_step));
|
|
+ FIELD_PREP(ADMV8818_LPF_WR0_MSK, lpf_state));
|
|
}
|
|
|
|
static int admv8818_lpf_select(struct admv8818_state *st, u64 freq)
|
|
@@ -242,16 +293,28 @@ static int admv8818_lpf_select(struct admv8818_state *st, u64 freq)
|
|
static int admv8818_rfin_band_select(struct admv8818_state *st)
|
|
{
|
|
int ret;
|
|
+ u64 hpf_corner_target, lpf_corner_target;
|
|
|
|
st->cf_hz = clk_get_rate(st->clkin);
|
|
|
|
+ /* Check for underflow */
|
|
+ if (st->cf_hz > st->hpf_margin_hz)
|
|
+ hpf_corner_target = st->cf_hz - st->hpf_margin_hz;
|
|
+ else
|
|
+ hpf_corner_target = 0;
|
|
+
|
|
+ /* Check for overflow */
|
|
+ lpf_corner_target = st->cf_hz + st->lpf_margin_hz;
|
|
+ if (lpf_corner_target < st->cf_hz)
|
|
+ lpf_corner_target = U64_MAX;
|
|
+
|
|
mutex_lock(&st->lock);
|
|
|
|
- ret = __admv8818_hpf_select(st, st->cf_hz);
|
|
+ ret = __admv8818_hpf_select(st, hpf_corner_target);
|
|
if (ret)
|
|
goto exit;
|
|
|
|
- ret = __admv8818_lpf_select(st, st->cf_hz);
|
|
+ ret = __admv8818_lpf_select(st, lpf_corner_target);
|
|
exit:
|
|
mutex_unlock(&st->lock);
|
|
return ret;
|
|
@@ -278,8 +341,11 @@ static int __admv8818_read_hpf_freq(struct admv8818_state *st, u64 *hpf_freq)
|
|
|
|
hpf_state = FIELD_GET(ADMV8818_HPF_WR0_MSK, data);
|
|
|
|
- *hpf_freq = div_u64(freq_range_hpf[hpf_band - 1][1] - freq_range_hpf[hpf_band - 1][0], 15);
|
|
- *hpf_freq = freq_range_hpf[hpf_band - 1][0] + (*hpf_freq * hpf_state);
|
|
+ *hpf_freq = freq_range_hpf[hpf_band][ADMV8818_BAND_CORNER_HIGH] -
|
|
+ freq_range_hpf[hpf_band][ADMV8818_BAND_CORNER_LOW];
|
|
+ *hpf_freq = div_u64(*hpf_freq, ADMV8818_NUM_STATES - 1);
|
|
+ *hpf_freq = freq_range_hpf[hpf_band][ADMV8818_BAND_CORNER_LOW] +
|
|
+ (*hpf_freq * hpf_state);
|
|
|
|
return ret;
|
|
}
|
|
@@ -316,8 +382,11 @@ static int __admv8818_read_lpf_freq(struct admv8818_state *st, u64 *lpf_freq)
|
|
|
|
lpf_state = FIELD_GET(ADMV8818_LPF_WR0_MSK, data);
|
|
|
|
- *lpf_freq = div_u64(freq_range_lpf[lpf_band - 1][1] - freq_range_lpf[lpf_band - 1][0], 15);
|
|
- *lpf_freq = freq_range_lpf[lpf_band - 1][0] + (*lpf_freq * lpf_state);
|
|
+ *lpf_freq = freq_range_lpf[lpf_band][ADMV8818_BAND_CORNER_HIGH] -
|
|
+ freq_range_lpf[lpf_band][ADMV8818_BAND_CORNER_LOW];
|
|
+ *lpf_freq = div_u64(*lpf_freq, ADMV8818_NUM_STATES - 1);
|
|
+ *lpf_freq = freq_range_lpf[lpf_band][ADMV8818_BAND_CORNER_LOW] +
|
|
+ (*lpf_freq * lpf_state);
|
|
|
|
return ret;
|
|
}
|
|
@@ -333,6 +402,19 @@ static int admv8818_read_lpf_freq(struct admv8818_state *st, u64 *lpf_freq)
|
|
return ret;
|
|
}
|
|
|
|
+static int admv8818_write_raw_get_fmt(struct iio_dev *indio_dev,
|
|
+ struct iio_chan_spec const *chan,
|
|
+ long mask)
|
|
+{
|
|
+ switch (mask) {
|
|
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
|
|
+ case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
|
|
+ return IIO_VAL_INT_64;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+}
|
|
+
|
|
static int admv8818_write_raw(struct iio_dev *indio_dev,
|
|
struct iio_chan_spec const *chan,
|
|
int val, int val2, long info)
|
|
@@ -341,6 +423,9 @@ static int admv8818_write_raw(struct iio_dev *indio_dev,
|
|
|
|
u64 freq = ((u64)val2 << 32 | (u32)val);
|
|
|
|
+ if ((s64)freq < 0)
|
|
+ return -EINVAL;
|
|
+
|
|
switch (info) {
|
|
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
|
|
return admv8818_lpf_select(st, freq);
|
|
@@ -502,6 +587,7 @@ static int admv8818_set_mode(struct iio_dev *indio_dev,
|
|
|
|
static const struct iio_info admv8818_info = {
|
|
.write_raw = admv8818_write_raw,
|
|
+ .write_raw_get_fmt = admv8818_write_raw_get_fmt,
|
|
.read_raw = admv8818_read_raw,
|
|
.debugfs_reg_access = &admv8818_reg_access,
|
|
};
|
|
@@ -641,6 +727,32 @@ static int admv8818_clk_setup(struct admv8818_state *st)
|
|
return devm_add_action_or_reset(&spi->dev, admv8818_clk_notifier_unreg, st);
|
|
}
|
|
|
|
+static int admv8818_read_properties(struct admv8818_state *st)
|
|
+{
|
|
+ struct spi_device *spi = st->spi;
|
|
+ u32 mhz;
|
|
+ int ret;
|
|
+
|
|
+ ret = device_property_read_u32(&spi->dev, "adi,lpf-margin-mhz", &mhz);
|
|
+ if (ret == 0)
|
|
+ st->lpf_margin_hz = (u64)mhz * HZ_PER_MHZ;
|
|
+ else if (ret == -EINVAL)
|
|
+ st->lpf_margin_hz = 0;
|
|
+ else
|
|
+ return ret;
|
|
+
|
|
+
|
|
+ ret = device_property_read_u32(&spi->dev, "adi,hpf-margin-mhz", &mhz);
|
|
+ if (ret == 0)
|
|
+ st->hpf_margin_hz = (u64)mhz * HZ_PER_MHZ;
|
|
+ else if (ret == -EINVAL)
|
|
+ st->hpf_margin_hz = 0;
|
|
+ else if (ret < 0)
|
|
+ return ret;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int admv8818_probe(struct spi_device *spi)
|
|
{
|
|
struct iio_dev *indio_dev;
|
|
@@ -672,6 +784,10 @@ static int admv8818_probe(struct spi_device *spi)
|
|
|
|
mutex_init(&st->lock);
|
|
|
|
+ ret = admv8818_read_properties(st);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
ret = admv8818_init(st);
|
|
if (ret)
|
|
return ret;
|
|
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
|
|
index 07fb8d3c037f00..d45e3909dafe1d 100644
|
|
--- a/drivers/infiniband/core/cm.c
|
|
+++ b/drivers/infiniband/core/cm.c
|
|
@@ -166,7 +166,7 @@ struct cm_port {
|
|
struct cm_device {
|
|
struct kref kref;
|
|
struct list_head list;
|
|
- spinlock_t mad_agent_lock;
|
|
+ rwlock_t mad_agent_lock;
|
|
struct ib_device *ib_device;
|
|
u8 ack_delay;
|
|
int going_down;
|
|
@@ -284,7 +284,7 @@ static struct ib_mad_send_buf *cm_alloc_msg(struct cm_id_private *cm_id_priv)
|
|
if (!cm_id_priv->av.port)
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
- spin_lock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
|
|
+ read_lock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
|
|
mad_agent = cm_id_priv->av.port->mad_agent;
|
|
if (!mad_agent) {
|
|
m = ERR_PTR(-EINVAL);
|
|
@@ -315,7 +315,7 @@ static struct ib_mad_send_buf *cm_alloc_msg(struct cm_id_private *cm_id_priv)
|
|
m->context[0] = cm_id_priv;
|
|
|
|
out:
|
|
- spin_unlock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
|
|
+ read_unlock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
|
|
return m;
|
|
}
|
|
|
|
@@ -1294,10 +1294,10 @@ static __be64 cm_form_tid(struct cm_id_private *cm_id_priv)
|
|
if (!cm_id_priv->av.port)
|
|
return cpu_to_be64(low_tid);
|
|
|
|
- spin_lock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
|
|
+ read_lock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
|
|
if (cm_id_priv->av.port->mad_agent)
|
|
hi_tid = ((u64)cm_id_priv->av.port->mad_agent->hi_tid) << 32;
|
|
- spin_unlock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
|
|
+ read_unlock(&cm_id_priv->av.port->cm_dev->mad_agent_lock);
|
|
return cpu_to_be64(hi_tid | low_tid);
|
|
}
|
|
|
|
@@ -4374,7 +4374,7 @@ static int cm_add_one(struct ib_device *ib_device)
|
|
return -ENOMEM;
|
|
|
|
kref_init(&cm_dev->kref);
|
|
- spin_lock_init(&cm_dev->mad_agent_lock);
|
|
+ rwlock_init(&cm_dev->mad_agent_lock);
|
|
cm_dev->ib_device = ib_device;
|
|
cm_dev->ack_delay = ib_device->attrs.local_ca_ack_delay;
|
|
cm_dev->going_down = 0;
|
|
@@ -4490,9 +4490,9 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data)
|
|
* The above ensures no call paths from the work are running,
|
|
* the remaining paths all take the mad_agent_lock.
|
|
*/
|
|
- spin_lock(&cm_dev->mad_agent_lock);
|
|
+ write_lock(&cm_dev->mad_agent_lock);
|
|
port->mad_agent = NULL;
|
|
- spin_unlock(&cm_dev->mad_agent_lock);
|
|
+ write_unlock(&cm_dev->mad_agent_lock);
|
|
ib_unregister_mad_agent(mad_agent);
|
|
ib_port_unregister_client_groups(ib_device, i,
|
|
cm_counter_groups);
|
|
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
|
|
index 348527cf1e7bfc..a5ceae2e075ad6 100644
|
|
--- a/drivers/infiniband/core/cma.c
|
|
+++ b/drivers/infiniband/core/cma.c
|
|
@@ -5215,7 +5215,8 @@ static int cma_netevent_callback(struct notifier_block *self,
|
|
neigh->ha, ETH_ALEN))
|
|
continue;
|
|
cma_id_get(current_id);
|
|
- queue_work(cma_wq, ¤t_id->id.net_work);
|
|
+ if (!queue_work(cma_wq, ¤t_id->id.net_work))
|
|
+ cma_id_put(current_id);
|
|
}
|
|
out:
|
|
spin_unlock_irqrestore(&id_table_lock, flags);
|
|
diff --git a/drivers/infiniband/hw/hns/hns_roce_ah.c b/drivers/infiniband/hw/hns/hns_roce_ah.c
|
|
index 3df032ddda1891..e99890e0c8c37b 100644
|
|
--- a/drivers/infiniband/hw/hns/hns_roce_ah.c
|
|
+++ b/drivers/infiniband/hw/hns/hns_roce_ah.c
|
|
@@ -33,7 +33,6 @@
|
|
#include <linux/pci.h>
|
|
#include <rdma/ib_addr.h>
|
|
#include <rdma/ib_cache.h>
|
|
-#include "hnae3.h"
|
|
#include "hns_roce_device.h"
|
|
#include "hns_roce_hw_v2.h"
|
|
|
|
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
|
|
index aded0a7f42838d..9d23d4b5c1285f 100644
|
|
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
|
|
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
|
|
@@ -42,7 +42,6 @@
|
|
#include <rdma/ib_umem.h>
|
|
#include <rdma/uverbs_ioctl.h>
|
|
|
|
-#include "hnae3.h"
|
|
#include "hns_roce_common.h"
|
|
#include "hns_roce_device.h"
|
|
#include "hns_roce_cmd.h"
|
|
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
|
|
index b8e17721f6fdea..7875283eb9d631 100644
|
|
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
|
|
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
|
|
@@ -34,6 +34,7 @@
|
|
#define _HNS_ROCE_HW_V2_H
|
|
|
|
#include <linux/bitops.h>
|
|
+#include "hnae3.h"
|
|
|
|
#define HNS_ROCE_V2_MAX_RC_INL_INN_SZ 32
|
|
#define HNS_ROCE_V2_MTT_ENTRY_SZ 64
|
|
diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
|
|
index a7e4c951f8fe40..5f39a25064d10d 100644
|
|
--- a/drivers/infiniband/hw/hns/hns_roce_main.c
|
|
+++ b/drivers/infiniband/hw/hns/hns_roce_main.c
|
|
@@ -37,7 +37,6 @@
|
|
#include <rdma/ib_smi.h>
|
|
#include <rdma/ib_user_verbs.h>
|
|
#include <rdma/ib_cache.h>
|
|
-#include "hnae3.h"
|
|
#include "hns_roce_common.h"
|
|
#include "hns_roce_device.h"
|
|
#include "hns_roce_hem.h"
|
|
diff --git a/drivers/infiniband/hw/hns/hns_roce_restrack.c b/drivers/infiniband/hw/hns/hns_roce_restrack.c
|
|
index 081a01de305535..1fb5e246836479 100644
|
|
--- a/drivers/infiniband/hw/hns/hns_roce_restrack.c
|
|
+++ b/drivers/infiniband/hw/hns/hns_roce_restrack.c
|
|
@@ -4,7 +4,6 @@
|
|
#include <rdma/rdma_cm.h>
|
|
#include <rdma/restrack.h>
|
|
#include <uapi/rdma/rdma_netlink.h>
|
|
-#include "hnae3.h"
|
|
#include "hns_roce_common.h"
|
|
#include "hns_roce_device.h"
|
|
#include "hns_roce_hw_v2.h"
|
|
diff --git a/drivers/infiniband/hw/mlx5/qpc.c b/drivers/infiniband/hw/mlx5/qpc.c
|
|
index d9cf6982d645ed..9de9bea1025e26 100644
|
|
--- a/drivers/infiniband/hw/mlx5/qpc.c
|
|
+++ b/drivers/infiniband/hw/mlx5/qpc.c
|
|
@@ -21,8 +21,10 @@ mlx5_get_rsc(struct mlx5_qp_table *table, u32 rsn)
|
|
spin_lock_irqsave(&table->lock, flags);
|
|
|
|
common = radix_tree_lookup(&table->tree, rsn);
|
|
- if (common)
|
|
+ if (common && !common->invalid)
|
|
refcount_inc(&common->refcount);
|
|
+ else
|
|
+ common = NULL;
|
|
|
|
spin_unlock_irqrestore(&table->lock, flags);
|
|
|
|
@@ -178,6 +180,18 @@ static int create_resource_common(struct mlx5_ib_dev *dev,
|
|
return 0;
|
|
}
|
|
|
|
+static void modify_resource_common_state(struct mlx5_ib_dev *dev,
|
|
+ struct mlx5_core_qp *qp,
|
|
+ bool invalid)
|
|
+{
|
|
+ struct mlx5_qp_table *table = &dev->qp_table;
|
|
+ unsigned long flags;
|
|
+
|
|
+ spin_lock_irqsave(&table->lock, flags);
|
|
+ qp->common.invalid = invalid;
|
|
+ spin_unlock_irqrestore(&table->lock, flags);
|
|
+}
|
|
+
|
|
static void destroy_resource_common(struct mlx5_ib_dev *dev,
|
|
struct mlx5_core_qp *qp)
|
|
{
|
|
@@ -604,8 +618,20 @@ int mlx5_core_create_rq_tracked(struct mlx5_ib_dev *dev, u32 *in, int inlen,
|
|
int mlx5_core_destroy_rq_tracked(struct mlx5_ib_dev *dev,
|
|
struct mlx5_core_qp *rq)
|
|
{
|
|
+ int ret;
|
|
+
|
|
+ /* The rq destruction can be called again in case it fails, hence we
|
|
+ * mark the common resource as invalid and only once FW destruction
|
|
+ * is completed successfully we actually destroy the resources.
|
|
+ */
|
|
+ modify_resource_common_state(dev, rq, true);
|
|
+ ret = destroy_rq_tracked(dev, rq->qpn, rq->uid);
|
|
+ if (ret) {
|
|
+ modify_resource_common_state(dev, rq, false);
|
|
+ return ret;
|
|
+ }
|
|
destroy_resource_common(dev, rq);
|
|
- return destroy_rq_tracked(dev, rq->qpn, rq->uid);
|
|
+ return 0;
|
|
}
|
|
|
|
static void destroy_sq_tracked(struct mlx5_ib_dev *dev, u32 sqn, u16 uid)
|
|
diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c
|
|
index 0d9a5756e3f593..cae1e416649214 100644
|
|
--- a/drivers/input/rmi4/rmi_f34.c
|
|
+++ b/drivers/input/rmi4/rmi_f34.c
|
|
@@ -4,6 +4,7 @@
|
|
* Copyright (C) 2016 Zodiac Inflight Innovations
|
|
*/
|
|
|
|
+#include "linux/device.h"
|
|
#include <linux/kernel.h>
|
|
#include <linux/rmi.h>
|
|
#include <linux/firmware.h>
|
|
@@ -298,39 +299,30 @@ static int rmi_f34_update_firmware(struct f34_data *f34,
|
|
return ret;
|
|
}
|
|
|
|
-static int rmi_f34_status(struct rmi_function *fn)
|
|
-{
|
|
- struct f34_data *f34 = dev_get_drvdata(&fn->dev);
|
|
-
|
|
- /*
|
|
- * The status is the percentage complete, or once complete,
|
|
- * zero for success or a negative return code.
|
|
- */
|
|
- return f34->update_status;
|
|
-}
|
|
-
|
|
static ssize_t rmi_driver_bootloader_id_show(struct device *dev,
|
|
struct device_attribute *dattr,
|
|
char *buf)
|
|
{
|
|
struct rmi_driver_data *data = dev_get_drvdata(dev);
|
|
- struct rmi_function *fn = data->f34_container;
|
|
+ struct rmi_function *fn;
|
|
struct f34_data *f34;
|
|
|
|
- if (fn) {
|
|
- f34 = dev_get_drvdata(&fn->dev);
|
|
-
|
|
- if (f34->bl_version == 5)
|
|
- return sysfs_emit(buf, "%c%c\n",
|
|
- f34->bootloader_id[0],
|
|
- f34->bootloader_id[1]);
|
|
- else
|
|
- return sysfs_emit(buf, "V%d.%d\n",
|
|
- f34->bootloader_id[1],
|
|
- f34->bootloader_id[0]);
|
|
- }
|
|
+ fn = data->f34_container;
|
|
+ if (!fn)
|
|
+ return -ENODEV;
|
|
|
|
- return 0;
|
|
+ f34 = dev_get_drvdata(&fn->dev);
|
|
+ if (!f34)
|
|
+ return -ENODEV;
|
|
+
|
|
+ if (f34->bl_version == 5)
|
|
+ return sysfs_emit(buf, "%c%c\n",
|
|
+ f34->bootloader_id[0],
|
|
+ f34->bootloader_id[1]);
|
|
+ else
|
|
+ return sysfs_emit(buf, "V%d.%d\n",
|
|
+ f34->bootloader_id[1],
|
|
+ f34->bootloader_id[0]);
|
|
}
|
|
|
|
static DEVICE_ATTR(bootloader_id, 0444, rmi_driver_bootloader_id_show, NULL);
|
|
@@ -343,13 +335,16 @@ static ssize_t rmi_driver_configuration_id_show(struct device *dev,
|
|
struct rmi_function *fn = data->f34_container;
|
|
struct f34_data *f34;
|
|
|
|
- if (fn) {
|
|
- f34 = dev_get_drvdata(&fn->dev);
|
|
+ fn = data->f34_container;
|
|
+ if (!fn)
|
|
+ return -ENODEV;
|
|
|
|
- return sysfs_emit(buf, "%s\n", f34->configuration_id);
|
|
- }
|
|
+ f34 = dev_get_drvdata(&fn->dev);
|
|
+ if (!f34)
|
|
+ return -ENODEV;
|
|
|
|
- return 0;
|
|
+
|
|
+ return sysfs_emit(buf, "%s\n", f34->configuration_id);
|
|
}
|
|
|
|
static DEVICE_ATTR(configuration_id, 0444,
|
|
@@ -365,10 +360,14 @@ static int rmi_firmware_update(struct rmi_driver_data *data,
|
|
|
|
if (!data->f34_container) {
|
|
dev_warn(dev, "%s: No F34 present!\n", __func__);
|
|
- return -EINVAL;
|
|
+ return -ENODEV;
|
|
}
|
|
|
|
f34 = dev_get_drvdata(&data->f34_container->dev);
|
|
+ if (!f34) {
|
|
+ dev_warn(dev, "%s: No valid F34 present!\n", __func__);
|
|
+ return -ENODEV;
|
|
+ }
|
|
|
|
if (f34->bl_version >= 7) {
|
|
if (data->pdt_props & HAS_BSR) {
|
|
@@ -494,10 +493,18 @@ static ssize_t rmi_driver_update_fw_status_show(struct device *dev,
|
|
char *buf)
|
|
{
|
|
struct rmi_driver_data *data = dev_get_drvdata(dev);
|
|
- int update_status = 0;
|
|
+ struct f34_data *f34;
|
|
+ int update_status = -ENODEV;
|
|
|
|
- if (data->f34_container)
|
|
- update_status = rmi_f34_status(data->f34_container);
|
|
+ /*
|
|
+ * The status is the percentage complete, or once complete,
|
|
+ * zero for success or a negative return code.
|
|
+ */
|
|
+ if (data->f34_container) {
|
|
+ f34 = dev_get_drvdata(&data->f34_container->dev);
|
|
+ if (f34)
|
|
+ update_status = f34->update_status;
|
|
+ }
|
|
|
|
return sysfs_emit(buf, "%d\n", update_status);
|
|
}
|
|
@@ -517,33 +524,21 @@ static const struct attribute_group rmi_firmware_attr_group = {
|
|
.attrs = rmi_firmware_attrs,
|
|
};
|
|
|
|
-static int rmi_f34_probe(struct rmi_function *fn)
|
|
+static int rmi_f34v5_probe(struct f34_data *f34)
|
|
{
|
|
- struct f34_data *f34;
|
|
- unsigned char f34_queries[9];
|
|
+ struct rmi_function *fn = f34->fn;
|
|
+ u8 f34_queries[9];
|
|
bool has_config_id;
|
|
- u8 version = fn->fd.function_version;
|
|
- int ret;
|
|
-
|
|
- f34 = devm_kzalloc(&fn->dev, sizeof(struct f34_data), GFP_KERNEL);
|
|
- if (!f34)
|
|
- return -ENOMEM;
|
|
-
|
|
- f34->fn = fn;
|
|
- dev_set_drvdata(&fn->dev, f34);
|
|
-
|
|
- /* v5 code only supported version 0, try V7 probe */
|
|
- if (version > 0)
|
|
- return rmi_f34v7_probe(f34);
|
|
+ int error;
|
|
|
|
f34->bl_version = 5;
|
|
|
|
- ret = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
|
|
- f34_queries, sizeof(f34_queries));
|
|
- if (ret) {
|
|
+ error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
|
|
+ f34_queries, sizeof(f34_queries));
|
|
+ if (error) {
|
|
dev_err(&fn->dev, "%s: Failed to query properties\n",
|
|
__func__);
|
|
- return ret;
|
|
+ return error;
|
|
}
|
|
|
|
snprintf(f34->bootloader_id, sizeof(f34->bootloader_id),
|
|
@@ -569,11 +564,11 @@ static int rmi_f34_probe(struct rmi_function *fn)
|
|
f34->v5.config_blocks);
|
|
|
|
if (has_config_id) {
|
|
- ret = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr,
|
|
- f34_queries, sizeof(f34_queries));
|
|
- if (ret) {
|
|
+ error = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr,
|
|
+ f34_queries, sizeof(f34_queries));
|
|
+ if (error) {
|
|
dev_err(&fn->dev, "Failed to read F34 config ID\n");
|
|
- return ret;
|
|
+ return error;
|
|
}
|
|
|
|
snprintf(f34->configuration_id, sizeof(f34->configuration_id),
|
|
@@ -582,12 +577,34 @@ static int rmi_f34_probe(struct rmi_function *fn)
|
|
f34_queries[2], f34_queries[3]);
|
|
|
|
rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Configuration ID: %s\n",
|
|
- f34->configuration_id);
|
|
+ f34->configuration_id);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
+static int rmi_f34_probe(struct rmi_function *fn)
|
|
+{
|
|
+ struct f34_data *f34;
|
|
+ u8 version = fn->fd.function_version;
|
|
+ int error;
|
|
+
|
|
+ f34 = devm_kzalloc(&fn->dev, sizeof(struct f34_data), GFP_KERNEL);
|
|
+ if (!f34)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ f34->fn = fn;
|
|
+
|
|
+ /* v5 code only supported version 0 */
|
|
+ error = version == 0 ? rmi_f34v5_probe(f34) : rmi_f34v7_probe(f34);
|
|
+ if (error)
|
|
+ return error;
|
|
+
|
|
+ dev_set_drvdata(&fn->dev, f34);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int rmi_f34_create_sysfs(struct rmi_device *rmi_dev)
|
|
{
|
|
return sysfs_create_group(&rmi_dev->dev.kobj, &rmi_firmware_attr_group);
|
|
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
|
|
index d57c5adf932e36..20aa5ed80aa387 100644
|
|
--- a/drivers/iommu/Kconfig
|
|
+++ b/drivers/iommu/Kconfig
|
|
@@ -191,7 +191,6 @@ source "drivers/iommu/iommufd/Kconfig"
|
|
config IRQ_REMAP
|
|
bool "Support for Interrupt Remapping"
|
|
depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI
|
|
- select DMAR_TABLE if INTEL_IOMMU
|
|
help
|
|
Supports Interrupt remapping for IO-APIC and MSI devices.
|
|
To use x2apic mode in the CPU's which support x2APIC enhancements or
|
|
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
|
|
index f2b3a4e2e54fc8..3fa5699b9ff191 100644
|
|
--- a/drivers/iommu/iommu.c
|
|
+++ b/drivers/iommu/iommu.c
|
|
@@ -2382,6 +2382,7 @@ static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long iova,
|
|
unsigned int pgsize_idx, pgsize_idx_next;
|
|
unsigned long pgsizes;
|
|
size_t offset, pgsize, pgsize_next;
|
|
+ size_t offset_end;
|
|
unsigned long addr_merge = paddr | iova;
|
|
|
|
/* Page sizes supported by the hardware and small enough for @size */
|
|
@@ -2422,7 +2423,8 @@ static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long iova,
|
|
* If size is big enough to accommodate the larger page, reduce
|
|
* the number of smaller pages.
|
|
*/
|
|
- if (offset + pgsize_next <= size)
|
|
+ if (!check_add_overflow(offset, pgsize_next, &offset_end) &&
|
|
+ offset_end <= size)
|
|
size = offset;
|
|
|
|
out_set_count:
|
|
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
|
|
index dc491dc771d712..ada679f4fca671 100644
|
|
--- a/drivers/md/dm-flakey.c
|
|
+++ b/drivers/md/dm-flakey.c
|
|
@@ -47,14 +47,15 @@ enum feature_flag_bits {
|
|
};
|
|
|
|
struct per_bio_data {
|
|
- bool bio_submitted;
|
|
+ bool bio_can_corrupt;
|
|
+ struct bvec_iter saved_iter;
|
|
};
|
|
|
|
static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
|
|
struct dm_target *ti)
|
|
{
|
|
- int r;
|
|
- unsigned int argc;
|
|
+ int r = 0;
|
|
+ unsigned int argc = 0;
|
|
const char *arg_name;
|
|
|
|
static const struct dm_arg _args[] = {
|
|
@@ -65,14 +66,13 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
|
|
{0, PROBABILITY_BASE, "Invalid random corrupt argument"},
|
|
};
|
|
|
|
- /* No feature arguments supplied. */
|
|
- if (!as->argc)
|
|
- return 0;
|
|
-
|
|
- r = dm_read_arg_group(_args, as, &argc, &ti->error);
|
|
- if (r)
|
|
+ if (as->argc && (r = dm_read_arg_group(_args, as, &argc, &ti->error)))
|
|
return r;
|
|
|
|
+ /* No feature arguments supplied. */
|
|
+ if (!argc)
|
|
+ goto error_all_io;
|
|
+
|
|
while (argc) {
|
|
arg_name = dm_shift_arg(as);
|
|
argc--;
|
|
@@ -217,6 +217,7 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
|
|
if (!fc->corrupt_bio_byte && !test_bit(ERROR_READS, &fc->flags) &&
|
|
!test_bit(DROP_WRITES, &fc->flags) && !test_bit(ERROR_WRITES, &fc->flags) &&
|
|
!fc->random_read_corrupt && !fc->random_write_corrupt) {
|
|
+error_all_io:
|
|
set_bit(ERROR_WRITES, &fc->flags);
|
|
set_bit(ERROR_READS, &fc->flags);
|
|
}
|
|
@@ -339,7 +340,8 @@ static void flakey_map_bio(struct dm_target *ti, struct bio *bio)
|
|
}
|
|
|
|
static void corrupt_bio_common(struct bio *bio, unsigned int corrupt_bio_byte,
|
|
- unsigned char corrupt_bio_value)
|
|
+ unsigned char corrupt_bio_value,
|
|
+ struct bvec_iter start)
|
|
{
|
|
struct bvec_iter iter;
|
|
struct bio_vec bvec;
|
|
@@ -348,7 +350,7 @@ static void corrupt_bio_common(struct bio *bio, unsigned int corrupt_bio_byte,
|
|
* Overwrite the Nth byte of the bio's data, on whichever page
|
|
* it falls.
|
|
*/
|
|
- bio_for_each_segment(bvec, bio, iter) {
|
|
+ __bio_for_each_segment(bvec, bio, iter, start) {
|
|
if (bio_iter_len(bio, iter) > corrupt_bio_byte) {
|
|
unsigned char *segment = bvec_kmap_local(&bvec);
|
|
segment[corrupt_bio_byte] = corrupt_bio_value;
|
|
@@ -357,36 +359,31 @@ static void corrupt_bio_common(struct bio *bio, unsigned int corrupt_bio_byte,
|
|
"(rw=%c bi_opf=%u bi_sector=%llu size=%u)\n",
|
|
bio, corrupt_bio_value, corrupt_bio_byte,
|
|
(bio_data_dir(bio) == WRITE) ? 'w' : 'r', bio->bi_opf,
|
|
- (unsigned long long)bio->bi_iter.bi_sector,
|
|
- bio->bi_iter.bi_size);
|
|
+ (unsigned long long)start.bi_sector,
|
|
+ start.bi_size);
|
|
break;
|
|
}
|
|
corrupt_bio_byte -= bio_iter_len(bio, iter);
|
|
}
|
|
}
|
|
|
|
-static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc)
|
|
+static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc,
|
|
+ struct bvec_iter start)
|
|
{
|
|
unsigned int corrupt_bio_byte = fc->corrupt_bio_byte - 1;
|
|
|
|
- if (!bio_has_data(bio))
|
|
- return;
|
|
-
|
|
- corrupt_bio_common(bio, corrupt_bio_byte, fc->corrupt_bio_value);
|
|
+ corrupt_bio_common(bio, corrupt_bio_byte, fc->corrupt_bio_value, start);
|
|
}
|
|
|
|
-static void corrupt_bio_random(struct bio *bio)
|
|
+static void corrupt_bio_random(struct bio *bio, struct bvec_iter start)
|
|
{
|
|
unsigned int corrupt_byte;
|
|
unsigned char corrupt_value;
|
|
|
|
- if (!bio_has_data(bio))
|
|
- return;
|
|
-
|
|
- corrupt_byte = get_random_u32() % bio->bi_iter.bi_size;
|
|
+ corrupt_byte = get_random_u32() % start.bi_size;
|
|
corrupt_value = get_random_u8();
|
|
|
|
- corrupt_bio_common(bio, corrupt_byte, corrupt_value);
|
|
+ corrupt_bio_common(bio, corrupt_byte, corrupt_value, start);
|
|
}
|
|
|
|
static void clone_free(struct bio *clone)
|
|
@@ -481,7 +478,7 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
|
|
unsigned int elapsed;
|
|
struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data));
|
|
|
|
- pb->bio_submitted = false;
|
|
+ pb->bio_can_corrupt = false;
|
|
|
|
if (op_is_zone_mgmt(bio_op(bio)))
|
|
goto map_bio;
|
|
@@ -490,10 +487,11 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
|
|
elapsed = (jiffies - fc->start_time) / HZ;
|
|
if (elapsed % (fc->up_interval + fc->down_interval) >= fc->up_interval) {
|
|
bool corrupt_fixed, corrupt_random;
|
|
- /*
|
|
- * Flag this bio as submitted while down.
|
|
- */
|
|
- pb->bio_submitted = true;
|
|
+
|
|
+ if (bio_has_data(bio)) {
|
|
+ pb->bio_can_corrupt = true;
|
|
+ pb->saved_iter = bio->bi_iter;
|
|
+ }
|
|
|
|
/*
|
|
* Error reads if neither corrupt_bio_byte or drop_writes or error_writes are set.
|
|
@@ -516,6 +514,8 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
|
|
return DM_MAPIO_SUBMITTED;
|
|
}
|
|
|
|
+ if (!pb->bio_can_corrupt)
|
|
+ goto map_bio;
|
|
/*
|
|
* Corrupt matching writes.
|
|
*/
|
|
@@ -535,9 +535,11 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
|
|
struct bio *clone = clone_bio(ti, fc, bio);
|
|
if (clone) {
|
|
if (corrupt_fixed)
|
|
- corrupt_bio_data(clone, fc);
|
|
+ corrupt_bio_data(clone, fc,
|
|
+ clone->bi_iter);
|
|
if (corrupt_random)
|
|
- corrupt_bio_random(clone);
|
|
+ corrupt_bio_random(clone,
|
|
+ clone->bi_iter);
|
|
submit_bio(clone);
|
|
return DM_MAPIO_SUBMITTED;
|
|
}
|
|
@@ -559,21 +561,21 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio,
|
|
if (op_is_zone_mgmt(bio_op(bio)))
|
|
return DM_ENDIO_DONE;
|
|
|
|
- if (!*error && pb->bio_submitted && (bio_data_dir(bio) == READ)) {
|
|
+ if (!*error && pb->bio_can_corrupt && (bio_data_dir(bio) == READ)) {
|
|
if (fc->corrupt_bio_byte) {
|
|
if ((fc->corrupt_bio_rw == READ) &&
|
|
all_corrupt_bio_flags_match(bio, fc)) {
|
|
/*
|
|
* Corrupt successful matching READs while in down state.
|
|
*/
|
|
- corrupt_bio_data(bio, fc);
|
|
+ corrupt_bio_data(bio, fc, pb->saved_iter);
|
|
}
|
|
}
|
|
if (fc->random_read_corrupt) {
|
|
u64 rnd = get_random_u64();
|
|
u32 rem = do_div(rnd, PROBABILITY_BASE);
|
|
if (rem < fc->random_read_corrupt)
|
|
- corrupt_bio_random(bio);
|
|
+ corrupt_bio_random(bio, pb->saved_iter);
|
|
}
|
|
if (test_bit(ERROR_READS, &fc->flags)) {
|
|
/*
|
|
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
|
|
index 9ea868bd0d1293..44424554e6b52a 100644
|
|
--- a/drivers/md/dm.c
|
|
+++ b/drivers/md/dm.c
|
|
@@ -2195,21 +2195,29 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
|
|
struct queue_limits *limits)
|
|
{
|
|
struct dm_table *old_map;
|
|
- sector_t size;
|
|
+ sector_t size, old_size;
|
|
int ret;
|
|
|
|
lockdep_assert_held(&md->suspend_lock);
|
|
|
|
size = dm_table_get_size(t);
|
|
|
|
+ old_size = dm_get_size(md);
|
|
+ set_capacity(md->disk, size);
|
|
+
|
|
+ ret = dm_table_set_restrictions(t, md->queue, limits);
|
|
+ if (ret) {
|
|
+ set_capacity(md->disk, old_size);
|
|
+ old_map = ERR_PTR(ret);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
/*
|
|
* Wipe any geometry if the size of the table changed.
|
|
*/
|
|
- if (size != dm_get_size(md))
|
|
+ if (size != old_size)
|
|
memset(&md->geometry, 0, sizeof(md->geometry));
|
|
|
|
- set_capacity(md->disk, size);
|
|
-
|
|
dm_table_event_callback(t, event_callback, md);
|
|
|
|
if (dm_table_request_based(t)) {
|
|
@@ -2227,10 +2235,10 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
|
|
* requests in the queue may refer to bio from the old bioset,
|
|
* so you must walk through the queue to unprep.
|
|
*/
|
|
- if (!md->mempools) {
|
|
+ if (!md->mempools)
|
|
md->mempools = t->mempools;
|
|
- t->mempools = NULL;
|
|
- }
|
|
+ else
|
|
+ dm_free_md_mempools(t->mempools);
|
|
} else {
|
|
/*
|
|
* The md may already have mempools that need changing.
|
|
@@ -2239,14 +2247,8 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
|
|
*/
|
|
dm_free_md_mempools(md->mempools);
|
|
md->mempools = t->mempools;
|
|
- t->mempools = NULL;
|
|
- }
|
|
-
|
|
- ret = dm_table_set_restrictions(t, md->queue, limits);
|
|
- if (ret) {
|
|
- old_map = ERR_PTR(ret);
|
|
- goto out;
|
|
}
|
|
+ t->mempools = NULL;
|
|
|
|
old_map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock));
|
|
rcu_assign_pointer(md->map, (void *)t);
|
|
diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c
|
|
index 1506d8d352b19b..5e39d91b728fc3 100644
|
|
--- a/drivers/mfd/exynos-lpass.c
|
|
+++ b/drivers/mfd/exynos-lpass.c
|
|
@@ -141,7 +141,6 @@ static int exynos_lpass_remove(struct platform_device *pdev)
|
|
{
|
|
struct exynos_lpass *lpass = platform_get_drvdata(pdev);
|
|
|
|
- exynos_lpass_disable(lpass);
|
|
pm_runtime_disable(&pdev->dev);
|
|
if (!pm_runtime_status_suspended(&pdev->dev))
|
|
exynos_lpass_disable(lpass);
|
|
diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c
|
|
index 792236f56399af..b9cc85ea2c4019 100644
|
|
--- a/drivers/mfd/stmpe-spi.c
|
|
+++ b/drivers/mfd/stmpe-spi.c
|
|
@@ -129,7 +129,7 @@ static const struct spi_device_id stmpe_spi_id[] = {
|
|
{ "stmpe2403", STMPE2403 },
|
|
{ }
|
|
};
|
|
-MODULE_DEVICE_TABLE(spi, stmpe_id);
|
|
+MODULE_DEVICE_TABLE(spi, stmpe_spi_id);
|
|
|
|
static struct spi_driver stmpe_spi_driver = {
|
|
.driver = {
|
|
diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c
|
|
index abe79f6fd2a79b..b64944367ac533 100644
|
|
--- a/drivers/misc/vmw_vmci/vmci_host.c
|
|
+++ b/drivers/misc/vmw_vmci/vmci_host.c
|
|
@@ -227,6 +227,7 @@ static int drv_cp_harray_to_user(void __user *user_buf_uva,
|
|
static int vmci_host_setup_notify(struct vmci_ctx *context,
|
|
unsigned long uva)
|
|
{
|
|
+ struct page *page;
|
|
int retval;
|
|
|
|
if (context->notify_page) {
|
|
@@ -243,13 +244,11 @@ static int vmci_host_setup_notify(struct vmci_ctx *context,
|
|
/*
|
|
* Lock physical page backing a given user VA.
|
|
*/
|
|
- retval = get_user_pages_fast(uva, 1, FOLL_WRITE, &context->notify_page);
|
|
- if (retval != 1) {
|
|
- context->notify_page = NULL;
|
|
+ retval = get_user_pages_fast(uva, 1, FOLL_WRITE, &page);
|
|
+ if (retval != 1)
|
|
return VMCI_ERROR_GENERIC;
|
|
- }
|
|
- if (context->notify_page == NULL)
|
|
- return VMCI_ERROR_UNAVAILABLE;
|
|
+
|
|
+ context->notify_page = page;
|
|
|
|
/*
|
|
* Map the locked page and set up notify pointer.
|
|
diff --git a/drivers/mtd/nand/ecc-mxic.c b/drivers/mtd/nand/ecc-mxic.c
|
|
index 47e10945b8d271..63cb206269dd9d 100644
|
|
--- a/drivers/mtd/nand/ecc-mxic.c
|
|
+++ b/drivers/mtd/nand/ecc-mxic.c
|
|
@@ -614,7 +614,7 @@ static int mxic_ecc_finish_io_req_external(struct nand_device *nand,
|
|
{
|
|
struct mxic_ecc_engine *mxic = nand_to_mxic(nand);
|
|
struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand);
|
|
- int nents, step, ret;
|
|
+ int nents, step, ret = 0;
|
|
|
|
if (req->mode == MTD_OPS_RAW)
|
|
return 0;
|
|
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
|
|
index 56c241246d1af4..85ab6925716272 100644
|
|
--- a/drivers/net/bonding/bond_main.c
|
|
+++ b/drivers/net/bonding/bond_main.c
|
|
@@ -2040,15 +2040,26 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
|
|
* set the master's mac address to that of the first slave
|
|
*/
|
|
memcpy(ss.__data, bond_dev->dev_addr, bond_dev->addr_len);
|
|
- ss.ss_family = slave_dev->type;
|
|
- res = dev_set_mac_address(slave_dev, (struct sockaddr *)&ss,
|
|
- extack);
|
|
- if (res) {
|
|
- slave_err(bond_dev, slave_dev, "Error %d calling set_mac_address\n", res);
|
|
- goto err_restore_mtu;
|
|
- }
|
|
+ } else if (bond->params.fail_over_mac == BOND_FOM_FOLLOW &&
|
|
+ BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP &&
|
|
+ memcmp(slave_dev->dev_addr, bond_dev->dev_addr, bond_dev->addr_len) == 0) {
|
|
+ /* Set slave to random address to avoid duplicate mac
|
|
+ * address in later fail over.
|
|
+ */
|
|
+ eth_random_addr(ss.__data);
|
|
+ } else {
|
|
+ goto skip_mac_set;
|
|
}
|
|
|
|
+ ss.ss_family = slave_dev->type;
|
|
+ res = dev_set_mac_address(slave_dev, (struct sockaddr *)&ss, extack);
|
|
+ if (res) {
|
|
+ slave_err(bond_dev, slave_dev, "Error %d calling set_mac_address\n", res);
|
|
+ goto err_restore_mtu;
|
|
+ }
|
|
+
|
|
+skip_mac_set:
|
|
+
|
|
/* set no_addrconf flag before open to prevent IPv6 addrconf */
|
|
slave_dev->priv_flags |= IFF_NO_ADDRCONF;
|
|
|
|
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
|
|
index d2ff2c2fcbbfc4..004d2c988ff097 100644
|
|
--- a/drivers/net/dsa/b53/b53_common.c
|
|
+++ b/drivers/net/dsa/b53/b53_common.c
|
|
@@ -1237,24 +1237,7 @@ static void b53_adjust_63xx_rgmii(struct dsa_switch *ds, int port,
|
|
off = B53_RGMII_CTRL_P(port);
|
|
|
|
b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl);
|
|
-
|
|
- switch (interface) {
|
|
- case PHY_INTERFACE_MODE_RGMII_ID:
|
|
- rgmii_ctrl |= (RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
|
|
- break;
|
|
- case PHY_INTERFACE_MODE_RGMII_RXID:
|
|
- rgmii_ctrl &= ~(RGMII_CTRL_DLL_TXC);
|
|
- rgmii_ctrl |= RGMII_CTRL_DLL_RXC;
|
|
- break;
|
|
- case PHY_INTERFACE_MODE_RGMII_TXID:
|
|
- rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC);
|
|
- rgmii_ctrl |= RGMII_CTRL_DLL_TXC;
|
|
- break;
|
|
- case PHY_INTERFACE_MODE_RGMII:
|
|
- default:
|
|
- rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
|
|
- break;
|
|
- }
|
|
+ rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
|
|
|
|
if (port != dev->imp_port) {
|
|
if (is63268(dev))
|
|
@@ -1394,6 +1377,10 @@ static void b53_phylink_get_caps(struct dsa_switch *ds, int port,
|
|
__set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces);
|
|
__set_bit(PHY_INTERFACE_MODE_REVMII, config->supported_interfaces);
|
|
|
|
+ /* BCM63xx RGMII ports support RGMII */
|
|
+ if (is63xx(dev) && in_range(port, B53_63XX_RGMII0, 4))
|
|
+ phy_interface_set_rgmii(config->supported_interfaces);
|
|
+
|
|
config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
|
MAC_10 | MAC_100;
|
|
|
|
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
|
|
index 8cd098fe88ef26..b4745d94cbbdbf 100644
|
|
--- a/drivers/net/ethernet/google/gve/gve_main.c
|
|
+++ b/drivers/net/ethernet/google/gve/gve_main.c
|
|
@@ -1992,7 +1992,7 @@ void gve_handle_report_stats(struct gve_priv *priv)
|
|
};
|
|
stats[stats_idx++] = (struct stats) {
|
|
.stat_name = cpu_to_be32(RX_BUFFERS_POSTED),
|
|
- .value = cpu_to_be64(priv->rx[0].fill_cnt),
|
|
+ .value = cpu_to_be64(priv->rx[idx].fill_cnt),
|
|
.queue_id = cpu_to_be32(idx),
|
|
};
|
|
}
|
|
diff --git a/drivers/net/ethernet/google/gve/gve_tx_dqo.c b/drivers/net/ethernet/google/gve/gve_tx_dqo.c
|
|
index 89b62b8d16e14b..857749fef37cf2 100644
|
|
--- a/drivers/net/ethernet/google/gve/gve_tx_dqo.c
|
|
+++ b/drivers/net/ethernet/google/gve/gve_tx_dqo.c
|
|
@@ -716,6 +716,9 @@ static int gve_tx_add_skb_dqo(struct gve_tx_ring *tx,
|
|
s16 completion_tag;
|
|
|
|
pkt = gve_alloc_pending_packet(tx);
|
|
+ if (!pkt)
|
|
+ return -ENOMEM;
|
|
+
|
|
pkt->skb = skb;
|
|
completion_tag = pkt - tx->dqo.pending_packets;
|
|
|
|
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
|
|
index d5509bc16d0d57..80036942dc764a 100644
|
|
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
|
|
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
|
|
@@ -1552,8 +1552,8 @@ static void i40e_cleanup_reset_vf(struct i40e_vf *vf)
|
|
* @vf: pointer to the VF structure
|
|
* @flr: VFLR was issued or not
|
|
*
|
|
- * Returns true if the VF is in reset, resets successfully, or resets
|
|
- * are disabled and false otherwise.
|
|
+ * Return: True if reset was performed successfully or if resets are disabled.
|
|
+ * False if reset is already in progress.
|
|
**/
|
|
bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
|
|
{
|
|
@@ -1572,7 +1572,7 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
|
|
|
|
/* If VF is being reset already we don't need to continue. */
|
|
if (test_and_set_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
|
|
- return true;
|
|
+ return false;
|
|
|
|
i40e_trigger_vf_reset(vf, flr);
|
|
|
|
@@ -4332,7 +4332,10 @@ int i40e_vc_process_vflr_event(struct i40e_pf *pf)
|
|
reg = rd32(hw, I40E_GLGEN_VFLRSTAT(reg_idx));
|
|
if (reg & BIT(bit_idx))
|
|
/* i40e_reset_vf will clear the bit in GLGEN_VFLRSTAT */
|
|
- i40e_reset_vf(vf, true);
|
|
+ if (!i40e_reset_vf(vf, true)) {
|
|
+ /* At least one VF did not finish resetting, retry next time */
|
|
+ set_bit(__I40E_VFLR_EVENT_PENDING, pf->state);
|
|
+ }
|
|
}
|
|
|
|
return 0;
|
|
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
|
|
index 0ae7bdfff83fb2..e1a68fb5e9fff0 100644
|
|
--- a/drivers/net/ethernet/intel/ice/ice_main.c
|
|
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
|
|
@@ -2650,6 +2650,27 @@ static void ice_vsi_assign_bpf_prog(struct ice_vsi *vsi, struct bpf_prog *prog)
|
|
bpf_prog_put(old_prog);
|
|
}
|
|
|
|
+/**
|
|
+ * ice_unmap_xdp_rings - Unmap XDP rings from interrupt vectors
|
|
+ * @vsi: the VSI with XDP rings being unmapped
|
|
+ */
|
|
+static void ice_unmap_xdp_rings(struct ice_vsi *vsi)
|
|
+{
|
|
+ int v_idx;
|
|
+
|
|
+ ice_for_each_q_vector(vsi, v_idx) {
|
|
+ struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];
|
|
+ struct ice_tx_ring *ring;
|
|
+
|
|
+ ice_for_each_tx_ring(ring, q_vector->tx)
|
|
+ if (!ring->tx_buf || !ice_ring_is_xdp(ring))
|
|
+ break;
|
|
+
|
|
+ /* restore the value of last node prior to XDP setup */
|
|
+ q_vector->tx.tx_ring = ring;
|
|
+ }
|
|
+}
|
|
+
|
|
/**
|
|
* ice_prepare_xdp_rings - Allocate, configure and setup Tx rings for XDP
|
|
* @vsi: VSI to bring up Tx rings used by XDP
|
|
@@ -2749,7 +2770,7 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
|
|
if (status) {
|
|
dev_err(dev, "Failed VSI LAN queue config for XDP, error: %d\n",
|
|
status);
|
|
- goto clear_xdp_rings;
|
|
+ goto unmap_xdp_rings;
|
|
}
|
|
|
|
/* assign the prog only when it's not already present on VSI;
|
|
@@ -2765,6 +2786,8 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
|
|
ice_vsi_assign_bpf_prog(vsi, prog);
|
|
|
|
return 0;
|
|
+unmap_xdp_rings:
|
|
+ ice_unmap_xdp_rings(vsi);
|
|
clear_xdp_rings:
|
|
ice_for_each_xdp_txq(vsi, i)
|
|
if (vsi->xdp_rings[i]) {
|
|
@@ -2781,6 +2804,8 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
|
|
mutex_unlock(&pf->avail_q_mutex);
|
|
|
|
devm_kfree(dev, vsi->xdp_rings);
|
|
+ vsi->xdp_rings = NULL;
|
|
+
|
|
return -ENOMEM;
|
|
}
|
|
|
|
@@ -2796,7 +2821,7 @@ int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type)
|
|
{
|
|
u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
|
|
struct ice_pf *pf = vsi->back;
|
|
- int i, v_idx;
|
|
+ int i;
|
|
|
|
/* q_vectors are freed in reset path so there's no point in detaching
|
|
* rings
|
|
@@ -2804,17 +2829,7 @@ int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type)
|
|
if (cfg_type == ICE_XDP_CFG_PART)
|
|
goto free_qmap;
|
|
|
|
- ice_for_each_q_vector(vsi, v_idx) {
|
|
- struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];
|
|
- struct ice_tx_ring *ring;
|
|
-
|
|
- ice_for_each_tx_ring(ring, q_vector->tx)
|
|
- if (!ring->tx_buf || !ice_ring_is_xdp(ring))
|
|
- break;
|
|
-
|
|
- /* restore the value of last node prior to XDP setup */
|
|
- q_vector->tx.tx_ring = ring;
|
|
- }
|
|
+ ice_unmap_xdp_rings(vsi);
|
|
|
|
free_qmap:
|
|
mutex_lock(&pf->avail_q_mutex);
|
|
@@ -2956,11 +2971,14 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
|
|
xdp_ring_err = ice_vsi_determine_xdp_res(vsi);
|
|
if (xdp_ring_err) {
|
|
NL_SET_ERR_MSG_MOD(extack, "Not enough Tx resources for XDP");
|
|
+ goto resume_if;
|
|
} else {
|
|
xdp_ring_err = ice_prepare_xdp_rings(vsi, prog,
|
|
ICE_XDP_CFG_FULL);
|
|
- if (xdp_ring_err)
|
|
+ if (xdp_ring_err) {
|
|
NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed");
|
|
+ goto resume_if;
|
|
+ }
|
|
}
|
|
xdp_features_set_redirect_target(vsi->netdev, true);
|
|
/* reallocate Rx queues that are used for zero-copy */
|
|
@@ -2978,6 +2996,7 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
|
|
NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Rx resources failed");
|
|
}
|
|
|
|
+resume_if:
|
|
if (if_running)
|
|
ret = ice_up(vsi);
|
|
|
|
diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c
|
|
index 908bcd07380333..c2de166f055150 100644
|
|
--- a/drivers/net/ethernet/intel/ice/ice_sched.c
|
|
+++ b/drivers/net/ethernet/intel/ice/ice_sched.c
|
|
@@ -84,6 +84,27 @@ ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid)
|
|
return NULL;
|
|
}
|
|
|
|
+/**
|
|
+ * ice_sched_find_next_vsi_node - find the next node for a given VSI
|
|
+ * @vsi_node: VSI support node to start search with
|
|
+ *
|
|
+ * Return: Next VSI support node, or NULL.
|
|
+ *
|
|
+ * The function returns a pointer to the next node from the VSI layer
|
|
+ * assigned to the given VSI, or NULL if there is no such a node.
|
|
+ */
|
|
+static struct ice_sched_node *
|
|
+ice_sched_find_next_vsi_node(struct ice_sched_node *vsi_node)
|
|
+{
|
|
+ unsigned int vsi_handle = vsi_node->vsi_handle;
|
|
+
|
|
+ while ((vsi_node = vsi_node->sibling) != NULL)
|
|
+ if (vsi_node->vsi_handle == vsi_handle)
|
|
+ break;
|
|
+
|
|
+ return vsi_node;
|
|
+}
|
|
+
|
|
/**
|
|
* ice_aqc_send_sched_elem_cmd - send scheduling elements cmd
|
|
* @hw: pointer to the HW struct
|
|
@@ -1096,8 +1117,10 @@ ice_sched_add_nodes_to_layer(struct ice_port_info *pi,
|
|
if (parent->num_children < max_child_nodes) {
|
|
new_num_nodes = max_child_nodes - parent->num_children;
|
|
} else {
|
|
- /* This parent is full, try the next sibling */
|
|
- parent = parent->sibling;
|
|
+ /* This parent is full,
|
|
+ * try the next available sibling.
|
|
+ */
|
|
+ parent = ice_sched_find_next_vsi_node(parent);
|
|
/* Don't modify the first node TEID memory if the
|
|
* first node was added already in the above call.
|
|
* Instead send some temp memory for all other
|
|
@@ -1538,12 +1561,23 @@ ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
|
|
/* get the first queue group node from VSI sub-tree */
|
|
qgrp_node = ice_sched_get_first_node(pi, vsi_node, qgrp_layer);
|
|
while (qgrp_node) {
|
|
+ struct ice_sched_node *next_vsi_node;
|
|
+
|
|
/* make sure the qgroup node is part of the VSI subtree */
|
|
if (ice_sched_find_node_in_subtree(pi->hw, vsi_node, qgrp_node))
|
|
if (qgrp_node->num_children < max_children &&
|
|
qgrp_node->owner == owner)
|
|
break;
|
|
qgrp_node = qgrp_node->sibling;
|
|
+ if (qgrp_node)
|
|
+ continue;
|
|
+
|
|
+ next_vsi_node = ice_sched_find_next_vsi_node(vsi_node);
|
|
+ if (!next_vsi_node)
|
|
+ break;
|
|
+
|
|
+ vsi_node = next_vsi_node;
|
|
+ qgrp_node = ice_sched_get_first_node(pi, vsi_node, qgrp_layer);
|
|
}
|
|
|
|
/* Select the best queue group */
|
|
@@ -1614,16 +1648,16 @@ ice_sched_get_agg_node(struct ice_port_info *pi, struct ice_sched_node *tc_node,
|
|
/**
|
|
* ice_sched_calc_vsi_child_nodes - calculate number of VSI child nodes
|
|
* @hw: pointer to the HW struct
|
|
- * @num_qs: number of queues
|
|
+ * @num_new_qs: number of new queues that will be added to the tree
|
|
* @num_nodes: num nodes array
|
|
*
|
|
* This function calculates the number of VSI child nodes based on the
|
|
* number of queues.
|
|
*/
|
|
static void
|
|
-ice_sched_calc_vsi_child_nodes(struct ice_hw *hw, u16 num_qs, u16 *num_nodes)
|
|
+ice_sched_calc_vsi_child_nodes(struct ice_hw *hw, u16 num_new_qs, u16 *num_nodes)
|
|
{
|
|
- u16 num = num_qs;
|
|
+ u16 num = num_new_qs;
|
|
u8 i, qgl, vsil;
|
|
|
|
qgl = ice_sched_get_qgrp_layer(hw);
|
|
@@ -1789,7 +1823,11 @@ ice_sched_add_vsi_support_nodes(struct ice_port_info *pi, u16 vsi_handle,
|
|
if (!parent)
|
|
return -EIO;
|
|
|
|
- if (i == vsil)
|
|
+ /* Do not modify the VSI handle for already existing VSI nodes,
|
|
+ * (if no new VSI node was added to the tree).
|
|
+ * Assign the VSI handle only to newly added VSI nodes.
|
|
+ */
|
|
+ if (i == vsil && num_added)
|
|
parent->vsi_handle = vsi_handle;
|
|
}
|
|
|
|
@@ -1822,6 +1860,41 @@ ice_sched_add_vsi_to_topo(struct ice_port_info *pi, u16 vsi_handle, u8 tc)
|
|
num_nodes);
|
|
}
|
|
|
|
+/**
|
|
+ * ice_sched_recalc_vsi_support_nodes - recalculate VSI support nodes count
|
|
+ * @hw: pointer to the HW struct
|
|
+ * @vsi_node: pointer to the leftmost VSI node that needs to be extended
|
|
+ * @new_numqs: new number of queues that has to be handled by the VSI
|
|
+ * @new_num_nodes: pointer to nodes count table to modify the VSI layer entry
|
|
+ *
|
|
+ * This function recalculates the number of supported nodes that need to
|
|
+ * be added after adding more Tx queues for a given VSI.
|
|
+ * The number of new VSI support nodes that shall be added will be saved
|
|
+ * to the @new_num_nodes table for the VSI layer.
|
|
+ */
|
|
+static void
|
|
+ice_sched_recalc_vsi_support_nodes(struct ice_hw *hw,
|
|
+ struct ice_sched_node *vsi_node,
|
|
+ unsigned int new_numqs, u16 *new_num_nodes)
|
|
+{
|
|
+ u32 vsi_nodes_cnt = 1;
|
|
+ u32 max_queue_cnt = 1;
|
|
+ u32 qgl, vsil;
|
|
+
|
|
+ qgl = ice_sched_get_qgrp_layer(hw);
|
|
+ vsil = ice_sched_get_vsi_layer(hw);
|
|
+
|
|
+ for (u32 i = vsil; i <= qgl; i++)
|
|
+ max_queue_cnt *= hw->max_children[i];
|
|
+
|
|
+ while ((vsi_node = ice_sched_find_next_vsi_node(vsi_node)) != NULL)
|
|
+ vsi_nodes_cnt++;
|
|
+
|
|
+ if (new_numqs > (max_queue_cnt * vsi_nodes_cnt))
|
|
+ new_num_nodes[vsil] = DIV_ROUND_UP(new_numqs, max_queue_cnt) -
|
|
+ vsi_nodes_cnt;
|
|
+}
|
|
+
|
|
/**
|
|
* ice_sched_update_vsi_child_nodes - update VSI child nodes
|
|
* @pi: port information structure
|
|
@@ -1873,15 +1946,25 @@ ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
|
|
return status;
|
|
}
|
|
|
|
- if (new_numqs)
|
|
- ice_sched_calc_vsi_child_nodes(hw, new_numqs, new_num_nodes);
|
|
- /* Keep the max number of queue configuration all the time. Update the
|
|
- * tree only if number of queues > previous number of queues. This may
|
|
+ ice_sched_recalc_vsi_support_nodes(hw, vsi_node,
|
|
+ new_numqs, new_num_nodes);
|
|
+ ice_sched_calc_vsi_child_nodes(hw, new_numqs - prev_numqs,
|
|
+ new_num_nodes);
|
|
+
|
|
+ /* Never decrease the number of queues in the tree. Update the tree
|
|
+ * only if number of queues > previous number of queues. This may
|
|
* leave some extra nodes in the tree if number of queues < previous
|
|
* number but that wouldn't harm anything. Removing those extra nodes
|
|
* may complicate the code if those nodes are part of SRL or
|
|
* individually rate limited.
|
|
+ * Also, add the required VSI support nodes if the existing ones cannot
|
|
+ * handle the requested new number of queues.
|
|
*/
|
|
+ status = ice_sched_add_vsi_support_nodes(pi, vsi_handle, tc_node,
|
|
+ new_num_nodes);
|
|
+ if (status)
|
|
+ return status;
|
|
+
|
|
status = ice_sched_add_vsi_child_nodes(pi, vsi_handle, tc_node,
|
|
new_num_nodes, owner);
|
|
if (status)
|
|
@@ -2022,6 +2105,58 @@ static bool ice_sched_is_leaf_node_present(struct ice_sched_node *node)
|
|
return (node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF);
|
|
}
|
|
|
|
+/**
|
|
+ * ice_sched_rm_vsi_subtree - remove all nodes assigned to a given VSI
|
|
+ * @pi: port information structure
|
|
+ * @vsi_node: pointer to the leftmost node of the VSI to be removed
|
|
+ * @owner: LAN or RDMA
|
|
+ * @tc: TC number
|
|
+ *
|
|
+ * Return: Zero in case of success, or -EBUSY if the VSI has leaf nodes in TC.
|
|
+ *
|
|
+ * This function removes all the VSI support nodes associated with a given VSI
|
|
+ * and its LAN or RDMA children nodes from the scheduler tree.
|
|
+ */
|
|
+static int
|
|
+ice_sched_rm_vsi_subtree(struct ice_port_info *pi,
|
|
+ struct ice_sched_node *vsi_node, u8 owner, u8 tc)
|
|
+{
|
|
+ u16 vsi_handle = vsi_node->vsi_handle;
|
|
+ bool all_vsi_nodes_removed = true;
|
|
+ int j = 0;
|
|
+
|
|
+ while (vsi_node) {
|
|
+ struct ice_sched_node *next_vsi_node;
|
|
+
|
|
+ if (ice_sched_is_leaf_node_present(vsi_node)) {
|
|
+ ice_debug(pi->hw, ICE_DBG_SCHED, "VSI has leaf nodes in TC %d\n", tc);
|
|
+ return -EBUSY;
|
|
+ }
|
|
+ while (j < vsi_node->num_children) {
|
|
+ if (vsi_node->children[j]->owner == owner)
|
|
+ ice_free_sched_node(pi, vsi_node->children[j]);
|
|
+ else
|
|
+ j++;
|
|
+ }
|
|
+
|
|
+ next_vsi_node = ice_sched_find_next_vsi_node(vsi_node);
|
|
+
|
|
+ /* remove the VSI if it has no children */
|
|
+ if (!vsi_node->num_children)
|
|
+ ice_free_sched_node(pi, vsi_node);
|
|
+ else
|
|
+ all_vsi_nodes_removed = false;
|
|
+
|
|
+ vsi_node = next_vsi_node;
|
|
+ }
|
|
+
|
|
+ /* clean up aggregator related VSI info if any */
|
|
+ if (all_vsi_nodes_removed)
|
|
+ ice_sched_rm_agg_vsi_info(pi, vsi_handle);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/**
|
|
* ice_sched_rm_vsi_cfg - remove the VSI and its children nodes
|
|
* @pi: port information structure
|
|
@@ -2048,7 +2183,6 @@ ice_sched_rm_vsi_cfg(struct ice_port_info *pi, u16 vsi_handle, u8 owner)
|
|
|
|
ice_for_each_traffic_class(i) {
|
|
struct ice_sched_node *vsi_node, *tc_node;
|
|
- u8 j = 0;
|
|
|
|
tc_node = ice_sched_get_tc_node(pi, i);
|
|
if (!tc_node)
|
|
@@ -2058,31 +2192,12 @@ ice_sched_rm_vsi_cfg(struct ice_port_info *pi, u16 vsi_handle, u8 owner)
|
|
if (!vsi_node)
|
|
continue;
|
|
|
|
- if (ice_sched_is_leaf_node_present(vsi_node)) {
|
|
- ice_debug(pi->hw, ICE_DBG_SCHED, "VSI has leaf nodes in TC %d\n", i);
|
|
- status = -EBUSY;
|
|
+ status = ice_sched_rm_vsi_subtree(pi, vsi_node, owner, i);
|
|
+ if (status)
|
|
goto exit_sched_rm_vsi_cfg;
|
|
- }
|
|
- while (j < vsi_node->num_children) {
|
|
- if (vsi_node->children[j]->owner == owner) {
|
|
- ice_free_sched_node(pi, vsi_node->children[j]);
|
|
|
|
- /* reset the counter again since the num
|
|
- * children will be updated after node removal
|
|
- */
|
|
- j = 0;
|
|
- } else {
|
|
- j++;
|
|
- }
|
|
- }
|
|
- /* remove the VSI if it has no children */
|
|
- if (!vsi_node->num_children) {
|
|
- ice_free_sched_node(pi, vsi_node);
|
|
- vsi_ctx->sched.vsi_node[i] = NULL;
|
|
+ vsi_ctx->sched.vsi_node[i] = NULL;
|
|
|
|
- /* clean up aggregator related VSI info if any */
|
|
- ice_sched_rm_agg_vsi_info(pi, vsi_handle);
|
|
- }
|
|
if (owner == ICE_SCHED_NODE_OWNER_LAN)
|
|
vsi_ctx->sched.max_lanq[i] = 0;
|
|
else
|
|
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
|
|
index 37db19584c1431..92861f102590fe 100644
|
|
--- a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
|
|
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
|
|
@@ -1560,6 +1560,7 @@ static int otx2_qos_leaf_del_last(struct otx2_nic *pfvf, u16 classid, bool force
|
|
if (!node->is_static)
|
|
dwrr_del_node = true;
|
|
|
|
+ WRITE_ONCE(node->qid, OTX2_QOS_QID_INNER);
|
|
/* destroy the leaf node */
|
|
otx2_qos_disable_sq(pfvf, qid);
|
|
otx2_qos_destroy_node(pfvf, node);
|
|
@@ -1604,9 +1605,6 @@ static int otx2_qos_leaf_del_last(struct otx2_nic *pfvf, u16 classid, bool force
|
|
}
|
|
kfree(new_cfg);
|
|
|
|
- /* update tx_real_queues */
|
|
- otx2_qos_update_tx_netdev_queues(pfvf);
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
|
|
index c2ab87828d8589..5eb7a97e7eb177 100644
|
|
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
|
|
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
|
|
@@ -1468,6 +1468,8 @@ static __maybe_unused int mtk_star_suspend(struct device *dev)
|
|
if (netif_running(ndev))
|
|
mtk_star_disable(ndev);
|
|
|
|
+ netif_device_detach(ndev);
|
|
+
|
|
clk_bulk_disable_unprepare(MTK_STAR_NCLKS, priv->clks);
|
|
|
|
return 0;
|
|
@@ -1492,6 +1494,8 @@ static __maybe_unused int mtk_star_resume(struct device *dev)
|
|
clk_bulk_disable_unprepare(MTK_STAR_NCLKS, priv->clks);
|
|
}
|
|
|
|
+ netif_device_attach(ndev);
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
|
|
index 9e3b761820881e..2d5b86207e0795 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
|
|
@@ -249,7 +249,7 @@ static const struct ptp_clock_info mlx4_en_ptp_clock_info = {
|
|
static u32 freq_to_shift(u16 freq)
|
|
{
|
|
u32 freq_khz = freq * 1000;
|
|
- u64 max_val_cycles = freq_khz * 1000 * MLX4_EN_WRAP_AROUND_SEC;
|
|
+ u64 max_val_cycles = freq_khz * 1000ULL * MLX4_EN_WRAP_AROUND_SEC;
|
|
u64 max_val_cycles_rounded = 1ULL << fls64(max_val_cycles - 1);
|
|
/* calculate max possible multiplier in order to fit in 64bit */
|
|
u64 max_mul = div64_u64(ULLONG_MAX, max_val_cycles_rounded);
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
|
|
index 463c23ae0ad1ec..5161bf51fa110c 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
|
|
@@ -1093,7 +1093,7 @@ mlx5e_ipsec_build_accel_pol_attrs(struct mlx5e_ipsec_pol_entry *pol_entry,
|
|
static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
|
|
struct netlink_ext_ack *extack)
|
|
{
|
|
- struct net_device *netdev = x->xdo.real_dev;
|
|
+ struct net_device *netdev = x->xdo.dev;
|
|
struct mlx5e_ipsec_pol_entry *pol_entry;
|
|
struct mlx5e_priv *priv;
|
|
int err;
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
|
|
index dc9b157a449935..2be9c69daad5fe 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
|
|
@@ -1915,9 +1915,8 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
|
|
return err;
|
|
}
|
|
|
|
-static bool mlx5_flow_has_geneve_opt(struct mlx5e_tc_flow *flow)
|
|
+static bool mlx5_flow_has_geneve_opt(struct mlx5_flow_spec *spec)
|
|
{
|
|
- struct mlx5_flow_spec *spec = &flow->attr->parse_attr->spec;
|
|
void *headers_v = MLX5_ADDR_OF(fte_match_param,
|
|
spec->match_value,
|
|
misc_parameters_3);
|
|
@@ -1956,7 +1955,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
|
|
}
|
|
complete_all(&flow->del_hw_done);
|
|
|
|
- if (mlx5_flow_has_geneve_opt(flow))
|
|
+ if (mlx5_flow_has_geneve_opt(&attr->parse_attr->spec))
|
|
mlx5_geneve_tlv_option_del(priv->mdev->geneve);
|
|
|
|
if (flow->decap_route)
|
|
@@ -2456,12 +2455,13 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,
|
|
|
|
err = mlx5e_tc_tun_parse(filter_dev, priv, tmp_spec, f, match_level);
|
|
if (err) {
|
|
- kvfree(tmp_spec);
|
|
NL_SET_ERR_MSG_MOD(extack, "Failed to parse tunnel attributes");
|
|
netdev_warn(priv->netdev, "Failed to parse tunnel attributes");
|
|
- return err;
|
|
+ } else {
|
|
+ err = mlx5e_tc_set_attr_rx_tun(flow, tmp_spec);
|
|
}
|
|
- err = mlx5e_tc_set_attr_rx_tun(flow, tmp_spec);
|
|
+ if (mlx5_flow_has_geneve_opt(tmp_spec))
|
|
+ mlx5_geneve_tlv_option_del(priv->mdev->geneve);
|
|
kvfree(tmp_spec);
|
|
if (err)
|
|
return err;
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
|
|
index f6022c135ec023..914b380fd3eeb5 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
|
|
@@ -1295,12 +1295,15 @@ mlx5_eswitch_enable_pf_vf_vports(struct mlx5_eswitch *esw,
|
|
ret = mlx5_eswitch_load_pf_vf_vport(esw, MLX5_VPORT_ECPF, enabled_events);
|
|
if (ret)
|
|
goto ecpf_err;
|
|
- if (mlx5_core_ec_sriov_enabled(esw->dev)) {
|
|
- ret = mlx5_eswitch_load_ec_vf_vports(esw, esw->esw_funcs.num_ec_vfs,
|
|
- enabled_events);
|
|
- if (ret)
|
|
- goto ec_vf_err;
|
|
- }
|
|
+ }
|
|
+
|
|
+ /* Enable ECVF vports */
|
|
+ if (mlx5_core_ec_sriov_enabled(esw->dev)) {
|
|
+ ret = mlx5_eswitch_load_ec_vf_vports(esw,
|
|
+ esw->esw_funcs.num_ec_vfs,
|
|
+ enabled_events);
|
|
+ if (ret)
|
|
+ goto ec_vf_err;
|
|
}
|
|
|
|
/* Enable VF vports */
|
|
@@ -1331,9 +1334,11 @@ void mlx5_eswitch_disable_pf_vf_vports(struct mlx5_eswitch *esw)
|
|
{
|
|
mlx5_eswitch_unload_vf_vports(esw, esw->esw_funcs.num_vfs);
|
|
|
|
+ if (mlx5_core_ec_sriov_enabled(esw->dev))
|
|
+ mlx5_eswitch_unload_ec_vf_vports(esw,
|
|
+ esw->esw_funcs.num_ec_vfs);
|
|
+
|
|
if (mlx5_ecpf_vport_exists(esw->dev)) {
|
|
- if (mlx5_core_ec_sriov_enabled(esw->dev))
|
|
- mlx5_eswitch_unload_ec_vf_vports(esw, esw->esw_funcs.num_vfs);
|
|
mlx5_eswitch_unload_pf_vf_vport(esw, MLX5_VPORT_ECPF);
|
|
}
|
|
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
|
|
index d2dc375f5e49cb..5f35a6fc030544 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
|
|
@@ -1984,6 +1984,7 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
|
|
struct mlx5_flow_handle *rule;
|
|
struct match_list *iter;
|
|
bool take_write = false;
|
|
+ bool try_again = false;
|
|
struct fs_fte *fte;
|
|
u64 version = 0;
|
|
int err;
|
|
@@ -2043,6 +2044,7 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
|
|
nested_down_write_ref_node(&g->node, FS_LOCK_PARENT);
|
|
|
|
if (!g->node.active) {
|
|
+ try_again = true;
|
|
up_write_ref_node(&g->node, false);
|
|
continue;
|
|
}
|
|
@@ -2064,7 +2066,8 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
|
|
tree_put_node(&fte->node, false);
|
|
return rule;
|
|
}
|
|
- rule = ERR_PTR(-ENOENT);
|
|
+ err = try_again ? -EAGAIN : -ENOENT;
|
|
+ rule = ERR_PTR(err);
|
|
out:
|
|
kmem_cache_free(steering->ftes_cache, fte);
|
|
return rule;
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
|
|
index dcf58efac159cf..e0581c6f9cecd5 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
|
|
@@ -291,7 +291,7 @@ static void free_4k(struct mlx5_core_dev *dev, u64 addr, u32 function)
|
|
static int alloc_system_page(struct mlx5_core_dev *dev, u32 function)
|
|
{
|
|
struct device *device = mlx5_core_dma_dev(dev);
|
|
- int nid = dev_to_node(device);
|
|
+ int nid = dev->priv.numa_node;
|
|
struct page *page;
|
|
u64 zero_addr = 1;
|
|
u64 addr;
|
|
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
|
|
index f971d60484f065..781440d5756f34 100644
|
|
--- a/drivers/net/ethernet/microchip/lan743x_main.c
|
|
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
|
|
@@ -1373,7 +1373,7 @@ static int lan743x_mac_set_mtu(struct lan743x_adapter *adapter, int new_mtu)
|
|
}
|
|
|
|
/* PHY */
|
|
-static int lan743x_phy_reset(struct lan743x_adapter *adapter)
|
|
+static int lan743x_hw_reset_phy(struct lan743x_adapter *adapter)
|
|
{
|
|
u32 data;
|
|
|
|
@@ -1407,7 +1407,7 @@ static void lan743x_phy_update_flowcontrol(struct lan743x_adapter *adapter,
|
|
|
|
static int lan743x_phy_init(struct lan743x_adapter *adapter)
|
|
{
|
|
- return lan743x_phy_reset(adapter);
|
|
+ return lan743x_hw_reset_phy(adapter);
|
|
}
|
|
|
|
static void lan743x_phy_link_status_change(struct net_device *netdev)
|
|
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
|
|
index c3f6c10bc23936..b424e75fd40c46 100644
|
|
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
|
|
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
|
|
@@ -353,6 +353,11 @@ static void lan966x_ifh_set_rew_op(void *ifh, u64 rew_op)
|
|
lan966x_ifh_set(ifh, rew_op, IFH_POS_REW_CMD, IFH_WID_REW_CMD);
|
|
}
|
|
|
|
+static void lan966x_ifh_set_oam_type(void *ifh, u64 oam_type)
|
|
+{
|
|
+ lan966x_ifh_set(ifh, oam_type, IFH_POS_PDU_TYPE, IFH_WID_PDU_TYPE);
|
|
+}
|
|
+
|
|
static void lan966x_ifh_set_timestamp(void *ifh, u64 timestamp)
|
|
{
|
|
lan966x_ifh_set(ifh, timestamp, IFH_POS_TIMESTAMP, IFH_WID_TIMESTAMP);
|
|
@@ -380,6 +385,7 @@ static netdev_tx_t lan966x_port_xmit(struct sk_buff *skb,
|
|
return err;
|
|
|
|
lan966x_ifh_set_rew_op(ifh, LAN966X_SKB_CB(skb)->rew_op);
|
|
+ lan966x_ifh_set_oam_type(ifh, LAN966X_SKB_CB(skb)->pdu_type);
|
|
lan966x_ifh_set_timestamp(ifh, LAN966X_SKB_CB(skb)->ts_id);
|
|
}
|
|
|
|
@@ -875,6 +881,7 @@ static int lan966x_probe_port(struct lan966x *lan966x, u32 p,
|
|
lan966x_vlan_port_set_vlan_aware(port, 0);
|
|
lan966x_vlan_port_set_vid(port, HOST_PVID, false, false);
|
|
lan966x_vlan_port_apply(port);
|
|
+ lan966x_vlan_port_rew_host(port);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
|
|
index caa9e0533c96b3..5a16d76eb000d6 100644
|
|
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
|
|
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
|
|
@@ -74,6 +74,10 @@
|
|
#define IFH_REW_OP_ONE_STEP_PTP 0x3
|
|
#define IFH_REW_OP_TWO_STEP_PTP 0x4
|
|
|
|
+#define IFH_PDU_TYPE_NONE 0
|
|
+#define IFH_PDU_TYPE_IPV4 7
|
|
+#define IFH_PDU_TYPE_IPV6 8
|
|
+
|
|
#define FDMA_RX_DCB_MAX_DBS 1
|
|
#define FDMA_TX_DCB_MAX_DBS 1
|
|
#define FDMA_DCB_INFO_DATAL(x) ((x) & GENMASK(15, 0))
|
|
@@ -306,6 +310,7 @@ struct lan966x_phc {
|
|
|
|
struct lan966x_skb_cb {
|
|
u8 rew_op;
|
|
+ u8 pdu_type;
|
|
u16 ts_id;
|
|
unsigned long jiffies;
|
|
};
|
|
@@ -544,6 +549,7 @@ void lan966x_vlan_port_apply(struct lan966x_port *port);
|
|
bool lan966x_vlan_cpu_member_cpu_vlan_mask(struct lan966x *lan966x, u16 vid);
|
|
void lan966x_vlan_port_set_vlan_aware(struct lan966x_port *port,
|
|
bool vlan_aware);
|
|
+void lan966x_vlan_port_rew_host(struct lan966x_port *port);
|
|
int lan966x_vlan_port_set_vid(struct lan966x_port *port,
|
|
u16 vid,
|
|
bool pvid,
|
|
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
|
|
index 63905bb5a63a83..87e5e81d40dc68 100644
|
|
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
|
|
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c
|
|
@@ -322,34 +322,55 @@ void lan966x_ptp_hwtstamp_get(struct lan966x_port *port,
|
|
*cfg = phc->hwtstamp_config;
|
|
}
|
|
|
|
-static int lan966x_ptp_classify(struct lan966x_port *port, struct sk_buff *skb)
|
|
+static void lan966x_ptp_classify(struct lan966x_port *port, struct sk_buff *skb,
|
|
+ u8 *rew_op, u8 *pdu_type)
|
|
{
|
|
struct ptp_header *header;
|
|
u8 msgtype;
|
|
int type;
|
|
|
|
- if (port->ptp_tx_cmd == IFH_REW_OP_NOOP)
|
|
- return IFH_REW_OP_NOOP;
|
|
+ if (port->ptp_tx_cmd == IFH_REW_OP_NOOP) {
|
|
+ *rew_op = IFH_REW_OP_NOOP;
|
|
+ *pdu_type = IFH_PDU_TYPE_NONE;
|
|
+ return;
|
|
+ }
|
|
|
|
type = ptp_classify_raw(skb);
|
|
- if (type == PTP_CLASS_NONE)
|
|
- return IFH_REW_OP_NOOP;
|
|
+ if (type == PTP_CLASS_NONE) {
|
|
+ *rew_op = IFH_REW_OP_NOOP;
|
|
+ *pdu_type = IFH_PDU_TYPE_NONE;
|
|
+ return;
|
|
+ }
|
|
|
|
header = ptp_parse_header(skb, type);
|
|
- if (!header)
|
|
- return IFH_REW_OP_NOOP;
|
|
+ if (!header) {
|
|
+ *rew_op = IFH_REW_OP_NOOP;
|
|
+ *pdu_type = IFH_PDU_TYPE_NONE;
|
|
+ return;
|
|
+ }
|
|
|
|
- if (port->ptp_tx_cmd == IFH_REW_OP_TWO_STEP_PTP)
|
|
- return IFH_REW_OP_TWO_STEP_PTP;
|
|
+ if (type & PTP_CLASS_L2)
|
|
+ *pdu_type = IFH_PDU_TYPE_NONE;
|
|
+ if (type & PTP_CLASS_IPV4)
|
|
+ *pdu_type = IFH_PDU_TYPE_IPV4;
|
|
+ if (type & PTP_CLASS_IPV6)
|
|
+ *pdu_type = IFH_PDU_TYPE_IPV6;
|
|
+
|
|
+ if (port->ptp_tx_cmd == IFH_REW_OP_TWO_STEP_PTP) {
|
|
+ *rew_op = IFH_REW_OP_TWO_STEP_PTP;
|
|
+ return;
|
|
+ }
|
|
|
|
/* If it is sync and run 1 step then set the correct operation,
|
|
* otherwise run as 2 step
|
|
*/
|
|
msgtype = ptp_get_msgtype(header, type);
|
|
- if ((msgtype & 0xf) == 0)
|
|
- return IFH_REW_OP_ONE_STEP_PTP;
|
|
+ if ((msgtype & 0xf) == 0) {
|
|
+ *rew_op = IFH_REW_OP_ONE_STEP_PTP;
|
|
+ return;
|
|
+ }
|
|
|
|
- return IFH_REW_OP_TWO_STEP_PTP;
|
|
+ *rew_op = IFH_REW_OP_TWO_STEP_PTP;
|
|
}
|
|
|
|
static void lan966x_ptp_txtstamp_old_release(struct lan966x_port *port)
|
|
@@ -374,10 +395,12 @@ int lan966x_ptp_txtstamp_request(struct lan966x_port *port,
|
|
{
|
|
struct lan966x *lan966x = port->lan966x;
|
|
unsigned long flags;
|
|
+ u8 pdu_type;
|
|
u8 rew_op;
|
|
|
|
- rew_op = lan966x_ptp_classify(port, skb);
|
|
+ lan966x_ptp_classify(port, skb, &rew_op, &pdu_type);
|
|
LAN966X_SKB_CB(skb)->rew_op = rew_op;
|
|
+ LAN966X_SKB_CB(skb)->pdu_type = pdu_type;
|
|
|
|
if (rew_op != IFH_REW_OP_TWO_STEP_PTP)
|
|
return 0;
|
|
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c b/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c
|
|
index 1c88120eb291a2..bcb4db76b75cd5 100644
|
|
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c
|
|
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c
|
|
@@ -297,6 +297,7 @@ static void lan966x_port_bridge_leave(struct lan966x_port *port,
|
|
lan966x_vlan_port_set_vlan_aware(port, false);
|
|
lan966x_vlan_port_set_vid(port, HOST_PVID, false, false);
|
|
lan966x_vlan_port_apply(port);
|
|
+ lan966x_vlan_port_rew_host(port);
|
|
}
|
|
|
|
int lan966x_port_changeupper(struct net_device *dev,
|
|
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c b/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c
|
|
index 3c44660128daed..ffb245fb7d6786 100644
|
|
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c
|
|
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c
|
|
@@ -149,6 +149,27 @@ void lan966x_vlan_port_set_vlan_aware(struct lan966x_port *port,
|
|
port->vlan_aware = vlan_aware;
|
|
}
|
|
|
|
+/* When the interface is in host mode, the interface should not be vlan aware
|
|
+ * but it should insert all the tags that it gets from the network stack.
|
|
+ * The tags are not in the data of the frame but actually in the skb and the ifh
|
|
+ * is configured already to get this tag. So what we need to do is to update the
|
|
+ * rewriter to insert the vlan tag for all frames which have a vlan tag
|
|
+ * different than 0.
|
|
+ */
|
|
+void lan966x_vlan_port_rew_host(struct lan966x_port *port)
|
|
+{
|
|
+ struct lan966x *lan966x = port->lan966x;
|
|
+ u32 val;
|
|
+
|
|
+ /* Tag all frames except when VID=0*/
|
|
+ val = REW_TAG_CFG_TAG_CFG_SET(2);
|
|
+
|
|
+ /* Update only some bits in the register */
|
|
+ lan_rmw(val,
|
|
+ REW_TAG_CFG_TAG_CFG,
|
|
+ lan966x, REW_TAG_CFG(port->chip_port));
|
|
+}
|
|
+
|
|
void lan966x_vlan_port_apply(struct lan966x_port *port)
|
|
{
|
|
struct lan966x *lan966x = port->lan966x;
|
|
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
index d3d5c01f6dcbaa..615d25a0e46be5 100644
|
|
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
|
@@ -842,6 +842,11 @@ int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags)
|
|
if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
|
|
return -EOPNOTSUPP;
|
|
|
|
+ if (!priv->plat->clk_ptp_rate) {
|
|
+ netdev_err(priv->dev, "Invalid PTP clock rate");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
stmmac_config_hw_tstamping(priv, priv->ptpaddr, systime_flags);
|
|
priv->systime_flags = systime_flags;
|
|
|
|
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
index 4d570efd9d4bbe..6c684f6ee84be9 100644
|
|
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
|
@@ -419,6 +419,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
|
|
struct device_node *np = pdev->dev.of_node;
|
|
struct plat_stmmacenet_data *plat;
|
|
struct stmmac_dma_cfg *dma_cfg;
|
|
+ static int bus_id = -ENODEV;
|
|
int phy_mode;
|
|
void *ret;
|
|
int rc;
|
|
@@ -454,8 +455,14 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
|
|
of_property_read_u32(np, "max-speed", &plat->max_speed);
|
|
|
|
plat->bus_id = of_alias_get_id(np, "ethernet");
|
|
- if (plat->bus_id < 0)
|
|
- plat->bus_id = 0;
|
|
+ if (plat->bus_id < 0) {
|
|
+ if (bus_id < 0)
|
|
+ bus_id = of_alias_get_highest_id("ethernet");
|
|
+ /* No ethernet alias found, init at -1 so first bus_id is 0 */
|
|
+ if (bus_id < 0)
|
|
+ bus_id = -1;
|
|
+ plat->bus_id = ++bus_id;
|
|
+ }
|
|
|
|
/* Default to phy auto-detection */
|
|
plat->phy_addr = -1;
|
|
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
|
|
index a04bb2e42c4ee1..80ecbd73333d9c 100644
|
|
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
|
|
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
|
|
@@ -295,7 +295,7 @@ void stmmac_ptp_register(struct stmmac_priv *priv)
|
|
|
|
/* Calculate the clock domain crossing (CDC) error if necessary */
|
|
priv->plat->cdc_error_adj = 0;
|
|
- if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate)
|
|
+ if (priv->plat->has_gmac4)
|
|
priv->plat->cdc_error_adj = (2 * NSEC_PER_SEC) / priv->plat->clk_ptp_rate;
|
|
|
|
stmmac_ptp_clock_ops.n_per_out = priv->dma_cap.pps_out_num;
|
|
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
|
|
index 7c96493a367bff..767053d6c6b6f9 100644
|
|
--- a/drivers/net/macsec.c
|
|
+++ b/drivers/net/macsec.c
|
|
@@ -243,15 +243,39 @@ static sci_t make_sci(const u8 *addr, __be16 port)
|
|
return sci;
|
|
}
|
|
|
|
-static sci_t macsec_frame_sci(struct macsec_eth_header *hdr, bool sci_present)
|
|
+static sci_t macsec_active_sci(struct macsec_secy *secy)
|
|
{
|
|
- sci_t sci;
|
|
+ struct macsec_rx_sc *rx_sc = rcu_dereference_bh(secy->rx_sc);
|
|
+
|
|
+ /* Case single RX SC */
|
|
+ if (rx_sc && !rcu_dereference_bh(rx_sc->next))
|
|
+ return (rx_sc->active) ? rx_sc->sci : 0;
|
|
+ /* Case no RX SC or multiple */
|
|
+ else
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static sci_t macsec_frame_sci(struct macsec_eth_header *hdr, bool sci_present,
|
|
+ struct macsec_rxh_data *rxd)
|
|
+{
|
|
+ struct macsec_dev *macsec;
|
|
+ sci_t sci = 0;
|
|
|
|
- if (sci_present)
|
|
+ /* SC = 1 */
|
|
+ if (sci_present) {
|
|
memcpy(&sci, hdr->secure_channel_id,
|
|
sizeof(hdr->secure_channel_id));
|
|
- else
|
|
+ /* SC = 0; ES = 0 */
|
|
+ } else if ((!(hdr->tci_an & (MACSEC_TCI_ES | MACSEC_TCI_SC))) &&
|
|
+ (list_is_singular(&rxd->secys))) {
|
|
+ /* Only one SECY should exist on this scenario */
|
|
+ macsec = list_first_or_null_rcu(&rxd->secys, struct macsec_dev,
|
|
+ secys);
|
|
+ if (macsec)
|
|
+ return macsec_active_sci(&macsec->secy);
|
|
+ } else {
|
|
sci = make_sci(hdr->eth.h_source, MACSEC_PORT_ES);
|
|
+ }
|
|
|
|
return sci;
|
|
}
|
|
@@ -1105,7 +1129,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
|
|
struct macsec_rxh_data *rxd;
|
|
struct macsec_dev *macsec;
|
|
unsigned int len;
|
|
- sci_t sci;
|
|
+ sci_t sci = 0;
|
|
u32 hdr_pn;
|
|
bool cbit;
|
|
struct pcpu_rx_sc_stats *rxsc_stats;
|
|
@@ -1152,11 +1176,14 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
|
|
|
|
macsec_skb_cb(skb)->has_sci = !!(hdr->tci_an & MACSEC_TCI_SC);
|
|
macsec_skb_cb(skb)->assoc_num = hdr->tci_an & MACSEC_AN_MASK;
|
|
- sci = macsec_frame_sci(hdr, macsec_skb_cb(skb)->has_sci);
|
|
|
|
rcu_read_lock();
|
|
rxd = macsec_data_rcu(skb->dev);
|
|
|
|
+ sci = macsec_frame_sci(hdr, macsec_skb_cb(skb)->has_sci, rxd);
|
|
+ if (!sci)
|
|
+ goto drop_nosc;
|
|
+
|
|
list_for_each_entry_rcu(macsec, &rxd->secys, secys) {
|
|
struct macsec_rx_sc *sc = find_rx_sc(&macsec->secy, sci);
|
|
|
|
@@ -1279,6 +1306,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
|
|
macsec_rxsa_put(rx_sa);
|
|
drop_nosa:
|
|
macsec_rxsc_put(rx_sc);
|
|
+drop_nosc:
|
|
rcu_read_unlock();
|
|
drop_direct:
|
|
kfree_skb(skb);
|
|
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
|
|
index 25dcaa49ab8be9..e02706b7cc1ed6 100644
|
|
--- a/drivers/net/phy/mdio_bus.c
|
|
+++ b/drivers/net/phy/mdio_bus.c
|
|
@@ -850,6 +850,9 @@ int __mdiobus_read(struct mii_bus *bus, int addr, u32 regnum)
|
|
|
|
lockdep_assert_held_once(&bus->mdio_lock);
|
|
|
|
+ if (addr >= PHY_MAX_ADDR)
|
|
+ return -ENXIO;
|
|
+
|
|
if (bus->read)
|
|
retval = bus->read(bus, addr, regnum);
|
|
else
|
|
@@ -879,6 +882,9 @@ int __mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val)
|
|
|
|
lockdep_assert_held_once(&bus->mdio_lock);
|
|
|
|
+ if (addr >= PHY_MAX_ADDR)
|
|
+ return -ENXIO;
|
|
+
|
|
if (bus->write)
|
|
err = bus->write(bus, addr, regnum, val);
|
|
else
|
|
@@ -940,6 +946,9 @@ int __mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum)
|
|
|
|
lockdep_assert_held_once(&bus->mdio_lock);
|
|
|
|
+ if (addr >= PHY_MAX_ADDR)
|
|
+ return -ENXIO;
|
|
+
|
|
if (bus->read_c45)
|
|
retval = bus->read_c45(bus, addr, devad, regnum);
|
|
else
|
|
@@ -971,6 +980,9 @@ int __mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum,
|
|
|
|
lockdep_assert_held_once(&bus->mdio_lock);
|
|
|
|
+ if (addr >= PHY_MAX_ADDR)
|
|
+ return -ENXIO;
|
|
+
|
|
if (bus->write_c45)
|
|
err = bus->write_c45(bus, addr, devad, regnum, val);
|
|
else
|
|
diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
|
|
index cf728bfd83e22c..7e7ce79eadffb9 100644
|
|
--- a/drivers/net/phy/mscc/mscc_ptp.c
|
|
+++ b/drivers/net/phy/mscc/mscc_ptp.c
|
|
@@ -943,7 +943,9 @@ static int vsc85xx_ip1_conf(struct phy_device *phydev, enum ts_blk blk,
|
|
/* UDP checksum offset in IPv4 packet
|
|
* according to: https://tools.ietf.org/html/rfc768
|
|
*/
|
|
- val |= IP1_NXT_PROT_UDP_CHKSUM_OFF(26) | IP1_NXT_PROT_UDP_CHKSUM_CLEAR;
|
|
+ val |= IP1_NXT_PROT_UDP_CHKSUM_OFF(26);
|
|
+ if (enable)
|
|
+ val |= IP1_NXT_PROT_UDP_CHKSUM_CLEAR;
|
|
vsc85xx_ts_write_csr(phydev, blk, MSCC_ANA_IP1_NXT_PROT_UDP_CHKSUM,
|
|
val);
|
|
|
|
@@ -1165,18 +1167,24 @@ static void vsc85xx_txtstamp(struct mii_timestamper *mii_ts,
|
|
container_of(mii_ts, struct vsc8531_private, mii_ts);
|
|
|
|
if (!vsc8531->ptp->configured)
|
|
- return;
|
|
+ goto out;
|
|
|
|
- if (vsc8531->ptp->tx_type == HWTSTAMP_TX_OFF) {
|
|
- kfree_skb(skb);
|
|
- return;
|
|
- }
|
|
+ if (vsc8531->ptp->tx_type == HWTSTAMP_TX_OFF)
|
|
+ goto out;
|
|
+
|
|
+ if (vsc8531->ptp->tx_type == HWTSTAMP_TX_ONESTEP_SYNC)
|
|
+ if (ptp_msg_is_sync(skb, type))
|
|
+ goto out;
|
|
|
|
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
|
|
|
|
mutex_lock(&vsc8531->ts_lock);
|
|
__skb_queue_tail(&vsc8531->ptp->tx_queue, skb);
|
|
mutex_unlock(&vsc8531->ts_lock);
|
|
+ return;
|
|
+
|
|
+out:
|
|
+ kfree_skb(skb);
|
|
}
|
|
|
|
static bool vsc85xx_rxtstamp(struct mii_timestamper *mii_ts,
|
|
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
|
|
index ec2a3d16b1a2da..cde0e80474a1de 100644
|
|
--- a/drivers/net/phy/phy_device.c
|
|
+++ b/drivers/net/phy/phy_device.c
|
|
@@ -1806,8 +1806,10 @@ void phy_detach(struct phy_device *phydev)
|
|
struct module *ndev_owner = NULL;
|
|
struct mii_bus *bus;
|
|
|
|
- if (phydev->devlink)
|
|
+ if (phydev->devlink) {
|
|
device_link_del(phydev->devlink);
|
|
+ phydev->devlink = NULL;
|
|
+ }
|
|
|
|
if (phydev->sysfs_links) {
|
|
if (dev)
|
|
diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
|
|
index 284375f662f1e0..3ebb1f84d30255 100644
|
|
--- a/drivers/net/usb/aqc111.c
|
|
+++ b/drivers/net/usb/aqc111.c
|
|
@@ -30,11 +30,14 @@ static int aqc111_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
|
|
ret = usbnet_read_cmd_nopm(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR |
|
|
USB_RECIP_DEVICE, value, index, data, size);
|
|
|
|
- if (unlikely(ret < 0))
|
|
+ if (unlikely(ret < size)) {
|
|
netdev_warn(dev->net,
|
|
"Failed to read(0x%x) reg index 0x%04x: %d\n",
|
|
cmd, index, ret);
|
|
|
|
+ ret = ret < 0 ? ret : -ENODATA;
|
|
+ }
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
@@ -46,11 +49,14 @@ static int aqc111_read_cmd(struct usbnet *dev, u8 cmd, u16 value,
|
|
ret = usbnet_read_cmd(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR |
|
|
USB_RECIP_DEVICE, value, index, data, size);
|
|
|
|
- if (unlikely(ret < 0))
|
|
+ if (unlikely(ret < size)) {
|
|
netdev_warn(dev->net,
|
|
"Failed to read(0x%x) reg index 0x%04x: %d\n",
|
|
cmd, index, ret);
|
|
|
|
+ ret = ret < 0 ? ret : -ENODATA;
|
|
+ }
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
|
|
index beebe09eb88ff3..afd78324f3aa39 100644
|
|
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
|
|
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
|
|
@@ -1499,6 +1499,30 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb,
|
|
return (hlen + (hdr.tcp->doff << 2));
|
|
}
|
|
|
|
+static void
|
|
+vmxnet3_lro_tunnel(struct sk_buff *skb, __be16 ip_proto)
|
|
+{
|
|
+ struct udphdr *uh = NULL;
|
|
+
|
|
+ if (ip_proto == htons(ETH_P_IP)) {
|
|
+ struct iphdr *iph = (struct iphdr *)skb->data;
|
|
+
|
|
+ if (iph->protocol == IPPROTO_UDP)
|
|
+ uh = (struct udphdr *)(iph + 1);
|
|
+ } else {
|
|
+ struct ipv6hdr *iph = (struct ipv6hdr *)skb->data;
|
|
+
|
|
+ if (iph->nexthdr == IPPROTO_UDP)
|
|
+ uh = (struct udphdr *)(iph + 1);
|
|
+ }
|
|
+ if (uh) {
|
|
+ if (uh->check)
|
|
+ skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL_CSUM;
|
|
+ else
|
|
+ skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL;
|
|
+ }
|
|
+}
|
|
+
|
|
static int
|
|
vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
|
|
struct vmxnet3_adapter *adapter, int quota)
|
|
@@ -1803,6 +1827,8 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
|
|
if (segCnt != 0 && mss != 0) {
|
|
skb_shinfo(skb)->gso_type = rcd->v4 ?
|
|
SKB_GSO_TCPV4 : SKB_GSO_TCPV6;
|
|
+ if (encap_lro)
|
|
+ vmxnet3_lro_tunnel(skb, skb->protocol);
|
|
skb_shinfo(skb)->gso_size = mss;
|
|
skb_shinfo(skb)->gso_segs = segCnt;
|
|
} else if ((segCnt != 0 || skb->len > mtu) && !encap_lro) {
|
|
diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c
|
|
index deb9636b0ecf8f..f98e0f027a0542 100644
|
|
--- a/drivers/net/wireguard/device.c
|
|
+++ b/drivers/net/wireguard/device.c
|
|
@@ -369,6 +369,7 @@ static int wg_newlink(struct net *src_net, struct net_device *dev,
|
|
if (ret < 0)
|
|
goto err_free_handshake_queue;
|
|
|
|
+ dev_set_threaded(dev, true);
|
|
ret = register_netdevice(dev);
|
|
if (ret < 0)
|
|
goto err_uninit_ratelimiter;
|
|
diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c
|
|
index 2c39bad7ebfb9a..1d06d4125992da 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/snoc.c
|
|
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
|
|
@@ -937,7 +937,9 @@ static int ath10k_snoc_hif_start(struct ath10k *ar)
|
|
|
|
dev_set_threaded(&ar->napi_dev, true);
|
|
ath10k_core_napi_enable(ar);
|
|
- ath10k_snoc_irq_enable(ar);
|
|
+ /* IRQs are left enabled when we restart due to a firmware crash */
|
|
+ if (!test_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags))
|
|
+ ath10k_snoc_irq_enable(ar);
|
|
ath10k_snoc_rx_post(ar);
|
|
|
|
clear_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags);
|
|
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
|
|
index fc7c4564a715cf..609d8387c41f3e 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/core.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
|
@@ -748,6 +748,7 @@ void ath11k_fw_stats_init(struct ath11k *ar)
|
|
INIT_LIST_HEAD(&ar->fw_stats.bcn);
|
|
|
|
init_completion(&ar->fw_stats_complete);
|
|
+ init_completion(&ar->fw_stats_done);
|
|
}
|
|
|
|
void ath11k_fw_stats_free(struct ath11k_fw_stats *stats)
|
|
@@ -1637,6 +1638,20 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
|
|
{
|
|
int ret;
|
|
|
|
+ switch (ath11k_crypto_mode) {
|
|
+ case ATH11K_CRYPT_MODE_SW:
|
|
+ set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
|
|
+ set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
|
|
+ break;
|
|
+ case ATH11K_CRYPT_MODE_HW:
|
|
+ clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
|
|
+ clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
|
|
+ break;
|
|
+ default:
|
|
+ ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
ret = ath11k_core_start_firmware(ab, ab->fw_mode);
|
|
if (ret) {
|
|
ath11k_err(ab, "failed to start firmware: %d\n", ret);
|
|
@@ -1655,20 +1670,6 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
|
|
goto err_firmware_stop;
|
|
}
|
|
|
|
- switch (ath11k_crypto_mode) {
|
|
- case ATH11K_CRYPT_MODE_SW:
|
|
- set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
|
|
- set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
|
|
- break;
|
|
- case ATH11K_CRYPT_MODE_HW:
|
|
- clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
|
|
- clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
|
|
- break;
|
|
- default:
|
|
- ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW)
|
|
set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
|
|
|
|
@@ -1742,6 +1743,7 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
|
|
void ath11k_core_halt(struct ath11k *ar)
|
|
{
|
|
struct ath11k_base *ab = ar->ab;
|
|
+ struct list_head *pos, *n;
|
|
|
|
lockdep_assert_held(&ar->conf_mutex);
|
|
|
|
@@ -1756,7 +1758,12 @@ void ath11k_core_halt(struct ath11k *ar)
|
|
|
|
rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
|
|
synchronize_rcu();
|
|
- INIT_LIST_HEAD(&ar->arvifs);
|
|
+
|
|
+ spin_lock_bh(&ar->data_lock);
|
|
+ list_for_each_safe(pos, n, &ar->arvifs)
|
|
+ list_del_init(pos);
|
|
+ spin_unlock_bh(&ar->data_lock);
|
|
+
|
|
idr_init(&ar->txmgmt_idr);
|
|
}
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
|
|
index b0444776248376..555deafd8399ac 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/core.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
|
@@ -550,6 +550,8 @@ struct ath11k_fw_stats {
|
|
struct list_head pdevs;
|
|
struct list_head vdevs;
|
|
struct list_head bcn;
|
|
+ u32 num_vdev_recvd;
|
|
+ u32 num_bcn_recvd;
|
|
};
|
|
|
|
struct ath11k_dbg_htt_stats {
|
|
@@ -732,7 +734,7 @@ struct ath11k {
|
|
u8 alpha2[REG_ALPHA2_LEN + 1];
|
|
struct ath11k_fw_stats fw_stats;
|
|
struct completion fw_stats_complete;
|
|
- bool fw_stats_done;
|
|
+ struct completion fw_stats_done;
|
|
|
|
/* protected by conf_mutex */
|
|
bool ps_state_enable;
|
|
diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
index 8cda73b78ebf41..50bc17127e68a3 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
@@ -1,7 +1,7 @@
|
|
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
/*
|
|
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
|
|
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
*/
|
|
|
|
#include <linux/vmalloc.h>
|
|
@@ -96,9 +96,10 @@ void ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
|
|
static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar)
|
|
{
|
|
spin_lock_bh(&ar->data_lock);
|
|
- ar->fw_stats_done = false;
|
|
ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
|
|
ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
|
|
+ ar->fw_stats.num_vdev_recvd = 0;
|
|
+ ar->fw_stats.num_bcn_recvd = 0;
|
|
spin_unlock_bh(&ar->data_lock);
|
|
}
|
|
|
|
@@ -106,15 +107,14 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *
|
|
{
|
|
struct ath11k_base *ab = ar->ab;
|
|
struct ath11k_pdev *pdev;
|
|
- bool is_end;
|
|
- static unsigned int num_vdev, num_bcn;
|
|
+ bool is_end = true;
|
|
size_t total_vdevs_started = 0;
|
|
int i;
|
|
|
|
/* WMI_REQUEST_PDEV_STAT request has been already processed */
|
|
|
|
if (stats->stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
|
|
- ar->fw_stats_done = true;
|
|
+ complete(&ar->fw_stats_done);
|
|
return;
|
|
}
|
|
|
|
@@ -132,15 +132,16 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *
|
|
total_vdevs_started += ar->num_started_vdevs;
|
|
}
|
|
|
|
- is_end = ((++num_vdev) == total_vdevs_started);
|
|
+ if (total_vdevs_started)
|
|
+ is_end = ((++ar->fw_stats.num_vdev_recvd) ==
|
|
+ total_vdevs_started);
|
|
|
|
list_splice_tail_init(&stats->vdevs,
|
|
&ar->fw_stats.vdevs);
|
|
|
|
- if (is_end) {
|
|
- ar->fw_stats_done = true;
|
|
- num_vdev = 0;
|
|
- }
|
|
+ if (is_end)
|
|
+ complete(&ar->fw_stats_done);
|
|
+
|
|
return;
|
|
}
|
|
|
|
@@ -152,15 +153,15 @@ void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *
|
|
/* Mark end until we reached the count of all started VDEVs
|
|
* within the PDEV
|
|
*/
|
|
- is_end = ((++num_bcn) == ar->num_started_vdevs);
|
|
+ if (ar->num_started_vdevs)
|
|
+ is_end = ((++ar->fw_stats.num_bcn_recvd) ==
|
|
+ ar->num_started_vdevs);
|
|
|
|
list_splice_tail_init(&stats->bcn,
|
|
&ar->fw_stats.bcn);
|
|
|
|
- if (is_end) {
|
|
- ar->fw_stats_done = true;
|
|
- num_bcn = 0;
|
|
- }
|
|
+ if (is_end)
|
|
+ complete(&ar->fw_stats_done);
|
|
}
|
|
}
|
|
|
|
@@ -168,21 +169,15 @@ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
|
|
struct stats_request_params *req_param)
|
|
{
|
|
struct ath11k_base *ab = ar->ab;
|
|
- unsigned long timeout, time_left;
|
|
+ unsigned long time_left;
|
|
int ret;
|
|
|
|
lockdep_assert_held(&ar->conf_mutex);
|
|
|
|
- /* FW stats can get split when exceeding the stats data buffer limit.
|
|
- * In that case, since there is no end marking for the back-to-back
|
|
- * received 'update stats' event, we keep a 3 seconds timeout in case,
|
|
- * fw_stats_done is not marked yet
|
|
- */
|
|
- timeout = jiffies + msecs_to_jiffies(3 * 1000);
|
|
-
|
|
ath11k_debugfs_fw_stats_reset(ar);
|
|
|
|
reinit_completion(&ar->fw_stats_complete);
|
|
+ reinit_completion(&ar->fw_stats_done);
|
|
|
|
ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
|
|
|
|
@@ -193,21 +188,18 @@ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
|
|
}
|
|
|
|
time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
|
|
-
|
|
if (!time_left)
|
|
return -ETIMEDOUT;
|
|
|
|
- for (;;) {
|
|
- if (time_after(jiffies, timeout))
|
|
- break;
|
|
+ /* FW stats can get split when exceeding the stats data buffer limit.
|
|
+ * In that case, since there is no end marking for the back-to-back
|
|
+ * received 'update stats' event, we keep a 3 seconds timeout in case,
|
|
+ * fw_stats_done is not marked yet
|
|
+ */
|
|
+ time_left = wait_for_completion_timeout(&ar->fw_stats_done, 3 * HZ);
|
|
+ if (!time_left)
|
|
+ return -ETIMEDOUT;
|
|
|
|
- spin_lock_bh(&ar->data_lock);
|
|
- if (ar->fw_stats_done) {
|
|
- spin_unlock_bh(&ar->data_lock);
|
|
- break;
|
|
- }
|
|
- spin_unlock_bh(&ar->data_lock);
|
|
- }
|
|
return 0;
|
|
}
|
|
|
|
@@ -980,7 +972,7 @@ int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
|
|
debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
|
|
&fops_simulate_fw_crash);
|
|
|
|
- debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
|
|
+ debugfs_create_file("soc_dp_stats", 0400, ab->debugfs_soc, ab,
|
|
&fops_soc_dp_stats);
|
|
|
|
if (ab->hw_params.sram_dump.start != 0)
|
|
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
|
|
index 4247c0f840a482..9df3f6449f7689 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
|
@@ -9010,11 +9010,13 @@ static int ath11k_fw_stats_request(struct ath11k *ar,
|
|
lockdep_assert_held(&ar->conf_mutex);
|
|
|
|
spin_lock_bh(&ar->data_lock);
|
|
- ar->fw_stats_done = false;
|
|
ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
|
|
+ ar->fw_stats.num_vdev_recvd = 0;
|
|
+ ar->fw_stats.num_bcn_recvd = 0;
|
|
spin_unlock_bh(&ar->data_lock);
|
|
|
|
reinit_completion(&ar->fw_stats_complete);
|
|
+ reinit_completion(&ar->fw_stats_done);
|
|
|
|
ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
|
|
if (ret) {
|
|
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
|
|
index 2cc13e60f422f7..9a829b8282420a 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
|
@@ -8183,7 +8183,7 @@ static void ath11k_update_stats_event(struct ath11k_base *ab, struct sk_buff *sk
|
|
*/
|
|
if (stats.stats_id == WMI_REQUEST_PDEV_STAT) {
|
|
list_splice_tail_init(&stats.pdevs, &ar->fw_stats.pdevs);
|
|
- ar->fw_stats_done = true;
|
|
+ complete(&ar->fw_stats_done);
|
|
goto complete;
|
|
}
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
|
|
index 3df8059d55129b..1b07a183aaedc0 100644
|
|
--- a/drivers/net/wireless/ath/ath12k/core.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/core.c
|
|
@@ -657,6 +657,7 @@ static int ath12k_core_reconfigure_on_crash(struct ath12k_base *ab)
|
|
|
|
void ath12k_core_halt(struct ath12k *ar)
|
|
{
|
|
+ struct list_head *pos, *n;
|
|
struct ath12k_base *ab = ar->ab;
|
|
|
|
lockdep_assert_held(&ar->conf_mutex);
|
|
@@ -671,7 +672,12 @@ void ath12k_core_halt(struct ath12k *ar)
|
|
|
|
rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
|
|
synchronize_rcu();
|
|
- INIT_LIST_HEAD(&ar->arvifs);
|
|
+
|
|
+ spin_lock_bh(&ar->data_lock);
|
|
+ list_for_each_safe(pos, n, &ar->arvifs)
|
|
+ list_del_init(pos);
|
|
+ spin_unlock_bh(&ar->data_lock);
|
|
+
|
|
idr_init(&ar->txmgmt_idr);
|
|
}
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
|
|
index 8d9315038a75e4..56dda76d066c31 100644
|
|
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
|
|
@@ -3683,6 +3683,15 @@ static bool ath12k_dp_rx_h_tkip_mic_err(struct ath12k *ar, struct sk_buff *msdu,
|
|
|
|
l3pad_bytes = ath12k_dp_rx_h_l3pad(ab, desc);
|
|
msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc);
|
|
+
|
|
+ if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) {
|
|
+ ath12k_dbg(ab, ATH12K_DBG_DATA,
|
|
+ "invalid msdu len in tkip mic err %u\n", msdu_len);
|
|
+ ath12k_dbg_dump(ab, ATH12K_DBG_DATA, NULL, "", desc,
|
|
+ sizeof(*desc));
|
|
+ return true;
|
|
+ }
|
|
+
|
|
skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
|
|
skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
|
|
index d87d5980325e8f..a0ac2f350934f9 100644
|
|
--- a/drivers/net/wireless/ath/ath12k/wmi.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
|
|
@@ -2066,7 +2066,7 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
|
|
|
|
for (i = 0; i < arg->peer_eht_mcs_count; i++) {
|
|
eht_mcs = ptr;
|
|
- eht_mcs->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_HE_RATE_SET,
|
|
+ eht_mcs->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_EHT_RATE_SET,
|
|
sizeof(*eht_mcs));
|
|
|
|
eht_mcs->rx_mcs_set = cpu_to_le32(arg->peer_eht_rx_mcs_set[i]);
|
|
@@ -4128,6 +4128,7 @@ static int ath12k_service_ready_ext_event(struct ath12k_base *ab,
|
|
return 0;
|
|
|
|
err:
|
|
+ kfree(svc_rdy_ext.mac_phy_caps);
|
|
ath12k_wmi_free_dbring_caps(ab);
|
|
return ret;
|
|
}
|
|
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
|
|
index 533471e694007e..18c7654bc539d1 100644
|
|
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
|
|
@@ -290,6 +290,9 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv,
|
|
struct ath_common *common = ath9k_hw_common(priv->ah);
|
|
int slot;
|
|
|
|
+ if (!priv->cur_beacon_conf.enable_beacon)
|
|
+ return;
|
|
+
|
|
if (swba->beacon_pending != 0) {
|
|
priv->beacon.bmisscnt++;
|
|
if (priv->beacon.bmisscnt > BSTUCK_THRESHOLD) {
|
|
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
|
|
index 7db436d908a39b..f4850c6daeb728 100644
|
|
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
|
|
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
|
|
@@ -755,6 +755,9 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
|
|
wed->wlan.base = devm_ioremap(dev->mt76.dev,
|
|
pci_resource_start(pci_dev, 0),
|
|
pci_resource_len(pci_dev, 0));
|
|
+ if (!wed->wlan.base)
|
|
+ return -ENOMEM;
|
|
+
|
|
wed->wlan.phy_base = pci_resource_start(pci_dev, 0);
|
|
wed->wlan.wpdma_int = pci_resource_start(pci_dev, 0) +
|
|
MT_INT_WED_SOURCE_CSR;
|
|
@@ -782,6 +785,9 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
|
|
wed->wlan.bus_type = MTK_WED_BUS_AXI;
|
|
wed->wlan.base = devm_ioremap(dev->mt76.dev, res->start,
|
|
resource_size(res));
|
|
+ if (!wed->wlan.base)
|
|
+ return -ENOMEM;
|
|
+
|
|
wed->wlan.phy_base = res->start;
|
|
wed->wlan.wpdma_int = res->start + MT_INT_SOURCE_CSR;
|
|
wed->wlan.wpdma_mask = res->start + MT_INT_MASK_CSR;
|
|
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
|
|
index 586e247a1e0648..04c9fd0e6b002a 100644
|
|
--- a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
|
|
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c
|
|
@@ -300,7 +300,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
|
|
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU],
|
|
MT_RXQ_ID(MT_RXQ_MCU),
|
|
MT7996_RX_MCU_RING_SIZE,
|
|
- MT_RX_BUF_SIZE,
|
|
+ MT7996_RX_MCU_BUF_SIZE,
|
|
MT_RXQ_RING_BASE(MT_RXQ_MCU));
|
|
if (ret)
|
|
return ret;
|
|
@@ -309,7 +309,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
|
|
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
|
|
MT_RXQ_ID(MT_RXQ_MCU_WA),
|
|
MT7996_RX_MCU_RING_SIZE_WA,
|
|
- MT_RX_BUF_SIZE,
|
|
+ MT7996_RX_MCU_BUF_SIZE,
|
|
MT_RXQ_RING_BASE(MT_RXQ_MCU_WA));
|
|
if (ret)
|
|
return ret;
|
|
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
|
|
index 0a701dcb8a92c5..375a3d6f4b384b 100644
|
|
--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
|
|
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
|
|
@@ -735,6 +735,9 @@ mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band,
|
|
u8_encode_bits(IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_11454,
|
|
IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK);
|
|
|
|
+ eht_cap_elem->mac_cap_info[1] |=
|
|
+ IEEE80211_EHT_MAC_CAP1_MAX_AMPDU_LEN_MASK;
|
|
+
|
|
eht_cap_elem->phy_cap_info[0] =
|
|
IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI |
|
|
IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER |
|
|
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
|
|
index 25bb3656123141..7d2074e2b635ec 100644
|
|
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
|
|
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
|
|
@@ -27,6 +27,9 @@
|
|
#define MT7996_RX_RING_SIZE 1536
|
|
#define MT7996_RX_MCU_RING_SIZE 512
|
|
#define MT7996_RX_MCU_RING_SIZE_WA 1024
|
|
+/* scatter-gather of mcu event is not supported in connac3 */
|
|
+#define MT7996_RX_MCU_BUF_SIZE (2048 + \
|
|
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
|
|
|
|
#define MT7996_FIRMWARE_WA "mediatek/mt7996/mt7996_wa.bin"
|
|
#define MT7996_FIRMWARE_WM "mediatek/mt7996/mt7996_wm.bin"
|
|
diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c
|
|
index d35f26919806a7..c45c7b596ffe92 100644
|
|
--- a/drivers/net/wireless/realtek/rtw88/coex.c
|
|
+++ b/drivers/net/wireless/realtek/rtw88/coex.c
|
|
@@ -309,7 +309,7 @@ static void rtw_coex_tdma_timer_base(struct rtw_dev *rtwdev, u8 type)
|
|
{
|
|
struct rtw_coex *coex = &rtwdev->coex;
|
|
struct rtw_coex_stat *coex_stat = &coex->stat;
|
|
- u8 para[2] = {0};
|
|
+ u8 para[6] = {};
|
|
u8 times;
|
|
u16 tbtt_interval = coex_stat->wl_beacon_interval;
|
|
|
|
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
|
|
index 3fe5c70ce731be..f9b2527fbeee56 100644
|
|
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
|
|
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
|
|
@@ -3991,7 +3991,8 @@ static void rtw8822c_dpk_cal_coef1(struct rtw_dev *rtwdev)
|
|
rtw_write32(rtwdev, REG_NCTL0, 0x00001148);
|
|
rtw_write32(rtwdev, REG_NCTL0, 0x00001149);
|
|
|
|
- check_hw_ready(rtwdev, 0x2d9c, MASKBYTE0, 0x55);
|
|
+ if (!check_hw_ready(rtwdev, 0x2d9c, MASKBYTE0, 0x55))
|
|
+ rtw_warn(rtwdev, "DPK stuck, performance may be suboptimal");
|
|
|
|
rtw_write8(rtwdev, 0x1b10, 0x0);
|
|
rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x0000000c);
|
|
diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c
|
|
index 9043569935796b..832a427279b40a 100644
|
|
--- a/drivers/net/wireless/realtek/rtw88/sdio.c
|
|
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c
|
|
@@ -718,10 +718,7 @@ static u8 rtw_sdio_get_tx_qsel(struct rtw_dev *rtwdev, struct sk_buff *skb,
|
|
case RTW_TX_QUEUE_H2C:
|
|
return TX_DESC_QSEL_H2C;
|
|
case RTW_TX_QUEUE_MGMT:
|
|
- if (rtw_chip_wcpu_11n(rtwdev))
|
|
- return TX_DESC_QSEL_HIGH;
|
|
- else
|
|
- return TX_DESC_QSEL_MGMT;
|
|
+ return TX_DESC_QSEL_MGMT;
|
|
case RTW_TX_QUEUE_HI0:
|
|
return TX_DESC_QSEL_HIGH;
|
|
default:
|
|
@@ -1226,10 +1223,7 @@ static void rtw_sdio_process_tx_queue(struct rtw_dev *rtwdev,
|
|
return;
|
|
}
|
|
|
|
- if (queue <= RTW_TX_QUEUE_VO)
|
|
- rtw_sdio_indicate_tx_status(rtwdev, skb);
|
|
- else
|
|
- dev_kfree_skb_any(skb);
|
|
+ rtw_sdio_indicate_tx_status(rtwdev, skb);
|
|
}
|
|
|
|
static void rtw_sdio_tx_handler(struct work_struct *work)
|
|
diff --git a/drivers/net/wwan/t7xx/t7xx_netdev.c b/drivers/net/wwan/t7xx/t7xx_netdev.c
|
|
index 3ef4a8a4f8fdbc..d879424093b782 100644
|
|
--- a/drivers/net/wwan/t7xx/t7xx_netdev.c
|
|
+++ b/drivers/net/wwan/t7xx/t7xx_netdev.c
|
|
@@ -296,7 +296,7 @@ static int t7xx_ccmni_wwan_newlink(void *ctxt, struct net_device *dev, u32 if_id
|
|
ccmni->ctlb = ctlb;
|
|
ccmni->dev = dev;
|
|
atomic_set(&ccmni->usage, 0);
|
|
- ctlb->ccmni_inst[if_id] = ccmni;
|
|
+ WRITE_ONCE(ctlb->ccmni_inst[if_id], ccmni);
|
|
|
|
ret = register_netdevice(dev);
|
|
if (ret)
|
|
@@ -318,6 +318,7 @@ static void t7xx_ccmni_wwan_dellink(void *ctxt, struct net_device *dev, struct l
|
|
if (WARN_ON(ctlb->ccmni_inst[if_id] != ccmni))
|
|
return;
|
|
|
|
+ WRITE_ONCE(ctlb->ccmni_inst[if_id], NULL);
|
|
unregister_netdevice(dev);
|
|
}
|
|
|
|
@@ -413,7 +414,7 @@ static void t7xx_ccmni_recv_skb(struct t7xx_ccmni_ctrl *ccmni_ctlb, struct sk_bu
|
|
|
|
skb_cb = T7XX_SKB_CB(skb);
|
|
netif_id = skb_cb->netif_idx;
|
|
- ccmni = ccmni_ctlb->ccmni_inst[netif_id];
|
|
+ ccmni = READ_ONCE(ccmni_ctlb->ccmni_inst[netif_id]);
|
|
if (!ccmni) {
|
|
dev_kfree_skb(skb);
|
|
return;
|
|
@@ -435,7 +436,7 @@ static void t7xx_ccmni_recv_skb(struct t7xx_ccmni_ctrl *ccmni_ctlb, struct sk_bu
|
|
|
|
static void t7xx_ccmni_queue_tx_irq_notify(struct t7xx_ccmni_ctrl *ctlb, int qno)
|
|
{
|
|
- struct t7xx_ccmni *ccmni = ctlb->ccmni_inst[0];
|
|
+ struct t7xx_ccmni *ccmni = READ_ONCE(ctlb->ccmni_inst[0]);
|
|
struct netdev_queue *net_queue;
|
|
|
|
if (netif_running(ccmni->dev) && atomic_read(&ccmni->usage) > 0) {
|
|
@@ -447,7 +448,7 @@ static void t7xx_ccmni_queue_tx_irq_notify(struct t7xx_ccmni_ctrl *ctlb, int qno
|
|
|
|
static void t7xx_ccmni_queue_tx_full_notify(struct t7xx_ccmni_ctrl *ctlb, int qno)
|
|
{
|
|
- struct t7xx_ccmni *ccmni = ctlb->ccmni_inst[0];
|
|
+ struct t7xx_ccmni *ccmni = READ_ONCE(ctlb->ccmni_inst[0]);
|
|
struct netdev_queue *net_queue;
|
|
|
|
if (atomic_read(&ccmni->usage) > 0) {
|
|
@@ -465,7 +466,7 @@ static void t7xx_ccmni_queue_state_notify(struct t7xx_pci_dev *t7xx_dev,
|
|
if (ctlb->md_sta != MD_STATE_READY)
|
|
return;
|
|
|
|
- if (!ctlb->ccmni_inst[0]) {
|
|
+ if (!READ_ONCE(ctlb->ccmni_inst[0])) {
|
|
dev_warn(&t7xx_dev->pdev->dev, "No netdev registered yet\n");
|
|
return;
|
|
}
|
|
diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c
|
|
index 4b35bdcac185ff..aeeb7455fc2e7d 100644
|
|
--- a/drivers/nvme/target/fcloop.c
|
|
+++ b/drivers/nvme/target/fcloop.c
|
|
@@ -613,12 +613,13 @@ fcloop_fcp_recv_work(struct work_struct *work)
|
|
{
|
|
struct fcloop_fcpreq *tfcp_req =
|
|
container_of(work, struct fcloop_fcpreq, fcp_rcv_work);
|
|
- struct nvmefc_fcp_req *fcpreq = tfcp_req->fcpreq;
|
|
+ struct nvmefc_fcp_req *fcpreq;
|
|
unsigned long flags;
|
|
int ret = 0;
|
|
bool aborted = false;
|
|
|
|
spin_lock_irqsave(&tfcp_req->reqlock, flags);
|
|
+ fcpreq = tfcp_req->fcpreq;
|
|
switch (tfcp_req->inistate) {
|
|
case INI_IO_START:
|
|
tfcp_req->inistate = INI_IO_ACTIVE;
|
|
@@ -633,16 +634,19 @@ fcloop_fcp_recv_work(struct work_struct *work)
|
|
}
|
|
spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
|
|
|
|
- if (unlikely(aborted))
|
|
- ret = -ECANCELED;
|
|
- else {
|
|
- if (likely(!check_for_drop(tfcp_req)))
|
|
- ret = nvmet_fc_rcv_fcp_req(tfcp_req->tport->targetport,
|
|
- &tfcp_req->tgt_fcp_req,
|
|
- fcpreq->cmdaddr, fcpreq->cmdlen);
|
|
- else
|
|
- pr_info("%s: dropped command ********\n", __func__);
|
|
+ if (unlikely(aborted)) {
|
|
+ /* the abort handler will call fcloop_call_host_done */
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (unlikely(check_for_drop(tfcp_req))) {
|
|
+ pr_info("%s: dropped command ********\n", __func__);
|
|
+ return;
|
|
}
|
|
+
|
|
+ ret = nvmet_fc_rcv_fcp_req(tfcp_req->tport->targetport,
|
|
+ &tfcp_req->tgt_fcp_req,
|
|
+ fcpreq->cmdaddr, fcpreq->cmdlen);
|
|
if (ret)
|
|
fcloop_call_host_done(fcpreq, tfcp_req, ret);
|
|
}
|
|
@@ -657,9 +661,10 @@ fcloop_fcp_abort_recv_work(struct work_struct *work)
|
|
unsigned long flags;
|
|
|
|
spin_lock_irqsave(&tfcp_req->reqlock, flags);
|
|
- fcpreq = tfcp_req->fcpreq;
|
|
switch (tfcp_req->inistate) {
|
|
case INI_IO_ABORTED:
|
|
+ fcpreq = tfcp_req->fcpreq;
|
|
+ tfcp_req->fcpreq = NULL;
|
|
break;
|
|
case INI_IO_COMPLETED:
|
|
completed = true;
|
|
@@ -681,10 +686,6 @@ fcloop_fcp_abort_recv_work(struct work_struct *work)
|
|
nvmet_fc_rcv_fcp_abort(tfcp_req->tport->targetport,
|
|
&tfcp_req->tgt_fcp_req);
|
|
|
|
- spin_lock_irqsave(&tfcp_req->reqlock, flags);
|
|
- tfcp_req->fcpreq = NULL;
|
|
- spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
|
|
-
|
|
fcloop_call_host_done(fcpreq, tfcp_req, -ECANCELED);
|
|
/* call_host_done releases reference for abort downcall */
|
|
}
|
|
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
|
|
index 8af95e9da7cec6..741e10a575ec75 100644
|
|
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
|
|
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
|
|
@@ -570,14 +570,5 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
|
|
if (!bridge->ops)
|
|
bridge->ops = &cdns_pcie_host_ops;
|
|
|
|
- ret = pci_host_probe(bridge);
|
|
- if (ret < 0)
|
|
- goto err_init;
|
|
-
|
|
- return 0;
|
|
-
|
|
- err_init:
|
|
- pm_runtime_put_sync(dev);
|
|
-
|
|
- return ret;
|
|
+ return pci_host_probe(bridge);
|
|
}
|
|
diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
|
|
index f7a248393a8f16..7e6bd63a6425e6 100644
|
|
--- a/drivers/pci/controller/pcie-apple.c
|
|
+++ b/drivers/pci/controller/pcie-apple.c
|
|
@@ -541,7 +541,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
|
|
rmw_set(PORT_APPCLK_EN, port->base + PORT_APPCLK);
|
|
|
|
/* Assert PERST# before setting up the clock */
|
|
- gpiod_set_value(reset, 1);
|
|
+ gpiod_set_value_cansleep(reset, 1);
|
|
|
|
ret = apple_pcie_setup_refclk(pcie, port);
|
|
if (ret < 0)
|
|
@@ -552,7 +552,7 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
|
|
|
|
/* Deassert PERST# */
|
|
rmw_set(PORT_PERST_OFF, port->base + PORT_PERST);
|
|
- gpiod_set_value(reset, 0);
|
|
+ gpiod_set_value_cansleep(reset, 0);
|
|
|
|
/* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */
|
|
msleep(100);
|
|
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
|
|
index 095fa1910d36db..503304aba9eac1 100644
|
|
--- a/drivers/pci/pci.c
|
|
+++ b/drivers/pci/pci.c
|
|
@@ -5221,7 +5221,7 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type)
|
|
delay);
|
|
if (!pcie_wait_for_link_delay(dev, true, delay)) {
|
|
/* Did not train, no need to wait any further */
|
|
- pci_info(dev, "Data Link Layer Link Active not set in 1000 msec\n");
|
|
+ pci_info(dev, "Data Link Layer Link Active not set in %d msec\n", delay);
|
|
return -ENOTTY;
|
|
}
|
|
|
|
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
|
|
index a5cec2a4e057d1..3c3ecb9cf57afb 100644
|
|
--- a/drivers/pci/pcie/dpc.c
|
|
+++ b/drivers/pci/pcie/dpc.c
|
|
@@ -263,7 +263,7 @@ static int dpc_get_aer_uncorrect_severity(struct pci_dev *dev,
|
|
void dpc_process_error(struct pci_dev *pdev)
|
|
{
|
|
u16 cap = pdev->dpc_cap, status, source, reason, ext_reason;
|
|
- struct aer_err_info info;
|
|
+ struct aer_err_info info = {};
|
|
|
|
pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
|
|
pci_read_config_word(pdev, cap + PCI_EXP_DPC_SOURCE_ID, &source);
|
|
diff --git a/drivers/perf/amlogic/meson_ddr_pmu_core.c b/drivers/perf/amlogic/meson_ddr_pmu_core.c
|
|
index bbc7285fd934a3..5f8699612a9ad1 100644
|
|
--- a/drivers/perf/amlogic/meson_ddr_pmu_core.c
|
|
+++ b/drivers/perf/amlogic/meson_ddr_pmu_core.c
|
|
@@ -510,7 +510,7 @@ int meson_ddr_pmu_create(struct platform_device *pdev)
|
|
|
|
fmt_attr_fill(pmu->info.hw_info->fmt_attr);
|
|
|
|
- pmu->cpu = smp_processor_id();
|
|
+ pmu->cpu = raw_smp_processor_id();
|
|
|
|
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, DDR_PERF_DEV_NAME);
|
|
if (!name)
|
|
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
|
|
index c697d01b2a2a1e..5072bca0af7c5d 100644
|
|
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
|
|
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
|
|
@@ -2044,12 +2044,16 @@ static void __iomem *qmp_usb_iomap(struct device *dev, struct device_node *np,
|
|
int index, bool exclusive)
|
|
{
|
|
struct resource res;
|
|
+ void __iomem *mem;
|
|
|
|
if (!exclusive) {
|
|
if (of_address_to_resource(np, index, &res))
|
|
return IOMEM_ERR_PTR(-EINVAL);
|
|
|
|
- return devm_ioremap(dev, res.start, resource_size(&res));
|
|
+ mem = devm_ioremap(dev, res.start, resource_size(&res));
|
|
+ if (!mem)
|
|
+ return IOMEM_ERR_PTR(-ENOMEM);
|
|
+ return mem;
|
|
}
|
|
|
|
return devm_of_iomap(dev, np, index, NULL);
|
|
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
|
|
index c34719b7506da6..1a39fd97a9005a 100644
|
|
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
|
|
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
|
|
@@ -417,20 +417,22 @@ static int armada_37xx_gpio_direction_output(struct gpio_chip *chip,
|
|
unsigned int offset, int value)
|
|
{
|
|
struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
|
|
- unsigned int reg = OUTPUT_EN;
|
|
+ unsigned int en_offset = offset;
|
|
+ unsigned int reg = OUTPUT_VAL;
|
|
unsigned int mask, val, ret;
|
|
|
|
armada_37xx_update_reg(®, &offset);
|
|
mask = BIT(offset);
|
|
+ val = value ? mask : 0;
|
|
|
|
- ret = regmap_update_bits(info->regmap, reg, mask, mask);
|
|
-
|
|
+ ret = regmap_update_bits(info->regmap, reg, mask, val);
|
|
if (ret)
|
|
return ret;
|
|
|
|
- reg = OUTPUT_VAL;
|
|
- val = value ? mask : 0;
|
|
- regmap_update_bits(info->regmap, reg, mask, val);
|
|
+ reg = OUTPUT_EN;
|
|
+ armada_37xx_update_reg(®, &en_offset);
|
|
+
|
|
+ regmap_update_bits(info->regmap, reg, mask, mask);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
|
|
index d7b66928a4e50d..3c09f743b68c2e 100644
|
|
--- a/drivers/pinctrl/pinctrl-at91.c
|
|
+++ b/drivers/pinctrl/pinctrl-at91.c
|
|
@@ -1825,12 +1825,16 @@ static int at91_gpio_probe(struct platform_device *pdev)
|
|
struct at91_gpio_chip *at91_chip = NULL;
|
|
struct gpio_chip *chip;
|
|
struct pinctrl_gpio_range *range;
|
|
+ int alias_idx;
|
|
int ret = 0;
|
|
int irq, i;
|
|
- int alias_idx = of_alias_get_id(np, "gpio");
|
|
uint32_t ngpio;
|
|
char **names;
|
|
|
|
+ alias_idx = of_alias_get_id(np, "gpio");
|
|
+ if (alias_idx < 0)
|
|
+ return alias_idx;
|
|
+
|
|
BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips));
|
|
if (gpio_chips[alias_idx])
|
|
return dev_err_probe(dev, -EBUSY, "%d slot is occupied.\n", alias_idx);
|
|
diff --git a/drivers/pinctrl/qcom/pinctrl-qcm2290.c b/drivers/pinctrl/qcom/pinctrl-qcm2290.c
|
|
index f5c1c427b44e91..61b7c22e963c2c 100644
|
|
--- a/drivers/pinctrl/qcom/pinctrl-qcm2290.c
|
|
+++ b/drivers/pinctrl/qcom/pinctrl-qcm2290.c
|
|
@@ -165,6 +165,10 @@ static const struct pinctrl_pin_desc qcm2290_pins[] = {
|
|
PINCTRL_PIN(62, "GPIO_62"),
|
|
PINCTRL_PIN(63, "GPIO_63"),
|
|
PINCTRL_PIN(64, "GPIO_64"),
|
|
+ PINCTRL_PIN(65, "GPIO_65"),
|
|
+ PINCTRL_PIN(66, "GPIO_66"),
|
|
+ PINCTRL_PIN(67, "GPIO_67"),
|
|
+ PINCTRL_PIN(68, "GPIO_68"),
|
|
PINCTRL_PIN(69, "GPIO_69"),
|
|
PINCTRL_PIN(70, "GPIO_70"),
|
|
PINCTRL_PIN(71, "GPIO_71"),
|
|
@@ -179,12 +183,17 @@ static const struct pinctrl_pin_desc qcm2290_pins[] = {
|
|
PINCTRL_PIN(80, "GPIO_80"),
|
|
PINCTRL_PIN(81, "GPIO_81"),
|
|
PINCTRL_PIN(82, "GPIO_82"),
|
|
+ PINCTRL_PIN(83, "GPIO_83"),
|
|
+ PINCTRL_PIN(84, "GPIO_84"),
|
|
+ PINCTRL_PIN(85, "GPIO_85"),
|
|
PINCTRL_PIN(86, "GPIO_86"),
|
|
PINCTRL_PIN(87, "GPIO_87"),
|
|
PINCTRL_PIN(88, "GPIO_88"),
|
|
PINCTRL_PIN(89, "GPIO_89"),
|
|
PINCTRL_PIN(90, "GPIO_90"),
|
|
PINCTRL_PIN(91, "GPIO_91"),
|
|
+ PINCTRL_PIN(92, "GPIO_92"),
|
|
+ PINCTRL_PIN(93, "GPIO_93"),
|
|
PINCTRL_PIN(94, "GPIO_94"),
|
|
PINCTRL_PIN(95, "GPIO_95"),
|
|
PINCTRL_PIN(96, "GPIO_96"),
|
|
diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c
|
|
index aa9b012d3d00b8..bafe4cc6fafdcb 100644
|
|
--- a/drivers/power/reset/at91-reset.c
|
|
+++ b/drivers/power/reset/at91-reset.c
|
|
@@ -129,12 +129,11 @@ static int at91_reset(struct notifier_block *this, unsigned long mode,
|
|
" str %4, [%0, %6]\n\t"
|
|
/* Disable SDRAM1 accesses */
|
|
"1: tst %1, #0\n\t"
|
|
- " beq 2f\n\t"
|
|
" strne %3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
|
|
/* Power down SDRAM1 */
|
|
" strne %4, [%1, %6]\n\t"
|
|
/* Reset CPU */
|
|
- "2: str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t"
|
|
+ " str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t"
|
|
|
|
" b .\n\t"
|
|
:
|
|
@@ -145,7 +144,7 @@ static int at91_reset(struct notifier_block *this, unsigned long mode,
|
|
"r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN),
|
|
"r" (reset->data->reset_args),
|
|
"r" (reset->ramc_lpr)
|
|
- : "r4");
|
|
+ );
|
|
|
|
return NOTIFY_DONE;
|
|
}
|
|
diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
|
|
index b8d4f61f14be4f..d0eb4555720eba 100644
|
|
--- a/drivers/ptp/ptp_private.h
|
|
+++ b/drivers/ptp/ptp_private.h
|
|
@@ -89,17 +89,7 @@ static inline int queue_cnt(const struct timestamp_event_queue *q)
|
|
/* Check if ptp virtual clock is in use */
|
|
static inline bool ptp_vclock_in_use(struct ptp_clock *ptp)
|
|
{
|
|
- bool in_use = false;
|
|
-
|
|
- if (mutex_lock_interruptible(&ptp->n_vclocks_mux))
|
|
- return true;
|
|
-
|
|
- if (!ptp->is_virtual_clock && ptp->n_vclocks)
|
|
- in_use = true;
|
|
-
|
|
- mutex_unlock(&ptp->n_vclocks_mux);
|
|
-
|
|
- return in_use;
|
|
+ return !ptp->is_virtual_clock;
|
|
}
|
|
|
|
/* Check if ptp clock shall be free running */
|
|
diff --git a/drivers/regulator/max20086-regulator.c b/drivers/regulator/max20086-regulator.c
|
|
index ebfbcadbca5295..1cf04d1efb3313 100644
|
|
--- a/drivers/regulator/max20086-regulator.c
|
|
+++ b/drivers/regulator/max20086-regulator.c
|
|
@@ -5,6 +5,7 @@
|
|
// Copyright (C) 2022 Laurent Pinchart <laurent.pinchart@idesonboard.com>
|
|
// Copyright (C) 2018 Avnet, Inc.
|
|
|
|
+#include <linux/cleanup.h>
|
|
#include <linux/err.h>
|
|
#include <linux/gpio/consumer.h>
|
|
#include <linux/i2c.h>
|
|
@@ -133,11 +134,11 @@ static int max20086_regulators_register(struct max20086 *chip)
|
|
static int max20086_parse_regulators_dt(struct max20086 *chip, bool *boot_on)
|
|
{
|
|
struct of_regulator_match *matches;
|
|
- struct device_node *node;
|
|
unsigned int i;
|
|
int ret;
|
|
|
|
- node = of_get_child_by_name(chip->dev->of_node, "regulators");
|
|
+ struct device_node *node __free(device_node) =
|
|
+ of_get_child_by_name(chip->dev->of_node, "regulators");
|
|
if (!node) {
|
|
dev_err(chip->dev, "regulators node not found\n");
|
|
return -ENODEV;
|
|
@@ -153,7 +154,6 @@ static int max20086_parse_regulators_dt(struct max20086 *chip, bool *boot_on)
|
|
|
|
ret = of_regulator_match(chip->dev, node, matches,
|
|
chip->info->num_outputs);
|
|
- of_node_put(node);
|
|
if (ret < 0) {
|
|
dev_err(chip->dev, "Failed to match regulators\n");
|
|
return -EINVAL;
|
|
diff --git a/drivers/remoteproc/qcom_wcnss_iris.c b/drivers/remoteproc/qcom_wcnss_iris.c
|
|
index dd36fd077911af..1e197f7734742b 100644
|
|
--- a/drivers/remoteproc/qcom_wcnss_iris.c
|
|
+++ b/drivers/remoteproc/qcom_wcnss_iris.c
|
|
@@ -197,6 +197,7 @@ struct qcom_iris *qcom_iris_probe(struct device *parent, bool *use_48mhz_xo)
|
|
|
|
err_device_del:
|
|
device_del(&iris->dev);
|
|
+ put_device(&iris->dev);
|
|
|
|
return ERR_PTR(ret);
|
|
}
|
|
@@ -204,4 +205,5 @@ struct qcom_iris *qcom_iris_probe(struct device *parent, bool *use_48mhz_xo)
|
|
void qcom_iris_remove(struct qcom_iris *iris)
|
|
{
|
|
device_del(&iris->dev);
|
|
+ put_device(&iris->dev);
|
|
}
|
|
diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c
|
|
index 5491b1b17ca368..37005640c784c0 100644
|
|
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
|
|
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
|
|
@@ -194,10 +194,6 @@ static void k3_r5_rproc_mbox_callback(struct mbox_client *client, void *data)
|
|
const char *name = kproc->rproc->name;
|
|
u32 msg = omap_mbox_message(data);
|
|
|
|
- /* Do not forward message from a detached core */
|
|
- if (kproc->rproc->state == RPROC_DETACHED)
|
|
- return;
|
|
-
|
|
dev_dbg(dev, "mbox msg: 0x%x\n", msg);
|
|
|
|
switch (msg) {
|
|
@@ -233,10 +229,6 @@ static void k3_r5_rproc_kick(struct rproc *rproc, int vqid)
|
|
mbox_msg_t msg = (mbox_msg_t)vqid;
|
|
int ret;
|
|
|
|
- /* Do not forward message to a detached core */
|
|
- if (kproc->rproc->state == RPROC_DETACHED)
|
|
- return;
|
|
-
|
|
/* send the index of the triggered virtqueue in the mailbox payload */
|
|
ret = mbox_send_message(kproc->mbox, (void *)msg);
|
|
if (ret < 0)
|
|
diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c
|
|
index 43f601c84b4fcb..79d35ab43729ea 100644
|
|
--- a/drivers/rpmsg/qcom_smd.c
|
|
+++ b/drivers/rpmsg/qcom_smd.c
|
|
@@ -746,7 +746,7 @@ static int __qcom_smd_send(struct qcom_smd_channel *channel, const void *data,
|
|
__le32 hdr[5] = { cpu_to_le32(len), };
|
|
int tlen = sizeof(hdr) + len;
|
|
unsigned long flags;
|
|
- int ret;
|
|
+ int ret = 0;
|
|
|
|
/* Word aligned channels only accept word size aligned data */
|
|
if (channel->info_word && len % 4)
|
|
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
|
|
index edfd942f8c5494..af10850fbac2e7 100644
|
|
--- a/drivers/rtc/class.c
|
|
+++ b/drivers/rtc/class.c
|
|
@@ -323,7 +323,7 @@ static void rtc_device_get_offset(struct rtc_device *rtc)
|
|
*
|
|
* Otherwise the offset seconds should be 0.
|
|
*/
|
|
- if (rtc->start_secs > rtc->range_max ||
|
|
+ if ((rtc->start_secs >= 0 && rtc->start_secs > rtc->range_max) ||
|
|
rtc->start_secs + range_secs - 1 < rtc->range_min)
|
|
rtc->offset_secs = rtc->start_secs - rtc->range_min;
|
|
else if (rtc->start_secs > rtc->range_min)
|
|
diff --git a/drivers/rtc/lib.c b/drivers/rtc/lib.c
|
|
index fe361652727a3f..13b5b1f2046510 100644
|
|
--- a/drivers/rtc/lib.c
|
|
+++ b/drivers/rtc/lib.c
|
|
@@ -46,24 +46,38 @@ EXPORT_SYMBOL(rtc_year_days);
|
|
* rtc_time64_to_tm - converts time64_t to rtc_time.
|
|
*
|
|
* @time: The number of seconds since 01-01-1970 00:00:00.
|
|
- * (Must be positive.)
|
|
+ * Works for values since at least 1900
|
|
* @tm: Pointer to the struct rtc_time.
|
|
*/
|
|
void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
|
|
{
|
|
- unsigned int secs;
|
|
- int days;
|
|
+ int days, secs;
|
|
|
|
u64 u64tmp;
|
|
u32 u32tmp, udays, century, day_of_century, year_of_century, year,
|
|
day_of_year, month, day;
|
|
bool is_Jan_or_Feb, is_leap_year;
|
|
|
|
- /* time must be positive */
|
|
+ /*
|
|
+ * Get days and seconds while preserving the sign to
|
|
+ * handle negative time values (dates before 1970-01-01)
|
|
+ */
|
|
days = div_s64_rem(time, 86400, &secs);
|
|
|
|
+ /*
|
|
+ * We need 0 <= secs < 86400 which isn't given for negative
|
|
+ * values of time. Fixup accordingly.
|
|
+ */
|
|
+ if (secs < 0) {
|
|
+ days -= 1;
|
|
+ secs += 86400;
|
|
+ }
|
|
+
|
|
/* day of the week, 1970-01-01 was a Thursday */
|
|
tm->tm_wday = (days + 4) % 7;
|
|
+ /* Ensure tm_wday is always positive */
|
|
+ if (tm->tm_wday < 0)
|
|
+ tm->tm_wday += 7;
|
|
|
|
/*
|
|
* The following algorithm is, basically, Proposition 6.3 of Neri
|
|
@@ -93,7 +107,7 @@ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
|
|
* thus, is slightly different from [1].
|
|
*/
|
|
|
|
- udays = ((u32) days) + 719468;
|
|
+ udays = days + 719468;
|
|
|
|
u32tmp = 4 * udays + 3;
|
|
century = u32tmp / 146097;
|
|
diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c
|
|
index 90e9d97a86b487..c9d5b91a6544d1 100644
|
|
--- a/drivers/rtc/rtc-loongson.c
|
|
+++ b/drivers/rtc/rtc-loongson.c
|
|
@@ -129,6 +129,14 @@ static u32 loongson_rtc_handler(void *id)
|
|
{
|
|
struct loongson_rtc_priv *priv = (struct loongson_rtc_priv *)id;
|
|
|
|
+ rtc_update_irq(priv->rtcdev, 1, RTC_AF | RTC_IRQF);
|
|
+
|
|
+ /*
|
|
+ * The TOY_MATCH0_REG should be cleared 0 here,
|
|
+ * otherwise the interrupt cannot be cleared.
|
|
+ */
|
|
+ regmap_write(priv->regmap, TOY_MATCH0_REG, 0);
|
|
+
|
|
spin_lock(&priv->lock);
|
|
/* Disable RTC alarm wakeup and interrupt */
|
|
writel(readl(priv->pm_base + PM1_EN_REG) & ~RTC_EN,
|
|
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
|
|
index cd146b5741431f..341b1b776e1a39 100644
|
|
--- a/drivers/rtc/rtc-sh.c
|
|
+++ b/drivers/rtc/rtc-sh.c
|
|
@@ -485,9 +485,15 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
|
|
return -ENOENT;
|
|
}
|
|
|
|
- rtc->periodic_irq = ret;
|
|
- rtc->carry_irq = platform_get_irq(pdev, 1);
|
|
- rtc->alarm_irq = platform_get_irq(pdev, 2);
|
|
+ if (!pdev->dev.of_node) {
|
|
+ rtc->periodic_irq = ret;
|
|
+ rtc->carry_irq = platform_get_irq(pdev, 1);
|
|
+ rtc->alarm_irq = platform_get_irq(pdev, 2);
|
|
+ } else {
|
|
+ rtc->alarm_irq = ret;
|
|
+ rtc->periodic_irq = platform_get_irq(pdev, 1);
|
|
+ rtc->carry_irq = platform_get_irq(pdev, 2);
|
|
+ }
|
|
|
|
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
|
if (!res)
|
|
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
|
|
index 7e64661d215bd2..3ad58250bf6b21 100644
|
|
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
|
|
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
|
|
@@ -1844,33 +1844,14 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device)
|
|
}
|
|
hisi_sas_dereg_device(hisi_hba, device);
|
|
|
|
- rc = hisi_sas_debug_I_T_nexus_reset(device);
|
|
- if (rc == TMF_RESP_FUNC_COMPLETE && dev_is_sata(device)) {
|
|
- struct sas_phy *local_phy;
|
|
-
|
|
+ if (dev_is_sata(device)) {
|
|
rc = hisi_sas_softreset_ata_disk(device);
|
|
- switch (rc) {
|
|
- case -ECOMM:
|
|
- rc = -ENODEV;
|
|
- break;
|
|
- case TMF_RESP_FUNC_FAILED:
|
|
- case -EMSGSIZE:
|
|
- case -EIO:
|
|
- local_phy = sas_get_local_phy(device);
|
|
- rc = sas_phy_enable(local_phy, 0);
|
|
- if (!rc) {
|
|
- local_phy->enabled = 0;
|
|
- dev_err(dev, "Disabled local phy of ATA disk %016llx due to softreset fail (%d)\n",
|
|
- SAS_ADDR(device->sas_addr), rc);
|
|
- rc = -ENODEV;
|
|
- }
|
|
- sas_put_local_phy(local_phy);
|
|
- break;
|
|
- default:
|
|
- break;
|
|
- }
|
|
+ if (rc == TMF_RESP_FUNC_FAILED)
|
|
+ dev_err(dev, "ata disk %016llx reset (%d)\n",
|
|
+ SAS_ADDR(device->sas_addr), rc);
|
|
}
|
|
|
|
+ rc = hisi_sas_debug_I_T_nexus_reset(device);
|
|
if ((rc == TMF_RESP_FUNC_COMPLETE) || (rc == -ENODEV))
|
|
hisi_sas_release_task(hisi_hba, device);
|
|
|
|
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
|
|
index 9a81d14aef6b99..17b19b39699a31 100644
|
|
--- a/drivers/scsi/qedf/qedf_main.c
|
|
+++ b/drivers/scsi/qedf/qedf_main.c
|
|
@@ -699,7 +699,7 @@ static u32 qedf_get_login_failures(void *cookie)
|
|
}
|
|
|
|
static struct qed_fcoe_cb_ops qedf_cb_ops = {
|
|
- {
|
|
+ .common = {
|
|
.link_update = qedf_link_update,
|
|
.bw_update = qedf_bw_update,
|
|
.schedule_recovery_handler = qedf_schedule_recovery_handler,
|
|
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
|
|
index 0c30fec555475b..f2c31e74d8ed06 100644
|
|
--- a/drivers/scsi/scsi_transport_iscsi.c
|
|
+++ b/drivers/scsi/scsi_transport_iscsi.c
|
|
@@ -3525,7 +3525,7 @@ static int iscsi_new_flashnode(struct iscsi_transport *transport,
|
|
pr_err("%s could not find host no %u\n",
|
|
__func__, ev->u.new_flashnode.host_no);
|
|
err = -ENODEV;
|
|
- goto put_host;
|
|
+ goto exit_new_fnode;
|
|
}
|
|
|
|
index = transport->new_flashnode(shost, data, len);
|
|
@@ -3535,7 +3535,6 @@ static int iscsi_new_flashnode(struct iscsi_transport *transport,
|
|
else
|
|
err = -EIO;
|
|
|
|
-put_host:
|
|
scsi_host_put(shost);
|
|
|
|
exit_new_fnode:
|
|
@@ -3560,7 +3559,7 @@ static int iscsi_del_flashnode(struct iscsi_transport *transport,
|
|
pr_err("%s could not find host no %u\n",
|
|
__func__, ev->u.del_flashnode.host_no);
|
|
err = -ENODEV;
|
|
- goto put_host;
|
|
+ goto exit_del_fnode;
|
|
}
|
|
|
|
idx = ev->u.del_flashnode.flashnode_idx;
|
|
@@ -3602,7 +3601,7 @@ static int iscsi_login_flashnode(struct iscsi_transport *transport,
|
|
pr_err("%s could not find host no %u\n",
|
|
__func__, ev->u.login_flashnode.host_no);
|
|
err = -ENODEV;
|
|
- goto put_host;
|
|
+ goto exit_login_fnode;
|
|
}
|
|
|
|
idx = ev->u.login_flashnode.flashnode_idx;
|
|
@@ -3654,7 +3653,7 @@ static int iscsi_logout_flashnode(struct iscsi_transport *transport,
|
|
pr_err("%s could not find host no %u\n",
|
|
__func__, ev->u.logout_flashnode.host_no);
|
|
err = -ENODEV;
|
|
- goto put_host;
|
|
+ goto exit_logout_fnode;
|
|
}
|
|
|
|
idx = ev->u.logout_flashnode.flashnode_idx;
|
|
@@ -3704,7 +3703,7 @@ static int iscsi_logout_flashnode_sid(struct iscsi_transport *transport,
|
|
pr_err("%s could not find host no %u\n",
|
|
__func__, ev->u.logout_flashnode.host_no);
|
|
err = -ENODEV;
|
|
- goto put_host;
|
|
+ goto exit_logout_sid;
|
|
}
|
|
|
|
session = iscsi_session_lookup(ev->u.logout_flashnode_sid.sid);
|
|
diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c
|
|
index 773dbcbc03a6cd..0f2ffee321dd9c 100644
|
|
--- a/drivers/soc/aspeed/aspeed-lpc-snoop.c
|
|
+++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c
|
|
@@ -166,7 +166,7 @@ static int aspeed_lpc_snoop_config_irq(struct aspeed_lpc_snoop *lpc_snoop,
|
|
int rc;
|
|
|
|
lpc_snoop->irq = platform_get_irq(pdev, 0);
|
|
- if (!lpc_snoop->irq)
|
|
+ if (lpc_snoop->irq < 0)
|
|
return -ENODEV;
|
|
|
|
rc = devm_request_irq(dev, lpc_snoop->irq,
|
|
@@ -200,11 +200,15 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
|
|
lpc_snoop->chan[channel].miscdev.minor = MISC_DYNAMIC_MINOR;
|
|
lpc_snoop->chan[channel].miscdev.name =
|
|
devm_kasprintf(dev, GFP_KERNEL, "%s%d", DEVICE_NAME, channel);
|
|
+ if (!lpc_snoop->chan[channel].miscdev.name) {
|
|
+ rc = -ENOMEM;
|
|
+ goto err_free_fifo;
|
|
+ }
|
|
lpc_snoop->chan[channel].miscdev.fops = &snoop_fops;
|
|
lpc_snoop->chan[channel].miscdev.parent = dev;
|
|
rc = misc_register(&lpc_snoop->chan[channel].miscdev);
|
|
if (rc)
|
|
- return rc;
|
|
+ goto err_free_fifo;
|
|
|
|
/* Enable LPC snoop channel at requested port */
|
|
switch (channel) {
|
|
@@ -221,7 +225,8 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
|
|
hicrb_en = HICRB_ENSNP1D;
|
|
break;
|
|
default:
|
|
- return -EINVAL;
|
|
+ rc = -EINVAL;
|
|
+ goto err_misc_deregister;
|
|
}
|
|
|
|
regmap_update_bits(lpc_snoop->regmap, HICR5, hicr5_en, hicr5_en);
|
|
@@ -231,6 +236,12 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
|
|
regmap_update_bits(lpc_snoop->regmap, HICRB,
|
|
hicrb_en, hicrb_en);
|
|
|
|
+ return 0;
|
|
+
|
|
+err_misc_deregister:
|
|
+ misc_deregister(&lpc_snoop->chan[channel].miscdev);
|
|
+err_free_fifo:
|
|
+ kfifo_free(&lpc_snoop->chan[channel].fifo);
|
|
return rc;
|
|
}
|
|
|
|
diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c
|
|
index 1ca857c2a4aa31..8df12efeea21c7 100644
|
|
--- a/drivers/spi/spi-bcm63xx-hsspi.c
|
|
+++ b/drivers/spi/spi-bcm63xx-hsspi.c
|
|
@@ -745,7 +745,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
|
|
if (IS_ERR(clk))
|
|
return PTR_ERR(clk);
|
|
|
|
- reset = devm_reset_control_get_optional_exclusive(dev, NULL);
|
|
+ reset = devm_reset_control_get_optional_shared(dev, NULL);
|
|
if (IS_ERR(reset))
|
|
return PTR_ERR(reset);
|
|
|
|
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
|
|
index ef3a7226db125c..a95badb7b71146 100644
|
|
--- a/drivers/spi/spi-bcm63xx.c
|
|
+++ b/drivers/spi/spi-bcm63xx.c
|
|
@@ -523,7 +523,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
|
|
return PTR_ERR(clk);
|
|
}
|
|
|
|
- reset = devm_reset_control_get_optional_exclusive(dev, NULL);
|
|
+ reset = devm_reset_control_get_optional_shared(dev, NULL);
|
|
if (IS_ERR(reset))
|
|
return PTR_ERR(reset);
|
|
|
|
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
|
|
index 6f12e4fb2e2e18..65c11909659c6b 100644
|
|
--- a/drivers/spi/spi-sh-msiof.c
|
|
+++ b/drivers/spi/spi-sh-msiof.c
|
|
@@ -918,6 +918,7 @@ static int sh_msiof_transfer_one(struct spi_controller *ctlr,
|
|
void *rx_buf = t->rx_buf;
|
|
unsigned int len = t->len;
|
|
unsigned int bits = t->bits_per_word;
|
|
+ unsigned int max_wdlen = 256;
|
|
unsigned int bytes_per_word;
|
|
unsigned int words;
|
|
int n;
|
|
@@ -931,17 +932,17 @@ static int sh_msiof_transfer_one(struct spi_controller *ctlr,
|
|
if (!spi_controller_is_target(p->ctlr))
|
|
sh_msiof_spi_set_clk_regs(p, t);
|
|
|
|
+ if (tx_buf)
|
|
+ max_wdlen = min(max_wdlen, p->tx_fifo_size);
|
|
+ if (rx_buf)
|
|
+ max_wdlen = min(max_wdlen, p->rx_fifo_size);
|
|
+
|
|
while (ctlr->dma_tx && len > 15) {
|
|
/*
|
|
* DMA supports 32-bit words only, hence pack 8-bit and 16-bit
|
|
* words, with byte resp. word swapping.
|
|
*/
|
|
- unsigned int l = 0;
|
|
-
|
|
- if (tx_buf)
|
|
- l = min(round_down(len, 4), p->tx_fifo_size * 4);
|
|
- if (rx_buf)
|
|
- l = min(round_down(len, 4), p->rx_fifo_size * 4);
|
|
+ unsigned int l = min(round_down(len, 4), max_wdlen * 4);
|
|
|
|
if (bits <= 8) {
|
|
copy32 = copy_bswap32;
|
|
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
|
|
index e3c236025a7b3b..e9afebd724237b 100644
|
|
--- a/drivers/spi/spi-tegra210-quad.c
|
|
+++ b/drivers/spi/spi-tegra210-quad.c
|
|
@@ -134,7 +134,7 @@
|
|
#define QSPI_COMMAND_VALUE_SET(X) (((x) & 0xFF) << 0)
|
|
|
|
#define QSPI_CMB_SEQ_CMD_CFG 0x1a0
|
|
-#define QSPI_COMMAND_X1_X2_X4(x) (((x) & 0x3) << 13)
|
|
+#define QSPI_COMMAND_X1_X2_X4(x) ((((x) >> 1) & 0x3) << 13)
|
|
#define QSPI_COMMAND_X1_X2_X4_MASK (0x03 << 13)
|
|
#define QSPI_COMMAND_SDR_DDR BIT(12)
|
|
#define QSPI_COMMAND_SIZE_SET(x) (((x) & 0xFF) << 0)
|
|
@@ -147,7 +147,7 @@
|
|
#define QSPI_ADDRESS_VALUE_SET(X) (((x) & 0xFFFF) << 0)
|
|
|
|
#define QSPI_CMB_SEQ_ADDR_CFG 0x1ac
|
|
-#define QSPI_ADDRESS_X1_X2_X4(x) (((x) & 0x3) << 13)
|
|
+#define QSPI_ADDRESS_X1_X2_X4(x) ((((x) >> 1) & 0x3) << 13)
|
|
#define QSPI_ADDRESS_X1_X2_X4_MASK (0x03 << 13)
|
|
#define QSPI_ADDRESS_SDR_DDR BIT(12)
|
|
#define QSPI_ADDRESS_SIZE_SET(x) (((x) & 0xFF) << 0)
|
|
@@ -1036,10 +1036,6 @@ static u32 tegra_qspi_addr_config(bool is_ddr, u8 bus_width, u8 len)
|
|
{
|
|
u32 addr_config = 0;
|
|
|
|
- /* Extract Address configuration and value */
|
|
- is_ddr = 0; //Only SDR mode supported
|
|
- bus_width = 0; //X1 mode
|
|
-
|
|
if (is_ddr)
|
|
addr_config |= QSPI_ADDRESS_SDR_DDR;
|
|
else
|
|
@@ -1079,13 +1075,13 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
|
|
switch (transfer_phase) {
|
|
case CMD_TRANSFER:
|
|
/* X1 SDR mode */
|
|
- cmd_config = tegra_qspi_cmd_config(false, 0,
|
|
+ cmd_config = tegra_qspi_cmd_config(false, xfer->tx_nbits,
|
|
xfer->len);
|
|
cmd_value = *((const u8 *)(xfer->tx_buf));
|
|
break;
|
|
case ADDR_TRANSFER:
|
|
/* X1 SDR mode */
|
|
- addr_config = tegra_qspi_addr_config(false, 0,
|
|
+ addr_config = tegra_qspi_addr_config(false, xfer->tx_nbits,
|
|
xfer->len);
|
|
address_value = *((const u32 *)(xfer->tx_buf));
|
|
break;
|
|
@@ -1163,26 +1159,22 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
|
|
ret = -EIO;
|
|
goto exit;
|
|
}
|
|
- if (!xfer->cs_change) {
|
|
- tegra_qspi_transfer_end(spi);
|
|
- spi_transfer_delay_exec(xfer);
|
|
- }
|
|
break;
|
|
default:
|
|
ret = -EINVAL;
|
|
goto exit;
|
|
}
|
|
msg->actual_length += xfer->len;
|
|
+ if (!xfer->cs_change && transfer_phase == DATA_TRANSFER) {
|
|
+ tegra_qspi_transfer_end(spi);
|
|
+ spi_transfer_delay_exec(xfer);
|
|
+ }
|
|
transfer_phase++;
|
|
}
|
|
ret = 0;
|
|
|
|
exit:
|
|
msg->status = ret;
|
|
- if (ret < 0) {
|
|
- tegra_qspi_transfer_end(spi);
|
|
- spi_transfer_delay_exec(xfer);
|
|
- }
|
|
|
|
return ret;
|
|
}
|
|
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
|
|
index ac398b5a973604..a1d941b0be00b7 100644
|
|
--- a/drivers/staging/media/rkvdec/rkvdec.c
|
|
+++ b/drivers/staging/media/rkvdec/rkvdec.c
|
|
@@ -213,8 +213,14 @@ static int rkvdec_enum_framesizes(struct file *file, void *priv,
|
|
if (!fmt)
|
|
return -EINVAL;
|
|
|
|
- fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
|
|
- fsize->stepwise = fmt->frmsize;
|
|
+ fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
|
|
+ fsize->stepwise.min_width = 1;
|
|
+ fsize->stepwise.max_width = fmt->frmsize.max_width;
|
|
+ fsize->stepwise.step_width = 1;
|
|
+ fsize->stepwise.min_height = 1;
|
|
+ fsize->stepwise.max_height = fmt->frmsize.max_height;
|
|
+ fsize->stepwise.step_height = 1;
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/thunderbolt/ctl.c b/drivers/thunderbolt/ctl.c
|
|
index d997a4c545f796..a60d7afc041f41 100644
|
|
--- a/drivers/thunderbolt/ctl.c
|
|
+++ b/drivers/thunderbolt/ctl.c
|
|
@@ -143,6 +143,11 @@ static void tb_cfg_request_dequeue(struct tb_cfg_request *req)
|
|
struct tb_ctl *ctl = req->ctl;
|
|
|
|
mutex_lock(&ctl->request_queue_lock);
|
|
+ if (!test_bit(TB_CFG_REQUEST_ACTIVE, &req->flags)) {
|
|
+ mutex_unlock(&ctl->request_queue_lock);
|
|
+ return;
|
|
+ }
|
|
+
|
|
list_del(&req->list);
|
|
clear_bit(TB_CFG_REQUEST_ACTIVE, &req->flags);
|
|
if (test_bit(TB_CFG_REQUEST_CANCELED, &req->flags))
|
|
diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c
|
|
index 8db9bd32f47384..e445516290f912 100644
|
|
--- a/drivers/thunderbolt/usb4.c
|
|
+++ b/drivers/thunderbolt/usb4.c
|
|
@@ -442,10 +442,10 @@ int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)
|
|
bool configured = val & PORT_CS_19_PC;
|
|
usb4 = port->usb4;
|
|
|
|
- if (((flags & TB_WAKE_ON_CONNECT) |
|
|
+ if (((flags & TB_WAKE_ON_CONNECT) &&
|
|
device_may_wakeup(&usb4->dev)) && !configured)
|
|
val |= PORT_CS_19_WOC;
|
|
- if (((flags & TB_WAKE_ON_DISCONNECT) |
|
|
+ if (((flags & TB_WAKE_ON_DISCONNECT) &&
|
|
device_may_wakeup(&usb4->dev)) && configured)
|
|
val |= PORT_CS_19_WOD;
|
|
if ((flags & TB_WAKE_ON_USB4) && configured)
|
|
diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c
|
|
index 222afc270c88d6..1bee624bd484cb 100644
|
|
--- a/drivers/tty/serial/jsm/jsm_tty.c
|
|
+++ b/drivers/tty/serial/jsm/jsm_tty.c
|
|
@@ -451,6 +451,7 @@ int jsm_uart_port_init(struct jsm_board *brd)
|
|
if (!brd->channels[i])
|
|
continue;
|
|
|
|
+ brd->channels[i]->uart_port.dev = &brd->pci_dev->dev;
|
|
brd->channels[i]->uart_port.irq = brd->irq;
|
|
brd->channels[i]->uart_port.uartclk = 14745600;
|
|
brd->channels[i]->uart_port.type = PORT_JSM;
|
|
diff --git a/drivers/tty/serial/milbeaut_usio.c b/drivers/tty/serial/milbeaut_usio.c
|
|
index 70a910085e9375..9de3883a4e0b03 100644
|
|
--- a/drivers/tty/serial/milbeaut_usio.c
|
|
+++ b/drivers/tty/serial/milbeaut_usio.c
|
|
@@ -522,7 +522,10 @@ static int mlb_usio_probe(struct platform_device *pdev)
|
|
}
|
|
port->membase = devm_ioremap(&pdev->dev, res->start,
|
|
resource_size(res));
|
|
-
|
|
+ if (!port->membase) {
|
|
+ ret = -ENOMEM;
|
|
+ goto failed;
|
|
+ }
|
|
ret = platform_get_irq_byname(pdev, "rx");
|
|
mlb_usio_irq[index][RX] = ret;
|
|
|
|
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
|
|
index 61d8f50676b1bd..be7e57e1d1e36a 100644
|
|
--- a/drivers/tty/serial/sh-sci.c
|
|
+++ b/drivers/tty/serial/sh-sci.c
|
|
@@ -174,6 +174,7 @@ struct sci_port {
|
|
|
|
bool has_rtscts;
|
|
bool autorts;
|
|
+ bool tx_occurred;
|
|
};
|
|
|
|
#define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS
|
|
@@ -182,6 +183,7 @@ 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 bool sci_uart_earlycon_dev_probing;
|
|
|
|
static inline struct sci_port *
|
|
to_sci_port(struct uart_port *uart)
|
|
@@ -838,6 +840,7 @@ static void sci_transmit_chars(struct uart_port *port)
|
|
{
|
|
struct circ_buf *xmit = &port->state->xmit;
|
|
unsigned int stopped = uart_tx_stopped(port);
|
|
+ struct sci_port *s = to_sci_port(port);
|
|
unsigned short status;
|
|
unsigned short ctrl;
|
|
int count;
|
|
@@ -874,6 +877,7 @@ static void sci_transmit_chars(struct uart_port *port)
|
|
}
|
|
|
|
serial_port_out(port, SCxTDR, c);
|
|
+ s->tx_occurred = true;
|
|
|
|
port->icount.tx++;
|
|
} while (--count > 0);
|
|
@@ -1230,6 +1234,8 @@ static void sci_dma_tx_complete(void *arg)
|
|
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
|
|
uart_write_wakeup(port);
|
|
|
|
+ s->tx_occurred = true;
|
|
+
|
|
if (!uart_circ_empty(xmit)) {
|
|
s->cookie_tx = 0;
|
|
schedule_work(&s->work_tx);
|
|
@@ -1719,6 +1725,19 @@ static void sci_flush_buffer(struct uart_port *port)
|
|
s->cookie_tx = -EINVAL;
|
|
}
|
|
}
|
|
+
|
|
+static void sci_dma_check_tx_occurred(struct sci_port *s)
|
|
+{
|
|
+ struct dma_tx_state state;
|
|
+ enum dma_status status;
|
|
+
|
|
+ if (!s->chan_tx)
|
|
+ return;
|
|
+
|
|
+ status = dmaengine_tx_status(s->chan_tx, s->cookie_tx, &state);
|
|
+ if (status == DMA_COMPLETE || status == DMA_IN_PROGRESS)
|
|
+ s->tx_occurred = true;
|
|
+}
|
|
#else /* !CONFIG_SERIAL_SH_SCI_DMA */
|
|
static inline void sci_request_dma(struct uart_port *port)
|
|
{
|
|
@@ -1728,6 +1747,10 @@ static inline void sci_free_dma(struct uart_port *port)
|
|
{
|
|
}
|
|
|
|
+static void sci_dma_check_tx_occurred(struct sci_port *s)
|
|
+{
|
|
+}
|
|
+
|
|
#define sci_flush_buffer NULL
|
|
#endif /* !CONFIG_SERIAL_SH_SCI_DMA */
|
|
|
|
@@ -2064,6 +2087,12 @@ static unsigned int sci_tx_empty(struct uart_port *port)
|
|
{
|
|
unsigned short status = serial_port_in(port, SCxSR);
|
|
unsigned short in_tx_fifo = sci_txfill(port);
|
|
+ struct sci_port *s = to_sci_port(port);
|
|
+
|
|
+ sci_dma_check_tx_occurred(s);
|
|
+
|
|
+ if (!s->tx_occurred)
|
|
+ return TIOCSER_TEMT;
|
|
|
|
return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0;
|
|
}
|
|
@@ -2234,6 +2263,7 @@ static int sci_startup(struct uart_port *port)
|
|
|
|
dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
|
|
|
|
+ s->tx_occurred = false;
|
|
sci_request_dma(port);
|
|
|
|
ret = sci_request_irq(s);
|
|
@@ -3014,10 +3044,6 @@ static int sci_init_single(struct platform_device *dev,
|
|
ret = sci_init_clocks(sci_port, &dev->dev);
|
|
if (ret < 0)
|
|
return ret;
|
|
-
|
|
- port->dev = &dev->dev;
|
|
-
|
|
- pm_runtime_enable(&dev->dev);
|
|
}
|
|
|
|
port->type = p->type;
|
|
@@ -3047,11 +3073,6 @@ static int sci_init_single(struct platform_device *dev,
|
|
return 0;
|
|
}
|
|
|
|
-static void sci_cleanup_single(struct sci_port *port)
|
|
-{
|
|
- pm_runtime_disable(port->port.dev);
|
|
-}
|
|
-
|
|
#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) || \
|
|
defined(CONFIG_SERIAL_SH_SCI_EARLYCON)
|
|
static void serial_console_putchar(struct uart_port *port, unsigned char ch)
|
|
@@ -3221,8 +3242,6 @@ static int sci_remove(struct platform_device *dev)
|
|
sci_ports_in_use &= ~BIT(port->port.line);
|
|
uart_remove_one_port(&sci_uart_driver, &port->port);
|
|
|
|
- sci_cleanup_single(port);
|
|
-
|
|
if (port->port.fifosize > 1)
|
|
device_remove_file(&dev->dev, &dev_attr_rx_fifo_trigger);
|
|
if (type == PORT_SCIFA || type == PORT_SCIFB || type == PORT_HSCIF)
|
|
@@ -3356,7 +3375,8 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev,
|
|
static int sci_probe_single(struct platform_device *dev,
|
|
unsigned int index,
|
|
struct plat_sci_port *p,
|
|
- struct sci_port *sciport)
|
|
+ struct sci_port *sciport,
|
|
+ struct resource *sci_res)
|
|
{
|
|
int ret;
|
|
|
|
@@ -3385,6 +3405,11 @@ static int sci_probe_single(struct platform_device *dev,
|
|
if (ret)
|
|
return ret;
|
|
|
|
+ sciport->port.dev = &dev->dev;
|
|
+ ret = devm_pm_runtime_enable(&dev->dev);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
sciport->gpios = mctrl_gpio_init(&sciport->port, 0);
|
|
if (IS_ERR(sciport->gpios))
|
|
return PTR_ERR(sciport->gpios);
|
|
@@ -3398,13 +3423,15 @@ static int sci_probe_single(struct platform_device *dev,
|
|
sciport->port.flags |= UPF_HARD_FLOW;
|
|
}
|
|
|
|
- ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
|
|
- if (ret) {
|
|
- sci_cleanup_single(sciport);
|
|
- return ret;
|
|
+ if (sci_uart_earlycon && sci_ports[0].port.mapbase == sci_res->start) {
|
|
+ /*
|
|
+ * Skip cleanup the sci_port[0] in early_console_exit(), this
|
|
+ * port is the same as the earlycon one.
|
|
+ */
|
|
+ sci_uart_earlycon_dev_probing = true;
|
|
}
|
|
|
|
- return 0;
|
|
+ return uart_add_one_port(&sci_uart_driver, &sciport->port);
|
|
}
|
|
|
|
static int sci_probe(struct platform_device *dev)
|
|
@@ -3462,7 +3489,7 @@ static int sci_probe(struct platform_device *dev)
|
|
|
|
platform_set_drvdata(dev, sp);
|
|
|
|
- ret = sci_probe_single(dev, dev_id, p, sp);
|
|
+ ret = sci_probe_single(dev, dev_id, p, sp, res);
|
|
if (ret)
|
|
return ret;
|
|
|
|
@@ -3619,6 +3646,22 @@ sh_early_platform_init_buffer("earlyprintk", &sci_driver,
|
|
#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON
|
|
static struct plat_sci_port port_cfg;
|
|
|
|
+static int early_console_exit(struct console *co)
|
|
+{
|
|
+ struct sci_port *sci_port = &sci_ports[0];
|
|
+
|
|
+ /*
|
|
+ * Clean the slot used by earlycon. A new SCI device might
|
|
+ * map to this slot.
|
|
+ */
|
|
+ if (!sci_uart_earlycon_dev_probing) {
|
|
+ memset(sci_port, 0, sizeof(*sci_port));
|
|
+ sci_uart_earlycon = false;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int __init early_console_setup(struct earlycon_device *device,
|
|
int type)
|
|
{
|
|
@@ -3638,6 +3681,8 @@ static int __init early_console_setup(struct earlycon_device *device,
|
|
SCSCR_RE | SCSCR_TE | port_cfg.scscr);
|
|
|
|
device->con->write = serial_console_write;
|
|
+ device->con->exit = early_console_exit;
|
|
+
|
|
return 0;
|
|
}
|
|
static int __init sci_early_console_setup(struct earlycon_device *device,
|
|
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
|
|
index 8c685b5014044b..5b21b60547da1f 100644
|
|
--- a/drivers/tty/vt/vt_ioctl.c
|
|
+++ b/drivers/tty/vt/vt_ioctl.c
|
|
@@ -1105,8 +1105,6 @@ long vt_compat_ioctl(struct tty_struct *tty,
|
|
case VT_WAITACTIVE:
|
|
case VT_RELDISP:
|
|
case VT_DISALLOCATE:
|
|
- case VT_RESIZE:
|
|
- case VT_RESIZEX:
|
|
return vt_ioctl(tty, cmd, arg);
|
|
|
|
/*
|
|
diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c
|
|
index 411109a5ebbffd..14864cfc242238 100644
|
|
--- a/drivers/ufs/core/ufs-mcq.c
|
|
+++ b/drivers/ufs/core/ufs-mcq.c
|
|
@@ -629,7 +629,6 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
|
|
int tag = scsi_cmd_to_rq(cmd)->tag;
|
|
struct ufshcd_lrb *lrbp = &hba->lrb[tag];
|
|
struct ufs_hw_queue *hwq;
|
|
- unsigned long flags;
|
|
int err;
|
|
|
|
/* Skip task abort in case previous aborts failed and report failure */
|
|
@@ -668,10 +667,5 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd)
|
|
return FAILED;
|
|
}
|
|
|
|
- spin_lock_irqsave(&hwq->cq_lock, flags);
|
|
- if (ufshcd_cmd_inflight(lrbp->cmd))
|
|
- ufshcd_release_scsi_cmd(hba, lrbp);
|
|
- spin_unlock_irqrestore(&hwq->cq_lock, flags);
|
|
-
|
|
return SUCCESS;
|
|
}
|
|
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
|
|
index 2346a1fc72b56e..9dabc03675b00a 100644
|
|
--- a/drivers/ufs/core/ufshcd.c
|
|
+++ b/drivers/ufs/core/ufshcd.c
|
|
@@ -6500,9 +6500,14 @@ static void ufshcd_err_handler(struct work_struct *work)
|
|
up(&hba->host_sem);
|
|
return;
|
|
}
|
|
- ufshcd_set_eh_in_progress(hba);
|
|
spin_unlock_irqrestore(hba->host->host_lock, flags);
|
|
+
|
|
ufshcd_err_handling_prepare(hba);
|
|
+
|
|
+ spin_lock_irqsave(hba->host->host_lock, flags);
|
|
+ ufshcd_set_eh_in_progress(hba);
|
|
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
|
|
+
|
|
/* Complete requests that have door-bell cleared by h/w */
|
|
ufshcd_complete_requests(hba, false);
|
|
spin_lock_irqsave(hba->host->host_lock, flags);
|
|
diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
|
|
index c6417ef074a478..c94824c999ccd9 100644
|
|
--- a/drivers/ufs/host/ufs-qcom.c
|
|
+++ b/drivers/ufs/host/ufs-qcom.c
|
|
@@ -453,10 +453,9 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
|
|
dev_warn(hba->dev, "%s: host reset returned %d\n",
|
|
__func__, ret);
|
|
|
|
- if (phy->power_count) {
|
|
+ if (phy->power_count)
|
|
phy_power_off(phy);
|
|
- phy_exit(phy);
|
|
- }
|
|
+
|
|
|
|
/* phy initialization - calibrate the phy */
|
|
ret = phy_init(phy);
|
|
diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c
|
|
index 601a60a2802240..132885fbb98f67 100644
|
|
--- a/drivers/usb/cdns3/cdnsp-gadget.c
|
|
+++ b/drivers/usb/cdns3/cdnsp-gadget.c
|
|
@@ -28,7 +28,8 @@
|
|
unsigned int cdnsp_port_speed(unsigned int port_status)
|
|
{
|
|
/*Detect gadget speed based on PORTSC register*/
|
|
- if (DEV_SUPERSPEEDPLUS(port_status))
|
|
+ if (DEV_SUPERSPEEDPLUS(port_status) ||
|
|
+ DEV_SSP_GEN1x2(port_status) || DEV_SSP_GEN2x2(port_status))
|
|
return USB_SPEED_SUPER_PLUS;
|
|
else if (DEV_SUPERSPEED(port_status))
|
|
return USB_SPEED_SUPER;
|
|
@@ -546,6 +547,7 @@ int cdnsp_wait_for_cmd_compl(struct cdnsp_device *pdev)
|
|
dma_addr_t cmd_deq_dma;
|
|
union cdnsp_trb *event;
|
|
u32 cycle_state;
|
|
+ u32 retry = 10;
|
|
int ret, val;
|
|
u64 cmd_dma;
|
|
u32 flags;
|
|
@@ -577,8 +579,23 @@ int cdnsp_wait_for_cmd_compl(struct cdnsp_device *pdev)
|
|
flags = le32_to_cpu(event->event_cmd.flags);
|
|
|
|
/* Check the owner of the TRB. */
|
|
- if ((flags & TRB_CYCLE) != cycle_state)
|
|
+ if ((flags & TRB_CYCLE) != cycle_state) {
|
|
+ /*
|
|
+ * Give some extra time to get chance controller
|
|
+ * to finish command before returning error code.
|
|
+ * Checking CMD_RING_BUSY is not sufficient because
|
|
+ * this bit is cleared to '0' when the Command
|
|
+ * Descriptor has been executed by controller
|
|
+ * and not when command completion event has
|
|
+ * be added to event ring.
|
|
+ */
|
|
+ if (retry--) {
|
|
+ udelay(20);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
return -EINVAL;
|
|
+ }
|
|
|
|
cmd_dma = le64_to_cpu(event->event_cmd.cmd_trb);
|
|
|
|
diff --git a/drivers/usb/cdns3/cdnsp-gadget.h b/drivers/usb/cdns3/cdnsp-gadget.h
|
|
index ed84dbb9fd6fbc..909cee01772a70 100644
|
|
--- a/drivers/usb/cdns3/cdnsp-gadget.h
|
|
+++ b/drivers/usb/cdns3/cdnsp-gadget.h
|
|
@@ -285,11 +285,15 @@ struct cdnsp_port_regs {
|
|
#define XDEV_HS (0x3 << 10)
|
|
#define XDEV_SS (0x4 << 10)
|
|
#define XDEV_SSP (0x5 << 10)
|
|
+#define XDEV_SSP1x2 (0x6 << 10)
|
|
+#define XDEV_SSP2x2 (0x7 << 10)
|
|
#define DEV_UNDEFSPEED(p) (((p) & DEV_SPEED_MASK) == (0x0 << 10))
|
|
#define DEV_FULLSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_FS)
|
|
#define DEV_HIGHSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_HS)
|
|
#define DEV_SUPERSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_SS)
|
|
#define DEV_SUPERSPEEDPLUS(p) (((p) & DEV_SPEED_MASK) == XDEV_SSP)
|
|
+#define DEV_SSP_GEN1x2(p) (((p) & DEV_SPEED_MASK) == XDEV_SSP1x2)
|
|
+#define DEV_SSP_GEN2x2(p) (((p) & DEV_SPEED_MASK) == XDEV_SSP2x2)
|
|
#define DEV_SUPERSPEED_ANY(p) (((p) & DEV_SPEED_MASK) >= XDEV_SS)
|
|
#define DEV_PORT_SPEED(p) (((p) >> 10) & 0x0f)
|
|
/* Port Link State Write Strobe - set this when changing link state */
|
|
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
|
|
index 2f92905e05cad0..ee45f3c74aecb5 100644
|
|
--- a/drivers/usb/class/usbtmc.c
|
|
+++ b/drivers/usb/class/usbtmc.c
|
|
@@ -483,6 +483,7 @@ static int usbtmc_get_stb(struct usbtmc_file_data *file_data, __u8 *stb)
|
|
u8 tag;
|
|
int rv;
|
|
long wait_rv;
|
|
+ unsigned long expire;
|
|
|
|
dev_dbg(dev, "Enter ioctl_read_stb iin_ep_present: %d\n",
|
|
data->iin_ep_present);
|
|
@@ -512,10 +513,11 @@ static int usbtmc_get_stb(struct usbtmc_file_data *file_data, __u8 *stb)
|
|
}
|
|
|
|
if (data->iin_ep_present) {
|
|
+ expire = msecs_to_jiffies(file_data->timeout);
|
|
wait_rv = wait_event_interruptible_timeout(
|
|
data->waitq,
|
|
atomic_read(&data->iin_data_valid) != 0,
|
|
- file_data->timeout);
|
|
+ expire);
|
|
if (wait_rv < 0) {
|
|
dev_dbg(dev, "wait interrupted %ld\n", wait_rv);
|
|
rv = wait_rv;
|
|
@@ -563,14 +565,15 @@ static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data,
|
|
|
|
rv = usbtmc_get_stb(file_data, &stb);
|
|
|
|
- if (rv > 0) {
|
|
- srq_asserted = atomic_xchg(&file_data->srq_asserted,
|
|
- srq_asserted);
|
|
- if (srq_asserted)
|
|
- stb |= 0x40; /* Set RQS bit */
|
|
+ if (rv < 0)
|
|
+ return rv;
|
|
+
|
|
+ srq_asserted = atomic_xchg(&file_data->srq_asserted, srq_asserted);
|
|
+ if (srq_asserted)
|
|
+ stb |= 0x40; /* Set RQS bit */
|
|
+
|
|
+ rv = put_user(stb, (__u8 __user *)arg);
|
|
|
|
- rv = put_user(stb, (__u8 __user *)arg);
|
|
- }
|
|
return rv;
|
|
|
|
}
|
|
@@ -2199,7 +2202,7 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|
|
|
case USBTMC_IOCTL_GET_STB:
|
|
retval = usbtmc_get_stb(file_data, &tmp_byte);
|
|
- if (retval > 0)
|
|
+ if (!retval)
|
|
retval = put_user(tmp_byte, (__u8 __user *)arg);
|
|
break;
|
|
|
|
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
|
|
index 760283a541b41b..855356752380b6 100644
|
|
--- a/drivers/usb/core/hub.c
|
|
+++ b/drivers/usb/core/hub.c
|
|
@@ -6103,6 +6103,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
|
|
struct usb_hub *parent_hub;
|
|
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
|
|
struct usb_device_descriptor descriptor;
|
|
+ struct usb_interface *intf;
|
|
struct usb_host_bos *bos;
|
|
int i, j, ret = 0;
|
|
int port1 = udev->portnum;
|
|
@@ -6160,6 +6161,18 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
|
|
if (!udev->actconfig)
|
|
goto done;
|
|
|
|
+ /*
|
|
+ * Some devices can't handle setting default altsetting 0 with a
|
|
+ * Set-Interface request. Disable host-side endpoints of those
|
|
+ * interfaces here. Enable and reset them back after host has set
|
|
+ * its internal endpoint structures during usb_hcd_alloc_bandwith()
|
|
+ */
|
|
+ for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
|
|
+ intf = udev->actconfig->interface[i];
|
|
+ if (intf->cur_altsetting->desc.bAlternateSetting == 0)
|
|
+ usb_disable_interface(udev, intf, true);
|
|
+ }
|
|
+
|
|
mutex_lock(hcd->bandwidth_mutex);
|
|
ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL);
|
|
if (ret < 0) {
|
|
@@ -6191,12 +6204,11 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
|
|
*/
|
|
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
|
|
struct usb_host_config *config = udev->actconfig;
|
|
- struct usb_interface *intf = config->interface[i];
|
|
struct usb_interface_descriptor *desc;
|
|
|
|
+ intf = config->interface[i];
|
|
desc = &intf->cur_altsetting->desc;
|
|
if (desc->bAlternateSetting == 0) {
|
|
- usb_disable_interface(udev, intf, true);
|
|
usb_enable_interface(udev, intf, true);
|
|
ret = 0;
|
|
} else {
|
|
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
|
|
index 4903c733d37ae7..c979ecd0169a2d 100644
|
|
--- a/drivers/usb/core/quirks.c
|
|
+++ b/drivers/usb/core/quirks.c
|
|
@@ -372,6 +372,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|
/* SanDisk Corp. SanDisk 3.2Gen1 */
|
|
{ USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT },
|
|
|
|
+ /* SanDisk Extreme 55AE */
|
|
+ { USB_DEVICE(0x0781, 0x55ae), .driver_info = USB_QUIRK_NO_LPM },
|
|
+
|
|
/* Realforce 87U Keyboard */
|
|
{ USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM },
|
|
|
|
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
|
|
index 2db01e03bfbf0b..2f1ec03d17d6db 100644
|
|
--- a/drivers/usb/gadget/function/f_hid.c
|
|
+++ b/drivers/usb/gadget/function/f_hid.c
|
|
@@ -118,8 +118,8 @@ static struct hid_descriptor hidg_desc = {
|
|
.bcdHID = cpu_to_le16(0x0101),
|
|
.bCountryCode = 0x00,
|
|
.bNumDescriptors = 0x1,
|
|
- /*.desc[0].bDescriptorType = DYNAMIC */
|
|
- /*.desc[0].wDescriptorLenght = DYNAMIC */
|
|
+ /*.rpt_desc.bDescriptorType = DYNAMIC */
|
|
+ /*.rpt_desc.wDescriptorLength = DYNAMIC */
|
|
};
|
|
|
|
/* Super-Speed Support */
|
|
@@ -728,8 +728,8 @@ static int hidg_setup(struct usb_function *f,
|
|
struct hid_descriptor hidg_desc_copy = hidg_desc;
|
|
|
|
VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: HID\n");
|
|
- hidg_desc_copy.desc[0].bDescriptorType = HID_DT_REPORT;
|
|
- hidg_desc_copy.desc[0].wDescriptorLength =
|
|
+ hidg_desc_copy.rpt_desc.bDescriptorType = HID_DT_REPORT;
|
|
+ hidg_desc_copy.rpt_desc.wDescriptorLength =
|
|
cpu_to_le16(hidg->report_desc_length);
|
|
|
|
length = min_t(unsigned short, length,
|
|
@@ -970,8 +970,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
|
|
* We can use hidg_desc struct here but we should not relay
|
|
* that its content won't change after returning from this function.
|
|
*/
|
|
- hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT;
|
|
- hidg_desc.desc[0].wDescriptorLength =
|
|
+ hidg_desc.rpt_desc.bDescriptorType = HID_DT_REPORT;
|
|
+ hidg_desc.rpt_desc.wDescriptorLength =
|
|
cpu_to_le16(hidg->report_desc_length);
|
|
|
|
hidg_hs_in_ep_desc.bEndpointAddress =
|
|
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c
|
|
index 205820544f6f9e..b720899725e537 100644
|
|
--- a/drivers/usb/renesas_usbhs/common.c
|
|
+++ b/drivers/usb/renesas_usbhs/common.c
|
|
@@ -674,10 +674,29 @@ static int usbhs_probe(struct platform_device *pdev)
|
|
INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug);
|
|
spin_lock_init(usbhs_priv_to_lock(priv));
|
|
|
|
+ /*
|
|
+ * Acquire clocks and enable power management (PM) early in the
|
|
+ * probe process, as the driver accesses registers during
|
|
+ * initialization. Ensure the device is active before proceeding.
|
|
+ */
|
|
+ pm_runtime_enable(dev);
|
|
+
|
|
+ ret = usbhsc_clk_get(dev, priv);
|
|
+ if (ret)
|
|
+ goto probe_pm_disable;
|
|
+
|
|
+ ret = pm_runtime_resume_and_get(dev);
|
|
+ if (ret)
|
|
+ goto probe_clk_put;
|
|
+
|
|
+ ret = usbhsc_clk_prepare_enable(priv);
|
|
+ if (ret)
|
|
+ goto probe_pm_put;
|
|
+
|
|
/* call pipe and module init */
|
|
ret = usbhs_pipe_probe(priv);
|
|
if (ret < 0)
|
|
- return ret;
|
|
+ goto probe_clk_dis_unprepare;
|
|
|
|
ret = usbhs_fifo_probe(priv);
|
|
if (ret < 0)
|
|
@@ -694,10 +713,6 @@ static int usbhs_probe(struct platform_device *pdev)
|
|
if (ret)
|
|
goto probe_fail_rst;
|
|
|
|
- ret = usbhsc_clk_get(dev, priv);
|
|
- if (ret)
|
|
- goto probe_fail_clks;
|
|
-
|
|
/*
|
|
* deviece reset here because
|
|
* USB device might be used in boot loader.
|
|
@@ -710,7 +725,7 @@ static int usbhs_probe(struct platform_device *pdev)
|
|
if (ret) {
|
|
dev_warn(dev, "USB function not selected (GPIO)\n");
|
|
ret = -ENOTSUPP;
|
|
- goto probe_end_mod_exit;
|
|
+ goto probe_assert_rest;
|
|
}
|
|
}
|
|
|
|
@@ -724,14 +739,19 @@ static int usbhs_probe(struct platform_device *pdev)
|
|
ret = usbhs_platform_call(priv, hardware_init, pdev);
|
|
if (ret < 0) {
|
|
dev_err(dev, "platform init failed.\n");
|
|
- goto probe_end_mod_exit;
|
|
+ goto probe_assert_rest;
|
|
}
|
|
|
|
/* reset phy for connection */
|
|
usbhs_platform_call(priv, phy_reset, pdev);
|
|
|
|
- /* power control */
|
|
- pm_runtime_enable(dev);
|
|
+ /*
|
|
+ * Disable the clocks that were enabled earlier in the probe path,
|
|
+ * and let the driver handle the clocks beyond this point.
|
|
+ */
|
|
+ usbhsc_clk_disable_unprepare(priv);
|
|
+ pm_runtime_put(dev);
|
|
+
|
|
if (!usbhs_get_dparam(priv, runtime_pwctrl)) {
|
|
usbhsc_power_ctrl(priv, 1);
|
|
usbhs_mod_autonomy_mode(priv);
|
|
@@ -748,9 +768,7 @@ static int usbhs_probe(struct platform_device *pdev)
|
|
|
|
return ret;
|
|
|
|
-probe_end_mod_exit:
|
|
- usbhsc_clk_put(priv);
|
|
-probe_fail_clks:
|
|
+probe_assert_rest:
|
|
reset_control_assert(priv->rsts);
|
|
probe_fail_rst:
|
|
usbhs_mod_remove(priv);
|
|
@@ -758,6 +776,14 @@ static int usbhs_probe(struct platform_device *pdev)
|
|
usbhs_fifo_remove(priv);
|
|
probe_end_pipe_exit:
|
|
usbhs_pipe_remove(priv);
|
|
+probe_clk_dis_unprepare:
|
|
+ usbhsc_clk_disable_unprepare(priv);
|
|
+probe_pm_put:
|
|
+ pm_runtime_put(dev);
|
|
+probe_clk_put:
|
|
+ usbhsc_clk_put(priv);
|
|
+probe_pm_disable:
|
|
+ pm_runtime_disable(dev);
|
|
|
|
dev_info(dev, "probe failed (%d)\n", ret);
|
|
|
|
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
|
|
index 8e327fcb222f73..1ba2287d4d456f 100644
|
|
--- a/drivers/usb/serial/pl2303.c
|
|
+++ b/drivers/usb/serial/pl2303.c
|
|
@@ -457,6 +457,8 @@ static int pl2303_detect_type(struct usb_serial *serial)
|
|
case 0x605:
|
|
case 0x700: /* GR */
|
|
case 0x705:
|
|
+ case 0x905: /* GT-2AB */
|
|
+ case 0x1005: /* GC-Q20 */
|
|
return TYPE_HXN;
|
|
}
|
|
break;
|
|
diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h
|
|
index d460d71b425783..1477e31d776327 100644
|
|
--- a/drivers/usb/storage/unusual_uas.h
|
|
+++ b/drivers/usb/storage/unusual_uas.h
|
|
@@ -52,6 +52,13 @@ UNUSUAL_DEV(0x059f, 0x1061, 0x0000, 0x9999,
|
|
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
|
US_FL_NO_REPORT_OPCODES | US_FL_NO_SAME),
|
|
|
|
+/* Reported-by: Zhihong Zhou <zhouzhihong@greatwall.com.cn> */
|
|
+UNUSUAL_DEV(0x0781, 0x55e8, 0x0000, 0x9999,
|
|
+ "SanDisk",
|
|
+ "",
|
|
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
|
+ US_FL_IGNORE_UAS),
|
|
+
|
|
/* Reported-by: Hongling Zeng <zenghongling@kylinos.cn> */
|
|
UNUSUAL_DEV(0x090c, 0x2000, 0x0000, 0x9999,
|
|
"Hiksemi",
|
|
diff --git a/drivers/usb/typec/tcpm/tcpci_maxim_core.c b/drivers/usb/typec/tcpm/tcpci_maxim_core.c
|
|
index 9454b12a073c96..e460b956ab7123 100644
|
|
--- a/drivers/usb/typec/tcpm/tcpci_maxim_core.c
|
|
+++ b/drivers/usb/typec/tcpm/tcpci_maxim_core.c
|
|
@@ -145,7 +145,8 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status)
|
|
return;
|
|
}
|
|
|
|
- if (count > sizeof(struct pd_message) || count + 1 > TCPC_RECEIVE_BUFFER_LEN) {
|
|
+ if (count > sizeof(struct pd_message) + 1 ||
|
|
+ count + 1 > TCPC_RECEIVE_BUFFER_LEN) {
|
|
dev_err(chip->dev, "Invalid TCPC_RX_BYTE_CNT %d\n", count);
|
|
return;
|
|
}
|
|
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
|
|
index 3bb23a2ea547ac..7706f4e951258b 100644
|
|
--- a/drivers/usb/typec/ucsi/ucsi.h
|
|
+++ b/drivers/usb/typec/ucsi/ucsi.h
|
|
@@ -302,7 +302,7 @@ struct ucsi_debugfs_entry {
|
|
u64 low;
|
|
u64 high;
|
|
} response;
|
|
- u32 status;
|
|
+ int status;
|
|
struct dentry *dentry;
|
|
};
|
|
|
|
diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
|
|
index 4d27465c8f1a89..712b178c42aae5 100644
|
|
--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
|
|
+++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
|
|
@@ -350,6 +350,32 @@ static int vf_qm_func_stop(struct hisi_qm *qm)
|
|
return hisi_qm_mb(qm, QM_MB_CMD_PAUSE_QM, 0, 0, 0);
|
|
}
|
|
|
|
+static int vf_qm_version_check(struct acc_vf_data *vf_data, struct device *dev)
|
|
+{
|
|
+ switch (vf_data->acc_magic) {
|
|
+ case ACC_DEV_MAGIC_V2:
|
|
+ if (vf_data->major_ver != ACC_DRV_MAJOR_VER) {
|
|
+ dev_info(dev, "migration driver version<%u.%u> not match!\n",
|
|
+ vf_data->major_ver, vf_data->minor_ver);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ break;
|
|
+ case ACC_DEV_MAGIC_V1:
|
|
+ /* Correct dma address */
|
|
+ vf_data->eqe_dma = vf_data->qm_eqc_dw[QM_XQC_ADDR_HIGH];
|
|
+ vf_data->eqe_dma <<= QM_XQC_ADDR_OFFSET;
|
|
+ vf_data->eqe_dma |= vf_data->qm_eqc_dw[QM_XQC_ADDR_LOW];
|
|
+ vf_data->aeqe_dma = vf_data->qm_aeqc_dw[QM_XQC_ADDR_HIGH];
|
|
+ vf_data->aeqe_dma <<= QM_XQC_ADDR_OFFSET;
|
|
+ vf_data->aeqe_dma |= vf_data->qm_aeqc_dw[QM_XQC_ADDR_LOW];
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
|
|
struct hisi_acc_vf_migration_file *migf)
|
|
{
|
|
@@ -363,7 +389,8 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
|
|
if (migf->total_length < QM_MATCH_SIZE || hisi_acc_vdev->match_done)
|
|
return 0;
|
|
|
|
- if (vf_data->acc_magic != ACC_DEV_MAGIC) {
|
|
+ ret = vf_qm_version_check(vf_data, dev);
|
|
+ if (ret) {
|
|
dev_err(dev, "failed to match ACC_DEV_MAGIC\n");
|
|
return -EINVAL;
|
|
}
|
|
@@ -399,13 +426,6 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
|
|
return -EINVAL;
|
|
}
|
|
|
|
- ret = qm_write_regs(vf_qm, QM_VF_STATE, &vf_data->vf_qm_state, 1);
|
|
- if (ret) {
|
|
- dev_err(dev, "failed to write QM_VF_STATE\n");
|
|
- return ret;
|
|
- }
|
|
-
|
|
- hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state;
|
|
hisi_acc_vdev->match_done = true;
|
|
return 0;
|
|
}
|
|
@@ -418,7 +438,9 @@ static int vf_qm_get_match_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
|
|
int vf_id = hisi_acc_vdev->vf_id;
|
|
int ret;
|
|
|
|
- vf_data->acc_magic = ACC_DEV_MAGIC;
|
|
+ vf_data->acc_magic = ACC_DEV_MAGIC_V2;
|
|
+ vf_data->major_ver = ACC_DRV_MAJOR_VER;
|
|
+ vf_data->minor_ver = ACC_DRV_MINOR_VER;
|
|
/* Save device id */
|
|
vf_data->dev_id = hisi_acc_vdev->vf_dev->device;
|
|
|
|
@@ -441,6 +463,19 @@ static int vf_qm_get_match_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
|
|
return 0;
|
|
}
|
|
|
|
+static void vf_qm_xeqc_save(struct hisi_qm *qm,
|
|
+ struct hisi_acc_vf_migration_file *migf)
|
|
+{
|
|
+ struct acc_vf_data *vf_data = &migf->vf_data;
|
|
+ u16 eq_head, aeq_head;
|
|
+
|
|
+ eq_head = vf_data->qm_eqc_dw[0] & 0xFFFF;
|
|
+ qm_db(qm, 0, QM_DOORBELL_CMD_EQ, eq_head, 0);
|
|
+
|
|
+ aeq_head = vf_data->qm_aeqc_dw[0] & 0xFFFF;
|
|
+ qm_db(qm, 0, QM_DOORBELL_CMD_AEQ, aeq_head, 0);
|
|
+}
|
|
+
|
|
static int vf_qm_load_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
|
|
struct hisi_acc_vf_migration_file *migf)
|
|
{
|
|
@@ -456,6 +491,20 @@ static int vf_qm_load_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
|
|
if (migf->total_length < sizeof(struct acc_vf_data))
|
|
return -EINVAL;
|
|
|
|
+ if (!vf_data->eqe_dma || !vf_data->aeqe_dma ||
|
|
+ !vf_data->sqc_dma || !vf_data->cqc_dma) {
|
|
+ dev_info(dev, "resume dma addr is NULL!\n");
|
|
+ hisi_acc_vdev->vf_qm_state = QM_NOT_READY;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ ret = qm_write_regs(qm, QM_VF_STATE, &vf_data->vf_qm_state, 1);
|
|
+ if (ret) {
|
|
+ dev_err(dev, "failed to write QM_VF_STATE\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state;
|
|
+
|
|
qm->eqe_dma = vf_data->eqe_dma;
|
|
qm->aeqe_dma = vf_data->aeqe_dma;
|
|
qm->sqc_dma = vf_data->sqc_dma;
|
|
@@ -516,12 +565,12 @@ static int vf_qm_state_save(struct hisi_acc_vf_core_device *hisi_acc_vdev,
|
|
return -EINVAL;
|
|
|
|
/* Every reg is 32 bit, the dma address is 64 bit. */
|
|
- vf_data->eqe_dma = vf_data->qm_eqc_dw[1];
|
|
+ vf_data->eqe_dma = vf_data->qm_eqc_dw[QM_XQC_ADDR_HIGH];
|
|
vf_data->eqe_dma <<= QM_XQC_ADDR_OFFSET;
|
|
- vf_data->eqe_dma |= vf_data->qm_eqc_dw[0];
|
|
- vf_data->aeqe_dma = vf_data->qm_aeqc_dw[1];
|
|
+ vf_data->eqe_dma |= vf_data->qm_eqc_dw[QM_XQC_ADDR_LOW];
|
|
+ vf_data->aeqe_dma = vf_data->qm_aeqc_dw[QM_XQC_ADDR_HIGH];
|
|
vf_data->aeqe_dma <<= QM_XQC_ADDR_OFFSET;
|
|
- vf_data->aeqe_dma |= vf_data->qm_aeqc_dw[0];
|
|
+ vf_data->aeqe_dma |= vf_data->qm_aeqc_dw[QM_XQC_ADDR_LOW];
|
|
|
|
/* Through SQC_BT/CQC_BT to get sqc and cqc address */
|
|
ret = qm_get_sqc(vf_qm, &vf_data->sqc_dma);
|
|
@@ -537,6 +586,9 @@ static int vf_qm_state_save(struct hisi_acc_vf_core_device *hisi_acc_vdev,
|
|
}
|
|
|
|
migf->total_length = sizeof(struct acc_vf_data);
|
|
+ /* Save eqc and aeqc interrupt information */
|
|
+ vf_qm_xeqc_save(vf_qm, migf);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -1352,6 +1404,7 @@ static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev)
|
|
hisi_acc_vdev->vf_id = pci_iov_vf_id(pdev) + 1;
|
|
hisi_acc_vdev->pf_qm = pf_qm;
|
|
hisi_acc_vdev->vf_dev = pdev;
|
|
+ hisi_acc_vdev->vf_qm_state = QM_NOT_READY;
|
|
mutex_init(&hisi_acc_vdev->state_mutex);
|
|
|
|
core_vdev->migration_flags = VFIO_MIGRATION_STOP_COPY | VFIO_MIGRATION_PRE_COPY;
|
|
diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h
|
|
index dcabfeec6ca19d..f1d8fe86b6eb26 100644
|
|
--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h
|
|
+++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h
|
|
@@ -38,6 +38,9 @@
|
|
#define QM_REG_ADDR_OFFSET 0x0004
|
|
|
|
#define QM_XQC_ADDR_OFFSET 32U
|
|
+#define QM_XQC_ADDR_LOW 0x1
|
|
+#define QM_XQC_ADDR_HIGH 0x2
|
|
+
|
|
#define QM_VF_AEQ_INT_MASK 0x0004
|
|
#define QM_VF_EQ_INT_MASK 0x000c
|
|
#define QM_IFC_INT_SOURCE_V 0x0020
|
|
@@ -49,10 +52,15 @@
|
|
#define QM_EQC_DW0 0X8000
|
|
#define QM_AEQC_DW0 0X8020
|
|
|
|
+#define ACC_DRV_MAJOR_VER 1
|
|
+#define ACC_DRV_MINOR_VER 0
|
|
+
|
|
+#define ACC_DEV_MAGIC_V1 0XCDCDCDCDFEEDAACC
|
|
+#define ACC_DEV_MAGIC_V2 0xAACCFEEDDECADEDE
|
|
+
|
|
struct acc_vf_data {
|
|
#define QM_MATCH_SIZE offsetofend(struct acc_vf_data, qm_rsv_state)
|
|
/* QM match information */
|
|
-#define ACC_DEV_MAGIC 0XCDCDCDCDFEEDAACC
|
|
u64 acc_magic;
|
|
u32 qp_num;
|
|
u32 dev_id;
|
|
@@ -60,7 +68,9 @@ struct acc_vf_data {
|
|
u32 qp_base;
|
|
u32 vf_qm_state;
|
|
/* QM reserved match information */
|
|
- u32 qm_rsv_state[3];
|
|
+ u16 major_ver;
|
|
+ u16 minor_ver;
|
|
+ u32 qm_rsv_state[2];
|
|
|
|
/* QM RW regs */
|
|
u32 aeq_int_mask;
|
|
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
|
|
index eacd6ec04de5a4..5fe7aed3672eea 100644
|
|
--- a/drivers/vfio/vfio_iommu_type1.c
|
|
+++ b/drivers/vfio/vfio_iommu_type1.c
|
|
@@ -294,7 +294,7 @@ static int vfio_dma_bitmap_alloc_all(struct vfio_iommu *iommu, size_t pgsize)
|
|
struct rb_node *p;
|
|
|
|
for (p = rb_prev(n); p; p = rb_prev(p)) {
|
|
- struct vfio_dma *dma = rb_entry(n,
|
|
+ struct vfio_dma *dma = rb_entry(p,
|
|
struct vfio_dma, node);
|
|
|
|
vfio_dma_bitmap_free(dma);
|
|
diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c
|
|
index 10129095a4c178..b19e5f73de8bb4 100644
|
|
--- a/drivers/video/backlight/qcom-wled.c
|
|
+++ b/drivers/video/backlight/qcom-wled.c
|
|
@@ -1406,9 +1406,11 @@ static int wled_configure(struct wled *wled)
|
|
wled->ctrl_addr = be32_to_cpu(*prop_addr);
|
|
|
|
rc = of_property_read_string(dev->of_node, "label", &wled->name);
|
|
- if (rc)
|
|
+ if (rc) {
|
|
wled->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFn", dev->of_node);
|
|
-
|
|
+ if (!wled->name)
|
|
+ return -ENOMEM;
|
|
+ }
|
|
switch (wled->version) {
|
|
case 3:
|
|
u32_opts = wled3_opts;
|
|
diff --git a/drivers/video/fbdev/core/fbcvt.c b/drivers/video/fbdev/core/fbcvt.c
|
|
index 64843464c66135..cd3821bd82e566 100644
|
|
--- a/drivers/video/fbdev/core/fbcvt.c
|
|
+++ b/drivers/video/fbdev/core/fbcvt.c
|
|
@@ -312,7 +312,7 @@ int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb)
|
|
cvt.f_refresh = cvt.refresh;
|
|
cvt.interlace = 1;
|
|
|
|
- if (!cvt.xres || !cvt.yres || !cvt.refresh) {
|
|
+ if (!cvt.xres || !cvt.yres || !cvt.refresh || cvt.f_refresh > INT_MAX) {
|
|
printk(KERN_INFO "fbcvt: Invalid input parameters\n");
|
|
return 1;
|
|
}
|
|
diff --git a/drivers/watchdog/exar_wdt.c b/drivers/watchdog/exar_wdt.c
|
|
index 7c61ff34327116..c2e3bb08df899a 100644
|
|
--- a/drivers/watchdog/exar_wdt.c
|
|
+++ b/drivers/watchdog/exar_wdt.c
|
|
@@ -221,7 +221,7 @@ static const struct watchdog_info exar_wdt_info = {
|
|
.options = WDIOF_KEEPALIVEPING |
|
|
WDIOF_SETTIMEOUT |
|
|
WDIOF_MAGICCLOSE,
|
|
- .identity = "Exar/MaxLinear XR28V38x Watchdog",
|
|
+ .identity = "Exar XR28V38x Watchdog",
|
|
};
|
|
|
|
static const struct watchdog_ops exar_wdt_ops = {
|
|
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
|
|
index b0b52fa8fba6da..204ec1bcbd526a 100644
|
|
--- a/drivers/xen/balloon.c
|
|
+++ b/drivers/xen/balloon.c
|
|
@@ -696,15 +696,18 @@ static int __init balloon_add_regions(void)
|
|
|
|
/*
|
|
* Extra regions are accounted for in the physmap, but need
|
|
- * decreasing from current_pages to balloon down the initial
|
|
- * allocation, because they are already accounted for in
|
|
- * total_pages.
|
|
+ * decreasing from current_pages and target_pages to balloon
|
|
+ * down the initial allocation, because they are already
|
|
+ * accounted for in total_pages.
|
|
*/
|
|
- if (extra_pfn_end - start_pfn >= balloon_stats.current_pages) {
|
|
+ pages = extra_pfn_end - start_pfn;
|
|
+ if (pages >= balloon_stats.current_pages ||
|
|
+ pages >= balloon_stats.target_pages) {
|
|
WARN(1, "Extra pages underflow current target");
|
|
return -ERANGE;
|
|
}
|
|
- balloon_stats.current_pages -= extra_pfn_end - start_pfn;
|
|
+ balloon_stats.current_pages -= pages;
|
|
+ balloon_stats.target_pages -= pages;
|
|
}
|
|
|
|
return 0;
|
|
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
|
|
index da49bdb70375b6..7632d652a1257d 100644
|
|
--- a/fs/btrfs/scrub.c
|
|
+++ b/fs/btrfs/scrub.c
|
|
@@ -153,12 +153,14 @@ struct scrub_stripe {
|
|
unsigned int init_nr_io_errors;
|
|
unsigned int init_nr_csum_errors;
|
|
unsigned int init_nr_meta_errors;
|
|
+ unsigned int init_nr_meta_gen_errors;
|
|
|
|
/*
|
|
* The following error bitmaps are all for the current status.
|
|
* Every time we submit a new read, these bitmaps may be updated.
|
|
*
|
|
- * error_bitmap = io_error_bitmap | csum_error_bitmap | meta_error_bitmap;
|
|
+ * error_bitmap = io_error_bitmap | csum_error_bitmap |
|
|
+ * meta_error_bitmap | meta_generation_bitmap;
|
|
*
|
|
* IO and csum errors can happen for both metadata and data.
|
|
*/
|
|
@@ -166,6 +168,7 @@ struct scrub_stripe {
|
|
unsigned long io_error_bitmap;
|
|
unsigned long csum_error_bitmap;
|
|
unsigned long meta_error_bitmap;
|
|
+ unsigned long meta_gen_error_bitmap;
|
|
|
|
/* For writeback (repair or replace) error reporting. */
|
|
unsigned long write_error_bitmap;
|
|
@@ -617,7 +620,7 @@ static void scrub_verify_one_metadata(struct scrub_stripe *stripe, int sector_nr
|
|
memcpy(on_disk_csum, header->csum, fs_info->csum_size);
|
|
|
|
if (logical != btrfs_stack_header_bytenr(header)) {
|
|
- bitmap_set(&stripe->csum_error_bitmap, sector_nr, sectors_per_tree);
|
|
+ bitmap_set(&stripe->meta_error_bitmap, sector_nr, sectors_per_tree);
|
|
bitmap_set(&stripe->error_bitmap, sector_nr, sectors_per_tree);
|
|
btrfs_warn_rl(fs_info,
|
|
"tree block %llu mirror %u has bad bytenr, has %llu want %llu",
|
|
@@ -673,7 +676,7 @@ static void scrub_verify_one_metadata(struct scrub_stripe *stripe, int sector_nr
|
|
}
|
|
if (stripe->sectors[sector_nr].generation !=
|
|
btrfs_stack_header_generation(header)) {
|
|
- bitmap_set(&stripe->meta_error_bitmap, sector_nr, sectors_per_tree);
|
|
+ bitmap_set(&stripe->meta_gen_error_bitmap, sector_nr, sectors_per_tree);
|
|
bitmap_set(&stripe->error_bitmap, sector_nr, sectors_per_tree);
|
|
btrfs_warn_rl(fs_info,
|
|
"tree block %llu mirror %u has bad generation, has %llu want %llu",
|
|
@@ -685,6 +688,7 @@ static void scrub_verify_one_metadata(struct scrub_stripe *stripe, int sector_nr
|
|
bitmap_clear(&stripe->error_bitmap, sector_nr, sectors_per_tree);
|
|
bitmap_clear(&stripe->csum_error_bitmap, sector_nr, sectors_per_tree);
|
|
bitmap_clear(&stripe->meta_error_bitmap, sector_nr, sectors_per_tree);
|
|
+ bitmap_clear(&stripe->meta_gen_error_bitmap, sector_nr, sectors_per_tree);
|
|
}
|
|
|
|
static void scrub_verify_one_sector(struct scrub_stripe *stripe, int sector_nr)
|
|
@@ -973,8 +977,22 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
|
|
if (__ratelimit(&rs) && dev)
|
|
scrub_print_common_warning("header error", dev, false,
|
|
stripe->logical, physical);
|
|
+ if (test_bit(sector_nr, &stripe->meta_gen_error_bitmap))
|
|
+ if (__ratelimit(&rs) && dev)
|
|
+ scrub_print_common_warning("generation error", dev, false,
|
|
+ stripe->logical, physical);
|
|
}
|
|
|
|
+ /* Update the device stats. */
|
|
+ for (int i = 0; i < stripe->init_nr_io_errors; i++)
|
|
+ btrfs_dev_stat_inc_and_print(stripe->dev, BTRFS_DEV_STAT_READ_ERRS);
|
|
+ for (int i = 0; i < stripe->init_nr_csum_errors; i++)
|
|
+ btrfs_dev_stat_inc_and_print(stripe->dev, BTRFS_DEV_STAT_CORRUPTION_ERRS);
|
|
+ /* Generation mismatch error is based on each metadata, not each block. */
|
|
+ for (int i = 0; i < stripe->init_nr_meta_gen_errors;
|
|
+ i += (fs_info->nodesize >> fs_info->sectorsize_bits))
|
|
+ btrfs_dev_stat_inc_and_print(stripe->dev, BTRFS_DEV_STAT_GENERATION_ERRS);
|
|
+
|
|
spin_lock(&sctx->stat_lock);
|
|
sctx->stat.data_extents_scrubbed += stripe->nr_data_extents;
|
|
sctx->stat.tree_extents_scrubbed += stripe->nr_meta_extents;
|
|
@@ -983,7 +1001,8 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
|
|
sctx->stat.no_csum += nr_nodatacsum_sectors;
|
|
sctx->stat.read_errors += stripe->init_nr_io_errors;
|
|
sctx->stat.csum_errors += stripe->init_nr_csum_errors;
|
|
- sctx->stat.verify_errors += stripe->init_nr_meta_errors;
|
|
+ sctx->stat.verify_errors += stripe->init_nr_meta_errors +
|
|
+ stripe->init_nr_meta_gen_errors;
|
|
sctx->stat.uncorrectable_errors +=
|
|
bitmap_weight(&stripe->error_bitmap, stripe->nr_sectors);
|
|
sctx->stat.corrected_errors += nr_repaired_sectors;
|
|
@@ -1029,6 +1048,8 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
|
|
stripe->nr_sectors);
|
|
stripe->init_nr_meta_errors = bitmap_weight(&stripe->meta_error_bitmap,
|
|
stripe->nr_sectors);
|
|
+ stripe->init_nr_meta_gen_errors = bitmap_weight(&stripe->meta_gen_error_bitmap,
|
|
+ stripe->nr_sectors);
|
|
|
|
if (bitmap_empty(&stripe->init_error_bitmap, stripe->nr_sectors))
|
|
goto out;
|
|
@@ -1143,6 +1164,9 @@ static void scrub_write_endio(struct btrfs_bio *bbio)
|
|
bitmap_set(&stripe->write_error_bitmap, sector_nr,
|
|
bio_size >> fs_info->sectorsize_bits);
|
|
spin_unlock_irqrestore(&stripe->write_error_lock, flags);
|
|
+ for (int i = 0; i < (bio_size >> fs_info->sectorsize_bits); i++)
|
|
+ btrfs_dev_stat_inc_and_print(stripe->dev,
|
|
+ BTRFS_DEV_STAT_WRITE_ERRS);
|
|
}
|
|
bio_put(&bbio->bio);
|
|
|
|
@@ -1505,10 +1529,12 @@ static void scrub_stripe_reset_bitmaps(struct scrub_stripe *stripe)
|
|
stripe->init_nr_io_errors = 0;
|
|
stripe->init_nr_csum_errors = 0;
|
|
stripe->init_nr_meta_errors = 0;
|
|
+ stripe->init_nr_meta_gen_errors = 0;
|
|
stripe->error_bitmap = 0;
|
|
stripe->io_error_bitmap = 0;
|
|
stripe->csum_error_bitmap = 0;
|
|
stripe->meta_error_bitmap = 0;
|
|
+ stripe->meta_gen_error_bitmap = 0;
|
|
}
|
|
|
|
/*
|
|
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
|
|
index acd0764b0286c8..a123bb26acd8bd 100644
|
|
--- a/fs/f2fs/data.c
|
|
+++ b/fs/f2fs/data.c
|
|
@@ -54,8 +54,8 @@ bool f2fs_is_cp_guaranteed(struct page *page)
|
|
struct inode *inode;
|
|
struct f2fs_sb_info *sbi;
|
|
|
|
- if (!mapping)
|
|
- return false;
|
|
+ if (fscrypt_is_bounce_page(page))
|
|
+ return page_private_gcing(fscrypt_pagecache_page(page));
|
|
|
|
inode = mapping->host;
|
|
sbi = F2FS_I_SB(inode);
|
|
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
|
|
index 5f6f159be456ea..911c4c64d729d3 100644
|
|
--- a/fs/f2fs/f2fs.h
|
|
+++ b/fs/f2fs/f2fs.h
|
|
@@ -2474,8 +2474,14 @@ static inline void dec_valid_block_count(struct f2fs_sb_info *sbi,
|
|
blkcnt_t sectors = count << F2FS_LOG_SECTORS_PER_BLOCK;
|
|
|
|
spin_lock(&sbi->stat_lock);
|
|
- f2fs_bug_on(sbi, sbi->total_valid_block_count < (block_t) count);
|
|
- sbi->total_valid_block_count -= (block_t)count;
|
|
+ if (unlikely(sbi->total_valid_block_count < count)) {
|
|
+ f2fs_warn(sbi, "Inconsistent total_valid_block_count:%u, ino:%lu, count:%u",
|
|
+ sbi->total_valid_block_count, inode->i_ino, count);
|
|
+ sbi->total_valid_block_count = 0;
|
|
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
|
|
+ } else {
|
|
+ sbi->total_valid_block_count -= count;
|
|
+ }
|
|
if (sbi->reserved_blocks &&
|
|
sbi->current_reserved_blocks < sbi->reserved_blocks)
|
|
sbi->current_reserved_blocks = min(sbi->reserved_blocks,
|
|
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
|
|
index 2e08e1fdf485c7..4d6f0a6365fe19 100644
|
|
--- a/fs/f2fs/namei.c
|
|
+++ b/fs/f2fs/namei.c
|
|
@@ -411,7 +411,7 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
|
|
|
|
if (is_inode_flag_set(dir, FI_PROJ_INHERIT) &&
|
|
(!projid_eq(F2FS_I(dir)->i_projid,
|
|
- F2FS_I(old_dentry->d_inode)->i_projid)))
|
|
+ F2FS_I(inode)->i_projid)))
|
|
return -EXDEV;
|
|
|
|
err = f2fs_dquot_initialize(dir);
|
|
@@ -905,7 +905,7 @@ static int f2fs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
|
|
|
|
if (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
|
|
(!projid_eq(F2FS_I(new_dir)->i_projid,
|
|
- F2FS_I(old_dentry->d_inode)->i_projid)))
|
|
+ F2FS_I(old_inode)->i_projid)))
|
|
return -EXDEV;
|
|
|
|
/*
|
|
@@ -1101,10 +1101,10 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|
|
|
if ((is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
|
|
!projid_eq(F2FS_I(new_dir)->i_projid,
|
|
- F2FS_I(old_dentry->d_inode)->i_projid)) ||
|
|
- (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
|
|
+ F2FS_I(old_inode)->i_projid)) ||
|
|
+ (is_inode_flag_set(old_dir, FI_PROJ_INHERIT) &&
|
|
!projid_eq(F2FS_I(old_dir)->i_projid,
|
|
- F2FS_I(new_dentry->d_inode)->i_projid)))
|
|
+ F2FS_I(new_inode)->i_projid)))
|
|
return -EXDEV;
|
|
|
|
err = f2fs_dquot_initialize(old_dir);
|
|
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
|
|
index 4cc87921aac3ed..6b3cafbe98672e 100644
|
|
--- a/fs/f2fs/super.c
|
|
+++ b/fs/f2fs/super.c
|
|
@@ -1849,9 +1849,9 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
|
buf->f_fsid = u64_to_fsid(id);
|
|
|
|
#ifdef CONFIG_QUOTA
|
|
- if (is_inode_flag_set(dentry->d_inode, FI_PROJ_INHERIT) &&
|
|
+ if (is_inode_flag_set(d_inode(dentry), FI_PROJ_INHERIT) &&
|
|
sb_has_quota_limits_enabled(sb, PRJQUOTA)) {
|
|
- f2fs_statfs_project(sb, F2FS_I(dentry->d_inode)->i_projid, buf);
|
|
+ f2fs_statfs_project(sb, F2FS_I(d_inode(dentry))->i_projid, buf);
|
|
}
|
|
#endif
|
|
return 0;
|
|
diff --git a/fs/filesystems.c b/fs/filesystems.c
|
|
index 58b9067b2391ce..95e5256821a534 100644
|
|
--- a/fs/filesystems.c
|
|
+++ b/fs/filesystems.c
|
|
@@ -156,15 +156,19 @@ static int fs_index(const char __user * __name)
|
|
static int fs_name(unsigned int index, char __user * buf)
|
|
{
|
|
struct file_system_type * tmp;
|
|
- int len, res;
|
|
+ int len, res = -EINVAL;
|
|
|
|
read_lock(&file_systems_lock);
|
|
- for (tmp = file_systems; tmp; tmp = tmp->next, index--)
|
|
- if (index <= 0 && try_module_get(tmp->owner))
|
|
+ for (tmp = file_systems; tmp; tmp = tmp->next, index--) {
|
|
+ if (index == 0) {
|
|
+ if (try_module_get(tmp->owner))
|
|
+ res = 0;
|
|
break;
|
|
+ }
|
|
+ }
|
|
read_unlock(&file_systems_lock);
|
|
- if (!tmp)
|
|
- return -EINVAL;
|
|
+ if (res)
|
|
+ return res;
|
|
|
|
/* OK, we got the reference, so we can safely block */
|
|
len = strlen(tmp->name) + 1;
|
|
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
|
|
index 29085643ad104e..1cb5ce63fbf697 100644
|
|
--- a/fs/gfs2/inode.c
|
|
+++ b/fs/gfs2/inode.c
|
|
@@ -658,7 +658,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
|
|
if (!IS_ERR(inode)) {
|
|
if (S_ISDIR(inode->i_mode)) {
|
|
iput(inode);
|
|
- inode = ERR_PTR(-EISDIR);
|
|
+ inode = NULL;
|
|
+ error = -EISDIR;
|
|
goto fail_gunlock;
|
|
}
|
|
d_instantiate(dentry, inode);
|
|
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
|
|
index b068ed32d7b32d..f6e2a4523f7e66 100644
|
|
--- a/fs/kernfs/dir.c
|
|
+++ b/fs/kernfs/dir.c
|
|
@@ -1560,8 +1560,9 @@ void kernfs_break_active_protection(struct kernfs_node *kn)
|
|
* invoked before finishing the kernfs operation. Note that while this
|
|
* function restores the active reference, it doesn't and can't actually
|
|
* restore the active protection - @kn may already or be in the process of
|
|
- * being removed. Once kernfs_break_active_protection() is invoked, that
|
|
- * protection is irreversibly gone for the kernfs operation instance.
|
|
+ * being drained and removed. Once kernfs_break_active_protection() is
|
|
+ * invoked, that protection is irreversibly gone for the kernfs operation
|
|
+ * instance.
|
|
*
|
|
* While this function may be called at any point after
|
|
* kernfs_break_active_protection() is invoked, its most useful location
|
|
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
|
|
index 332d08d2fe0d56..6b90fea6cca209 100644
|
|
--- a/fs/kernfs/file.c
|
|
+++ b/fs/kernfs/file.c
|
|
@@ -820,8 +820,9 @@ bool kernfs_should_drain_open_files(struct kernfs_node *kn)
|
|
/*
|
|
* @kn being deactivated guarantees that @kn->attr.open can't change
|
|
* beneath us making the lockless test below safe.
|
|
+ * Callers post kernfs_unbreak_active_protection may be counted in
|
|
+ * kn->active by now, do not WARN_ON because of them.
|
|
*/
|
|
- WARN_ON_ONCE(atomic_read(&kn->active) != KN_DEACTIVATED_BIAS);
|
|
|
|
rcu_read_lock();
|
|
on = rcu_dereference(kn->attr.open);
|
|
diff --git a/fs/namespace.c b/fs/namespace.c
|
|
index ef3b2ae2957ec3..eab9185e228584 100644
|
|
--- a/fs/namespace.c
|
|
+++ b/fs/namespace.c
|
|
@@ -2557,6 +2557,10 @@ static int do_change_type(struct path *path, int ms_flags)
|
|
return -EINVAL;
|
|
|
|
namespace_lock();
|
|
+ if (!check_mnt(mnt)) {
|
|
+ err = -EINVAL;
|
|
+ goto out_unlock;
|
|
+ }
|
|
if (type == MS_SHARED) {
|
|
err = invent_group_ids(mnt, recurse);
|
|
if (err)
|
|
@@ -2995,7 +2999,7 @@ static int do_set_group(struct path *from_path, struct path *to_path)
|
|
if (IS_MNT_SLAVE(from)) {
|
|
struct mount *m = from->mnt_master;
|
|
|
|
- list_add(&to->mnt_slave, &m->mnt_slave_list);
|
|
+ list_add(&to->mnt_slave, &from->mnt_slave);
|
|
to->mnt_master = m;
|
|
}
|
|
|
|
@@ -3020,18 +3024,25 @@ static int do_set_group(struct path *from_path, struct path *to_path)
|
|
* Check if path is overmounted, i.e., if there's a mount on top of
|
|
* @path->mnt with @path->dentry as mountpoint.
|
|
*
|
|
- * Context: This function expects namespace_lock() to be held.
|
|
+ * Context: namespace_sem must be held at least shared.
|
|
+ * MUST NOT be called under lock_mount_hash() (there one should just
|
|
+ * call __lookup_mnt() and check if it returns NULL).
|
|
* Return: If path is overmounted true is returned, false if not.
|
|
*/
|
|
static inline bool path_overmounted(const struct path *path)
|
|
{
|
|
+ unsigned seq = read_seqbegin(&mount_lock);
|
|
+ bool no_child;
|
|
+
|
|
rcu_read_lock();
|
|
- if (unlikely(__lookup_mnt(path->mnt, path->dentry))) {
|
|
- rcu_read_unlock();
|
|
- return true;
|
|
- }
|
|
+ no_child = !__lookup_mnt(path->mnt, path->dentry);
|
|
rcu_read_unlock();
|
|
- return false;
|
|
+ if (need_seqretry(&mount_lock, seq)) {
|
|
+ read_seqlock_excl(&mount_lock);
|
|
+ no_child = !__lookup_mnt(path->mnt, path->dentry);
|
|
+ read_sequnlock_excl(&mount_lock);
|
|
+ }
|
|
+ return unlikely(!no_child);
|
|
}
|
|
|
|
/**
|
|
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
|
|
index e1bcad5906ae7b..4e72ee57fc8fc2 100644
|
|
--- a/fs/nfs/super.c
|
|
+++ b/fs/nfs/super.c
|
|
@@ -1020,6 +1020,16 @@ int nfs_reconfigure(struct fs_context *fc)
|
|
|
|
sync_filesystem(sb);
|
|
|
|
+ /*
|
|
+ * The SB_RDONLY flag has been removed from the superblock during
|
|
+ * mounts to prevent interference between different filesystems.
|
|
+ * Similarly, it is also necessary to ignore the SB_RDONLY flag
|
|
+ * during reconfiguration; otherwise, it may also result in the
|
|
+ * creation of redundant superblocks when mounting a directory with
|
|
+ * different rw and ro flags multiple times.
|
|
+ */
|
|
+ fc->sb_flags_mask &= ~SB_RDONLY;
|
|
+
|
|
/*
|
|
* Userspace mount programs that send binary options generally send
|
|
* them populated with default values. We have no way to know which
|
|
@@ -1277,8 +1287,17 @@ int nfs_get_tree_common(struct fs_context *fc)
|
|
if (IS_ERR(server))
|
|
return PTR_ERR(server);
|
|
|
|
+ /*
|
|
+ * When NFS_MOUNT_UNSHARED is not set, NFS forces the sharing of a
|
|
+ * superblock among each filesystem that mounts sub-directories
|
|
+ * belonging to a single exported root path.
|
|
+ * To prevent interference between different filesystems, the
|
|
+ * SB_RDONLY flag should be removed from the superblock.
|
|
+ */
|
|
if (server->flags & NFS_MOUNT_UNSHARED)
|
|
compare_super = NULL;
|
|
+ else
|
|
+ fc->sb_flags &= ~SB_RDONLY;
|
|
|
|
/* -o noac implies -o sync */
|
|
if (server->flags & NFS_MOUNT_NOAC)
|
|
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
|
|
index dbd27a44632fa9..5e70a3478afe09 100644
|
|
--- a/fs/nilfs2/btree.c
|
|
+++ b/fs/nilfs2/btree.c
|
|
@@ -2094,11 +2094,13 @@ static int nilfs_btree_propagate(struct nilfs_bmap *btree,
|
|
|
|
ret = nilfs_btree_do_lookup(btree, path, key, NULL, level + 1, 0);
|
|
if (ret < 0) {
|
|
- if (unlikely(ret == -ENOENT))
|
|
+ if (unlikely(ret == -ENOENT)) {
|
|
nilfs_crit(btree->b_inode->i_sb,
|
|
"writing node/leaf block does not appear in b-tree (ino=%lu) at key=%llu, level=%d",
|
|
btree->b_inode->i_ino,
|
|
(unsigned long long)key, level);
|
|
+ ret = -EINVAL;
|
|
+ }
|
|
goto out;
|
|
}
|
|
|
|
diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c
|
|
index 893ab36824cc2b..2d8dc6b35b5477 100644
|
|
--- a/fs/nilfs2/direct.c
|
|
+++ b/fs/nilfs2/direct.c
|
|
@@ -273,6 +273,9 @@ static int nilfs_direct_propagate(struct nilfs_bmap *bmap,
|
|
dat = nilfs_bmap_get_dat(bmap);
|
|
key = nilfs_bmap_data_get_key(bmap, bh);
|
|
ptr = nilfs_direct_get_ptr(bmap, key);
|
|
+ if (ptr == NILFS_BMAP_INVALID_PTR)
|
|
+ return -EINVAL;
|
|
+
|
|
if (!buffer_nilfs_volatile(bh)) {
|
|
oldreq.pr_entry_nr = ptr;
|
|
newreq.pr_entry_nr = ptr;
|
|
diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c
|
|
index 28aae6ea1e615e..191b91ffadbb21 100644
|
|
--- a/fs/ntfs3/index.c
|
|
+++ b/fs/ntfs3/index.c
|
|
@@ -2184,6 +2184,10 @@ static int indx_get_entry_to_replace(struct ntfs_index *indx,
|
|
|
|
e = hdr_first_de(&n->index->ihdr);
|
|
fnd_push(fnd, n, e);
|
|
+ if (!e) {
|
|
+ err = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
|
|
if (!de_is_last(e)) {
|
|
/*
|
|
@@ -2205,6 +2209,10 @@ static int indx_get_entry_to_replace(struct ntfs_index *indx,
|
|
|
|
n = fnd->nodes[level];
|
|
te = hdr_first_de(&n->index->ihdr);
|
|
+ if (!te) {
|
|
+ err = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
/* Copy the candidate entry into the replacement entry buffer. */
|
|
re = kmalloc(le16_to_cpu(te->size) + sizeof(u64), GFP_NOFS);
|
|
if (!re) {
|
|
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
|
|
index 0ca8975a1df479..c7bda48b5fb21c 100644
|
|
--- a/fs/ocfs2/quota_local.c
|
|
+++ b/fs/ocfs2/quota_local.c
|
|
@@ -671,7 +671,7 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
|
|
break;
|
|
}
|
|
out:
|
|
- kfree(rec);
|
|
+ ocfs2_free_quota_recovery(rec);
|
|
return status;
|
|
}
|
|
|
|
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
|
|
index b91184ebce02c5..c36ab20050c16d 100644
|
|
--- a/fs/smb/client/cifssmb.c
|
|
+++ b/fs/smb/client/cifssmb.c
|
|
@@ -2738,10 +2738,10 @@ int cifs_query_reparse_point(const unsigned int xid,
|
|
|
|
io_req->TotalParameterCount = 0;
|
|
io_req->TotalDataCount = 0;
|
|
- io_req->MaxParameterCount = cpu_to_le32(2);
|
|
+ io_req->MaxParameterCount = cpu_to_le32(0);
|
|
/* BB find exact data count max from sess structure BB */
|
|
io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
|
|
- io_req->MaxSetupCount = 4;
|
|
+ io_req->MaxSetupCount = 1;
|
|
io_req->Reserved = 0;
|
|
io_req->ParameterOffset = 0;
|
|
io_req->DataCount = 0;
|
|
@@ -2768,6 +2768,22 @@ int cifs_query_reparse_point(const unsigned int xid,
|
|
goto error;
|
|
}
|
|
|
|
+ /* SetupCount must be 1, otherwise offset to ByteCount is incorrect. */
|
|
+ if (io_rsp->SetupCount != 1) {
|
|
+ rc = -EIO;
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * ReturnedDataLen is output length of executed IOCTL.
|
|
+ * DataCount is output length transferred over network.
|
|
+ * Check that we have full FSCTL_GET_REPARSE_POINT buffer.
|
|
+ */
|
|
+ if (data_count != le16_to_cpu(io_rsp->ReturnedDataLen)) {
|
|
+ rc = -EIO;
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
|
|
start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
|
|
if (start >= end) {
|
|
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
|
|
index 22e812808e5cf9..3a27d4268b3c4a 100644
|
|
--- a/fs/squashfs/super.c
|
|
+++ b/fs/squashfs/super.c
|
|
@@ -202,6 +202,11 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc)
|
|
msblk->panic_on_errors = (opts->errors == Opt_errors_panic);
|
|
|
|
msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE);
|
|
+ if (!msblk->devblksize) {
|
|
+ errorf(fc, "squashfs: unable to set blocksize\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
msblk->devblksize_log2 = ffz(~msblk->devblksize);
|
|
|
|
mutex_init(&msblk->meta_index_mutex);
|
|
diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h
|
|
index 255701e1251b4a..f652a5028b5907 100644
|
|
--- a/include/linux/arm_sdei.h
|
|
+++ b/include/linux/arm_sdei.h
|
|
@@ -46,12 +46,12 @@ int sdei_unregister_ghes(struct ghes *ghes);
|
|
/* For use by arch code when CPU hotplug notifiers are not appropriate. */
|
|
int sdei_mask_local_cpu(void);
|
|
int sdei_unmask_local_cpu(void);
|
|
-void __init sdei_init(void);
|
|
+void __init acpi_sdei_init(void);
|
|
void sdei_handler_abort(void);
|
|
#else
|
|
static inline int sdei_mask_local_cpu(void) { return 0; }
|
|
static inline int sdei_unmask_local_cpu(void) { return 0; }
|
|
-static inline void sdei_init(void) { }
|
|
+static inline void acpi_sdei_init(void) { }
|
|
static inline void sdei_handler_abort(void) { }
|
|
#endif /* CONFIG_ARM_SDE_INTERFACE */
|
|
|
|
diff --git a/include/linux/bio.h b/include/linux/bio.h
|
|
index b893418c3cc022..f193aef4fac08d 100644
|
|
--- a/include/linux/bio.h
|
|
+++ b/include/linux/bio.h
|
|
@@ -294,7 +294,7 @@ static inline void bio_first_folio(struct folio_iter *fi, struct bio *bio,
|
|
|
|
fi->folio = page_folio(bvec->bv_page);
|
|
fi->offset = bvec->bv_offset +
|
|
- PAGE_SIZE * (bvec->bv_page - &fi->folio->page);
|
|
+ PAGE_SIZE * folio_page_idx(fi->folio, bvec->bv_page);
|
|
fi->_seg_count = bvec->bv_len;
|
|
fi->length = min(folio_size(fi->folio) - fi->offset, fi->_seg_count);
|
|
fi->_next = folio_next(fi->folio);
|
|
diff --git a/include/linux/bvec.h b/include/linux/bvec.h
|
|
index bd1e361b351c5a..99ab7b2bba27cd 100644
|
|
--- a/include/linux/bvec.h
|
|
+++ b/include/linux/bvec.h
|
|
@@ -57,9 +57,12 @@ static inline void bvec_set_page(struct bio_vec *bv, struct page *page,
|
|
* @offset: offset into the folio
|
|
*/
|
|
static inline void bvec_set_folio(struct bio_vec *bv, struct folio *folio,
|
|
- unsigned int len, unsigned int offset)
|
|
+ size_t len, size_t offset)
|
|
{
|
|
- bvec_set_page(bv, &folio->page, len, offset);
|
|
+ unsigned long nr = offset / PAGE_SIZE;
|
|
+
|
|
+ WARN_ON_ONCE(len > UINT_MAX);
|
|
+ bvec_set_page(bv, folio_page(folio, nr), len, offset % PAGE_SIZE);
|
|
}
|
|
|
|
/**
|
|
diff --git a/include/linux/hid.h b/include/linux/hid.h
|
|
index 38e161a827bde9..5d37e2349fae81 100644
|
|
--- a/include/linux/hid.h
|
|
+++ b/include/linux/hid.h
|
|
@@ -736,8 +736,9 @@ struct hid_descriptor {
|
|
__le16 bcdHID;
|
|
__u8 bCountryCode;
|
|
__u8 bNumDescriptors;
|
|
+ struct hid_class_descriptor rpt_desc;
|
|
|
|
- struct hid_class_descriptor desc[1];
|
|
+ struct hid_class_descriptor opt_descs[];
|
|
} __attribute__ ((packed));
|
|
|
|
#define HID_DEVICE(b, g, ven, prod) \
|
|
diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h
|
|
index 0fadef2983e01b..dad2f9e4d53d66 100644
|
|
--- a/include/linux/io_uring_types.h
|
|
+++ b/include/linux/io_uring_types.h
|
|
@@ -416,6 +416,7 @@ enum {
|
|
/* keep async read/write and isreg together and in order */
|
|
REQ_F_SUPPORT_NOWAIT_BIT,
|
|
REQ_F_ISREG_BIT,
|
|
+ REQ_F_CAN_POLL_BIT,
|
|
|
|
/* not a real bit, just to check we're not overflowing the space */
|
|
__REQ_F_LAST_BIT,
|
|
@@ -483,6 +484,8 @@ enum {
|
|
REQ_F_CLEAR_POLLIN = BIT(REQ_F_CLEAR_POLLIN_BIT),
|
|
/* hashed into ->cancel_hash_locked, protected by ->uring_lock */
|
|
REQ_F_HASH_LOCKED = BIT(REQ_F_HASH_LOCKED_BIT),
|
|
+ /* file is pollable */
|
|
+ REQ_F_CAN_POLL = BIT(REQ_F_CAN_POLL_BIT),
|
|
};
|
|
|
|
typedef void (*io_req_tw_func_t)(struct io_kiocb *req, struct io_tw_state *ts);
|
|
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
|
|
index 8fa23bdcedbf98..0bca1a960853f4 100644
|
|
--- a/include/linux/mdio.h
|
|
+++ b/include/linux/mdio.h
|
|
@@ -44,10 +44,7 @@ struct mdio_device {
|
|
unsigned int reset_deassert_delay;
|
|
};
|
|
|
|
-static inline struct mdio_device *to_mdio_device(const struct device *dev)
|
|
-{
|
|
- return container_of(dev, struct mdio_device, dev);
|
|
-}
|
|
+#define to_mdio_device(__dev) container_of_const(__dev, struct mdio_device, dev)
|
|
|
|
/* struct mdio_driver_common: Common to all MDIO drivers */
|
|
struct mdio_driver_common {
|
|
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
|
|
index 69d844b34da0d3..696a2227869fb3 100644
|
|
--- a/include/linux/mlx5/driver.h
|
|
+++ b/include/linux/mlx5/driver.h
|
|
@@ -390,6 +390,7 @@ struct mlx5_core_rsc_common {
|
|
enum mlx5_res_type res;
|
|
refcount_t refcount;
|
|
struct completion free;
|
|
+ bool invalid;
|
|
};
|
|
|
|
struct mlx5_uars_page {
|
|
diff --git a/include/linux/phy.h b/include/linux/phy.h
|
|
index 5aa30ee9981047..a57e799b1de185 100644
|
|
--- a/include/linux/phy.h
|
|
+++ b/include/linux/phy.h
|
|
@@ -766,10 +766,7 @@ struct phy_device {
|
|
/* Generic phy_device::dev_flags */
|
|
#define PHY_F_NO_IRQ 0x80000000
|
|
|
|
-static inline struct phy_device *to_phy_device(const struct device *dev)
|
|
-{
|
|
- return container_of(to_mdio_device(dev), struct phy_device, mdio);
|
|
-}
|
|
+#define to_phy_device(__dev) container_of_const(to_mdio_device(__dev), struct phy_device, mdio)
|
|
|
|
/**
|
|
* struct phy_tdr_config - Configuration of a TDR raw test
|
|
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
|
|
index e9214ccfde2d72..d63af08c6cdc2b 100644
|
|
--- a/include/net/bluetooth/hci_core.h
|
|
+++ b/include/net/bluetooth/hci_core.h
|
|
@@ -542,6 +542,7 @@ struct hci_dev {
|
|
struct hci_conn_hash conn_hash;
|
|
|
|
struct list_head mesh_pending;
|
|
+ struct mutex mgmt_pending_lock;
|
|
struct list_head mgmt_pending;
|
|
struct list_head reject_list;
|
|
struct list_head accept_list;
|
|
@@ -2305,7 +2306,6 @@ void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev,
|
|
u8 instance);
|
|
void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev,
|
|
u8 instance);
|
|
-void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle);
|
|
int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip);
|
|
void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle,
|
|
bdaddr_t *bdaddr, u8 addr_type);
|
|
diff --git a/include/net/sock.h b/include/net/sock.h
|
|
index dc625f94ee37b7..e15bea43b2ecd1 100644
|
|
--- a/include/net/sock.h
|
|
+++ b/include/net/sock.h
|
|
@@ -3043,8 +3043,11 @@ int sock_ioctl_inout(struct sock *sk, unsigned int cmd,
|
|
int sk_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
|
|
static inline bool sk_is_readable(struct sock *sk)
|
|
{
|
|
- if (sk->sk_prot->sock_is_readable)
|
|
- return sk->sk_prot->sock_is_readable(sk);
|
|
+ const struct proto *prot = READ_ONCE(sk->sk_prot);
|
|
+
|
|
+ if (prot->sock_is_readable)
|
|
+ return prot->sock_is_readable(sk);
|
|
+
|
|
return false;
|
|
}
|
|
#endif /* _SOCK_H */
|
|
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
|
|
index 43b46098279a16..ff1a93d405e99e 100644
|
|
--- a/io_uring/io_uring.c
|
|
+++ b/io_uring/io_uring.c
|
|
@@ -920,14 +920,6 @@ static bool __io_post_aux_cqe(struct io_ring_ctx *ctx, u64 user_data, s32 res, u
|
|
{
|
|
bool filled;
|
|
|
|
- /*
|
|
- * If multishot has already posted deferred completions, ensure that
|
|
- * those are flushed first before posting this one. If not, CQEs
|
|
- * could get reordered.
|
|
- */
|
|
- if (!wq_list_empty(&ctx->submit_state.compl_reqs))
|
|
- __io_submit_flush_completions(ctx);
|
|
-
|
|
io_cq_lock(ctx);
|
|
filled = io_fill_cqe_aux(ctx, user_data, res, cflags);
|
|
if (!filled && allow_overflow)
|
|
@@ -1953,7 +1945,7 @@ void io_wq_submit_work(struct io_wq_work *work)
|
|
if (req->flags & REQ_F_FORCE_ASYNC) {
|
|
bool opcode_poll = def->pollin || def->pollout;
|
|
|
|
- if (opcode_poll && file_can_poll(req->file)) {
|
|
+ if (opcode_poll && io_file_can_poll(req)) {
|
|
needs_poll = true;
|
|
issue_flags |= IO_URING_F_NONBLOCK;
|
|
}
|
|
diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
|
|
index 0ffec66deee7f1..59f5f71037ffe1 100644
|
|
--- a/io_uring/io_uring.h
|
|
+++ b/io_uring/io_uring.h
|
|
@@ -5,6 +5,7 @@
|
|
#include <linux/lockdep.h>
|
|
#include <linux/resume_user_mode.h>
|
|
#include <linux/kasan.h>
|
|
+#include <linux/poll.h>
|
|
#include <linux/io_uring_types.h>
|
|
#include <uapi/linux/eventpoll.h>
|
|
#include "io-wq.h"
|
|
@@ -410,4 +411,15 @@ static inline size_t uring_sqe_size(struct io_ring_ctx *ctx)
|
|
return 2 * sizeof(struct io_uring_sqe);
|
|
return sizeof(struct io_uring_sqe);
|
|
}
|
|
+
|
|
+static inline bool io_file_can_poll(struct io_kiocb *req)
|
|
+{
|
|
+ if (req->flags & REQ_F_CAN_POLL)
|
|
+ return true;
|
|
+ if (file_can_poll(req->file)) {
|
|
+ req->flags |= REQ_F_CAN_POLL;
|
|
+ return true;
|
|
+ }
|
|
+ return false;
|
|
+}
|
|
#endif
|
|
diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c
|
|
index 8c6611fe4f4633..addd7c97365727 100644
|
|
--- a/io_uring/kbuf.c
|
|
+++ b/io_uring/kbuf.c
|
|
@@ -148,8 +148,7 @@ static void __user *io_ring_buffer_select(struct io_kiocb *req, size_t *len,
|
|
req->buf_list = bl;
|
|
req->buf_index = buf->bid;
|
|
|
|
- if (issue_flags & IO_URING_F_UNLOCKED ||
|
|
- (req->file && !file_can_poll(req->file))) {
|
|
+ if (issue_flags & IO_URING_F_UNLOCKED || !io_file_can_poll(req)) {
|
|
/*
|
|
* If we came in unlocked, we have no choice but to consume the
|
|
* buffer here, otherwise nothing ensures that the buffer won't
|
|
diff --git a/io_uring/poll.c b/io_uring/poll.c
|
|
index cf8e86bc96deb5..2390bf5f1710b4 100644
|
|
--- a/io_uring/poll.c
|
|
+++ b/io_uring/poll.c
|
|
@@ -717,7 +717,7 @@ int io_arm_poll_handler(struct io_kiocb *req, unsigned issue_flags)
|
|
|
|
if (!def->pollin && !def->pollout)
|
|
return IO_APOLL_ABORTED;
|
|
- if (!file_can_poll(req->file))
|
|
+ if (!io_file_can_poll(req))
|
|
return IO_APOLL_ABORTED;
|
|
if (!(req->flags & REQ_F_APOLL_MULTISHOT))
|
|
mask |= EPOLLONESHOT;
|
|
diff --git a/io_uring/rw.c b/io_uring/rw.c
|
|
index 75b001febb4d28..4ff3442ac2eeea 100644
|
|
--- a/io_uring/rw.c
|
|
+++ b/io_uring/rw.c
|
|
@@ -28,9 +28,19 @@ struct io_rw {
|
|
rwf_t flags;
|
|
};
|
|
|
|
-static inline bool io_file_supports_nowait(struct io_kiocb *req)
|
|
+static bool io_file_supports_nowait(struct io_kiocb *req, __poll_t mask)
|
|
{
|
|
- return req->flags & REQ_F_SUPPORT_NOWAIT;
|
|
+ /* If FMODE_NOWAIT is set for a file, we're golden */
|
|
+ if (req->flags & REQ_F_SUPPORT_NOWAIT)
|
|
+ return true;
|
|
+ /* No FMODE_NOWAIT, if we can poll, check the status */
|
|
+ if (io_file_can_poll(req)) {
|
|
+ struct poll_table_struct pt = { ._key = mask };
|
|
+
|
|
+ return vfs_poll(req->file, &pt) & mask;
|
|
+ }
|
|
+ /* No FMODE_NOWAIT support, and file isn't pollable. Tough luck. */
|
|
+ return false;
|
|
}
|
|
|
|
#ifdef CONFIG_COMPAT
|
|
@@ -629,7 +639,7 @@ static bool io_rw_should_retry(struct io_kiocb *req)
|
|
* just use poll if we can, and don't attempt if the fs doesn't
|
|
* support callback based unlocks
|
|
*/
|
|
- if (file_can_poll(req->file) || !(req->file->f_mode & FMODE_BUF_RASYNC))
|
|
+ if (io_file_can_poll(req) || !(req->file->f_mode & FMODE_BUF_RASYNC))
|
|
return false;
|
|
|
|
wait->wait.func = io_async_buf_func;
|
|
@@ -685,8 +695,8 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode)
|
|
* supports async. Otherwise it's impossible to use O_NONBLOCK files
|
|
* reliably. If not, or it IOCB_NOWAIT is set, don't retry.
|
|
*/
|
|
- if ((kiocb->ki_flags & IOCB_NOWAIT) ||
|
|
- ((file->f_flags & O_NONBLOCK) && !io_file_supports_nowait(req)))
|
|
+ if (kiocb->ki_flags & IOCB_NOWAIT ||
|
|
+ ((file->f_flags & O_NONBLOCK && !(req->flags & REQ_F_SUPPORT_NOWAIT))))
|
|
req->flags |= REQ_F_NOWAIT;
|
|
|
|
if (ctx->flags & IORING_SETUP_IOPOLL) {
|
|
@@ -752,7 +762,7 @@ static int __io_read(struct io_kiocb *req, unsigned int issue_flags)
|
|
|
|
if (force_nonblock) {
|
|
/* If the file doesn't support async, just async punt */
|
|
- if (unlikely(!io_file_supports_nowait(req))) {
|
|
+ if (unlikely(!io_file_supports_nowait(req, EPOLLIN))) {
|
|
ret = io_setup_async_rw(req, iovec, s, true);
|
|
return ret ?: -EAGAIN;
|
|
}
|
|
@@ -783,7 +793,7 @@ static int __io_read(struct io_kiocb *req, unsigned int issue_flags)
|
|
if (ret == -EAGAIN || (req->flags & REQ_F_REISSUE)) {
|
|
req->flags &= ~REQ_F_REISSUE;
|
|
/* if we can poll, just do that */
|
|
- if (req->opcode == IORING_OP_READ && file_can_poll(req->file))
|
|
+ if (req->opcode == IORING_OP_READ && io_file_can_poll(req))
|
|
return -EAGAIN;
|
|
/* IOPOLL retry should happen for io-wq threads */
|
|
if (!force_nonblock && !(req->ctx->flags & IORING_SETUP_IOPOLL))
|
|
@@ -927,7 +937,7 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags)
|
|
|
|
if (force_nonblock) {
|
|
/* If the file doesn't support async, just async punt */
|
|
- if (unlikely(!io_file_supports_nowait(req)))
|
|
+ if (unlikely(!io_file_supports_nowait(req, EPOLLOUT)))
|
|
goto copy_iov;
|
|
|
|
/* File path supports NOWAIT for non-direct_IO only for block devices. */
|
|
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
|
|
index 81fd1bb9941644..5eaaf95048abc1 100644
|
|
--- a/kernel/bpf/core.c
|
|
+++ b/kernel/bpf/core.c
|
|
@@ -2258,8 +2258,8 @@ static unsigned int __bpf_prog_ret0_warn(const void *ctx,
|
|
}
|
|
#endif
|
|
|
|
-bool bpf_prog_map_compatible(struct bpf_map *map,
|
|
- const struct bpf_prog *fp)
|
|
+static bool __bpf_prog_map_compatible(struct bpf_map *map,
|
|
+ const struct bpf_prog *fp)
|
|
{
|
|
enum bpf_prog_type prog_type = resolve_prog_type(fp);
|
|
bool ret;
|
|
@@ -2268,14 +2268,6 @@ bool bpf_prog_map_compatible(struct bpf_map *map,
|
|
if (fp->kprobe_override)
|
|
return false;
|
|
|
|
- /* XDP programs inserted into maps are not guaranteed to run on
|
|
- * a particular netdev (and can run outside driver context entirely
|
|
- * in the case of devmap and cpumap). Until device checks
|
|
- * are implemented, prohibit adding dev-bound programs to program maps.
|
|
- */
|
|
- if (bpf_prog_is_dev_bound(aux))
|
|
- return false;
|
|
-
|
|
spin_lock(&map->owner.lock);
|
|
if (!map->owner.type) {
|
|
/* There's no owner yet where we could check for
|
|
@@ -2309,6 +2301,19 @@ bool bpf_prog_map_compatible(struct bpf_map *map,
|
|
return ret;
|
|
}
|
|
|
|
+bool bpf_prog_map_compatible(struct bpf_map *map, const struct bpf_prog *fp)
|
|
+{
|
|
+ /* XDP programs inserted into maps are not guaranteed to run on
|
|
+ * a particular netdev (and can run outside driver context entirely
|
|
+ * in the case of devmap and cpumap). Until device checks
|
|
+ * are implemented, prohibit adding dev-bound programs to program maps.
|
|
+ */
|
|
+ if (bpf_prog_is_dev_bound(fp->aux))
|
|
+ return false;
|
|
+
|
|
+ return __bpf_prog_map_compatible(map, fp);
|
|
+}
|
|
+
|
|
static int bpf_check_tail_call(const struct bpf_prog *fp)
|
|
{
|
|
struct bpf_prog_aux *aux = fp->aux;
|
|
@@ -2321,7 +2326,7 @@ static int bpf_check_tail_call(const struct bpf_prog *fp)
|
|
if (!map_type_contains_progs(map))
|
|
continue;
|
|
|
|
- if (!bpf_prog_map_compatible(map, fp)) {
|
|
+ if (!__bpf_prog_map_compatible(map, fp)) {
|
|
ret = -EINVAL;
|
|
goto out;
|
|
}
|
|
@@ -2359,7 +2364,7 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err)
|
|
/* In case of BPF to BPF calls, verifier did all the prep
|
|
* work with regards to JITing, etc.
|
|
*/
|
|
- bool jit_needed = false;
|
|
+ bool jit_needed = fp->jit_requested;
|
|
|
|
if (fp->bpf_func)
|
|
goto finalize;
|
|
diff --git a/kernel/events/core.c b/kernel/events/core.c
|
|
index 5dd6424e62fa89..563f39518f7fe6 100644
|
|
--- a/kernel/events/core.c
|
|
+++ b/kernel/events/core.c
|
|
@@ -5913,6 +5913,9 @@ static int perf_event_set_output(struct perf_event *event,
|
|
static int perf_event_set_filter(struct perf_event *event, void __user *arg);
|
|
static int perf_copy_attr(struct perf_event_attr __user *uattr,
|
|
struct perf_event_attr *attr);
|
|
+static int __perf_event_set_bpf_prog(struct perf_event *event,
|
|
+ struct bpf_prog *prog,
|
|
+ u64 bpf_cookie);
|
|
|
|
static long _perf_ioctl(struct perf_event *event, unsigned int cmd, unsigned long arg)
|
|
{
|
|
@@ -5981,7 +5984,7 @@ static long _perf_ioctl(struct perf_event *event, unsigned int cmd, unsigned lon
|
|
if (IS_ERR(prog))
|
|
return PTR_ERR(prog);
|
|
|
|
- err = perf_event_set_bpf_prog(event, prog, 0);
|
|
+ err = __perf_event_set_bpf_prog(event, prog, 0);
|
|
if (err) {
|
|
bpf_prog_put(prog);
|
|
return err;
|
|
@@ -9553,14 +9556,14 @@ __perf_event_account_interrupt(struct perf_event *event, int throttle)
|
|
hwc->interrupts = 1;
|
|
} else {
|
|
hwc->interrupts++;
|
|
- if (unlikely(throttle &&
|
|
- hwc->interrupts > max_samples_per_tick)) {
|
|
- __this_cpu_inc(perf_throttled_count);
|
|
- tick_dep_set_cpu(smp_processor_id(), TICK_DEP_BIT_PERF_EVENTS);
|
|
- hwc->interrupts = MAX_INTERRUPTS;
|
|
- perf_log_throttle(event, 0);
|
|
- ret = 1;
|
|
- }
|
|
+ }
|
|
+
|
|
+ if (unlikely(throttle && hwc->interrupts >= max_samples_per_tick)) {
|
|
+ __this_cpu_inc(perf_throttled_count);
|
|
+ tick_dep_set_cpu(smp_processor_id(), TICK_DEP_BIT_PERF_EVENTS);
|
|
+ hwc->interrupts = MAX_INTERRUPTS;
|
|
+ perf_log_throttle(event, 0);
|
|
+ ret = 1;
|
|
}
|
|
|
|
if (event->attr.freq) {
|
|
@@ -10583,8 +10586,9 @@ static inline bool perf_event_is_tracing(struct perf_event *event)
|
|
return false;
|
|
}
|
|
|
|
-int perf_event_set_bpf_prog(struct perf_event *event, struct bpf_prog *prog,
|
|
- u64 bpf_cookie)
|
|
+static int __perf_event_set_bpf_prog(struct perf_event *event,
|
|
+ struct bpf_prog *prog,
|
|
+ u64 bpf_cookie)
|
|
{
|
|
bool is_kprobe, is_uprobe, is_tracepoint, is_syscall_tp;
|
|
|
|
@@ -10622,6 +10626,20 @@ int perf_event_set_bpf_prog(struct perf_event *event, struct bpf_prog *prog,
|
|
return perf_event_attach_bpf_prog(event, prog, bpf_cookie);
|
|
}
|
|
|
|
+int perf_event_set_bpf_prog(struct perf_event *event,
|
|
+ struct bpf_prog *prog,
|
|
+ u64 bpf_cookie)
|
|
+{
|
|
+ struct perf_event_context *ctx;
|
|
+ int ret;
|
|
+
|
|
+ ctx = perf_event_ctx_lock(event);
|
|
+ ret = __perf_event_set_bpf_prog(event, prog, bpf_cookie);
|
|
+ perf_event_ctx_unlock(event, ctx);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
void perf_event_free_bpf_prog(struct perf_event *event)
|
|
{
|
|
if (!perf_event_is_tracing(event)) {
|
|
@@ -10641,7 +10659,15 @@ static void perf_event_free_filter(struct perf_event *event)
|
|
{
|
|
}
|
|
|
|
-int perf_event_set_bpf_prog(struct perf_event *event, struct bpf_prog *prog,
|
|
+static int __perf_event_set_bpf_prog(struct perf_event *event,
|
|
+ struct bpf_prog *prog,
|
|
+ u64 bpf_cookie)
|
|
+{
|
|
+ return -ENOENT;
|
|
+}
|
|
+
|
|
+int perf_event_set_bpf_prog(struct perf_event *event,
|
|
+ struct bpf_prog *prog,
|
|
u64 bpf_cookie)
|
|
{
|
|
return -ENOENT;
|
|
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
|
|
index c2fc58938dee5d..76dcf2e28427f2 100644
|
|
--- a/kernel/power/hibernate.c
|
|
+++ b/kernel/power/hibernate.c
|
|
@@ -80,6 +80,11 @@ void hibernate_release(void)
|
|
atomic_inc(&hibernate_atomic);
|
|
}
|
|
|
|
+bool hibernation_in_progress(void)
|
|
+{
|
|
+ return !atomic_read(&hibernate_atomic);
|
|
+}
|
|
+
|
|
bool hibernation_available(void)
|
|
{
|
|
return nohibernate == 0 &&
|
|
diff --git a/kernel/power/main.c b/kernel/power/main.c
|
|
index f6425ae3e8b055..a3543bd2d25afc 100644
|
|
--- a/kernel/power/main.c
|
|
+++ b/kernel/power/main.c
|
|
@@ -585,7 +585,8 @@ bool pm_debug_messages_on __read_mostly;
|
|
|
|
bool pm_debug_messages_should_print(void)
|
|
{
|
|
- return pm_debug_messages_on && pm_suspend_target_state != PM_SUSPEND_ON;
|
|
+ return pm_debug_messages_on && (hibernation_in_progress() ||
|
|
+ pm_suspend_target_state != PM_SUSPEND_ON);
|
|
}
|
|
EXPORT_SYMBOL_GPL(pm_debug_messages_should_print);
|
|
|
|
diff --git a/kernel/power/power.h b/kernel/power/power.h
|
|
index a98f95e309a338..62a7cb452a4be6 100644
|
|
--- a/kernel/power/power.h
|
|
+++ b/kernel/power/power.h
|
|
@@ -66,10 +66,14 @@ extern void enable_restore_image_protection(void);
|
|
static inline void enable_restore_image_protection(void) {}
|
|
#endif /* CONFIG_STRICT_KERNEL_RWX */
|
|
|
|
+extern bool hibernation_in_progress(void);
|
|
+
|
|
#else /* !CONFIG_HIBERNATION */
|
|
|
|
static inline void hibernate_reserved_size_init(void) {}
|
|
static inline void hibernate_image_size_init(void) {}
|
|
+
|
|
+static inline bool hibernation_in_progress(void) { return false; }
|
|
#endif /* !CONFIG_HIBERNATION */
|
|
|
|
#define power_attr(_name) \
|
|
diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c
|
|
index 52571dcad768b9..4e941999a53ba6 100644
|
|
--- a/kernel/power/wakelock.c
|
|
+++ b/kernel/power/wakelock.c
|
|
@@ -49,6 +49,9 @@ ssize_t pm_show_wakelocks(char *buf, bool show_active)
|
|
len += sysfs_emit_at(buf, len, "%s ", wl->name);
|
|
}
|
|
|
|
+ if (len > 0)
|
|
+ --len;
|
|
+
|
|
len += sysfs_emit_at(buf, len, "\n");
|
|
|
|
mutex_unlock(&wakelocks_lock);
|
|
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
|
|
index fda08520c75c58..1fb3b7a0ed5d27 100644
|
|
--- a/kernel/rcu/tree.c
|
|
+++ b/kernel/rcu/tree.c
|
|
@@ -754,6 +754,10 @@ static int dyntick_save_progress_counter(struct rcu_data *rdp)
|
|
return 0;
|
|
}
|
|
|
|
+#ifndef arch_irq_stat_cpu
|
|
+#define arch_irq_stat_cpu(cpu) 0
|
|
+#endif
|
|
+
|
|
/*
|
|
* Returns positive if the specified CPU has passed through a quiescent state
|
|
* by virtue of being in or having passed through an dynticks idle state since
|
|
@@ -889,9 +893,9 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
|
|
rsrp->cputime_irq = kcpustat_field(kcsp, CPUTIME_IRQ, cpu);
|
|
rsrp->cputime_softirq = kcpustat_field(kcsp, CPUTIME_SOFTIRQ, cpu);
|
|
rsrp->cputime_system = kcpustat_field(kcsp, CPUTIME_SYSTEM, cpu);
|
|
- rsrp->nr_hardirqs = kstat_cpu_irqs_sum(rdp->cpu);
|
|
- rsrp->nr_softirqs = kstat_cpu_softirqs_sum(rdp->cpu);
|
|
- rsrp->nr_csw = nr_context_switches_cpu(rdp->cpu);
|
|
+ rsrp->nr_hardirqs = kstat_cpu_irqs_sum(cpu) + arch_irq_stat_cpu(cpu);
|
|
+ rsrp->nr_softirqs = kstat_cpu_softirqs_sum(cpu);
|
|
+ rsrp->nr_csw = nr_context_switches_cpu(cpu);
|
|
rsrp->jiffies = jiffies;
|
|
rsrp->gp_seq = rdp->gp_seq;
|
|
}
|
|
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
|
|
index 9eb43b501ff5c8..ac8cc756920ddf 100644
|
|
--- a/kernel/rcu/tree.h
|
|
+++ b/kernel/rcu/tree.h
|
|
@@ -169,7 +169,7 @@ struct rcu_snap_record {
|
|
u64 cputime_irq; /* Accumulated cputime of hard irqs */
|
|
u64 cputime_softirq;/* Accumulated cputime of soft irqs */
|
|
u64 cputime_system; /* Accumulated cputime of kernel tasks */
|
|
- unsigned long nr_hardirqs; /* Accumulated number of hard irqs */
|
|
+ u64 nr_hardirqs; /* Accumulated number of hard irqs */
|
|
unsigned int nr_softirqs; /* Accumulated number of soft irqs */
|
|
unsigned long long nr_csw; /* Accumulated number of task switches */
|
|
unsigned long jiffies; /* Track jiffies value */
|
|
diff --git a/kernel/rcu/tree_stall.h b/kernel/rcu/tree_stall.h
|
|
index 11a1fac3a58985..aab91040b83b16 100644
|
|
--- a/kernel/rcu/tree_stall.h
|
|
+++ b/kernel/rcu/tree_stall.h
|
|
@@ -452,8 +452,8 @@ static void print_cpu_stat_info(int cpu)
|
|
rsr.cputime_system = kcpustat_field(kcsp, CPUTIME_SYSTEM, cpu);
|
|
|
|
pr_err("\t hardirqs softirqs csw/system\n");
|
|
- pr_err("\t number: %8ld %10d %12lld\n",
|
|
- kstat_cpu_irqs_sum(cpu) - rsrp->nr_hardirqs,
|
|
+ pr_err("\t number: %8lld %10d %12lld\n",
|
|
+ kstat_cpu_irqs_sum(cpu) + arch_irq_stat_cpu(cpu) - rsrp->nr_hardirqs,
|
|
kstat_cpu_softirqs_sum(cpu) - rsrp->nr_softirqs,
|
|
nr_context_switches_cpu(cpu) - rsrp->nr_csw);
|
|
pr_err("\tcputime: %8lld %10lld %12lld ==> %d(ms)\n",
|
|
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
|
|
index e9c6f9d0e42ce4..9af1f2a72a0ab3 100644
|
|
--- a/kernel/time/posix-cpu-timers.c
|
|
+++ b/kernel/time/posix-cpu-timers.c
|
|
@@ -1437,6 +1437,15 @@ void run_posix_cpu_timers(void)
|
|
|
|
lockdep_assert_irqs_disabled();
|
|
|
|
+ /*
|
|
+ * Ensure that release_task(tsk) can't happen while
|
|
+ * handle_posix_cpu_timers() is running. Otherwise, a concurrent
|
|
+ * posix_cpu_timer_del() may fail to lock_task_sighand(tsk) and
|
|
+ * miss timer->it.cpu.firing != 0.
|
|
+ */
|
|
+ if (tsk->exit_state)
|
|
+ return;
|
|
+
|
|
/*
|
|
* If the actual expiry is deferred to task work context and the
|
|
* work is already scheduled there is no point to do anything here.
|
|
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
|
|
index 97f660a8ddc73d..8903db0b596026 100644
|
|
--- a/kernel/trace/bpf_trace.c
|
|
+++ b/kernel/trace/bpf_trace.c
|
|
@@ -1834,7 +1834,7 @@ static struct pt_regs *get_bpf_raw_tp_regs(void)
|
|
struct bpf_raw_tp_regs *tp_regs = this_cpu_ptr(&bpf_raw_tp_regs);
|
|
int nest_level = this_cpu_inc_return(bpf_raw_tp_nest_level);
|
|
|
|
- if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(tp_regs->regs))) {
|
|
+ if (nest_level > ARRAY_SIZE(tp_regs->regs)) {
|
|
this_cpu_dec(bpf_raw_tp_nest_level);
|
|
return ERR_PTR(-EBUSY);
|
|
}
|
|
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
|
|
index 43d19b69c635b2..946350c98b5396 100644
|
|
--- a/kernel/trace/trace.c
|
|
+++ b/kernel/trace/trace.c
|
|
@@ -7023,7 +7023,7 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
|
|
ret = trace_seq_to_buffer(&iter->seq,
|
|
page_address(spd.pages[i]),
|
|
min((size_t)trace_seq_used(&iter->seq),
|
|
- PAGE_SIZE));
|
|
+ (size_t)PAGE_SIZE));
|
|
if (ret < 0) {
|
|
__free_page(spd.pages[i]);
|
|
break;
|
|
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
|
|
index faf892aecdf490..e3afb830fbcc7b 100644
|
|
--- a/kernel/trace/trace.h
|
|
+++ b/kernel/trace/trace.h
|
|
@@ -1643,6 +1643,9 @@ extern int event_enable_register_trigger(char *glob,
|
|
extern void event_enable_unregister_trigger(char *glob,
|
|
struct event_trigger_data *test,
|
|
struct trace_event_file *file);
|
|
+extern struct event_trigger_data *
|
|
+trigger_data_alloc(struct event_command *cmd_ops, char *cmd, char *param,
|
|
+ void *private_data);
|
|
extern void trigger_data_free(struct event_trigger_data *data);
|
|
extern int event_trigger_init(struct event_trigger_data *data);
|
|
extern int trace_event_trigger_enable_disable(struct trace_event_file *file,
|
|
@@ -1669,11 +1672,6 @@ extern bool event_trigger_check_remove(const char *glob);
|
|
extern bool event_trigger_empty_param(const char *param);
|
|
extern int event_trigger_separate_filter(char *param_and_filter, char **param,
|
|
char **filter, bool param_required);
|
|
-extern struct event_trigger_data *
|
|
-event_trigger_alloc(struct event_command *cmd_ops,
|
|
- char *cmd,
|
|
- char *param,
|
|
- void *private_data);
|
|
extern int event_trigger_parse_num(char *trigger,
|
|
struct event_trigger_data *trigger_data);
|
|
extern int event_trigger_set_filter(struct event_command *cmd_ops,
|
|
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
|
|
index e6f9cbc622c759..88985aefb71ff8 100644
|
|
--- a/kernel/trace/trace_events_hist.c
|
|
+++ b/kernel/trace/trace_events_hist.c
|
|
@@ -5257,17 +5257,94 @@ hist_trigger_actions(struct hist_trigger_data *hist_data,
|
|
}
|
|
}
|
|
|
|
+/*
|
|
+ * The hist_pad structure is used to save information to create
|
|
+ * a histogram from the histogram trigger. It's too big to store
|
|
+ * on the stack, so when the histogram trigger is initialized
|
|
+ * a percpu array of 4 hist_pad structures is allocated.
|
|
+ * This will cover every context from normal, softirq, irq and NMI
|
|
+ * in the very unlikely event that a tigger happens at each of
|
|
+ * these contexts and interrupts a currently active trigger.
|
|
+ */
|
|
+struct hist_pad {
|
|
+ unsigned long entries[HIST_STACKTRACE_DEPTH];
|
|
+ u64 var_ref_vals[TRACING_MAP_VARS_MAX];
|
|
+ char compound_key[HIST_KEY_SIZE_MAX];
|
|
+};
|
|
+
|
|
+static struct hist_pad __percpu *hist_pads;
|
|
+static DEFINE_PER_CPU(int, hist_pad_cnt);
|
|
+static refcount_t hist_pad_ref;
|
|
+
|
|
+/* One hist_pad for every context (normal, softirq, irq, NMI) */
|
|
+#define MAX_HIST_CNT 4
|
|
+
|
|
+static int alloc_hist_pad(void)
|
|
+{
|
|
+ lockdep_assert_held(&event_mutex);
|
|
+
|
|
+ if (refcount_read(&hist_pad_ref)) {
|
|
+ refcount_inc(&hist_pad_ref);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ hist_pads = __alloc_percpu(sizeof(struct hist_pad) * MAX_HIST_CNT,
|
|
+ __alignof__(struct hist_pad));
|
|
+ if (!hist_pads)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ refcount_set(&hist_pad_ref, 1);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void free_hist_pad(void)
|
|
+{
|
|
+ lockdep_assert_held(&event_mutex);
|
|
+
|
|
+ if (!refcount_dec_and_test(&hist_pad_ref))
|
|
+ return;
|
|
+
|
|
+ free_percpu(hist_pads);
|
|
+ hist_pads = NULL;
|
|
+}
|
|
+
|
|
+static struct hist_pad *get_hist_pad(void)
|
|
+{
|
|
+ struct hist_pad *hist_pad;
|
|
+ int cnt;
|
|
+
|
|
+ if (WARN_ON_ONCE(!hist_pads))
|
|
+ return NULL;
|
|
+
|
|
+ preempt_disable();
|
|
+
|
|
+ hist_pad = per_cpu_ptr(hist_pads, smp_processor_id());
|
|
+
|
|
+ if (this_cpu_read(hist_pad_cnt) == MAX_HIST_CNT) {
|
|
+ preempt_enable();
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ cnt = this_cpu_inc_return(hist_pad_cnt) - 1;
|
|
+
|
|
+ return &hist_pad[cnt];
|
|
+}
|
|
+
|
|
+static void put_hist_pad(void)
|
|
+{
|
|
+ this_cpu_dec(hist_pad_cnt);
|
|
+ preempt_enable();
|
|
+}
|
|
+
|
|
static void event_hist_trigger(struct event_trigger_data *data,
|
|
struct trace_buffer *buffer, void *rec,
|
|
struct ring_buffer_event *rbe)
|
|
{
|
|
struct hist_trigger_data *hist_data = data->private_data;
|
|
bool use_compound_key = (hist_data->n_keys > 1);
|
|
- unsigned long entries[HIST_STACKTRACE_DEPTH];
|
|
- u64 var_ref_vals[TRACING_MAP_VARS_MAX];
|
|
- char compound_key[HIST_KEY_SIZE_MAX];
|
|
struct tracing_map_elt *elt = NULL;
|
|
struct hist_field *key_field;
|
|
+ struct hist_pad *hist_pad;
|
|
u64 field_contents;
|
|
void *key = NULL;
|
|
unsigned int i;
|
|
@@ -5275,12 +5352,18 @@ static void event_hist_trigger(struct event_trigger_data *data,
|
|
if (unlikely(!rbe))
|
|
return;
|
|
|
|
- memset(compound_key, 0, hist_data->key_size);
|
|
+ hist_pad = get_hist_pad();
|
|
+ if (!hist_pad)
|
|
+ return;
|
|
+
|
|
+ memset(hist_pad->compound_key, 0, hist_data->key_size);
|
|
|
|
for_each_hist_key_field(i, hist_data) {
|
|
key_field = hist_data->fields[i];
|
|
|
|
if (key_field->flags & HIST_FIELD_FL_STACKTRACE) {
|
|
+ unsigned long *entries = hist_pad->entries;
|
|
+
|
|
memset(entries, 0, HIST_STACKTRACE_SIZE);
|
|
if (key_field->field) {
|
|
unsigned long *stack, n_entries;
|
|
@@ -5304,26 +5387,31 @@ static void event_hist_trigger(struct event_trigger_data *data,
|
|
}
|
|
|
|
if (use_compound_key)
|
|
- add_to_key(compound_key, key, key_field, rec);
|
|
+ add_to_key(hist_pad->compound_key, key, key_field, rec);
|
|
}
|
|
|
|
if (use_compound_key)
|
|
- key = compound_key;
|
|
+ key = hist_pad->compound_key;
|
|
|
|
if (hist_data->n_var_refs &&
|
|
- !resolve_var_refs(hist_data, key, var_ref_vals, false))
|
|
- return;
|
|
+ !resolve_var_refs(hist_data, key, hist_pad->var_ref_vals, false))
|
|
+ goto out;
|
|
|
|
elt = tracing_map_insert(hist_data->map, key);
|
|
if (!elt)
|
|
- return;
|
|
+ goto out;
|
|
|
|
- hist_trigger_elt_update(hist_data, elt, buffer, rec, rbe, var_ref_vals);
|
|
+ hist_trigger_elt_update(hist_data, elt, buffer, rec, rbe, hist_pad->var_ref_vals);
|
|
|
|
- if (resolve_var_refs(hist_data, key, var_ref_vals, true))
|
|
- hist_trigger_actions(hist_data, elt, buffer, rec, rbe, key, var_ref_vals);
|
|
+ if (resolve_var_refs(hist_data, key, hist_pad->var_ref_vals, true)) {
|
|
+ hist_trigger_actions(hist_data, elt, buffer, rec, rbe,
|
|
+ key, hist_pad->var_ref_vals);
|
|
+ }
|
|
|
|
hist_poll_wakeup();
|
|
+
|
|
+ out:
|
|
+ put_hist_pad();
|
|
}
|
|
|
|
static void hist_trigger_stacktrace_print(struct seq_file *m,
|
|
@@ -6168,6 +6256,9 @@ static int event_hist_trigger_init(struct event_trigger_data *data)
|
|
{
|
|
struct hist_trigger_data *hist_data = data->private_data;
|
|
|
|
+ if (alloc_hist_pad() < 0)
|
|
+ return -ENOMEM;
|
|
+
|
|
if (!data->ref && hist_data->attrs->name)
|
|
save_named_trigger(hist_data->attrs->name, data);
|
|
|
|
@@ -6212,6 +6303,7 @@ static void event_hist_trigger_free(struct event_trigger_data *data)
|
|
|
|
destroy_hist_data(hist_data);
|
|
}
|
|
+ free_hist_pad();
|
|
}
|
|
|
|
static struct event_trigger_ops event_hist_trigger_ops = {
|
|
@@ -6227,9 +6319,7 @@ static int event_hist_trigger_named_init(struct event_trigger_data *data)
|
|
|
|
save_named_trigger(data->named_data->name, data);
|
|
|
|
- event_hist_trigger_init(data->named_data);
|
|
-
|
|
- return 0;
|
|
+ return event_hist_trigger_init(data->named_data);
|
|
}
|
|
|
|
static void event_hist_trigger_named_free(struct event_trigger_data *data)
|
|
@@ -6716,7 +6806,7 @@ static int event_hist_trigger_parse(struct event_command *cmd_ops,
|
|
return PTR_ERR(hist_data);
|
|
}
|
|
|
|
- trigger_data = event_trigger_alloc(cmd_ops, cmd, param, hist_data);
|
|
+ trigger_data = trigger_data_alloc(cmd_ops, cmd, param, hist_data);
|
|
if (!trigger_data) {
|
|
ret = -ENOMEM;
|
|
goto out_free;
|
|
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
|
|
index 2c233c0d38fa95..fe079ff82ef1bf 100644
|
|
--- a/kernel/trace/trace_events_trigger.c
|
|
+++ b/kernel/trace/trace_events_trigger.c
|
|
@@ -809,7 +809,7 @@ int event_trigger_separate_filter(char *param_and_filter, char **param,
|
|
}
|
|
|
|
/**
|
|
- * event_trigger_alloc - allocate and init event_trigger_data for a trigger
|
|
+ * trigger_data_alloc - allocate and init event_trigger_data for a trigger
|
|
* @cmd_ops: The event_command operations for the trigger
|
|
* @cmd: The cmd string
|
|
* @param: The param string
|
|
@@ -820,14 +820,14 @@ int event_trigger_separate_filter(char *param_and_filter, char **param,
|
|
* trigger_ops to assign to the event_trigger_data. @private_data can
|
|
* also be passed in and associated with the event_trigger_data.
|
|
*
|
|
- * Use event_trigger_free() to free an event_trigger_data object.
|
|
+ * Use trigger_data_free() to free an event_trigger_data object.
|
|
*
|
|
* Return: The trigger_data object success, NULL otherwise
|
|
*/
|
|
-struct event_trigger_data *event_trigger_alloc(struct event_command *cmd_ops,
|
|
- char *cmd,
|
|
- char *param,
|
|
- void *private_data)
|
|
+struct event_trigger_data *trigger_data_alloc(struct event_command *cmd_ops,
|
|
+ char *cmd,
|
|
+ char *param,
|
|
+ void *private_data)
|
|
{
|
|
struct event_trigger_data *trigger_data;
|
|
struct event_trigger_ops *trigger_ops;
|
|
@@ -994,13 +994,13 @@ event_trigger_parse(struct event_command *cmd_ops,
|
|
return ret;
|
|
|
|
ret = -ENOMEM;
|
|
- trigger_data = event_trigger_alloc(cmd_ops, cmd, param, file);
|
|
+ trigger_data = trigger_data_alloc(cmd_ops, cmd, param, file);
|
|
if (!trigger_data)
|
|
goto out;
|
|
|
|
if (remove) {
|
|
event_trigger_unregister(cmd_ops, file, glob+1, trigger_data);
|
|
- kfree(trigger_data);
|
|
+ trigger_data_free(trigger_data);
|
|
ret = 0;
|
|
goto out;
|
|
}
|
|
@@ -1027,7 +1027,7 @@ event_trigger_parse(struct event_command *cmd_ops,
|
|
|
|
out_free:
|
|
event_trigger_reset_filter(cmd_ops, trigger_data);
|
|
- kfree(trigger_data);
|
|
+ trigger_data_free(trigger_data);
|
|
goto out;
|
|
}
|
|
|
|
@@ -1787,7 +1787,7 @@ int event_enable_trigger_parse(struct event_command *cmd_ops,
|
|
enable_data->enable = enable;
|
|
enable_data->file = event_enable_file;
|
|
|
|
- trigger_data = event_trigger_alloc(cmd_ops, cmd, param, enable_data);
|
|
+ trigger_data = trigger_data_alloc(cmd_ops, cmd, param, enable_data);
|
|
if (!trigger_data) {
|
|
kfree(enable_data);
|
|
goto out;
|
|
diff --git a/lib/kunit/static_stub.c b/lib/kunit/static_stub.c
|
|
index 92b2cccd5e7633..484fd85251b415 100644
|
|
--- a/lib/kunit/static_stub.c
|
|
+++ b/lib/kunit/static_stub.c
|
|
@@ -96,7 +96,7 @@ void __kunit_activate_static_stub(struct kunit *test,
|
|
|
|
/* If the replacement address is NULL, deactivate the stub. */
|
|
if (!replacement_addr) {
|
|
- kunit_deactivate_static_stub(test, replacement_addr);
|
|
+ kunit_deactivate_static_stub(test, real_fn_addr);
|
|
return;
|
|
}
|
|
|
|
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
|
|
index ecced40e510320..465e6a53b3bf25 100644
|
|
--- a/mm/kasan/report.c
|
|
+++ b/mm/kasan/report.c
|
|
@@ -538,7 +538,7 @@ void kasan_report_invalid_free(void *ptr, unsigned long ip, enum kasan_report_ty
|
|
|
|
start_report(&flags, true);
|
|
|
|
- memset(&info, 0, sizeof(info));
|
|
+ __memset(&info, 0, sizeof(info));
|
|
info.type = type;
|
|
info.access_addr = ptr;
|
|
info.access_size = 0;
|
|
@@ -576,7 +576,7 @@ bool kasan_report(const void *addr, size_t size, bool is_write,
|
|
|
|
start_report(&irq_flags, true);
|
|
|
|
- memset(&info, 0, sizeof(info));
|
|
+ __memset(&info, 0, sizeof(info));
|
|
info.type = KASAN_REPORT_ACCESS;
|
|
info.access_addr = addr;
|
|
info.access_size = size;
|
|
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
|
|
index dd772f9d0f0802..d687f09a7ae37f 100644
|
|
--- a/mm/kasan/shadow.c
|
|
+++ b/mm/kasan/shadow.c
|
|
@@ -324,7 +324,7 @@ static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr,
|
|
if (!page)
|
|
return -ENOMEM;
|
|
|
|
- memset((void *)page, KASAN_VMALLOC_INVALID, PAGE_SIZE);
|
|
+ __memset((void *)page, KASAN_VMALLOC_INVALID, PAGE_SIZE);
|
|
pte = pfn_pte(PFN_DOWN(__pa(page)), PAGE_KERNEL);
|
|
|
|
spin_lock(&init_mm.page_table_lock);
|
|
diff --git a/net/bluetooth/eir.c b/net/bluetooth/eir.c
|
|
index 1bc51e2b05a347..3e1713673ecc93 100644
|
|
--- a/net/bluetooth/eir.c
|
|
+++ b/net/bluetooth/eir.c
|
|
@@ -366,17 +366,19 @@ u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr)
|
|
|
|
void *eir_get_service_data(u8 *eir, size_t eir_len, u16 uuid, size_t *len)
|
|
{
|
|
- while ((eir = eir_get_data(eir, eir_len, EIR_SERVICE_DATA, len))) {
|
|
+ size_t dlen;
|
|
+
|
|
+ while ((eir = eir_get_data(eir, eir_len, EIR_SERVICE_DATA, &dlen))) {
|
|
u16 value = get_unaligned_le16(eir);
|
|
|
|
if (uuid == value) {
|
|
if (len)
|
|
- *len -= 2;
|
|
+ *len = dlen - 2;
|
|
return &eir[2];
|
|
}
|
|
|
|
- eir += *len;
|
|
- eir_len -= *len;
|
|
+ eir += dlen;
|
|
+ eir_len -= dlen;
|
|
}
|
|
|
|
return NULL;
|
|
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
|
|
index 30519d47e8a695..32f7bd0e891689 100644
|
|
--- a/net/bluetooth/hci_core.c
|
|
+++ b/net/bluetooth/hci_core.c
|
|
@@ -1862,10 +1862,8 @@ void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
|
|
if (monitor->handle)
|
|
idr_remove(&hdev->adv_monitors_idr, monitor->handle);
|
|
|
|
- if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) {
|
|
+ if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED)
|
|
hdev->adv_monitors_cnt--;
|
|
- mgmt_adv_monitor_removed(hdev, monitor->handle);
|
|
- }
|
|
|
|
kfree(monitor);
|
|
}
|
|
@@ -2492,6 +2490,7 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
|
|
|
|
mutex_init(&hdev->lock);
|
|
mutex_init(&hdev->req_lock);
|
|
+ mutex_init(&hdev->mgmt_pending_lock);
|
|
|
|
ida_init(&hdev->unset_handle_ida);
|
|
|
|
@@ -3380,23 +3379,18 @@ static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
|
|
|
|
bt_dev_err(hdev, "link tx timeout");
|
|
|
|
- rcu_read_lock();
|
|
+ hci_dev_lock(hdev);
|
|
|
|
/* Kill stalled connections */
|
|
- list_for_each_entry_rcu(c, &h->list, list) {
|
|
+ list_for_each_entry(c, &h->list, list) {
|
|
if (c->type == type && c->sent) {
|
|
bt_dev_err(hdev, "killing stalled connection %pMR",
|
|
&c->dst);
|
|
- /* hci_disconnect might sleep, so, we have to release
|
|
- * the RCU read lock before calling it.
|
|
- */
|
|
- rcu_read_unlock();
|
|
hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
|
|
- rcu_read_lock();
|
|
}
|
|
}
|
|
|
|
- rcu_read_unlock();
|
|
+ hci_dev_unlock(hdev);
|
|
}
|
|
|
|
static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
|
|
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
|
|
index d6f40806ee5126..e92bc4ceb5adda 100644
|
|
--- a/net/bluetooth/hci_sync.c
|
|
+++ b/net/bluetooth/hci_sync.c
|
|
@@ -1586,7 +1586,8 @@ static int hci_enable_per_advertising_sync(struct hci_dev *hdev, u8 instance)
|
|
static int hci_adv_bcast_annoucement(struct hci_dev *hdev, struct adv_info *adv)
|
|
{
|
|
u8 bid[3];
|
|
- u8 ad[4 + 3];
|
|
+ u8 ad[HCI_MAX_EXT_AD_LENGTH];
|
|
+ u8 len;
|
|
|
|
/* Skip if NULL adv as instance 0x00 is used for general purpose
|
|
* advertising so it cannot used for the likes of Broadcast Announcement
|
|
@@ -1612,8 +1613,10 @@ static int hci_adv_bcast_annoucement(struct hci_dev *hdev, struct adv_info *adv)
|
|
|
|
/* Generate Broadcast ID */
|
|
get_random_bytes(bid, sizeof(bid));
|
|
- eir_append_service_data(ad, 0, 0x1852, bid, sizeof(bid));
|
|
- hci_set_adv_instance_data(hdev, adv->instance, sizeof(ad), ad, 0, NULL);
|
|
+ len = eir_append_service_data(ad, 0, 0x1852, bid, sizeof(bid));
|
|
+ memcpy(ad + len, adv->adv_data, adv->adv_data_len);
|
|
+ hci_set_adv_instance_data(hdev, adv->instance, len + adv->adv_data_len,
|
|
+ ad, 0, NULL);
|
|
|
|
return hci_update_adv_data_sync(hdev, adv->instance);
|
|
}
|
|
@@ -1630,8 +1633,15 @@ int hci_start_per_adv_sync(struct hci_dev *hdev, u8 instance, u8 data_len,
|
|
|
|
if (instance) {
|
|
adv = hci_find_adv_instance(hdev, instance);
|
|
- /* Create an instance if that could not be found */
|
|
- if (!adv) {
|
|
+ if (adv) {
|
|
+ /* Turn it into periodic advertising */
|
|
+ adv->periodic = true;
|
|
+ adv->per_adv_data_len = data_len;
|
|
+ if (data)
|
|
+ memcpy(adv->per_adv_data, data, data_len);
|
|
+ adv->flags = flags;
|
|
+ } else if (!adv) {
|
|
+ /* Create an instance if that could not be found */
|
|
adv = hci_add_per_instance(hdev, instance, flags,
|
|
data_len, data,
|
|
sync_interval,
|
|
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
|
|
index 1c54e812ef1f78..2744ad11687c65 100644
|
|
--- a/net/bluetooth/l2cap_core.c
|
|
+++ b/net/bluetooth/l2cap_core.c
|
|
@@ -4833,7 +4833,8 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
|
|
|
|
if (!smp_sufficient_security(conn->hcon, pchan->sec_level,
|
|
SMP_ALLOW_STK)) {
|
|
- result = L2CAP_CR_LE_AUTHENTICATION;
|
|
+ result = pchan->sec_level == BT_SECURITY_MEDIUM ?
|
|
+ L2CAP_CR_LE_ENCRYPTION : L2CAP_CR_LE_AUTHENTICATION;
|
|
chan = NULL;
|
|
goto response_unlock;
|
|
}
|
|
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
|
|
index 589c3a481e4c10..853d217cabc917 100644
|
|
--- a/net/bluetooth/mgmt.c
|
|
+++ b/net/bluetooth/mgmt.c
|
|
@@ -1433,22 +1433,17 @@ static void settings_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
|
|
|
send_settings_rsp(cmd->sk, cmd->opcode, match->hdev);
|
|
|
|
- list_del(&cmd->list);
|
|
-
|
|
if (match->sk == NULL) {
|
|
match->sk = cmd->sk;
|
|
sock_hold(match->sk);
|
|
}
|
|
-
|
|
- mgmt_pending_free(cmd);
|
|
}
|
|
|
|
static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
|
{
|
|
u8 *status = data;
|
|
|
|
- mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, *status);
|
|
- mgmt_pending_remove(cmd);
|
|
+ mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, *status);
|
|
}
|
|
|
|
static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
|
@@ -1462,8 +1457,6 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
|
|
|
if (cmd->cmd_complete) {
|
|
cmd->cmd_complete(cmd, match->mgmt_status);
|
|
- mgmt_pending_remove(cmd);
|
|
-
|
|
return;
|
|
}
|
|
|
|
@@ -1472,13 +1465,13 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
|
|
|
static int generic_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
|
|
{
|
|
- return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status,
|
|
+ return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status,
|
|
cmd->param, cmd->param_len);
|
|
}
|
|
|
|
static int addr_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
|
|
{
|
|
- return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status,
|
|
+ return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status,
|
|
cmd->param, sizeof(struct mgmt_addr_info));
|
|
}
|
|
|
|
@@ -1518,7 +1511,7 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
|
|
|
|
if (err) {
|
|
u8 mgmt_err = mgmt_status(err);
|
|
- mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
|
+ mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
|
|
hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
|
|
goto done;
|
|
}
|
|
@@ -1693,7 +1686,7 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
|
|
|
|
if (err) {
|
|
u8 mgmt_err = mgmt_status(err);
|
|
- mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
|
+ mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
|
|
goto done;
|
|
}
|
|
|
|
@@ -1930,8 +1923,8 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
|
|
new_settings(hdev, NULL);
|
|
}
|
|
|
|
- mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp,
|
|
- &mgmt_err);
|
|
+ mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true,
|
|
+ cmd_status_rsp, &mgmt_err);
|
|
return;
|
|
}
|
|
|
|
@@ -1941,7 +1934,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
|
|
changed = hci_dev_test_and_clear_flag(hdev, HCI_SSP_ENABLED);
|
|
}
|
|
|
|
- mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match);
|
|
+ mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true, settings_rsp, &match);
|
|
|
|
if (changed)
|
|
new_settings(hdev, match.sk);
|
|
@@ -2061,12 +2054,12 @@ static void set_le_complete(struct hci_dev *hdev, void *data, int err)
|
|
bt_dev_dbg(hdev, "err %d", err);
|
|
|
|
if (status) {
|
|
- mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp,
|
|
- &status);
|
|
+ mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, cmd_status_rsp,
|
|
+ &status);
|
|
return;
|
|
}
|
|
|
|
- mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match);
|
|
+ mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, settings_rsp, &match);
|
|
|
|
new_settings(hdev, match.sk);
|
|
|
|
@@ -2125,7 +2118,7 @@ static void set_mesh_complete(struct hci_dev *hdev, void *data, int err)
|
|
struct sock *sk = cmd->sk;
|
|
|
|
if (status) {
|
|
- mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev,
|
|
+ mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, true,
|
|
cmd_status_rsp, &status);
|
|
return;
|
|
}
|
|
@@ -2566,7 +2559,7 @@ static void mgmt_class_complete(struct hci_dev *hdev, void *data, int err)
|
|
|
|
bt_dev_dbg(hdev, "err %d", err);
|
|
|
|
- mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
|
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
|
mgmt_status(err), hdev->dev_class, 3);
|
|
|
|
mgmt_pending_free(cmd);
|
|
@@ -3354,7 +3347,7 @@ static int pairing_complete(struct mgmt_pending_cmd *cmd, u8 status)
|
|
bacpy(&rp.addr.bdaddr, &conn->dst);
|
|
rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
|
|
|
|
- err = mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE,
|
|
+ err = mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_PAIR_DEVICE,
|
|
status, &rp, sizeof(rp));
|
|
|
|
/* So we don't get further callbacks for this connection */
|
|
@@ -5165,24 +5158,14 @@ static void mgmt_adv_monitor_added(struct sock *sk, struct hci_dev *hdev,
|
|
mgmt_event(MGMT_EV_ADV_MONITOR_ADDED, hdev, &ev, sizeof(ev), sk);
|
|
}
|
|
|
|
-void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle)
|
|
+static void mgmt_adv_monitor_removed(struct sock *sk, struct hci_dev *hdev,
|
|
+ __le16 handle)
|
|
{
|
|
struct mgmt_ev_adv_monitor_removed ev;
|
|
- struct mgmt_pending_cmd *cmd;
|
|
- struct sock *sk_skip = NULL;
|
|
- struct mgmt_cp_remove_adv_monitor *cp;
|
|
-
|
|
- cmd = pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev);
|
|
- if (cmd) {
|
|
- cp = cmd->param;
|
|
-
|
|
- if (cp->monitor_handle)
|
|
- sk_skip = cmd->sk;
|
|
- }
|
|
|
|
- ev.monitor_handle = cpu_to_le16(handle);
|
|
+ ev.monitor_handle = handle;
|
|
|
|
- mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk_skip);
|
|
+ mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk);
|
|
}
|
|
|
|
static int read_adv_mon_features(struct sock *sk, struct hci_dev *hdev,
|
|
@@ -5253,7 +5236,7 @@ static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev,
|
|
hci_update_passive_scan(hdev);
|
|
}
|
|
|
|
- mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
|
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
|
mgmt_status(status), &rp, sizeof(rp));
|
|
mgmt_pending_remove(cmd);
|
|
|
|
@@ -5284,8 +5267,7 @@ static int __add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev,
|
|
|
|
if (pending_find(MGMT_OP_SET_LE, hdev) ||
|
|
pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR, hdev) ||
|
|
- pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev) ||
|
|
- pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) {
|
|
+ pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev)) {
|
|
status = MGMT_STATUS_BUSY;
|
|
goto unlock;
|
|
}
|
|
@@ -5455,8 +5437,7 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev,
|
|
struct mgmt_pending_cmd *cmd = data;
|
|
struct mgmt_cp_remove_adv_monitor *cp;
|
|
|
|
- if (status == -ECANCELED ||
|
|
- cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev))
|
|
+ if (status == -ECANCELED)
|
|
return;
|
|
|
|
hci_dev_lock(hdev);
|
|
@@ -5465,12 +5446,14 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev,
|
|
|
|
rp.monitor_handle = cp->monitor_handle;
|
|
|
|
- if (!status)
|
|
+ if (!status) {
|
|
+ mgmt_adv_monitor_removed(cmd->sk, hdev, cp->monitor_handle);
|
|
hci_update_passive_scan(hdev);
|
|
+ }
|
|
|
|
- mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
|
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
|
mgmt_status(status), &rp, sizeof(rp));
|
|
- mgmt_pending_remove(cmd);
|
|
+ mgmt_pending_free(cmd);
|
|
|
|
hci_dev_unlock(hdev);
|
|
bt_dev_dbg(hdev, "remove monitor %d complete, status %d",
|
|
@@ -5480,10 +5463,6 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev,
|
|
static int mgmt_remove_adv_monitor_sync(struct hci_dev *hdev, void *data)
|
|
{
|
|
struct mgmt_pending_cmd *cmd = data;
|
|
-
|
|
- if (cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev))
|
|
- return -ECANCELED;
|
|
-
|
|
struct mgmt_cp_remove_adv_monitor *cp = cmd->param;
|
|
u16 handle = __le16_to_cpu(cp->monitor_handle);
|
|
|
|
@@ -5502,14 +5481,13 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
|
|
hci_dev_lock(hdev);
|
|
|
|
if (pending_find(MGMT_OP_SET_LE, hdev) ||
|
|
- pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev) ||
|
|
pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR, hdev) ||
|
|
pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev)) {
|
|
status = MGMT_STATUS_BUSY;
|
|
goto unlock;
|
|
}
|
|
|
|
- cmd = mgmt_pending_add(sk, MGMT_OP_REMOVE_ADV_MONITOR, hdev, data, len);
|
|
+ cmd = mgmt_pending_new(sk, MGMT_OP_REMOVE_ADV_MONITOR, hdev, data, len);
|
|
if (!cmd) {
|
|
status = MGMT_STATUS_NO_RESOURCES;
|
|
goto unlock;
|
|
@@ -5519,7 +5497,7 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
|
|
mgmt_remove_adv_monitor_complete);
|
|
|
|
if (err) {
|
|
- mgmt_pending_remove(cmd);
|
|
+ mgmt_pending_free(cmd);
|
|
|
|
if (err == -ENOMEM)
|
|
status = MGMT_STATUS_NO_RESOURCES;
|
|
@@ -5872,7 +5850,7 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err)
|
|
cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev))
|
|
return;
|
|
|
|
- mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err),
|
|
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err),
|
|
cmd->param, 1);
|
|
mgmt_pending_remove(cmd);
|
|
|
|
@@ -6110,7 +6088,7 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err)
|
|
|
|
bt_dev_dbg(hdev, "err %d", err);
|
|
|
|
- mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err),
|
|
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err),
|
|
cmd->param, 1);
|
|
mgmt_pending_remove(cmd);
|
|
|
|
@@ -6335,7 +6313,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
|
|
u8 status = mgmt_status(err);
|
|
|
|
if (status) {
|
|
- mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev,
|
|
+ mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true,
|
|
cmd_status_rsp, &status);
|
|
return;
|
|
}
|
|
@@ -6345,7 +6323,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
|
|
else
|
|
hci_dev_clear_flag(hdev, HCI_ADVERTISING);
|
|
|
|
- mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp,
|
|
+ mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true, settings_rsp,
|
|
&match);
|
|
|
|
new_settings(hdev, match.sk);
|
|
@@ -6689,7 +6667,7 @@ static void set_bredr_complete(struct hci_dev *hdev, void *data, int err)
|
|
*/
|
|
hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED);
|
|
|
|
- mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
|
+ mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
|
|
} else {
|
|
send_settings_rsp(cmd->sk, MGMT_OP_SET_BREDR, hdev);
|
|
new_settings(hdev, cmd->sk);
|
|
@@ -6826,7 +6804,7 @@ static void set_secure_conn_complete(struct hci_dev *hdev, void *data, int err)
|
|
if (err) {
|
|
u8 mgmt_err = mgmt_status(err);
|
|
|
|
- mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
|
+ mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
|
|
goto done;
|
|
}
|
|
|
|
@@ -7273,7 +7251,7 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err)
|
|
rp.max_tx_power = HCI_TX_POWER_INVALID;
|
|
}
|
|
|
|
- mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status,
|
|
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_GET_CONN_INFO, status,
|
|
&rp, sizeof(rp));
|
|
|
|
mgmt_pending_free(cmd);
|
|
@@ -7433,7 +7411,7 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err)
|
|
}
|
|
|
|
complete:
|
|
- mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp,
|
|
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, &rp,
|
|
sizeof(rp));
|
|
|
|
mgmt_pending_free(cmd);
|
|
@@ -8637,10 +8615,10 @@ static void add_advertising_complete(struct hci_dev *hdev, void *data, int err)
|
|
rp.instance = cp->instance;
|
|
|
|
if (err)
|
|
- mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
|
|
+ mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
|
|
mgmt_status(err));
|
|
else
|
|
- mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
|
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
|
mgmt_status(err), &rp, sizeof(rp));
|
|
|
|
add_adv_complete(hdev, cmd->sk, cp->instance, err);
|
|
@@ -8828,10 +8806,10 @@ static void add_ext_adv_params_complete(struct hci_dev *hdev, void *data,
|
|
|
|
hci_remove_adv_instance(hdev, cp->instance);
|
|
|
|
- mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
|
|
+ mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
|
|
mgmt_status(err));
|
|
} else {
|
|
- mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
|
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
|
mgmt_status(err), &rp, sizeof(rp));
|
|
}
|
|
|
|
@@ -8979,10 +8957,10 @@ static void add_ext_adv_data_complete(struct hci_dev *hdev, void *data, int err)
|
|
rp.instance = cp->instance;
|
|
|
|
if (err)
|
|
- mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
|
|
+ mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
|
|
mgmt_status(err));
|
|
else
|
|
- mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
|
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
|
mgmt_status(err), &rp, sizeof(rp));
|
|
|
|
mgmt_pending_free(cmd);
|
|
@@ -9141,10 +9119,10 @@ static void remove_advertising_complete(struct hci_dev *hdev, void *data,
|
|
rp.instance = cp->instance;
|
|
|
|
if (err)
|
|
- mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
|
|
+ mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
|
|
mgmt_status(err));
|
|
else
|
|
- mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
|
+ mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
|
|
MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
|
|
|
|
mgmt_pending_free(cmd);
|
|
@@ -9415,7 +9393,7 @@ void mgmt_index_removed(struct hci_dev *hdev)
|
|
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
|
|
return;
|
|
|
|
- mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match);
|
|
+ mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match);
|
|
|
|
if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
|
|
mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0,
|
|
@@ -9453,7 +9431,8 @@ void mgmt_power_on(struct hci_dev *hdev, int err)
|
|
hci_update_passive_scan(hdev);
|
|
}
|
|
|
|
- mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
|
|
+ mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp,
|
|
+ &match);
|
|
|
|
new_settings(hdev, match.sk);
|
|
|
|
@@ -9468,7 +9447,8 @@ void __mgmt_power_off(struct hci_dev *hdev)
|
|
struct cmd_lookup match = { NULL, hdev };
|
|
u8 zero_cod[] = { 0, 0, 0 };
|
|
|
|
- mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
|
|
+ mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp,
|
|
+ &match);
|
|
|
|
/* If the power off is because of hdev unregistration let
|
|
* use the appropriate INVALID_INDEX status. Otherwise use
|
|
@@ -9482,7 +9462,7 @@ void __mgmt_power_off(struct hci_dev *hdev)
|
|
else
|
|
match.mgmt_status = MGMT_STATUS_NOT_POWERED;
|
|
|
|
- mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match);
|
|
+ mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match);
|
|
|
|
if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) {
|
|
mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev,
|
|
@@ -9723,7 +9703,6 @@ static void unpair_device_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
|
device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk);
|
|
|
|
cmd->cmd_complete(cmd, 0);
|
|
- mgmt_pending_remove(cmd);
|
|
}
|
|
|
|
bool mgmt_powering_down(struct hci_dev *hdev)
|
|
@@ -9776,8 +9755,8 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
|
struct mgmt_cp_disconnect *cp;
|
|
struct mgmt_pending_cmd *cmd;
|
|
|
|
- mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
|
|
- hdev);
|
|
+ mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, true,
|
|
+ unpair_device_rsp, hdev);
|
|
|
|
cmd = pending_find(MGMT_OP_DISCONNECT, hdev);
|
|
if (!cmd)
|
|
@@ -9970,7 +9949,7 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
|
|
|
|
if (status) {
|
|
u8 mgmt_err = mgmt_status(status);
|
|
- mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev,
|
|
+ mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true,
|
|
cmd_status_rsp, &mgmt_err);
|
|
return;
|
|
}
|
|
@@ -9980,8 +9959,8 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
|
|
else
|
|
changed = hci_dev_test_and_clear_flag(hdev, HCI_LINK_SECURITY);
|
|
|
|
- mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp,
|
|
- &match);
|
|
+ mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true,
|
|
+ settings_rsp, &match);
|
|
|
|
if (changed)
|
|
new_settings(hdev, match.sk);
|
|
@@ -10005,9 +9984,12 @@ void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
|
|
{
|
|
struct cmd_lookup match = { NULL, hdev, mgmt_status(status) };
|
|
|
|
- mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, sk_lookup, &match);
|
|
- mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match);
|
|
- mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match);
|
|
+ mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, false, sk_lookup,
|
|
+ &match);
|
|
+ mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, false, sk_lookup,
|
|
+ &match);
|
|
+ mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, false, sk_lookup,
|
|
+ &match);
|
|
|
|
if (!status) {
|
|
mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class,
|
|
diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c
|
|
index 0115f783bde805..4ba500c377a4c0 100644
|
|
--- a/net/bluetooth/mgmt_util.c
|
|
+++ b/net/bluetooth/mgmt_util.c
|
|
@@ -217,47 +217,47 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
|
|
struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode,
|
|
struct hci_dev *hdev)
|
|
{
|
|
- struct mgmt_pending_cmd *cmd;
|
|
+ struct mgmt_pending_cmd *cmd, *tmp;
|
|
+
|
|
+ mutex_lock(&hdev->mgmt_pending_lock);
|
|
|
|
- list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
|
|
+ list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) {
|
|
if (hci_sock_get_channel(cmd->sk) != channel)
|
|
continue;
|
|
- if (cmd->opcode == opcode)
|
|
- return cmd;
|
|
- }
|
|
|
|
- return NULL;
|
|
-}
|
|
-
|
|
-struct mgmt_pending_cmd *mgmt_pending_find_data(unsigned short channel,
|
|
- u16 opcode,
|
|
- struct hci_dev *hdev,
|
|
- const void *data)
|
|
-{
|
|
- struct mgmt_pending_cmd *cmd;
|
|
-
|
|
- list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
|
|
- if (cmd->user_data != data)
|
|
- continue;
|
|
- if (cmd->opcode == opcode)
|
|
+ if (cmd->opcode == opcode) {
|
|
+ mutex_unlock(&hdev->mgmt_pending_lock);
|
|
return cmd;
|
|
+ }
|
|
}
|
|
|
|
+ mutex_unlock(&hdev->mgmt_pending_lock);
|
|
+
|
|
return NULL;
|
|
}
|
|
|
|
-void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev,
|
|
+void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove,
|
|
void (*cb)(struct mgmt_pending_cmd *cmd, void *data),
|
|
void *data)
|
|
{
|
|
struct mgmt_pending_cmd *cmd, *tmp;
|
|
|
|
+ mutex_lock(&hdev->mgmt_pending_lock);
|
|
+
|
|
list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) {
|
|
if (opcode > 0 && cmd->opcode != opcode)
|
|
continue;
|
|
|
|
+ if (remove)
|
|
+ list_del(&cmd->list);
|
|
+
|
|
cb(cmd, data);
|
|
+
|
|
+ if (remove)
|
|
+ mgmt_pending_free(cmd);
|
|
}
|
|
+
|
|
+ mutex_unlock(&hdev->mgmt_pending_lock);
|
|
}
|
|
|
|
struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode,
|
|
@@ -271,7 +271,7 @@ struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode,
|
|
return NULL;
|
|
|
|
cmd->opcode = opcode;
|
|
- cmd->index = hdev->id;
|
|
+ cmd->hdev = hdev;
|
|
|
|
cmd->param = kmemdup(data, len, GFP_KERNEL);
|
|
if (!cmd->param) {
|
|
@@ -297,7 +297,9 @@ struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
|
|
if (!cmd)
|
|
return NULL;
|
|
|
|
+ mutex_lock(&hdev->mgmt_pending_lock);
|
|
list_add_tail(&cmd->list, &hdev->mgmt_pending);
|
|
+ mutex_unlock(&hdev->mgmt_pending_lock);
|
|
|
|
return cmd;
|
|
}
|
|
@@ -311,7 +313,10 @@ void mgmt_pending_free(struct mgmt_pending_cmd *cmd)
|
|
|
|
void mgmt_pending_remove(struct mgmt_pending_cmd *cmd)
|
|
{
|
|
+ mutex_lock(&cmd->hdev->mgmt_pending_lock);
|
|
list_del(&cmd->list);
|
|
+ mutex_unlock(&cmd->hdev->mgmt_pending_lock);
|
|
+
|
|
mgmt_pending_free(cmd);
|
|
}
|
|
|
|
@@ -321,7 +326,7 @@ void mgmt_mesh_foreach(struct hci_dev *hdev,
|
|
{
|
|
struct mgmt_mesh_tx *mesh_tx, *tmp;
|
|
|
|
- list_for_each_entry_safe(mesh_tx, tmp, &hdev->mgmt_pending, list) {
|
|
+ list_for_each_entry_safe(mesh_tx, tmp, &hdev->mesh_pending, list) {
|
|
if (!sk || mesh_tx->sk == sk)
|
|
cb(mesh_tx, data);
|
|
}
|
|
diff --git a/net/bluetooth/mgmt_util.h b/net/bluetooth/mgmt_util.h
|
|
index bdf978605d5a85..024e51dd693756 100644
|
|
--- a/net/bluetooth/mgmt_util.h
|
|
+++ b/net/bluetooth/mgmt_util.h
|
|
@@ -33,7 +33,7 @@ struct mgmt_mesh_tx {
|
|
struct mgmt_pending_cmd {
|
|
struct list_head list;
|
|
u16 opcode;
|
|
- int index;
|
|
+ struct hci_dev *hdev;
|
|
void *param;
|
|
size_t param_len;
|
|
struct sock *sk;
|
|
@@ -54,11 +54,7 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
|
|
|
|
struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode,
|
|
struct hci_dev *hdev);
|
|
-struct mgmt_pending_cmd *mgmt_pending_find_data(unsigned short channel,
|
|
- u16 opcode,
|
|
- struct hci_dev *hdev,
|
|
- const void *data);
|
|
-void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev,
|
|
+void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove,
|
|
void (*cb)(struct mgmt_pending_cmd *cmd, void *data),
|
|
void *data);
|
|
struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
|
|
diff --git a/net/bridge/netfilter/nf_conntrack_bridge.c b/net/bridge/netfilter/nf_conntrack_bridge.c
|
|
index 4fbfbafdfa0274..4b4a396d972259 100644
|
|
--- a/net/bridge/netfilter/nf_conntrack_bridge.c
|
|
+++ b/net/bridge/netfilter/nf_conntrack_bridge.c
|
|
@@ -60,19 +60,19 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk,
|
|
struct ip_fraglist_iter iter;
|
|
struct sk_buff *frag;
|
|
|
|
- if (first_len - hlen > mtu ||
|
|
- skb_headroom(skb) < ll_rs)
|
|
+ if (first_len - hlen > mtu)
|
|
goto blackhole;
|
|
|
|
- if (skb_cloned(skb))
|
|
+ if (skb_cloned(skb) ||
|
|
+ skb_headroom(skb) < ll_rs)
|
|
goto slow_path;
|
|
|
|
skb_walk_frags(skb, frag) {
|
|
- if (frag->len > mtu ||
|
|
- skb_headroom(frag) < hlen + ll_rs)
|
|
+ if (frag->len > mtu)
|
|
goto blackhole;
|
|
|
|
- if (skb_shared(frag))
|
|
+ if (skb_shared(frag) ||
|
|
+ skb_headroom(frag) < hlen + ll_rs)
|
|
goto slow_path;
|
|
}
|
|
|
|
diff --git a/net/core/skmsg.c b/net/core/skmsg.c
|
|
index b9b941c487c8a7..2076db464e9360 100644
|
|
--- a/net/core/skmsg.c
|
|
+++ b/net/core/skmsg.c
|
|
@@ -529,16 +529,22 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
|
|
u32 off, u32 len,
|
|
struct sk_psock *psock,
|
|
struct sock *sk,
|
|
- struct sk_msg *msg)
|
|
+ struct sk_msg *msg,
|
|
+ bool take_ref)
|
|
{
|
|
int num_sge, copied;
|
|
|
|
+ /* skb_to_sgvec will fail when the total number of fragments in
|
|
+ * frag_list and frags exceeds MAX_MSG_FRAGS. For example, the
|
|
+ * caller may aggregate multiple skbs.
|
|
+ */
|
|
num_sge = skb_to_sgvec(skb, msg->sg.data, off, len);
|
|
if (num_sge < 0) {
|
|
/* skb linearize may fail with ENOMEM, but lets simply try again
|
|
* later if this happens. Under memory pressure we don't want to
|
|
* drop the skb. We need to linearize the skb so that the mapping
|
|
* in skb_to_sgvec can not error.
|
|
+ * Note that skb_linearize requires the skb not to be shared.
|
|
*/
|
|
if (skb_linearize(skb))
|
|
return -EAGAIN;
|
|
@@ -555,7 +561,7 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
|
|
msg->sg.start = 0;
|
|
msg->sg.size = copied;
|
|
msg->sg.end = num_sge;
|
|
- msg->skb = skb;
|
|
+ msg->skb = take_ref ? skb_get(skb) : skb;
|
|
|
|
sk_psock_queue_msg(psock, msg);
|
|
sk_psock_data_ready(sk, psock);
|
|
@@ -563,7 +569,7 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
|
|
}
|
|
|
|
static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb,
|
|
- u32 off, u32 len);
|
|
+ u32 off, u32 len, bool take_ref);
|
|
|
|
static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
|
|
u32 off, u32 len)
|
|
@@ -577,7 +583,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
|
|
* correctly.
|
|
*/
|
|
if (unlikely(skb->sk == sk))
|
|
- return sk_psock_skb_ingress_self(psock, skb, off, len);
|
|
+ return sk_psock_skb_ingress_self(psock, skb, off, len, true);
|
|
msg = sk_psock_create_ingress_msg(sk, skb);
|
|
if (!msg)
|
|
return -EAGAIN;
|
|
@@ -589,7 +595,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
|
|
* into user buffers.
|
|
*/
|
|
skb_set_owner_r(skb, sk);
|
|
- err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg);
|
|
+ err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg, true);
|
|
if (err < 0)
|
|
kfree(msg);
|
|
return err;
|
|
@@ -600,7 +606,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
|
|
* because the skb is already accounted for here.
|
|
*/
|
|
static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb,
|
|
- u32 off, u32 len)
|
|
+ u32 off, u32 len, bool take_ref)
|
|
{
|
|
struct sk_msg *msg = alloc_sk_msg(GFP_ATOMIC);
|
|
struct sock *sk = psock->sk;
|
|
@@ -609,7 +615,7 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb
|
|
if (unlikely(!msg))
|
|
return -EAGAIN;
|
|
skb_set_owner_r(skb, sk);
|
|
- err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg);
|
|
+ err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg, take_ref);
|
|
if (err < 0)
|
|
kfree(msg);
|
|
return err;
|
|
@@ -618,18 +624,13 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb
|
|
static int sk_psock_handle_skb(struct sk_psock *psock, struct sk_buff *skb,
|
|
u32 off, u32 len, bool ingress)
|
|
{
|
|
- int err = 0;
|
|
-
|
|
if (!ingress) {
|
|
if (!sock_writeable(psock->sk))
|
|
return -EAGAIN;
|
|
return skb_send_sock(psock->sk, skb, off, len);
|
|
}
|
|
- skb_get(skb);
|
|
- err = sk_psock_skb_ingress(psock, skb, off, len);
|
|
- if (err < 0)
|
|
- kfree_skb(skb);
|
|
- return err;
|
|
+
|
|
+ return sk_psock_skb_ingress(psock, skb, off, len);
|
|
}
|
|
|
|
static void sk_psock_skb_state(struct sk_psock *psock,
|
|
@@ -654,12 +655,14 @@ static void sk_psock_backlog(struct work_struct *work)
|
|
bool ingress;
|
|
int ret;
|
|
|
|
+ /* Increment the psock refcnt to synchronize with close(fd) path in
|
|
+ * sock_map_close(), ensuring we wait for backlog thread completion
|
|
+ * before sk_socket freed. If refcnt increment fails, it indicates
|
|
+ * sock_map_close() completed with sk_socket potentially already freed.
|
|
+ */
|
|
+ if (!sk_psock_get(psock->sk))
|
|
+ return;
|
|
mutex_lock(&psock->work_mutex);
|
|
- if (unlikely(state->len)) {
|
|
- len = state->len;
|
|
- off = state->off;
|
|
- }
|
|
-
|
|
while ((skb = skb_peek(&psock->ingress_skb))) {
|
|
len = skb->len;
|
|
off = 0;
|
|
@@ -669,6 +672,13 @@ static void sk_psock_backlog(struct work_struct *work)
|
|
off = stm->offset;
|
|
len = stm->full_len;
|
|
}
|
|
+
|
|
+ /* Resume processing from previous partial state */
|
|
+ if (unlikely(state->len)) {
|
|
+ len = state->len;
|
|
+ off = state->off;
|
|
+ }
|
|
+
|
|
ingress = skb_bpf_ingress(skb);
|
|
skb_bpf_redirect_clear(skb);
|
|
do {
|
|
@@ -696,11 +706,14 @@ static void sk_psock_backlog(struct work_struct *work)
|
|
len -= ret;
|
|
} while (len);
|
|
|
|
+ /* The entire skb sent, clear state */
|
|
+ sk_psock_skb_state(psock, state, 0, 0);
|
|
skb = skb_dequeue(&psock->ingress_skb);
|
|
kfree_skb(skb);
|
|
}
|
|
end:
|
|
mutex_unlock(&psock->work_mutex);
|
|
+ sk_psock_put(psock->sk, psock);
|
|
}
|
|
|
|
struct sk_psock *sk_psock_init(struct sock *sk, int node)
|
|
@@ -1013,7 +1026,7 @@ static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb,
|
|
off = stm->offset;
|
|
len = stm->full_len;
|
|
}
|
|
- err = sk_psock_skb_ingress_self(psock, skb, off, len);
|
|
+ err = sk_psock_skb_ingress_self(psock, skb, off, len, false);
|
|
}
|
|
if (err < 0) {
|
|
spin_lock_bh(&psock->ingress_lock);
|
|
diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
|
|
index cacdafb41200e5..146c1dbd15a93f 100644
|
|
--- a/net/dsa/tag_brcm.c
|
|
+++ b/net/dsa/tag_brcm.c
|
|
@@ -257,7 +257,7 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
|
|
int source_port;
|
|
u8 *brcm_tag;
|
|
|
|
- if (unlikely(!pskb_may_pull(skb, BRCM_LEG_PORT_ID)))
|
|
+ if (unlikely(!pskb_may_pull(skb, BRCM_LEG_TAG_LEN + VLAN_HLEN)))
|
|
return NULL;
|
|
|
|
brcm_tag = dsa_etype_header_pos_rx(skb);
|
|
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
|
|
index 132cfc3b2c847b..3870b59f540048 100644
|
|
--- a/net/ipv4/udp_offload.c
|
|
+++ b/net/ipv4/udp_offload.c
|
|
@@ -332,6 +332,7 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
|
|
bool copy_dtor;
|
|
__sum16 check;
|
|
__be16 newlen;
|
|
+ int ret = 0;
|
|
|
|
mss = skb_shinfo(gso_skb)->gso_size;
|
|
if (gso_skb->len <= sizeof(*uh) + mss)
|
|
@@ -354,6 +355,10 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
|
|
if (skb_pagelen(gso_skb) - sizeof(*uh) == skb_shinfo(gso_skb)->gso_size)
|
|
return __udp_gso_segment_list(gso_skb, features, is_ipv6);
|
|
|
|
+ ret = __skb_linearize(gso_skb);
|
|
+ if (ret)
|
|
+ return ERR_PTR(ret);
|
|
+
|
|
/* Setup csum, as fraglist skips this in udp4_gro_receive. */
|
|
gso_skb->csum_start = skb_transport_header(gso_skb) - gso_skb->head;
|
|
gso_skb->csum_offset = offsetof(struct udphdr, check);
|
|
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
|
|
index 7c4af48d529e1e..606aae4e78a9a4 100644
|
|
--- a/net/ipv6/netfilter.c
|
|
+++ b/net/ipv6/netfilter.c
|
|
@@ -163,20 +163,20 @@ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
|
struct ip6_fraglist_iter iter;
|
|
struct sk_buff *frag2;
|
|
|
|
- if (first_len - hlen > mtu ||
|
|
- skb_headroom(skb) < (hroom + sizeof(struct frag_hdr)))
|
|
+ if (first_len - hlen > mtu)
|
|
goto blackhole;
|
|
|
|
- if (skb_cloned(skb))
|
|
+ if (skb_cloned(skb) ||
|
|
+ skb_headroom(skb) < (hroom + sizeof(struct frag_hdr)))
|
|
goto slow_path;
|
|
|
|
skb_walk_frags(skb, frag2) {
|
|
- if (frag2->len > mtu ||
|
|
- skb_headroom(frag2) < (hlen + hroom + sizeof(struct frag_hdr)))
|
|
+ if (frag2->len > mtu)
|
|
goto blackhole;
|
|
|
|
/* Partially cloned skb? */
|
|
- if (skb_shared(frag2))
|
|
+ if (skb_shared(frag2) ||
|
|
+ skb_headroom(frag2) < (hlen + hroom + sizeof(struct frag_hdr)))
|
|
goto slow_path;
|
|
}
|
|
|
|
diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c
|
|
index c9f1634b3838ae..a89ce0fbfe4b12 100644
|
|
--- a/net/ipv6/netfilter/nft_fib_ipv6.c
|
|
+++ b/net/ipv6/netfilter/nft_fib_ipv6.c
|
|
@@ -158,6 +158,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
|
|
{
|
|
const struct nft_fib *priv = nft_expr_priv(expr);
|
|
int noff = skb_network_offset(pkt->skb);
|
|
+ const struct net_device *found = NULL;
|
|
const struct net_device *oif = NULL;
|
|
u32 *dest = ®s->data[priv->dreg];
|
|
struct ipv6hdr *iph, _iph;
|
|
@@ -202,11 +203,15 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
|
|
if (rt->rt6i_flags & (RTF_REJECT | RTF_ANYCAST | RTF_LOCAL))
|
|
goto put_rt_err;
|
|
|
|
- if (oif && oif != rt->rt6i_idev->dev &&
|
|
- l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) != oif->ifindex)
|
|
- goto put_rt_err;
|
|
+ if (!oif) {
|
|
+ found = rt->rt6i_idev->dev;
|
|
+ } else {
|
|
+ if (oif == rt->rt6i_idev->dev ||
|
|
+ l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) == oif->ifindex)
|
|
+ found = oif;
|
|
+ }
|
|
|
|
- nft_fib_store_result(dest, priv, rt->rt6i_idev->dev);
|
|
+ nft_fib_store_result(dest, priv, found);
|
|
put_rt_err:
|
|
ip6_rt_put(rt);
|
|
}
|
|
diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
|
|
index c434940131b1d0..7f295b9c13744d 100644
|
|
--- a/net/ipv6/seg6_local.c
|
|
+++ b/net/ipv6/seg6_local.c
|
|
@@ -1638,10 +1638,8 @@ static const struct nla_policy seg6_local_policy[SEG6_LOCAL_MAX + 1] = {
|
|
[SEG6_LOCAL_SRH] = { .type = NLA_BINARY },
|
|
[SEG6_LOCAL_TABLE] = { .type = NLA_U32 },
|
|
[SEG6_LOCAL_VRFTABLE] = { .type = NLA_U32 },
|
|
- [SEG6_LOCAL_NH4] = { .type = NLA_BINARY,
|
|
- .len = sizeof(struct in_addr) },
|
|
- [SEG6_LOCAL_NH6] = { .type = NLA_BINARY,
|
|
- .len = sizeof(struct in6_addr) },
|
|
+ [SEG6_LOCAL_NH4] = NLA_POLICY_EXACT_LEN(sizeof(struct in_addr)),
|
|
+ [SEG6_LOCAL_NH6] = NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
|
|
[SEG6_LOCAL_IIF] = { .type = NLA_U32 },
|
|
[SEG6_LOCAL_OIF] = { .type = NLA_U32 },
|
|
[SEG6_LOCAL_BPF] = { .type = NLA_NESTED },
|
|
diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h
|
|
index 4e0842df5234ea..2c260f33b55cc5 100644
|
|
--- a/net/ncsi/internal.h
|
|
+++ b/net/ncsi/internal.h
|
|
@@ -143,16 +143,15 @@ struct ncsi_channel_vlan_filter {
|
|
};
|
|
|
|
struct ncsi_channel_stats {
|
|
- u32 hnc_cnt_hi; /* Counter cleared */
|
|
- u32 hnc_cnt_lo; /* Counter cleared */
|
|
- u32 hnc_rx_bytes; /* Rx bytes */
|
|
- u32 hnc_tx_bytes; /* Tx bytes */
|
|
- u32 hnc_rx_uc_pkts; /* Rx UC packets */
|
|
- u32 hnc_rx_mc_pkts; /* Rx MC packets */
|
|
- u32 hnc_rx_bc_pkts; /* Rx BC packets */
|
|
- u32 hnc_tx_uc_pkts; /* Tx UC packets */
|
|
- u32 hnc_tx_mc_pkts; /* Tx MC packets */
|
|
- u32 hnc_tx_bc_pkts; /* Tx BC packets */
|
|
+ u64 hnc_cnt; /* Counter cleared */
|
|
+ u64 hnc_rx_bytes; /* Rx bytes */
|
|
+ u64 hnc_tx_bytes; /* Tx bytes */
|
|
+ u64 hnc_rx_uc_pkts; /* Rx UC packets */
|
|
+ u64 hnc_rx_mc_pkts; /* Rx MC packets */
|
|
+ u64 hnc_rx_bc_pkts; /* Rx BC packets */
|
|
+ u64 hnc_tx_uc_pkts; /* Tx UC packets */
|
|
+ u64 hnc_tx_mc_pkts; /* Tx MC packets */
|
|
+ u64 hnc_tx_bc_pkts; /* Tx BC packets */
|
|
u32 hnc_fcs_err; /* FCS errors */
|
|
u32 hnc_align_err; /* Alignment errors */
|
|
u32 hnc_false_carrier; /* False carrier detection */
|
|
@@ -181,7 +180,7 @@ struct ncsi_channel_stats {
|
|
u32 hnc_tx_1023_frames; /* Tx 512-1023 bytes frames */
|
|
u32 hnc_tx_1522_frames; /* Tx 1024-1522 bytes frames */
|
|
u32 hnc_tx_9022_frames; /* Tx 1523-9022 bytes frames */
|
|
- u32 hnc_rx_valid_bytes; /* Rx valid bytes */
|
|
+ u64 hnc_rx_valid_bytes; /* Rx valid bytes */
|
|
u32 hnc_rx_runt_pkts; /* Rx error runt packets */
|
|
u32 hnc_rx_jabber_pkts; /* Rx error jabber packets */
|
|
u32 ncsi_rx_cmds; /* Rx NCSI commands */
|
|
diff --git a/net/ncsi/ncsi-pkt.h b/net/ncsi/ncsi-pkt.h
|
|
index f2f3b5c1b94126..24edb273797240 100644
|
|
--- a/net/ncsi/ncsi-pkt.h
|
|
+++ b/net/ncsi/ncsi-pkt.h
|
|
@@ -252,16 +252,15 @@ struct ncsi_rsp_gp_pkt {
|
|
/* Get Controller Packet Statistics */
|
|
struct ncsi_rsp_gcps_pkt {
|
|
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
|
|
- __be32 cnt_hi; /* Counter cleared */
|
|
- __be32 cnt_lo; /* Counter cleared */
|
|
- __be32 rx_bytes; /* Rx bytes */
|
|
- __be32 tx_bytes; /* Tx bytes */
|
|
- __be32 rx_uc_pkts; /* Rx UC packets */
|
|
- __be32 rx_mc_pkts; /* Rx MC packets */
|
|
- __be32 rx_bc_pkts; /* Rx BC packets */
|
|
- __be32 tx_uc_pkts; /* Tx UC packets */
|
|
- __be32 tx_mc_pkts; /* Tx MC packets */
|
|
- __be32 tx_bc_pkts; /* Tx BC packets */
|
|
+ __be64 cnt; /* Counter cleared */
|
|
+ __be64 rx_bytes; /* Rx bytes */
|
|
+ __be64 tx_bytes; /* Tx bytes */
|
|
+ __be64 rx_uc_pkts; /* Rx UC packets */
|
|
+ __be64 rx_mc_pkts; /* Rx MC packets */
|
|
+ __be64 rx_bc_pkts; /* Rx BC packets */
|
|
+ __be64 tx_uc_pkts; /* Tx UC packets */
|
|
+ __be64 tx_mc_pkts; /* Tx MC packets */
|
|
+ __be64 tx_bc_pkts; /* Tx BC packets */
|
|
__be32 fcs_err; /* FCS errors */
|
|
__be32 align_err; /* Alignment errors */
|
|
__be32 false_carrier; /* False carrier detection */
|
|
@@ -290,11 +289,11 @@ struct ncsi_rsp_gcps_pkt {
|
|
__be32 tx_1023_frames; /* Tx 512-1023 bytes frames */
|
|
__be32 tx_1522_frames; /* Tx 1024-1522 bytes frames */
|
|
__be32 tx_9022_frames; /* Tx 1523-9022 bytes frames */
|
|
- __be32 rx_valid_bytes; /* Rx valid bytes */
|
|
+ __be64 rx_valid_bytes; /* Rx valid bytes */
|
|
__be32 rx_runt_pkts; /* Rx error runt packets */
|
|
__be32 rx_jabber_pkts; /* Rx error jabber packets */
|
|
__be32 checksum; /* Checksum */
|
|
-};
|
|
+} __packed __aligned(4);
|
|
|
|
/* Get NCSI Statistics */
|
|
struct ncsi_rsp_gns_pkt {
|
|
diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
|
|
index 4a8ce2949faeac..8668888c5a2f99 100644
|
|
--- a/net/ncsi/ncsi-rsp.c
|
|
+++ b/net/ncsi/ncsi-rsp.c
|
|
@@ -926,16 +926,15 @@ static int ncsi_rsp_handler_gcps(struct ncsi_request *nr)
|
|
|
|
/* Update HNC's statistics */
|
|
ncs = &nc->stats;
|
|
- ncs->hnc_cnt_hi = ntohl(rsp->cnt_hi);
|
|
- ncs->hnc_cnt_lo = ntohl(rsp->cnt_lo);
|
|
- ncs->hnc_rx_bytes = ntohl(rsp->rx_bytes);
|
|
- ncs->hnc_tx_bytes = ntohl(rsp->tx_bytes);
|
|
- ncs->hnc_rx_uc_pkts = ntohl(rsp->rx_uc_pkts);
|
|
- ncs->hnc_rx_mc_pkts = ntohl(rsp->rx_mc_pkts);
|
|
- ncs->hnc_rx_bc_pkts = ntohl(rsp->rx_bc_pkts);
|
|
- ncs->hnc_tx_uc_pkts = ntohl(rsp->tx_uc_pkts);
|
|
- ncs->hnc_tx_mc_pkts = ntohl(rsp->tx_mc_pkts);
|
|
- ncs->hnc_tx_bc_pkts = ntohl(rsp->tx_bc_pkts);
|
|
+ ncs->hnc_cnt = be64_to_cpu(rsp->cnt);
|
|
+ ncs->hnc_rx_bytes = be64_to_cpu(rsp->rx_bytes);
|
|
+ ncs->hnc_tx_bytes = be64_to_cpu(rsp->tx_bytes);
|
|
+ ncs->hnc_rx_uc_pkts = be64_to_cpu(rsp->rx_uc_pkts);
|
|
+ ncs->hnc_rx_mc_pkts = be64_to_cpu(rsp->rx_mc_pkts);
|
|
+ ncs->hnc_rx_bc_pkts = be64_to_cpu(rsp->rx_bc_pkts);
|
|
+ ncs->hnc_tx_uc_pkts = be64_to_cpu(rsp->tx_uc_pkts);
|
|
+ ncs->hnc_tx_mc_pkts = be64_to_cpu(rsp->tx_mc_pkts);
|
|
+ ncs->hnc_tx_bc_pkts = be64_to_cpu(rsp->tx_bc_pkts);
|
|
ncs->hnc_fcs_err = ntohl(rsp->fcs_err);
|
|
ncs->hnc_align_err = ntohl(rsp->align_err);
|
|
ncs->hnc_false_carrier = ntohl(rsp->false_carrier);
|
|
@@ -964,7 +963,7 @@ static int ncsi_rsp_handler_gcps(struct ncsi_request *nr)
|
|
ncs->hnc_tx_1023_frames = ntohl(rsp->tx_1023_frames);
|
|
ncs->hnc_tx_1522_frames = ntohl(rsp->tx_1522_frames);
|
|
ncs->hnc_tx_9022_frames = ntohl(rsp->tx_9022_frames);
|
|
- ncs->hnc_rx_valid_bytes = ntohl(rsp->rx_valid_bytes);
|
|
+ ncs->hnc_rx_valid_bytes = be64_to_cpu(rsp->rx_valid_bytes);
|
|
ncs->hnc_rx_runt_pkts = ntohl(rsp->rx_runt_pkts);
|
|
ncs->hnc_rx_jabber_pkts = ntohl(rsp->rx_jabber_pkts);
|
|
|
|
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
|
|
index ccca6e3848bcc8..9df883d79acc92 100644
|
|
--- a/net/netfilter/nf_nat_core.c
|
|
+++ b/net/netfilter/nf_nat_core.c
|
|
@@ -248,7 +248,7 @@ static noinline bool
|
|
nf_nat_used_tuple_new(const struct nf_conntrack_tuple *tuple,
|
|
const struct nf_conn *ignored_ct)
|
|
{
|
|
- static const unsigned long uses_nat = IPS_NAT_MASK | IPS_SEQ_ADJUST_BIT;
|
|
+ static const unsigned long uses_nat = IPS_NAT_MASK | IPS_SEQ_ADJUST;
|
|
const struct nf_conntrack_tuple_hash *thash;
|
|
const struct nf_conntrack_zone *zone;
|
|
struct nf_conn *ct;
|
|
@@ -287,8 +287,14 @@ nf_nat_used_tuple_new(const struct nf_conntrack_tuple *tuple,
|
|
zone = nf_ct_zone(ignored_ct);
|
|
|
|
thash = nf_conntrack_find_get(net, zone, tuple);
|
|
- if (unlikely(!thash)) /* clashing entry went away */
|
|
- return false;
|
|
+ if (unlikely(!thash)) {
|
|
+ struct nf_conntrack_tuple reply;
|
|
+
|
|
+ nf_ct_invert_tuple(&reply, tuple);
|
|
+ thash = nf_conntrack_find_get(net, zone, &reply);
|
|
+ if (!thash) /* clashing entry went away */
|
|
+ return false;
|
|
+ }
|
|
|
|
ct = nf_ct_tuplehash_to_ctrack(thash);
|
|
|
|
diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c
|
|
index 9b2d7463d3d326..df0798da2329b9 100644
|
|
--- a/net/netfilter/nft_quota.c
|
|
+++ b/net/netfilter/nft_quota.c
|
|
@@ -19,10 +19,16 @@ struct nft_quota {
|
|
};
|
|
|
|
static inline bool nft_overquota(struct nft_quota *priv,
|
|
- const struct sk_buff *skb)
|
|
+ const struct sk_buff *skb,
|
|
+ bool *report)
|
|
{
|
|
- return atomic64_add_return(skb->len, priv->consumed) >=
|
|
- atomic64_read(&priv->quota);
|
|
+ u64 consumed = atomic64_add_return(skb->len, priv->consumed);
|
|
+ u64 quota = atomic64_read(&priv->quota);
|
|
+
|
|
+ if (report)
|
|
+ *report = consumed >= quota;
|
|
+
|
|
+ return consumed > quota;
|
|
}
|
|
|
|
static inline bool nft_quota_invert(struct nft_quota *priv)
|
|
@@ -34,7 +40,7 @@ static inline void nft_quota_do_eval(struct nft_quota *priv,
|
|
struct nft_regs *regs,
|
|
const struct nft_pktinfo *pkt)
|
|
{
|
|
- if (nft_overquota(priv, pkt->skb) ^ nft_quota_invert(priv))
|
|
+ if (nft_overquota(priv, pkt->skb, NULL) ^ nft_quota_invert(priv))
|
|
regs->verdict.code = NFT_BREAK;
|
|
}
|
|
|
|
@@ -51,13 +57,13 @@ static void nft_quota_obj_eval(struct nft_object *obj,
|
|
const struct nft_pktinfo *pkt)
|
|
{
|
|
struct nft_quota *priv = nft_obj_data(obj);
|
|
- bool overquota;
|
|
+ bool overquota, report;
|
|
|
|
- overquota = nft_overquota(priv, pkt->skb);
|
|
+ overquota = nft_overquota(priv, pkt->skb, &report);
|
|
if (overquota ^ nft_quota_invert(priv))
|
|
regs->verdict.code = NFT_BREAK;
|
|
|
|
- if (overquota &&
|
|
+ if (report &&
|
|
!test_and_set_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags))
|
|
nft_obj_notify(nft_net(pkt), obj->key.table, obj, 0, 0,
|
|
NFT_MSG_NEWOBJ, 0, nft_pf(pkt), 0, GFP_ATOMIC);
|
|
diff --git a/net/netfilter/nft_set_pipapo_avx2.c b/net/netfilter/nft_set_pipapo_avx2.c
|
|
index c15db28c5ebc43..be7c16c79f711e 100644
|
|
--- a/net/netfilter/nft_set_pipapo_avx2.c
|
|
+++ b/net/netfilter/nft_set_pipapo_avx2.c
|
|
@@ -1113,6 +1113,25 @@ bool nft_pipapo_avx2_estimate(const struct nft_set_desc *desc, u32 features,
|
|
return true;
|
|
}
|
|
|
|
+/**
|
|
+ * pipapo_resmap_init_avx2() - Initialise result map before first use
|
|
+ * @m: Matching data, including mapping table
|
|
+ * @res_map: Result map
|
|
+ *
|
|
+ * Like pipapo_resmap_init() but do not set start map bits covered by the first field.
|
|
+ */
|
|
+static inline void pipapo_resmap_init_avx2(const struct nft_pipapo_match *m, unsigned long *res_map)
|
|
+{
|
|
+ const struct nft_pipapo_field *f = m->f;
|
|
+ int i;
|
|
+
|
|
+ /* Starting map doesn't need to be set to all-ones for this implementation,
|
|
+ * but we do need to zero the remaining bits, if any.
|
|
+ */
|
|
+ for (i = f->bsize; i < m->bsize_max; i++)
|
|
+ res_map[i] = 0ul;
|
|
+}
|
|
+
|
|
/**
|
|
* nft_pipapo_avx2_lookup() - Lookup function for AVX2 implementation
|
|
* @net: Network namespace
|
|
@@ -1171,7 +1190,7 @@ bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set,
|
|
res = scratch->map + (map_index ? m->bsize_max : 0);
|
|
fill = scratch->map + (map_index ? 0 : m->bsize_max);
|
|
|
|
- /* Starting map doesn't need to be set for this implementation */
|
|
+ pipapo_resmap_init_avx2(m, res);
|
|
|
|
nft_pipapo_avx2_prepare();
|
|
|
|
diff --git a/net/netfilter/nft_tunnel.c b/net/netfilter/nft_tunnel.c
|
|
index d499eb3f4f2978..3e3ae29dde3359 100644
|
|
--- a/net/netfilter/nft_tunnel.c
|
|
+++ b/net/netfilter/nft_tunnel.c
|
|
@@ -617,10 +617,10 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb,
|
|
struct geneve_opt *opt;
|
|
int offset = 0;
|
|
|
|
- inner = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS_GENEVE);
|
|
- if (!inner)
|
|
- goto failure;
|
|
while (opts->len > offset) {
|
|
+ inner = nla_nest_start_noflag(skb, NFTA_TUNNEL_KEY_OPTS_GENEVE);
|
|
+ if (!inner)
|
|
+ goto failure;
|
|
opt = (struct geneve_opt *)(opts->u.data + offset);
|
|
if (nla_put_be16(skb, NFTA_TUNNEL_KEY_GENEVE_CLASS,
|
|
opt->opt_class) ||
|
|
@@ -630,8 +630,8 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb,
|
|
opt->length * 4, opt->opt_data))
|
|
goto inner_failure;
|
|
offset += sizeof(*opt) + opt->length * 4;
|
|
+ nla_nest_end(skb, inner);
|
|
}
|
|
- nla_nest_end(skb, inner);
|
|
}
|
|
nla_nest_end(skb, nest);
|
|
return 0;
|
|
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
|
|
index 27511c90a26f40..daef0eeaea2c7a 100644
|
|
--- a/net/netlabel/netlabel_kapi.c
|
|
+++ b/net/netlabel/netlabel_kapi.c
|
|
@@ -1140,6 +1140,11 @@ int netlbl_conn_setattr(struct sock *sk,
|
|
break;
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
case AF_INET6:
|
|
+ if (sk->sk_family != AF_INET6) {
|
|
+ ret_val = -EAFNOSUPPORT;
|
|
+ goto conn_setattr_return;
|
|
+ }
|
|
+
|
|
addr6 = (struct sockaddr_in6 *)addr;
|
|
entry = netlbl_domhsh_getentry_af6(secattr->domain,
|
|
&addr6->sin6_addr);
|
|
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
|
|
index 8a848ce72e2910..b80bd3a9077397 100644
|
|
--- a/net/openvswitch/flow.c
|
|
+++ b/net/openvswitch/flow.c
|
|
@@ -788,7 +788,7 @@ static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key)
|
|
memset(&key->ipv4, 0, sizeof(key->ipv4));
|
|
}
|
|
} else if (eth_p_mpls(key->eth.type)) {
|
|
- u8 label_count = 1;
|
|
+ size_t label_count = 1;
|
|
|
|
memset(&key->mpls, 0, sizeof(key->mpls));
|
|
skb_set_inner_network_header(skb, skb->mac_len);
|
|
diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
|
|
index 9da86db4d2c2fe..3ee46f6e005da0 100644
|
|
--- a/net/sched/sch_ets.c
|
|
+++ b/net/sched/sch_ets.c
|
|
@@ -661,7 +661,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
|
|
for (i = q->nbands; i < oldbands; i++) {
|
|
if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
|
|
list_del_init(&q->classes[i].alist);
|
|
- qdisc_tree_flush_backlog(q->classes[i].qdisc);
|
|
+ qdisc_purge_queue(q->classes[i].qdisc);
|
|
}
|
|
q->nstrict = nstrict;
|
|
memcpy(q->prio2band, priomap, sizeof(priomap));
|
|
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
|
|
index fdc5ef52c3ee92..fdd9caa41e80fb 100644
|
|
--- a/net/sched/sch_prio.c
|
|
+++ b/net/sched/sch_prio.c
|
|
@@ -211,7 +211,7 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt,
|
|
memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1);
|
|
|
|
for (i = q->bands; i < oldbands; i++)
|
|
- qdisc_tree_flush_backlog(q->queues[i]);
|
|
+ qdisc_purge_queue(q->queues[i]);
|
|
|
|
for (i = oldbands; i < q->bands; i++) {
|
|
q->queues[i] = queues[i];
|
|
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
|
|
index 16277b6a0238da..3c6b4460cf2c0c 100644
|
|
--- a/net/sched/sch_red.c
|
|
+++ b/net/sched/sch_red.c
|
|
@@ -283,7 +283,7 @@ static int __red_change(struct Qdisc *sch, struct nlattr **tb,
|
|
q->userbits = userbits;
|
|
q->limit = ctl->limit;
|
|
if (child) {
|
|
- qdisc_tree_flush_backlog(q->qdisc);
|
|
+ qdisc_purge_queue(q->qdisc);
|
|
old_child = q->qdisc;
|
|
q->qdisc = child;
|
|
}
|
|
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
|
|
index 002941d35b643c..d564675a8be4d7 100644
|
|
--- a/net/sched/sch_sfq.c
|
|
+++ b/net/sched/sch_sfq.c
|
|
@@ -310,7 +310,10 @@ static unsigned int sfq_drop(struct Qdisc *sch, struct sk_buff **to_free)
|
|
/* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */
|
|
x = q->tail->next;
|
|
slot = &q->slots[x];
|
|
- q->tail->next = slot->next;
|
|
+ if (slot->next == x)
|
|
+ q->tail = NULL; /* no more active slots */
|
|
+ else
|
|
+ q->tail->next = slot->next;
|
|
q->ht[slot->hash] = SFQ_EMPTY_SLOT;
|
|
goto drop;
|
|
}
|
|
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
|
|
index f92174008499bb..61dd5c8f23101d 100644
|
|
--- a/net/sched/sch_tbf.c
|
|
+++ b/net/sched/sch_tbf.c
|
|
@@ -452,7 +452,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
|
|
|
|
sch_tree_lock(sch);
|
|
if (child) {
|
|
- qdisc_tree_flush_backlog(q->qdisc);
|
|
+ qdisc_purge_queue(q->qdisc);
|
|
old = q->qdisc;
|
|
q->qdisc = child;
|
|
}
|
|
diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c
|
|
index 8584893b478510..79f91b6ca8c847 100644
|
|
--- a/net/tipc/crypto.c
|
|
+++ b/net/tipc/crypto.c
|
|
@@ -818,7 +818,11 @@ static int tipc_aead_encrypt(struct tipc_aead *aead, struct sk_buff *skb,
|
|
}
|
|
|
|
/* Get net to avoid freed tipc_crypto when delete namespace */
|
|
- get_net(aead->crypto->net);
|
|
+ if (!maybe_get_net(aead->crypto->net)) {
|
|
+ tipc_bearer_put(b);
|
|
+ rc = -ENODEV;
|
|
+ goto exit;
|
|
+ }
|
|
|
|
/* Now, do encrypt */
|
|
rc = crypto_aead_encrypt(req);
|
|
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
|
|
index 6e30fe879d538e..4a9a3aed5d6d41 100644
|
|
--- a/net/tls/tls_sw.c
|
|
+++ b/net/tls/tls_sw.c
|
|
@@ -908,6 +908,13 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk,
|
|
&msg_redir, send, flags);
|
|
lock_sock(sk);
|
|
if (err < 0) {
|
|
+ /* Regardless of whether the data represented by
|
|
+ * msg_redir is sent successfully, we have already
|
|
+ * uncharged it via sk_msg_return_zero(). The
|
|
+ * msg->sg.size represents the remaining unprocessed
|
|
+ * data, which needs to be uncharged here.
|
|
+ */
|
|
+ sk_mem_uncharge(sk, msg->sg.size);
|
|
*copied -= sk_msg_free_nocharge(sk, &msg_redir);
|
|
msg->sg.size = 0;
|
|
}
|
|
@@ -1120,9 +1127,13 @@ static int tls_sw_sendmsg_locked(struct sock *sk, struct msghdr *msg,
|
|
num_async++;
|
|
else if (ret == -ENOMEM)
|
|
goto wait_for_memory;
|
|
- else if (ctx->open_rec && ret == -ENOSPC)
|
|
+ else if (ctx->open_rec && ret == -ENOSPC) {
|
|
+ if (msg_pl->cork_bytes) {
|
|
+ ret = 0;
|
|
+ goto send_end;
|
|
+ }
|
|
goto rollback_iter;
|
|
- else if (ret != -EAGAIN)
|
|
+ } else if (ret != -EAGAIN)
|
|
goto send_end;
|
|
}
|
|
continue;
|
|
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
|
|
index 04dc0c8a837076..7188d3592dde4e 100644
|
|
--- a/net/xfrm/xfrm_device.c
|
|
+++ b/net/xfrm/xfrm_device.c
|
|
@@ -371,7 +371,6 @@ int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp,
|
|
|
|
xdo->dev = dev;
|
|
netdev_tracker_alloc(dev, &xdo->dev_tracker, GFP_ATOMIC);
|
|
- xdo->real_dev = dev;
|
|
xdo->type = XFRM_DEV_OFFLOAD_PACKET;
|
|
switch (dir) {
|
|
case XFRM_POLICY_IN:
|
|
@@ -393,7 +392,6 @@ int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp,
|
|
err = dev->xfrmdev_ops->xdo_dev_policy_add(xp, extack);
|
|
if (err) {
|
|
xdo->dev = NULL;
|
|
- xdo->real_dev = NULL;
|
|
xdo->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
|
|
xdo->dir = 0;
|
|
netdev_put(dev, &xdo->dev_tracker);
|
|
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
|
|
index 86029cf5358c7a..d2bd5bddfb05d8 100644
|
|
--- a/net/xfrm/xfrm_state.c
|
|
+++ b/net/xfrm/xfrm_state.c
|
|
@@ -1326,7 +1326,6 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
|
|
xso->type = XFRM_DEV_OFFLOAD_PACKET;
|
|
xso->dir = xdo->dir;
|
|
xso->dev = xdo->dev;
|
|
- xso->real_dev = xdo->real_dev;
|
|
xso->flags = XFRM_DEV_OFFLOAD_FLAG_ACQ;
|
|
netdev_hold(xso->dev, &xso->dev_tracker, GFP_ATOMIC);
|
|
error = xso->dev->xfrmdev_ops->xdo_dev_state_add(x, NULL);
|
|
@@ -1334,7 +1333,6 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
|
|
xso->dir = 0;
|
|
netdev_put(xso->dev, &xso->dev_tracker);
|
|
xso->dev = NULL;
|
|
- xso->real_dev = NULL;
|
|
xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
|
|
x->km.state = XFRM_STATE_DEAD;
|
|
to_put = x;
|
|
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
|
|
index 0ea3281a92e1eb..570f64e2ddf107 100644
|
|
--- a/scripts/Makefile.extrawarn
|
|
+++ b/scripts/Makefile.extrawarn
|
|
@@ -29,6 +29,18 @@ KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds
|
|
ifdef CONFIG_CC_IS_CLANG
|
|
# The kernel builds with '-std=gnu11' so use of GNU extensions is acceptable.
|
|
KBUILD_CFLAGS += -Wno-gnu
|
|
+
|
|
+# Clang may emit a warning when a const variable, such as the dummy variables
|
|
+# in typecheck(), or const member of an aggregate type are not initialized,
|
|
+# which can result in unexpected behavior. However, in many audited cases of
|
|
+# the "field" variant of the warning, this is intentional because the field is
|
|
+# never used within a particular call path, the field is within a union with
|
|
+# other non-const members, or the containing object is not const so the field
|
|
+# can be modified via memcpy() / memset(). While the variable warning also gets
|
|
+# disabled with this same switch, there should not be too much coverage lost
|
|
+# because -Wuninitialized will still flag when an uninitialized const variable
|
|
+# is used.
|
|
+KBUILD_CFLAGS += $(call cc-disable-warning, default-const-init-unsafe)
|
|
else
|
|
|
|
# gcc inanely warns about local variables called 'main'
|
|
diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h
|
|
index 1ae39b9f4a95ef..90e83d62adb547 100644
|
|
--- a/scripts/gcc-plugins/gcc-common.h
|
|
+++ b/scripts/gcc-plugins/gcc-common.h
|
|
@@ -128,6 +128,38 @@ static inline tree build_const_char_string(int len, const char *str)
|
|
return cstr;
|
|
}
|
|
|
|
+static inline void __add_type_attr(tree type, const char *attr, tree args)
|
|
+{
|
|
+ tree oldattr;
|
|
+
|
|
+ if (type == NULL_TREE)
|
|
+ return;
|
|
+ oldattr = lookup_attribute(attr, TYPE_ATTRIBUTES(type));
|
|
+ if (oldattr != NULL_TREE) {
|
|
+ gcc_assert(TREE_VALUE(oldattr) == args || TREE_VALUE(TREE_VALUE(oldattr)) == TREE_VALUE(args));
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
|
|
+ TYPE_ATTRIBUTES(type) = tree_cons(get_identifier(attr), args, TYPE_ATTRIBUTES(type));
|
|
+}
|
|
+
|
|
+static inline void add_type_attr(tree type, const char *attr, tree args)
|
|
+{
|
|
+ tree main_variant = TYPE_MAIN_VARIANT(type);
|
|
+
|
|
+ __add_type_attr(TYPE_CANONICAL(type), attr, args);
|
|
+ __add_type_attr(TYPE_CANONICAL(main_variant), attr, args);
|
|
+ __add_type_attr(main_variant, attr, args);
|
|
+
|
|
+ for (type = TYPE_NEXT_VARIANT(main_variant); type; type = TYPE_NEXT_VARIANT(type)) {
|
|
+ if (!lookup_attribute(attr, TYPE_ATTRIBUTES(type)))
|
|
+ TYPE_ATTRIBUTES(type) = TYPE_ATTRIBUTES(main_variant);
|
|
+
|
|
+ __add_type_attr(TYPE_CANONICAL(type), attr, args);
|
|
+ }
|
|
+}
|
|
+
|
|
#define PASS_INFO(NAME, REF, ID, POS) \
|
|
struct register_pass_info NAME##_pass_info = { \
|
|
.pass = make_##NAME##_pass(), \
|
|
diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c
|
|
index 746ff2d272f256..e70eef049ada66 100644
|
|
--- a/scripts/gcc-plugins/randomize_layout_plugin.c
|
|
+++ b/scripts/gcc-plugins/randomize_layout_plugin.c
|
|
@@ -77,6 +77,9 @@ static tree handle_randomize_layout_attr(tree *node, tree name, tree args, int f
|
|
|
|
if (TYPE_P(*node)) {
|
|
type = *node;
|
|
+ } else if (TREE_CODE(*node) == FIELD_DECL) {
|
|
+ *no_add_attrs = false;
|
|
+ return NULL_TREE;
|
|
} else {
|
|
gcc_assert(TREE_CODE(*node) == TYPE_DECL);
|
|
type = TREE_TYPE(*node);
|
|
@@ -348,35 +351,18 @@ static int relayout_struct(tree type)
|
|
|
|
shuffle(type, (tree *)newtree, shuffle_length);
|
|
|
|
- /*
|
|
- * set up a bogus anonymous struct field designed to error out on unnamed struct initializers
|
|
- * as gcc provides no other way to detect such code
|
|
- */
|
|
- list = make_node(FIELD_DECL);
|
|
- TREE_CHAIN(list) = newtree[0];
|
|
- TREE_TYPE(list) = void_type_node;
|
|
- DECL_SIZE(list) = bitsize_zero_node;
|
|
- DECL_NONADDRESSABLE_P(list) = 1;
|
|
- DECL_FIELD_BIT_OFFSET(list) = bitsize_zero_node;
|
|
- DECL_SIZE_UNIT(list) = size_zero_node;
|
|
- DECL_FIELD_OFFSET(list) = size_zero_node;
|
|
- DECL_CONTEXT(list) = type;
|
|
- // to satisfy the constify plugin
|
|
- TREE_READONLY(list) = 1;
|
|
-
|
|
for (i = 0; i < num_fields - 1; i++)
|
|
TREE_CHAIN(newtree[i]) = newtree[i+1];
|
|
TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE;
|
|
|
|
+ add_type_attr(type, "randomize_performed", NULL_TREE);
|
|
+ add_type_attr(type, "designated_init", NULL_TREE);
|
|
+ if (has_flexarray)
|
|
+ add_type_attr(type, "has_flexarray", NULL_TREE);
|
|
+
|
|
main_variant = TYPE_MAIN_VARIANT(type);
|
|
- for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) {
|
|
- TYPE_FIELDS(variant) = list;
|
|
- TYPE_ATTRIBUTES(variant) = copy_list(TYPE_ATTRIBUTES(variant));
|
|
- TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("randomize_performed"), NULL_TREE, TYPE_ATTRIBUTES(variant));
|
|
- TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("designated_init"), NULL_TREE, TYPE_ATTRIBUTES(variant));
|
|
- if (has_flexarray)
|
|
- TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("has_flexarray"), NULL_TREE, TYPE_ATTRIBUTES(type));
|
|
- }
|
|
+ for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant))
|
|
+ TYPE_FIELDS(variant) = newtree[0];
|
|
|
|
/*
|
|
* force a re-layout of the main variant
|
|
@@ -444,10 +430,8 @@ static void randomize_type(tree type)
|
|
if (lookup_attribute("randomize_layout", TYPE_ATTRIBUTES(TYPE_MAIN_VARIANT(type))) || is_pure_ops_struct(type))
|
|
relayout_struct(type);
|
|
|
|
- for (variant = TYPE_MAIN_VARIANT(type); variant; variant = TYPE_NEXT_VARIANT(variant)) {
|
|
- TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
|
|
- TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("randomize_considered"), NULL_TREE, TYPE_ATTRIBUTES(type));
|
|
- }
|
|
+ add_type_attr(type, "randomize_considered", NULL_TREE);
|
|
+
|
|
#ifdef __DEBUG_PLUGIN
|
|
fprintf(stderr, "Marking randomize_considered on struct %s\n", ORIG_TYPE_NAME(type));
|
|
#ifdef __DEBUG_VERBOSE
|
|
diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
|
|
index ce77934f3eef31..0e96caa607fb8c 100644
|
|
--- a/sound/soc/apple/mca.c
|
|
+++ b/sound/soc/apple/mca.c
|
|
@@ -464,6 +464,28 @@ static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit,
|
|
return -EINVAL;
|
|
}
|
|
|
|
+static int mca_fe_startup(struct snd_pcm_substream *substream,
|
|
+ struct snd_soc_dai *dai)
|
|
+{
|
|
+ struct mca_cluster *cl = mca_dai_to_cluster(dai);
|
|
+ unsigned int mask, nchannels;
|
|
+
|
|
+ if (cl->tdm_slots) {
|
|
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
|
+ mask = cl->tdm_tx_mask;
|
|
+ else
|
|
+ mask = cl->tdm_rx_mask;
|
|
+
|
|
+ nchannels = hweight32(mask);
|
|
+ } else {
|
|
+ nchannels = 2;
|
|
+ }
|
|
+
|
|
+ return snd_pcm_hw_constraint_minmax(substream->runtime,
|
|
+ SNDRV_PCM_HW_PARAM_CHANNELS,
|
|
+ 1, nchannels);
|
|
+}
|
|
+
|
|
static int mca_fe_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
|
|
unsigned int rx_mask, int slots, int slot_width)
|
|
{
|
|
@@ -680,6 +702,7 @@ static int mca_fe_hw_params(struct snd_pcm_substream *substream,
|
|
}
|
|
|
|
static const struct snd_soc_dai_ops mca_fe_ops = {
|
|
+ .startup = mca_fe_startup,
|
|
.set_fmt = mca_fe_set_fmt,
|
|
.set_bclk_ratio = mca_set_bclk_ratio,
|
|
.set_tdm_slot = mca_fe_set_tdm_slot,
|
|
diff --git a/sound/soc/codecs/hda.c b/sound/soc/codecs/hda.c
|
|
index d57b043d6bfefe..42aca0a63c441e 100644
|
|
--- a/sound/soc/codecs/hda.c
|
|
+++ b/sound/soc/codecs/hda.c
|
|
@@ -150,7 +150,7 @@ int hda_codec_probe_complete(struct hda_codec *codec)
|
|
ret = snd_hda_codec_build_controls(codec);
|
|
if (ret < 0) {
|
|
dev_err(&hdev->dev, "unable to create controls %d\n", ret);
|
|
- goto out;
|
|
+ return ret;
|
|
}
|
|
|
|
/* Bus suspended codecs as it does not manage their pm */
|
|
@@ -158,7 +158,7 @@ int hda_codec_probe_complete(struct hda_codec *codec)
|
|
/* rpm was forbidden in snd_hda_codec_device_new() */
|
|
snd_hda_codec_set_power_save(codec, 2000);
|
|
snd_hda_codec_register(codec);
|
|
-out:
|
|
+
|
|
/* Complement pm_runtime_get_sync(bus) in probe */
|
|
pm_runtime_mark_last_busy(bus->dev);
|
|
pm_runtime_put_autosuspend(bus->dev);
|
|
diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c
|
|
index 72d6356b898148..054c6f860675a1 100644
|
|
--- a/sound/soc/codecs/tas2764.c
|
|
+++ b/sound/soc/codecs/tas2764.c
|
|
@@ -542,7 +542,7 @@ static int tas2764_codec_probe(struct snd_soc_component *component)
|
|
tas2764_reset(tas2764);
|
|
|
|
if (tas2764->irq) {
|
|
- ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK0, 0xff);
|
|
+ ret = snd_soc_component_write(tas2764->component, TAS2764_INT_MASK0, 0x00);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c
|
|
index bdd388ec01eaf7..26d0c3a5a9542d 100644
|
|
--- a/sound/soc/intel/avs/debugfs.c
|
|
+++ b/sound/soc/intel/avs/debugfs.c
|
|
@@ -371,7 +371,10 @@ static ssize_t trace_control_write(struct file *file, const char __user *from, s
|
|
return ret;
|
|
|
|
num_elems = *array;
|
|
- resource_mask = array[1];
|
|
+ if (!num_elems) {
|
|
+ ret = -EINVAL;
|
|
+ goto free_array;
|
|
+ }
|
|
|
|
/*
|
|
* Disable if just resource mask is provided - no log priority flags.
|
|
@@ -379,6 +382,7 @@ static ssize_t trace_control_write(struct file *file, const char __user *from, s
|
|
* Enable input format: mask, prio1, .., prioN
|
|
* Where 'N' equals number of bits set in the 'mask'.
|
|
*/
|
|
+ resource_mask = array[1];
|
|
if (num_elems == 1) {
|
|
ret = disable_logs(adev, resource_mask);
|
|
} else {
|
|
diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c
|
|
index 74f676fdfba29d..afd472906ede4c 100644
|
|
--- a/sound/soc/intel/avs/ipc.c
|
|
+++ b/sound/soc/intel/avs/ipc.c
|
|
@@ -169,7 +169,9 @@ static void avs_dsp_exception_caught(struct avs_dev *adev, union avs_notify_msg
|
|
|
|
dev_crit(adev->dev, "communication severed, rebooting dsp..\n");
|
|
|
|
- cancel_delayed_work_sync(&ipc->d0ix_work);
|
|
+ /* Avoid deadlock as the exception may be the response to SET_D0IX. */
|
|
+ if (current_work() != &ipc->d0ix_work.work)
|
|
+ cancel_delayed_work_sync(&ipc->d0ix_work);
|
|
ipc->in_d0ix = false;
|
|
/* Re-enabled on recovery completion. */
|
|
pm_runtime_disable(adev->dev);
|
|
diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c
|
|
index bb5df0d214e367..a29632423ccda1 100644
|
|
--- a/sound/soc/sof/ipc4-pcm.c
|
|
+++ b/sound/soc/sof/ipc4-pcm.c
|
|
@@ -615,7 +615,8 @@ static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm
|
|
|
|
/* allocate memory for max number of pipeline IDs */
|
|
pipeline_list->pipelines = kcalloc(ipc4_data->max_num_pipelines,
|
|
- sizeof(struct snd_sof_widget *), GFP_KERNEL);
|
|
+ sizeof(*pipeline_list->pipelines),
|
|
+ GFP_KERNEL);
|
|
if (!pipeline_list->pipelines) {
|
|
sof_ipc4_pcm_free(sdev, spcm);
|
|
return -ENOMEM;
|
|
diff --git a/sound/soc/ti/omap-hdmi.c b/sound/soc/ti/omap-hdmi.c
|
|
index 0a731b21e5a58d..72fabf22a02ee7 100644
|
|
--- a/sound/soc/ti/omap-hdmi.c
|
|
+++ b/sound/soc/ti/omap-hdmi.c
|
|
@@ -361,17 +361,20 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev)
|
|
if (!card->dai_link)
|
|
return -ENOMEM;
|
|
|
|
- compnent = devm_kzalloc(dev, sizeof(*compnent), GFP_KERNEL);
|
|
+ compnent = devm_kzalloc(dev, 2 * sizeof(*compnent), GFP_KERNEL);
|
|
if (!compnent)
|
|
return -ENOMEM;
|
|
- card->dai_link->cpus = compnent;
|
|
+ card->dai_link->cpus = &compnent[0];
|
|
card->dai_link->num_cpus = 1;
|
|
card->dai_link->codecs = &asoc_dummy_dlc;
|
|
card->dai_link->num_codecs = 1;
|
|
+ card->dai_link->platforms = &compnent[1];
|
|
+ card->dai_link->num_platforms = 1;
|
|
|
|
card->dai_link->name = card->name;
|
|
card->dai_link->stream_name = card->name;
|
|
card->dai_link->cpus->dai_name = dev_name(ad->dssdev);
|
|
+ card->dai_link->platforms->name = dev_name(ad->dssdev);
|
|
card->num_links = 1;
|
|
card->dev = dev;
|
|
|
|
diff --git a/sound/usb/implicit.c b/sound/usb/implicit.c
|
|
index 4727043fd74580..77f06da93151e8 100644
|
|
--- a/sound/usb/implicit.c
|
|
+++ b/sound/usb/implicit.c
|
|
@@ -57,6 +57,7 @@ static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = {
|
|
IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0002, 0x81, 2), /* Solid State Logic SSL2+ */
|
|
IMPLICIT_FB_FIXED_DEV(0x0499, 0x172f, 0x81, 2), /* Steinberg UR22C */
|
|
IMPLICIT_FB_FIXED_DEV(0x0d9a, 0x00df, 0x81, 2), /* RTX6001 */
|
|
+ IMPLICIT_FB_FIXED_DEV(0x19f7, 0x000a, 0x84, 3), /* RODE AI-1 */
|
|
IMPLICIT_FB_FIXED_DEV(0x22f0, 0x0006, 0x81, 3), /* Allen&Heath Qu-16 */
|
|
IMPLICIT_FB_FIXED_DEV(0x1686, 0xf029, 0x82, 2), /* Zoom UAC-2 */
|
|
IMPLICIT_FB_FIXED_DEV(0x2466, 0x8003, 0x86, 2), /* Fractal Audio Axe-Fx II */
|
|
diff --git a/tools/arch/x86/kcpuid/kcpuid.c b/tools/arch/x86/kcpuid/kcpuid.c
|
|
index b7965dfff33a9a..8c2644f3497e64 100644
|
|
--- a/tools/arch/x86/kcpuid/kcpuid.c
|
|
+++ b/tools/arch/x86/kcpuid/kcpuid.c
|
|
@@ -1,11 +1,12 @@
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
#define _GNU_SOURCE
|
|
|
|
-#include <stdio.h>
|
|
+#include <err.h>
|
|
+#include <getopt.h>
|
|
#include <stdbool.h>
|
|
+#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
-#include <getopt.h>
|
|
|
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
|
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
|
@@ -156,14 +157,14 @@ static bool cpuid_store(struct cpuid_range *range, u32 f, int subleaf,
|
|
if (!func->leafs) {
|
|
func->leafs = malloc(sizeof(struct subleaf));
|
|
if (!func->leafs)
|
|
- perror("malloc func leaf");
|
|
+ err(EXIT_FAILURE, NULL);
|
|
|
|
func->nr = 1;
|
|
} else {
|
|
s = func->nr;
|
|
func->leafs = realloc(func->leafs, (s + 1) * sizeof(*leaf));
|
|
if (!func->leafs)
|
|
- perror("realloc f->leafs");
|
|
+ err(EXIT_FAILURE, NULL);
|
|
|
|
func->nr++;
|
|
}
|
|
@@ -222,7 +223,7 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
|
|
|
|
range = malloc(sizeof(struct cpuid_range));
|
|
if (!range)
|
|
- perror("malloc range");
|
|
+ err(EXIT_FAILURE, NULL);
|
|
|
|
if (input_eax & 0x80000000)
|
|
range->is_ext = true;
|
|
@@ -231,7 +232,7 @@ struct cpuid_range *setup_cpuid_range(u32 input_eax)
|
|
|
|
range->funcs = malloc(sizeof(struct cpuid_func) * idx_func);
|
|
if (!range->funcs)
|
|
- perror("malloc range->funcs");
|
|
+ err(EXIT_FAILURE, NULL);
|
|
|
|
range->nr = idx_func;
|
|
memset(range->funcs, 0, sizeof(struct cpuid_func) * idx_func);
|
|
@@ -387,8 +388,8 @@ static int parse_line(char *line)
|
|
return 0;
|
|
|
|
err_exit:
|
|
- printf("Warning: wrong line format:\n");
|
|
- printf("\tline[%d]: %s\n", flines, line);
|
|
+ warnx("Wrong line format:\n"
|
|
+ "\tline[%d]: %s", flines, line);
|
|
return -1;
|
|
}
|
|
|
|
@@ -410,10 +411,8 @@ static void parse_text(void)
|
|
file = fopen("./cpuid.csv", "r");
|
|
}
|
|
|
|
- if (!file) {
|
|
- printf("Fail to open '%s'\n", filename);
|
|
- return;
|
|
- }
|
|
+ if (!file)
|
|
+ err(EXIT_FAILURE, "%s", filename);
|
|
|
|
while (1) {
|
|
ret = getline(&line, &len, file);
|
|
@@ -521,7 +520,7 @@ static inline struct cpuid_func *index_to_func(u32 index)
|
|
func_idx = index & 0xffff;
|
|
|
|
if ((func_idx + 1) > (u32)range->nr) {
|
|
- printf("ERR: invalid input index (0x%x)\n", index);
|
|
+ warnx("Invalid input index (0x%x)", index);
|
|
return NULL;
|
|
}
|
|
return &range->funcs[func_idx];
|
|
@@ -553,7 +552,7 @@ static void show_info(void)
|
|
return;
|
|
}
|
|
|
|
- printf("ERR: invalid input subleaf (0x%x)\n", user_sub);
|
|
+ warnx("Invalid input subleaf (0x%x)", user_sub);
|
|
}
|
|
|
|
show_func(func);
|
|
@@ -584,15 +583,15 @@ static void setup_platform_cpuid(void)
|
|
|
|
static void usage(void)
|
|
{
|
|
- printf("kcpuid [-abdfhr] [-l leaf] [-s subleaf]\n"
|
|
- "\t-a|--all Show both bit flags and complex bit fields info\n"
|
|
- "\t-b|--bitflags Show boolean flags only\n"
|
|
- "\t-d|--detail Show details of the flag/fields (default)\n"
|
|
- "\t-f|--flags Specify the cpuid csv file\n"
|
|
- "\t-h|--help Show usage info\n"
|
|
- "\t-l|--leaf=index Specify the leaf you want to check\n"
|
|
- "\t-r|--raw Show raw cpuid data\n"
|
|
- "\t-s|--subleaf=sub Specify the subleaf you want to check\n"
|
|
+ warnx("kcpuid [-abdfhr] [-l leaf] [-s subleaf]\n"
|
|
+ "\t-a|--all Show both bit flags and complex bit fields info\n"
|
|
+ "\t-b|--bitflags Show boolean flags only\n"
|
|
+ "\t-d|--detail Show details of the flag/fields (default)\n"
|
|
+ "\t-f|--flags Specify the CPUID CSV file\n"
|
|
+ "\t-h|--help Show usage info\n"
|
|
+ "\t-l|--leaf=index Specify the leaf you want to check\n"
|
|
+ "\t-r|--raw Show raw CPUID data\n"
|
|
+ "\t-s|--subleaf=sub Specify the subleaf you want to check"
|
|
);
|
|
}
|
|
|
|
@@ -643,7 +642,7 @@ static int parse_options(int argc, char *argv[])
|
|
user_sub = strtoul(optarg, NULL, 0);
|
|
break;
|
|
default:
|
|
- printf("%s: Invalid option '%c'\n", argv[0], optopt);
|
|
+ warnx("Invalid option '%c'", optopt);
|
|
return -1;
|
|
}
|
|
|
|
diff --git a/tools/bpf/resolve_btfids/Makefile b/tools/bpf/resolve_btfids/Makefile
|
|
index 4b8079f294f65b..b0072e64b01023 100644
|
|
--- a/tools/bpf/resolve_btfids/Makefile
|
|
+++ b/tools/bpf/resolve_btfids/Makefile
|
|
@@ -19,7 +19,7 @@ endif
|
|
|
|
# Overrides for the prepare step libraries.
|
|
HOST_OVERRIDES := AR="$(HOSTAR)" CC="$(HOSTCC)" LD="$(HOSTLD)" ARCH="$(HOSTARCH)" \
|
|
- CROSS_COMPILE="" EXTRA_CFLAGS="$(HOSTCFLAGS)"
|
|
+ CROSS_COMPILE="" CLANG_CROSS_FLAGS="" EXTRA_CFLAGS="$(HOSTCFLAGS)"
|
|
|
|
RM ?= rm
|
|
HOSTCC ?= gcc
|
|
diff --git a/tools/lib/bpf/bpf_core_read.h b/tools/lib/bpf/bpf_core_read.h
|
|
index e2b9e8415c0446..b3fc384595a9f3 100644
|
|
--- a/tools/lib/bpf/bpf_core_read.h
|
|
+++ b/tools/lib/bpf/bpf_core_read.h
|
|
@@ -312,7 +312,13 @@ enum bpf_enum_value_kind {
|
|
#define ___arrow10(a, b, c, d, e, f, g, h, i, j) a->b->c->d->e->f->g->h->i->j
|
|
#define ___arrow(...) ___apply(___arrow, ___narg(__VA_ARGS__))(__VA_ARGS__)
|
|
|
|
+#if defined(__clang__) && (__clang_major__ >= 19)
|
|
+#define ___type(...) __typeof_unqual__(___arrow(__VA_ARGS__))
|
|
+#elif defined(__GNUC__) && (__GNUC__ >= 14)
|
|
+#define ___type(...) __typeof_unqual__(___arrow(__VA_ARGS__))
|
|
+#else
|
|
#define ___type(...) typeof(___arrow(__VA_ARGS__))
|
|
+#endif
|
|
|
|
#define ___read(read_fn, dst, src_type, src, accessor) \
|
|
read_fn((void *)(dst), sizeof(*(dst)), &((src_type)(src))->accessor)
|
|
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
|
|
index fa2abe56e845d9..5dc2e555533586 100644
|
|
--- a/tools/lib/bpf/libbpf.c
|
|
+++ b/tools/lib/bpf/libbpf.c
|
|
@@ -246,7 +246,7 @@ void libbpf_print(enum libbpf_print_level level, const char *format, ...)
|
|
old_errno = errno;
|
|
|
|
va_start(args, format);
|
|
- __libbpf_pr(level, format, args);
|
|
+ print_fn(level, format, args);
|
|
va_end(args);
|
|
|
|
errno = old_errno;
|
|
@@ -838,7 +838,7 @@ bpf_object__add_programs(struct bpf_object *obj, Elf_Data *sec_data,
|
|
return -LIBBPF_ERRNO__FORMAT;
|
|
}
|
|
|
|
- if (sec_off + prog_sz > sec_sz) {
|
|
+ if (sec_off + prog_sz > sec_sz || sec_off + prog_sz < sec_off) {
|
|
pr_warn("sec '%s': program at offset %zu crosses section boundary\n",
|
|
sec_name, sec_off);
|
|
return -LIBBPF_ERRNO__FORMAT;
|
|
@@ -12453,7 +12453,6 @@ struct perf_buffer *perf_buffer__new(int map_fd, size_t page_cnt,
|
|
attr.config = PERF_COUNT_SW_BPF_OUTPUT;
|
|
attr.type = PERF_TYPE_SOFTWARE;
|
|
attr.sample_type = PERF_SAMPLE_RAW;
|
|
- attr.sample_period = sample_period;
|
|
attr.wakeup_events = sample_period;
|
|
|
|
p.attr = &attr;
|
|
diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
|
|
index a3a190d13db8a0..e1b3136643aa86 100644
|
|
--- a/tools/lib/bpf/linker.c
|
|
+++ b/tools/lib/bpf/linker.c
|
|
@@ -1187,7 +1187,7 @@ static int linker_append_sec_data(struct bpf_linker *linker, struct src_obj *obj
|
|
} else {
|
|
if (!secs_match(dst_sec, src_sec)) {
|
|
pr_warn("ELF sections %s are incompatible\n", src_sec->sec_name);
|
|
- return -1;
|
|
+ return -EINVAL;
|
|
}
|
|
|
|
/* "license" and "version" sections are deduped */
|
|
@@ -2034,7 +2034,7 @@ static int linker_append_elf_relos(struct bpf_linker *linker, struct src_obj *ob
|
|
}
|
|
} else if (!secs_match(dst_sec, src_sec)) {
|
|
pr_warn("sections %s are not compatible\n", src_sec->sec_name);
|
|
- return -1;
|
|
+ return -EINVAL;
|
|
}
|
|
|
|
/* shdr->sh_link points to SYMTAB */
|
|
diff --git a/tools/lib/bpf/nlattr.c b/tools/lib/bpf/nlattr.c
|
|
index 975e265eab3bfe..06663f9ea581f9 100644
|
|
--- a/tools/lib/bpf/nlattr.c
|
|
+++ b/tools/lib/bpf/nlattr.c
|
|
@@ -63,16 +63,16 @@ static int validate_nla(struct nlattr *nla, int maxtype,
|
|
minlen = nla_attr_minlen[pt->type];
|
|
|
|
if (libbpf_nla_len(nla) < minlen)
|
|
- return -1;
|
|
+ return -EINVAL;
|
|
|
|
if (pt->maxlen && libbpf_nla_len(nla) > pt->maxlen)
|
|
- return -1;
|
|
+ return -EINVAL;
|
|
|
|
if (pt->type == LIBBPF_NLA_STRING) {
|
|
char *data = libbpf_nla_data(nla);
|
|
|
|
if (data[libbpf_nla_len(nla) - 1] != '\0')
|
|
- return -1;
|
|
+ return -EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
@@ -118,19 +118,18 @@ int libbpf_nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head,
|
|
if (policy) {
|
|
err = validate_nla(nla, maxtype, policy);
|
|
if (err < 0)
|
|
- goto errout;
|
|
+ return err;
|
|
}
|
|
|
|
- if (tb[type])
|
|
+ if (tb[type]) {
|
|
pr_warn("Attribute of type %#x found multiple times in message, "
|
|
"previous attribute is being ignored.\n", type);
|
|
+ }
|
|
|
|
tb[type] = nla;
|
|
}
|
|
|
|
- err = 0;
|
|
-errout:
|
|
- return err;
|
|
+ return 0;
|
|
}
|
|
|
|
/**
|
|
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
|
|
index d66b52407e19c6..9da9f878f50f7b 100644
|
|
--- a/tools/perf/Makefile.config
|
|
+++ b/tools/perf/Makefile.config
|
|
@@ -554,6 +554,8 @@ ifndef NO_LIBELF
|
|
ifeq ($(feature-libdebuginfod), 1)
|
|
CFLAGS += -DHAVE_DEBUGINFOD_SUPPORT
|
|
EXTLIBS += -ldebuginfod
|
|
+ else
|
|
+ $(warning No elfutils/debuginfod.h found, no debuginfo server support, please install libdebuginfod-dev/elfutils-debuginfod-client-devel or equivalent)
|
|
endif
|
|
endif
|
|
|
|
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
|
|
index b94ae33a343c2a..81f77c0505fde0 100644
|
|
--- a/tools/perf/builtin-record.c
|
|
+++ b/tools/perf/builtin-record.c
|
|
@@ -3427,7 +3427,7 @@ static struct option __record_options[] = {
|
|
"sample selected machine registers on interrupt,"
|
|
" use '-I?' to list register names", parse_intr_regs),
|
|
OPT_CALLBACK_OPTARG(0, "user-regs", &record.opts.sample_user_regs, NULL, "any register",
|
|
- "sample selected machine registers on interrupt,"
|
|
+ "sample selected machine registers in user space,"
|
|
" use '--user-regs=?' to list register names", parse_user_regs),
|
|
OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
|
|
"Record running/enabled time of read (:S) events"),
|
|
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
|
|
index 12bdbf3ecc6ae4..7ee3285af10c99 100644
|
|
--- a/tools/perf/builtin-trace.c
|
|
+++ b/tools/perf/builtin-trace.c
|
|
@@ -2586,8 +2586,8 @@ errno_print: {
|
|
else if (sc->fmt->errpid) {
|
|
struct thread *child = machine__find_thread(trace->host, ret, ret);
|
|
|
|
+ fprintf(trace->output, "%ld", ret);
|
|
if (child != NULL) {
|
|
- fprintf(trace->output, "%ld", ret);
|
|
if (thread__comm_set(child))
|
|
fprintf(trace->output, " (%s)", thread__comm_str(child));
|
|
thread__put(child);
|
|
@@ -3589,10 +3589,13 @@ static int trace__set_filter_loop_pids(struct trace *trace)
|
|
if (!strcmp(thread__comm_str(parent), "sshd") ||
|
|
strstarts(thread__comm_str(parent), "gnome-terminal")) {
|
|
pids[nr++] = thread__tid(parent);
|
|
+ thread__put(parent);
|
|
break;
|
|
}
|
|
+ thread__put(thread);
|
|
thread = parent;
|
|
}
|
|
+ thread__put(thread);
|
|
|
|
err = evlist__append_tp_filter_pids(trace->evlist, nr, pids);
|
|
if (!err && trace->filter_pids.map)
|
|
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
|
|
index 13f2d8a8161096..99742013676b3d 100755
|
|
--- a/tools/perf/scripts/python/exported-sql-viewer.py
|
|
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
|
|
@@ -680,7 +680,10 @@ class CallGraphModelBase(TreeModel):
|
|
s = value.replace("%", "\%")
|
|
s = s.replace("_", "\_")
|
|
# Translate * and ? into SQL LIKE pattern characters % and _
|
|
- trans = string.maketrans("*?", "%_")
|
|
+ if sys.version_info[0] == 3:
|
|
+ trans = str.maketrans("*?", "%_")
|
|
+ else:
|
|
+ trans = string.maketrans("*?", "%_")
|
|
match = " LIKE '" + str(s).translate(trans) + "'"
|
|
else:
|
|
match = " GLOB '" + str(value) + "'"
|
|
diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
|
|
index e52b031bedc5a9..2c7bdf4fd55edd 100644
|
|
--- a/tools/perf/tests/switch-tracking.c
|
|
+++ b/tools/perf/tests/switch-tracking.c
|
|
@@ -258,7 +258,7 @@ static int compar(const void *a, const void *b)
|
|
const struct event_node *nodeb = b;
|
|
s64 cmp = nodea->event_time - nodeb->event_time;
|
|
|
|
- return cmp;
|
|
+ return cmp < 0 ? -1 : (cmp > 0 ? 1 : 0);
|
|
}
|
|
|
|
static int process_events(struct evlist *evlist,
|
|
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
|
|
index bb59d27642ccf2..a53a0257a4bca2 100644
|
|
--- a/tools/perf/ui/browsers/hists.c
|
|
+++ b/tools/perf/ui/browsers/hists.c
|
|
@@ -3239,10 +3239,10 @@ static int evsel__hists_browse(struct evsel *evsel, int nr_events, const char *h
|
|
/*
|
|
* No need to set actions->dso here since
|
|
* it's just to remove the current filter.
|
|
- * Ditto for thread below.
|
|
*/
|
|
do_zoom_dso(browser, actions);
|
|
} else if (top == &browser->hists->thread_filter) {
|
|
+ actions->thread = thread;
|
|
do_zoom_thread(browser, actions);
|
|
} else if (top == &browser->hists->socket_filter) {
|
|
do_zoom_socket(browser, actions);
|
|
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
|
|
index 4db9a098f59262..e9f97c0c335827 100644
|
|
--- a/tools/perf/util/intel-pt.c
|
|
+++ b/tools/perf/util/intel-pt.c
|
|
@@ -127,6 +127,7 @@ struct intel_pt {
|
|
|
|
bool single_pebs;
|
|
bool sample_pebs;
|
|
+ int pebs_data_src_fmt;
|
|
struct evsel *pebs_evsel;
|
|
|
|
u64 evt_sample_type;
|
|
@@ -175,6 +176,7 @@ enum switch_state {
|
|
struct intel_pt_pebs_event {
|
|
struct evsel *evsel;
|
|
u64 id;
|
|
+ int data_src_fmt;
|
|
};
|
|
|
|
struct intel_pt_queue {
|
|
@@ -2232,7 +2234,146 @@ static void intel_pt_add_lbrs(struct branch_stack *br_stack,
|
|
}
|
|
}
|
|
|
|
-static int intel_pt_do_synth_pebs_sample(struct intel_pt_queue *ptq, struct evsel *evsel, u64 id)
|
|
+#define P(a, b) PERF_MEM_S(a, b)
|
|
+#define OP_LH (P(OP, LOAD) | P(LVL, HIT))
|
|
+#define LEVEL(x) P(LVLNUM, x)
|
|
+#define REM P(REMOTE, REMOTE)
|
|
+#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))
|
|
+
|
|
+#define PERF_PEBS_DATA_SOURCE_GRT_MAX 0x10
|
|
+#define PERF_PEBS_DATA_SOURCE_GRT_MASK (PERF_PEBS_DATA_SOURCE_GRT_MAX - 1)
|
|
+
|
|
+/* Based on kernel __intel_pmu_pebs_data_source_grt() and pebs_data_source */
|
|
+static const u64 pebs_data_source_grt[PERF_PEBS_DATA_SOURCE_GRT_MAX] = {
|
|
+ P(OP, LOAD) | P(LVL, MISS) | LEVEL(L3) | P(SNOOP, NA), /* L3 miss|SNP N/A */
|
|
+ OP_LH | P(LVL, L1) | LEVEL(L1) | P(SNOOP, NONE), /* L1 hit|SNP None */
|
|
+ OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE), /* LFB/MAB hit|SNP None */
|
|
+ OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, NONE), /* L2 hit|SNP None */
|
|
+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, NONE), /* L3 hit|SNP None */
|
|
+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT), /* L3 hit|SNP Hit */
|
|
+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM), /* L3 hit|SNP HitM */
|
|
+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM), /* L3 hit|SNP HitM */
|
|
+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOPX, FWD), /* L3 hit|SNP Fwd */
|
|
+ OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HITM), /* Remote L3 hit|SNP HitM */
|
|
+ OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | P(SNOOP, HIT), /* RAM hit|SNP Hit */
|
|
+ OP_LH | P(LVL, REM_RAM1) | REM | LEVEL(L3) | P(SNOOP, HIT), /* Remote L3 hit|SNP Hit */
|
|
+ OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | SNOOP_NONE_MISS, /* RAM hit|SNP None or Miss */
|
|
+ OP_LH | P(LVL, REM_RAM1) | LEVEL(RAM) | REM | SNOOP_NONE_MISS, /* Remote RAM hit|SNP None or Miss */
|
|
+ OP_LH | P(LVL, IO) | LEVEL(NA) | P(SNOOP, NONE), /* I/O hit|SNP None */
|
|
+ OP_LH | P(LVL, UNC) | LEVEL(NA) | P(SNOOP, NONE), /* Uncached hit|SNP None */
|
|
+};
|
|
+
|
|
+/* Based on kernel __intel_pmu_pebs_data_source_cmt() and pebs_data_source */
|
|
+static const u64 pebs_data_source_cmt[PERF_PEBS_DATA_SOURCE_GRT_MAX] = {
|
|
+ P(OP, LOAD) | P(LVL, MISS) | LEVEL(L3) | P(SNOOP, NA), /* L3 miss|SNP N/A */
|
|
+ OP_LH | P(LVL, L1) | LEVEL(L1) | P(SNOOP, NONE), /* L1 hit|SNP None */
|
|
+ OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE), /* LFB/MAB hit|SNP None */
|
|
+ OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, NONE), /* L2 hit|SNP None */
|
|
+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, NONE), /* L3 hit|SNP None */
|
|
+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, MISS), /* L3 hit|SNP Hit */
|
|
+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT), /* L3 hit|SNP HitM */
|
|
+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOPX, FWD), /* L3 hit|SNP HitM */
|
|
+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM), /* L3 hit|SNP Fwd */
|
|
+ OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HITM), /* Remote L3 hit|SNP HitM */
|
|
+ OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | P(SNOOP, NONE), /* RAM hit|SNP Hit */
|
|
+ OP_LH | LEVEL(RAM) | REM | P(SNOOP, NONE), /* Remote L3 hit|SNP Hit */
|
|
+ OP_LH | LEVEL(RAM) | REM | P(SNOOPX, FWD), /* RAM hit|SNP None or Miss */
|
|
+ OP_LH | LEVEL(RAM) | REM | P(SNOOP, HITM), /* Remote RAM hit|SNP None or Miss */
|
|
+ OP_LH | P(LVL, IO) | LEVEL(NA) | P(SNOOP, NONE), /* I/O hit|SNP None */
|
|
+ OP_LH | P(LVL, UNC) | LEVEL(NA) | P(SNOOP, NONE), /* Uncached hit|SNP None */
|
|
+};
|
|
+
|
|
+/* Based on kernel pebs_set_tlb_lock() */
|
|
+static inline void pebs_set_tlb_lock(u64 *val, bool tlb, bool lock)
|
|
+{
|
|
+ /*
|
|
+ * TLB access
|
|
+ * 0 = did not miss 2nd level TLB
|
|
+ * 1 = missed 2nd level TLB
|
|
+ */
|
|
+ if (tlb)
|
|
+ *val |= P(TLB, MISS) | P(TLB, L2);
|
|
+ else
|
|
+ *val |= P(TLB, HIT) | P(TLB, L1) | P(TLB, L2);
|
|
+
|
|
+ /* locked prefix */
|
|
+ if (lock)
|
|
+ *val |= P(LOCK, LOCKED);
|
|
+}
|
|
+
|
|
+/* Based on kernel __grt_latency_data() */
|
|
+static u64 intel_pt_grt_latency_data(u8 dse, bool tlb, bool lock, bool blk,
|
|
+ const u64 *pebs_data_source)
|
|
+{
|
|
+ u64 val;
|
|
+
|
|
+ dse &= PERF_PEBS_DATA_SOURCE_GRT_MASK;
|
|
+ val = pebs_data_source[dse];
|
|
+
|
|
+ pebs_set_tlb_lock(&val, tlb, lock);
|
|
+
|
|
+ if (blk)
|
|
+ val |= P(BLK, DATA);
|
|
+ else
|
|
+ val |= P(BLK, NA);
|
|
+
|
|
+ return val;
|
|
+}
|
|
+
|
|
+/* Default value for data source */
|
|
+#define PERF_MEM_NA (PERF_MEM_S(OP, NA) |\
|
|
+ PERF_MEM_S(LVL, NA) |\
|
|
+ PERF_MEM_S(SNOOP, NA) |\
|
|
+ PERF_MEM_S(LOCK, NA) |\
|
|
+ PERF_MEM_S(TLB, NA) |\
|
|
+ PERF_MEM_S(LVLNUM, NA))
|
|
+
|
|
+enum DATA_SRC_FORMAT {
|
|
+ DATA_SRC_FORMAT_ERR = -1,
|
|
+ DATA_SRC_FORMAT_NA = 0,
|
|
+ DATA_SRC_FORMAT_GRT = 1,
|
|
+ DATA_SRC_FORMAT_CMT = 2,
|
|
+};
|
|
+
|
|
+/* Based on kernel grt_latency_data() and cmt_latency_data */
|
|
+static u64 intel_pt_get_data_src(u64 mem_aux_info, int data_src_fmt)
|
|
+{
|
|
+ switch (data_src_fmt) {
|
|
+ case DATA_SRC_FORMAT_GRT: {
|
|
+ union {
|
|
+ u64 val;
|
|
+ struct {
|
|
+ unsigned int dse:4;
|
|
+ unsigned int locked:1;
|
|
+ unsigned int stlb_miss:1;
|
|
+ unsigned int fwd_blk:1;
|
|
+ unsigned int reserved:25;
|
|
+ };
|
|
+ } x = {.val = mem_aux_info};
|
|
+ return intel_pt_grt_latency_data(x.dse, x.stlb_miss, x.locked, x.fwd_blk,
|
|
+ pebs_data_source_grt);
|
|
+ }
|
|
+ case DATA_SRC_FORMAT_CMT: {
|
|
+ union {
|
|
+ u64 val;
|
|
+ struct {
|
|
+ unsigned int dse:5;
|
|
+ unsigned int locked:1;
|
|
+ unsigned int stlb_miss:1;
|
|
+ unsigned int fwd_blk:1;
|
|
+ unsigned int reserved:24;
|
|
+ };
|
|
+ } x = {.val = mem_aux_info};
|
|
+ return intel_pt_grt_latency_data(x.dse, x.stlb_miss, x.locked, x.fwd_blk,
|
|
+ pebs_data_source_cmt);
|
|
+ }
|
|
+ default:
|
|
+ return PERF_MEM_NA;
|
|
+ }
|
|
+}
|
|
+
|
|
+static int intel_pt_do_synth_pebs_sample(struct intel_pt_queue *ptq, struct evsel *evsel,
|
|
+ u64 id, int data_src_fmt)
|
|
{
|
|
const struct intel_pt_blk_items *items = &ptq->state->items;
|
|
struct perf_sample sample = { .ip = 0, };
|
|
@@ -2350,6 +2491,18 @@ static int intel_pt_do_synth_pebs_sample(struct intel_pt_queue *ptq, struct evse
|
|
}
|
|
}
|
|
|
|
+ if (sample_type & PERF_SAMPLE_DATA_SRC) {
|
|
+ if (items->has_mem_aux_info && data_src_fmt) {
|
|
+ if (data_src_fmt < 0) {
|
|
+ pr_err("Intel PT missing data_src info\n");
|
|
+ return -1;
|
|
+ }
|
|
+ sample.data_src = intel_pt_get_data_src(items->mem_aux_info, data_src_fmt);
|
|
+ } else {
|
|
+ sample.data_src = PERF_MEM_NA;
|
|
+ }
|
|
+ }
|
|
+
|
|
if (sample_type & PERF_SAMPLE_TRANSACTION && items->has_tsx_aux_info) {
|
|
u64 ax = items->has_rax ? items->rax : 0;
|
|
/* Refer kernel's intel_hsw_transaction() */
|
|
@@ -2368,9 +2521,10 @@ static int intel_pt_synth_single_pebs_sample(struct intel_pt_queue *ptq)
|
|
{
|
|
struct intel_pt *pt = ptq->pt;
|
|
struct evsel *evsel = pt->pebs_evsel;
|
|
+ int data_src_fmt = pt->pebs_data_src_fmt;
|
|
u64 id = evsel->core.id[0];
|
|
|
|
- return intel_pt_do_synth_pebs_sample(ptq, evsel, id);
|
|
+ return intel_pt_do_synth_pebs_sample(ptq, evsel, id, data_src_fmt);
|
|
}
|
|
|
|
static int intel_pt_synth_pebs_sample(struct intel_pt_queue *ptq)
|
|
@@ -2395,7 +2549,7 @@ static int intel_pt_synth_pebs_sample(struct intel_pt_queue *ptq)
|
|
hw_id);
|
|
return intel_pt_synth_single_pebs_sample(ptq);
|
|
}
|
|
- err = intel_pt_do_synth_pebs_sample(ptq, pe->evsel, pe->id);
|
|
+ err = intel_pt_do_synth_pebs_sample(ptq, pe->evsel, pe->id, pe->data_src_fmt);
|
|
if (err)
|
|
return err;
|
|
}
|
|
@@ -3355,6 +3509,49 @@ static int intel_pt_process_itrace_start(struct intel_pt *pt,
|
|
event->itrace_start.tid);
|
|
}
|
|
|
|
+/*
|
|
+ * Events with data_src are identified by L1_Hit_Indication
|
|
+ * refer https://github.com/intel/perfmon
|
|
+ */
|
|
+static int intel_pt_data_src_fmt(struct intel_pt *pt, struct evsel *evsel)
|
|
+{
|
|
+ struct perf_env *env = pt->machine->env;
|
|
+ int fmt = DATA_SRC_FORMAT_NA;
|
|
+
|
|
+ if (!env->cpuid)
|
|
+ return DATA_SRC_FORMAT_ERR;
|
|
+
|
|
+ /*
|
|
+ * PEBS-via-PT is only supported on E-core non-hybrid. Of those only
|
|
+ * Gracemont and Crestmont have data_src. Check for:
|
|
+ * Alderlake N (Gracemont)
|
|
+ * Sierra Forest (Crestmont)
|
|
+ * Grand Ridge (Crestmont)
|
|
+ */
|
|
+
|
|
+ if (!strncmp(env->cpuid, "GenuineIntel,6,190,", 19))
|
|
+ fmt = DATA_SRC_FORMAT_GRT;
|
|
+
|
|
+ if (!strncmp(env->cpuid, "GenuineIntel,6,175,", 19) ||
|
|
+ !strncmp(env->cpuid, "GenuineIntel,6,182,", 19))
|
|
+ fmt = DATA_SRC_FORMAT_CMT;
|
|
+
|
|
+ if (fmt == DATA_SRC_FORMAT_NA)
|
|
+ return fmt;
|
|
+
|
|
+ /*
|
|
+ * Only data_src events are:
|
|
+ * mem-loads event=0xd0,umask=0x5
|
|
+ * mem-stores event=0xd0,umask=0x6
|
|
+ */
|
|
+ if (evsel->core.attr.type == PERF_TYPE_RAW &&
|
|
+ ((evsel->core.attr.config & 0xffff) == 0x5d0 ||
|
|
+ (evsel->core.attr.config & 0xffff) == 0x6d0))
|
|
+ return fmt;
|
|
+
|
|
+ return DATA_SRC_FORMAT_NA;
|
|
+}
|
|
+
|
|
static int intel_pt_process_aux_output_hw_id(struct intel_pt *pt,
|
|
union perf_event *event,
|
|
struct perf_sample *sample)
|
|
@@ -3375,6 +3572,7 @@ static int intel_pt_process_aux_output_hw_id(struct intel_pt *pt,
|
|
|
|
ptq->pebs[hw_id].evsel = evsel;
|
|
ptq->pebs[hw_id].id = sample->id;
|
|
+ ptq->pebs[hw_id].data_src_fmt = intel_pt_data_src_fmt(pt, evsel);
|
|
|
|
return 0;
|
|
}
|
|
@@ -3946,6 +4144,7 @@ static void intel_pt_setup_pebs_events(struct intel_pt *pt)
|
|
}
|
|
pt->single_pebs = true;
|
|
pt->sample_pebs = true;
|
|
+ pt->pebs_data_src_fmt = intel_pt_data_src_fmt(pt, evsel);
|
|
pt->pebs_evsel = evsel;
|
|
}
|
|
}
|
|
diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c b/tools/testing/selftests/bpf/prog_tests/bpf_nf.c
|
|
index b30ff6b3b81ae3..f80660c00a1a75 100644
|
|
--- a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c
|
|
+++ b/tools/testing/selftests/bpf/prog_tests/bpf_nf.c
|
|
@@ -63,6 +63,12 @@ static void test_bpf_nf_ct(int mode)
|
|
.repeat = 1,
|
|
);
|
|
|
|
+ if (SYS_NOFAIL("iptables-legacy --version")) {
|
|
+ fprintf(stdout, "Missing required iptables-legacy tool\n");
|
|
+ test__skip();
|
|
+ return;
|
|
+ }
|
|
+
|
|
skel = test_bpf_nf__open_and_load();
|
|
if (!ASSERT_OK_PTR(skel, "test_bpf_nf__open_and_load"))
|
|
return;
|
|
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
|
|
index cacf6507f69055..15325ca35f1e2b 100644
|
|
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
|
|
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
|
|
@@ -3154,12 +3154,15 @@ TEST(syscall_restart)
|
|
ret = get_syscall(_metadata, child_pid);
|
|
#if defined(__arm__)
|
|
/*
|
|
- * FIXME:
|
|
* - native ARM registers do NOT expose true syscall.
|
|
* - compat ARM registers on ARM64 DO expose true syscall.
|
|
+ * - values of utsbuf.machine include 'armv8l' or 'armb8b'
|
|
+ * for ARM64 running in compat mode.
|
|
*/
|
|
ASSERT_EQ(0, uname(&utsbuf));
|
|
- if (strncmp(utsbuf.machine, "arm", 3) == 0) {
|
|
+ if ((strncmp(utsbuf.machine, "arm", 3) == 0) &&
|
|
+ (strncmp(utsbuf.machine, "armv8l", 6) != 0) &&
|
|
+ (strncmp(utsbuf.machine, "armv8b", 6) != 0)) {
|
|
EXPECT_EQ(__NR_nanosleep, ret);
|
|
} else
|
|
#endif
|