diff options
author | Alice Ferrazzi <alicef@gentoo.org> | 2021-10-14 01:14:14 +0900 |
---|---|---|
committer | Alice Ferrazzi <alicef@gentoo.org> | 2021-10-14 01:14:54 +0900 |
commit | 94580b1463bbf03ca324c74c008b18d535048b6f (patch) | |
tree | 9f7e004c67ba4e85bd793fa67ee4fece7637fa23 | |
parent | Linux patch 5.14.11 (diff) | |
download | linux-patches-94580b1463bbf03ca324c74c008b18d535048b6f.tar.gz linux-patches-94580b1463bbf03ca324c74c008b18d535048b6f.tar.bz2 linux-patches-94580b1463bbf03ca324c74c008b18d535048b6f.zip |
Linux patch 5.14.125.14-13
Signed-off-by: Alice Ferrazzi <alicef@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1011_linux-5.14.12.patch | 5808 |
2 files changed, 5812 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 6096d944..4456b487 100644 --- a/0000_README +++ b/0000_README @@ -91,6 +91,10 @@ Patch: 1010_linux-5.14.11.patch From: http://www.kernel.org Desc: Linux 5.14.11 +Patch: 1011_linux-5.14.12.patch +From: http://www.kernel.org +Desc: Linux 5.14.12 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1011_linux-5.14.12.patch b/1011_linux-5.14.12.patch new file mode 100644 index 00000000..5f0db51a --- /dev/null +++ b/1011_linux-5.14.12.patch @@ -0,0 +1,5808 @@ +diff --git a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml +index 26932d2e86aba..8608b9dd8e9db 100644 +--- a/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml ++++ b/Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml +@@ -18,7 +18,7 @@ properties: + const: ti,sn65dsi86 + + reg: +- const: 0x2d ++ enum: [ 0x2c, 0x2d ] + + enable-gpios: + maxItems: 1 +diff --git a/Makefile b/Makefile +index ca6c4472775cb..02cde08f4978e 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 14 +-SUBLEVEL = 11 ++SUBLEVEL = 12 + EXTRAVERSION = + NAME = Opossums on Parade + +diff --git a/arch/arm/boot/dts/imx53-m53menlo.dts b/arch/arm/boot/dts/imx53-m53menlo.dts +index d3082b9774e40..4f88e96d81ddb 100644 +--- a/arch/arm/boot/dts/imx53-m53menlo.dts ++++ b/arch/arm/boot/dts/imx53-m53menlo.dts +@@ -56,6 +56,7 @@ + panel { + compatible = "edt,etm0700g0dh6"; + pinctrl-0 = <&pinctrl_display_gpio>; ++ pinctrl-names = "default"; + enable-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; + + port { +@@ -76,8 +77,7 @@ + regulator-name = "vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; +- gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>; +- enable-active-high; ++ gpio = <&gpio1 2 0>; + }; + }; + +diff --git a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi +index cb8b539eb29d1..e5c4dc65fbabf 100644 +--- a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi ++++ b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi +@@ -5,6 +5,7 @@ + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/input/input.h> ++#include <dt-bindings/leds/common.h> + #include <dt-bindings/pwm/pwm.h> + + / { +@@ -277,6 +278,7 @@ + led-cur = /bits/ 8 <0x20>; + max-cur = /bits/ 8 <0x60>; + reg = <0>; ++ color = <LED_COLOR_ID_RED>; + }; + + chan@1 { +@@ -284,6 +286,7 @@ + led-cur = /bits/ 8 <0x20>; + max-cur = /bits/ 8 <0x60>; + reg = <1>; ++ color = <LED_COLOR_ID_GREEN>; + }; + + chan@2 { +@@ -291,6 +294,7 @@ + led-cur = /bits/ 8 <0x20>; + max-cur = /bits/ 8 <0x60>; + reg = <2>; ++ color = <LED_COLOR_ID_BLUE>; + }; + + chan@3 { +@@ -298,6 +302,7 @@ + led-cur = /bits/ 8 <0x0>; + max-cur = /bits/ 8 <0x0>; + reg = <3>; ++ color = <LED_COLOR_ID_WHITE>; + }; + }; + +diff --git a/arch/arm/boot/dts/imx6qdl-pico.dtsi b/arch/arm/boot/dts/imx6qdl-pico.dtsi +index 5de4ccb979163..f7a56d6b160c8 100644 +--- a/arch/arm/boot/dts/imx6qdl-pico.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-pico.dtsi +@@ -176,7 +176,18 @@ + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii-id"; + phy-reset-gpios = <&gpio1 26 GPIO_ACTIVE_LOW>; ++ phy-handle = <&phy>; + status = "okay"; ++ ++ mdio { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ phy: ethernet-phy@1 { ++ reg = <1>; ++ qca,clk-out-frequency = <125000000>; ++ }; ++ }; + }; + + &hdmi { +diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts +index 5a63ca6157229..99f4cf777a384 100644 +--- a/arch/arm/boot/dts/imx6sx-sdb.dts ++++ b/arch/arm/boot/dts/imx6sx-sdb.dts +@@ -114,7 +114,7 @@ + compatible = "micron,n25q256a", "jedec,spi-nor"; + spi-max-frequency = <29000000>; + spi-rx-bus-width = <4>; +- spi-tx-bus-width = <4>; ++ spi-tx-bus-width = <1>; + reg = <0>; + }; + +@@ -124,7 +124,7 @@ + compatible = "micron,n25q256a", "jedec,spi-nor"; + spi-max-frequency = <29000000>; + spi-rx-bus-width = <4>; +- spi-tx-bus-width = <4>; ++ spi-tx-bus-width = <1>; + reg = <2>; + }; + }; +diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi +index 779cc536566d6..a3fde3316c736 100644 +--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi ++++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi +@@ -292,7 +292,7 @@ + compatible = "micron,n25q256a", "jedec,spi-nor"; + spi-max-frequency = <29000000>; + spi-rx-bus-width = <4>; +- spi-tx-bus-width = <4>; ++ spi-tx-bus-width = <1>; + reg = <0>; + }; + }; +diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts +index c5b9037184149..7d530ae3483b8 100644 +--- a/arch/arm/boot/dts/omap3430-sdp.dts ++++ b/arch/arm/boot/dts/omap3430-sdp.dts +@@ -101,7 +101,7 @@ + + nand@1,0 { + compatible = "ti,omap2-nand"; +- reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ ++ reg = <1 0 4>; /* CS1, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ +diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi +index e36d590e83732..72c4a9fc41a20 100644 +--- a/arch/arm/boot/dts/qcom-apq8064.dtsi ++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi +@@ -198,7 +198,7 @@ + clock-frequency = <19200000>; + }; + +- pxo_board { ++ pxo_board: pxo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; +@@ -1148,7 +1148,7 @@ + }; + + gpu: adreno-3xx@4300000 { +- compatible = "qcom,adreno-3xx"; ++ compatible = "qcom,adreno-320.2", "qcom,adreno"; + reg = <0x04300000 0x20000>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; +@@ -1163,7 +1163,6 @@ + <&mmcc GFX3D_AHB_CLK>, + <&mmcc GFX3D_AXI_CLK>, + <&mmcc MMSS_IMEM_AHB_CLK>; +- qcom,chipid = <0x03020002>; + + iommus = <&gfx3d 0 + &gfx3d 1 +@@ -1306,7 +1305,7 @@ + reg-names = "dsi_pll", "dsi_phy", "dsi_phy_regulator"; + clock-names = "iface_clk", "ref"; + clocks = <&mmcc DSI_M_AHB_CLK>, +- <&cxo_board>; ++ <&pxo_board>; + }; + + +diff --git a/arch/arm/configs/gemini_defconfig b/arch/arm/configs/gemini_defconfig +index d2d5f1cf815f2..e6ff844821cfb 100644 +--- a/arch/arm/configs/gemini_defconfig ++++ b/arch/arm/configs/gemini_defconfig +@@ -76,6 +76,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y + CONFIG_DRM=y + CONFIG_DRM_PANEL_ILITEK_IL9322=y + CONFIG_DRM_TVE200=y ++CONFIG_FB=y + CONFIG_LOGO=y + CONFIG_USB=y + CONFIG_USB_MON=y +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index 90dcdfe3b3d0d..2dee383f90509 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -514,18 +514,22 @@ static const struct of_device_id ramc_ids[] __initconst = { + { /*sentinel*/ } + }; + +-static __init void at91_dt_ramc(void) ++static __init int at91_dt_ramc(void) + { + struct device_node *np; + const struct of_device_id *of_id; + int idx = 0; + void *standby = NULL; + const struct ramc_info *ramc; ++ int ret; + + for_each_matching_node_and_match(np, ramc_ids, &of_id) { + soc_pm.data.ramc[idx] = of_iomap(np, 0); +- if (!soc_pm.data.ramc[idx]) +- panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx); ++ if (!soc_pm.data.ramc[idx]) { ++ pr_err("unable to map ramc[%d] cpu registers\n", idx); ++ ret = -ENOMEM; ++ goto unmap_ramc; ++ } + + ramc = of_id->data; + if (!standby) +@@ -535,15 +539,26 @@ static __init void at91_dt_ramc(void) + idx++; + } + +- if (!idx) +- panic(pr_fmt("unable to find compatible ram controller node in dtb\n")); ++ if (!idx) { ++ pr_err("unable to find compatible ram controller node in dtb\n"); ++ ret = -ENODEV; ++ goto unmap_ramc; ++ } + + if (!standby) { + pr_warn("ramc no standby function available\n"); +- return; ++ return 0; + } + + at91_cpuidle_device.dev.platform_data = standby; ++ ++ return 0; ++ ++unmap_ramc: ++ while (idx) ++ iounmap(soc_pm.data.ramc[--idx]); ++ ++ return ret; + } + + static void at91rm9200_idle(void) +@@ -866,6 +881,8 @@ static void __init at91_pm_init(void (*pm_idle)(void)) + + void __init at91rm9200_pm_init(void) + { ++ int ret; ++ + if (!IS_ENABLED(CONFIG_SOC_AT91RM9200)) + return; + +@@ -877,7 +894,9 @@ void __init at91rm9200_pm_init(void) + soc_pm.data.standby_mode = AT91_PM_STANDBY; + soc_pm.data.suspend_mode = AT91_PM_ULP0; + +- at91_dt_ramc(); ++ ret = at91_dt_ramc(); ++ if (ret) ++ return; + + /* + * AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. +@@ -892,13 +911,17 @@ void __init sam9x60_pm_init(void) + static const int modes[] __initconst = { + AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1, + }; ++ int ret; + + if (!IS_ENABLED(CONFIG_SOC_SAM9X60)) + return; + + at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); + at91_pm_modes_init(); +- at91_dt_ramc(); ++ ret = at91_dt_ramc(); ++ if (ret) ++ return; ++ + at91_pm_init(NULL); + + soc_pm.ws_ids = sam9x60_ws_ids; +@@ -907,6 +930,8 @@ void __init sam9x60_pm_init(void) + + void __init at91sam9_pm_init(void) + { ++ int ret; ++ + if (!IS_ENABLED(CONFIG_SOC_AT91SAM9)) + return; + +@@ -918,7 +943,10 @@ void __init at91sam9_pm_init(void) + soc_pm.data.standby_mode = AT91_PM_STANDBY; + soc_pm.data.suspend_mode = AT91_PM_ULP0; + +- at91_dt_ramc(); ++ ret = at91_dt_ramc(); ++ if (ret) ++ return; ++ + at91_pm_init(at91sam9_idle); + } + +@@ -927,12 +955,16 @@ void __init sama5_pm_init(void) + static const int modes[] __initconst = { + AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, + }; ++ int ret; + + if (!IS_ENABLED(CONFIG_SOC_SAMA5)) + return; + + at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); +- at91_dt_ramc(); ++ ret = at91_dt_ramc(); ++ if (ret) ++ return; ++ + at91_pm_init(NULL); + } + +@@ -942,13 +974,17 @@ void __init sama5d2_pm_init(void) + AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1, + AT91_PM_BACKUP, + }; ++ int ret; + + if (!IS_ENABLED(CONFIG_SOC_SAMA5D2)) + return; + + at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); + at91_pm_modes_init(); +- at91_dt_ramc(); ++ ret = at91_dt_ramc(); ++ if (ret) ++ return; ++ + at91_pm_init(NULL); + + soc_pm.ws_ids = sama5d2_ws_ids; +diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c +index 9244437cb1b9b..f2ecca339910a 100644 +--- a/arch/arm/mach-imx/pm-imx6.c ++++ b/arch/arm/mach-imx/pm-imx6.c +@@ -10,6 +10,7 @@ + #include <linux/io.h> + #include <linux/irq.h> + #include <linux/genalloc.h> ++#include <linux/irqchip/arm-gic.h> + #include <linux/mfd/syscon.h> + #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> + #include <linux/of.h> +@@ -619,6 +620,7 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata + + static void imx6_pm_stby_poweroff(void) + { ++ gic_cpu_if_down(0); + imx6_set_lpm(STOP_POWER_OFF); + imx6q_suspend_finish(0); + +diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c +index 12b26e04686fa..0c2936c7a3799 100644 +--- a/arch/arm/mach-omap2/omap_hwmod.c ++++ b/arch/arm/mach-omap2/omap_hwmod.c +@@ -3614,6 +3614,8 @@ int omap_hwmod_init_module(struct device *dev, + oh->flags |= HWMOD_SWSUP_SIDLE_ACT; + if (data->cfg->quirks & SYSC_QUIRK_SWSUP_MSTANDBY) + oh->flags |= HWMOD_SWSUP_MSTANDBY; ++ if (data->cfg->quirks & SYSC_QUIRK_CLKDM_NOAUTO) ++ oh->flags |= HWMOD_CLKDM_NOAUTO; + + error = omap_hwmod_check_module(dev, oh, data, sysc_fields, + rev_offs, sysc_offs, syss_offs, +diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c +index a951276f05475..a903b26cde409 100644 +--- a/arch/arm/net/bpf_jit_32.c ++++ b/arch/arm/net/bpf_jit_32.c +@@ -36,6 +36,10 @@ + * +-----+ + * |RSVD | JIT scratchpad + * current ARM_SP => +-----+ <= (BPF_FP - STACK_SIZE + SCRATCH_SIZE) ++ * | ... | caller-saved registers ++ * +-----+ ++ * | ... | arguments passed on stack ++ * ARM_SP during call => +-----| + * | | + * | ... | Function call stack + * | | +@@ -63,6 +67,12 @@ + * + * When popping registers off the stack at the end of a BPF function, we + * reference them via the current ARM_FP register. ++ * ++ * Some eBPF operations are implemented via a call to a helper function. ++ * Such calls are "invisible" in the eBPF code, so it is up to the calling ++ * program to preserve any caller-saved ARM registers during the call. The ++ * JIT emits code to push and pop those registers onto the stack, immediately ++ * above the callee stack frame. + */ + #define CALLEE_MASK (1 << ARM_R4 | 1 << ARM_R5 | 1 << ARM_R6 | \ + 1 << ARM_R7 | 1 << ARM_R8 | 1 << ARM_R9 | \ +@@ -70,6 +80,8 @@ + #define CALLEE_PUSH_MASK (CALLEE_MASK | 1 << ARM_LR) + #define CALLEE_POP_MASK (CALLEE_MASK | 1 << ARM_PC) + ++#define CALLER_MASK (1 << ARM_R0 | 1 << ARM_R1 | 1 << ARM_R2 | 1 << ARM_R3) ++ + enum { + /* Stack layout - these are offsets from (top of stack - 4) */ + BPF_R2_HI, +@@ -464,6 +476,7 @@ static inline int epilogue_offset(const struct jit_ctx *ctx) + + static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) + { ++ const int exclude_mask = BIT(ARM_R0) | BIT(ARM_R1); + const s8 *tmp = bpf2a32[TMP_REG_1]; + + #if __LINUX_ARM_ARCH__ == 7 +@@ -495,11 +508,17 @@ static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) + emit(ARM_MOV_R(ARM_R0, rm), ctx); + } + ++ /* Push caller-saved registers on stack */ ++ emit(ARM_PUSH(CALLER_MASK & ~exclude_mask), ctx); ++ + /* Call appropriate function */ + emit_mov_i(ARM_IP, op == BPF_DIV ? + (u32)jit_udiv32 : (u32)jit_mod32, ctx); + emit_blx_r(ARM_IP, ctx); + ++ /* Restore caller-saved registers from stack */ ++ emit(ARM_POP(CALLER_MASK & ~exclude_mask), ctx); ++ + /* Save return value */ + if (rd != ARM_R0) + emit(ARM_MOV_R(rd, ARM_R0), ctx); +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +index 343ecf0e8973a..06b36cc65865c 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi ++++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +@@ -405,9 +405,9 @@ + interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <0>; /* fixed up by bootloader */ + clocks = <&clockgen QORIQ_CLK_HWACCEL 1>; +- voltage-ranges = <1800 1800 3300 3300>; ++ voltage-ranges = <1800 1800>; + sdhci,auto-cmd12; +- broken-cd; ++ non-removable; + little-endian; + bus-width = <4>; + status = "disabled"; +diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi +index 988f8ab679ad6..40f5e7a3b0644 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi +@@ -91,7 +91,7 @@ + #size-cells = <1>; + compatible = "jedec,spi-nor"; + spi-max-frequency = <80000000>; +- spi-tx-bus-width = <4>; ++ spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + }; + }; +diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts +index 4e2820d19244a..a2b24d4d4e3e7 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts ++++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts +@@ -48,7 +48,7 @@ + #size-cells = <1>; + compatible = "jedec,spi-nor"; + spi-max-frequency = <80000000>; +- spi-tx-bus-width = <4>; ++ spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + }; + }; +diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi +index d0456daefda88..9db9b90bf2bc9 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi +@@ -102,6 +102,7 @@ + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <950000>; + regulator-boot-on; ++ regulator-always-on; + regulator-ramp-delay = <3125>; + nxp,dvs-run-voltage = <950000>; + nxp,dvs-standby-voltage = <850000>; +diff --git a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi +index 54eaf3d6055b1..3b2d627a03428 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi +@@ -101,7 +101,7 @@ + #size-cells = <1>; + compatible = "jedec,spi-nor"; + spi-max-frequency = <80000000>; +- spi-tx-bus-width = <4>; ++ spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + }; + }; +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi +index aa78e0d8c72b2..fc178eebf8aa4 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi +@@ -74,7 +74,7 @@ + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <80000000>; +- spi-tx-bus-width = <4>; ++ spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + }; + }; +diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts +index 4d2035e3dd7cc..4886f3e31587a 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts ++++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts +@@ -337,6 +337,8 @@ + #size-cells = <1>; + compatible = "micron,n25q256a", "jedec,spi-nor"; + spi-max-frequency = <29000000>; ++ spi-tx-bus-width = <1>; ++ spi-rx-bus-width = <4>; + }; + }; + +diff --git a/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts b/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts +index f593e4ff62e1c..564746d5000d5 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts ++++ b/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts +@@ -281,7 +281,7 @@ + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; +- spi-tx-bus-width = <4>; ++ spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + m25p,fast-read; + spi-max-frequency = <50000000>; +diff --git a/arch/arm64/boot/dts/qcom/pm8150.dtsi b/arch/arm64/boot/dts/qcom/pm8150.dtsi +index c566a64b1373f..00385b1fd358f 100644 +--- a/arch/arm64/boot/dts/qcom/pm8150.dtsi ++++ b/arch/arm64/boot/dts/qcom/pm8150.dtsi +@@ -48,7 +48,7 @@ + #size-cells = <0>; + + pon: power-on@800 { +- compatible = "qcom,pm8916-pon"; ++ compatible = "qcom,pm8998-pon"; + reg = <0x0800>; + + pon_pwrkey: pwrkey { +diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi +index c08f074106994..188c5768a55ae 100644 +--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi +@@ -1437,9 +1437,9 @@ + + cpufreq_hw: cpufreq@18591000 { + compatible = "qcom,cpufreq-epss"; +- reg = <0 0x18591100 0 0x900>, +- <0 0x18592100 0 0x900>, +- <0 0x18593100 0 0x900>; ++ reg = <0 0x18591000 0 0x1000>, ++ <0 0x18592000 0 0x1000>, ++ <0 0x18593000 0 0x1000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>; + clock-names = "xo", "alternate"; + #freq-domain-cells = <1>; +diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h +index 35fb8ee6dd33e..fd43d876892ec 100644 +--- a/arch/mips/include/asm/mips-cps.h ++++ b/arch/mips/include/asm/mips-cps.h +@@ -10,8 +10,6 @@ + #include <linux/io.h> + #include <linux/types.h> + +-#include <asm/mips-boards/launch.h> +- + extern unsigned long __cps_access_bad_size(void) + __compiletime_error("Bad size for CPS accessor"); + +@@ -167,30 +165,11 @@ static inline uint64_t mips_cps_cluster_config(unsigned int cluster) + */ + static inline unsigned int mips_cps_numcores(unsigned int cluster) + { +- unsigned int ncores; +- + if (!mips_cm_present()) + return 0; + + /* Add one before masking to handle 0xff indicating no cores */ +- ncores = (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES; +- +- if (IS_ENABLED(CONFIG_SOC_MT7621)) { +- struct cpulaunch *launch; +- +- /* +- * Ralink MT7621S SoC is single core, but the GCR_CONFIG method +- * always reports 2 cores. Check the second core's LAUNCH_FREADY +- * flag to detect if the second core is missing. This method +- * only works before the core has been started. +- */ +- launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH); +- launch += 2; /* MT7621 has 2 VPEs per core */ +- if (!(launch->flags & LAUNCH_FREADY)) +- ncores = 1; +- } +- +- return ncores; ++ return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES; + } + + /** +diff --git a/arch/powerpc/boot/dts/fsl/t1023rdb.dts b/arch/powerpc/boot/dts/fsl/t1023rdb.dts +index 5ba6fbfca2742..f82f85c65964c 100644 +--- a/arch/powerpc/boot/dts/fsl/t1023rdb.dts ++++ b/arch/powerpc/boot/dts/fsl/t1023rdb.dts +@@ -154,7 +154,7 @@ + + fm1mac3: ethernet@e4000 { + phy-handle = <&sgmii_aqr_phy3>; +- phy-connection-type = "sgmii-2500"; ++ phy-connection-type = "2500base-x"; + sleep = <&rcpm 0x20000000>; + }; + +diff --git a/arch/powerpc/include/asm/book3s/32/kup.h b/arch/powerpc/include/asm/book3s/32/kup.h +index d4b145b279f6c..9f38040f0641d 100644 +--- a/arch/powerpc/include/asm/book3s/32/kup.h ++++ b/arch/powerpc/include/asm/book3s/32/kup.h +@@ -136,6 +136,14 @@ static inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap) + if (kuap_is_disabled()) + return; + ++ if (unlikely(kuap != KUAP_NONE)) { ++ current->thread.kuap = KUAP_NONE; ++ kuap_lock(kuap, false); ++ } ++ ++ if (likely(regs->kuap == KUAP_NONE)) ++ return; ++ + current->thread.kuap = regs->kuap; + + kuap_unlock(regs->kuap, false); +diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h +index 6b800d3e2681f..a925dbc5833c7 100644 +--- a/arch/powerpc/include/asm/interrupt.h ++++ b/arch/powerpc/include/asm/interrupt.h +@@ -525,10 +525,9 @@ static __always_inline long ____##func(struct pt_regs *regs) + /* kernel/traps.c */ + DECLARE_INTERRUPT_HANDLER_NMI(system_reset_exception); + #ifdef CONFIG_PPC_BOOK3S_64 +-DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception); +-#else +-DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception); ++DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async); + #endif ++DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception); + DECLARE_INTERRUPT_HANDLER(SMIException); + DECLARE_INTERRUPT_HANDLER(handle_hmi_exception); + DECLARE_INTERRUPT_HANDLER(unknown_exception); +diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c +index 111249fd619de..038ce8d9061d1 100644 +--- a/arch/powerpc/kernel/dma-iommu.c ++++ b/arch/powerpc/kernel/dma-iommu.c +@@ -184,6 +184,15 @@ u64 dma_iommu_get_required_mask(struct device *dev) + struct iommu_table *tbl = get_iommu_table_base(dev); + u64 mask; + ++ if (dev_is_pci(dev)) { ++ u64 bypass_mask = dma_direct_get_required_mask(dev); ++ ++ if (dma_iommu_dma_supported(dev, bypass_mask)) { ++ dev_info(dev, "%s: returning bypass mask 0x%llx\n", __func__, bypass_mask); ++ return bypass_mask; ++ } ++ } ++ + if (!tbl) + return 0; + +diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S +index 37859e62a8dcb..eaf1f72131a18 100644 +--- a/arch/powerpc/kernel/exceptions-64s.S ++++ b/arch/powerpc/kernel/exceptions-64s.S +@@ -1243,7 +1243,7 @@ EXC_COMMON_BEGIN(machine_check_common) + li r10,MSR_RI + mtmsrd r10,1 + addi r3,r1,STACK_FRAME_OVERHEAD +- bl machine_check_exception ++ bl machine_check_exception_async + b interrupt_return_srr + + +@@ -1303,7 +1303,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) + subi r12,r12,1 + sth r12,PACA_IN_MCE(r13) + +- /* Invoke machine_check_exception to print MCE event and panic. */ ++ /* ++ * Invoke machine_check_exception to print MCE event and panic. ++ * This is the NMI version of the handler because we are called from ++ * the early handler which is a true NMI. ++ */ + addi r3,r1,STACK_FRAME_OVERHEAD + bl machine_check_exception + +@@ -1665,27 +1669,30 @@ EXC_COMMON_BEGIN(program_check_common) + */ + + andi. r10,r12,MSR_PR +- bne 2f /* If userspace, go normal path */ ++ bne .Lnormal_stack /* If userspace, go normal path */ + + andis. r10,r12,(SRR1_PROGTM)@h +- bne 1f /* If TM, emergency */ ++ bne .Lemergency_stack /* If TM, emergency */ + + cmpdi r1,-INT_FRAME_SIZE /* check if r1 is in userspace */ +- blt 2f /* normal path if not */ ++ blt .Lnormal_stack /* normal path if not */ + + /* Use the emergency stack */ +-1: andi. r10,r12,MSR_PR /* Set CR0 correctly for label */ ++.Lemergency_stack: ++ andi. r10,r12,MSR_PR /* Set CR0 correctly for label */ + /* 3 in EXCEPTION_PROLOG_COMMON */ + mr r10,r1 /* Save r1 */ + ld r1,PACAEMERGSP(r13) /* Use emergency stack */ + subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ + __ISTACK(program_check)=0 + __GEN_COMMON_BODY program_check +- b 3f +-2: ++ b .Ldo_program_check ++ ++.Lnormal_stack: + __ISTACK(program_check)=1 + __GEN_COMMON_BODY program_check +-3: ++ ++.Ldo_program_check: + addi r3,r1,STACK_FRAME_OVERHEAD + bl program_check_exception + REST_NVGPRS(r1) /* instruction emulation may change GPRs */ +diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c +index d56254f05e174..08356ec9bfed4 100644 +--- a/arch/powerpc/kernel/traps.c ++++ b/arch/powerpc/kernel/traps.c +@@ -341,10 +341,16 @@ static bool exception_common(int signr, struct pt_regs *regs, int code, + return false; + } + +- show_signal_msg(signr, regs, code, addr); ++ /* ++ * Must not enable interrupts even for user-mode exception, because ++ * this can be called from machine check, which may be a NMI or IRQ ++ * which don't like interrupts being enabled. Could check for ++ * in_hardirq || in_nmi perhaps, but there doesn't seem to be a good ++ * reason why _exception() should enable irqs for an exception handler, ++ * the handlers themselves do that directly. ++ */ + +- if (arch_irqs_disabled()) +- interrupt_cond_local_irq_enable(regs); ++ show_signal_msg(signr, regs, code, addr); + + current->thread.trap_nr = code; + +@@ -791,24 +797,22 @@ void die_mce(const char *str, struct pt_regs *regs, long err) + * do_exit() checks for in_interrupt() and panics in that case, so + * exit the irq/nmi before calling die. + */ +- if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) +- irq_exit(); +- else ++ if (in_nmi()) + nmi_exit(); ++ else ++ irq_exit(); + die(str, regs, err); + } + + /* +- * BOOK3S_64 does not call this handler as a non-maskable interrupt ++ * BOOK3S_64 does not usually call this handler as a non-maskable interrupt + * (it uses its own early real-mode handler to handle the MCE proper + * and then raises irq_work to call this handler when interrupts are +- * enabled). ++ * enabled). The only time when this is not true is if the early handler ++ * is unrecoverable, then it does call this directly to try to get a ++ * message out. + */ +-#ifdef CONFIG_PPC_BOOK3S_64 +-DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception) +-#else +-DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception) +-#endif ++static void __machine_check_exception(struct pt_regs *regs) + { + int recover = 0; + +@@ -842,12 +846,19 @@ bail: + /* Must die if the interrupt is not recoverable */ + if (!(regs->msr & MSR_RI)) + die_mce("Unrecoverable Machine check", regs, SIGBUS); ++} + + #ifdef CONFIG_PPC_BOOK3S_64 +- return; +-#else +- return 0; ++DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async) ++{ ++ __machine_check_exception(regs); ++} + #endif ++DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception) ++{ ++ __machine_check_exception(regs); ++ ++ return 0; + } + + DEFINE_INTERRUPT_HANDLER(SMIException) /* async? */ +diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c +index beb12cbc8c299..a7759aa8043d2 100644 +--- a/arch/powerpc/net/bpf_jit_comp32.c ++++ b/arch/powerpc/net/bpf_jit_comp32.c +@@ -355,7 +355,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * + PPC_LI32(_R0, imm); + EMIT(PPC_RAW_ADDC(dst_reg, dst_reg, _R0)); + } +- if (imm >= 0) ++ if (imm >= 0 || (BPF_OP(code) == BPF_SUB && imm == 0x80000000)) + EMIT(PPC_RAW_ADDZE(dst_reg_h, dst_reg_h)); + else + EMIT(PPC_RAW_ADDME(dst_reg_h, dst_reg_h)); +@@ -623,7 +623,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * + EMIT(PPC_RAW_LI(dst_reg_h, 0)); + break; + case BPF_ALU | BPF_ARSH | BPF_X: /* (s32) dst >>= src */ +- EMIT(PPC_RAW_SRAW(dst_reg_h, dst_reg, src_reg)); ++ EMIT(PPC_RAW_SRAW(dst_reg, dst_reg, src_reg)); + break; + case BPF_ALU64 | BPF_ARSH | BPF_X: /* (s64) dst >>= src */ + bpf_set_seen_register(ctx, tmp_reg); +@@ -1073,7 +1073,7 @@ cond_branch: + break; + case BPF_JMP32 | BPF_JSET | BPF_K: + /* andi does not sign-extend the immediate */ +- if (imm >= -32768 && imm < 32768) { ++ if (imm >= 0 && imm < 32768) { + /* PPC_ANDI is _only/always_ dot-form */ + EMIT(PPC_RAW_ANDI(_R0, dst_reg, imm)); + } else { +@@ -1103,7 +1103,7 @@ cond_branch: + return -EOPNOTSUPP; + } + if (BPF_CLASS(code) == BPF_ALU && !fp->aux->verifier_zext && +- !insn_is_zext(&insn[i + 1])) ++ !insn_is_zext(&insn[i + 1]) && !(BPF_OP(code) == BPF_END && imm == 64)) + EMIT(PPC_RAW_LI(dst_reg_h, 0)); + } + +diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c +index b87a63dba9c8f..dff4a2930970b 100644 +--- a/arch/powerpc/net/bpf_jit_comp64.c ++++ b/arch/powerpc/net/bpf_jit_comp64.c +@@ -328,18 +328,25 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * + EMIT(PPC_RAW_SUB(dst_reg, dst_reg, src_reg)); + goto bpf_alu32_trunc; + case BPF_ALU | BPF_ADD | BPF_K: /* (u32) dst += (u32) imm */ +- case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */ + case BPF_ALU64 | BPF_ADD | BPF_K: /* dst += imm */ ++ if (!imm) { ++ goto bpf_alu32_trunc; ++ } else if (imm >= -32768 && imm < 32768) { ++ EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm))); ++ } else { ++ PPC_LI32(b2p[TMP_REG_1], imm); ++ EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1])); ++ } ++ goto bpf_alu32_trunc; ++ case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */ + case BPF_ALU64 | BPF_SUB | BPF_K: /* dst -= imm */ +- if (BPF_OP(code) == BPF_SUB) +- imm = -imm; +- if (imm) { +- if (imm >= -32768 && imm < 32768) +- EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm))); +- else { +- PPC_LI32(b2p[TMP_REG_1], imm); +- EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1])); +- } ++ if (!imm) { ++ goto bpf_alu32_trunc; ++ } else if (imm > -32768 && imm <= 32768) { ++ EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(-imm))); ++ } else { ++ PPC_LI32(b2p[TMP_REG_1], imm); ++ EMIT(PPC_RAW_SUB(dst_reg, dst_reg, b2p[TMP_REG_1])); + } + goto bpf_alu32_trunc; + case BPF_ALU | BPF_MUL | BPF_X: /* (u32) dst *= (u32) src */ +@@ -389,8 +396,14 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * + case BPF_ALU64 | BPF_DIV | BPF_K: /* dst /= imm */ + if (imm == 0) + return -EINVAL; +- else if (imm == 1) +- goto bpf_alu32_trunc; ++ if (imm == 1) { ++ if (BPF_OP(code) == BPF_DIV) { ++ goto bpf_alu32_trunc; ++ } else { ++ EMIT(PPC_RAW_LI(dst_reg, 0)); ++ break; ++ } ++ } + + PPC_LI32(b2p[TMP_REG_1], imm); + switch (BPF_CLASS(code)) { +diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c +index bc15200852b7c..09fafcf2d3a06 100644 +--- a/arch/powerpc/platforms/pseries/eeh_pseries.c ++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c +@@ -867,6 +867,10 @@ static int __init eeh_pseries_init(void) + if (is_kdump_kernel() || reset_devices) { + pr_info("Issue PHB reset ...\n"); + list_for_each_entry(phb, &hose_list, list_node) { ++ // Skip if the slot is empty ++ if (list_empty(&PCI_DN(phb->dn)->child_list)) ++ continue; ++ + pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list); + config_addr = pseries_eeh_get_pe_config_addr(pdn); + +diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile +index bc74afdbf31e2..83ee0e71204cb 100644 +--- a/arch/riscv/Makefile ++++ b/arch/riscv/Makefile +@@ -108,6 +108,12 @@ PHONY += vdso_install + vdso_install: + $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@ + ++ifeq ($(CONFIG_MMU),y) ++prepare: vdso_prepare ++vdso_prepare: prepare0 ++ $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h ++endif ++ + ifneq ($(CONFIG_XIP_KERNEL),y) + ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN),yy) + KBUILD_IMAGE := $(boot)/loader.bin +diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h +index b933b1583c9fd..34fbb3ea21d5b 100644 +--- a/arch/riscv/include/asm/syscall.h ++++ b/arch/riscv/include/asm/syscall.h +@@ -82,4 +82,5 @@ static inline int syscall_get_arch(struct task_struct *task) + #endif + } + ++asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t); + #endif /* _ASM_RISCV_SYSCALL_H */ +diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h +index 1453a2f563bcc..208e31bc5d1c2 100644 +--- a/arch/riscv/include/asm/vdso.h ++++ b/arch/riscv/include/asm/vdso.h +@@ -8,27 +8,32 @@ + #ifndef _ASM_RISCV_VDSO_H + #define _ASM_RISCV_VDSO_H + +-#include <linux/types.h> + +-#ifndef CONFIG_GENERIC_TIME_VSYSCALL +-struct vdso_data { +-}; +-#endif ++/* ++ * All systems with an MMU have a VDSO, but systems without an MMU don't ++ * support shared libraries and therefor don't have one. ++ */ ++#ifdef CONFIG_MMU + ++#include <linux/types.h> + /* +- * The VDSO symbols are mapped into Linux so we can just use regular symbol +- * addressing to get their offsets in userspace. The symbols are mapped at an +- * offset of 0, but since the linker must support setting weak undefined +- * symbols to the absolute address 0 it also happens to support other low +- * addresses even when the code model suggests those low addresses would not +- * otherwise be availiable. ++ * All systems with an MMU have a VDSO, but systems without an MMU don't ++ * support shared libraries and therefor don't have one. + */ ++#ifdef CONFIG_MMU ++ ++#define __VVAR_PAGES 1 ++ ++#ifndef __ASSEMBLY__ ++#include <generated/vdso-offsets.h> ++ + #define VDSO_SYMBOL(base, name) \ +-({ \ +- extern const char __vdso_##name[]; \ +- (void __user *)((unsigned long)(base) + __vdso_##name); \ +-}) ++ (void __user *)((unsigned long)(base) + __vdso_##name##_offset) ++ ++#endif /* CONFIG_MMU */ ++ ++#endif /* !__ASSEMBLY__ */ + +-asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t); ++#endif /* CONFIG_MMU */ + + #endif /* _ASM_RISCV_VDSO_H */ +diff --git a/arch/riscv/include/uapi/asm/unistd.h b/arch/riscv/include/uapi/asm/unistd.h +index 4b989ae15d59f..8062996c2dfd0 100644 +--- a/arch/riscv/include/uapi/asm/unistd.h ++++ b/arch/riscv/include/uapi/asm/unistd.h +@@ -18,9 +18,10 @@ + #ifdef __LP64__ + #define __ARCH_WANT_NEW_STAT + #define __ARCH_WANT_SET_GET_RLIMIT +-#define __ARCH_WANT_SYS_CLONE3 + #endif /* __LP64__ */ + ++#define __ARCH_WANT_SYS_CLONE3 ++ + #include <asm-generic/unistd.h> + + /* +diff --git a/arch/riscv/kernel/syscall_table.c b/arch/riscv/kernel/syscall_table.c +index a63c667c27b35..44b1420a22705 100644 +--- a/arch/riscv/kernel/syscall_table.c ++++ b/arch/riscv/kernel/syscall_table.c +@@ -7,7 +7,6 @@ + #include <linux/linkage.h> + #include <linux/syscalls.h> + #include <asm-generic/syscalls.h> +-#include <asm/vdso.h> + #include <asm/syscall.h> + + #undef __SYSCALL +diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c +index 25a3b88495991..b70956d804081 100644 +--- a/arch/riscv/kernel/vdso.c ++++ b/arch/riscv/kernel/vdso.c +@@ -12,14 +12,24 @@ + #include <linux/binfmts.h> + #include <linux/err.h> + #include <asm/page.h> ++#include <asm/vdso.h> ++ + #ifdef CONFIG_GENERIC_TIME_VSYSCALL + #include <vdso/datapage.h> + #else +-#include <asm/vdso.h> ++struct vdso_data { ++}; + #endif + + extern char vdso_start[], vdso_end[]; + ++enum vvar_pages { ++ VVAR_DATA_PAGE_OFFSET, ++ VVAR_NR_PAGES, ++}; ++ ++#define VVAR_SIZE (VVAR_NR_PAGES << PAGE_SHIFT) ++ + static unsigned int vdso_pages __ro_after_init; + static struct page **vdso_pagelist __ro_after_init; + +@@ -38,7 +48,7 @@ static int __init vdso_init(void) + + vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; + vdso_pagelist = +- kcalloc(vdso_pages + 1, sizeof(struct page *), GFP_KERNEL); ++ kcalloc(vdso_pages + VVAR_NR_PAGES, sizeof(struct page *), GFP_KERNEL); + if (unlikely(vdso_pagelist == NULL)) { + pr_err("vdso: pagelist allocation failed\n"); + return -ENOMEM; +@@ -63,38 +73,41 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, + unsigned long vdso_base, vdso_len; + int ret; + +- vdso_len = (vdso_pages + 1) << PAGE_SHIFT; ++ BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES); ++ ++ vdso_len = (vdso_pages + VVAR_NR_PAGES) << PAGE_SHIFT; ++ ++ if (mmap_write_lock_killable(mm)) ++ return -EINTR; + +- mmap_write_lock(mm); + vdso_base = get_unmapped_area(NULL, 0, vdso_len, 0, 0); + if (IS_ERR_VALUE(vdso_base)) { + ret = vdso_base; + goto end; + } + +- /* +- * Put vDSO base into mm struct. We need to do this before calling +- * install_special_mapping or the perf counter mmap tracking code +- * will fail to recognise it as a vDSO (since arch_vma_name fails). +- */ +- mm->context.vdso = (void *)vdso_base; ++ mm->context.vdso = NULL; ++ ret = install_special_mapping(mm, vdso_base, VVAR_SIZE, ++ (VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]); ++ if (unlikely(ret)) ++ goto end; + + ret = +- install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT, ++ install_special_mapping(mm, vdso_base + VVAR_SIZE, ++ vdso_pages << PAGE_SHIFT, + (VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC), + vdso_pagelist); + +- if (unlikely(ret)) { +- mm->context.vdso = NULL; ++ if (unlikely(ret)) + goto end; +- } + +- vdso_base += (vdso_pages << PAGE_SHIFT); +- ret = install_special_mapping(mm, vdso_base, PAGE_SIZE, +- (VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]); ++ /* ++ * Put vDSO base into mm struct. We need to do this before calling ++ * install_special_mapping or the perf counter mmap tracking code ++ * will fail to recognise it as a vDSO (since arch_vma_name fails). ++ */ ++ mm->context.vdso = (void *)vdso_base + VVAR_SIZE; + +- if (unlikely(ret)) +- mm->context.vdso = NULL; + end: + mmap_write_unlock(mm); + return ret; +@@ -105,7 +118,7 @@ const char *arch_vma_name(struct vm_area_struct *vma) + if (vma->vm_mm && (vma->vm_start == (long)vma->vm_mm->context.vdso)) + return "[vdso]"; + if (vma->vm_mm && (vma->vm_start == +- (long)vma->vm_mm->context.vdso + PAGE_SIZE)) ++ (long)vma->vm_mm->context.vdso - VVAR_SIZE)) + return "[vdso_data]"; + return NULL; + } +diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile +index 24d936c147cdf..f8cb9144a2842 100644 +--- a/arch/riscv/kernel/vdso/Makefile ++++ b/arch/riscv/kernel/vdso/Makefile +@@ -23,10 +23,10 @@ ifneq ($(c-gettimeofday-y),) + endif + + # Build rules +-targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds vdso-syms.S ++targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds + obj-vdso := $(addprefix $(obj)/, $(obj-vdso)) + +-obj-y += vdso.o vdso-syms.o ++obj-y += vdso.o + CPPFLAGS_vdso.lds += -P -C -U$(ARCH) + + # Disable -pg to prevent insert call site +@@ -43,20 +43,22 @@ $(obj)/vdso.o: $(obj)/vdso.so + # link rule for the .so file, .lds has to be first + $(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE + $(call if_changed,vdsold) +-LDFLAGS_vdso.so.dbg = -shared -s -soname=linux-vdso.so.1 \ ++LDFLAGS_vdso.so.dbg = -shared -S -soname=linux-vdso.so.1 \ + --build-id=sha1 --hash-style=both --eh-frame-hdr + +-# We also create a special relocatable object that should mirror the symbol +-# table and layout of the linked DSO. With ld --just-symbols we can then +-# refer to these symbols in the kernel code rather than hand-coded addresses. +-$(obj)/vdso-syms.S: $(obj)/vdso.so FORCE +- $(call if_changed,so2s) +- + # strip rule for the .so file + $(obj)/%.so: OBJCOPYFLAGS := -S + $(obj)/%.so: $(obj)/%.so.dbg FORCE + $(call if_changed,objcopy) + ++# Generate VDSO offsets using helper script ++gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh ++quiet_cmd_vdsosym = VDSOSYM $@ ++ cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ ++ ++include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE ++ $(call if_changed,vdsosym) ++ + # actual build commands + # The DSO images are built using a special linker script + # Make sure only to export the intended __vdso_xxx symbol offsets. +@@ -65,11 +67,6 @@ quiet_cmd_vdsold = VDSOLD $@ + $(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ && \ + rm $@.tmp + +-# Extracts symbol offsets from the VDSO, converting them into an assembly file +-# that contains the same symbols at the same offsets. +-quiet_cmd_so2s = SO2S $@ +- cmd_so2s = $(NM) -D $< | $(srctree)/$(src)/so2s.sh > $@ +- + # install commands for the unstripped file + quiet_cmd_vdso_install = INSTALL $@ + cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ +diff --git a/arch/riscv/kernel/vdso/gen_vdso_offsets.sh b/arch/riscv/kernel/vdso/gen_vdso_offsets.sh +new file mode 100755 +index 0000000000000..c2e5613f34951 +--- /dev/null ++++ b/arch/riscv/kernel/vdso/gen_vdso_offsets.sh +@@ -0,0 +1,5 @@ ++#!/bin/sh ++# SPDX-License-Identifier: GPL-2.0 ++ ++LC_ALL=C ++sed -n -e 's/^[0]\+\(0[0-9a-fA-F]*\) . \(__vdso_[a-zA-Z0-9_]*\)$/\#define \2_offset\t0x\1/p' +diff --git a/arch/riscv/kernel/vdso/so2s.sh b/arch/riscv/kernel/vdso/so2s.sh +deleted file mode 100755 +index e64cb6d9440e7..0000000000000 +--- a/arch/riscv/kernel/vdso/so2s.sh ++++ /dev/null +@@ -1,6 +0,0 @@ +-#!/bin/sh +-# SPDX-License-Identifier: GPL-2.0+ +-# Copyright 2020 Palmer Dabbelt <palmerdabbelt@google.com> +- +-sed 's!\([0-9a-f]*\) T \([a-z0-9_]*\)\(@@LINUX_4.15\)*!.global \2\n.set \2,0x\1!' \ +-| grep '^\.' +diff --git a/arch/riscv/kernel/vdso/vdso.lds.S b/arch/riscv/kernel/vdso/vdso.lds.S +index e6f558bca71bb..e9111f700af08 100644 +--- a/arch/riscv/kernel/vdso/vdso.lds.S ++++ b/arch/riscv/kernel/vdso/vdso.lds.S +@@ -3,12 +3,13 @@ + * Copyright (C) 2012 Regents of the University of California + */ + #include <asm/page.h> ++#include <asm/vdso.h> + + OUTPUT_ARCH(riscv) + + SECTIONS + { +- PROVIDE(_vdso_data = . + PAGE_SIZE); ++ PROVIDE(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE); + . = SIZEOF_HEADERS; + + .hash : { *(.hash) } :text +diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c +index 094118663285d..89f81067e09ed 100644 +--- a/arch/riscv/mm/cacheflush.c ++++ b/arch/riscv/mm/cacheflush.c +@@ -16,6 +16,8 @@ static void ipi_remote_fence_i(void *info) + + void flush_icache_all(void) + { ++ local_flush_icache_all(); ++ + if (IS_ENABLED(CONFIG_RISCV_SBI)) + sbi_remote_fence_i(NULL); + else +diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c +index 840d8594437d5..1a374d021e256 100644 +--- a/arch/s390/net/bpf_jit_comp.c ++++ b/arch/s390/net/bpf_jit_comp.c +@@ -1826,7 +1826,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) + jit.addrs = kvcalloc(fp->len + 1, sizeof(*jit.addrs), GFP_KERNEL); + if (jit.addrs == NULL) { + fp = orig_fp; +- goto out; ++ goto free_addrs; + } + /* + * Three initial passes: +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index 88fb922c23a0a..51341f2e218de 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -1400,7 +1400,7 @@ config HIGHMEM4G + + config HIGHMEM64G + bool "64GB" +- depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6 ++ depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !MWINCHIP3D && !MK6 + select X86_PAE + help + Select this if you have a 32-bit processor and more than 4 +diff --git a/arch/x86/include/asm/entry-common.h b/arch/x86/include/asm/entry-common.h +index 14ebd21965691..43184640b579a 100644 +--- a/arch/x86/include/asm/entry-common.h ++++ b/arch/x86/include/asm/entry-common.h +@@ -25,7 +25,7 @@ static __always_inline void arch_check_user_regs(struct pt_regs *regs) + * For !SMAP hardware we patch out CLAC on entry. + */ + if (boot_cpu_has(X86_FEATURE_SMAP) || +- (IS_ENABLED(CONFIG_64_BIT) && boot_cpu_has(X86_FEATURE_XENPV))) ++ (IS_ENABLED(CONFIG_64BIT) && boot_cpu_has(X86_FEATURE_XENPV))) + mask |= X86_EFLAGS_AC; + + WARN_ON_ONCE(flags & mask); +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c +index 64b805bd6a542..340caa7aebfba 100644 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -320,6 +320,7 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c) + #ifdef CONFIG_X86_SMAP + cr4_set_bits(X86_CR4_SMAP); + #else ++ clear_cpu_cap(c, X86_FEATURE_SMAP); + cr4_clear_bits(X86_CR4_SMAP); + #endif + } +diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c +index 38837dad46e62..391a4e2b86049 100644 +--- a/arch/x86/kernel/early-quirks.c ++++ b/arch/x86/kernel/early-quirks.c +@@ -714,12 +714,6 @@ static struct chipset early_qrk[] __initdata = { + */ + { PCI_VENDOR_ID_INTEL, 0x0f00, + PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, +- { PCI_VENDOR_ID_INTEL, 0x3e20, +- PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, +- { PCI_VENDOR_ID_INTEL, 0x3ec4, +- PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, +- { PCI_VENDOR_ID_INTEL, 0x8a12, +- PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, + { PCI_VENDOR_ID_BROADCOM, 0x4331, + PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset}, + {} +diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c +index 445c57c9c5397..fa17a27390ab0 100644 +--- a/arch/x86/kernel/fpu/signal.c ++++ b/arch/x86/kernel/fpu/signal.c +@@ -379,9 +379,14 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx, + sizeof(fpu->state.fxsave))) + return -EFAULT; + +- /* Reject invalid MXCSR values. */ +- if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask) +- return -EINVAL; ++ if (IS_ENABLED(CONFIG_X86_64)) { ++ /* Reject invalid MXCSR values. */ ++ if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask) ++ return -EINVAL; ++ } else { ++ /* Mask invalid bits out for historical reasons (broken hardware). */ ++ fpu->state.fxsave.mxcsr &= ~mxcsr_feature_mask; ++ } + + /* Enforce XFEATURE_MASK_FPSSE when XSAVE is enabled */ + if (use_xsave()) +diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c +index 42fc41dd0e1f1..882213df37130 100644 +--- a/arch/x86/kernel/hpet.c ++++ b/arch/x86/kernel/hpet.c +@@ -10,6 +10,7 @@ + #include <asm/irq_remapping.h> + #include <asm/hpet.h> + #include <asm/time.h> ++#include <asm/mwait.h> + + #undef pr_fmt + #define pr_fmt(fmt) "hpet: " fmt +@@ -916,6 +917,83 @@ static bool __init hpet_counting(void) + return false; + } + ++static bool __init mwait_pc10_supported(void) ++{ ++ unsigned int eax, ebx, ecx, mwait_substates; ++ ++ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) ++ return false; ++ ++ if (!cpu_feature_enabled(X86_FEATURE_MWAIT)) ++ return false; ++ ++ if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) ++ return false; ++ ++ cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates); ++ ++ return (ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) && ++ (ecx & CPUID5_ECX_INTERRUPT_BREAK) && ++ (mwait_substates & (0xF << 28)); ++} ++ ++/* ++ * Check whether the system supports PC10. If so force disable HPET as that ++ * stops counting in PC10. This check is overbroad as it does not take any ++ * of the following into account: ++ * ++ * - ACPI tables ++ * - Enablement of intel_idle ++ * - Command line arguments which limit intel_idle C-state support ++ * ++ * That's perfectly fine. HPET is a piece of hardware designed by committee ++ * and the only reasons why it is still in use on modern systems is the ++ * fact that it is impossible to reliably query TSC and CPU frequency via ++ * CPUID or firmware. ++ * ++ * If HPET is functional it is useful for calibrating TSC, but this can be ++ * done via PMTIMER as well which seems to be the last remaining timer on ++ * X86/INTEL platforms that has not been completely wreckaged by feature ++ * creep. ++ * ++ * In theory HPET support should be removed altogether, but there are older ++ * systems out there which depend on it because TSC and APIC timer are ++ * dysfunctional in deeper C-states. ++ * ++ * It's only 20 years now that hardware people have been asked to provide ++ * reliable and discoverable facilities which can be used for timekeeping ++ * and per CPU timer interrupts. ++ * ++ * The probability that this problem is going to be solved in the ++ * forseeable future is close to zero, so the kernel has to be cluttered ++ * with heuristics to keep up with the ever growing amount of hardware and ++ * firmware trainwrecks. Hopefully some day hardware people will understand ++ * that the approach of "This can be fixed in software" is not sustainable. ++ * Hope dies last... ++ */ ++static bool __init hpet_is_pc10_damaged(void) ++{ ++ unsigned long long pcfg; ++ ++ /* Check whether PC10 substates are supported */ ++ if (!mwait_pc10_supported()) ++ return false; ++ ++ /* Check whether PC10 is enabled in PKG C-state limit */ ++ rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, pcfg); ++ if ((pcfg & 0xF) < 8) ++ return false; ++ ++ if (hpet_force_user) { ++ pr_warn("HPET force enabled via command line, but dysfunctional in PC10.\n"); ++ return false; ++ } ++ ++ pr_info("HPET dysfunctional in PC10. Force disabled.\n"); ++ boot_hpet_disable = true; ++ return true; ++} ++ + /** + * hpet_enable - Try to setup the HPET timer. Returns 1 on success. + */ +@@ -929,6 +1007,9 @@ int __init hpet_enable(void) + if (!is_hpet_capable()) + return 0; + ++ if (hpet_is_pc10_damaged()) ++ return 0; ++ + hpet_set_mapping(); + if (!hpet_virt_address) + return 0; +diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c +index 9f90f460a28cc..bf1033a62e480 100644 +--- a/arch/x86/kernel/sev-shared.c ++++ b/arch/x86/kernel/sev-shared.c +@@ -130,6 +130,8 @@ static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb, + } else { + ret = ES_VMM_ERROR; + } ++ } else if (ghcb->save.sw_exit_info_1 & 0xffffffff) { ++ ret = ES_VMM_ERROR; + } else { + ret = ES_OK; + } +diff --git a/arch/x86/platform/olpc/olpc.c b/arch/x86/platform/olpc/olpc.c +index ee2beda590d0d..1d4a00e767ece 100644 +--- a/arch/x86/platform/olpc/olpc.c ++++ b/arch/x86/platform/olpc/olpc.c +@@ -274,7 +274,7 @@ static struct olpc_ec_driver ec_xo1_driver = { + + static struct olpc_ec_driver ec_xo1_5_driver = { + .ec_cmd = olpc_xo1_ec_cmd, +-#ifdef CONFIG_OLPC_XO1_5_SCI ++#ifdef CONFIG_OLPC_XO15_SCI + /* + * XO-1.5 EC wakeups are available when olpc-xo15-sci driver is + * compiled in +diff --git a/arch/xtensa/include/asm/kmem_layout.h b/arch/xtensa/include/asm/kmem_layout.h +index 7cbf68ca71060..6fc05cba61a27 100644 +--- a/arch/xtensa/include/asm/kmem_layout.h ++++ b/arch/xtensa/include/asm/kmem_layout.h +@@ -78,7 +78,7 @@ + #endif + #define XCHAL_KIO_SIZE 0x10000000 + +-#if (!XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY) && defined(CONFIG_OF) ++#if (!XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY) && defined(CONFIG_USE_OF) + #define XCHAL_KIO_PADDR xtensa_get_kio_paddr() + #ifndef __ASSEMBLY__ + extern unsigned long xtensa_kio_paddr; +diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c +index a48bf2d10ac2d..80cc9770a8d2d 100644 +--- a/arch/xtensa/kernel/irq.c ++++ b/arch/xtensa/kernel/irq.c +@@ -145,7 +145,7 @@ unsigned xtensa_get_ext_irq_no(unsigned irq) + + void __init init_IRQ(void) + { +-#ifdef CONFIG_OF ++#ifdef CONFIG_USE_OF + irqchip_init(); + #else + #ifdef CONFIG_HAVE_SMP +diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c +index ed184106e4cf9..ee9082a142feb 100644 +--- a/arch/xtensa/kernel/setup.c ++++ b/arch/xtensa/kernel/setup.c +@@ -63,7 +63,7 @@ extern unsigned long initrd_end; + extern int initrd_below_start_ok; + #endif + +-#ifdef CONFIG_OF ++#ifdef CONFIG_USE_OF + void *dtb_start = __dtb_start; + #endif + +@@ -125,7 +125,7 @@ __tagtable(BP_TAG_INITRD, parse_tag_initrd); + + #endif /* CONFIG_BLK_DEV_INITRD */ + +-#ifdef CONFIG_OF ++#ifdef CONFIG_USE_OF + + static int __init parse_tag_fdt(const bp_tag_t *tag) + { +@@ -135,7 +135,7 @@ static int __init parse_tag_fdt(const bp_tag_t *tag) + + __tagtable(BP_TAG_FDT, parse_tag_fdt); + +-#endif /* CONFIG_OF */ ++#endif /* CONFIG_USE_OF */ + + static int __init parse_tag_cmdline(const bp_tag_t* tag) + { +@@ -183,7 +183,7 @@ static int __init parse_bootparam(const bp_tag_t *tag) + } + #endif + +-#ifdef CONFIG_OF ++#ifdef CONFIG_USE_OF + + #if !XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY + unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR; +@@ -232,7 +232,7 @@ void __init early_init_devtree(void *params) + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); + } + +-#endif /* CONFIG_OF */ ++#endif /* CONFIG_USE_OF */ + + /* + * Initialize architecture. (Early stage) +@@ -253,7 +253,7 @@ void __init init_arch(bp_tag_t *bp_start) + if (bp_start) + parse_bootparam(bp_start); + +-#ifdef CONFIG_OF ++#ifdef CONFIG_USE_OF + early_init_devtree(dtb_start); + #endif + +diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c +index 7e4d97dc8bd8f..38acda4f04e85 100644 +--- a/arch/xtensa/mm/mmu.c ++++ b/arch/xtensa/mm/mmu.c +@@ -101,7 +101,7 @@ void init_mmu(void) + + void init_kio(void) + { +-#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF) ++#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_USE_OF) + /* + * Update the IO area mapping in case xtensa_kio_paddr has changed + */ +diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c +index 148a4dd8cb9ac..418ada474a85d 100644 +--- a/drivers/bus/ti-sysc.c ++++ b/drivers/bus/ti-sysc.c +@@ -1468,6 +1468,9 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { + /* Quirks that need to be set based on detected module */ + SYSC_QUIRK("aess", 0, 0, 0x10, -ENODEV, 0x40000000, 0xffffffff, + SYSC_MODULE_QUIRK_AESS), ++ /* Errata i893 handling for dra7 dcan1 and 2 */ ++ SYSC_QUIRK("dcan", 0x4ae3c000, 0x20, -ENODEV, -ENODEV, 0xa3170504, 0xffffffff, ++ SYSC_QUIRK_CLKDM_NOAUTO), + SYSC_QUIRK("dcan", 0x48480000, 0x20, -ENODEV, -ENODEV, 0xa3170504, 0xffffffff, + SYSC_QUIRK_CLKDM_NOAUTO), + SYSC_QUIRK("dss", 0x4832a000, 0, 0x10, 0x14, 0x00000020, 0xffffffff, +@@ -2955,6 +2958,7 @@ static int sysc_init_soc(struct sysc *ddata) + break; + case SOC_AM3: + sysc_add_disabled(0x48310000); /* rng */ ++ break; + default: + break; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index 177a663a6a691..a1c5bd2859fc3 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -1082,6 +1082,7 @@ struct amdgpu_device { + + bool no_hw_access; + struct pci_saved_state *pci_state; ++ pci_channel_state_t pci_channel_state; + + struct amdgpu_reset_control *reset_cntl; + }; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +index 4fb15750b9bb4..b18c0697356c1 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +@@ -563,6 +563,7 @@ kfd_mem_dmaunmap_userptr(struct kgd_mem *mem, + + dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0); + sg_free_table(ttm->sg); ++ kfree(ttm->sg); + ttm->sg = NULL; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index d3247a5cceb4c..d60096b3b2c2a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -5329,6 +5329,8 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta + return PCI_ERS_RESULT_DISCONNECT; + } + ++ adev->pci_channel_state = state; ++ + switch (state) { + case pci_channel_io_normal: + return PCI_ERS_RESULT_CAN_RECOVER; +@@ -5471,6 +5473,10 @@ void amdgpu_pci_resume(struct pci_dev *pdev) + + DRM_INFO("PCI error: resume callback!!\n"); + ++ /* Only continue execution for the case of pci_channel_io_frozen */ ++ if (adev->pci_channel_state != pci_channel_io_frozen) ++ return; ++ + for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { + struct amdgpu_ring *ring = adev->rings[i]; + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +index b4ced45301bec..1795d448c7000 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +@@ -31,6 +31,8 @@ + /* delay 0.1 second to enable gfx off feature */ + #define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(100) + ++#define GFX_OFF_NO_DELAY 0 ++ + /* + * GPU GFX IP block helpers function. + */ +@@ -558,6 +560,8 @@ int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev) + + void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) + { ++ unsigned long delay = GFX_OFF_DELAY_ENABLE; ++ + if (!(adev->pm.pp_feature & PP_GFXOFF_MASK)) + return; + +@@ -573,8 +577,14 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) + + adev->gfx.gfx_off_req_count--; + +- if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state) +- schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE); ++ if (adev->gfx.gfx_off_req_count == 0 && ++ !adev->gfx.gfx_off_state) { ++ /* If going to s2idle, no need to wait */ ++ if (adev->in_s0ix) ++ delay = GFX_OFF_NO_DELAY; ++ schedule_delayed_work(&adev->gfx.gfx_off_delay_work, ++ delay); ++ } + } else { + if (adev->gfx.gfx_off_req_count == 0) { + cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h +index d8b22618b79e8..c337588231ff0 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h +@@ -118,6 +118,7 @@ struct dcn10_link_enc_registers { + uint32_t RDPCSTX_PHY_CNTL4; + uint32_t RDPCSTX_PHY_CNTL5; + uint32_t RDPCSTX_PHY_CNTL6; ++ uint32_t RDPCSPIPE_PHY_CNTL6; + uint32_t RDPCSTX_PHY_CNTL7; + uint32_t RDPCSTX_PHY_CNTL8; + uint32_t RDPCSTX_PHY_CNTL9; +diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c +index 90127c1f9e35d..b0892443fbd57 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c +@@ -37,6 +37,7 @@ + + #include "link_enc_cfg.h" + #include "dc_dmub_srv.h" ++#include "dal_asic_id.h" + + #define CTX \ + enc10->base.ctx +@@ -62,6 +63,10 @@ + #define AUX_REG_WRITE(reg_name, val) \ + dm_write_reg(CTX, AUX_REG(reg_name), val) + ++#ifndef MIN ++#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) ++#endif ++ + void dcn31_link_encoder_set_dio_phy_mux( + struct link_encoder *enc, + enum encoder_type_select sel, +@@ -215,8 +220,8 @@ static const struct link_encoder_funcs dcn31_link_enc_funcs = { + .fec_is_active = enc2_fec_is_active, + .get_dig_frontend = dcn10_get_dig_frontend, + .get_dig_mode = dcn10_get_dig_mode, +- .is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode, +- .get_max_link_cap = dcn20_link_encoder_get_max_link_cap, ++ .is_in_alt_mode = dcn31_link_encoder_is_in_alt_mode, ++ .get_max_link_cap = dcn31_link_encoder_get_max_link_cap, + .set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux, + }; + +@@ -404,3 +409,60 @@ void dcn31_link_encoder_disable_output( + } + } + ++bool dcn31_link_encoder_is_in_alt_mode(struct link_encoder *enc) ++{ ++ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); ++ uint32_t dp_alt_mode_disable; ++ bool is_usb_c_alt_mode = false; ++ ++ if (enc->features.flags.bits.DP_IS_USB_C) { ++ if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) { ++ // [Note] no need to check hw_internal_rev once phy mux selection is ready ++ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable); ++ } else { ++ /* ++ * B0 phys use a new set of registers to check whether alt mode is disabled. ++ * if value == 1 alt mode is disabled, otherwise it is enabled. ++ */ ++ if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A) ++ || (enc10->base.transmitter == TRANSMITTER_UNIPHY_B) ++ || (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) { ++ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable); ++ } else { ++ // [Note] need to change TRANSMITTER_UNIPHY_C/D to F/G once phy mux selection is ready ++ REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable); ++ } ++ } ++ ++ is_usb_c_alt_mode = (dp_alt_mode_disable == 0); ++ } ++ ++ return is_usb_c_alt_mode; ++} ++ ++void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc, ++ struct dc_link_settings *link_settings) ++{ ++ struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); ++ uint32_t is_in_usb_c_dp4_mode = 0; ++ ++ dcn10_link_encoder_get_max_link_cap(enc, link_settings); ++ ++ /* in usb c dp2 mode, max lane count is 2 */ ++ if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) { ++ if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) { ++ // [Note] no need to check hw_internal_rev once phy mux selection is ready ++ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode); ++ } else { ++ if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A) ++ || (enc10->base.transmitter == TRANSMITTER_UNIPHY_B) ++ || (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) { ++ REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode); ++ } else { ++ REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode); ++ } ++ } ++ if (!is_in_usb_c_dp4_mode) ++ link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count); ++ } ++} +diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h +index 32d146312838b..3454f1e7c1f17 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h +@@ -69,6 +69,7 @@ + SRI(RDPCSTX_PHY_CNTL4, RDPCSTX, id), \ + SRI(RDPCSTX_PHY_CNTL5, RDPCSTX, id), \ + SRI(RDPCSTX_PHY_CNTL6, RDPCSTX, id), \ ++ SRI(RDPCSPIPE_PHY_CNTL6, RDPCSPIPE, id), \ + SRI(RDPCSTX_PHY_CNTL7, RDPCSTX, id), \ + SRI(RDPCSTX_PHY_CNTL8, RDPCSTX, id), \ + SRI(RDPCSTX_PHY_CNTL9, RDPCSTX, id), \ +@@ -115,7 +116,9 @@ + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX2_MPLL_EN, mask_sh),\ + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX3_MPLL_EN, mask_sh),\ + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\ +- LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\ ++ LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\ ++ LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\ ++ LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE_ACK, mask_sh),\ + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_QUOT, mask_sh),\ + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_DEN, mask_sh),\ + LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL8, RDPCS_PHY_DP_MPLLB_SSC_PEAK, mask_sh),\ +@@ -243,4 +246,13 @@ void dcn31_link_encoder_disable_output( + struct link_encoder *enc, + enum signal_type signal); + ++/* ++ * Check whether USB-C DP Alt mode is disabled ++ */ ++bool dcn31_link_encoder_is_in_alt_mode( ++ struct link_encoder *enc); ++ ++void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc, ++ struct dc_link_settings *link_settings); ++ + #endif /* __DC_LINK_ENCODER__DCN31_H__ */ +diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c +index cd3248dc31d87..7ea362a864c43 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c +@@ -928,7 +928,7 @@ static const struct dc_debug_options debug_defaults_drv = { + .disable_dcc = DCC_ENABLE, + .vsr_support = true, + .performance_trace = false, +- .max_downscale_src_width = 7680,/*upto 8K*/ ++ .max_downscale_src_width = 3840,/*upto 4K*/ + .disable_pplib_wm_range = false, + .scl_reset_length10 = true, + .sanity_checks = false, +@@ -1284,6 +1284,12 @@ static struct stream_encoder *dcn31_stream_encoder_create( + if (!enc1 || !vpg || !afmt) + return NULL; + ++ if (ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && ++ ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { ++ if ((eng_id == ENGINE_ID_DIGC) || (eng_id == ENGINE_ID_DIGD)) ++ eng_id = eng_id + 3; // For B0 only. C->F, D->G. ++ } ++ + dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, + eng_id, vpg, afmt, + &stream_enc_regs[eng_id], +diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h +index 381c17caace18..5adc471bef57f 100644 +--- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h ++++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h +@@ -227,7 +227,7 @@ enum { + #define FAMILY_YELLOW_CARP 146 + + #define YELLOW_CARP_A0 0x01 +-#define YELLOW_CARP_B0 0x02 // TODO: DCN31 - update with correct B0 ID ++#define YELLOW_CARP_B0 0x1A + #define YELLOW_CARP_UNKNOWN 0xFF + + #ifndef ASICREV_IS_YELLOW_CARP +diff --git a/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h +index 92caf8441d1e0..01a56556cde13 100644 +--- a/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h ++++ b/drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h +@@ -11932,5 +11932,32 @@ + #define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_RX_OVRD_OUT_2 0xe0c7 + #define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_TX_OVRD_IN_2 0xe0c8 + ++//RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6 ++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT 0x10 ++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT 0x11 ++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT 0x12 ++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK 0x00010000L ++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK 0x00020000L ++#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK 0x00040000L ++ ++//RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6 ++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT 0x10 ++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT 0x11 ++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT 0x12 ++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK 0x00010000L ++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK 0x00020000L ++#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK 0x00040000L ++ ++//[Note] Hack. RDPCSPIPE only has 2 instances. ++#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6 0x2d73 ++#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2 ++#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6 0x2e4b ++#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2 ++#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6 0x2d73 ++#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2 ++#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6 0x2e4b ++#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2 ++#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6 0x2d73 ++#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6_BASE_IDX 2 + + #endif +diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c +index 16812488c5ddc..13bafa9d49c01 100644 +--- a/drivers/gpu/drm/i915/display/icl_dsi.c ++++ b/drivers/gpu/drm/i915/display/icl_dsi.c +@@ -1253,15 +1253,36 @@ static void gen11_dsi_pre_enable(struct intel_atomic_state *state, + gen11_dsi_set_transcoder_timings(encoder, pipe_config); + } + ++/* ++ * Wa_1409054076:icl,jsl,ehl ++ * When pipe A is disabled and MIPI DSI is enabled on pipe B, ++ * the AMT KVMR feature will incorrectly see pipe A as enabled. ++ * Set 0x42080 bit 23=1 before enabling DSI on pipe B and leave ++ * it set while DSI is enabled on pipe B ++ */ ++static void icl_apply_kvmr_pipe_a_wa(struct intel_encoder *encoder, ++ enum pipe pipe, bool enable) ++{ ++ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); ++ ++ if (DISPLAY_VER(dev_priv) == 11 && pipe == PIPE_B) ++ intel_de_rmw(dev_priv, CHICKEN_PAR1_1, ++ IGNORE_KVMR_PIPE_A, ++ enable ? IGNORE_KVMR_PIPE_A : 0); ++} + static void gen11_dsi_enable(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) + { + struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); ++ struct intel_crtc *crtc = to_intel_crtc(conn_state->crtc); + + drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder); + ++ /* Wa_1409054076:icl,jsl,ehl */ ++ icl_apply_kvmr_pipe_a_wa(encoder, crtc->pipe, true); ++ + /* step6d: enable dsi transcoder */ + gen11_dsi_enable_transcoder(encoder); + +@@ -1415,6 +1436,7 @@ static void gen11_dsi_disable(struct intel_atomic_state *state, + const struct drm_connector_state *old_conn_state) + { + struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); ++ struct intel_crtc *crtc = to_intel_crtc(old_conn_state->crtc); + + /* step1: turn off backlight */ + intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF); +@@ -1423,6 +1445,9 @@ static void gen11_dsi_disable(struct intel_atomic_state *state, + /* step2d,e: disable transcoder and wait */ + gen11_dsi_disable_transcoder(encoder); + ++ /* Wa_1409054076:icl,jsl,ehl */ ++ icl_apply_kvmr_pipe_a_wa(encoder, crtc->pipe, false); ++ + /* step2f,g: powerdown panel */ + gen11_dsi_powerdown_panel(encoder); + +@@ -1548,6 +1573,28 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder, + pipe_config->mode_flags |= I915_MODE_FLAG_DSI_PERIODIC_CMD_MODE; + } + ++static void gen11_dsi_sync_state(struct intel_encoder *encoder, ++ const struct intel_crtc_state *crtc_state) ++{ ++ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); ++ struct intel_crtc *intel_crtc; ++ enum pipe pipe; ++ ++ if (!crtc_state) ++ return; ++ ++ intel_crtc = to_intel_crtc(crtc_state->uapi.crtc); ++ pipe = intel_crtc->pipe; ++ ++ /* wa verify 1409054076:icl,jsl,ehl */ ++ if (DISPLAY_VER(dev_priv) == 11 && pipe == PIPE_B && ++ !(intel_de_read(dev_priv, CHICKEN_PAR1_1) & IGNORE_KVMR_PIPE_A)) ++ drm_dbg_kms(&dev_priv->drm, ++ "[ENCODER:%d:%s] BIOS left IGNORE_KVMR_PIPE_A cleared with pipe B enabled\n", ++ encoder->base.base.id, ++ encoder->base.name); ++} ++ + static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state) + { +@@ -1966,6 +2013,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) + encoder->post_disable = gen11_dsi_post_disable; + encoder->port = port; + encoder->get_config = gen11_dsi_get_config; ++ encoder->sync_state = gen11_dsi_sync_state; + encoder->update_pipe = intel_panel_update_backlight; + encoder->compute_config = gen11_dsi_compute_config; + encoder->get_hw_state = gen11_dsi_get_hw_state; +diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c +index 5f4f316b3ab5c..4e4429535f9e4 100644 +--- a/drivers/gpu/drm/i915/display/intel_audio.c ++++ b/drivers/gpu/drm/i915/display/intel_audio.c +@@ -1308,8 +1308,9 @@ static void i915_audio_component_init(struct drm_i915_private *dev_priv) + else + aud_freq = aud_freq_init; + +- /* use BIOS provided value for TGL unless it is a known bad value */ +- if (IS_TIGERLAKE(dev_priv) && aud_freq_init != AUD_FREQ_TGL_BROKEN) ++ /* use BIOS provided value for TGL and RKL unless it is a known bad value */ ++ if ((IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv)) && ++ aud_freq_init != AUD_FREQ_TGL_BROKEN) + aud_freq = aud_freq_init; + + drm_dbg_kms(&dev_priv->drm, "use AUD_FREQ_CNTRL of 0x%x (init value 0x%x)\n", +diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c +index aa667fa711584..106f696e50a0e 100644 +--- a/drivers/gpu/drm/i915/display/intel_bios.c ++++ b/drivers/gpu/drm/i915/display/intel_bios.c +@@ -451,13 +451,23 @@ parse_lfp_backlight(struct drm_i915_private *i915, + } + + i915->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI; +- if (bdb->version >= 191 && +- get_blocksize(backlight_data) >= sizeof(*backlight_data)) { +- const struct lfp_backlight_control_method *method; ++ if (bdb->version >= 191) { ++ size_t exp_size; + +- method = &backlight_data->backlight_control[panel_type]; +- i915->vbt.backlight.type = method->type; +- i915->vbt.backlight.controller = method->controller; ++ if (bdb->version >= 236) ++ exp_size = sizeof(struct bdb_lfp_backlight_data); ++ else if (bdb->version >= 234) ++ exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_234; ++ else ++ exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_191; ++ ++ if (get_blocksize(backlight_data) >= exp_size) { ++ const struct lfp_backlight_control_method *method; ++ ++ method = &backlight_data->backlight_control[panel_type]; ++ i915->vbt.backlight.type = method->type; ++ i915->vbt.backlight.controller = method->controller; ++ } + } + + i915->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz; +diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c +index 00dade49665b8..89a109f65f389 100644 +--- a/drivers/gpu/drm/i915/display/intel_ddi.c ++++ b/drivers/gpu/drm/i915/display/intel_ddi.c +@@ -3899,7 +3899,13 @@ void hsw_ddi_get_config(struct intel_encoder *encoder, + static void intel_ddi_sync_state(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) + { +- if (intel_crtc_has_dp_encoder(crtc_state)) ++ struct drm_i915_private *i915 = to_i915(encoder->base.dev); ++ enum phy phy = intel_port_to_phy(i915, encoder->port); ++ ++ if (intel_phy_is_tc(i915, phy)) ++ intel_tc_port_sanitize(enc_to_dig_port(encoder)); ++ ++ if (crtc_state && intel_crtc_has_dp_encoder(crtc_state)) + intel_dp_sync_state(encoder, crtc_state); + } + +diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c +index 0a8a2395c8aca..bb1d2b19be151 100644 +--- a/drivers/gpu/drm/i915/display/intel_display.c ++++ b/drivers/gpu/drm/i915/display/intel_display.c +@@ -12933,18 +12933,16 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) + readout_plane_state(dev_priv); + + for_each_intel_encoder(dev, encoder) { ++ struct intel_crtc_state *crtc_state = NULL; ++ + pipe = 0; + + if (encoder->get_hw_state(encoder, &pipe)) { +- struct intel_crtc_state *crtc_state; +- + crtc = intel_get_crtc_for_pipe(dev_priv, pipe); + crtc_state = to_intel_crtc_state(crtc->base.state); + + encoder->base.crtc = &crtc->base; + intel_encoder_get_config(encoder, crtc_state); +- if (encoder->sync_state) +- encoder->sync_state(encoder, crtc_state); + + /* read out to slave crtc as well for bigjoiner */ + if (crtc_state->bigjoiner) { +@@ -12959,6 +12957,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) + encoder->base.crtc = NULL; + } + ++ if (encoder->sync_state) ++ encoder->sync_state(encoder, crtc_state); ++ + drm_dbg_kms(&dev_priv->drm, + "[ENCODER:%d:%s] hw state readout: %s, pipe %c\n", + encoder->base.base.id, encoder->base.name, +@@ -13241,17 +13242,6 @@ intel_modeset_setup_hw_state(struct drm_device *dev, + intel_modeset_readout_hw_state(dev); + + /* HW state is read out, now we need to sanitize this mess. */ +- +- /* Sanitize the TypeC port mode upfront, encoders depend on this */ +- for_each_intel_encoder(dev, encoder) { +- enum phy phy = intel_port_to_phy(dev_priv, encoder->port); +- +- /* We need to sanitize only the MST primary port. */ +- if (encoder->type != INTEL_OUTPUT_DP_MST && +- intel_phy_is_tc(dev_priv, phy)) +- intel_tc_port_sanitize(enc_to_dig_port(encoder)); +- } +- + get_encoder_power_domains(dev_priv); + + if (HAS_PCH_IBX(dev_priv)) +diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h +index dbe24d7e73759..cf1ffe4a0e46a 100644 +--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h ++++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h +@@ -814,6 +814,11 @@ struct lfp_brightness_level { + u16 reserved; + } __packed; + ++#define EXP_BDB_LFP_BL_DATA_SIZE_REV_191 \ ++ offsetof(struct bdb_lfp_backlight_data, brightness_level) ++#define EXP_BDB_LFP_BL_DATA_SIZE_REV_234 \ ++ offsetof(struct bdb_lfp_backlight_data, brightness_precision_bits) ++ + struct bdb_lfp_backlight_data { + u8 entry_size; + struct lfp_backlight_data_entry data[16]; +diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +index e382b7f2353b8..5ab136ffdeb2d 100644 +--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c ++++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +@@ -118,7 +118,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww, + intel_wakeref_t wakeref = 0; + unsigned long count = 0; + unsigned long scanned = 0; +- int err; ++ int err = 0; + + /* CHV + VTD workaround use stop_machine(); need to trylock vm->mutex */ + bool trylock_vm = !ww && intel_vm_no_concurrent_access_wa(i915); +@@ -242,12 +242,15 @@ skip: + list_splice_tail(&still_in_list, phase->list); + spin_unlock_irqrestore(&i915->mm.obj_lock, flags); + if (err) +- return err; ++ break; + } + + if (shrink & I915_SHRINK_BOUND) + intel_runtime_pm_put(&i915->runtime_pm, wakeref); + ++ if (err) ++ return err; ++ + if (nr_scanned) + *nr_scanned += scanned; + return count; +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 476bb3b9ad11a..5aa5ddefd22d2 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -8113,6 +8113,7 @@ enum { + # define CHICKEN3_DGMG_DONE_FIX_DISABLE (1 << 2) + + #define CHICKEN_PAR1_1 _MMIO(0x42080) ++#define IGNORE_KVMR_PIPE_A REG_BIT(23) + #define KBL_ARB_FILL_SPARE_22 REG_BIT(22) + #define DIS_RAM_BYPASS_PSR2_MAN_TRACK (1 << 16) + #define SKL_DE_COMPRESSED_HASH_MODE (1 << 15) +@@ -8150,6 +8151,11 @@ enum { + #define HSW_SPR_STRETCH_MAX_X1 REG_FIELD_PREP(HSW_SPR_STRETCH_MAX_MASK, 3) + #define HSW_FBCQ_DIS (1 << 22) + #define BDW_DPRS_MASK_VBLANK_SRD (1 << 0) ++#define SKL_PLANE1_STRETCH_MAX_MASK REG_GENMASK(1, 0) ++#define SKL_PLANE1_STRETCH_MAX_X8 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 0) ++#define SKL_PLANE1_STRETCH_MAX_X4 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 1) ++#define SKL_PLANE1_STRETCH_MAX_X2 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 2) ++#define SKL_PLANE1_STRETCH_MAX_X1 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 3) + #define CHICKEN_PIPESL_1(pipe) _MMIO_PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B) + + #define _CHICKEN_TRANS_A 0x420c0 +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 45fefa0ed1607..28959e67c00ee 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -76,6 +76,8 @@ struct intel_wm_config { + + static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) + { ++ enum pipe pipe; ++ + if (HAS_LLC(dev_priv)) { + /* + * WaCompressedResourceDisplayNewHashMode:skl,kbl +@@ -89,6 +91,16 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) + SKL_DE_COMPRESSED_HASH_MODE); + } + ++ for_each_pipe(dev_priv, pipe) { ++ /* ++ * "Plane N strech max must be programmed to 11b (x1) ++ * when Async flips are enabled on that plane." ++ */ ++ if (!IS_GEMINILAKE(dev_priv) && intel_vtd_active()) ++ intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe), ++ SKL_PLANE1_STRETCH_MAX_MASK, SKL_PLANE1_STRETCH_MAX_X1); ++ } ++ + /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */ + intel_uncore_write(&dev_priv->uncore, CHICKEN_PAR1_1, + intel_uncore_read(&dev_priv->uncore, CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP); +diff --git a/drivers/gpu/drm/nouveau/dispnv50/crc.c b/drivers/gpu/drm/nouveau/dispnv50/crc.c +index b8c31b697797e..66f32d965c723 100644 +--- a/drivers/gpu/drm/nouveau/dispnv50/crc.c ++++ b/drivers/gpu/drm/nouveau/dispnv50/crc.c +@@ -704,6 +704,7 @@ static const struct file_operations nv50_crc_flip_threshold_fops = { + .open = nv50_crc_debugfs_flip_threshold_open, + .read = seq_read, + .write = nv50_crc_debugfs_flip_threshold_set, ++ .release = single_release, + }; + + int nv50_head_crc_late_register(struct nv50_head *head) +diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c +index d66f97280282a..72099d1e48169 100644 +--- a/drivers/gpu/drm/nouveau/dispnv50/head.c ++++ b/drivers/gpu/drm/nouveau/dispnv50/head.c +@@ -52,6 +52,7 @@ nv50_head_flush_clr(struct nv50_head *head, + void + nv50_head_flush_set_wndw(struct nv50_head *head, struct nv50_head_atom *asyh) + { ++ if (asyh->set.curs ) head->func->curs_set(head, asyh); + if (asyh->set.olut ) { + asyh->olut.offset = nv50_lut_load(&head->olut, + asyh->olut.buffer, +@@ -67,7 +68,6 @@ nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh) + if (asyh->set.view ) head->func->view (head, asyh); + if (asyh->set.mode ) head->func->mode (head, asyh); + if (asyh->set.core ) head->func->core_set(head, asyh); +- if (asyh->set.curs ) head->func->curs_set(head, asyh); + if (asyh->set.base ) head->func->base (head, asyh); + if (asyh->set.ovly ) head->func->ovly (head, asyh); + if (asyh->set.dither ) head->func->dither (head, asyh); +diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h +index c68cc957248e2..a582c0cb0cb0d 100644 +--- a/drivers/gpu/drm/nouveau/include/nvif/class.h ++++ b/drivers/gpu/drm/nouveau/include/nvif/class.h +@@ -71,6 +71,7 @@ + #define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c06f + #define VOLTA_CHANNEL_GPFIFO_A /* clc36f.h */ 0x0000c36f + #define TURING_CHANNEL_GPFIFO_A /* clc36f.h */ 0x0000c46f ++#define AMPERE_CHANNEL_GPFIFO_B /* clc36f.h */ 0x0000c76f + + #define NV50_DISP /* cl5070.h */ 0x00005070 + #define G82_DISP /* cl5070.h */ 0x00008270 +@@ -200,6 +201,7 @@ + #define PASCAL_DMA_COPY_B 0x0000c1b5 + #define VOLTA_DMA_COPY_A 0x0000c3b5 + #define TURING_DMA_COPY_A 0x0000c5b5 ++#define AMPERE_DMA_COPY_B 0x0000c7b5 + + #define FERMI_DECOMPRESS 0x000090b8 + +diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +index 54fab7cc36c1b..64ee82c7c1be5 100644 +--- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h ++++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +@@ -77,4 +77,5 @@ int gp100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct + int gp10b_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); + int gv100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); + int tu102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); ++int ga102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **); + #endif +diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c +index 6d07e653f82d5..c58bcdba2c7aa 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_bo.c ++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c +@@ -844,6 +844,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm) + struct ttm_resource *, struct ttm_resource *); + int (*init)(struct nouveau_channel *, u32 handle); + } _methods[] = { ++ { "COPY", 4, 0xc7b5, nve0_bo_move_copy, nve0_bo_move_init }, + { "COPY", 4, 0xc5b5, nve0_bo_move_copy, nve0_bo_move_init }, + { "GRCE", 0, 0xc5b5, nve0_bo_move_copy, nvc0_bo_move_init }, + { "COPY", 4, 0xc3b5, nve0_bo_move_copy, nve0_bo_move_init }, +diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c +index 80099ef757022..ea7769135b0dc 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_chan.c ++++ b/drivers/gpu/drm/nouveau/nouveau_chan.c +@@ -250,7 +250,8 @@ static int + nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, + u64 runlist, bool priv, struct nouveau_channel **pchan) + { +- static const u16 oclasses[] = { TURING_CHANNEL_GPFIFO_A, ++ static const u16 oclasses[] = { AMPERE_CHANNEL_GPFIFO_B, ++ TURING_CHANNEL_GPFIFO_A, + VOLTA_CHANNEL_GPFIFO_A, + PASCAL_CHANNEL_GPFIFO_A, + MAXWELL_CHANNEL_GPFIFO_A, +@@ -386,7 +387,8 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) + + nvif_object_map(&chan->user, NULL, 0); + +- if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO) { ++ if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO && ++ chan->user.oclass < AMPERE_CHANNEL_GPFIFO_B) { + ret = nvif_notify_ctor(&chan->user, "abi16ChanKilled", + nouveau_channel_killed, + true, NV906F_V0_NTFY_KILLED, +diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c +index c2bc05eb2e54a..1cbe01048b930 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c ++++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c +@@ -207,6 +207,7 @@ static const struct file_operations nouveau_pstate_fops = { + .open = nouveau_debugfs_pstate_open, + .read = seq_read, + .write = nouveau_debugfs_pstate_set, ++ .release = single_release, + }; + + static struct drm_info_list nouveau_debugfs_list[] = { +diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c +index ba4cd5f837259..9b0084e4bbcfb 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drm.c ++++ b/drivers/gpu/drm/nouveau/nouveau_drm.c +@@ -345,6 +345,9 @@ nouveau_accel_gr_init(struct nouveau_drm *drm) + u32 arg0, arg1; + int ret; + ++ if (device->info.family >= NV_DEVICE_INFO_V0_AMPERE) ++ return; ++ + /* Allocate channel that has access to the graphics engine. */ + if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) { + arg0 = nvif_fifo_runlist(device, NV_DEVICE_HOST_RUNLIST_ENGINES_GR); +@@ -469,6 +472,7 @@ nouveau_accel_init(struct nouveau_drm *drm) + case PASCAL_CHANNEL_GPFIFO_A: + case VOLTA_CHANNEL_GPFIFO_A: + case TURING_CHANNEL_GPFIFO_A: ++ case AMPERE_CHANNEL_GPFIFO_B: + ret = nvc0_fence_create(drm); + break; + default: +diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c +index 5b27845075a1c..8c2ecc2827232 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_gem.c ++++ b/drivers/gpu/drm/nouveau/nouveau_gem.c +@@ -247,10 +247,8 @@ nouveau_gem_new(struct nouveau_cli *cli, u64 size, int align, uint32_t domain, + } + + ret = nouveau_bo_init(nvbo, size, align, domain, NULL, NULL); +- if (ret) { +- nouveau_bo_ref(NULL, &nvbo); ++ if (ret) + return ret; +- } + + /* we restrict allowed domains on nv50+ to only the types + * that were requested at creation time. not possibly on +diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c +index 7c9c928c31966..c3526a8622e3e 100644 +--- a/drivers/gpu/drm/nouveau/nv84_fence.c ++++ b/drivers/gpu/drm/nouveau/nv84_fence.c +@@ -204,7 +204,7 @@ nv84_fence_create(struct nouveau_drm *drm) + priv->base.context_new = nv84_fence_context_new; + priv->base.context_del = nv84_fence_context_del; + +- priv->base.uevent = true; ++ priv->base.uevent = drm->client.device.info.family < NV_DEVICE_INFO_V0_AMPERE; + + mutex_init(&priv->mutex); + +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +index 93ddf63d11140..ca75c5f6ecaf8 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +@@ -2602,6 +2602,7 @@ nv172_chipset = { + .top = { 0x00000001, ga100_top_new }, + .disp = { 0x00000001, ga102_disp_new }, + .dma = { 0x00000001, gv100_dma_new }, ++ .fifo = { 0x00000001, ga102_fifo_new }, + }; + + static const struct nvkm_device_chip +@@ -2622,6 +2623,7 @@ nv174_chipset = { + .top = { 0x00000001, ga100_top_new }, + .disp = { 0x00000001, ga102_disp_new }, + .dma = { 0x00000001, gv100_dma_new }, ++ .fifo = { 0x00000001, ga102_fifo_new }, + }; + + static const struct nvkm_device_chip +@@ -2642,6 +2644,7 @@ nv177_chipset = { + .top = { 0x00000001, ga100_top_new }, + .disp = { 0x00000001, ga102_disp_new }, + .dma = { 0x00000001, gv100_dma_new }, ++ .fifo = { 0x00000001, ga102_fifo_new }, + }; + + static int +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild +index 3209eb7af65fb..5e831d347a957 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild +@@ -18,6 +18,7 @@ nvkm-y += nvkm/engine/fifo/gp100.o + nvkm-y += nvkm/engine/fifo/gp10b.o + nvkm-y += nvkm/engine/fifo/gv100.o + nvkm-y += nvkm/engine/fifo/tu102.o ++nvkm-y += nvkm/engine/fifo/ga102.o + + nvkm-y += nvkm/engine/fifo/chan.o + nvkm-y += nvkm/engine/fifo/channv50.o +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c +new file mode 100644 +index 0000000000000..c630dbd2911ae +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c +@@ -0,0 +1,311 @@ ++/* ++ * Copyright 2021 Red Hat Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++#define ga102_fifo(p) container_of((p), struct ga102_fifo, base.engine) ++#define ga102_chan(p) container_of((p), struct ga102_chan, object) ++#include <engine/fifo.h> ++#include "user.h" ++ ++#include <core/memory.h> ++#include <subdev/mmu.h> ++#include <subdev/timer.h> ++#include <subdev/top.h> ++ ++#include <nvif/cl0080.h> ++#include <nvif/clc36f.h> ++#include <nvif/class.h> ++ ++struct ga102_fifo { ++ struct nvkm_fifo base; ++}; ++ ++struct ga102_chan { ++ struct nvkm_object object; ++ ++ struct { ++ u32 runl; ++ u32 chan; ++ } ctrl; ++ ++ struct nvkm_memory *mthd; ++ struct nvkm_memory *inst; ++ struct nvkm_memory *user; ++ struct nvkm_memory *runl; ++ ++ struct nvkm_vmm *vmm; ++}; ++ ++static int ++ga102_chan_sclass(struct nvkm_object *object, int index, struct nvkm_oclass *oclass) ++{ ++ if (index == 0) { ++ oclass->ctor = nvkm_object_new; ++ oclass->base = (struct nvkm_sclass) { -1, -1, AMPERE_DMA_COPY_B }; ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ ++static int ++ga102_chan_map(struct nvkm_object *object, void *argv, u32 argc, ++ enum nvkm_object_map *type, u64 *addr, u64 *size) ++{ ++ struct ga102_chan *chan = ga102_chan(object); ++ struct nvkm_device *device = chan->object.engine->subdev.device; ++ u64 bar2 = nvkm_memory_bar2(chan->user); ++ ++ if (bar2 == ~0ULL) ++ return -EFAULT; ++ ++ *type = NVKM_OBJECT_MAP_IO; ++ *addr = device->func->resource_addr(device, 3) + bar2; ++ *size = 0x1000; ++ return 0; ++} ++ ++static int ++ga102_chan_fini(struct nvkm_object *object, bool suspend) ++{ ++ struct ga102_chan *chan = ga102_chan(object); ++ struct nvkm_device *device = chan->object.engine->subdev.device; ++ ++ nvkm_wr32(device, chan->ctrl.chan, 0x00000003); ++ ++ nvkm_wr32(device, chan->ctrl.runl + 0x098, 0x01000000); ++ nvkm_msec(device, 2000, ++ if (!(nvkm_rd32(device, chan->ctrl.runl + 0x098) & 0x00100000)) ++ break; ++ ); ++ ++ nvkm_wr32(device, chan->ctrl.runl + 0x088, 0); ++ ++ nvkm_wr32(device, chan->ctrl.chan, 0xffffffff); ++ return 0; ++} ++ ++static int ++ga102_chan_init(struct nvkm_object *object) ++{ ++ struct ga102_chan *chan = ga102_chan(object); ++ struct nvkm_device *device = chan->object.engine->subdev.device; ++ ++ nvkm_mask(device, chan->ctrl.runl + 0x300, 0x80000000, 0x80000000); ++ ++ nvkm_wr32(device, chan->ctrl.runl + 0x080, lower_32_bits(nvkm_memory_addr(chan->runl))); ++ nvkm_wr32(device, chan->ctrl.runl + 0x084, upper_32_bits(nvkm_memory_addr(chan->runl))); ++ nvkm_wr32(device, chan->ctrl.runl + 0x088, 2); ++ ++ nvkm_wr32(device, chan->ctrl.chan, 0x00000002); ++ nvkm_wr32(device, chan->ctrl.runl + 0x0090, 0); ++ return 0; ++} ++ ++static void * ++ga102_chan_dtor(struct nvkm_object *object) ++{ ++ struct ga102_chan *chan = ga102_chan(object); ++ ++ if (chan->vmm) { ++ nvkm_vmm_part(chan->vmm, chan->inst); ++ nvkm_vmm_unref(&chan->vmm); ++ } ++ ++ nvkm_memory_unref(&chan->runl); ++ nvkm_memory_unref(&chan->user); ++ nvkm_memory_unref(&chan->inst); ++ nvkm_memory_unref(&chan->mthd); ++ return chan; ++} ++ ++static const struct nvkm_object_func ++ga102_chan = { ++ .dtor = ga102_chan_dtor, ++ .init = ga102_chan_init, ++ .fini = ga102_chan_fini, ++ .map = ga102_chan_map, ++ .sclass = ga102_chan_sclass, ++}; ++ ++static int ++ga102_chan_new(struct nvkm_device *device, ++ const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject) ++{ ++ struct volta_channel_gpfifo_a_v0 *args = argv; ++ struct nvkm_top_device *tdev; ++ struct nvkm_vmm *vmm; ++ struct ga102_chan *chan; ++ int ret; ++ ++ if (argc != sizeof(*args)) ++ return -ENOSYS; ++ ++ vmm = nvkm_uvmm_search(oclass->client, args->vmm); ++ if (IS_ERR(vmm)) ++ return PTR_ERR(vmm); ++ ++ if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) ++ return -ENOMEM; ++ ++ nvkm_object_ctor(&ga102_chan, oclass, &chan->object); ++ *pobject = &chan->object; ++ ++ list_for_each_entry(tdev, &device->top->device, head) { ++ if (tdev->type == NVKM_ENGINE_CE) { ++ chan->ctrl.runl = tdev->runlist; ++ break; ++ } ++ } ++ ++ if (!chan->ctrl.runl) ++ return -ENODEV; ++ ++ chan->ctrl.chan = nvkm_rd32(device, chan->ctrl.runl + 0x004) & 0xfffffff0; ++ ++ args->chid = 0; ++ args->inst = 0; ++ args->token = nvkm_rd32(device, chan->ctrl.runl + 0x008) & 0xffff0000; ++ ++ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->mthd); ++ if (ret) ++ return ret; ++ ++ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->inst); ++ if (ret) ++ return ret; ++ ++ nvkm_kmap(chan->inst); ++ nvkm_wo32(chan->inst, 0x010, 0x0000face); ++ nvkm_wo32(chan->inst, 0x030, 0x7ffff902); ++ nvkm_wo32(chan->inst, 0x048, lower_32_bits(args->ioffset)); ++ nvkm_wo32(chan->inst, 0x04c, upper_32_bits(args->ioffset) | ++ (order_base_2(args->ilength / 8) << 16)); ++ nvkm_wo32(chan->inst, 0x084, 0x20400000); ++ nvkm_wo32(chan->inst, 0x094, 0x30000001); ++ nvkm_wo32(chan->inst, 0x0ac, 0x00020000); ++ nvkm_wo32(chan->inst, 0x0e4, 0x00000000); ++ nvkm_wo32(chan->inst, 0x0e8, 0); ++ nvkm_wo32(chan->inst, 0x0f4, 0x00001000); ++ nvkm_wo32(chan->inst, 0x0f8, 0x10003080); ++ nvkm_mo32(chan->inst, 0x218, 0x00000000, 0x00000000); ++ nvkm_wo32(chan->inst, 0x220, lower_32_bits(nvkm_memory_bar2(chan->mthd))); ++ nvkm_wo32(chan->inst, 0x224, upper_32_bits(nvkm_memory_bar2(chan->mthd))); ++ nvkm_done(chan->inst); ++ ++ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->user); ++ if (ret) ++ return ret; ++ ++ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->runl); ++ if (ret) ++ return ret; ++ ++ nvkm_kmap(chan->runl); ++ nvkm_wo32(chan->runl, 0x00, 0x80030001); ++ nvkm_wo32(chan->runl, 0x04, 1); ++ nvkm_wo32(chan->runl, 0x08, 0); ++ nvkm_wo32(chan->runl, 0x0c, 0x00000000); ++ nvkm_wo32(chan->runl, 0x10, lower_32_bits(nvkm_memory_addr(chan->user))); ++ nvkm_wo32(chan->runl, 0x14, upper_32_bits(nvkm_memory_addr(chan->user))); ++ nvkm_wo32(chan->runl, 0x18, lower_32_bits(nvkm_memory_addr(chan->inst))); ++ nvkm_wo32(chan->runl, 0x1c, upper_32_bits(nvkm_memory_addr(chan->inst))); ++ nvkm_done(chan->runl); ++ ++ ret = nvkm_vmm_join(vmm, chan->inst); ++ if (ret) ++ return ret; ++ ++ chan->vmm = nvkm_vmm_ref(vmm); ++ return 0; ++} ++ ++static const struct nvkm_device_oclass ++ga102_chan_oclass = { ++ .ctor = ga102_chan_new, ++}; ++ ++static int ++ga102_user_new(struct nvkm_device *device, ++ const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject) ++{ ++ return tu102_fifo_user_new(oclass, argv, argc, pobject); ++} ++ ++static const struct nvkm_device_oclass ++ga102_user_oclass = { ++ .ctor = ga102_user_new, ++}; ++ ++static int ++ga102_fifo_sclass(struct nvkm_oclass *oclass, int index, const struct nvkm_device_oclass **class) ++{ ++ if (index == 0) { ++ oclass->base = (struct nvkm_sclass) { -1, -1, VOLTA_USERMODE_A }; ++ *class = &ga102_user_oclass; ++ return 0; ++ } else ++ if (index == 1) { ++ oclass->base = (struct nvkm_sclass) { 0, 0, AMPERE_CHANNEL_GPFIFO_B }; ++ *class = &ga102_chan_oclass; ++ return 0; ++ } ++ ++ return 2; ++} ++ ++static int ++ga102_fifo_info(struct nvkm_engine *engine, u64 mthd, u64 *data) ++{ ++ switch (mthd) { ++ case NV_DEVICE_HOST_CHANNELS: *data = 1; return 0; ++ default: ++ break; ++ } ++ ++ return -ENOSYS; ++} ++ ++static void * ++ga102_fifo_dtor(struct nvkm_engine *engine) ++{ ++ return ga102_fifo(engine); ++} ++ ++static const struct nvkm_engine_func ++ga102_fifo = { ++ .dtor = ga102_fifo_dtor, ++ .info = ga102_fifo_info, ++ .base.sclass = ga102_fifo_sclass, ++}; ++ ++int ++ga102_fifo_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, ++ struct nvkm_fifo **pfifo) ++{ ++ struct ga102_fifo *fifo; ++ ++ if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL))) ++ return -ENOMEM; ++ ++ nvkm_engine_ctor(&ga102_fifo, device, type, inst, true, &fifo->base.engine); ++ *pfifo = &fifo->base; ++ return 0; ++} +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/top/ga100.c +index 31933f3e5a076..c982d834c8d98 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/top/ga100.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/ga100.c +@@ -54,7 +54,7 @@ ga100_top_oneinit(struct nvkm_top *top) + info->reset = (data & 0x0000001f); + break; + case 2: +- info->runlist = (data & 0x0000fc00) >> 10; ++ info->runlist = (data & 0x00fffc00); + info->engine = (data & 0x00000003); + break; + default: +@@ -85,9 +85,10 @@ ga100_top_oneinit(struct nvkm_top *top) + } + + nvkm_debug(subdev, "%02x.%d (%8s): addr %06x fault %2d " +- "runlist %2d engine %2d reset %2d\n", type, inst, ++ "runlist %6x engine %2d reset %2d\n", type, inst, + info->type == NVKM_SUBDEV_NR ? "????????" : nvkm_subdev_type[info->type], +- info->addr, info->fault, info->runlist, info->engine, info->reset); ++ info->addr, info->fault, info->runlist < 0 ? 0 : info->runlist, ++ info->engine, info->reset); + info = NULL; + } + +diff --git a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c +index 2d8794d495d08..3d8a9ab47cae2 100644 +--- a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c ++++ b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c +@@ -146,8 +146,8 @@ static const struct reg_sequence y030xx067a_init_sequence[] = { + { 0x09, REG09_SUB_BRIGHT_R(0x20) }, + { 0x0a, REG0A_SUB_BRIGHT_B(0x20) }, + { 0x0b, REG0B_HD_FREERUN | REG0B_VD_FREERUN }, +- { 0x0c, REG0C_CONTRAST_R(0x10) }, +- { 0x0d, REG0D_CONTRAST_G(0x10) }, ++ { 0x0c, REG0C_CONTRAST_R(0x00) }, ++ { 0x0d, REG0D_CONTRAST_G(0x00) }, + { 0x0e, REG0E_CONTRAST_B(0x10) }, + { 0x0f, 0 }, + { 0x10, REG10_BRIGHT(0x7f) }, +diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +index f75fb157f2ff7..016b877051dab 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c ++++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +@@ -216,11 +216,13 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, + goto err_disable_clk_tmds; + } + ++ ret = sun8i_hdmi_phy_init(hdmi->phy); ++ if (ret) ++ goto err_disable_clk_tmds; ++ + drm_encoder_helper_add(encoder, &sun8i_dw_hdmi_encoder_helper_funcs); + drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); + +- sun8i_hdmi_phy_init(hdmi->phy); +- + plat_data->mode_valid = hdmi->quirks->mode_valid; + plat_data->use_drm_infoframe = hdmi->quirks->use_drm_infoframe; + sun8i_hdmi_phy_set_ops(hdmi->phy, plat_data); +@@ -262,6 +264,7 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master, + struct sun8i_dw_hdmi *hdmi = dev_get_drvdata(dev); + + dw_hdmi_unbind(hdmi->hdmi); ++ sun8i_hdmi_phy_deinit(hdmi->phy); + clk_disable_unprepare(hdmi->clk_tmds); + reset_control_assert(hdmi->rst_ctrl); + gpiod_set_value(hdmi->ddc_en, 0); +diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +index 74f6ed0e25709..bffe1b9cd3dcb 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h ++++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +@@ -169,6 +169,7 @@ struct sun8i_hdmi_phy { + struct clk *clk_phy; + struct clk *clk_pll0; + struct clk *clk_pll1; ++ struct device *dev; + unsigned int rcal; + struct regmap *regs; + struct reset_control *rst_phy; +@@ -205,7 +206,8 @@ encoder_to_sun8i_dw_hdmi(struct drm_encoder *encoder) + + int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node); + +-void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy); ++int sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy); ++void sun8i_hdmi_phy_deinit(struct sun8i_hdmi_phy *phy); + void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy, + struct dw_hdmi_plat_data *plat_data); + +diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +index c9239708d398c..b64d93da651d2 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c ++++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +@@ -506,9 +506,60 @@ static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy) + phy->rcal = (val & SUN8I_HDMI_PHY_ANA_STS_RCAL_MASK) >> 2; + } + +-void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy) ++int sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy) + { ++ int ret; ++ ++ ret = reset_control_deassert(phy->rst_phy); ++ if (ret) { ++ dev_err(phy->dev, "Cannot deassert phy reset control: %d\n", ret); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(phy->clk_bus); ++ if (ret) { ++ dev_err(phy->dev, "Cannot enable bus clock: %d\n", ret); ++ goto err_assert_rst_phy; ++ } ++ ++ ret = clk_prepare_enable(phy->clk_mod); ++ if (ret) { ++ dev_err(phy->dev, "Cannot enable mod clock: %d\n", ret); ++ goto err_disable_clk_bus; ++ } ++ ++ if (phy->variant->has_phy_clk) { ++ ret = sun8i_phy_clk_create(phy, phy->dev, ++ phy->variant->has_second_pll); ++ if (ret) { ++ dev_err(phy->dev, "Couldn't create the PHY clock\n"); ++ goto err_disable_clk_mod; ++ } ++ ++ clk_prepare_enable(phy->clk_phy); ++ } ++ + phy->variant->phy_init(phy); ++ ++ return 0; ++ ++err_disable_clk_mod: ++ clk_disable_unprepare(phy->clk_mod); ++err_disable_clk_bus: ++ clk_disable_unprepare(phy->clk_bus); ++err_assert_rst_phy: ++ reset_control_assert(phy->rst_phy); ++ ++ return ret; ++} ++ ++void sun8i_hdmi_phy_deinit(struct sun8i_hdmi_phy *phy) ++{ ++ clk_disable_unprepare(phy->clk_mod); ++ clk_disable_unprepare(phy->clk_bus); ++ clk_disable_unprepare(phy->clk_phy); ++ ++ reset_control_assert(phy->rst_phy); + } + + void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy, +@@ -638,6 +689,7 @@ static int sun8i_hdmi_phy_probe(struct platform_device *pdev) + return -ENOMEM; + + phy->variant = (struct sun8i_hdmi_phy_variant *)match->data; ++ phy->dev = dev; + + ret = of_address_to_resource(node, 0, &res); + if (ret) { +@@ -696,47 +748,10 @@ static int sun8i_hdmi_phy_probe(struct platform_device *pdev) + goto err_put_clk_pll1; + } + +- ret = reset_control_deassert(phy->rst_phy); +- if (ret) { +- dev_err(dev, "Cannot deassert phy reset control: %d\n", ret); +- goto err_put_rst_phy; +- } +- +- ret = clk_prepare_enable(phy->clk_bus); +- if (ret) { +- dev_err(dev, "Cannot enable bus clock: %d\n", ret); +- goto err_deassert_rst_phy; +- } +- +- ret = clk_prepare_enable(phy->clk_mod); +- if (ret) { +- dev_err(dev, "Cannot enable mod clock: %d\n", ret); +- goto err_disable_clk_bus; +- } +- +- if (phy->variant->has_phy_clk) { +- ret = sun8i_phy_clk_create(phy, dev, +- phy->variant->has_second_pll); +- if (ret) { +- dev_err(dev, "Couldn't create the PHY clock\n"); +- goto err_disable_clk_mod; +- } +- +- clk_prepare_enable(phy->clk_phy); +- } +- + platform_set_drvdata(pdev, phy); + + return 0; + +-err_disable_clk_mod: +- clk_disable_unprepare(phy->clk_mod); +-err_disable_clk_bus: +- clk_disable_unprepare(phy->clk_bus); +-err_deassert_rst_phy: +- reset_control_assert(phy->rst_phy); +-err_put_rst_phy: +- reset_control_put(phy->rst_phy); + err_put_clk_pll1: + clk_put(phy->clk_pll1); + err_put_clk_pll0: +@@ -753,12 +768,6 @@ static int sun8i_hdmi_phy_remove(struct platform_device *pdev) + { + struct sun8i_hdmi_phy *phy = platform_get_drvdata(pdev); + +- clk_disable_unprepare(phy->clk_mod); +- clk_disable_unprepare(phy->clk_bus); +- clk_disable_unprepare(phy->clk_phy); +- +- reset_control_assert(phy->rst_phy); +- + reset_control_put(phy->rst_phy); + + clk_put(phy->clk_pll0); +diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c +index 4e0b7c2882ced..015e11c4663f3 100644 +--- a/drivers/i2c/busses/i2c-mlxcpld.c ++++ b/drivers/i2c/busses/i2c-mlxcpld.c +@@ -49,7 +49,7 @@ + #define MLXCPLD_LPCI2C_NACK_IND 2 + + #define MLXCPLD_I2C_FREQ_1000KHZ_SET 0x04 +-#define MLXCPLD_I2C_FREQ_400KHZ_SET 0x0f ++#define MLXCPLD_I2C_FREQ_400KHZ_SET 0x0c + #define MLXCPLD_I2C_FREQ_100KHZ_SET 0x42 + + enum mlxcpld_i2c_frequency { +@@ -495,7 +495,7 @@ mlxcpld_i2c_set_frequency(struct mlxcpld_i2c_priv *priv, + return err; + + /* Set frequency only if it is not 100KHz, which is default. */ +- switch ((data->reg & data->mask) >> data->bit) { ++ switch ((regval & data->mask) >> data->bit) { + case MLXCPLD_I2C_FREQ_1000KHZ: + freq = MLXCPLD_I2C_FREQ_1000KHZ_SET; + break; +diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c +index 477480d1de6bd..7d4b3eb7077ad 100644 +--- a/drivers/i2c/busses/i2c-mt65xx.c ++++ b/drivers/i2c/busses/i2c-mt65xx.c +@@ -41,6 +41,8 @@ + #define I2C_HANDSHAKE_RST 0x0020 + #define I2C_FIFO_ADDR_CLR 0x0001 + #define I2C_DELAY_LEN 0x0002 ++#define I2C_ST_START_CON 0x8001 ++#define I2C_FS_START_CON 0x1800 + #define I2C_TIME_CLR_VALUE 0x0000 + #define I2C_TIME_DEFAULT_VALUE 0x0003 + #define I2C_WRRD_TRANAC_VALUE 0x0002 +@@ -480,6 +482,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c) + { + u16 control_reg; + u16 intr_stat_reg; ++ u16 ext_conf_val; + + mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_START); + intr_stat_reg = mtk_i2c_readw(i2c, OFFSET_INTR_STAT); +@@ -518,8 +521,13 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c) + if (i2c->dev_comp->ltiming_adjust) + mtk_i2c_writew(i2c, i2c->ltiming_reg, OFFSET_LTIMING); + ++ if (i2c->speed_hz <= I2C_MAX_STANDARD_MODE_FREQ) ++ ext_conf_val = I2C_ST_START_CON; ++ else ++ ext_conf_val = I2C_FS_START_CON; ++ + if (i2c->dev_comp->timing_adjust) { +- mtk_i2c_writew(i2c, i2c->ac_timing.ext, OFFSET_EXT_CONF); ++ ext_conf_val = i2c->ac_timing.ext; + mtk_i2c_writew(i2c, i2c->ac_timing.inter_clk_div, + OFFSET_CLOCK_DIV); + mtk_i2c_writew(i2c, I2C_SCL_MIS_COMP_VALUE, +@@ -544,6 +552,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c) + OFFSET_HS_STA_STO_AC_TIMING); + } + } ++ mtk_i2c_writew(i2c, ext_conf_val, OFFSET_EXT_CONF); + + /* If use i2c pin from PMIC mt6397 side, need set PATH_DIR first */ + if (i2c->have_pmic) +diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c +index 6f0aa0ed3241e..74925621f2395 100644 +--- a/drivers/i2c/i2c-core-acpi.c ++++ b/drivers/i2c/i2c-core-acpi.c +@@ -422,6 +422,7 @@ static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, + break; + + i2c_acpi_register_device(adapter, adev, &info); ++ put_device(&adapter->dev); + break; + case ACPI_RECONFIG_DEVICE_REMOVE: + if (!acpi_device_enumerated(adev)) +diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c +index 3f28eb4d17fe7..8f36536cb1b6d 100644 +--- a/drivers/mmc/host/meson-gx-mmc.c ++++ b/drivers/mmc/host/meson-gx-mmc.c +@@ -746,7 +746,7 @@ static void meson_mmc_desc_chain_transfer(struct mmc_host *mmc, u32 cmd_cfg) + writel(start, host->regs + SD_EMMC_START); + } + +-/* local sg copy to buffer version with _to/fromio usage for dram_access_quirk */ ++/* local sg copy for dram_access_quirk */ + static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data, + size_t buflen, bool to_buffer) + { +@@ -764,21 +764,27 @@ static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data + sg_miter_start(&miter, sgl, nents, sg_flags); + + while ((offset < buflen) && sg_miter_next(&miter)) { +- unsigned int len; ++ unsigned int buf_offset = 0; ++ unsigned int len, left; ++ u32 *buf = miter.addr; + + len = min(miter.length, buflen - offset); ++ left = len; + +- /* When dram_access_quirk, the bounce buffer is a iomem mapping */ +- if (host->dram_access_quirk) { +- if (to_buffer) +- memcpy_toio(host->bounce_iomem_buf + offset, miter.addr, len); +- else +- memcpy_fromio(miter.addr, host->bounce_iomem_buf + offset, len); ++ if (to_buffer) { ++ do { ++ writel(*buf++, host->bounce_iomem_buf + offset + buf_offset); ++ ++ buf_offset += 4; ++ left -= 4; ++ } while (left); + } else { +- if (to_buffer) +- memcpy(host->bounce_buf + offset, miter.addr, len); +- else +- memcpy(miter.addr, host->bounce_buf + offset, len); ++ do { ++ *buf++ = readl(host->bounce_iomem_buf + offset + buf_offset); ++ ++ buf_offset += 4; ++ left -= 4; ++ } while (left); + } + + offset += len; +@@ -830,7 +836,11 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) + if (data->flags & MMC_DATA_WRITE) { + cmd_cfg |= CMD_CFG_DATA_WR; + WARN_ON(xfer_bytes > host->bounce_buf_size); +- meson_mmc_copy_buffer(host, data, xfer_bytes, true); ++ if (host->dram_access_quirk) ++ meson_mmc_copy_buffer(host, data, xfer_bytes, true); ++ else ++ sg_copy_to_buffer(data->sg, data->sg_len, ++ host->bounce_buf, xfer_bytes); + dma_wmb(); + } + +@@ -849,12 +859,43 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) + writel(cmd->arg, host->regs + SD_EMMC_CMD_ARG); + } + ++static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data *data) ++{ ++ struct scatterlist *sg; ++ int i; ++ ++ /* Reject request if any element offset or size is not 32bit aligned */ ++ for_each_sg(data->sg, sg, data->sg_len, i) { ++ if (!IS_ALIGNED(sg->offset, sizeof(u32)) || ++ !IS_ALIGNED(sg->length, sizeof(u32))) { ++ dev_err(mmc_dev(mmc), "unaligned sg offset %u len %u\n", ++ data->sg->offset, data->sg->length); ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ + static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) + { + struct meson_host *host = mmc_priv(mmc); + bool needs_pre_post_req = mrq->data && + !(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE); + ++ /* ++ * The memory at the end of the controller used as bounce buffer for ++ * the dram_access_quirk only accepts 32bit read/write access, ++ * check the aligment and length of the data before starting the request. ++ */ ++ if (host->dram_access_quirk && mrq->data) { ++ mrq->cmd->error = meson_mmc_validate_dram_access(mmc, mrq->data); ++ if (mrq->cmd->error) { ++ mmc_request_done(mmc, mrq); ++ return; ++ } ++ } ++ + if (needs_pre_post_req) { + meson_mmc_get_transfer_mode(mmc, mrq); + if (!meson_mmc_desc_chain_mode(mrq->data)) +@@ -999,7 +1040,11 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) + if (meson_mmc_bounce_buf_read(data)) { + xfer_bytes = data->blksz * data->blocks; + WARN_ON(xfer_bytes > host->bounce_buf_size); +- meson_mmc_copy_buffer(host, data, xfer_bytes, false); ++ if (host->dram_access_quirk) ++ meson_mmc_copy_buffer(host, data, xfer_bytes, false); ++ else ++ sg_copy_from_buffer(data->sg, data->sg_len, ++ host->bounce_buf, xfer_bytes); + } + + next_cmd = meson_mmc_get_next_command(cmd); +diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c +index 5564d7b23e7cd..d1a1c548c515f 100644 +--- a/drivers/mmc/host/sdhci-of-at91.c ++++ b/drivers/mmc/host/sdhci-of-at91.c +@@ -11,6 +11,7 @@ + #include <linux/delay.h> + #include <linux/err.h> + #include <linux/io.h> ++#include <linux/iopoll.h> + #include <linux/kernel.h> + #include <linux/mmc/host.h> + #include <linux/mmc/slot-gpio.h> +@@ -61,7 +62,6 @@ static void sdhci_at91_set_force_card_detect(struct sdhci_host *host) + static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock) + { + u16 clk; +- unsigned long timeout; + + host->mmc->actual_clock = 0; + +@@ -86,16 +86,11 @@ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock) + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); + + /* Wait max 20 ms */ +- timeout = 20; +- while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) +- & SDHCI_CLOCK_INT_STABLE)) { +- if (timeout == 0) { +- pr_err("%s: Internal clock never stabilised.\n", +- mmc_hostname(host->mmc)); +- return; +- } +- timeout--; +- mdelay(1); ++ if (read_poll_timeout(sdhci_readw, clk, (clk & SDHCI_CLOCK_INT_STABLE), ++ 1000, 20000, false, host, SDHCI_CLOCK_CONTROL)) { ++ pr_err("%s: Internal clock never stabilised.\n", ++ mmc_hostname(host->mmc)); ++ return; + } + + clk |= SDHCI_CLOCK_CARD_EN; +@@ -114,6 +109,7 @@ static void sdhci_at91_reset(struct sdhci_host *host, u8 mask) + { + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_at91_priv *priv = sdhci_pltfm_priv(pltfm_host); ++ unsigned int tmp; + + sdhci_reset(host, mask); + +@@ -126,6 +122,10 @@ static void sdhci_at91_reset(struct sdhci_host *host, u8 mask) + + sdhci_writel(host, calcr | SDMMC_CALCR_ALWYSON | SDMMC_CALCR_EN, + SDMMC_CALCR); ++ ++ if (read_poll_timeout(sdhci_readl, tmp, !(tmp & SDMMC_CALCR_EN), ++ 10, 20000, false, host, SDMMC_CALCR)) ++ dev_err(mmc_dev(host->mmc), "Failed to calibrate\n"); + } + } + +diff --git a/drivers/net/ethernet/google/gve/gve.h b/drivers/net/ethernet/google/gve/gve.h +index 1d3188e8e3b3c..92dc18a4bcc41 100644 +--- a/drivers/net/ethernet/google/gve/gve.h ++++ b/drivers/net/ethernet/google/gve/gve.h +@@ -780,7 +780,7 @@ struct gve_queue_page_list *gve_assign_rx_qpl(struct gve_priv *priv) + gve_num_tx_qpls(priv)); + + /* we are out of rx qpls */ +- if (id == priv->qpl_cfg.qpl_map_size) ++ if (id == gve_num_tx_qpls(priv) + gve_num_rx_qpls(priv)) + return NULL; + + set_bit(id, priv->qpl_cfg.qpl_id_map); +diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c +index 099a2bc5ae670..bf8a4a7c43f78 100644 +--- a/drivers/net/ethernet/google/gve/gve_main.c ++++ b/drivers/net/ethernet/google/gve/gve_main.c +@@ -41,6 +41,7 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) + { + struct gve_priv *priv = netdev_priv(dev); + unsigned int start; ++ u64 packets, bytes; + int ring; + + if (priv->rx) { +@@ -48,10 +49,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) + do { + start = + u64_stats_fetch_begin(&priv->rx[ring].statss); +- s->rx_packets += priv->rx[ring].rpackets; +- s->rx_bytes += priv->rx[ring].rbytes; ++ packets = priv->rx[ring].rpackets; ++ bytes = priv->rx[ring].rbytes; + } while (u64_stats_fetch_retry(&priv->rx[ring].statss, + start)); ++ s->rx_packets += packets; ++ s->rx_bytes += bytes; + } + } + if (priv->tx) { +@@ -59,10 +62,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) + do { + start = + u64_stats_fetch_begin(&priv->tx[ring].statss); +- s->tx_packets += priv->tx[ring].pkt_done; +- s->tx_bytes += priv->tx[ring].bytes_done; ++ packets = priv->tx[ring].pkt_done; ++ bytes = priv->tx[ring].bytes_done; + } while (u64_stats_fetch_retry(&priv->tx[ring].statss, + start)); ++ s->tx_packets += packets; ++ s->tx_bytes += bytes; + } + } + } +@@ -82,6 +87,9 @@ static int gve_alloc_counter_array(struct gve_priv *priv) + + static void gve_free_counter_array(struct gve_priv *priv) + { ++ if (!priv->counter_array) ++ return; ++ + dma_free_coherent(&priv->pdev->dev, + priv->num_event_counters * + sizeof(*priv->counter_array), +@@ -142,6 +150,9 @@ static int gve_alloc_stats_report(struct gve_priv *priv) + + static void gve_free_stats_report(struct gve_priv *priv) + { ++ if (!priv->stats_report) ++ return; ++ + del_timer_sync(&priv->stats_report_timer); + dma_free_coherent(&priv->pdev->dev, priv->stats_report_len, + priv->stats_report, priv->stats_report_bus); +@@ -370,18 +381,19 @@ static void gve_free_notify_blocks(struct gve_priv *priv) + { + int i; + +- if (priv->msix_vectors) { +- /* Free the irqs */ +- for (i = 0; i < priv->num_ntfy_blks; i++) { +- struct gve_notify_block *block = &priv->ntfy_blocks[i]; +- int msix_idx = i; ++ if (!priv->msix_vectors) ++ return; + +- irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector, +- NULL); +- free_irq(priv->msix_vectors[msix_idx].vector, block); +- } +- free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv); ++ /* Free the irqs */ ++ for (i = 0; i < priv->num_ntfy_blks; i++) { ++ struct gve_notify_block *block = &priv->ntfy_blocks[i]; ++ int msix_idx = i; ++ ++ irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector, ++ NULL); ++ free_irq(priv->msix_vectors[msix_idx].vector, block); + } ++ free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv); + dma_free_coherent(&priv->pdev->dev, + priv->num_ntfy_blks * sizeof(*priv->ntfy_blocks), + priv->ntfy_blocks, priv->ntfy_block_bus); +@@ -1185,9 +1197,10 @@ static void gve_handle_reset(struct gve_priv *priv) + + void gve_handle_report_stats(struct gve_priv *priv) + { +- int idx, stats_idx = 0, tx_bytes; +- unsigned int start = 0; + struct stats *stats = priv->stats_report->stats; ++ int idx, stats_idx = 0; ++ unsigned int start = 0; ++ u64 tx_bytes; + + if (!gve_get_report_stats(priv)) + return; +diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c +index bb82613682502..94941d4e47449 100644 +--- a/drivers/net/ethernet/google/gve/gve_rx.c ++++ b/drivers/net/ethernet/google/gve/gve_rx.c +@@ -104,8 +104,14 @@ static int gve_prefill_rx_pages(struct gve_rx_ring *rx) + if (!rx->data.page_info) + return -ENOMEM; + +- if (!rx->data.raw_addressing) ++ if (!rx->data.raw_addressing) { + rx->data.qpl = gve_assign_rx_qpl(priv); ++ if (!rx->data.qpl) { ++ kvfree(rx->data.page_info); ++ rx->data.page_info = NULL; ++ return -ENOMEM; ++ } ++ } + for (i = 0; i < slots; i++) { + if (!rx->data.raw_addressing) { + struct page *page = rx->data.qpl->pages[i]; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c +index 1d1f52756a932..5d3d6b1dae7b0 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -4868,7 +4868,8 @@ static void i40e_clear_interrupt_scheme(struct i40e_pf *pf) + { + int i; + +- i40e_free_misc_vector(pf); ++ if (test_bit(__I40E_MISC_IRQ_REQUESTED, pf->state)) ++ i40e_free_misc_vector(pf); + + i40e_put_lump(pf->irq_pile, pf->iwarp_base_vector, + I40E_IWARP_IRQ_PILE_ID); +@@ -10110,7 +10111,7 @@ static int i40e_get_capabilities(struct i40e_pf *pf, + if (pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOMEM) { + /* retry with a larger buffer */ + buf_len = data_size; +- } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK) { ++ } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK || err) { + dev_info(&pf->pdev->dev, + "capability discovery failed, err %s aq_err %s\n", + i40e_stat_str(&pf->hw, err), +diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c +index 23762a7ef740b..cada4e0e40b48 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_main.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c +@@ -1965,7 +1965,6 @@ static void iavf_watchdog_task(struct work_struct *work) + } + adapter->aq_required = 0; + adapter->current_op = VIRTCHNL_OP_UNKNOWN; +- mutex_unlock(&adapter->crit_lock); + queue_delayed_work(iavf_wq, + &adapter->watchdog_task, + msecs_to_jiffies(10)); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h +index 3f67efbe12fc5..dcbdf746be35c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h +@@ -863,6 +863,7 @@ struct mlx5e_priv { + struct mlx5e_channel_stats channel_stats[MLX5E_MAX_NUM_CHANNELS]; + struct mlx5e_channel_stats trap_stats; + struct mlx5e_ptp_stats ptp_stats; ++ u16 stats_nch; + u16 max_nch; + u8 max_opened_tc; + bool tx_ptp_opened; +@@ -1156,12 +1157,6 @@ int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv, + struct ethtool_pauseparam *pauseparam); + + /* mlx5e generic netdev management API */ +-static inline unsigned int +-mlx5e_calc_max_nch(struct mlx5e_priv *priv, const struct mlx5e_profile *profile) +-{ +- return priv->netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1); +-} +- + static inline bool + mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev) + { +@@ -1170,11 +1165,13 @@ mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev) + } + + int mlx5e_priv_init(struct mlx5e_priv *priv, ++ const struct mlx5e_profile *profile, + struct net_device *netdev, + struct mlx5_core_dev *mdev); + void mlx5e_priv_cleanup(struct mlx5e_priv *priv); + struct net_device * +-mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs); ++mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile, ++ unsigned int txqs, unsigned int rxqs); + int mlx5e_attach_netdev(struct mlx5e_priv *priv); + void mlx5e_detach_netdev(struct mlx5e_priv *priv); + void mlx5e_destroy_netdev(struct mlx5e_priv *priv); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c +index ac44bbe95c5c1..d290d7276b8d9 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c +@@ -35,7 +35,7 @@ static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, void *data, + { + int ch, i = 0; + +- for (ch = 0; ch < priv->max_nch; ch++) { ++ for (ch = 0; ch < priv->stats_nch; ch++) { + void *buf = data + i; + + if (WARN_ON_ONCE(buf + +@@ -51,7 +51,7 @@ static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, void *data, + static int mlx5e_hv_vhca_stats_buf_size(struct mlx5e_priv *priv) + { + return (sizeof(struct mlx5e_hv_vhca_per_ring_stats) * +- priv->max_nch); ++ priv->stats_nch); + } + + static void mlx5e_hv_vhca_stats_work(struct work_struct *work) +@@ -100,7 +100,7 @@ static void mlx5e_hv_vhca_stats_control(struct mlx5_hv_vhca_agent *agent, + sagent = &priv->stats_agent; + + block->version = MLX5_HV_VHCA_STATS_VERSION; +- block->rings = priv->max_nch; ++ block->rings = priv->stats_nch; + + if (!block->command) { + cancel_delayed_work_sync(&priv->stats_agent.work); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +index efef4adce086a..93a8fa31255d0 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +@@ -13,8 +13,6 @@ struct mlx5e_ptp_fs { + bool valid; + }; + +-#define MLX5E_PTP_CHANNEL_IX 0 +- + struct mlx5e_ptp_params { + struct mlx5e_params params; + struct mlx5e_sq_param txq_sq_param; +@@ -505,6 +503,7 @@ static int mlx5e_init_ptp_rq(struct mlx5e_ptp *c, struct mlx5e_params *params, + rq->mdev = mdev; + rq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); + rq->stats = &c->priv->ptp_stats.rq; ++ rq->ix = MLX5E_PTP_CHANNEL_IX; + rq->ptp_cyc2time = mlx5_rq_ts_translator(mdev); + err = mlx5e_rq_set_handlers(rq, params, false); + if (err) +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h +index c96668bd701cd..a71a32e00ebb9 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h +@@ -8,6 +8,8 @@ + #include "en_stats.h" + #include <linux/ptp_classify.h> + ++#define MLX5E_PTP_CHANNEL_IX 0 ++ + struct mlx5e_ptpsq { + struct mlx5e_txqsq txqsq; + struct mlx5e_cq ts_cq; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index fa718e71db2d4..548e8e7fc956e 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -3515,7 +3515,7 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s) + { + int i; + +- for (i = 0; i < priv->max_nch; i++) { ++ for (i = 0; i < priv->stats_nch; i++) { + struct mlx5e_channel_stats *channel_stats = &priv->channel_stats[i]; + struct mlx5e_rq_stats *xskrq_stats = &channel_stats->xskrq; + struct mlx5e_rq_stats *rq_stats = &channel_stats->rq; +@@ -4661,8 +4661,6 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16 + struct mlx5_core_dev *mdev = priv->mdev; + u8 rx_cq_period_mode; + +- priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile); +- + params->sw_mtu = mtu; + params->hard_mtu = MLX5E_ETH_HARD_MTU; + params->num_channels = min_t(unsigned int, MLX5E_MAX_NUM_CHANNELS / 2, +@@ -5203,8 +5201,35 @@ static const struct mlx5e_profile mlx5e_nic_profile = { + .rx_ptp_support = true, + }; + ++static unsigned int ++mlx5e_calc_max_nch(struct mlx5_core_dev *mdev, struct net_device *netdev, ++ const struct mlx5e_profile *profile) ++ ++{ ++ unsigned int max_nch, tmp; ++ ++ /* core resources */ ++ max_nch = mlx5e_get_max_num_channels(mdev); ++ ++ /* netdev rx queues */ ++ tmp = netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1); ++ max_nch = min_t(unsigned int, max_nch, tmp); ++ ++ /* netdev tx queues */ ++ tmp = netdev->num_tx_queues; ++ if (mlx5_qos_is_supported(mdev)) ++ tmp -= mlx5e_qos_max_leaf_nodes(mdev); ++ if (MLX5_CAP_GEN(mdev, ts_cqe_to_dest_cqn)) ++ tmp -= profile->max_tc; ++ tmp = tmp / profile->max_tc; ++ max_nch = min_t(unsigned int, max_nch, tmp); ++ ++ return max_nch; ++} ++ + /* mlx5e generic netdev management API (move to en_common.c) */ + int mlx5e_priv_init(struct mlx5e_priv *priv, ++ const struct mlx5e_profile *profile, + struct net_device *netdev, + struct mlx5_core_dev *mdev) + { +@@ -5212,6 +5237,8 @@ int mlx5e_priv_init(struct mlx5e_priv *priv, + priv->mdev = mdev; + priv->netdev = netdev; + priv->msglevel = MLX5E_MSG_LEVEL; ++ priv->max_nch = mlx5e_calc_max_nch(mdev, netdev, profile); ++ priv->stats_nch = priv->max_nch; + priv->max_opened_tc = 1; + + if (!alloc_cpumask_var(&priv->scratchpad.cpumask, GFP_KERNEL)) +@@ -5255,7 +5282,8 @@ void mlx5e_priv_cleanup(struct mlx5e_priv *priv) + } + + struct net_device * +-mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs) ++mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile, ++ unsigned int txqs, unsigned int rxqs) + { + struct net_device *netdev; + int err; +@@ -5266,7 +5294,7 @@ mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int + return NULL; + } + +- err = mlx5e_priv_init(netdev_priv(netdev), netdev, mdev); ++ err = mlx5e_priv_init(netdev_priv(netdev), profile, netdev, mdev); + if (err) { + mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err); + goto err_free_netdev; +@@ -5308,7 +5336,7 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv) + clear_bit(MLX5E_STATE_DESTROYING, &priv->state); + + /* max number of channels may have changed */ +- max_nch = mlx5e_get_max_num_channels(priv->mdev); ++ max_nch = mlx5e_calc_max_nch(priv->mdev, priv->netdev, profile); + if (priv->channels.params.num_channels > max_nch) { + mlx5_core_warn(priv->mdev, "MLX5E: Reducing number of channels to %d\n", max_nch); + /* Reducing the number of channels - RXFH has to be reset, and +@@ -5317,6 +5345,13 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv) + priv->netdev->priv_flags &= ~IFF_RXFH_CONFIGURED; + priv->channels.params.num_channels = max_nch; + } ++ if (max_nch != priv->max_nch) { ++ mlx5_core_warn(priv->mdev, ++ "MLX5E: Updating max number of channels from %u to %u\n", ++ priv->max_nch, max_nch); ++ priv->max_nch = max_nch; ++ } ++ + /* 1. Set the real number of queues in the kernel the first time. + * 2. Set our default XPS cpumask. + * 3. Build the RQT. +@@ -5381,7 +5416,7 @@ mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mde + struct mlx5e_priv *priv = netdev_priv(netdev); + int err; + +- err = mlx5e_priv_init(priv, netdev, mdev); ++ err = mlx5e_priv_init(priv, new_profile, netdev, mdev); + if (err) { + mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err); + return err; +@@ -5407,20 +5442,12 @@ priv_cleanup: + int mlx5e_netdev_change_profile(struct mlx5e_priv *priv, + const struct mlx5e_profile *new_profile, void *new_ppriv) + { +- unsigned int new_max_nch = mlx5e_calc_max_nch(priv, new_profile); + const struct mlx5e_profile *orig_profile = priv->profile; + struct net_device *netdev = priv->netdev; + struct mlx5_core_dev *mdev = priv->mdev; + void *orig_ppriv = priv->ppriv; + int err, rollback_err; + +- /* sanity */ +- if (new_max_nch != priv->max_nch) { +- netdev_warn(netdev, "%s: Replacing profile with different max channels\n", +- __func__); +- return -EINVAL; +- } +- + /* cleanup old profile */ + mlx5e_detach_netdev(priv); + priv->profile->cleanup(priv); +@@ -5516,7 +5543,7 @@ static int mlx5e_probe(struct auxiliary_device *adev, + nch = mlx5e_get_max_num_channels(mdev); + txqs = nch * profile->max_tc + ptp_txqs + qos_sqs; + rxqs = nch * profile->rq_groups; +- netdev = mlx5e_create_netdev(mdev, txqs, rxqs); ++ netdev = mlx5e_create_netdev(mdev, profile, txqs, rxqs); + if (!netdev) { + mlx5_core_err(mdev, "mlx5e_create_netdev failed\n"); + return -ENOMEM; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +index bf94bcb6fa5d2..bec1d344481cd 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +@@ -561,7 +561,6 @@ static void mlx5e_build_rep_params(struct net_device *netdev) + MLX5_CQ_PERIOD_MODE_START_FROM_CQE : + MLX5_CQ_PERIOD_MODE_START_FROM_EQE; + +- priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile); + params = &priv->channels.params; + + params->num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS; +@@ -1151,7 +1150,7 @@ mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) + nch = mlx5e_get_max_num_channels(dev); + txqs = nch * profile->max_tc; + rxqs = nch * profile->rq_groups; +- netdev = mlx5e_create_netdev(dev, txqs, rxqs); ++ netdev = mlx5e_create_netdev(dev, profile, txqs, rxqs); + if (!netdev) { + mlx5_core_warn(dev, + "Failed to create representor netdev for vport %d\n", +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +index 3c65fd0bcf31c..29a6586ef28dc 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +@@ -1001,14 +1001,9 @@ static inline void mlx5e_handle_csum(struct net_device *netdev, + goto csum_unnecessary; + + if (likely(is_last_ethertype_ip(skb, &network_depth, &proto))) { +- u8 ipproto = get_ip_proto(skb, network_depth, proto); +- +- if (unlikely(ipproto == IPPROTO_SCTP)) ++ if (unlikely(get_ip_proto(skb, network_depth, proto) == IPPROTO_SCTP)) + goto csum_unnecessary; + +- if (unlikely(mlx5_ipsec_is_rx_flow(cqe))) +- goto csum_none; +- + stats->csum_complete++; + skb->ip_summed = CHECKSUM_COMPLETE; + skb->csum = csum_unfold((__force __sum16)cqe->check_sum); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c +index e4f5b63951482..e1dd17019030e 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c +@@ -34,6 +34,7 @@ + #include "en.h" + #include "en_accel/tls.h" + #include "en_accel/en_accel.h" ++#include "en/ptp.h" + + static unsigned int stats_grps_num(struct mlx5e_priv *priv) + { +@@ -450,7 +451,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(sw) + + memset(s, 0, sizeof(*s)); + +- for (i = 0; i < priv->max_nch; i++) { ++ for (i = 0; i < priv->stats_nch; i++) { + struct mlx5e_channel_stats *channel_stats = + &priv->channel_stats[i]; + int j; +@@ -2076,7 +2077,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(ptp) + if (priv->rx_ptp_opened) { + for (i = 0; i < NUM_PTP_RQ_STATS; i++) + sprintf(data + (idx++) * ETH_GSTRING_LEN, +- ptp_rq_stats_desc[i].format); ++ ptp_rq_stats_desc[i].format, MLX5E_PTP_CHANNEL_IX); + } + return idx; + } +@@ -2119,7 +2120,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(ptp) { return; } + + static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(channels) + { +- int max_nch = priv->max_nch; ++ int max_nch = priv->stats_nch; + + return (NUM_RQ_STATS * max_nch) + + (NUM_CH_STATS * max_nch) + +@@ -2133,7 +2134,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(channels) + static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(channels) + { + bool is_xsk = priv->xsk.ever_used; +- int max_nch = priv->max_nch; ++ int max_nch = priv->stats_nch; + int i, j, tc; + + for (i = 0; i < max_nch; i++) +@@ -2175,7 +2176,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(channels) + static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(channels) + { + bool is_xsk = priv->xsk.ever_used; +- int max_nch = priv->max_nch; ++ int max_nch = priv->stats_nch; + int i, j, tc; + + for (i = 0; i < max_nch; i++) +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c +index 0399a396d1662..60a73990017c2 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c +@@ -79,12 +79,16 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw, + int dest_num = 0; + int err = 0; + +- if (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, flow_counter)) { ++ if (vport->egress.legacy.drop_counter) { ++ drop_counter = vport->egress.legacy.drop_counter; ++ } else if (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, flow_counter)) { + drop_counter = mlx5_fc_create(esw->dev, false); +- if (IS_ERR(drop_counter)) ++ if (IS_ERR(drop_counter)) { + esw_warn(esw->dev, + "vport[%d] configure egress drop rule counter err(%ld)\n", + vport->vport, PTR_ERR(drop_counter)); ++ drop_counter = NULL; ++ } + vport->egress.legacy.drop_counter = drop_counter; + } + +@@ -123,7 +127,7 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw, + flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP; + + /* Attach egress drop flow counter */ +- if (!IS_ERR_OR_NULL(drop_counter)) { ++ if (drop_counter) { + flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT; + drop_ctr_dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER; + drop_ctr_dst.counter_id = mlx5_fc_id(drop_counter); +@@ -162,7 +166,7 @@ void esw_acl_egress_lgcy_cleanup(struct mlx5_eswitch *esw, + esw_acl_egress_table_destroy(vport); + + clean_drop_counter: +- if (!IS_ERR_OR_NULL(vport->egress.legacy.drop_counter)) { ++ if (vport->egress.legacy.drop_counter) { + mlx5_fc_destroy(esw->dev, vport->egress.legacy.drop_counter); + vport->egress.legacy.drop_counter = NULL; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c +index f75b86abaf1cd..b1a5199260f69 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c +@@ -160,7 +160,9 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw, + + esw_acl_ingress_lgcy_rules_destroy(vport); + +- if (MLX5_CAP_ESW_INGRESS_ACL(esw->dev, flow_counter)) { ++ if (vport->ingress.legacy.drop_counter) { ++ counter = vport->ingress.legacy.drop_counter; ++ } else if (MLX5_CAP_ESW_INGRESS_ACL(esw->dev, flow_counter)) { + counter = mlx5_fc_create(esw->dev, false); + if (IS_ERR(counter)) { + esw_warn(esw->dev, +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +index 620d638e1e8ff..1c9de6eddef86 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +@@ -113,7 +113,7 @@ static void mlx5i_grp_sw_update_stats(struct mlx5e_priv *priv) + struct mlx5e_sw_stats s = { 0 }; + int i, j; + +- for (i = 0; i < priv->max_nch; i++) { ++ for (i = 0; i < priv->stats_nch; i++) { + struct mlx5e_channel_stats *channel_stats; + struct mlx5e_rq_stats *rq_stats; + +@@ -729,7 +729,7 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u32 port_num, + goto destroy_ht; + } + +- err = mlx5e_priv_init(epriv, netdev, mdev); ++ err = mlx5e_priv_init(epriv, prof, netdev, mdev); + if (err) + goto destroy_mdev_resources; + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +index ce696d5234931..c009ccc88df49 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +@@ -448,22 +448,20 @@ static u64 find_target_cycles(struct mlx5_core_dev *mdev, s64 target_ns) + return cycles_now + cycles_delta; + } + +-static u64 perout_conf_internal_timer(struct mlx5_core_dev *mdev, +- s64 sec, u32 nsec) ++static u64 perout_conf_internal_timer(struct mlx5_core_dev *mdev, s64 sec) + { +- struct timespec64 ts; ++ struct timespec64 ts = {}; + s64 target_ns; + + ts.tv_sec = sec; +- ts.tv_nsec = nsec; + target_ns = timespec64_to_ns(&ts); + + return find_target_cycles(mdev, target_ns); + } + +-static u64 perout_conf_real_time(s64 sec, u32 nsec) ++static u64 perout_conf_real_time(s64 sec) + { +- return (u64)nsec | (u64)sec << 32; ++ return (u64)sec << 32; + } + + static int mlx5_perout_configure(struct ptp_clock_info *ptp, +@@ -474,6 +472,7 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, + container_of(ptp, struct mlx5_clock, ptp_info); + struct mlx5_core_dev *mdev = + container_of(clock, struct mlx5_core_dev, clock); ++ bool rt_mode = mlx5_real_time_mode(mdev); + u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0}; + struct timespec64 ts; + u32 field_select = 0; +@@ -501,8 +500,10 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, + + if (on) { + bool rt_mode = mlx5_real_time_mode(mdev); +- u32 nsec; +- s64 sec; ++ s64 sec = rq->perout.start.sec; ++ ++ if (rq->perout.start.nsec) ++ return -EINVAL; + + pin_mode = MLX5_PIN_MODE_OUT; + pattern = MLX5_OUT_PATTERN_PERIODIC; +@@ -513,14 +514,11 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, + if ((ns >> 1) != 500000000LL) + return -EINVAL; + +- nsec = rq->perout.start.nsec; +- sec = rq->perout.start.sec; +- + if (rt_mode && sec > U32_MAX) + return -EINVAL; + +- time_stamp = rt_mode ? perout_conf_real_time(sec, nsec) : +- perout_conf_internal_timer(mdev, sec, nsec); ++ time_stamp = rt_mode ? perout_conf_real_time(sec) : ++ perout_conf_internal_timer(mdev, sec); + + field_select |= MLX5_MTPPS_FS_PIN_MODE | + MLX5_MTPPS_FS_PATTERN | +@@ -538,6 +536,9 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, + if (err) + return err; + ++ if (rt_mode) ++ return 0; ++ + return mlx5_set_mtppse(mdev, pin, 0, + MLX5_EVENT_MODE_REPETETIVE & on); + } +@@ -705,20 +706,14 @@ static void ts_next_sec(struct timespec64 *ts) + static u64 perout_conf_next_event_timer(struct mlx5_core_dev *mdev, + struct mlx5_clock *clock) + { +- bool rt_mode = mlx5_real_time_mode(mdev); + struct timespec64 ts; + s64 target_ns; + +- if (rt_mode) +- ts = mlx5_ptp_gettimex_real_time(mdev, NULL); +- else +- mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL); +- ++ mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL); + ts_next_sec(&ts); + target_ns = timespec64_to_ns(&ts); + +- return rt_mode ? perout_conf_real_time(ts.tv_sec, ts.tv_nsec) : +- find_target_cycles(mdev, target_ns); ++ return find_target_cycles(mdev, target_ns); + } + + static int mlx5_pps_event(struct notifier_block *nb, +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +index 3465b363fc2fe..d9345c9ebbff1 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +@@ -13,8 +13,8 @@ + #endif + + #define MLX5_MAX_IRQ_NAME (32) +-/* max irq_index is 255. three chars */ +-#define MLX5_MAX_IRQ_IDX_CHARS (3) ++/* max irq_index is 2047, so four chars */ ++#define MLX5_MAX_IRQ_IDX_CHARS (4) + + #define MLX5_SFS_PER_CTRL_IRQ 64 + #define MLX5_IRQ_CTRL_SF_MAX 8 +@@ -610,8 +610,9 @@ void mlx5_irq_table_destroy(struct mlx5_core_dev *dev) + int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table) + { + if (table->sf_comp_pool) +- return table->sf_comp_pool->xa_num_irqs.max - +- table->sf_comp_pool->xa_num_irqs.min + 1; ++ return min_t(int, num_online_cpus(), ++ table->sf_comp_pool->xa_num_irqs.max - ++ table->sf_comp_pool->xa_num_irqs.min + 1); + else + return mlx5_irq_table_get_num_comp(table); + } +diff --git a/drivers/net/ethernet/mscc/ocelot_vcap.c b/drivers/net/ethernet/mscc/ocelot_vcap.c +index 7945393a06557..99d7376a70a74 100644 +--- a/drivers/net/ethernet/mscc/ocelot_vcap.c ++++ b/drivers/net/ethernet/mscc/ocelot_vcap.c +@@ -998,8 +998,8 @@ ocelot_vcap_block_find_filter_by_index(struct ocelot_vcap_block *block, + } + + struct ocelot_vcap_filter * +-ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int cookie, +- bool tc_offload) ++ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, ++ unsigned long cookie, bool tc_offload) + { + struct ocelot_vcap_filter *filter; + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +index ed817011a94a0..6924a6aacbd53 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +@@ -21,6 +21,7 @@ + #include <linux/delay.h> + #include <linux/mfd/syscon.h> + #include <linux/regmap.h> ++#include <linux/pm_runtime.h> + + #include "stmmac_platform.h" + +@@ -1528,6 +1529,8 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) + return ret; + } + ++ pm_runtime_get_sync(dev); ++ + if (bsp_priv->integrated_phy) + rk_gmac_integrated_phy_powerup(bsp_priv); + +@@ -1539,6 +1542,8 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac) + if (gmac->integrated_phy) + rk_gmac_integrated_phy_powerdown(gmac); + ++ pm_runtime_put_sync(&gmac->pdev->dev); ++ + phy_power_on(gmac, false); + gmac_clk_enable(gmac, false); + } +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 86151a817b79a..6b2a5e5769e89 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -477,6 +477,10 @@ bool stmmac_eee_init(struct stmmac_priv *priv) + stmmac_lpi_entry_timer_config(priv, 0); + del_timer_sync(&priv->eee_ctrl_timer); + stmmac_set_eee_timer(priv, priv->hw, 0, eee_tw_timer); ++ if (priv->hw->xpcs) ++ xpcs_config_eee(priv->hw->xpcs, ++ priv->plat->mult_fact_100ns, ++ false); + } + mutex_unlock(&priv->lock); + return false; +@@ -1038,7 +1042,7 @@ static void stmmac_mac_link_down(struct phylink_config *config, + stmmac_mac_set(priv, priv->ioaddr, false); + priv->eee_active = false; + priv->tx_lpi_enabled = false; +- stmmac_eee_init(priv); ++ priv->eee_enabled = stmmac_eee_init(priv); + stmmac_set_eee_pls(priv, priv->hw, false); + + if (priv->dma_cap.fpesel) +diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c +index 4bd61339823ce..d4ab03a92fb59 100644 +--- a/drivers/net/pcs/pcs-xpcs.c ++++ b/drivers/net/pcs/pcs-xpcs.c +@@ -662,6 +662,10 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) + { + int ret; + ++ ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0); ++ if (ret < 0) ++ return ret; ++ + if (enable) { + /* Enable EEE */ + ret = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | +@@ -669,9 +673,6 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) + DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | + mult_fact_100ns << DW_VR_MII_EEE_MULT_FACT_100NS_SHIFT; + } else { +- ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0); +- if (ret < 0) +- return ret; + ret &= ~(DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | + DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN | + DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | +@@ -686,21 +687,28 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) + if (ret < 0) + return ret; + +- ret |= DW_VR_MII_EEE_TRN_LPI; ++ if (enable) ++ ret |= DW_VR_MII_EEE_TRN_LPI; ++ else ++ ret &= ~DW_VR_MII_EEE_TRN_LPI; ++ + return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, ret); + } + EXPORT_SYMBOL_GPL(xpcs_config_eee); + + static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) + { +- int ret; ++ int ret, mdio_ctrl; + + /* For AN for C37 SGMII mode, the settings are :- +- * 1) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN) +- * 2) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII) ++ * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable SGMII AN in case ++ it is already enabled) ++ * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN) ++ * 3) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII) + * DW xPCS used with DW EQoS MAC is always MAC side SGMII. +- * 3) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic ++ * 4) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic + * speed/duplex mode change by HW after SGMII AN complete) ++ * 5) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable SGMII AN) + * + * Note: Since it is MAC side SGMII, there is no need to set + * SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from +@@ -708,6 +716,17 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) + * between PHY and Link Partner. There is also no need to + * trigger AN restart for MAC-side SGMII. + */ ++ mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL); ++ if (mdio_ctrl < 0) ++ return mdio_ctrl; ++ ++ if (mdio_ctrl & AN_CL37_EN) { ++ ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ++ mdio_ctrl & ~AN_CL37_EN); ++ if (ret < 0) ++ return ret; ++ } ++ + ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL); + if (ret < 0) + return ret; +@@ -732,7 +751,15 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) + else + ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; + +- return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); ++ ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); ++ if (ret < 0) ++ return ret; ++ ++ if (phylink_autoneg_inband(mode)) ++ ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ++ mdio_ctrl | AN_CL37_EN); ++ ++ return ret; + } + + static int xpcs_config_2500basex(struct dw_xpcs *xpcs) +diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c +index ee8313a4ac713..6865d9319197f 100644 +--- a/drivers/net/phy/mdio_bus.c ++++ b/drivers/net/phy/mdio_bus.c +@@ -538,6 +538,13 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner) + bus->dev.groups = NULL; + dev_set_name(&bus->dev, "%s", bus->id); + ++ /* We need to set state to MDIOBUS_UNREGISTERED to correctly release ++ * the device in mdiobus_free() ++ * ++ * State will be updated later in this function in case of success ++ */ ++ bus->state = MDIOBUS_UNREGISTERED; ++ + err = device_register(&bus->dev); + if (err) { + pr_err("mii_bus %s failed to register\n", bus->id); +diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c +index 34e90216bd2cb..ab77a9f439ef9 100644 +--- a/drivers/net/phy/sfp.c ++++ b/drivers/net/phy/sfp.c +@@ -134,7 +134,7 @@ static const char * const sm_state_strings[] = { + [SFP_S_LINK_UP] = "link_up", + [SFP_S_TX_FAULT] = "tx_fault", + [SFP_S_REINIT] = "reinit", +- [SFP_S_TX_DISABLE] = "rx_disable", ++ [SFP_S_TX_DISABLE] = "tx_disable", + }; + + static const char *sm_state_to_str(unsigned short sm_state) +diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig +index f35cd8de228e4..6914b37bb0fbc 100644 +--- a/drivers/net/wireless/ath/ath5k/Kconfig ++++ b/drivers/net/wireless/ath/ath5k/Kconfig +@@ -3,9 +3,7 @@ config ATH5K + tristate "Atheros 5xxx wireless cards support" + depends on (PCI || ATH25) && MAC80211 + select ATH_COMMON +- select MAC80211_LEDS +- select LEDS_CLASS +- select NEW_LEDS ++ select MAC80211_LEDS if LEDS_CLASS=y || LEDS_CLASS=MAC80211 + select ATH5K_AHB if ATH25 + select ATH5K_PCI if !ATH25 + help +diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c +index 6a2a168567630..33e9928af3635 100644 +--- a/drivers/net/wireless/ath/ath5k/led.c ++++ b/drivers/net/wireless/ath/ath5k/led.c +@@ -89,7 +89,8 @@ static const struct pci_device_id ath5k_led_devices[] = { + + void ath5k_led_enable(struct ath5k_hw *ah) + { +- if (test_bit(ATH_STAT_LEDSOFT, ah->status)) { ++ if (IS_ENABLED(CONFIG_MAC80211_LEDS) && ++ test_bit(ATH_STAT_LEDSOFT, ah->status)) { + ath5k_hw_set_gpio_output(ah, ah->led_pin); + ath5k_led_off(ah); + } +@@ -104,7 +105,8 @@ static void ath5k_led_on(struct ath5k_hw *ah) + + void ath5k_led_off(struct ath5k_hw *ah) + { +- if (!test_bit(ATH_STAT_LEDSOFT, ah->status)) ++ if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || ++ !test_bit(ATH_STAT_LEDSOFT, ah->status)) + return; + ath5k_hw_set_gpio(ah, ah->led_pin, !ah->led_on); + } +@@ -146,7 +148,7 @@ ath5k_register_led(struct ath5k_hw *ah, struct ath5k_led *led, + static void + ath5k_unregister_led(struct ath5k_led *led) + { +- if (!led->ah) ++ if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || !led->ah) + return; + led_classdev_unregister(&led->led_dev); + ath5k_led_off(led->ah); +@@ -169,7 +171,7 @@ int ath5k_init_leds(struct ath5k_hw *ah) + char name[ATH5K_LED_MAX_NAME_LEN + 1]; + const struct pci_device_id *match; + +- if (!ah->pdev) ++ if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || !ah->pdev) + return 0; + + #ifdef CONFIG_ATH5K_AHB +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +index 24b658a3098aa..3ae727bc4e944 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +@@ -652,12 +652,13 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm, + u32 *uid) + { + u32 id; +- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); ++ struct iwl_mvm_vif *mvmvif; + enum nl80211_iftype iftype; + + if (!te_data->vif) + return false; + ++ mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); + iftype = te_data->vif->type; + + /* +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +index 6f49950a5f6d1..be3ad42813532 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +@@ -547,6 +547,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { + IWL_DEV_INFO(0x43F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x43F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x43F0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), ++ IWL_DEV_INFO(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650s_name), ++ IWL_DEV_INFO(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650i_name), + IWL_DEV_INFO(0x43F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0x43F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), + IWL_DEV_INFO(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), +diff --git a/drivers/of/base.c b/drivers/of/base.c +index 48e941f99558e..073ea7cd007bb 100644 +--- a/drivers/of/base.c ++++ b/drivers/of/base.c +@@ -36,6 +36,7 @@ LIST_HEAD(aliases_lookup); + struct device_node *of_root; + EXPORT_SYMBOL(of_root); + struct device_node *of_chosen; ++EXPORT_SYMBOL(of_chosen); + struct device_node *of_aliases; + struct device_node *of_stdout; + static const char *of_stdout_options; +diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c +index a53bd8728d0d3..fc1a29acadbbf 100644 +--- a/drivers/pci/controller/pci-hyperv.c ++++ b/drivers/pci/controller/pci-hyperv.c +@@ -3229,9 +3229,17 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs) + return 0; + + if (!keep_devs) { +- /* Delete any children which might still exist. */ ++ struct list_head removed; ++ ++ /* Move all present children to the list on stack */ ++ INIT_LIST_HEAD(&removed); + spin_lock_irqsave(&hbus->device_list_lock, flags); +- list_for_each_entry_safe(hpdev, tmp, &hbus->children, list_entry) { ++ list_for_each_entry_safe(hpdev, tmp, &hbus->children, list_entry) ++ list_move_tail(&hpdev->list_entry, &removed); ++ spin_unlock_irqrestore(&hbus->device_list_lock, flags); ++ ++ /* Remove all children in the list */ ++ list_for_each_entry_safe(hpdev, tmp, &removed, list_entry) { + list_del(&hpdev->list_entry); + if (hpdev->pci_slot) + pci_destroy_slot(hpdev->pci_slot); +@@ -3239,7 +3247,6 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs) + put_pcichild(hpdev); + put_pcichild(hpdev); + } +- spin_unlock_irqrestore(&hbus->device_list_lock, flags); + } + + ret = hv_send_resources_released(hdev); +diff --git a/drivers/ptp/ptp_pch.c b/drivers/ptp/ptp_pch.c +index a17e8cc642c5f..8070f3fd98f01 100644 +--- a/drivers/ptp/ptp_pch.c ++++ b/drivers/ptp/ptp_pch.c +@@ -644,6 +644,7 @@ static const struct pci_device_id pch_ieee1588_pcidev_id[] = { + }, + {0} + }; ++MODULE_DEVICE_TABLE(pci, pch_ieee1588_pcidev_id); + + static SIMPLE_DEV_PM_OPS(pch_pm_ops, pch_suspend, pch_resume); + +diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c +index 4683c183e9d41..5bc91d34df634 100644 +--- a/drivers/scsi/libiscsi.c ++++ b/drivers/scsi/libiscsi.c +@@ -2281,11 +2281,6 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) + return FAILED; + } + +- conn = session->leadconn; +- iscsi_get_conn(conn->cls_conn); +- conn->eh_abort_cnt++; +- age = session->age; +- + spin_lock(&session->back_lock); + task = (struct iscsi_task *)sc->SCp.ptr; + if (!task || !task->sc) { +@@ -2293,8 +2288,16 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) + ISCSI_DBG_EH(session, "sc completed while abort in progress\n"); + + spin_unlock(&session->back_lock); +- goto success; ++ spin_unlock_bh(&session->frwd_lock); ++ mutex_unlock(&session->eh_mutex); ++ return SUCCESS; + } ++ ++ conn = session->leadconn; ++ iscsi_get_conn(conn->cls_conn); ++ conn->eh_abort_cnt++; ++ age = session->age; ++ + ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", sc, task->itt); + __iscsi_get_task(task); + spin_unlock(&session->back_lock); +diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c +index a3f5af088122e..b073b514dcc48 100644 +--- a/drivers/scsi/ufs/ufshcd.c ++++ b/drivers/scsi/ufs/ufshcd.c +@@ -6365,27 +6365,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) + return retval; + } + +-struct ctm_info { +- struct ufs_hba *hba; +- unsigned long pending; +- unsigned int ncpl; +-}; +- +-static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved) +-{ +- struct ctm_info *const ci = priv; +- struct completion *c; +- +- WARN_ON_ONCE(reserved); +- if (test_bit(req->tag, &ci->pending)) +- return true; +- ci->ncpl++; +- c = req->end_io_data; +- if (c) +- complete(c); +- return true; +-} +- + /** + * ufshcd_tmc_handler - handle task management function completion + * @hba: per adapter instance +@@ -6396,18 +6375,24 @@ static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved) + */ + static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba) + { +- unsigned long flags; +- struct request_queue *q = hba->tmf_queue; +- struct ctm_info ci = { +- .hba = hba, +- }; ++ unsigned long flags, pending, issued; ++ irqreturn_t ret = IRQ_NONE; ++ int tag; ++ ++ pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); + + spin_lock_irqsave(hba->host->host_lock, flags); +- ci.pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); +- blk_mq_tagset_busy_iter(q->tag_set, ufshcd_compl_tm, &ci); ++ issued = hba->outstanding_tasks & ~pending; ++ for_each_set_bit(tag, &issued, hba->nutmrs) { ++ struct request *req = hba->tmf_rqs[tag]; ++ struct completion *c = req->end_io_data; ++ ++ complete(c); ++ ret = IRQ_HANDLED; ++ } + spin_unlock_irqrestore(hba->host->host_lock, flags); + +- return ci.ncpl ? IRQ_HANDLED : IRQ_NONE; ++ return ret; + } + + /** +@@ -6530,9 +6515,9 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, + ufshcd_hold(hba, false); + + spin_lock_irqsave(host->host_lock, flags); +- blk_mq_start_request(req); + + task_tag = req->tag; ++ hba->tmf_rqs[req->tag] = req; + treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag); + + memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq)); +@@ -6576,6 +6561,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, + } + + spin_lock_irqsave(hba->host->host_lock, flags); ++ hba->tmf_rqs[req->tag] = NULL; + __clear_bit(task_tag, &hba->outstanding_tasks); + spin_unlock_irqrestore(hba->host->host_lock, flags); + +@@ -9568,6 +9554,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) + err = PTR_ERR(hba->tmf_queue); + goto free_tmf_tag_set; + } ++ hba->tmf_rqs = devm_kcalloc(hba->dev, hba->nutmrs, ++ sizeof(*hba->tmf_rqs), GFP_KERNEL); ++ if (!hba->tmf_rqs) { ++ err = -ENOMEM; ++ goto free_tmf_queue; ++ } + + /* Reset the attached device */ + ufshcd_device_reset(hba); +diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h +index aa95deffb873a..6069e37ec983c 100644 +--- a/drivers/scsi/ufs/ufshcd.h ++++ b/drivers/scsi/ufs/ufshcd.h +@@ -780,6 +780,7 @@ struct ufs_hba { + + struct blk_mq_tag_set tmf_tag_set; + struct request_queue *tmf_queue; ++ struct request **tmf_rqs; + + struct uic_command *active_uic_cmd; + struct mutex uic_cmd_mutex; +diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c +index eba7f76f9d61a..6034cd8992b0e 100644 +--- a/drivers/soc/qcom/mdt_loader.c ++++ b/drivers/soc/qcom/mdt_loader.c +@@ -98,7 +98,7 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len) + if (ehdr->e_phnum < 2) + return ERR_PTR(-EINVAL); + +- if (phdrs[0].p_type == PT_LOAD || phdrs[1].p_type == PT_LOAD) ++ if (phdrs[0].p_type == PT_LOAD) + return ERR_PTR(-EINVAL); + + if ((phdrs[1].p_flags & QCOM_MDT_TYPE_MASK) != QCOM_MDT_TYPE_HASH) +diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c +index b2f049faa3dfa..a6cffd57d3c7b 100644 +--- a/drivers/soc/qcom/socinfo.c ++++ b/drivers/soc/qcom/socinfo.c +@@ -628,7 +628,7 @@ static int qcom_socinfo_probe(struct platform_device *pdev) + /* Feed the soc specific unique data into entropy pool */ + add_device_randomness(info, item_size); + +- platform_set_drvdata(pdev, qs->soc_dev); ++ platform_set_drvdata(pdev, qs); + + return 0; + } +diff --git a/drivers/soc/ti/omap_prm.c b/drivers/soc/ti/omap_prm.c +index ea64e187854eb..f32e1cbbe8c52 100644 +--- a/drivers/soc/ti/omap_prm.c ++++ b/drivers/soc/ti/omap_prm.c +@@ -825,25 +825,28 @@ static int omap_reset_deassert(struct reset_controller_dev *rcdev, + writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl); + spin_unlock_irqrestore(&reset->lock, flags); + +- if (!has_rstst) +- goto exit; ++ /* wait for the reset bit to clear */ ++ ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + ++ reset->prm->data->rstctrl, ++ v, !(v & BIT(id)), 1, ++ OMAP_RESET_MAX_WAIT); ++ if (ret) ++ pr_err("%s: timedout waiting for %s:%lu\n", __func__, ++ reset->prm->data->name, id); + + /* wait for the status to be set */ +- ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + ++ if (has_rstst) { ++ ret = readl_relaxed_poll_timeout_atomic(reset->prm->base + + reset->prm->data->rstst, + v, v & BIT(st_bit), 1, + OMAP_RESET_MAX_WAIT); +- if (ret) +- pr_err("%s: timedout waiting for %s:%lu\n", __func__, +- reset->prm->data->name, id); ++ if (ret) ++ pr_err("%s: timedout waiting for %s:%lu\n", __func__, ++ reset->prm->data->name, id); ++ } + +-exit: +- if (reset->clkdm) { +- /* At least dra7 iva needs a delay before clkdm idle */ +- if (has_rstst) +- udelay(1); ++ if (reset->clkdm) + pdata->clkdm_allow_idle(reset->clkdm); +- } + + return ret; + } +diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c +index 8b7bc10b6e8b4..f1d100671ee6a 100644 +--- a/drivers/usb/chipidea/ci_hdrc_imx.c ++++ b/drivers/usb/chipidea/ci_hdrc_imx.c +@@ -420,11 +420,16 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0); + if (IS_ERR(data->phy)) { + ret = PTR_ERR(data->phy); +- /* Return -EINVAL if no usbphy is available */ +- if (ret == -ENODEV) +- data->phy = NULL; +- else +- goto err_clk; ++ if (ret == -ENODEV) { ++ data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0); ++ if (IS_ERR(data->phy)) { ++ ret = PTR_ERR(data->phy); ++ if (ret == -ENODEV) ++ data->phy = NULL; ++ else ++ goto err_clk; ++ } ++ } + } + + pdata.usb_phy = data->phy; +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 5b90d0979c607..8913c58c306ef 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -340,6 +340,9 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf) + acm->iocount.overrun++; + spin_unlock_irqrestore(&acm->read_lock, flags); + ++ if (newctrl & ACM_CTRL_BRK) ++ tty_flip_buffer_push(&acm->port); ++ + if (difference) + wake_up_all(&acm->wioctl); + +@@ -475,11 +478,16 @@ static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags) + + static void acm_process_read_urb(struct acm *acm, struct urb *urb) + { ++ unsigned long flags; ++ + if (!urb->actual_length) + return; + ++ spin_lock_irqsave(&acm->read_lock, flags); + tty_insert_flip_string(&acm->port, urb->transfer_buffer, + urb->actual_length); ++ spin_unlock_irqrestore(&acm->read_lock, flags); ++ + tty_flip_buffer_push(&acm->port); + } + +diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c +index 35d5908b5478a..fdf79bcf7eb09 100644 +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -824,7 +824,7 @@ static struct usb_class_driver wdm_class = { + }; + + /* --- WWAN framework integration --- */ +-#ifdef CONFIG_WWAN_CORE ++#ifdef CONFIG_WWAN + static int wdm_wwan_port_start(struct wwan_port *port) + { + struct wdm_device *desc = wwan_port_get_drvdata(port); +@@ -963,11 +963,11 @@ static void wdm_wwan_rx(struct wdm_device *desc, int length) + /* inbuf has been copied, it is safe to check for outstanding data */ + schedule_work(&desc->service_outs_intr); + } +-#else /* CONFIG_WWAN_CORE */ ++#else /* CONFIG_WWAN */ + static void wdm_wwan_init(struct wdm_device *desc) {} + static void wdm_wwan_deinit(struct wdm_device *desc) {} + static void wdm_wwan_rx(struct wdm_device *desc, int length) {} +-#endif /* CONFIG_WWAN_CORE */ ++#endif /* CONFIG_WWAN */ + + /* --- error handling --- */ + static void wdm_rxwork(struct work_struct *work) +diff --git a/drivers/usb/common/Kconfig b/drivers/usb/common/Kconfig +index 5e8a04e3dd3c8..b856622431a73 100644 +--- a/drivers/usb/common/Kconfig ++++ b/drivers/usb/common/Kconfig +@@ -6,8 +6,7 @@ config USB_COMMON + + config USB_LED_TRIG + bool "USB LED Triggers" +- depends on LEDS_CLASS && LEDS_TRIGGERS +- select USB_COMMON ++ depends on LEDS_CLASS && USB_COMMON && LEDS_TRIGGERS + help + This option adds LED triggers for USB host and/or gadget activity. + +diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c +index 37c94031af1ed..53cb6b2637a09 100644 +--- a/drivers/usb/gadget/function/f_uac2.c ++++ b/drivers/usb/gadget/function/f_uac2.c +@@ -593,11 +593,17 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, + ssize = uac2_opts->c_ssize; + } + +- if (!is_playback && (uac2_opts->c_sync == USB_ENDPOINT_SYNC_ASYNC)) ++ if (!is_playback && (uac2_opts->c_sync == USB_ENDPOINT_SYNC_ASYNC)) { ++ // Win10 requires max packet size + 1 frame + srate = srate * (1000 + uac2_opts->fb_max) / 1000; +- +- max_size_bw = num_channels(chmask) * ssize * +- DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); ++ // updated srate is always bigger, therefore DIV_ROUND_UP always yields +1 ++ max_size_bw = num_channels(chmask) * ssize * ++ (DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)))); ++ } else { ++ // adding 1 frame provision for Win10 ++ max_size_bw = num_channels(chmask) * ssize * ++ (DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))) + 1); ++ } + ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, + max_size_ep)); + +diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c +index 9858716698dfe..c15eec9cc460a 100644 +--- a/drivers/usb/typec/tcpm/tcpci.c ++++ b/drivers/usb/typec/tcpm/tcpci.c +@@ -696,7 +696,7 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci) + tcpm_pd_receive(tcpci->port, &msg); + } + +- if (status & TCPC_ALERT_EXTENDED_STATUS) { ++ if (tcpci->data->vbus_vsafe0v && (status & TCPC_ALERT_EXTENDED_STATUS)) { + ret = regmap_read(tcpci->regmap, TCPC_EXTENDED_STATUS, &raw); + if (!ret && (raw & TCPC_EXTENDED_STATUS_VSAFE0V)) + tcpm_vbus_change(tcpci->port); +diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c +index 5d05de6665974..686b9245d6d67 100644 +--- a/drivers/usb/typec/tcpm/tcpm.c ++++ b/drivers/usb/typec/tcpm/tcpm.c +@@ -4846,6 +4846,7 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1, + tcpm_set_state(port, SRC_ATTACH_WAIT, 0); + break; + case SRC_ATTACHED: ++ case SRC_STARTUP: + case SRC_SEND_CAPABILITIES: + case SRC_READY: + if (tcpm_port_is_disconnected(port) || +diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c +index 21b3ae25c76d2..ea4cc0a6e40cc 100644 +--- a/drivers/usb/typec/tipd/core.c ++++ b/drivers/usb/typec/tipd/core.c +@@ -625,10 +625,6 @@ static int tps6598x_probe(struct i2c_client *client) + if (ret < 0) + return ret; + +- fwnode = device_get_named_child_node(&client->dev, "connector"); +- if (!fwnode) +- return -ENODEV; +- + /* + * This fwnode has a "compatible" property, but is never populated as a + * struct device. Instead we simply parse it to read the properties. +@@ -636,7 +632,9 @@ static int tps6598x_probe(struct i2c_client *client) + * with existing DT files, we work around this by deleting any + * fwnode_links to/from this fwnode. + */ +- fw_devlink_purge_absent_suppliers(fwnode); ++ fwnode = device_get_named_child_node(&client->dev, "connector"); ++ if (fwnode) ++ fw_devlink_purge_absent_suppliers(fwnode); + + tps->role_sw = fwnode_usb_role_switch_get(fwnode); + if (IS_ERR(tps->role_sw)) { +diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig +index d33c5cd684c0b..f71668367caf1 100644 +--- a/drivers/video/fbdev/Kconfig ++++ b/drivers/video/fbdev/Kconfig +@@ -2191,8 +2191,9 @@ config FB_HYPERV + This framebuffer driver supports Microsoft Hyper-V Synthetic Video. + + config FB_SIMPLE +- bool "Simple framebuffer support" +- depends on (FB = y) && !DRM_SIMPLEDRM ++ tristate "Simple framebuffer support" ++ depends on FB ++ depends on !DRM_SIMPLEDRM + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT +diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c +index c5b99a4861e87..6b4d5a7f3e152 100644 +--- a/drivers/video/fbdev/gbefb.c ++++ b/drivers/video/fbdev/gbefb.c +@@ -1267,7 +1267,7 @@ static struct platform_device *gbefb_device; + static int __init gbefb_init(void) + { + int ret = platform_driver_register(&gbefb_driver); +- if (!ret) { ++ if (IS_ENABLED(CONFIG_SGI_IP32) && !ret) { + gbefb_device = platform_device_alloc("gbefb", 0); + if (gbefb_device) { + ret = platform_device_add(gbefb_device); +diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c +index 43ebfe36ac276..3a50f097ed3ed 100644 +--- a/drivers/xen/balloon.c ++++ b/drivers/xen/balloon.c +@@ -491,12 +491,12 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) + } + + /* +- * Stop waiting if either state is not BP_EAGAIN and ballooning action is +- * needed, or if the credit has changed while state is BP_EAGAIN. ++ * Stop waiting if either state is BP_DONE and ballooning action is ++ * needed, or if the credit has changed while state is not BP_DONE. + */ + static bool balloon_thread_cond(enum bp_state state, long credit) + { +- if (state != BP_EAGAIN) ++ if (state == BP_DONE) + credit = 0; + + return current_credit() != credit || kthread_should_stop(); +@@ -516,10 +516,19 @@ static int balloon_thread(void *unused) + + set_freezable(); + for (;;) { +- if (state == BP_EAGAIN) +- timeout = balloon_stats.schedule_delay * HZ; +- else ++ switch (state) { ++ case BP_DONE: ++ case BP_ECANCELED: + timeout = 3600 * HZ; ++ break; ++ case BP_EAGAIN: ++ timeout = balloon_stats.schedule_delay * HZ; ++ break; ++ case BP_WAIT: ++ timeout = HZ; ++ break; ++ } ++ + credit = current_credit(); + + wait_event_freezable_timeout(balloon_thread_wq, +diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c +index 720a7b7abd46d..fe8df32bb612b 100644 +--- a/drivers/xen/privcmd.c ++++ b/drivers/xen/privcmd.c +@@ -803,11 +803,12 @@ static long privcmd_ioctl_mmap_resource(struct file *file, + unsigned int domid = + (xdata.flags & XENMEM_rsrc_acq_caller_owned) ? + DOMID_SELF : kdata.dom; +- int num; ++ int num, *errs = (int *)pfns; + ++ BUILD_BUG_ON(sizeof(*errs) > sizeof(*pfns)); + num = xen_remap_domain_mfn_array(vma, + kdata.addr & PAGE_MASK, +- pfns, kdata.num, (int *)pfns, ++ pfns, kdata.num, errs, + vma->vm_page_prot, + domid, + vma->vm_private_data); +@@ -817,7 +818,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file, + unsigned int i; + + for (i = 0; i < num; i++) { +- rc = pfns[i]; ++ rc = errs[i]; + if (rc < 0) + break; + } +diff --git a/fs/afs/write.c b/fs/afs/write.c +index 2dfe3b3a53d69..f24370f5c7744 100644 +--- a/fs/afs/write.c ++++ b/fs/afs/write.c +@@ -974,8 +974,7 @@ int afs_launder_page(struct page *page) + iov_iter_bvec(&iter, WRITE, bv, 1, bv[0].bv_len); + + trace_afs_page_dirty(vnode, tracepoint_string("launder"), page); +- ret = afs_store_data(vnode, &iter, (loff_t)page->index * PAGE_SIZE, +- true); ++ ret = afs_store_data(vnode, &iter, page_offset(page) + f, true); + } + + trace_afs_page_dirty(vnode, tracepoint_string("laundered"), page); +diff --git a/fs/netfs/read_helper.c b/fs/netfs/read_helper.c +index 0b6cd3b8734c6..994ec22d40402 100644 +--- a/fs/netfs/read_helper.c ++++ b/fs/netfs/read_helper.c +@@ -150,7 +150,7 @@ static void netfs_clear_unread(struct netfs_read_subrequest *subreq) + { + struct iov_iter iter; + +- iov_iter_xarray(&iter, WRITE, &subreq->rreq->mapping->i_pages, ++ iov_iter_xarray(&iter, READ, &subreq->rreq->mapping->i_pages, + subreq->start + subreq->transferred, + subreq->len - subreq->transferred); + iov_iter_zero(iov_iter_count(&iter), &iter); +diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c +index 7abeccb975b22..cf030ebe28275 100644 +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -3544,15 +3544,18 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, + goto fail; + cd->rd_maxcount -= entry_bytes; + /* +- * RFC 3530 14.2.24 describes rd_dircount as only a "hint", so +- * let's always let through the first entry, at least: ++ * RFC 3530 14.2.24 describes rd_dircount as only a "hint", and ++ * notes that it could be zero. If it is zero, then the server ++ * should enforce only the rd_maxcount value. + */ +- if (!cd->rd_dircount) +- goto fail; +- name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8; +- if (name_and_cookie > cd->rd_dircount && cd->cookie_offset) +- goto fail; +- cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie); ++ if (cd->rd_dircount) { ++ name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8; ++ if (name_and_cookie > cd->rd_dircount && cd->cookie_offset) ++ goto fail; ++ cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie); ++ if (!cd->rd_dircount) ++ cd->rd_maxcount = 0; ++ } + + cd->cookie_offset = cookie_offset; + skip_entry: +diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c +index c2c3d9077dc58..09ae1a0873d05 100644 +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -1545,7 +1545,7 @@ static int __init init_nfsd(void) + goto out_free_all; + return 0; + out_free_all: +- unregister_pernet_subsys(&nfsd_net_ops); ++ unregister_filesystem(&nfsd_fs_type); + out_free_exports: + remove_proc_entry("fs/nfs/exports", NULL); + remove_proc_entry("fs/nfs", NULL); +diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c +index 7c1850adec288..a4ad25f1f797f 100644 +--- a/fs/overlayfs/dir.c ++++ b/fs/overlayfs/dir.c +@@ -1215,9 +1215,13 @@ static int ovl_rename(struct user_namespace *mnt_userns, struct inode *olddir, + goto out_dput; + } + } else { +- if (!d_is_negative(newdentry) && +- (!new_opaque || !ovl_is_whiteout(newdentry))) +- goto out_dput; ++ if (!d_is_negative(newdentry)) { ++ if (!new_opaque || !ovl_is_whiteout(newdentry)) ++ goto out_dput; ++ } else { ++ if (flags & RENAME_EXCHANGE) ++ goto out_dput; ++ } + } + + if (olddentry == trap) +diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c +index d081faa55e830..c88ac571593dc 100644 +--- a/fs/overlayfs/file.c ++++ b/fs/overlayfs/file.c +@@ -296,6 +296,12 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter) + if (ret) + return ret; + ++ ret = -EINVAL; ++ if (iocb->ki_flags & IOCB_DIRECT && ++ (!real.file->f_mapping->a_ops || ++ !real.file->f_mapping->a_ops->direct_IO)) ++ goto out_fdput; ++ + old_cred = ovl_override_creds(file_inode(file)->i_sb); + if (is_sync_kiocb(iocb)) { + ret = vfs_iter_read(real.file, iter, &iocb->ki_pos, +@@ -320,7 +326,7 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter) + out: + revert_creds(old_cred); + ovl_file_accessed(file); +- ++out_fdput: + fdput(real); + + return ret; +@@ -349,6 +355,12 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter) + if (ret) + goto out_unlock; + ++ ret = -EINVAL; ++ if (iocb->ki_flags & IOCB_DIRECT && ++ (!real.file->f_mapping->a_ops || ++ !real.file->f_mapping->a_ops->direct_IO)) ++ goto out_fdput; ++ + if (!ovl_should_sync(OVL_FS(inode->i_sb))) + ifl &= ~(IOCB_DSYNC | IOCB_SYNC); + +@@ -384,6 +396,7 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter) + } + out: + revert_creds(old_cred); ++out_fdput: + fdput(real); + + out_unlock: +diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h +index 0fd8a4159662d..ceadf8ba25a44 100644 +--- a/include/net/netfilter/ipv6/nf_defrag_ipv6.h ++++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h +@@ -17,7 +17,6 @@ struct inet_frags_ctl; + struct nft_ct_frag6_pernet { + struct ctl_table_header *nf_frag_frags_hdr; + struct fqdir *fqdir; +- unsigned int users; + }; + + #endif /* _NF_DEFRAG_IPV6_H */ +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index 148f5d8ee5ab3..a16171c5fd9eb 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -1202,7 +1202,7 @@ struct nft_object *nft_obj_lookup(const struct net *net, + + void nft_obj_notify(struct net *net, const struct nft_table *table, + struct nft_object *obj, u32 portid, u32 seq, +- int event, int family, int report, gfp_t gfp); ++ int event, u16 flags, int family, int report, gfp_t gfp); + + /** + * struct nft_object_type - stateful object type +diff --git a/include/net/netns/netfilter.h b/include/net/netns/netfilter.h +index 15e2b13fb0c0f..71343b969cd31 100644 +--- a/include/net/netns/netfilter.h ++++ b/include/net/netns/netfilter.h +@@ -28,5 +28,11 @@ struct netns_nf { + #if IS_ENABLED(CONFIG_DECNET) + struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS]; + #endif ++#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) ++ unsigned int defrag_ipv4_users; ++#endif ++#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) ++ unsigned int defrag_ipv6_users; ++#endif + }; + #endif +diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h +index 25fd525aaf928..4869ebbd438d9 100644 +--- a/include/soc/mscc/ocelot_vcap.h ++++ b/include/soc/mscc/ocelot_vcap.h +@@ -694,7 +694,7 @@ int ocelot_vcap_filter_add(struct ocelot *ocelot, + int ocelot_vcap_filter_del(struct ocelot *ocelot, + struct ocelot_vcap_filter *rule); + struct ocelot_vcap_filter * +-ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int id, +- bool tc_offload); ++ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, ++ unsigned long cookie, bool tc_offload); + + #endif /* _OCELOT_VCAP_H_ */ +diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c +index 6fbc2abe9c916..2553caf4f74a3 100644 +--- a/kernel/bpf/stackmap.c ++++ b/kernel/bpf/stackmap.c +@@ -63,7 +63,8 @@ static inline int stack_map_data_size(struct bpf_map *map) + + static int prealloc_elems_and_freelist(struct bpf_stack_map *smap) + { +- u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size; ++ u64 elem_size = sizeof(struct stack_map_bucket) + ++ (u64)smap->map.value_size; + int err; + + smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries, +diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c +index 8642e56059fb2..2abfbd4b8a15e 100644 +--- a/net/bridge/br_netlink.c ++++ b/net/bridge/br_netlink.c +@@ -1657,7 +1657,8 @@ static size_t br_get_linkxstats_size(const struct net_device *dev, int attr) + } + + return numvls * nla_total_size(sizeof(struct bridge_vlan_xstats)) + +- nla_total_size(sizeof(struct br_mcast_stats)) + ++ nla_total_size_64bit(sizeof(struct br_mcast_stats)) + ++ (p ? nla_total_size_64bit(sizeof(p->stp_xstats)) : 0) + + nla_total_size(0); + } + +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 662eb1c37f47b..10e2a0e4804b4 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -5265,7 +5265,7 @@ nla_put_failure: + static size_t if_nlmsg_stats_size(const struct net_device *dev, + u32 filter_mask) + { +- size_t size = 0; ++ size_t size = NLMSG_ALIGN(sizeof(struct if_stats_msg)); + + if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, 0)) + size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64)); +diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c +index a822355afc903..26c6768b6b0c5 100644 +--- a/net/dsa/tag_dsa.c ++++ b/net/dsa/tag_dsa.c +@@ -176,7 +176,7 @@ static struct sk_buff *dsa_rcv_ll(struct sk_buff *skb, struct net_device *dev, + case DSA_CMD_FORWARD: + skb->offload_fwd_mark = 1; + +- trunk = !!(dsa_header[1] & 7); ++ trunk = !!(dsa_header[1] & 4); + break; + + case DSA_CMD_TO_CPU: +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 80aeaf9e6e16e..bfb522e513461 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -242,8 +242,10 @@ static inline int compute_score(struct sock *sk, struct net *net, + + if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif)) + return -1; ++ score = sk->sk_bound_dev_if ? 2 : 1; + +- score = sk->sk_family == PF_INET ? 2 : 1; ++ if (sk->sk_family == PF_INET) ++ score++; + if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) + score++; + } +diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c +index 613432a36f0a7..e61ea428ea187 100644 +--- a/net/ipv4/netfilter/nf_defrag_ipv4.c ++++ b/net/ipv4/netfilter/nf_defrag_ipv4.c +@@ -20,13 +20,8 @@ + #endif + #include <net/netfilter/nf_conntrack_zones.h> + +-static unsigned int defrag4_pernet_id __read_mostly; + static DEFINE_MUTEX(defrag4_mutex); + +-struct defrag4_pernet { +- unsigned int users; +-}; +- + static int nf_ct_ipv4_gather_frags(struct net *net, struct sk_buff *skb, + u_int32_t user) + { +@@ -111,19 +106,15 @@ static const struct nf_hook_ops ipv4_defrag_ops[] = { + + static void __net_exit defrag4_net_exit(struct net *net) + { +- struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id); +- +- if (nf_defrag->users) { ++ if (net->nf.defrag_ipv4_users) { + nf_unregister_net_hooks(net, ipv4_defrag_ops, + ARRAY_SIZE(ipv4_defrag_ops)); +- nf_defrag->users = 0; ++ net->nf.defrag_ipv4_users = 0; + } + } + + static struct pernet_operations defrag4_net_ops = { + .exit = defrag4_net_exit, +- .id = &defrag4_pernet_id, +- .size = sizeof(struct defrag4_pernet), + }; + + static int __init nf_defrag_init(void) +@@ -138,24 +129,23 @@ static void __exit nf_defrag_fini(void) + + int nf_defrag_ipv4_enable(struct net *net) + { +- struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id); + int err = 0; + + mutex_lock(&defrag4_mutex); +- if (nf_defrag->users == UINT_MAX) { ++ if (net->nf.defrag_ipv4_users == UINT_MAX) { + err = -EOVERFLOW; + goto out_unlock; + } + +- if (nf_defrag->users) { +- nf_defrag->users++; ++ if (net->nf.defrag_ipv4_users) { ++ net->nf.defrag_ipv4_users++; + goto out_unlock; + } + + err = nf_register_net_hooks(net, ipv4_defrag_ops, + ARRAY_SIZE(ipv4_defrag_ops)); + if (err == 0) +- nf_defrag->users = 1; ++ net->nf.defrag_ipv4_users = 1; + + out_unlock: + mutex_unlock(&defrag4_mutex); +@@ -165,12 +155,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable); + + void nf_defrag_ipv4_disable(struct net *net) + { +- struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id); +- + mutex_lock(&defrag4_mutex); +- if (nf_defrag->users) { +- nf_defrag->users--; +- if (nf_defrag->users == 0) ++ if (net->nf.defrag_ipv4_users) { ++ net->nf.defrag_ipv4_users--; ++ if (net->nf.defrag_ipv4_users == 0) + nf_unregister_net_hooks(net, ipv4_defrag_ops, + ARRAY_SIZE(ipv4_defrag_ops)); + } +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 915ea635b2d5a..cbc7907f79b84 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -390,7 +390,8 @@ static int compute_score(struct sock *sk, struct net *net, + dif, sdif); + if (!dev_match) + return -1; +- score += 4; ++ if (sk->sk_bound_dev_if) ++ score += 4; + + if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) + score++; +diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c +index 55c290d556059..67c9114835c84 100644 +--- a/net/ipv6/inet6_hashtables.c ++++ b/net/ipv6/inet6_hashtables.c +@@ -106,7 +106,7 @@ static inline int compute_score(struct sock *sk, struct net *net, + if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif)) + return -1; + +- score = 1; ++ score = sk->sk_bound_dev_if ? 2 : 1; + if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) + score++; + } +diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c +index a0108415275fe..5c47be29b9ee9 100644 +--- a/net/ipv6/netfilter/nf_conntrack_reasm.c ++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c +@@ -33,7 +33,7 @@ + + static const char nf_frags_cache_name[] = "nf-frags"; + +-unsigned int nf_frag_pernet_id __read_mostly; ++static unsigned int nf_frag_pernet_id __read_mostly; + static struct inet_frags nf_frags; + + static struct nft_ct_frag6_pernet *nf_frag_pernet(struct net *net) +diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c +index e8a59d8bf2adf..cb4eb1d2c620b 100644 +--- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c ++++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c +@@ -25,8 +25,6 @@ + #include <net/netfilter/nf_conntrack_zones.h> + #include <net/netfilter/ipv6/nf_defrag_ipv6.h> + +-extern unsigned int nf_frag_pernet_id; +- + static DEFINE_MUTEX(defrag6_mutex); + + static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, +@@ -91,12 +89,10 @@ static const struct nf_hook_ops ipv6_defrag_ops[] = { + + static void __net_exit defrag6_net_exit(struct net *net) + { +- struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id); +- +- if (nf_frag->users) { ++ if (net->nf.defrag_ipv6_users) { + nf_unregister_net_hooks(net, ipv6_defrag_ops, + ARRAY_SIZE(ipv6_defrag_ops)); +- nf_frag->users = 0; ++ net->nf.defrag_ipv6_users = 0; + } + } + +@@ -134,24 +130,23 @@ static void __exit nf_defrag_fini(void) + + int nf_defrag_ipv6_enable(struct net *net) + { +- struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id); + int err = 0; + + mutex_lock(&defrag6_mutex); +- if (nf_frag->users == UINT_MAX) { ++ if (net->nf.defrag_ipv6_users == UINT_MAX) { + err = -EOVERFLOW; + goto out_unlock; + } + +- if (nf_frag->users) { +- nf_frag->users++; ++ if (net->nf.defrag_ipv6_users) { ++ net->nf.defrag_ipv6_users++; + goto out_unlock; + } + + err = nf_register_net_hooks(net, ipv6_defrag_ops, + ARRAY_SIZE(ipv6_defrag_ops)); + if (err == 0) +- nf_frag->users = 1; ++ net->nf.defrag_ipv6_users = 1; + + out_unlock: + mutex_unlock(&defrag6_mutex); +@@ -161,12 +156,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable); + + void nf_defrag_ipv6_disable(struct net *net) + { +- struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id); +- + mutex_lock(&defrag6_mutex); +- if (nf_frag->users) { +- nf_frag->users--; +- if (nf_frag->users == 0) ++ if (net->nf.defrag_ipv6_users) { ++ net->nf.defrag_ipv6_users--; ++ if (net->nf.defrag_ipv6_users == 0) + nf_unregister_net_hooks(net, ipv6_defrag_ops, + ARRAY_SIZE(ipv6_defrag_ops)); + } +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 80ae024d13c8c..ba77955d75fbd 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -133,7 +133,8 @@ static int compute_score(struct sock *sk, struct net *net, + dev_match = udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif); + if (!dev_match) + return -1; +- score++; ++ if (sk->sk_bound_dev_if) ++ score++; + + if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) + score++; +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index b9546defdc280..c0851fec11d46 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -780,6 +780,7 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event) + { + struct nftables_pernet *nft_net; + struct sk_buff *skb; ++ u16 flags = 0; + int err; + + if (!ctx->report && +@@ -790,8 +791,11 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event) + if (skb == NULL) + goto err; + ++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) ++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); ++ + err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq, +- event, 0, ctx->family, ctx->table); ++ event, flags, ctx->family, ctx->table); + if (err < 0) { + kfree_skb(skb); + goto err; +@@ -1563,6 +1567,7 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event) + { + struct nftables_pernet *nft_net; + struct sk_buff *skb; ++ u16 flags = 0; + int err; + + if (!ctx->report && +@@ -1573,8 +1578,11 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event) + if (skb == NULL) + goto err; + ++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) ++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); ++ + err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq, +- event, 0, ctx->family, ctx->table, ++ event, flags, ctx->family, ctx->table, + ctx->chain); + if (err < 0) { + kfree_skb(skb); +@@ -2866,8 +2874,7 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, + u32 flags, int family, + const struct nft_table *table, + const struct nft_chain *chain, +- const struct nft_rule *rule, +- const struct nft_rule *prule) ++ const struct nft_rule *rule, u64 handle) + { + struct nlmsghdr *nlh; + const struct nft_expr *expr, *next; +@@ -2887,9 +2894,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, + NFTA_RULE_PAD)) + goto nla_put_failure; + +- if (event != NFT_MSG_DELRULE && prule) { +- if (nla_put_be64(skb, NFTA_RULE_POSITION, +- cpu_to_be64(prule->handle), ++ if (event != NFT_MSG_DELRULE && handle) { ++ if (nla_put_be64(skb, NFTA_RULE_POSITION, cpu_to_be64(handle), + NFTA_RULE_PAD)) + goto nla_put_failure; + } +@@ -2925,7 +2931,10 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx, + const struct nft_rule *rule, int event) + { + struct nftables_pernet *nft_net = nft_pernet(ctx->net); ++ const struct nft_rule *prule; + struct sk_buff *skb; ++ u64 handle = 0; ++ u16 flags = 0; + int err; + + if (!ctx->report && +@@ -2936,9 +2945,20 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx, + if (skb == NULL) + goto err; + ++ if (event == NFT_MSG_NEWRULE && ++ !list_is_first(&rule->list, &ctx->chain->rules) && ++ !list_is_last(&rule->list, &ctx->chain->rules)) { ++ prule = list_prev_entry(rule, list); ++ handle = prule->handle; ++ } ++ if (ctx->flags & (NLM_F_APPEND | NLM_F_REPLACE)) ++ flags |= NLM_F_APPEND; ++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) ++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); ++ + err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq, +- event, 0, ctx->family, ctx->table, +- ctx->chain, rule, NULL); ++ event, flags, ctx->family, ctx->table, ++ ctx->chain, rule, handle); + if (err < 0) { + kfree_skb(skb); + goto err; +@@ -2964,6 +2984,7 @@ static int __nf_tables_dump_rules(struct sk_buff *skb, + struct net *net = sock_net(skb->sk); + const struct nft_rule *rule, *prule; + unsigned int s_idx = cb->args[0]; ++ u64 handle; + + prule = NULL; + list_for_each_entry_rcu(rule, &chain->rules, list) { +@@ -2975,12 +2996,17 @@ static int __nf_tables_dump_rules(struct sk_buff *skb, + memset(&cb->args[1], 0, + sizeof(cb->args) - sizeof(cb->args[0])); + } ++ if (prule) ++ handle = prule->handle; ++ else ++ handle = 0; ++ + if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, + NFT_MSG_NEWRULE, + NLM_F_MULTI | NLM_F_APPEND, + table->family, +- table, chain, rule, prule) < 0) ++ table, chain, rule, handle) < 0) + return 1; + + nl_dump_check_consistent(cb, nlmsg_hdr(skb)); +@@ -3143,7 +3169,7 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info, + + err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid, + info->nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0, +- family, table, chain, rule, NULL); ++ family, table, chain, rule, 0); + if (err < 0) + goto err_fill_rule_info; + +@@ -3403,17 +3429,15 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info, + } + + if (info->nlh->nlmsg_flags & NLM_F_REPLACE) { ++ err = nft_delrule(&ctx, old_rule); ++ if (err < 0) ++ goto err_destroy_flow_rule; ++ + trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule); + if (trans == NULL) { + err = -ENOMEM; + goto err_destroy_flow_rule; + } +- err = nft_delrule(&ctx, old_rule); +- if (err < 0) { +- nft_trans_destroy(trans); +- goto err_destroy_flow_rule; +- } +- + list_add_tail_rcu(&rule->list, &old_rule->list); + } else { + trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule); +@@ -3943,8 +3967,9 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx, + gfp_t gfp_flags) + { + struct nftables_pernet *nft_net = nft_pernet(ctx->net); +- struct sk_buff *skb; + u32 portid = ctx->portid; ++ struct sk_buff *skb; ++ u16 flags = 0; + int err; + + if (!ctx->report && +@@ -3955,7 +3980,10 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx, + if (skb == NULL) + goto err; + +- err = nf_tables_fill_set(skb, ctx, set, event, 0); ++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) ++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); ++ ++ err = nf_tables_fill_set(skb, ctx, set, event, flags); + if (err < 0) { + kfree_skb(skb); + goto err; +@@ -5231,12 +5259,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb, + static void nf_tables_setelem_notify(const struct nft_ctx *ctx, + const struct nft_set *set, + const struct nft_set_elem *elem, +- int event, u16 flags) ++ int event) + { + struct nftables_pernet *nft_net; + struct net *net = ctx->net; + u32 portid = ctx->portid; + struct sk_buff *skb; ++ u16 flags = 0; + int err; + + if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES)) +@@ -5246,6 +5275,9 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx, + if (skb == NULL) + goto err; + ++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) ++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); ++ + err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags, + set, elem); + if (err < 0) { +@@ -6921,7 +6953,7 @@ static int nf_tables_delobj(struct sk_buff *skb, const struct nfnl_info *info, + + void nft_obj_notify(struct net *net, const struct nft_table *table, + struct nft_object *obj, u32 portid, u32 seq, int event, +- int family, int report, gfp_t gfp) ++ u16 flags, int family, int report, gfp_t gfp) + { + struct nftables_pernet *nft_net = nft_pernet(net); + struct sk_buff *skb; +@@ -6946,8 +6978,9 @@ void nft_obj_notify(struct net *net, const struct nft_table *table, + if (skb == NULL) + goto err; + +- err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family, +- table, obj, false); ++ err = nf_tables_fill_obj_info(skb, net, portid, seq, event, ++ flags & (NLM_F_CREATE | NLM_F_EXCL), ++ family, table, obj, false); + if (err < 0) { + kfree_skb(skb); + goto err; +@@ -6964,7 +6997,7 @@ static void nf_tables_obj_notify(const struct nft_ctx *ctx, + struct nft_object *obj, int event) + { + nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event, +- ctx->family, ctx->report, GFP_KERNEL); ++ ctx->flags, ctx->family, ctx->report, GFP_KERNEL); + } + + /* +@@ -7745,6 +7778,7 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx, + { + struct nftables_pernet *nft_net = nft_pernet(ctx->net); + struct sk_buff *skb; ++ u16 flags = 0; + int err; + + if (!ctx->report && +@@ -7755,8 +7789,11 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx, + if (skb == NULL) + goto err; + ++ if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) ++ flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); ++ + err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid, +- ctx->seq, event, 0, ++ ctx->seq, event, flags, + ctx->family, flowtable, hook_list); + if (err < 0) { + kfree_skb(skb); +@@ -8634,7 +8671,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) + nft_setelem_activate(net, te->set, &te->elem); + nf_tables_setelem_notify(&trans->ctx, te->set, + &te->elem, +- NFT_MSG_NEWSETELEM, 0); ++ NFT_MSG_NEWSETELEM); + nft_trans_destroy(trans); + break; + case NFT_MSG_DELSETELEM: +@@ -8642,7 +8679,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) + + nf_tables_setelem_notify(&trans->ctx, te->set, + &te->elem, +- NFT_MSG_DELSETELEM, 0); ++ NFT_MSG_DELSETELEM); + nft_setelem_remove(net, te->set, &te->elem); + if (!nft_setelem_is_catchall(te->set, &te->elem)) { + atomic_dec(&te->set->nelems); +diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c +index 0363f533a42b8..c4d1389f7185a 100644 +--- a/net/netfilter/nft_quota.c ++++ b/net/netfilter/nft_quota.c +@@ -60,7 +60,7 @@ static void nft_quota_obj_eval(struct nft_object *obj, + if (overquota && + !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, nft_pf(pkt), 0, GFP_ATOMIC); ++ NFT_MSG_NEWOBJ, 0, nft_pf(pkt), 0, GFP_ATOMIC); + } + + static int nft_quota_do_init(const struct nlattr * const tb[], +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 24b7cf447bc55..ada47e59647a0 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -594,7 +594,10 @@ static int netlink_insert(struct sock *sk, u32 portid) + + /* We need to ensure that the socket is hashed and visible. */ + smp_wmb(); +- nlk_sk(sk)->bound = portid; ++ /* Paired with lockless reads from netlink_bind(), ++ * netlink_connect() and netlink_sendmsg(). ++ */ ++ WRITE_ONCE(nlk_sk(sk)->bound, portid); + + err: + release_sock(sk); +@@ -1012,7 +1015,8 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, + if (nlk->ngroups < BITS_PER_LONG) + groups &= (1UL << nlk->ngroups) - 1; + +- bound = nlk->bound; ++ /* Paired with WRITE_ONCE() in netlink_insert() */ ++ bound = READ_ONCE(nlk->bound); + if (bound) { + /* Ensure nlk->portid is up-to-date. */ + smp_rmb(); +@@ -1098,8 +1102,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr, + + /* No need for barriers here as we return to user-space without + * using any of the bound attributes. ++ * Paired with WRITE_ONCE() in netlink_insert(). + */ +- if (!nlk->bound) ++ if (!READ_ONCE(nlk->bound)) + err = netlink_autobind(sock); + + if (err == 0) { +@@ -1888,7 +1893,8 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + dst_group = nlk->dst_group; + } + +- if (!nlk->bound) { ++ /* Paired with WRITE_ONCE() in netlink_insert() */ ++ if (!READ_ONCE(nlk->bound)) { + err = netlink_autobind(sock); + if (err) + goto out; +diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c +index a579a4131d22d..e1040421b7979 100644 +--- a/net/sched/sch_fifo.c ++++ b/net/sched/sch_fifo.c +@@ -233,6 +233,9 @@ int fifo_set_limit(struct Qdisc *q, unsigned int limit) + if (strncmp(q->ops->id + 1, "fifo", 4) != 0) + return 0; + ++ if (!q->ops->change) ++ return 0; ++ + nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)), GFP_KERNEL); + if (nla) { + nla->nla_type = RTM_NEWQDISC; +diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c +index 1ab2fc933a214..b9fd18d986464 100644 +--- a/net/sched/sch_taprio.c ++++ b/net/sched/sch_taprio.c +@@ -1641,6 +1641,10 @@ static void taprio_destroy(struct Qdisc *sch) + list_del(&q->taprio_list); + spin_unlock(&taprio_list_lock); + ++ /* Note that taprio_reset() might not be called if an error ++ * happens in qdisc_create(), after taprio_init() has been called. ++ */ ++ hrtimer_cancel(&q->advance_timer); + + taprio_disable_offload(dev, q, NULL); + +diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c +index 3d685fe328fad..9fd35a60de6ce 100644 +--- a/net/sunrpc/auth_gss/svcauth_gss.c ++++ b/net/sunrpc/auth_gss/svcauth_gss.c +@@ -643,7 +643,7 @@ static bool gss_check_seq_num(const struct svc_rqst *rqstp, struct rsc *rsci, + } + __set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win); + goto ok; +- } else if (seq_num <= sd->sd_max - GSS_SEQ_WIN) { ++ } else if (seq_num + GSS_SEQ_WIN <= sd->sd_max) { + goto toolow; + } + if (__test_and_set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win)) +diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c +index d27e017ebfbea..f1bc09e606cd1 100644 +--- a/tools/lib/bpf/libbpf.c ++++ b/tools/lib/bpf/libbpf.c +@@ -8115,7 +8115,8 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr) + + if (obj->gen_loader) { + /* reset FDs */ +- btf__set_fd(obj->btf, -1); ++ if (obj->btf) ++ btf__set_fd(obj->btf, -1); + for (i = 0; i < obj->nr_maps; i++) + obj->maps[i].fd = -1; + if (!err) +diff --git a/tools/lib/bpf/strset.c b/tools/lib/bpf/strset.c +index 1fb8b49de1d62..ea655318153f2 100644 +--- a/tools/lib/bpf/strset.c ++++ b/tools/lib/bpf/strset.c +@@ -88,6 +88,7 @@ void strset__free(struct strset *set) + + hashmap__free(set->strs_hash); + free(set->strs_data); ++ free(set); + } + + size_t strset__data_size(const struct strset *set) +diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c +index bc821056aba90..0893436cc09f8 100644 +--- a/tools/objtool/arch/x86/decode.c ++++ b/tools/objtool/arch/x86/decode.c +@@ -684,7 +684,7 @@ static int elf_add_alternative(struct elf *elf, + sec = find_section_by_name(elf, ".altinstructions"); + if (!sec) { + sec = elf_create_section(elf, ".altinstructions", +- SHF_ALLOC, size, 0); ++ SHF_ALLOC, 0, 0); + + if (!sec) { + WARN_ELF("elf_create_section"); +diff --git a/tools/objtool/special.c b/tools/objtool/special.c +index f1428e32a5052..83d5f969bcb00 100644 +--- a/tools/objtool/special.c ++++ b/tools/objtool/special.c +@@ -58,22 +58,11 @@ void __weak arch_handle_alternative(unsigned short feature, struct special_alt * + { + } + +-static bool reloc2sec_off(struct reloc *reloc, struct section **sec, unsigned long *off) ++static void reloc_to_sec_off(struct reloc *reloc, struct section **sec, ++ unsigned long *off) + { +- switch (reloc->sym->type) { +- case STT_FUNC: +- *sec = reloc->sym->sec; +- *off = reloc->sym->offset + reloc->addend; +- return true; +- +- case STT_SECTION: +- *sec = reloc->sym->sec; +- *off = reloc->addend; +- return true; +- +- default: +- return false; +- } ++ *sec = reloc->sym->sec; ++ *off = reloc->sym->offset + reloc->addend; + } + + static int get_alt_entry(struct elf *elf, struct special_entry *entry, +@@ -109,13 +98,8 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry, + WARN_FUNC("can't find orig reloc", sec, offset + entry->orig); + return -1; + } +- if (!reloc2sec_off(orig_reloc, &alt->orig_sec, &alt->orig_off)) { +- WARN_FUNC("don't know how to handle reloc symbol type %d: %s", +- sec, offset + entry->orig, +- orig_reloc->sym->type, +- orig_reloc->sym->name); +- return -1; +- } ++ ++ reloc_to_sec_off(orig_reloc, &alt->orig_sec, &alt->orig_off); + + if (!entry->group || alt->new_len) { + new_reloc = find_reloc_by_dest(elf, sec, offset + entry->new); +@@ -133,13 +117,7 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry, + if (arch_is_retpoline(new_reloc->sym)) + return 1; + +- if (!reloc2sec_off(new_reloc, &alt->new_sec, &alt->new_off)) { +- WARN_FUNC("don't know how to handle reloc symbol type %d: %s", +- sec, offset + entry->new, +- new_reloc->sym->type, +- new_reloc->sym->name); +- return -1; +- } ++ reloc_to_sec_off(new_reloc, &alt->new_sec, &alt->new_off); + + /* _ASM_EXTABLE_EX hack */ + if (alt->new_off >= 0x7ffffff0) +diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c +index 9604446f8360b..8b536117e154f 100644 +--- a/tools/perf/pmu-events/jevents.c ++++ b/tools/perf/pmu-events/jevents.c +@@ -1284,6 +1284,7 @@ int main(int argc, char *argv[]) + } + + free_arch_std_events(); ++ free_sys_event_tables(); + free(mapfile); + return 0; + +@@ -1305,6 +1306,7 @@ err_close_eventsfp: + create_empty_mapping(output_file); + err_out: + free_arch_std_events(); ++ free_sys_event_tables(); + free(mapfile); + return ret; + } |