diff options
author | 2024-06-27 08:31:46 -0400 | |
---|---|---|
committer | 2024-06-27 08:31:46 -0400 | |
commit | 3122325dd9d49ca1ade622f019c91cbcd64ccf8f (patch) | |
tree | 7ffd87a40e0d55570296cf5b0b347db20fe02a9c | |
parent | Linux patch 6.9.6 (diff) | |
download | linux-patches-3122325dd9d49ca1ade622f019c91cbcd64ccf8f.tar.gz linux-patches-3122325dd9d49ca1ade622f019c91cbcd64ccf8f.tar.bz2 linux-patches-3122325dd9d49ca1ade622f019c91cbcd64ccf8f.zip |
Linux patch 6.9.76.9-8
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 6 | ||||
-rw-r--r-- | 1006_linux-6.9.7.patch | 11106 |
2 files changed, 11111 insertions, 1 deletions
diff --git a/0000_README b/0000_README index 9c96fb59..5ba3f04f 100644 --- a/0000_README +++ b/0000_README @@ -67,8 +67,12 @@ Patch: 1005_linux-6.9.6.patch From: https://www.kernel.org Desc: Linux 6.9.6 +Patch: 1006_linux-6.9.7.patch +From: https://www.kernel.org +Desc: Linux 6.9.7 + Patch: 1510_fs-enable-link-security-restrictions-by-default.patch -From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/ +From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch Desc: Enable link security restrictions by default. Patch: 1700_sparc-address-warray-bound-warnings.patch diff --git a/1006_linux-6.9.7.patch b/1006_linux-6.9.7.patch new file mode 100644 index 00000000..a905db13 --- /dev/null +++ b/1006_linux-6.9.7.patch @@ -0,0 +1,11106 @@ +diff --git a/Documentation/devicetree/bindings/dma/fsl,edma.yaml b/Documentation/devicetree/bindings/dma/fsl,edma.yaml +index aa51d278cb67b..83e77ee4894ef 100644 +--- a/Documentation/devicetree/bindings/dma/fsl,edma.yaml ++++ b/Documentation/devicetree/bindings/dma/fsl,edma.yaml +@@ -48,8 +48,8 @@ properties: + - 3 + + dma-channels: +- minItems: 1 +- maxItems: 64 ++ minimum: 1 ++ maximum: 64 + + clocks: + minItems: 1 +diff --git a/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml b/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml +index b1c13bab24722..b2d19cfb87add 100644 +--- a/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml ++++ b/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml +@@ -77,7 +77,7 @@ required: + - clocks + + allOf: +- - $ref: i2c-controller.yaml ++ - $ref: /schemas/i2c/i2c-controller.yaml# + - if: + properties: + compatible: +diff --git a/Documentation/devicetree/bindings/i2c/google,cros-ec-i2c-tunnel.yaml b/Documentation/devicetree/bindings/i2c/google,cros-ec-i2c-tunnel.yaml +index ab151c9db2191..580003cdfff59 100644 +--- a/Documentation/devicetree/bindings/i2c/google,cros-ec-i2c-tunnel.yaml ++++ b/Documentation/devicetree/bindings/i2c/google,cros-ec-i2c-tunnel.yaml +@@ -21,7 +21,7 @@ description: | + google,cros-ec-spi or google,cros-ec-i2c. + + allOf: +- - $ref: i2c-controller.yaml# ++ - $ref: /schemas/i2c/i2c-controller.yaml# + + properties: + compatible: +diff --git a/Makefile b/Makefile +index 8da63744745be..17dc3e55323e7 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 9 +-SUBLEVEL = 6 ++SUBLEVEL = 7 + EXTRAVERSION = + NAME = Hurr durr I'ma ninja sloth + +diff --git a/arch/arm/boot/dts/nxp/imx/imx53-qsb-common.dtsi b/arch/arm/boot/dts/nxp/imx/imx53-qsb-common.dtsi +index d804404464737..05d7a462ea25a 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx53-qsb-common.dtsi ++++ b/arch/arm/boot/dts/nxp/imx/imx53-qsb-common.dtsi +@@ -85,7 +85,7 @@ led-user { + }; + }; + +- panel { ++ panel_dpi: panel { + compatible = "sii,43wvf1g"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_display_power>; +diff --git a/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso b/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso +index c84e9b0525276..151e9cee3c87e 100644 +--- a/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso ++++ b/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso +@@ -10,8 +10,6 @@ + /plugin/; + + &{/} { +- /delete-node/ panel; +- + hdmi: connector-hdmi { + compatible = "hdmi-connector"; + label = "hdmi"; +@@ -82,6 +80,10 @@ sii9022_out: endpoint { + }; + }; + ++&panel_dpi { ++ status = "disabled"; ++}; ++ + &tve { + status = "disabled"; + }; +diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi +index 6f0811587142d..1b1880c607cfe 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi +@@ -6,6 +6,7 @@ + #include <dt-bindings/phy/phy-imx8-pcie.h> + #include <dt-bindings/pwm/pwm.h> + #include "imx8mm.dtsi" ++#include "imx8mm-overdrive.dtsi" + + / { + chosen { +@@ -929,7 +930,7 @@ pinctrl_gpio8: gpio8grp { + /* Verdin GPIO_9_DSI (pulled-up as active-low) */ + pinctrl_gpio_9_dsi: gpio9dsigrp { + fsl,pins = +- <MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15 0x146>; /* SODIMM 17 */ ++ <MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15 0x1c6>; /* SODIMM 17 */ + }; + + /* Verdin GPIO_10_DSI (pulled-up as active-low) */ +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi +index 43f1d45ccc96f..f5115f9e8c473 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi +@@ -254,7 +254,7 @@ tc_bridge: bridge@f { + <&clk IMX8MP_CLK_CLKOUT2>, + <&clk IMX8MP_AUDIO_PLL2_OUT>; + assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>; +- assigned-clock-rates = <13000000>, <13000000>, <156000000>; ++ assigned-clock-rates = <13000000>, <13000000>, <208000000>; + reset-gpios = <&gpio4 1 GPIO_ACTIVE_HIGH>; + status = "disabled"; + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi +index f5491a608b2f3..3c063f8a9383e 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi +@@ -183,7 +183,7 @@ &uart3 { + + bluetooth { + compatible = "brcm,bcm4330-bt"; +- shutdown-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>; ++ shutdown-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; + }; + }; + +diff --git a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts +index 77ac0efdfaada..c5585bfc4efe6 100644 +--- a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts ++++ b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts +@@ -36,7 +36,7 @@ reg_usdhc2_vmmc: usdhc2-vmmc { + regulator-name = "SD1_SPWR"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; +- gpio = <&lsio_gpio4 19 GPIO_ACTIVE_HIGH>; ++ gpio = <&lsio_gpio4 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; +diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts +index 9921ea13ab489..a7cb571d74023 100644 +--- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts ++++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts +@@ -175,7 +175,6 @@ &usdhc2 { + vmmc-supply = <®_usdhc2_vmmc>; + bus-width = <4>; + status = "okay"; +- no-sdio; + no-mmc; + }; + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index 2c30d617e1802..8d39b863251b2 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -1585,6 +1585,7 @@ CONFIG_INTERCONNECT_QCOM_SC8180X=y + CONFIG_INTERCONNECT_QCOM_SC8280XP=y + CONFIG_INTERCONNECT_QCOM_SDM845=y + CONFIG_INTERCONNECT_QCOM_SDX75=y ++CONFIG_INTERCONNECT_QCOM_SM6115=y + CONFIG_INTERCONNECT_QCOM_SM8150=m + CONFIG_INTERCONNECT_QCOM_SM8250=y + CONFIG_INTERCONNECT_QCOM_SM8350=m +diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h +index 9e8999592f3af..af3b206fa4239 100644 +--- a/arch/arm64/include/asm/sysreg.h ++++ b/arch/arm64/include/asm/sysreg.h +@@ -1036,18 +1036,18 @@ + * Permission Indirection Extension (PIE) permission encodings. + * Encodings with the _O suffix, have overlays applied (Permission Overlay Extension). + */ +-#define PIE_NONE_O 0x0 +-#define PIE_R_O 0x1 +-#define PIE_X_O 0x2 +-#define PIE_RX_O 0x3 +-#define PIE_RW_O 0x5 +-#define PIE_RWnX_O 0x6 +-#define PIE_RWX_O 0x7 +-#define PIE_R 0x8 +-#define PIE_GCS 0x9 +-#define PIE_RX 0xa +-#define PIE_RW 0xc +-#define PIE_RWX 0xe ++#define PIE_NONE_O UL(0x0) ++#define PIE_R_O UL(0x1) ++#define PIE_X_O UL(0x2) ++#define PIE_RX_O UL(0x3) ++#define PIE_RW_O UL(0x5) ++#define PIE_RWnX_O UL(0x6) ++#define PIE_RWX_O UL(0x7) ++#define PIE_R UL(0x8) ++#define PIE_GCS UL(0x9) ++#define PIE_RX UL(0xa) ++#define PIE_RW UL(0xc) ++#define PIE_RWX UL(0xe) + + #define PIRx_ELx_PERM(idx, perm) ((perm) << ((idx) * 4)) + +diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c +index f20941f83a077..ce3bcff34b09b 100644 +--- a/arch/arm64/kvm/vgic/vgic-init.c ++++ b/arch/arm64/kvm/vgic/vgic-init.c +@@ -355,7 +355,7 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm) + + if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { + list_for_each_entry_safe(rdreg, next, &dist->rd_regions, list) +- vgic_v3_free_redist_region(rdreg); ++ vgic_v3_free_redist_region(kvm, rdreg); + INIT_LIST_HEAD(&dist->rd_regions); + } else { + dist->vgic_cpu_base = VGIC_ADDR_UNDEF; +diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c +index c15ee1df036a2..dad60b1e21d4d 100644 +--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c ++++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c +@@ -919,8 +919,19 @@ static int vgic_v3_alloc_redist_region(struct kvm *kvm, uint32_t index, + return ret; + } + +-void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg) ++void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg) + { ++ struct kvm_vcpu *vcpu; ++ unsigned long c; ++ ++ lockdep_assert_held(&kvm->arch.config_lock); ++ ++ /* Garbage collect the region */ ++ kvm_for_each_vcpu(c, vcpu, kvm) { ++ if (vcpu->arch.vgic_cpu.rdreg == rdreg) ++ vcpu->arch.vgic_cpu.rdreg = NULL; ++ } ++ + list_del(&rdreg->list); + kfree(rdreg); + } +@@ -945,7 +956,7 @@ int vgic_v3_set_redist_base(struct kvm *kvm, u32 index, u64 addr, u32 count) + + mutex_lock(&kvm->arch.config_lock); + rdreg = vgic_v3_rdist_region_from_index(kvm, index); +- vgic_v3_free_redist_region(rdreg); ++ vgic_v3_free_redist_region(kvm, rdreg); + mutex_unlock(&kvm->arch.config_lock); + return ret; + } +diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h +index 0c2b82de8fa3c..08b4c09a0886d 100644 +--- a/arch/arm64/kvm/vgic/vgic.h ++++ b/arch/arm64/kvm/vgic/vgic.h +@@ -317,7 +317,7 @@ vgic_v3_rd_region_size(struct kvm *kvm, struct vgic_redist_region *rdreg) + + struct vgic_redist_region *vgic_v3_rdist_region_from_index(struct kvm *kvm, + u32 index); +-void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg); ++void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg); + + bool vgic_v3_rdist_overlap(struct kvm *kvm, gpa_t base, size_t size); + +diff --git a/arch/csky/kernel/probes/ftrace.c b/arch/csky/kernel/probes/ftrace.c +index 834cffcfbce32..7ba4b98076de1 100644 +--- a/arch/csky/kernel/probes/ftrace.c ++++ b/arch/csky/kernel/probes/ftrace.c +@@ -12,6 +12,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, + struct kprobe_ctlblk *kcb; + struct pt_regs *regs; + ++ if (unlikely(kprobe_ftrace_disabled)) ++ return; ++ + bit = ftrace_test_recursion_trylock(ip, parent_ip); + if (bit < 0) + return; +diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig +index 54ad04dacdee9..d1b94ce58f793 100644 +--- a/arch/loongarch/Kconfig ++++ b/arch/loongarch/Kconfig +@@ -138,7 +138,7 @@ config LOONGARCH + select HAVE_LIVEPATCH + select HAVE_MOD_ARCH_SPECIFIC + select HAVE_NMI +- select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS ++ select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS && AS_HAS_THIN_ADD_SUB && !CC_IS_CLANG + select HAVE_PCI + select HAVE_PERF_EVENTS + select HAVE_PERF_REGS +@@ -257,6 +257,9 @@ config AS_HAS_EXPLICIT_RELOCS + config AS_HAS_FCSR_CLASS + def_bool $(as-instr,movfcsr2gr \$t0$(comma)\$fcsr0) + ++config AS_HAS_THIN_ADD_SUB ++ def_bool $(cc-option,-Wa$(comma)-mthin-add-sub) ++ + config AS_HAS_LSX_EXTENSION + def_bool $(as-instr,vld \$vr0$(comma)\$a0$(comma)0) + +diff --git a/arch/loongarch/Kconfig.debug b/arch/loongarch/Kconfig.debug +index 98d60630c3d4b..8b2ce5b5d43e8 100644 +--- a/arch/loongarch/Kconfig.debug ++++ b/arch/loongarch/Kconfig.debug +@@ -28,6 +28,7 @@ config UNWINDER_PROLOGUE + + config UNWINDER_ORC + bool "ORC unwinder" ++ depends on HAVE_OBJTOOL + select OBJTOOL + help + This option enables the ORC (Oops Rewind Capability) unwinder for +diff --git a/arch/loongarch/include/asm/hw_breakpoint.h b/arch/loongarch/include/asm/hw_breakpoint.h +index 21447fb1efc77..d78330916bd18 100644 +--- a/arch/loongarch/include/asm/hw_breakpoint.h ++++ b/arch/loongarch/include/asm/hw_breakpoint.h +@@ -75,6 +75,8 @@ do { \ + #define CSR_MWPC_NUM 0x3f + + #define CTRL_PLV_ENABLE 0x1e ++#define CTRL_PLV0_ENABLE 0x02 ++#define CTRL_PLV3_ENABLE 0x10 + + #define MWPnCFG3_LoadEn 8 + #define MWPnCFG3_StoreEn 9 +@@ -101,7 +103,7 @@ struct perf_event; + struct perf_event_attr; + + extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, +- int *gen_len, int *gen_type, int *offset); ++ int *gen_len, int *gen_type); + extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw); + extern int hw_breakpoint_arch_parse(struct perf_event *bp, + const struct perf_event_attr *attr, +diff --git a/arch/loongarch/kernel/ftrace_dyn.c b/arch/loongarch/kernel/ftrace_dyn.c +index 73858c9029cc9..bff058317062e 100644 +--- a/arch/loongarch/kernel/ftrace_dyn.c ++++ b/arch/loongarch/kernel/ftrace_dyn.c +@@ -287,6 +287,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, + struct kprobe *p; + struct kprobe_ctlblk *kcb; + ++ if (unlikely(kprobe_ftrace_disabled)) ++ return; ++ + bit = ftrace_test_recursion_trylock(ip, parent_ip); + if (bit < 0) + return; +diff --git a/arch/loongarch/kernel/hw_breakpoint.c b/arch/loongarch/kernel/hw_breakpoint.c +index fc55c4de2a11f..621ad7634df71 100644 +--- a/arch/loongarch/kernel/hw_breakpoint.c ++++ b/arch/loongarch/kernel/hw_breakpoint.c +@@ -174,11 +174,21 @@ void flush_ptrace_hw_breakpoint(struct task_struct *tsk) + static int hw_breakpoint_control(struct perf_event *bp, + enum hw_breakpoint_ops ops) + { +- u32 ctrl; ++ u32 ctrl, privilege; + int i, max_slots, enable; ++ struct pt_regs *regs; + struct perf_event **slots; + struct arch_hw_breakpoint *info = counter_arch_bp(bp); + ++ if (arch_check_bp_in_kernelspace(info)) ++ privilege = CTRL_PLV0_ENABLE; ++ else ++ privilege = CTRL_PLV3_ENABLE; ++ ++ /* Whether bp belongs to a task. */ ++ if (bp->hw.target) ++ regs = task_pt_regs(bp->hw.target); ++ + if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) { + /* Breakpoint */ + slots = this_cpu_ptr(bp_on_reg); +@@ -197,31 +207,38 @@ static int hw_breakpoint_control(struct perf_event *bp, + switch (ops) { + case HW_BREAKPOINT_INSTALL: + /* Set the FWPnCFG/MWPnCFG 1~4 register. */ +- write_wb_reg(CSR_CFG_ADDR, i, 0, info->address); +- write_wb_reg(CSR_CFG_ADDR, i, 1, info->address); +- write_wb_reg(CSR_CFG_MASK, i, 0, info->mask); +- write_wb_reg(CSR_CFG_MASK, i, 1, info->mask); +- write_wb_reg(CSR_CFG_ASID, i, 0, 0); +- write_wb_reg(CSR_CFG_ASID, i, 1, 0); + if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) { +- write_wb_reg(CSR_CFG_CTRL, i, 0, CTRL_PLV_ENABLE); ++ write_wb_reg(CSR_CFG_ADDR, i, 0, info->address); ++ write_wb_reg(CSR_CFG_MASK, i, 0, info->mask); ++ write_wb_reg(CSR_CFG_ASID, i, 0, 0); ++ write_wb_reg(CSR_CFG_CTRL, i, 0, privilege); + } else { ++ write_wb_reg(CSR_CFG_ADDR, i, 1, info->address); ++ write_wb_reg(CSR_CFG_MASK, i, 1, info->mask); ++ write_wb_reg(CSR_CFG_ASID, i, 1, 0); + ctrl = encode_ctrl_reg(info->ctrl); +- write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl | CTRL_PLV_ENABLE); ++ write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl | privilege); + } + enable = csr_read64(LOONGARCH_CSR_CRMD); + csr_write64(CSR_CRMD_WE | enable, LOONGARCH_CSR_CRMD); ++ if (bp->hw.target) ++ regs->csr_prmd |= CSR_PRMD_PWE; + break; + case HW_BREAKPOINT_UNINSTALL: + /* Reset the FWPnCFG/MWPnCFG 1~4 register. */ +- write_wb_reg(CSR_CFG_ADDR, i, 0, 0); +- write_wb_reg(CSR_CFG_ADDR, i, 1, 0); +- write_wb_reg(CSR_CFG_MASK, i, 0, 0); +- write_wb_reg(CSR_CFG_MASK, i, 1, 0); +- write_wb_reg(CSR_CFG_CTRL, i, 0, 0); +- write_wb_reg(CSR_CFG_CTRL, i, 1, 0); +- write_wb_reg(CSR_CFG_ASID, i, 0, 0); +- write_wb_reg(CSR_CFG_ASID, i, 1, 0); ++ if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) { ++ write_wb_reg(CSR_CFG_ADDR, i, 0, 0); ++ write_wb_reg(CSR_CFG_MASK, i, 0, 0); ++ write_wb_reg(CSR_CFG_CTRL, i, 0, 0); ++ write_wb_reg(CSR_CFG_ASID, i, 0, 0); ++ } else { ++ write_wb_reg(CSR_CFG_ADDR, i, 1, 0); ++ write_wb_reg(CSR_CFG_MASK, i, 1, 0); ++ write_wb_reg(CSR_CFG_CTRL, i, 1, 0); ++ write_wb_reg(CSR_CFG_ASID, i, 1, 0); ++ } ++ if (bp->hw.target) ++ regs->csr_prmd &= ~CSR_PRMD_PWE; + break; + } + +@@ -283,7 +300,7 @@ int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw) + * to generic breakpoint descriptions. + */ + int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, +- int *gen_len, int *gen_type, int *offset) ++ int *gen_len, int *gen_type) + { + /* Type */ + switch (ctrl.type) { +@@ -303,11 +320,6 @@ int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, + return -EINVAL; + } + +- if (!ctrl.len) +- return -EINVAL; +- +- *offset = __ffs(ctrl.len); +- + /* Len */ + switch (ctrl.len) { + case LOONGARCH_BREAKPOINT_LEN_1: +@@ -386,21 +398,17 @@ int hw_breakpoint_arch_parse(struct perf_event *bp, + struct arch_hw_breakpoint *hw) + { + int ret; +- u64 alignment_mask, offset; ++ u64 alignment_mask; + + /* Build the arch_hw_breakpoint. */ + ret = arch_build_bp_info(bp, attr, hw); + if (ret) + return ret; + +- if (hw->ctrl.type != LOONGARCH_BREAKPOINT_EXECUTE) +- alignment_mask = 0x7; +- else ++ if (hw->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) { + alignment_mask = 0x3; +- offset = hw->address & alignment_mask; +- +- hw->address &= ~alignment_mask; +- hw->ctrl.len <<= offset; ++ hw->address &= ~alignment_mask; ++ } + + return 0; + } +@@ -471,12 +479,15 @@ void breakpoint_handler(struct pt_regs *regs) + slots = this_cpu_ptr(bp_on_reg); + + for (i = 0; i < boot_cpu_data.watch_ireg_count; ++i) { +- bp = slots[i]; +- if (bp == NULL) +- continue; +- perf_bp_event(bp, regs); ++ if ((csr_read32(LOONGARCH_CSR_FWPS) & (0x1 << i))) { ++ bp = slots[i]; ++ if (bp == NULL) ++ continue; ++ perf_bp_event(bp, regs); ++ csr_write32(0x1 << i, LOONGARCH_CSR_FWPS); ++ update_bp_registers(regs, 0, 0); ++ } + } +- update_bp_registers(regs, 0, 0); + } + NOKPROBE_SYMBOL(breakpoint_handler); + +@@ -488,12 +499,15 @@ void watchpoint_handler(struct pt_regs *regs) + slots = this_cpu_ptr(wp_on_reg); + + for (i = 0; i < boot_cpu_data.watch_dreg_count; ++i) { +- wp = slots[i]; +- if (wp == NULL) +- continue; +- perf_bp_event(wp, regs); ++ if ((csr_read32(LOONGARCH_CSR_MWPS) & (0x1 << i))) { ++ wp = slots[i]; ++ if (wp == NULL) ++ continue; ++ perf_bp_event(wp, regs); ++ csr_write32(0x1 << i, LOONGARCH_CSR_MWPS); ++ update_bp_registers(regs, 0, 1); ++ } + } +- update_bp_registers(regs, 0, 1); + } + NOKPROBE_SYMBOL(watchpoint_handler); + +diff --git a/arch/loongarch/kernel/ptrace.c b/arch/loongarch/kernel/ptrace.c +index c114c5ef13325..200109de1971a 100644 +--- a/arch/loongarch/kernel/ptrace.c ++++ b/arch/loongarch/kernel/ptrace.c +@@ -494,28 +494,14 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type, + struct arch_hw_breakpoint_ctrl ctrl, + struct perf_event_attr *attr) + { +- int err, len, type, offset; ++ int err, len, type; + +- err = arch_bp_generic_fields(ctrl, &len, &type, &offset); ++ err = arch_bp_generic_fields(ctrl, &len, &type); + if (err) + return err; + +- switch (note_type) { +- case NT_LOONGARCH_HW_BREAK: +- if ((type & HW_BREAKPOINT_X) != type) +- return -EINVAL; +- break; +- case NT_LOONGARCH_HW_WATCH: +- if ((type & HW_BREAKPOINT_RW) != type) +- return -EINVAL; +- break; +- default: +- return -EINVAL; +- } +- + attr->bp_len = len; + attr->bp_type = type; +- attr->bp_addr += offset; + + return 0; + } +@@ -609,10 +595,27 @@ static int ptrace_hbp_set_ctrl(unsigned int note_type, + return PTR_ERR(bp); + + attr = bp->attr; +- decode_ctrl_reg(uctrl, &ctrl); +- err = ptrace_hbp_fill_attr_ctrl(note_type, ctrl, &attr); +- if (err) +- return err; ++ ++ switch (note_type) { ++ case NT_LOONGARCH_HW_BREAK: ++ ctrl.type = LOONGARCH_BREAKPOINT_EXECUTE; ++ ctrl.len = LOONGARCH_BREAKPOINT_LEN_4; ++ break; ++ case NT_LOONGARCH_HW_WATCH: ++ decode_ctrl_reg(uctrl, &ctrl); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (uctrl & CTRL_PLV_ENABLE) { ++ err = ptrace_hbp_fill_attr_ctrl(note_type, ctrl, &attr); ++ if (err) ++ return err; ++ attr.disabled = 0; ++ } else { ++ attr.disabled = 1; ++ } + + return modify_user_hw_breakpoint(bp, &attr); + } +@@ -643,6 +646,10 @@ static int ptrace_hbp_set_addr(unsigned int note_type, + struct perf_event *bp; + struct perf_event_attr attr; + ++ /* Kernel-space address cannot be monitored by user-space */ ++ if ((unsigned long)addr >= XKPRANGE) ++ return -EINVAL; ++ + bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx); + if (IS_ERR(bp)) + return PTR_ERR(bp); +diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c +index ec180ab92eaa8..66a8ba19c2872 100644 +--- a/arch/mips/bmips/setup.c ++++ b/arch/mips/bmips/setup.c +@@ -110,7 +110,8 @@ static void bcm6358_quirks(void) + * RAC flush causes kernel panics on BCM6358 when booting from TP1 + * because the bootloader is not initializing it properly. + */ +- bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)); ++ bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)) || ++ !!BMIPS_GET_CBR(); + } + + static void bcm6368_quirks(void) +diff --git a/arch/mips/include/asm/mipsmtregs.h b/arch/mips/include/asm/mipsmtregs.h +index 30e86861c206c..b1ee3c48e84ba 100644 +--- a/arch/mips/include/asm/mipsmtregs.h ++++ b/arch/mips/include/asm/mipsmtregs.h +@@ -322,7 +322,7 @@ static inline void ehb(void) + " .set push \n" \ + " .set "MIPS_ISA_LEVEL" \n" \ + _ASM_SET_MFTC0 \ +- " mftc0 $1, " #rt ", " #sel " \n" \ ++ " mftc0 %0, " #rt ", " #sel " \n" \ + _ASM_UNSET_MFTC0 \ + " .set pop \n" \ + : "=r" (__res)); \ +diff --git a/arch/mips/pci/ops-rc32434.c b/arch/mips/pci/ops-rc32434.c +index 874ed6df97683..34b9323bdabb0 100644 +--- a/arch/mips/pci/ops-rc32434.c ++++ b/arch/mips/pci/ops-rc32434.c +@@ -112,8 +112,8 @@ static int read_config_dword(struct pci_bus *bus, unsigned int devfn, + * gives them time to settle + */ + if (where == PCI_VENDOR_ID) { +- if (ret == 0xffffffff || ret == 0x00000000 || +- ret == 0x0000ffff || ret == 0xffff0000) { ++ if (*val == 0xffffffff || *val == 0x00000000 || ++ *val == 0x0000ffff || *val == 0xffff0000) { + if (delay > 4) + return 0; + delay *= 2; +diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c +old mode 100644 +new mode 100755 +index 2583e318e8c6b..b080c7c6cc463 +--- a/arch/mips/pci/pcie-octeon.c ++++ b/arch/mips/pci/pcie-octeon.c +@@ -230,12 +230,18 @@ static inline uint64_t __cvmx_pcie_build_config_addr(int pcie_port, int bus, + { + union cvmx_pcie_address pcie_addr; + union cvmx_pciercx_cfg006 pciercx_cfg006; ++ union cvmx_pciercx_cfg032 pciercx_cfg032; + + pciercx_cfg006.u32 = + cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG006(pcie_port)); + if ((bus <= pciercx_cfg006.s.pbnum) && (dev != 0)) + return 0; + ++ pciercx_cfg032.u32 = ++ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port)); ++ if ((pciercx_cfg032.s.dlla == 0) || (pciercx_cfg032.s.lt == 1)) ++ return 0; ++ + pcie_addr.u64 = 0; + pcie_addr.config.upper = 2; + pcie_addr.config.io = 1; +diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c +index 621a4b386ae4f..c91f9c2e61ed2 100644 +--- a/arch/parisc/kernel/ftrace.c ++++ b/arch/parisc/kernel/ftrace.c +@@ -206,6 +206,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, + struct kprobe *p; + int bit; + ++ if (unlikely(kprobe_ftrace_disabled)) ++ return; ++ + bit = ftrace_test_recursion_trylock(ip, parent_ip); + if (bit < 0) + return; +diff --git a/arch/powerpc/crypto/.gitignore b/arch/powerpc/crypto/.gitignore +index e1094f08f713a..e9fe73aac8b61 100644 +--- a/arch/powerpc/crypto/.gitignore ++++ b/arch/powerpc/crypto/.gitignore +@@ -1,3 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0-only + aesp10-ppc.S ++aesp8-ppc.S + ghashp10-ppc.S ++ghashp8-ppc.S +diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h +index 51172625fa3a5..7a8495660c2f8 100644 +--- a/arch/powerpc/include/asm/hvcall.h ++++ b/arch/powerpc/include/asm/hvcall.h +@@ -524,7 +524,7 @@ long plpar_hcall_norets_notrace(unsigned long opcode, ...); + * Used for all but the craziest of phyp interfaces (see plpar_hcall9) + */ + #define PLPAR_HCALL_BUFSIZE 4 +-long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...); ++long plpar_hcall(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...); + + /** + * plpar_hcall_raw: - Make a hypervisor call without calculating hcall stats +@@ -538,7 +538,7 @@ long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...); + * plpar_hcall, but plpar_hcall_raw works in real mode and does not + * calculate hypervisor call statistics. + */ +-long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...); ++long plpar_hcall_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...); + + /** + * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments +@@ -549,8 +549,8 @@ long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...); + * PLPAR_HCALL9_BUFSIZE to size the return argument buffer. + */ + #define PLPAR_HCALL9_BUFSIZE 9 +-long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...); +-long plpar_hcall9_raw(unsigned long opcode, unsigned long *retbuf, ...); ++long plpar_hcall9(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...); ++long plpar_hcall9_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...); + + /* pseries hcall tracing */ + extern struct static_key hcall_tracepoint_key; +diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h +index 08c550ed49be6..ba2e13bb879dc 100644 +--- a/arch/powerpc/include/asm/io.h ++++ b/arch/powerpc/include/asm/io.h +@@ -585,12 +585,12 @@ __do_out_asm(_rec_outl, "stwbrx") + #define __do_inw(port) _rec_inw(port) + #define __do_inl(port) _rec_inl(port) + #else /* CONFIG_PPC32 */ +-#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)_IO_BASE+port); +-#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)_IO_BASE+port); +-#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)_IO_BASE+port); +-#define __do_inb(port) readb((PCI_IO_ADDR)_IO_BASE + port); +-#define __do_inw(port) readw((PCI_IO_ADDR)_IO_BASE + port); +-#define __do_inl(port) readl((PCI_IO_ADDR)_IO_BASE + port); ++#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)(_IO_BASE+port)); ++#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)(_IO_BASE+port)); ++#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)(_IO_BASE+port)); ++#define __do_inb(port) readb((PCI_IO_ADDR)(_IO_BASE + port)); ++#define __do_inw(port) readw((PCI_IO_ADDR)(_IO_BASE + port)); ++#define __do_inl(port) readl((PCI_IO_ADDR)(_IO_BASE + port)); + #endif /* !CONFIG_PPC32 */ + + #ifdef CONFIG_EEH +@@ -606,12 +606,12 @@ __do_out_asm(_rec_outl, "stwbrx") + #define __do_writesw(a, b, n) _outsw(PCI_FIX_ADDR(a),(b),(n)) + #define __do_writesl(a, b, n) _outsl(PCI_FIX_ADDR(a),(b),(n)) + +-#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) +-#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) +-#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) +-#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) +-#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) +-#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) ++#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n)) ++#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n)) ++#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n)) ++#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n)) ++#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n)) ++#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n)) + + #define __do_memset_io(addr, c, n) \ + _memset_io(PCI_FIX_ADDR(addr), c, n) +diff --git a/arch/powerpc/kernel/kprobes-ftrace.c b/arch/powerpc/kernel/kprobes-ftrace.c +index 072ebe7f290ba..f8208c027148f 100644 +--- a/arch/powerpc/kernel/kprobes-ftrace.c ++++ b/arch/powerpc/kernel/kprobes-ftrace.c +@@ -21,6 +21,9 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip, + struct pt_regs *regs; + int bit; + ++ if (unlikely(kprobe_ftrace_disabled)) ++ return; ++ + bit = ftrace_test_recursion_trylock(nip, parent_nip); + if (bit < 0) + return; +diff --git a/arch/riscv/kernel/probes/ftrace.c b/arch/riscv/kernel/probes/ftrace.c +index 7142ec42e889f..a69dfa610aa85 100644 +--- a/arch/riscv/kernel/probes/ftrace.c ++++ b/arch/riscv/kernel/probes/ftrace.c +@@ -11,6 +11,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, + struct kprobe_ctlblk *kcb; + int bit; + ++ if (unlikely(kprobe_ftrace_disabled)) ++ return; ++ + bit = ftrace_test_recursion_trylock(ip, parent_ip); + if (bit < 0) + return; +diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c +index c46381ea04ecb..7f6f8c438c265 100644 +--- a/arch/s390/kernel/ftrace.c ++++ b/arch/s390/kernel/ftrace.c +@@ -296,6 +296,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, + struct kprobe *p; + int bit; + ++ if (unlikely(kprobe_ftrace_disabled)) ++ return; ++ + bit = ftrace_test_recursion_trylock(ip, parent_ip); + if (bit < 0) + return; +diff --git a/arch/x86/include/asm/cpu_device_id.h b/arch/x86/include/asm/cpu_device_id.h +index eb8fcede9e3bf..e8e3dbe7f1730 100644 +--- a/arch/x86/include/asm/cpu_device_id.h ++++ b/arch/x86/include/asm/cpu_device_id.h +@@ -2,6 +2,39 @@ + #ifndef _ASM_X86_CPU_DEVICE_ID + #define _ASM_X86_CPU_DEVICE_ID + ++/* ++ * Can't use <linux/bitfield.h> because it generates expressions that ++ * cannot be used in structure initializers. Bitfield construction ++ * here must match the union in struct cpuinfo_86: ++ * union { ++ * struct { ++ * __u8 x86_model; ++ * __u8 x86; ++ * __u8 x86_vendor; ++ * __u8 x86_reserved; ++ * }; ++ * __u32 x86_vfm; ++ * }; ++ */ ++#define VFM_MODEL_BIT 0 ++#define VFM_FAMILY_BIT 8 ++#define VFM_VENDOR_BIT 16 ++#define VFM_RSVD_BIT 24 ++ ++#define VFM_MODEL_MASK GENMASK(VFM_FAMILY_BIT - 1, VFM_MODEL_BIT) ++#define VFM_FAMILY_MASK GENMASK(VFM_VENDOR_BIT - 1, VFM_FAMILY_BIT) ++#define VFM_VENDOR_MASK GENMASK(VFM_RSVD_BIT - 1, VFM_VENDOR_BIT) ++ ++#define VFM_MODEL(vfm) (((vfm) & VFM_MODEL_MASK) >> VFM_MODEL_BIT) ++#define VFM_FAMILY(vfm) (((vfm) & VFM_FAMILY_MASK) >> VFM_FAMILY_BIT) ++#define VFM_VENDOR(vfm) (((vfm) & VFM_VENDOR_MASK) >> VFM_VENDOR_BIT) ++ ++#define VFM_MAKE(_vendor, _family, _model) ( \ ++ ((_model) << VFM_MODEL_BIT) | \ ++ ((_family) << VFM_FAMILY_BIT) | \ ++ ((_vendor) << VFM_VENDOR_BIT) \ ++) ++ + /* + * Declare drivers belonging to specific x86 CPUs + * Similar in spirit to pci_device_id and related PCI functions +@@ -20,6 +53,9 @@ + #define X86_CENTAUR_FAM6_C7_D 0xd + #define X86_CENTAUR_FAM6_NANO 0xf + ++/* x86_cpu_id::flags */ ++#define X86_CPU_ID_FLAG_ENTRY_VALID BIT(0) ++ + #define X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins) + /** + * X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching +@@ -46,6 +82,18 @@ + .model = _model, \ + .steppings = _steppings, \ + .feature = _feature, \ ++ .flags = X86_CPU_ID_FLAG_ENTRY_VALID, \ ++ .driver_data = (unsigned long) _data \ ++} ++ ++#define X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \ ++ _steppings, _feature, _data) { \ ++ .vendor = _vendor, \ ++ .family = _family, \ ++ .model = _model, \ ++ .steppings = _steppings, \ ++ .feature = _feature, \ ++ .flags = X86_CPU_ID_FLAG_ENTRY_VALID, \ + .driver_data = (unsigned long) _data \ + } + +@@ -164,6 +212,56 @@ + X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, INTEL_FAM6_##model, \ + steppings, X86_FEATURE_ANY, data) + ++/** ++ * X86_MATCH_VFM - Match encoded vendor/family/model ++ * @vfm: Encoded 8-bits each for vendor, family, model ++ * @data: Driver specific data or NULL. The internal storage ++ * format is unsigned long. The supplied value, pointer ++ * etc. is cast to unsigned long internally. ++ * ++ * Stepping and feature are set to wildcards ++ */ ++#define X86_MATCH_VFM(vfm, data) \ ++ X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \ ++ VFM_VENDOR(vfm), \ ++ VFM_FAMILY(vfm), \ ++ VFM_MODEL(vfm), \ ++ X86_STEPPING_ANY, X86_FEATURE_ANY, data) ++ ++/** ++ * X86_MATCH_VFM_STEPPINGS - Match encoded vendor/family/model/stepping ++ * @vfm: Encoded 8-bits each for vendor, family, model ++ * @steppings: Bitmask of steppings to match ++ * @data: Driver specific data or NULL. The internal storage ++ * format is unsigned long. The supplied value, pointer ++ * etc. is cast to unsigned long internally. ++ * ++ * feature is set to wildcard ++ */ ++#define X86_MATCH_VFM_STEPPINGS(vfm, steppings, data) \ ++ X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \ ++ VFM_VENDOR(vfm), \ ++ VFM_FAMILY(vfm), \ ++ VFM_MODEL(vfm), \ ++ steppings, X86_FEATURE_ANY, data) ++ ++/** ++ * X86_MATCH_VFM_FEATURE - Match encoded vendor/family/model/feature ++ * @vfm: Encoded 8-bits each for vendor, family, model ++ * @feature: A X86_FEATURE bit ++ * @data: Driver specific data or NULL. The internal storage ++ * format is unsigned long. The supplied value, pointer ++ * etc. is cast to unsigned long internally. ++ * ++ * Steppings is set to wildcard ++ */ ++#define X86_MATCH_VFM_FEATURE(vfm, feature, data) \ ++ X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \ ++ VFM_VENDOR(vfm), \ ++ VFM_FAMILY(vfm), \ ++ VFM_MODEL(vfm), \ ++ X86_STEPPING_ANY, feature, data) ++ + /* + * Match specific microcode revisions. + * +diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h +index 1dc600fa3ba53..481096177500e 100644 +--- a/arch/x86/include/asm/efi.h ++++ b/arch/x86/include/asm/efi.h +@@ -401,7 +401,6 @@ extern int __init efi_memmap_alloc(unsigned int num_entries, + struct efi_memory_map_data *data); + extern void __efi_memmap_free(u64 phys, unsigned long size, + unsigned long flags); +-#define __efi_memmap_free __efi_memmap_free + + extern int __init efi_memmap_install(struct efi_memory_map_data *data); + extern int __init efi_memmap_split_count(efi_memory_desc_t *md, +diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c +index ad6776081e60d..ae71b8ef909c9 100644 +--- a/arch/x86/kernel/cpu/match.c ++++ b/arch/x86/kernel/cpu/match.c +@@ -39,9 +39,7 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) + const struct x86_cpu_id *m; + struct cpuinfo_x86 *c = &boot_cpu_data; + +- for (m = match; +- m->vendor | m->family | m->model | m->steppings | m->feature; +- m++) { ++ for (m = match; m->flags & X86_CPU_ID_FLAG_ENTRY_VALID; m++) { + if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor) + continue; + if (m->family != X86_FAMILY_ANY && c->x86 != m->family) +diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c +index c34a35ec0f031..2ce5f4913c820 100644 +--- a/arch/x86/kernel/cpu/resctrl/monitor.c ++++ b/arch/x86/kernel/cpu/resctrl/monitor.c +@@ -508,7 +508,8 @@ void free_rmid(u32 closid, u32 rmid) + * allows architectures that ignore the closid parameter to avoid an + * unnecessary check. + */ +- if (idx == resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID, ++ if (!resctrl_arch_mon_capable() || ++ idx == resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID, + RESCTRL_RESERVED_RMID)) + return; + +diff --git a/arch/x86/kernel/kprobes/ftrace.c b/arch/x86/kernel/kprobes/ftrace.c +index dd2ec14adb77b..15af7e98e161a 100644 +--- a/arch/x86/kernel/kprobes/ftrace.c ++++ b/arch/x86/kernel/kprobes/ftrace.c +@@ -21,6 +21,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, + struct kprobe_ctlblk *kcb; + int bit; + ++ if (unlikely(kprobe_ftrace_disabled)) ++ return; ++ + bit = ftrace_test_recursion_trylock(ip, parent_ip); + if (bit < 0) + return; +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 91478b769af08..4dbd9d99f9ea0 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -10677,13 +10677,12 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) + + bitmap_zero(vcpu->arch.ioapic_handled_vectors, 256); + ++ static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); ++ + if (irqchip_split(vcpu->kvm)) + kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors); +- else { +- static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); +- if (ioapic_in_kernel(vcpu->kvm)) +- kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors); +- } ++ else if (ioapic_in_kernel(vcpu->kvm)) ++ kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors); + + if (is_guest_mode(vcpu)) + vcpu->arch.load_eoi_exitmap_pending = true; +diff --git a/arch/x86/platform/efi/memmap.c b/arch/x86/platform/efi/memmap.c +index 4ef20b49eb5e7..6ed1935504b96 100644 +--- a/arch/x86/platform/efi/memmap.c ++++ b/arch/x86/platform/efi/memmap.c +@@ -92,12 +92,22 @@ int __init efi_memmap_alloc(unsigned int num_entries, + */ + int __init efi_memmap_install(struct efi_memory_map_data *data) + { ++ unsigned long size = efi.memmap.desc_size * efi.memmap.nr_map; ++ unsigned long flags = efi.memmap.flags; ++ u64 phys = efi.memmap.phys_map; ++ int ret; ++ + efi_memmap_unmap(); + + if (efi_enabled(EFI_PARAVIRT)) + return 0; + +- return __efi_memmap_init(data); ++ ret = __efi_memmap_init(data); ++ if (ret) ++ return ret; ++ ++ __efi_memmap_free(phys, size, flags); ++ return 0; + } + + /** +diff --git a/block/ioctl.c b/block/ioctl.c +index f505f9c341eb0..2639ce9df3852 100644 +--- a/block/ioctl.c ++++ b/block/ioctl.c +@@ -33,7 +33,7 @@ static int blkpg_do_ioctl(struct block_device *bdev, + if (op == BLKPG_DEL_PARTITION) + return bdev_del_partition(disk, p.pno); + +- if (p.start < 0 || p.length <= 0 || p.start + p.length < 0) ++ if (p.start < 0 || p.length <= 0 || LLONG_MAX - p.length < p.start) + return -EINVAL; + /* Check that the partition is aligned to the block size */ + if (!IS_ALIGNED(p.start | p.length, bdev_logical_block_size(bdev))) +diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h +index ddd072cbc738d..2133085deda77 100644 +--- a/drivers/acpi/acpica/acevents.h ++++ b/drivers/acpi/acpica/acevents.h +@@ -191,6 +191,10 @@ void + acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, + acpi_adr_space_type space_id, u32 function); + ++void ++acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *node, ++ acpi_adr_space_type space_id); ++ + acpi_status + acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function); + +diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c +index 18fdf2bc2d499..dc6004daf624b 100644 +--- a/drivers/acpi/acpica/evregion.c ++++ b/drivers/acpi/acpica/evregion.c +@@ -20,10 +20,6 @@ extern u8 acpi_gbl_default_address_spaces[]; + + /* Local prototypes */ + +-static void +-acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node, +- acpi_adr_space_type space_id); +- + static acpi_status + acpi_ev_reg_run(acpi_handle obj_handle, + u32 level, void *context, void **return_value); +@@ -818,7 +814,7 @@ acpi_ev_reg_run(acpi_handle obj_handle, + * + ******************************************************************************/ + +-static void ++void + acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node, + acpi_adr_space_type space_id) + { +diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c +index 3197e6303c5b0..624361a5f34d8 100644 +--- a/drivers/acpi/acpica/evxfregn.c ++++ b/drivers/acpi/acpica/evxfregn.c +@@ -306,3 +306,57 @@ acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id) + } + + ACPI_EXPORT_SYMBOL(acpi_execute_reg_methods) ++ ++/******************************************************************************* ++ * ++ * FUNCTION: acpi_execute_orphan_reg_method ++ * ++ * PARAMETERS: device - Handle for the device ++ * space_id - The address space ID ++ * ++ * RETURN: Status ++ * ++ * DESCRIPTION: Execute an "orphan" _REG method that appears under an ACPI ++ * device. This is a _REG method that has no corresponding region ++ * within the device's scope. ++ * ++ ******************************************************************************/ ++acpi_status ++acpi_execute_orphan_reg_method(acpi_handle device, acpi_adr_space_type space_id) ++{ ++ struct acpi_namespace_node *node; ++ acpi_status status; ++ ++ ACPI_FUNCTION_TRACE(acpi_execute_orphan_reg_method); ++ ++ /* Parameter validation */ ++ ++ if (!device) { ++ return_ACPI_STATUS(AE_BAD_PARAMETER); ++ } ++ ++ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); ++ if (ACPI_FAILURE(status)) { ++ return_ACPI_STATUS(status); ++ } ++ ++ /* Convert and validate the device handle */ ++ ++ node = acpi_ns_validate_handle(device); ++ if (node) { ++ ++ /* ++ * If an "orphan" _REG method is present in the device's scope ++ * for the given address space ID, run it. ++ */ ++ ++ acpi_ev_execute_orphan_reg_method(node, space_id); ++ } else { ++ status = AE_BAD_PARAMETER; ++ } ++ ++ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); ++ return_ACPI_STATUS(status); ++} ++ ++ACPI_EXPORT_SYMBOL(acpi_execute_orphan_reg_method) +diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c +index 8907b8bf42672..c49b9f8de723d 100644 +--- a/drivers/acpi/acpica/exregion.c ++++ b/drivers/acpi/acpica/exregion.c +@@ -44,7 +44,6 @@ acpi_ex_system_memory_space_handler(u32 function, + struct acpi_mem_mapping *mm = mem_info->cur_mm; + u32 length; + acpi_size map_length; +- acpi_size page_boundary_map_length; + #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED + u32 remainder; + #endif +@@ -138,26 +137,8 @@ acpi_ex_system_memory_space_handler(u32 function, + map_length = (acpi_size) + ((mem_info->address + mem_info->length) - address); + +- /* +- * If mapping the entire remaining portion of the region will cross +- * a page boundary, just map up to the page boundary, do not cross. +- * On some systems, crossing a page boundary while mapping regions +- * can cause warnings if the pages have different attributes +- * due to resource management. +- * +- * This has the added benefit of constraining a single mapping to +- * one page, which is similar to the original code that used a 4k +- * maximum window. +- */ +- page_boundary_map_length = (acpi_size) +- (ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address); +- if (page_boundary_map_length == 0) { +- page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE; +- } +- +- if (map_length > page_boundary_map_length) { +- map_length = page_boundary_map_length; +- } ++ if (map_length > ACPI_DEFAULT_PAGE_SIZE) ++ map_length = ACPI_DEFAULT_PAGE_SIZE; + + /* Create a new mapping starting at the address given */ + +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index 02255795b800d..1cec29ab64ce8 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -1482,13 +1482,14 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec) + static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device, + bool call_reg) + { ++ acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle; + acpi_status status; + + acpi_ec_start(ec, false); + + if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) { + acpi_ec_enter_noirq(ec); +- status = acpi_install_address_space_handler_no_reg(ec->handle, ++ status = acpi_install_address_space_handler_no_reg(scope_handle, + ACPI_ADR_SPACE_EC, + &acpi_ec_space_handler, + NULL, ec); +@@ -1497,11 +1498,13 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device, + return -ENODEV; + } + set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags); +- ec->address_space_handler_holder = ec->handle; + } + + if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) { +- acpi_execute_reg_methods(ec->handle, ACPI_ADR_SPACE_EC); ++ acpi_execute_reg_methods(scope_handle, ACPI_ADR_SPACE_EC); ++ if (scope_handle != ec->handle) ++ acpi_execute_orphan_reg_method(ec->handle, ACPI_ADR_SPACE_EC); ++ + set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags); + } + +@@ -1553,10 +1556,13 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device, + + static void ec_remove_handlers(struct acpi_ec *ec) + { ++ acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle; ++ + if (test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) { + if (ACPI_FAILURE(acpi_remove_address_space_handler( +- ec->address_space_handler_holder, +- ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) ++ scope_handle, ++ ACPI_ADR_SPACE_EC, ++ &acpi_ec_space_handler))) + pr_err("failed to remove space handler\n"); + clear_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags); + } +@@ -1595,14 +1601,18 @@ static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device, bool ca + { + int ret; + +- ret = ec_install_handlers(ec, device, call_reg); +- if (ret) +- return ret; +- + /* First EC capable of handling transactions */ + if (!first_ec) + first_ec = ec; + ++ ret = ec_install_handlers(ec, device, call_reg); ++ if (ret) { ++ if (ec == first_ec) ++ first_ec = NULL; ++ ++ return ret; ++ } ++ + pr_info("EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", ec->command_addr, + ec->data_addr); + +diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h +index ca72a0dc57151..a96d1bc662a37 100644 +--- a/drivers/acpi/internal.h ++++ b/drivers/acpi/internal.h +@@ -185,7 +185,6 @@ enum acpi_ec_event_state { + + struct acpi_ec { + acpi_handle handle; +- acpi_handle address_space_handler_holder; + int gpe; + int irq; + unsigned long command_addr; +@@ -302,6 +301,10 @@ void acpi_mipi_check_crs_csi2(acpi_handle handle); + void acpi_mipi_scan_crs_csi2(void); + void acpi_mipi_init_crs_csi2_swnodes(void); + void acpi_mipi_crs_csi2_cleanup(void); ++#ifdef CONFIG_X86 + bool acpi_graph_ignore_port(acpi_handle handle); ++#else ++static inline bool acpi_graph_ignore_port(acpi_handle handle) { return false; } ++#endif + + #endif /* _ACPI_INTERNAL_H_ */ +diff --git a/drivers/acpi/mipi-disco-img.c b/drivers/acpi/mipi-disco-img.c +index d05413a0672a9..0ab13751f0dbc 100644 +--- a/drivers/acpi/mipi-disco-img.c ++++ b/drivers/acpi/mipi-disco-img.c +@@ -725,14 +725,20 @@ void acpi_mipi_crs_csi2_cleanup(void) + acpi_mipi_del_crs_csi2(csi2); + } + +-static const struct dmi_system_id dmi_ignore_port_nodes[] = { +- { +- .matches = { +- DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."), +- DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS 9315"), +- }, +- }, +- { } ++#ifdef CONFIG_X86 ++#include <asm/cpu_device_id.h> ++#include <asm/intel-family.h> ++ ++/* CPU matches for Dell generations with broken ACPI MIPI DISCO info */ ++static const struct x86_cpu_id dell_broken_mipi_disco_cpu_gens[] = { ++ X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, NULL), ++ X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, NULL), ++ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, NULL), ++ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, NULL), ++ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, NULL), ++ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, NULL), ++ X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, NULL), ++ {} + }; + + static const char *strnext(const char *s1, const char *s2) +@@ -761,7 +767,10 @@ bool acpi_graph_ignore_port(acpi_handle handle) + static bool dmi_tested, ignore_port; + + if (!dmi_tested) { +- ignore_port = dmi_first_match(dmi_ignore_port_nodes); ++ if (dmi_name_in_vendors("Dell Inc.") && ++ x86_match_cpu(dell_broken_mipi_disco_cpu_gens)) ++ ignore_port = true; ++ + dmi_tested = true; + } + +@@ -794,3 +803,4 @@ bool acpi_graph_ignore_port(acpi_handle handle) + kfree(orig_path); + return false; + } ++#endif +diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c +index 6cc8572759a3d..b5bf8b81a050a 100644 +--- a/drivers/acpi/resource.c ++++ b/drivers/acpi/resource.c +@@ -517,6 +517,13 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = { + DMI_MATCH(DMI_BOARD_NAME, "E1504GAB"), + }, + }, ++ { ++ /* Asus Vivobook Pro N6506MV */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ++ DMI_MATCH(DMI_BOARD_NAME, "N6506MV"), ++ }, ++ }, + { + /* LG Electronics 17U70P */ + .matches = { +@@ -533,6 +540,12 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = { + * to have a working keyboard. + */ + static const struct dmi_system_id irq1_edge_low_force_override[] = { ++ { ++ /* XMG APEX 17 (M23) */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "GMxBGxx"), ++ }, ++ }, + { + /* TongFang GMxRGxx/XMG CORE 15 (M22)/TUXEDO Stellaris 15 Gen4 AMD */ + .matches = { +diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c +index 9fdcc620c6524..2cc3821b2b16e 100644 +--- a/drivers/acpi/video_detect.c ++++ b/drivers/acpi/video_detect.c +@@ -497,6 +497,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "82BK"), + }, + }, ++ { ++ .callback = video_detect_force_native, ++ /* Lenovo Slim 7 16ARH7 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "82UX"), ++ }, ++ }, + { + .callback = video_detect_force_native, + /* Lenovo ThinkPad X131e (3371 AMD version) */ +diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c +index 7507a7706898c..448e0d14fd7bd 100644 +--- a/drivers/acpi/x86/utils.c ++++ b/drivers/acpi/x86/utils.c +@@ -256,9 +256,10 @@ bool force_storage_d3(void) + #define ACPI_QUIRK_SKIP_I2C_CLIENTS BIT(0) + #define ACPI_QUIRK_UART1_SKIP BIT(1) + #define ACPI_QUIRK_UART1_TTY_UART2_SKIP BIT(2) +-#define ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY BIT(3) +-#define ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY BIT(4) +-#define ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS BIT(5) ++#define ACPI_QUIRK_PNP_UART1_SKIP BIT(3) ++#define ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY BIT(4) ++#define ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY BIT(5) ++#define ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS BIT(6) + + static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { + /* +@@ -338,6 +339,7 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { + DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"), + }, + .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | ++ ACPI_QUIRK_PNP_UART1_SKIP | + ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), + }, + { +@@ -436,14 +438,18 @@ static int acpi_dmi_skip_serdev_enumeration(struct device *controller_parent, bo + if (ret) + return 0; + +- /* to not match on PNP enumerated debug UARTs */ +- if (!dev_is_platform(controller_parent)) +- return 0; +- + dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids); + if (dmi_id) + quirks = (unsigned long)dmi_id->driver_data; + ++ if (!dev_is_platform(controller_parent)) { ++ /* PNP enumerated UARTs */ ++ if ((quirks & ACPI_QUIRK_PNP_UART1_SKIP) && uid == 1) ++ *skip = true; ++ ++ return 0; ++ } ++ + if ((quirks & ACPI_QUIRK_UART1_SKIP) && uid == 1) + *skip = true; + +diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c +index 07d66d2c5f0dd..5eb38fbbbecdb 100644 +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -1735,6 +1735,14 @@ static void ahci_update_initial_lpm_policy(struct ata_port *ap) + if (ap->pflags & ATA_PFLAG_EXTERNAL) + return; + ++ /* If no LPM states are supported by the HBA, do not bother with LPM */ ++ if ((ap->host->flags & ATA_HOST_NO_PART) && ++ (ap->host->flags & ATA_HOST_NO_SSC) && ++ (ap->host->flags & ATA_HOST_NO_DEVSLP)) { ++ ata_port_dbg(ap, "no LPM states supported, not enabling LPM\n"); ++ return; ++ } ++ + /* user modified policy via module param */ + if (mobile_lpm_policy != -1) { + policy = mobile_lpm_policy; +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 9d4ec9273bf95..1ddd3e5497896 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -588,7 +588,10 @@ static inline int was_interrupted(int result) + return result == -ERESTARTSYS || result == -EINTR; + } + +-/* always call with the tx_lock held */ ++/* ++ * Returns BLK_STS_RESOURCE if the caller should retry after a delay. Returns ++ * -EAGAIN if the caller should requeue @cmd. Returns -EIO if sending failed. ++ */ + static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) + { + struct request *req = blk_mq_rq_from_pdu(cmd); +@@ -605,6 +608,9 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) + u32 nbd_cmd_flags = 0; + int sent = nsock->sent, skip = 0; + ++ lockdep_assert_held(&cmd->lock); ++ lockdep_assert_held(&nsock->tx_lock); ++ + iov_iter_kvec(&from, ITER_SOURCE, &iov, 1, sizeof(request)); + + type = req_to_nbd_cmd_type(req); +@@ -669,7 +675,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) + nsock->sent = sent; + } + set_bit(NBD_CMD_REQUEUED, &cmd->flags); +- return BLK_STS_RESOURCE; ++ return (__force int)BLK_STS_RESOURCE; + } + dev_err_ratelimited(disk_to_dev(nbd->disk), + "Send control failed (result %d)\n", result); +@@ -710,7 +716,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) + nsock->pending = req; + nsock->sent = sent; + set_bit(NBD_CMD_REQUEUED, &cmd->flags); +- return BLK_STS_RESOURCE; ++ return (__force int)BLK_STS_RESOURCE; + } + dev_err(disk_to_dev(nbd->disk), + "Send data failed (result %d)\n", +@@ -1007,7 +1013,7 @@ static int wait_for_reconnect(struct nbd_device *nbd) + return !test_bit(NBD_RT_DISCONNECTED, &config->runtime_flags); + } + +-static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) ++static blk_status_t nbd_handle_cmd(struct nbd_cmd *cmd, int index) + { + struct request *req = blk_mq_rq_from_pdu(cmd); + struct nbd_device *nbd = cmd->nbd; +@@ -1015,18 +1021,20 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) + struct nbd_sock *nsock; + int ret; + ++ lockdep_assert_held(&cmd->lock); ++ + config = nbd_get_config_unlocked(nbd); + if (!config) { + dev_err_ratelimited(disk_to_dev(nbd->disk), + "Socks array is empty\n"); +- return -EINVAL; ++ return BLK_STS_IOERR; + } + + if (index >= config->num_connections) { + dev_err_ratelimited(disk_to_dev(nbd->disk), + "Attempted send on invalid socket\n"); + nbd_config_put(nbd); +- return -EINVAL; ++ return BLK_STS_IOERR; + } + cmd->status = BLK_STS_OK; + again: +@@ -1049,7 +1057,7 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) + */ + sock_shutdown(nbd); + nbd_config_put(nbd); +- return -EIO; ++ return BLK_STS_IOERR; + } + goto again; + } +@@ -1062,7 +1070,7 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) + blk_mq_start_request(req); + if (unlikely(nsock->pending && nsock->pending != req)) { + nbd_requeue_cmd(cmd); +- ret = 0; ++ ret = BLK_STS_OK; + goto out; + } + /* +@@ -1081,19 +1089,19 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) + "Request send failed, requeueing\n"); + nbd_mark_nsock_dead(nbd, nsock, 1); + nbd_requeue_cmd(cmd); +- ret = 0; ++ ret = BLK_STS_OK; + } + out: + mutex_unlock(&nsock->tx_lock); + nbd_config_put(nbd); +- return ret; ++ return ret < 0 ? BLK_STS_IOERR : (__force blk_status_t)ret; + } + + static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) + { + struct nbd_cmd *cmd = blk_mq_rq_to_pdu(bd->rq); +- int ret; ++ blk_status_t ret; + + /* + * Since we look at the bio's to send the request over the network we +@@ -1113,10 +1121,6 @@ static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx, + * appropriate. + */ + ret = nbd_handle_cmd(cmd, hctx->queue_num); +- if (ret < 0) +- ret = BLK_STS_IOERR; +- else if (!ret) +- ret = BLK_STS_OK; + mutex_unlock(&cmd->lock); + + return ret; +diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c +index 88262d3a93923..ce97b336fbfb8 100644 +--- a/drivers/bluetooth/ath3k.c ++++ b/drivers/bluetooth/ath3k.c +@@ -3,7 +3,6 @@ + * Copyright (c) 2008-2009 Atheros Communications Inc. + */ + +- + #include <linux/module.h> + #include <linux/kernel.h> + #include <linux/init.h> +@@ -128,7 +127,6 @@ MODULE_DEVICE_TABLE(usb, ath3k_table); + * for AR3012 + */ + static const struct usb_device_id ath3k_blist_tbl[] = { +- + /* Atheros AR3012 with sflash firmware*/ + { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, +@@ -202,7 +200,7 @@ static inline void ath3k_log_failed_loading(int err, int len, int size, + #define TIMEGAP_USEC_MAX 100 + + static int ath3k_load_firmware(struct usb_device *udev, +- const struct firmware *firmware) ++ const struct firmware *firmware) + { + u8 *send_buf; + int len = 0; +@@ -237,9 +235,9 @@ static int ath3k_load_firmware(struct usb_device *udev, + memcpy(send_buf, firmware->data + sent, size); + + err = usb_bulk_msg(udev, pipe, send_buf, size, +- &len, 3000); ++ &len, 3000); + +- if (err || (len != size)) { ++ if (err || len != size) { + ath3k_log_failed_loading(err, len, size, count); + goto error; + } +@@ -262,7 +260,7 @@ static int ath3k_get_state(struct usb_device *udev, unsigned char *state) + } + + static int ath3k_get_version(struct usb_device *udev, +- struct ath3k_version *version) ++ struct ath3k_version *version) + { + return usb_control_msg_recv(udev, 0, ATH3K_GETVERSION, + USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, +@@ -271,7 +269,7 @@ static int ath3k_get_version(struct usb_device *udev, + } + + static int ath3k_load_fwfile(struct usb_device *udev, +- const struct firmware *firmware) ++ const struct firmware *firmware) + { + u8 *send_buf; + int len = 0; +@@ -310,8 +308,8 @@ static int ath3k_load_fwfile(struct usb_device *udev, + memcpy(send_buf, firmware->data + sent, size); + + err = usb_bulk_msg(udev, pipe, send_buf, size, +- &len, 3000); +- if (err || (len != size)) { ++ &len, 3000); ++ if (err || len != size) { + ath3k_log_failed_loading(err, len, size, count); + kfree(send_buf); + return err; +@@ -425,7 +423,6 @@ static int ath3k_load_syscfg(struct usb_device *udev) + } + + switch (fw_version.ref_clock) { +- + case ATH3K_XTAL_FREQ_26M: + clk_value = 26; + break; +@@ -441,7 +438,7 @@ static int ath3k_load_syscfg(struct usb_device *udev) + } + + snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", +- le32_to_cpu(fw_version.rom_version), clk_value, ".dfu"); ++ le32_to_cpu(fw_version.rom_version), clk_value, ".dfu"); + + ret = request_firmware(&firmware, filename, &udev->dev); + if (ret < 0) { +@@ -456,7 +453,7 @@ static int ath3k_load_syscfg(struct usb_device *udev) + } + + static int ath3k_probe(struct usb_interface *intf, +- const struct usb_device_id *id) ++ const struct usb_device_id *id) + { + const struct firmware *firmware; + struct usb_device *udev = interface_to_usbdev(intf); +@@ -505,10 +502,10 @@ static int ath3k_probe(struct usb_interface *intf, + if (ret < 0) { + if (ret == -ENOENT) + BT_ERR("Firmware file \"%s\" not found", +- ATH3K_FIRMWARE); ++ ATH3K_FIRMWARE); + else + BT_ERR("Firmware file \"%s\" request failed (err=%d)", +- ATH3K_FIRMWARE, ret); ++ ATH3K_FIRMWARE, ret); + return ret; + } + +diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c +index 6c989d859b396..6af175e6c08ac 100644 +--- a/drivers/cpufreq/amd-pstate.c ++++ b/drivers/cpufreq/amd-pstate.c +@@ -1462,6 +1462,13 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy) + + static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy) + { ++ struct amd_cpudata *cpudata = policy->driver_data; ++ ++ if (cpudata) { ++ kfree(cpudata); ++ policy->driver_data = NULL; ++ } ++ + pr_debug("CPU %d exiting\n", policy->cpu); + return 0; + } +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index 92f0a1d9b4a6b..13e413533f082 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -2893,12 +2893,9 @@ void hisi_qm_uninit(struct hisi_qm *qm) + hisi_qm_set_state(qm, QM_NOT_READY); + up_write(&qm->qps_lock); + ++ qm_remove_uacce(qm); + qm_irqs_unregister(qm); + hisi_qm_pci_uninit(qm); +- if (qm->use_sva) { +- uacce_remove(qm->uacce); +- qm->uacce = NULL; +- } + } + EXPORT_SYMBOL_GPL(hisi_qm_uninit); + +diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c +index 93a972fcbf638..0558f98e221f6 100644 +--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c ++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c +@@ -481,8 +481,10 @@ static void sec_alg_resource_free(struct sec_ctx *ctx, + + if (ctx->pbuf_supported) + sec_free_pbuf_resource(dev, qp_ctx->res); +- if (ctx->alg_type == SEC_AEAD) ++ if (ctx->alg_type == SEC_AEAD) { + sec_free_mac_resource(dev, qp_ctx->res); ++ sec_free_aiv_resource(dev, qp_ctx->res); ++ } + } + + static int sec_alloc_qp_ctx_resource(struct sec_ctx *ctx, struct sec_qp_ctx *qp_ctx) +diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c +index 0df09bd794088..2773f05adb7d2 100644 +--- a/drivers/cxl/core/pci.c ++++ b/drivers/cxl/core/pci.c +@@ -1045,3 +1045,32 @@ long cxl_pci_get_latency(struct pci_dev *pdev) + + return cxl_flit_size(pdev) * MEGA / bw; + } ++ ++static int __cxl_endpoint_decoder_reset_detected(struct device *dev, void *data) ++{ ++ struct cxl_port *port = data; ++ struct cxl_decoder *cxld; ++ struct cxl_hdm *cxlhdm; ++ void __iomem *hdm; ++ u32 ctrl; ++ ++ if (!is_endpoint_decoder(dev)) ++ return 0; ++ ++ cxld = to_cxl_decoder(dev); ++ if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0) ++ return 0; ++ ++ cxlhdm = dev_get_drvdata(&port->dev); ++ hdm = cxlhdm->regs.hdm_decoder; ++ ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(cxld->id)); ++ ++ return !FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl); ++} ++ ++bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port) ++{ ++ return device_for_each_child(&port->dev, port, ++ __cxl_endpoint_decoder_reset_detected); ++} ++EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_reset_detected, CXL); +diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h +index 036d17db68e00..72fa477407689 100644 +--- a/drivers/cxl/cxl.h ++++ b/drivers/cxl/cxl.h +@@ -891,6 +891,8 @@ void cxl_coordinates_combine(struct access_coordinate *out, + struct access_coordinate *c1, + struct access_coordinate *c2); + ++bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port); ++ + /* + * Unit test builds overrides this to __weak, find the 'strong' version + * of these symbols in tools/testing/cxl/. +diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c +index 2ff361e756d66..659f9d46b154c 100644 +--- a/drivers/cxl/pci.c ++++ b/drivers/cxl/pci.c +@@ -957,11 +957,33 @@ static void cxl_error_resume(struct pci_dev *pdev) + dev->driver ? "successful" : "failed"); + } + ++static void cxl_reset_done(struct pci_dev *pdev) ++{ ++ struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); ++ struct cxl_memdev *cxlmd = cxlds->cxlmd; ++ struct device *dev = &pdev->dev; ++ ++ /* ++ * FLR does not expect to touch the HDM decoders and related ++ * registers. SBR, however, will wipe all device configurations. ++ * Issue a warning if there was an active decoder before the reset ++ * that no longer exists. ++ */ ++ guard(device)(&cxlmd->dev); ++ if (cxlmd->endpoint && ++ cxl_endpoint_decoder_reset_detected(cxlmd->endpoint)) { ++ dev_crit(dev, "SBR happened without memory regions removal.\n"); ++ dev_crit(dev, "System may be unstable if regions hosted system memory.\n"); ++ add_taint(TAINT_USER, LOCKDEP_STILL_OK); ++ } ++} ++ + static const struct pci_error_handlers cxl_error_handlers = { + .error_detected = cxl_error_detected, + .slot_reset = cxl_slot_reset, + .resume = cxl_error_resume, + .cor_error_detected = cxl_cor_error_detected, ++ .reset_done = cxl_reset_done, + }; + + static struct pci_driver cxl_pci_driver = { +diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig +index 002a5ec806207..9fc99cfbef08c 100644 +--- a/drivers/dma/Kconfig ++++ b/drivers/dma/Kconfig +@@ -394,7 +394,7 @@ config LS2X_APB_DMA + + config MCF_EDMA + tristate "Freescale eDMA engine support, ColdFire mcf5441x SoCs" +- depends on M5441x || COMPILE_TEST ++ depends on M5441x || (COMPILE_TEST && FSL_EDMA=n) + select DMA_ENGINE + select DMA_VIRTUAL_CHANNELS + help +diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +index a86a81ff0caa6..321446fdddbd7 100644 +--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c ++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +@@ -302,6 +302,7 @@ static struct axi_dma_desc *axi_desc_alloc(u32 num) + kfree(desc); + return NULL; + } ++ desc->nr_hw_descs = num; + + return desc; + } +@@ -328,7 +329,7 @@ static struct axi_dma_lli *axi_desc_get(struct axi_dma_chan *chan, + static void axi_desc_put(struct axi_dma_desc *desc) + { + struct axi_dma_chan *chan = desc->chan; +- int count = atomic_read(&chan->descs_allocated); ++ int count = desc->nr_hw_descs; + struct axi_dma_hw_desc *hw_desc; + int descs_put; + +@@ -1139,9 +1140,6 @@ static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan) + /* Remove the completed descriptor from issued list before completing */ + list_del(&vd->node); + vchan_cookie_complete(vd); +- +- /* Submit queued descriptors after processing the completed ones */ +- axi_chan_start_first_queued(chan); + } + + out: +diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +index 454904d996540..ac571b413b21c 100644 +--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h ++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +@@ -104,6 +104,7 @@ struct axi_dma_desc { + u32 completed_blocks; + u32 length; + u32 period_len; ++ u32 nr_hw_descs; + }; + + struct axi_dma_chan_config { +diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c +index 8dc029c865515..fc049c9c9892e 100644 +--- a/drivers/dma/idxd/irq.c ++++ b/drivers/dma/idxd/irq.c +@@ -611,11 +611,13 @@ static void irq_process_work_list(struct idxd_irq_entry *irq_entry) + + spin_unlock(&irq_entry->list_lock); + +- list_for_each_entry(desc, &flist, list) { ++ list_for_each_entry_safe(desc, n, &flist, list) { + /* + * Check against the original status as ABORT is software defined + * and 0xff, which DSA_COMP_STATUS_MASK can mask out. + */ ++ list_del(&desc->list); ++ + if (unlikely(desc->completion->status == IDXD_COMP_DESC_ABORT)) { + idxd_desc_complete(desc, IDXD_COMPLETE_ABORT, true); + continue; +diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c +index 9c364e92cb828..e8f45a7fded43 100644 +--- a/drivers/dma/ioat/init.c ++++ b/drivers/dma/ioat/init.c +@@ -534,18 +534,6 @@ static int ioat_probe(struct ioatdma_device *ioat_dma) + return err; + } + +-static int ioat_register(struct ioatdma_device *ioat_dma) +-{ +- int err = dma_async_device_register(&ioat_dma->dma_dev); +- +- if (err) { +- ioat_disable_interrupts(ioat_dma); +- dma_pool_destroy(ioat_dma->completion_pool); +- } +- +- return err; +-} +- + static void ioat_dma_remove(struct ioatdma_device *ioat_dma) + { + struct dma_device *dma = &ioat_dma->dma_dev; +@@ -1181,9 +1169,9 @@ static int ioat3_dma_probe(struct ioatdma_device *ioat_dma, int dca) + ioat_chan->reg_base + IOAT_DCACTRL_OFFSET); + } + +- err = ioat_register(ioat_dma); ++ err = dma_async_device_register(&ioat_dma->dma_dev); + if (err) +- return err; ++ goto err_disable_interrupts; + + ioat_kobject_add(ioat_dma, &ioat_ktype); + +@@ -1192,20 +1180,29 @@ static int ioat3_dma_probe(struct ioatdma_device *ioat_dma, int dca) + + /* disable relaxed ordering */ + err = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &val16); +- if (err) +- return pcibios_err_to_errno(err); ++ if (err) { ++ err = pcibios_err_to_errno(err); ++ goto err_disable_interrupts; ++ } + + /* clear relaxed ordering enable */ + val16 &= ~PCI_EXP_DEVCTL_RELAX_EN; + err = pcie_capability_write_word(pdev, PCI_EXP_DEVCTL, val16); +- if (err) +- return pcibios_err_to_errno(err); ++ if (err) { ++ err = pcibios_err_to_errno(err); ++ goto err_disable_interrupts; ++ } + + if (ioat_dma->cap & IOAT_CAP_DPS) + writeb(ioat_pending_level + 1, + ioat_dma->reg_base + IOAT_PREFETCH_LIMIT_OFFSET); + + return 0; ++ ++err_disable_interrupts: ++ ioat_disable_interrupts(ioat_dma); ++ dma_pool_destroy(ioat_dma->completion_pool); ++ return err; + } + + static void ioat_shutdown(struct pci_dev *pdev) +@@ -1350,6 +1347,8 @@ static int ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + void __iomem * const *iomap; + struct device *dev = &pdev->dev; + struct ioatdma_device *device; ++ unsigned int i; ++ u8 version; + int err; + + err = pcim_enable_device(pdev); +@@ -1363,6 +1362,10 @@ static int ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + if (!iomap) + return -ENOMEM; + ++ version = readb(iomap[IOAT_MMIO_BAR] + IOAT_VER_OFFSET); ++ if (version < IOAT_VER_3_0) ++ return -ENODEV; ++ + err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); + if (err) + return err; +@@ -1373,17 +1376,18 @@ static int ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + pci_set_master(pdev); + pci_set_drvdata(pdev, device); + +- device->version = readb(device->reg_base + IOAT_VER_OFFSET); ++ device->version = version; + if (device->version >= IOAT_VER_3_4) + ioat_dca_enabled = 0; +- if (device->version >= IOAT_VER_3_0) { +- if (is_skx_ioat(pdev)) +- device->version = IOAT_VER_3_2; +- err = ioat3_dma_probe(device, ioat_dca_enabled); +- } else +- return -ENODEV; + ++ if (is_skx_ioat(pdev)) ++ device->version = IOAT_VER_3_2; ++ ++ err = ioat3_dma_probe(device, ioat_dca_enabled); + if (err) { ++ for (i = 0; i < IOAT_MAX_CHANS; i++) ++ kfree(device->idx[i]); ++ kfree(device); + dev_err(dev, "Intel(R) I/OAT DMA Engine init failed\n"); + return -ENODEV; + } +@@ -1445,6 +1449,7 @@ module_init(ioat_init_module); + static void __exit ioat_exit_module(void) + { + pci_unregister_driver(&ioat_pci_driver); ++ kmem_cache_destroy(ioat_sed_cache); + kmem_cache_destroy(ioat_cache); + } + module_exit(ioat_exit_module); +diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c +index c9b93055dc9d3..f0a399cf45b2a 100644 +--- a/drivers/dma/ti/k3-udma-glue.c ++++ b/drivers/dma/ti/k3-udma-glue.c +@@ -200,12 +200,9 @@ of_k3_udma_glue_parse_chn_by_id(struct device_node *udmax_np, struct k3_udma_glu + + ret = of_k3_udma_glue_parse(udmax_np, common); + if (ret) +- goto out_put_spec; ++ return ret; + + ret = of_k3_udma_glue_parse_chn_common(common, thread_id, tx_chn); +- +-out_put_spec: +- of_node_put(udmax_np); + return ret; + } + +diff --git a/drivers/dma/xilinx/xdma.c b/drivers/dma/xilinx/xdma.c +index 313b217388fe9..ae6e06057aa1d 100644 +--- a/drivers/dma/xilinx/xdma.c ++++ b/drivers/dma/xilinx/xdma.c +@@ -885,11 +885,11 @@ static irqreturn_t xdma_channel_isr(int irq, void *dev_id) + u32 st; + bool repeat_tx; + ++ spin_lock(&xchan->vchan.lock); ++ + if (xchan->stop_requested) + complete(&xchan->last_interrupt); + +- spin_lock(&xchan->vchan.lock); +- + /* get submitted request */ + vd = vchan_next_desc(&xchan->vchan); + if (!vd) +diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c +index 3365944f79654..34109fd86c55d 100644 +--- a/drivers/firmware/efi/memmap.c ++++ b/drivers/firmware/efi/memmap.c +@@ -15,10 +15,6 @@ + #include <asm/early_ioremap.h> + #include <asm/efi.h> + +-#ifndef __efi_memmap_free +-#define __efi_memmap_free(phys, size, flags) do { } while (0) +-#endif +- + /** + * __efi_memmap_init - Common code for mapping the EFI memory map + * @data: EFI memory map data +@@ -51,11 +47,6 @@ int __init __efi_memmap_init(struct efi_memory_map_data *data) + return -ENOMEM; + } + +- if (efi.memmap.flags & (EFI_MEMMAP_MEMBLOCK | EFI_MEMMAP_SLAB)) +- __efi_memmap_free(efi.memmap.phys_map, +- efi.memmap.desc_size * efi.memmap.nr_map, +- efi.memmap.flags); +- + map.phys_map = data->phys_map; + map.nr_map = data->size / data->desc_size; + map.map_end = map.map + data->size; +diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c +index d9629ff878619..2328ca58bba61 100644 +--- a/drivers/firmware/psci/psci.c ++++ b/drivers/firmware/psci/psci.c +@@ -497,10 +497,12 @@ int psci_cpu_suspend_enter(u32 state) + + static int psci_system_suspend(unsigned long unused) + { ++ int err; + phys_addr_t pa_cpu_resume = __pa_symbol(cpu_resume); + +- return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), ++ err = invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), + pa_cpu_resume, 0, 0); ++ return psci_to_linux_errno(err); + } + + static int psci_system_suspend_enter(suspend_state_t state) +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +index be4629cdac049..08b9dfb653355 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +@@ -684,12 +684,17 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid, + struct amdgpu_ring *ring = &adev->gfx.kiq[inst].ring; + struct amdgpu_kiq *kiq = &adev->gfx.kiq[inst]; + unsigned int ndw; +- signed long r; ++ int r; + uint32_t seq; + +- if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready || +- !down_read_trylock(&adev->reset_domain->sem)) { ++ /* ++ * A GPU reset should flush all TLBs anyway, so no need to do ++ * this while one is ongoing. ++ */ ++ if (!down_read_trylock(&adev->reset_domain->sem)) ++ return 0; + ++ if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready) { + if (adev->gmc.flush_tlb_needs_extra_type_2) + adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid, + 2, all_hub, +@@ -703,43 +708,40 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid, + adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid, + flush_type, all_hub, + inst); +- return 0; +- } ++ r = 0; ++ } else { ++ /* 2 dwords flush + 8 dwords fence */ ++ ndw = kiq->pmf->invalidate_tlbs_size + 8; + +- /* 2 dwords flush + 8 dwords fence */ +- ndw = kiq->pmf->invalidate_tlbs_size + 8; ++ if (adev->gmc.flush_tlb_needs_extra_type_2) ++ ndw += kiq->pmf->invalidate_tlbs_size; + +- if (adev->gmc.flush_tlb_needs_extra_type_2) +- ndw += kiq->pmf->invalidate_tlbs_size; ++ if (adev->gmc.flush_tlb_needs_extra_type_0) ++ ndw += kiq->pmf->invalidate_tlbs_size; + +- if (adev->gmc.flush_tlb_needs_extra_type_0) +- ndw += kiq->pmf->invalidate_tlbs_size; ++ spin_lock(&adev->gfx.kiq[inst].ring_lock); ++ amdgpu_ring_alloc(ring, ndw); ++ if (adev->gmc.flush_tlb_needs_extra_type_2) ++ kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub); + +- spin_lock(&adev->gfx.kiq[inst].ring_lock); +- amdgpu_ring_alloc(ring, ndw); +- if (adev->gmc.flush_tlb_needs_extra_type_2) +- kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub); ++ if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0) ++ kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub); + +- if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0) +- kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub); ++ kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub); ++ r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT); ++ if (r) { ++ amdgpu_ring_undo(ring); ++ spin_unlock(&adev->gfx.kiq[inst].ring_lock); ++ goto error_unlock_reset; ++ } + +- kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub); +- r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT); +- if (r) { +- amdgpu_ring_undo(ring); ++ amdgpu_ring_commit(ring); + spin_unlock(&adev->gfx.kiq[inst].ring_lock); +- goto error_unlock_reset; +- } +- +- amdgpu_ring_commit(ring); +- spin_unlock(&adev->gfx.kiq[inst].ring_lock); +- r = amdgpu_fence_wait_polling(ring, seq, usec_timeout); +- if (r < 1) { +- dev_err(adev->dev, "wait for kiq fence error: %ld.\n", r); +- r = -ETIME; +- goto error_unlock_reset; ++ if (amdgpu_fence_wait_polling(ring, seq, usec_timeout) < 1) { ++ dev_err(adev->dev, "timeout waiting for kiq fence\n"); ++ r = -ETIME; ++ } + } +- r = 0; + + error_unlock_reset: + up_read(&adev->reset_domain->sem); +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index d6e71aa808d88..f866a02f4f489 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -9149,9 +9149,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) + + trace_amdgpu_dm_atomic_commit_tail_begin(state); + +- if (dm->dc->caps.ips_support && dm->dc->idle_optimizations_allowed) +- dc_allow_idle_optimizations(dm->dc, false); +- + drm_atomic_helper_update_legacy_modeset_state(dev, state); + drm_dp_mst_atomic_wait_for_dependencies(state); + +diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +index 6083b1dcf050a..a72e849eced3f 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c ++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +@@ -1340,16 +1340,27 @@ void dc_dmub_srv_apply_idle_power_optimizations(const struct dc *dc, bool allow_ + * Powering up the hardware requires notifying PMFW and DMCUB. + * Clearing the driver idle allow requires a DMCUB command. + * DMCUB commands requires the DMCUB to be powered up and restored. +- * +- * Exit out early to prevent an infinite loop of DMCUB commands +- * triggering exit low power - use software state to track this. + */ +- dc_dmub_srv->idle_allowed = allow_idle; + +- if (!allow_idle) ++ if (!allow_idle) { + dc_dmub_srv_exit_low_power_state(dc); +- else ++ /* ++ * Idle is considered fully exited only after the sequence above ++ * fully completes. If we have a race of two threads exiting ++ * at the same time then it's safe to perform the sequence ++ * twice as long as we're not re-entering. ++ * ++ * Infinite command submission is avoided by using the ++ * dm_execute_dmub_cmd submission instead of the "wake" helpers. ++ */ ++ dc_dmub_srv->idle_allowed = false; ++ } else { ++ /* Consider idle as notified prior to the actual submission to ++ * prevent multiple entries. */ ++ dc_dmub_srv->idle_allowed = true; ++ + dc_dmub_srv_notify_idle(dc, allow_idle); ++ } + } + + bool dc_wake_and_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmd *cmd, +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +index a14f99f4f14a5..eb6c6ba64c0b9 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +@@ -1373,3 +1373,75 @@ void dcn35_set_static_screen_control(struct pipe_ctx **pipe_ctx, + set_static_screen_control(pipe_ctx[i]->stream_res.tg, + triggers, params->num_frames); + } ++ ++static bool should_avoid_empty_tu(struct pipe_ctx *pipe_ctx) ++{ ++ /* Calculate average pixel count per TU, return false if under ~2.00 to ++ * avoid empty TUs. This is only required for DPIA tunneling as empty TUs ++ * are legal to generate for native DP links. Assume TU size 64 as there ++ * is currently no scenario where it's reprogrammed from HW default. ++ * MTPs have no such limitation, so this does not affect MST use cases. ++ */ ++ unsigned int pix_clk_mhz; ++ unsigned int symclk_mhz; ++ unsigned int avg_pix_per_tu_x1000; ++ unsigned int tu_size_bytes = 64; ++ struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; ++ struct dc_link_settings *link_settings = &pipe_ctx->link_config.dp_link_settings; ++ const struct dc *dc = pipe_ctx->stream->link->dc; ++ ++ if (pipe_ctx->stream->link->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) ++ return false; ++ ++ // Not necessary for MST configurations ++ if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) ++ return false; ++ ++ pix_clk_mhz = timing->pix_clk_100hz / 10000; ++ ++ // If this is true, can't block due to dynamic ODM ++ if (pix_clk_mhz > dc->clk_mgr->bw_params->clk_table.entries[0].dispclk_mhz) ++ return false; ++ ++ switch (link_settings->link_rate) { ++ case LINK_RATE_LOW: ++ symclk_mhz = 162; ++ break; ++ case LINK_RATE_HIGH: ++ symclk_mhz = 270; ++ break; ++ case LINK_RATE_HIGH2: ++ symclk_mhz = 540; ++ break; ++ case LINK_RATE_HIGH3: ++ symclk_mhz = 810; ++ break; ++ default: ++ // We shouldn't be tunneling any other rates, something is wrong ++ ASSERT(0); ++ return false; ++ } ++ ++ avg_pix_per_tu_x1000 = (1000 * pix_clk_mhz * tu_size_bytes) ++ / (symclk_mhz * link_settings->lane_count); ++ ++ // Add small empirically-decided margin to account for potential jitter ++ return (avg_pix_per_tu_x1000 < 2020); ++} ++ ++bool dcn35_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx) ++{ ++ struct dc *dc = pipe_ctx->stream->ctx->dc; ++ ++ if (!is_h_timing_divisible_by_2(pipe_ctx->stream)) ++ return false; ++ ++ if (should_avoid_empty_tu(pipe_ctx)) ++ return false; ++ ++ if (dc_is_dp_signal(pipe_ctx->stream->signal) && !dc->link_srv->dp_is_128b_132b_signal(pipe_ctx) && ++ dc->debug.enable_dp_dig_pixel_rate_div_policy) ++ return true; ++ ++ return false; ++} +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h +index c354efa6c1b2f..91f5d1136a2e6 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h +@@ -93,4 +93,6 @@ void dcn35_set_drr(struct pipe_ctx **pipe_ctx, + void dcn35_set_static_screen_control(struct pipe_ctx **pipe_ctx, + int num_pipes, const struct dc_static_screen_params *params); + ++bool dcn35_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx); ++ + #endif /* __DC_HWSS_DCN35_H__ */ +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c +index a93073055e7bf..6c8da59b7956d 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c +@@ -158,7 +158,7 @@ static const struct hwseq_private_funcs dcn35_private_funcs = { + .setup_hpo_hw_control = dcn35_setup_hpo_hw_control, + .calculate_dccg_k1_k2_values = dcn32_calculate_dccg_k1_k2_values, + .set_pixels_per_cycle = dcn32_set_pixels_per_cycle, +- .is_dp_dig_pixel_rate_div_policy = dcn32_is_dp_dig_pixel_rate_div_policy, ++ .is_dp_dig_pixel_rate_div_policy = dcn35_is_dp_dig_pixel_rate_div_policy, + .dsc_pg_control = dcn35_dsc_pg_control, + .dsc_pg_status = dcn32_dsc_pg_status, + .enable_plane = dcn35_enable_plane, +diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +index 5cb4725c773f6..c8586cb7d0fec 100644 +--- a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c ++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +@@ -164,6 +164,8 @@ static void sumo_construct_vid_mapping_table(struct amdgpu_device *adev, + + for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) { + if (table[i].ulSupportedSCLK != 0) { ++ if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES) ++ continue; + vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit = + table[i].usVoltageID; + vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit = +diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c +index e583515f9b25a..950f86fb13511 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp.c ++++ b/drivers/gpu/drm/i915/display/intel_dp.c +@@ -431,6 +431,10 @@ bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp) + struct intel_encoder *encoder = &intel_dig_port->base; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + ++ /* eDP MSO is not compatible with joiner */ ++ if (intel_dp->mso_link_count) ++ return false; ++ + return DISPLAY_VER(dev_priv) >= 12 || + (DISPLAY_VER(dev_priv) == 11 && + encoder->port != PORT_A); +diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c +index fbc43f243c54d..6d000504e1a4e 100644 +--- a/drivers/gpu/drm/lima/lima_bcast.c ++++ b/drivers/gpu/drm/lima/lima_bcast.c +@@ -43,6 +43,18 @@ void lima_bcast_suspend(struct lima_ip *ip) + + } + ++int lima_bcast_mask_irq(struct lima_ip *ip) ++{ ++ bcast_write(LIMA_BCAST_BROADCAST_MASK, 0); ++ bcast_write(LIMA_BCAST_INTERRUPT_MASK, 0); ++ return 0; ++} ++ ++int lima_bcast_reset(struct lima_ip *ip) ++{ ++ return lima_bcast_hw_init(ip); ++} ++ + int lima_bcast_init(struct lima_ip *ip) + { + int i; +diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h +index 465ee587bceb2..cd08841e47879 100644 +--- a/drivers/gpu/drm/lima/lima_bcast.h ++++ b/drivers/gpu/drm/lima/lima_bcast.h +@@ -13,4 +13,7 @@ void lima_bcast_fini(struct lima_ip *ip); + + void lima_bcast_enable(struct lima_device *dev, int num_pp); + ++int lima_bcast_mask_irq(struct lima_ip *ip); ++int lima_bcast_reset(struct lima_ip *ip); ++ + #endif +diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c +index 6b354e2fb61d4..e15295071533b 100644 +--- a/drivers/gpu/drm/lima/lima_gp.c ++++ b/drivers/gpu/drm/lima/lima_gp.c +@@ -233,6 +233,13 @@ static void lima_gp_task_mmu_error(struct lima_sched_pipe *pipe) + lima_sched_pipe_task_done(pipe); + } + ++static void lima_gp_task_mask_irq(struct lima_sched_pipe *pipe) ++{ ++ struct lima_ip *ip = pipe->processor[0]; ++ ++ gp_write(LIMA_GP_INT_MASK, 0); ++} ++ + static int lima_gp_task_recover(struct lima_sched_pipe *pipe) + { + struct lima_ip *ip = pipe->processor[0]; +@@ -365,6 +372,7 @@ int lima_gp_pipe_init(struct lima_device *dev) + pipe->task_error = lima_gp_task_error; + pipe->task_mmu_error = lima_gp_task_mmu_error; + pipe->task_recover = lima_gp_task_recover; ++ pipe->task_mask_irq = lima_gp_task_mask_irq; + + return 0; + } +diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c +index d0d2db0ef1ce8..a4a2ffe6527c2 100644 +--- a/drivers/gpu/drm/lima/lima_pp.c ++++ b/drivers/gpu/drm/lima/lima_pp.c +@@ -429,6 +429,9 @@ static void lima_pp_task_error(struct lima_sched_pipe *pipe) + + lima_pp_hard_reset(ip); + } ++ ++ if (pipe->bcast_processor) ++ lima_bcast_reset(pipe->bcast_processor); + } + + static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe) +@@ -437,6 +440,20 @@ static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe) + lima_sched_pipe_task_done(pipe); + } + ++static void lima_pp_task_mask_irq(struct lima_sched_pipe *pipe) ++{ ++ int i; ++ ++ for (i = 0; i < pipe->num_processor; i++) { ++ struct lima_ip *ip = pipe->processor[i]; ++ ++ pp_write(LIMA_PP_INT_MASK, 0); ++ } ++ ++ if (pipe->bcast_processor) ++ lima_bcast_mask_irq(pipe->bcast_processor); ++} ++ + static struct kmem_cache *lima_pp_task_slab; + static int lima_pp_task_slab_refcnt; + +@@ -468,6 +485,7 @@ int lima_pp_pipe_init(struct lima_device *dev) + pipe->task_fini = lima_pp_task_fini; + pipe->task_error = lima_pp_task_error; + pipe->task_mmu_error = lima_pp_task_mmu_error; ++ pipe->task_mask_irq = lima_pp_task_mask_irq; + + return 0; + } +diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c +index 00b19adfc8881..bbf3f8feab944 100644 +--- a/drivers/gpu/drm/lima/lima_sched.c ++++ b/drivers/gpu/drm/lima/lima_sched.c +@@ -422,12 +422,21 @@ static enum drm_gpu_sched_stat lima_sched_timedout_job(struct drm_sched_job *job + */ + for (i = 0; i < pipe->num_processor; i++) + synchronize_irq(pipe->processor[i]->irq); ++ if (pipe->bcast_processor) ++ synchronize_irq(pipe->bcast_processor->irq); + + if (dma_fence_is_signaled(task->fence)) { + DRM_WARN("%s unexpectedly high interrupt latency\n", lima_ip_name(ip)); + return DRM_GPU_SCHED_STAT_NOMINAL; + } + ++ /* ++ * The task might still finish while this timeout handler runs. ++ * To prevent a race condition on its completion, mask all irqs ++ * on the running core until the next hard reset completes. ++ */ ++ pipe->task_mask_irq(pipe); ++ + if (!pipe->error) + DRM_ERROR("%s job timeout\n", lima_ip_name(ip)); + +diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h +index 6bd4f3b701091..85b23ba901d53 100644 +--- a/drivers/gpu/drm/lima/lima_sched.h ++++ b/drivers/gpu/drm/lima/lima_sched.h +@@ -80,6 +80,7 @@ struct lima_sched_pipe { + void (*task_error)(struct lima_sched_pipe *pipe); + void (*task_mmu_error)(struct lima_sched_pipe *pipe); + int (*task_recover)(struct lima_sched_pipe *pipe); ++ void (*task_mask_irq)(struct lima_sched_pipe *pipe); + + struct work_struct recover_work; + }; +diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c +index 21d27e6235f39..b11f7c5bbcbe9 100644 +--- a/drivers/gpu/drm/radeon/sumo_dpm.c ++++ b/drivers/gpu/drm/radeon/sumo_dpm.c +@@ -1619,6 +1619,8 @@ void sumo_construct_vid_mapping_table(struct radeon_device *rdev, + + for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) { + if (table[i].ulSupportedSCLK != 0) { ++ if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES) ++ continue; + vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit = + table[i].usVoltageID; + vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit = +diff --git a/drivers/gpu/drm/xe/xe_guc.c b/drivers/gpu/drm/xe/xe_guc.c +index 0d2a2dd13f112..a38f59b4356d4 100644 +--- a/drivers/gpu/drm/xe/xe_guc.c ++++ b/drivers/gpu/drm/xe/xe_guc.c +@@ -643,8 +643,6 @@ int xe_guc_enable_communication(struct xe_guc *guc) + struct xe_device *xe = guc_to_xe(guc); + int err; + +- guc_enable_irq(guc); +- + if (IS_SRIOV_VF(xe) && xe_device_has_memirq(xe)) { + struct xe_gt *gt = guc_to_gt(guc); + struct xe_tile *tile = gt_to_tile(gt); +@@ -652,6 +650,8 @@ int xe_guc_enable_communication(struct xe_guc *guc) + err = xe_memirq_init_guc(&tile->sriov.vf.memirq, guc); + if (err) + return err; ++ } else { ++ guc_enable_irq(guc); + } + + xe_mmio_rmw32(guc_to_gt(guc), PMINTRMSK, +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index 78cdfb8b9a7ae..88cbb2fe6ac8c 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -335,36 +335,20 @@ static int asus_raw_event(struct hid_device *hdev, + if (drvdata->quirks & QUIRK_MEDION_E1239T) + return asus_e1239t_event(drvdata, data, size); + +- if (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) { ++ /* ++ * Skip these report ID, the device emits a continuous stream associated ++ * with the AURA mode it is in which looks like an 'echo'. ++ */ ++ if (report->id == FEATURE_KBD_LED_REPORT_ID1 || report->id == FEATURE_KBD_LED_REPORT_ID2) ++ return -1; ++ if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) { + /* +- * Skip these report ID, the device emits a continuous stream associated +- * with the AURA mode it is in which looks like an 'echo'. ++ * G713 and G733 send these codes on some keypresses, depending on ++ * the key pressed it can trigger a shutdown event if not caught. + */ +- if (report->id == FEATURE_KBD_LED_REPORT_ID1 || +- report->id == FEATURE_KBD_LED_REPORT_ID2) { ++ if (data[0] == 0x02 && data[1] == 0x30) { + return -1; +- /* Additional report filtering */ +- } else if (report->id == FEATURE_KBD_REPORT_ID) { +- /* +- * G14 and G15 send these codes on some keypresses with no +- * discernable reason for doing so. We'll filter them out to avoid +- * unmapped warning messages later. +- */ +- if (data[1] == 0xea || data[1] == 0xec || data[1] == 0x02 || +- data[1] == 0x8a || data[1] == 0x9e) { +- return -1; +- } +- } +- if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) { +- /* +- * G713 and G733 send these codes on some keypresses, depending on +- * the key pressed it can trigger a shutdown event if not caught. +- */ +- if(data[0] == 0x02 && data[1] == 0x30) { +- return -1; +- } + } +- + } + + if (drvdata->quirks & QUIRK_ROG_CLAYMORE_II_KEYBOARD) { +@@ -1250,6 +1234,19 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, + rdesc[205] = 0x01; + } + ++ /* match many more n-key devices */ ++ if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD && *rsize > 15) { ++ for (int i = 0; i < *rsize - 15; i++) { ++ /* offset to the count from 0x5a report part always 14 */ ++ if (rdesc[i] == 0x85 && rdesc[i + 1] == 0x5a && ++ rdesc[i + 14] == 0x95 && rdesc[i + 15] == 0x05) { ++ hid_info(hdev, "Fixing up Asus N-Key report descriptor\n"); ++ rdesc[i + 15] = 0x01; ++ break; ++ } ++ } ++ } ++ + return rdesc; + } + +@@ -1319,4 +1316,4 @@ static struct hid_driver asus_driver = { + }; + module_hid_driver(asus_driver); + +-MODULE_LICENSE("GPL"); +\ No newline at end of file ++MODULE_LICENSE("GPL"); +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 8376fb5e2d0b4..68b0f39deaa9a 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -823,6 +823,7 @@ + #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e + #define USB_DEVICE_ID_LOGITECH_T651 0xb00c + #define USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD 0xb309 ++#define USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD 0xbb00 + #define USB_DEVICE_ID_LOGITECH_C007 0xc007 + #define USB_DEVICE_ID_LOGITECH_C077 0xc077 + #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 04a014cd2a2f6..56fc78841f245 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -2081,6 +2081,12 @@ static const struct hid_device_id mt_devices[] = { + USB_VENDOR_ID_LENOVO, + USB_DEVICE_ID_LENOVO_X12_TAB) }, + ++ /* Logitech devices */ ++ { .driver_data = MT_CLS_NSMU, ++ HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8, ++ USB_VENDOR_ID_LOGITECH, ++ USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD) }, ++ + /* MosArt panels */ + { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, + MT_USB_DEVICE(USB_VENDOR_ID_ASUS, +diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c +index 6d72e4e126dde..36e8f6196a87b 100644 +--- a/drivers/i2c/busses/i2c-imx-lpi2c.c ++++ b/drivers/i2c/busses/i2c-imx-lpi2c.c +@@ -99,6 +99,7 @@ struct lpi2c_imx_struct { + __u8 *rx_buf; + __u8 *tx_buf; + struct completion complete; ++ unsigned long rate_per; + unsigned int msglen; + unsigned int delivered; + unsigned int block_data; +@@ -212,9 +213,7 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx) + + lpi2c_imx_set_mode(lpi2c_imx); + +- clk_rate = clk_get_rate(lpi2c_imx->clks[0].clk); +- if (!clk_rate) +- return -EINVAL; ++ clk_rate = lpi2c_imx->rate_per; + + if (lpi2c_imx->mode == HS || lpi2c_imx->mode == ULTRA_FAST) + filt = 0; +@@ -611,6 +610,20 @@ static int lpi2c_imx_probe(struct platform_device *pdev) + if (ret) + return ret; + ++ /* ++ * Lock the parent clock rate to avoid getting parent clock upon ++ * each transfer ++ */ ++ ret = devm_clk_rate_exclusive_get(&pdev->dev, lpi2c_imx->clks[0].clk); ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, ++ "can't lock I2C peripheral clock rate\n"); ++ ++ lpi2c_imx->rate_per = clk_get_rate(lpi2c_imx->clks[0].clk); ++ if (!lpi2c_imx->rate_per) ++ return dev_err_probe(&pdev->dev, -EINVAL, ++ "can't get I2C peripheral clock rate\n"); ++ + pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_get_noresume(&pdev->dev); +diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c +index e106af83cef4d..350ccfbe86340 100644 +--- a/drivers/i2c/busses/i2c-ocores.c ++++ b/drivers/i2c/busses/i2c-ocores.c +@@ -442,8 +442,8 @@ static int ocores_init(struct device *dev, struct ocores_i2c *i2c) + oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); + + /* Init the device */ +- oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN); ++ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); + + return 0; + } +diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h +index 9dca451ed5221..6974922e5609a 100644 +--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h ++++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h +@@ -107,8 +107,6 @@ struct bnxt_re_gsi_context { + struct bnxt_re_sqp_entries *sqp_tbl; + }; + +-#define BNXT_RE_MIN_MSIX 2 +-#define BNXT_RE_MAX_MSIX 9 + #define BNXT_RE_AEQ_IDX 0 + #define BNXT_RE_NQ_IDX 1 + #define BNXT_RE_GEN_P5_MAX_VF 64 +@@ -168,7 +166,7 @@ struct bnxt_re_dev { + struct bnxt_qplib_rcfw rcfw; + + /* NQ */ +- struct bnxt_qplib_nq nq[BNXT_RE_MAX_MSIX]; ++ struct bnxt_qplib_nq nq[BNXT_MAX_ROCE_MSIX]; + + /* Device Resources */ + struct bnxt_qplib_dev_attr dev_attr; +diff --git a/drivers/infiniband/hw/mana/mr.c b/drivers/infiniband/hw/mana/mr.c +index b70b13484f097..13a49d8fd49d5 100644 +--- a/drivers/infiniband/hw/mana/mr.c ++++ b/drivers/infiniband/hw/mana/mr.c +@@ -112,6 +112,7 @@ struct ib_mr *mana_ib_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 length, + "start 0x%llx, iova 0x%llx length 0x%llx access_flags 0x%x", + start, iova, length, access_flags); + ++ access_flags &= ~IB_ACCESS_OPTIONAL; + if (access_flags & ~VALID_MR_FLAGS) + return ERR_PTR(-EINVAL); + +diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c +index c2b557e642906..9fb8a544236d7 100644 +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -3760,10 +3760,10 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev) + spin_lock_init(&dev->dm.lock); + dev->dm.dev = mdev; + return 0; +-err: +- mlx5r_macsec_dealloc_gids(dev); + err_mp: + mlx5_ib_cleanup_multiport_master(dev); ++err: ++ mlx5r_macsec_dealloc_gids(dev); + return err; + } + +diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c +index ecc111ed5d86e..d3c1f63791a2b 100644 +--- a/drivers/infiniband/hw/mlx5/mr.c ++++ b/drivers/infiniband/hw/mlx5/mr.c +@@ -246,6 +246,7 @@ static void set_cache_mkc(struct mlx5_cache_ent *ent, void *mkc) + MLX5_SET(mkc, mkc, access_mode_1_0, ent->rb_key.access_mode & 0x3); + MLX5_SET(mkc, mkc, access_mode_4_2, + (ent->rb_key.access_mode >> 2) & 0x7); ++ MLX5_SET(mkc, mkc, ma_translation_mode, !!ent->rb_key.ats); + + MLX5_SET(mkc, mkc, translations_octword_size, + get_mkc_octo_size(ent->rb_key.access_mode, +@@ -641,10 +642,8 @@ static int mlx5_cache_ent_insert(struct mlx5_mkey_cache *cache, + new = &((*new)->rb_left); + if (cmp < 0) + new = &((*new)->rb_right); +- if (cmp == 0) { +- mutex_unlock(&cache->rb_lock); ++ if (cmp == 0) + return -EEXIST; +- } + } + + /* Add new node and rebalance tree. */ +@@ -719,6 +718,8 @@ static struct mlx5_ib_mr *_mlx5_mr_cache_alloc(struct mlx5_ib_dev *dev, + } + mr->mmkey.cache_ent = ent; + mr->mmkey.type = MLX5_MKEY_MR; ++ mr->mmkey.rb_key = ent->rb_key; ++ mr->mmkey.cacheable = true; + init_waitqueue_head(&mr->mmkey.wait); + return mr; + } +@@ -1169,7 +1170,6 @@ static struct mlx5_ib_mr *alloc_cacheable_mr(struct ib_pd *pd, + mr->ibmr.pd = pd; + mr->umem = umem; + mr->page_shift = order_base_2(page_size); +- mr->mmkey.cacheable = true; + set_mr_fields(dev, mr, umem->length, access_flags, iova); + + return mr; +diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c +index a056ea835da54..84be0c3d56995 100644 +--- a/drivers/infiniband/hw/mlx5/srq.c ++++ b/drivers/infiniband/hw/mlx5/srq.c +@@ -199,17 +199,20 @@ int mlx5_ib_create_srq(struct ib_srq *ib_srq, + int err; + struct mlx5_srq_attr in = {}; + __u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz); ++ __u32 max_sge_sz = MLX5_CAP_GEN(dev->mdev, max_wqe_sz_rq) / ++ sizeof(struct mlx5_wqe_data_seg); + + if (init_attr->srq_type != IB_SRQT_BASIC && + init_attr->srq_type != IB_SRQT_XRC && + init_attr->srq_type != IB_SRQT_TM) + return -EOPNOTSUPP; + +- /* Sanity check SRQ size before proceeding */ +- if (init_attr->attr.max_wr >= max_srq_wqes) { +- mlx5_ib_dbg(dev, "max_wr %d, cap %d\n", +- init_attr->attr.max_wr, +- max_srq_wqes); ++ /* Sanity check SRQ and sge size before proceeding */ ++ if (init_attr->attr.max_wr >= max_srq_wqes || ++ init_attr->attr.max_sge > max_sge_sz) { ++ mlx5_ib_dbg(dev, "max_wr %d,wr_cap %d,max_sge %d, sge_cap:%d\n", ++ init_attr->attr.max_wr, max_srq_wqes, ++ init_attr->attr.max_sge, max_sge_sz); + return -EINVAL; + } + +diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c +index 963382f625d71..fa2b87c749292 100644 +--- a/drivers/infiniband/sw/rxe/rxe_resp.c ++++ b/drivers/infiniband/sw/rxe/rxe_resp.c +@@ -354,6 +354,19 @@ static enum resp_states rxe_resp_check_length(struct rxe_qp *qp, + * receive buffer later. For rmda operations additional + * length checks are performed in check_rkey. + */ ++ if ((qp_type(qp) == IB_QPT_GSI) || (qp_type(qp) == IB_QPT_UD)) { ++ unsigned int payload = payload_size(pkt); ++ unsigned int recv_buffer_len = 0; ++ int i; ++ ++ for (i = 0; i < qp->resp.wqe->dma.num_sge; i++) ++ recv_buffer_len += qp->resp.wqe->dma.sge[i].length; ++ if (payload + 40 > recv_buffer_len) { ++ rxe_dbg_qp(qp, "The receive buffer is too small for this UD packet.\n"); ++ return RESPST_ERR_LENGTH; ++ } ++ } ++ + if (pkt->mask & RXE_PAYLOAD_MASK && ((qp_type(qp) == IB_QPT_RC) || + (qp_type(qp) == IB_QPT_UC))) { + unsigned int mtu = qp->mtu; +diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c +index a49784e5156c5..a7e9510666e23 100644 +--- a/drivers/infiniband/sw/rxe/rxe_verbs.c ++++ b/drivers/infiniband/sw/rxe/rxe_verbs.c +@@ -812,7 +812,7 @@ static void copy_inline_data_to_wqe(struct rxe_send_wqe *wqe, + int i; + + for (i = 0; i < ibwr->num_sge; i++, sge++) { +- memcpy(p, ib_virt_dma_to_page(sge->addr), sge->length); ++ memcpy(p, ib_virt_dma_to_ptr(sge->addr), sge->length); + p += sge->length; + } + } +diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +index 41f93c3ab160d..3afec8714cf28 100644 +--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c ++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +@@ -3402,7 +3402,7 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu) + smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX); + + /* Add callback to free MSIs on teardown */ +- devm_add_action(dev, arm_smmu_free_msis, dev); ++ devm_add_action_or_reset(dev, arm_smmu_free_msis, dev); + } + + static void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu) +diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c +index e994db4f4d914..61750cc98d705 100644 +--- a/drivers/media/pci/intel/ipu-bridge.c ++++ b/drivers/media/pci/intel/ipu-bridge.c +@@ -15,6 +15,8 @@ + #include <media/ipu-bridge.h> + #include <media/v4l2-fwnode.h> + ++#define ADEV_DEV(adev) ACPI_PTR(&((adev)->dev)) ++ + /* + * 92335fcf-3203-4472-af93-7b4453ac29da + * +@@ -87,6 +89,7 @@ static const char * const ipu_vcm_types[] = { + "lc898212axb", + }; + ++#if IS_ENABLED(CONFIG_ACPI) + /* + * Used to figure out IVSC acpi device by ipu_bridge_get_ivsc_acpi_dev() + * instead of device and driver match to probe IVSC device. +@@ -100,13 +103,13 @@ static const struct acpi_device_id ivsc_acpi_ids[] = { + + static struct acpi_device *ipu_bridge_get_ivsc_acpi_dev(struct acpi_device *adev) + { +- acpi_handle handle = acpi_device_handle(adev); +- struct acpi_device *consumer, *ivsc_adev; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(ivsc_acpi_ids); i++) { + const struct acpi_device_id *acpi_id = &ivsc_acpi_ids[i]; ++ struct acpi_device *consumer, *ivsc_adev; + ++ acpi_handle handle = acpi_device_handle(adev); + for_each_acpi_dev_match(ivsc_adev, acpi_id->id, NULL, -1) + /* camera sensor depends on IVSC in DSDT if exist */ + for_each_acpi_consumer_dev(ivsc_adev, consumer) +@@ -118,6 +121,12 @@ static struct acpi_device *ipu_bridge_get_ivsc_acpi_dev(struct acpi_device *adev + + return NULL; + } ++#else ++static struct acpi_device *ipu_bridge_get_ivsc_acpi_dev(struct acpi_device *adev) ++{ ++ return NULL; ++} ++#endif + + static int ipu_bridge_match_ivsc_dev(struct device *dev, const void *adev) + { +@@ -163,7 +172,7 @@ static int ipu_bridge_check_ivsc_dev(struct ipu_sensor *sensor, + csi_dev = ipu_bridge_get_ivsc_csi_dev(adev); + if (!csi_dev) { + acpi_dev_put(adev); +- dev_err(&adev->dev, "Failed to find MEI CSI dev\n"); ++ dev_err(ADEV_DEV(adev), "Failed to find MEI CSI dev\n"); + return -ENODEV; + } + +@@ -182,24 +191,25 @@ static int ipu_bridge_read_acpi_buffer(struct acpi_device *adev, char *id, + acpi_status status; + int ret = 0; + +- status = acpi_evaluate_object(adev->handle, id, NULL, &buffer); ++ status = acpi_evaluate_object(ACPI_PTR(adev->handle), ++ id, NULL, &buffer); + if (ACPI_FAILURE(status)) + return -ENODEV; + + obj = buffer.pointer; + if (!obj) { +- dev_err(&adev->dev, "Couldn't locate ACPI buffer\n"); ++ dev_err(ADEV_DEV(adev), "Couldn't locate ACPI buffer\n"); + return -ENODEV; + } + + if (obj->type != ACPI_TYPE_BUFFER) { +- dev_err(&adev->dev, "Not an ACPI buffer\n"); ++ dev_err(ADEV_DEV(adev), "Not an ACPI buffer\n"); + ret = -ENODEV; + goto out_free_buff; + } + + if (obj->buffer.length > size) { +- dev_err(&adev->dev, "Given buffer is too small\n"); ++ dev_err(ADEV_DEV(adev), "Given buffer is too small\n"); + ret = -EINVAL; + goto out_free_buff; + } +@@ -220,7 +230,7 @@ static u32 ipu_bridge_parse_rotation(struct acpi_device *adev, + case IPU_SENSOR_ROTATION_INVERTED: + return 180; + default: +- dev_warn(&adev->dev, ++ dev_warn(ADEV_DEV(adev), + "Unknown rotation %d. Assume 0 degree rotation\n", + ssdb->degree); + return 0; +@@ -230,12 +240,14 @@ static u32 ipu_bridge_parse_rotation(struct acpi_device *adev, + static enum v4l2_fwnode_orientation ipu_bridge_parse_orientation(struct acpi_device *adev) + { + enum v4l2_fwnode_orientation orientation; +- struct acpi_pld_info *pld; +- acpi_status status; ++ struct acpi_pld_info *pld = NULL; ++ acpi_status status = AE_ERROR; + ++#if IS_ENABLED(CONFIG_ACPI) + status = acpi_get_physical_device_location(adev->handle, &pld); ++#endif + if (ACPI_FAILURE(status)) { +- dev_warn(&adev->dev, "_PLD call failed, using default orientation\n"); ++ dev_warn(ADEV_DEV(adev), "_PLD call failed, using default orientation\n"); + return V4L2_FWNODE_ORIENTATION_EXTERNAL; + } + +@@ -253,7 +265,8 @@ static enum v4l2_fwnode_orientation ipu_bridge_parse_orientation(struct acpi_dev + orientation = V4L2_FWNODE_ORIENTATION_EXTERNAL; + break; + default: +- dev_warn(&adev->dev, "Unknown _PLD panel val %d\n", pld->panel); ++ dev_warn(ADEV_DEV(adev), "Unknown _PLD panel val %d\n", ++ pld->panel); + orientation = V4L2_FWNODE_ORIENTATION_EXTERNAL; + break; + } +@@ -272,12 +285,12 @@ int ipu_bridge_parse_ssdb(struct acpi_device *adev, struct ipu_sensor *sensor) + return ret; + + if (ssdb.vcmtype > ARRAY_SIZE(ipu_vcm_types)) { +- dev_warn(&adev->dev, "Unknown VCM type %d\n", ssdb.vcmtype); ++ dev_warn(ADEV_DEV(adev), "Unknown VCM type %d\n", ssdb.vcmtype); + ssdb.vcmtype = 0; + } + + if (ssdb.lanes > IPU_MAX_LANES) { +- dev_err(&adev->dev, "Number of lanes in SSDB is invalid\n"); ++ dev_err(ADEV_DEV(adev), "Number of lanes in SSDB is invalid\n"); + return -EINVAL; + } + +@@ -465,8 +478,14 @@ static void ipu_bridge_create_connection_swnodes(struct ipu_bridge *bridge, + sensor->ipu_properties); + + if (sensor->csi_dev) { ++ const char *device_hid = ""; ++ ++#if IS_ENABLED(CONFIG_ACPI) ++ device_hid = acpi_device_hid(sensor->ivsc_adev); ++#endif ++ + snprintf(sensor->ivsc_name, sizeof(sensor->ivsc_name), "%s-%u", +- acpi_device_hid(sensor->ivsc_adev), sensor->link); ++ device_hid, sensor->link); + + nodes[SWNODE_IVSC_HID] = NODE_SENSOR(sensor->ivsc_name, + sensor->ivsc_properties); +@@ -631,11 +650,15 @@ static int ipu_bridge_connect_sensor(const struct ipu_sensor_config *cfg, + { + struct fwnode_handle *fwnode, *primary; + struct ipu_sensor *sensor; +- struct acpi_device *adev; ++ struct acpi_device *adev = NULL; + int ret; + ++#if IS_ENABLED(CONFIG_ACPI) + for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) { +- if (!adev->status.enabled) ++#else ++ while (true) { ++#endif ++ if (!ACPI_PTR(adev->status.enabled)) + continue; + + if (bridge->n_sensors >= IPU_MAX_PORTS) { +@@ -671,7 +694,7 @@ static int ipu_bridge_connect_sensor(const struct ipu_sensor_config *cfg, + goto err_free_swnodes; + } + +- sensor->adev = acpi_dev_get(adev); ++ sensor->adev = ACPI_PTR(acpi_dev_get(adev)); + + primary = acpi_fwnode_handle(adev); + primary->secondary = fwnode; +@@ -727,11 +750,16 @@ static int ipu_bridge_ivsc_is_ready(void) + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(ipu_supported_sensors); i++) { ++#if IS_ENABLED(CONFIG_ACPI) + const struct ipu_sensor_config *cfg = + &ipu_supported_sensors[i]; + + for_each_acpi_dev_match(sensor_adev, cfg->hid, NULL, -1) { +- if (!sensor_adev->status.enabled) ++#else ++ while (true) { ++ sensor_adev = NULL; ++#endif ++ if (!ACPI_PTR(sensor_adev->status.enabled)) + continue; + + adev = ipu_bridge_get_ivsc_acpi_dev(sensor_adev); +diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c +index 6bbe55de6ce9a..ff23b225db705 100644 +--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c ++++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c +@@ -79,6 +79,8 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(void *priv, enum mtk_vcodec_fw_use + } + + fw = devm_kzalloc(&plat_dev->dev, sizeof(*fw), GFP_KERNEL); ++ if (!fw) ++ return ERR_PTR(-ENOMEM); + fw->type = SCP; + fw->ops = &mtk_vcodec_rproc_msg; + fw->scp = scp; +diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c +index e10ae94cf7711..5ccb1a3a149d8 100644 +--- a/drivers/net/dsa/realtek/rtl8366rb.c ++++ b/drivers/net/dsa/realtek/rtl8366rb.c +@@ -185,7 +185,12 @@ + #define RTL8366RB_LED_BLINKRATE_222MS 0x0004 + #define RTL8366RB_LED_BLINKRATE_446MS 0x0005 + ++/* LED trigger event for each group */ + #define RTL8366RB_LED_CTRL_REG 0x0431 ++#define RTL8366RB_LED_CTRL_OFFSET(led_group) \ ++ (4 * (led_group)) ++#define RTL8366RB_LED_CTRL_MASK(led_group) \ ++ (0xf << RTL8366RB_LED_CTRL_OFFSET(led_group)) + #define RTL8366RB_LED_OFF 0x0 + #define RTL8366RB_LED_DUP_COL 0x1 + #define RTL8366RB_LED_LINK_ACT 0x2 +@@ -202,6 +207,11 @@ + #define RTL8366RB_LED_LINK_TX 0xd + #define RTL8366RB_LED_MASTER 0xe + #define RTL8366RB_LED_FORCE 0xf ++ ++/* The RTL8366RB_LED_X_X registers are used to manually set the LED state only ++ * when the corresponding LED group in RTL8366RB_LED_CTRL_REG is ++ * RTL8366RB_LED_FORCE. Otherwise, it is ignored. ++ */ + #define RTL8366RB_LED_0_1_CTRL_REG 0x0432 + #define RTL8366RB_LED_1_OFFSET 6 + #define RTL8366RB_LED_2_3_CTRL_REG 0x0433 +@@ -1001,28 +1011,20 @@ static int rtl8366rb_setup(struct dsa_switch *ds) + */ + if (priv->leds_disabled) { + /* Turn everything off */ +- regmap_update_bits(priv->map, +- RTL8366RB_LED_0_1_CTRL_REG, +- 0x0FFF, 0); +- regmap_update_bits(priv->map, +- RTL8366RB_LED_2_3_CTRL_REG, +- 0x0FFF, 0); + regmap_update_bits(priv->map, + RTL8366RB_INTERRUPT_CONTROL_REG, + RTL8366RB_P4_RGMII_LED, + 0); +- val = RTL8366RB_LED_OFF; +- } else { +- /* TODO: make this configurable per LED */ +- val = RTL8366RB_LED_FORCE; +- } +- for (i = 0; i < 4; i++) { +- ret = regmap_update_bits(priv->map, +- RTL8366RB_LED_CTRL_REG, +- 0xf << (i * 4), +- val << (i * 4)); +- if (ret) +- return ret; ++ ++ for (i = 0; i < RTL8366RB_NUM_LEDGROUPS; i++) { ++ val = RTL8366RB_LED_OFF << RTL8366RB_LED_CTRL_OFFSET(i); ++ ret = regmap_update_bits(priv->map, ++ RTL8366RB_LED_CTRL_REG, ++ RTL8366RB_LED_CTRL_MASK(i), ++ val); ++ if (ret) ++ return ret; ++ } + } + + ret = rtl8366_reset_vlan(priv); +@@ -1167,52 +1169,6 @@ rtl8366rb_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, + } + } + +-static void rb8366rb_set_port_led(struct realtek_priv *priv, +- int port, bool enable) +-{ +- u16 val = enable ? 0x3f : 0; +- int ret; +- +- if (priv->leds_disabled) +- return; +- +- switch (port) { +- case 0: +- ret = regmap_update_bits(priv->map, +- RTL8366RB_LED_0_1_CTRL_REG, +- 0x3F, val); +- break; +- case 1: +- ret = regmap_update_bits(priv->map, +- RTL8366RB_LED_0_1_CTRL_REG, +- 0x3F << RTL8366RB_LED_1_OFFSET, +- val << RTL8366RB_LED_1_OFFSET); +- break; +- case 2: +- ret = regmap_update_bits(priv->map, +- RTL8366RB_LED_2_3_CTRL_REG, +- 0x3F, val); +- break; +- case 3: +- ret = regmap_update_bits(priv->map, +- RTL8366RB_LED_2_3_CTRL_REG, +- 0x3F << RTL8366RB_LED_3_OFFSET, +- val << RTL8366RB_LED_3_OFFSET); +- break; +- case 4: +- ret = regmap_update_bits(priv->map, +- RTL8366RB_INTERRUPT_CONTROL_REG, +- RTL8366RB_P4_RGMII_LED, +- enable ? RTL8366RB_P4_RGMII_LED : 0); +- break; +- default: +- dev_err(priv->dev, "no LED for port %d\n", port); +- return; +- } +- if (ret) +- dev_err(priv->dev, "error updating LED on port %d\n", port); +-} +- + static int + rtl8366rb_port_enable(struct dsa_switch *ds, int port, + struct phy_device *phy) +@@ -1226,7 +1182,6 @@ rtl8366rb_port_enable(struct dsa_switch *ds, int port, + if (ret) + return ret; + +- rb8366rb_set_port_led(priv, port, true); + return 0; + } + +@@ -1241,8 +1196,6 @@ rtl8366rb_port_disable(struct dsa_switch *ds, int port) + BIT(port)); + if (ret) + return; +- +- rb8366rb_set_port_led(priv, port, false); + } + + static int +diff --git a/drivers/net/dsa/realtek/rtl83xx.c b/drivers/net/dsa/realtek/rtl83xx.c +index d2e876805393b..a9c1702431efb 100644 +--- a/drivers/net/dsa/realtek/rtl83xx.c ++++ b/drivers/net/dsa/realtek/rtl83xx.c +@@ -290,16 +290,13 @@ EXPORT_SYMBOL_NS_GPL(rtl83xx_shutdown, REALTEK_DSA); + * rtl83xx_remove() - Cleanup a realtek switch driver + * @priv: realtek_priv pointer + * +- * If a method is provided, this function asserts the hard reset of the switch +- * in order to avoid leaking traffic when the driver is gone. ++ * Placehold for common cleanup procedures. + * +- * Context: Might sleep if priv->gdev->chip->can_sleep. ++ * Context: Any + * Return: nothing + */ + void rtl83xx_remove(struct realtek_priv *priv) + { +- /* leave the device reset asserted */ +- rtl83xx_reset_assert(priv); + } + EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, REALTEK_DSA); + +diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.c b/drivers/net/ethernet/amazon/ena/ena_eth_com.c +index 933e619b3a313..4c6e07aa4bbb5 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.c ++++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.c +@@ -229,30 +229,43 @@ static struct ena_eth_io_rx_cdesc_base * + idx * io_cq->cdesc_entry_size_in_bytes); + } + +-static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq, +- u16 *first_cdesc_idx) ++static int ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq, ++ u16 *first_cdesc_idx, ++ u16 *num_descs) + { ++ u16 count = io_cq->cur_rx_pkt_cdesc_count, head_masked; + struct ena_eth_io_rx_cdesc_base *cdesc; +- u16 count = 0, head_masked; + u32 last = 0; + + do { ++ u32 status; ++ + cdesc = ena_com_get_next_rx_cdesc(io_cq); + if (!cdesc) + break; ++ status = READ_ONCE(cdesc->status); + + ena_com_cq_inc_head(io_cq); ++ if (unlikely((status & ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK) >> ++ ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT && count != 0)) { ++ struct ena_com_dev *dev = ena_com_io_cq_to_ena_dev(io_cq); ++ ++ netdev_err(dev->net_device, ++ "First bit is on in descriptor #%d on q_id: %d, req_id: %u\n", ++ count, io_cq->qid, cdesc->req_id); ++ return -EFAULT; ++ } + count++; +- last = (READ_ONCE(cdesc->status) & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >> +- ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT; ++ last = (status & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >> ++ ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT; + } while (!last); + + if (last) { + *first_cdesc_idx = io_cq->cur_rx_pkt_cdesc_start_idx; +- count += io_cq->cur_rx_pkt_cdesc_count; + + head_masked = io_cq->head & (io_cq->q_depth - 1); + ++ *num_descs = count; + io_cq->cur_rx_pkt_cdesc_count = 0; + io_cq->cur_rx_pkt_cdesc_start_idx = head_masked; + +@@ -260,11 +273,11 @@ static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq, + "ENA q_id: %d packets were completed. first desc idx %u descs# %d\n", + io_cq->qid, *first_cdesc_idx, count); + } else { +- io_cq->cur_rx_pkt_cdesc_count += count; +- count = 0; ++ io_cq->cur_rx_pkt_cdesc_count = count; ++ *num_descs = 0; + } + +- return count; ++ return 0; + } + + static int ena_com_create_meta(struct ena_com_io_sq *io_sq, +@@ -539,10 +552,14 @@ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq, + u16 cdesc_idx = 0; + u16 nb_hw_desc; + u16 i = 0; ++ int rc; + + WARN(io_cq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type"); + +- nb_hw_desc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx); ++ rc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx, &nb_hw_desc); ++ if (unlikely(rc != 0)) ++ return -EFAULT; ++ + if (nb_hw_desc == 0) { + ena_rx_ctx->descs = nb_hw_desc; + return 0; +diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c +index be5acfa41ee0c..8db05f7544f90 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -1347,6 +1347,8 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi, + if (rc == -ENOSPC) { + ena_increase_stat(&rx_ring->rx_stats.bad_desc_num, 1, &rx_ring->syncp); + ena_reset_device(adapter, ENA_REGS_RESET_TOO_MANY_RX_DESCS); ++ } else if (rc == -EFAULT) { ++ ena_reset_device(adapter, ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED); + } else { + ena_increase_stat(&rx_ring->rx_stats.bad_req_id, 1, + &rx_ring->syncp); +diff --git a/drivers/net/ethernet/amazon/ena/ena_regs_defs.h b/drivers/net/ethernet/amazon/ena/ena_regs_defs.h +index 2c3d6a77ea79f..a2efebafd686a 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_regs_defs.h ++++ b/drivers/net/ethernet/amazon/ena/ena_regs_defs.h +@@ -22,6 +22,7 @@ enum ena_regs_reset_reason_types { + ENA_REGS_RESET_GENERIC = 13, + ENA_REGS_RESET_MISS_INTERRUPT = 14, + ENA_REGS_RESET_SUSPECTED_POLL_STARVATION = 15, ++ ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED = 16, + }; + + /* ena_registers offsets */ +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 2c2ee79c4d779..0fab62a56f3b3 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -730,9 +730,6 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) + return NETDEV_TX_OK; + + tx_dma_error: +- if (BNXT_TX_PTP_IS_SET(lflags)) +- atomic_inc(&bp->ptp_cfg->tx_avail); +- + last_frag = i; + + /* start back at beginning and unmap skb */ +@@ -754,6 +751,8 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) + tx_free: + dev_kfree_skb_any(skb); + tx_kick_pending: ++ if (BNXT_TX_PTP_IS_SET(lflags)) ++ atomic_inc(&bp->ptp_cfg->tx_avail); + if (txr->kick_pending) + bnxt_txr_db_kick(bp, txr, txr->tx_prod); + txr->tx_buf_ring[txr->tx_prod].skb = NULL; +diff --git a/drivers/net/ethernet/intel/ice/ice_ddp.c b/drivers/net/ethernet/intel/ice/ice_ddp.c +index 4df561d64bc38..6e7d58243c7cb 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ddp.c ++++ b/drivers/net/ethernet/intel/ice/ice_ddp.c +@@ -1329,6 +1329,7 @@ ice_dwnld_cfg_bufs_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 start, + + for (i = 0; i < count; i++) { + bool last = false; ++ int try_cnt = 0; + int status; + + bh = (struct ice_buf_hdr *)(bufs + start + i); +@@ -1336,8 +1337,26 @@ ice_dwnld_cfg_bufs_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 start, + if (indicate_last) + last = ice_is_last_download_buffer(bh, i, count); + +- status = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE, last, +- &offset, &info, NULL); ++ while (1) { ++ status = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE, ++ last, &offset, &info, ++ NULL); ++ if (hw->adminq.sq_last_status != ICE_AQ_RC_ENOSEC && ++ hw->adminq.sq_last_status != ICE_AQ_RC_EBADSIG) ++ break; ++ ++ try_cnt++; ++ ++ if (try_cnt == 5) ++ break; ++ ++ msleep(20); ++ } ++ ++ if (try_cnt) ++ dev_dbg(ice_hw_to_dev(hw), ++ "ice_aq_download_pkg number of retries: %d\n", ++ try_cnt); + + /* Save AQ status from download package */ + if (status) { +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 10fef2e726b39..61eef3259cbaa 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -803,6 +803,9 @@ void ice_print_link_msg(struct ice_vsi *vsi, bool isup) + } + + switch (vsi->port_info->phy.link_info.link_speed) { ++ case ICE_AQ_LINK_SPEED_200GB: ++ speed = "200 G"; ++ break; + case ICE_AQ_LINK_SPEED_100GB: + speed = "100 G"; + break; +@@ -5451,7 +5454,7 @@ static int __maybe_unused ice_suspend(struct device *dev) + */ + disabled = ice_service_task_stop(pf); + +- ice_unplug_aux_dev(pf); ++ ice_deinit_rdma(pf); + + /* Already suspended?, then there is nothing to do */ + if (test_and_set_bit(ICE_SUSPENDED, pf->state)) { +@@ -5531,6 +5534,11 @@ static int __maybe_unused ice_resume(struct device *dev) + if (ret) + dev_err(dev, "Cannot restore interrupt scheme: %d\n", ret); + ++ ret = ice_init_rdma(pf); ++ if (ret) ++ dev_err(dev, "Reinitialize RDMA during resume failed: %d\n", ++ ret); ++ + clear_bit(ICE_DOWN, pf->state); + /* Now perform PF reset and rebuild */ + reset_type = ICE_RESET_PFR; +diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c +index b4ea935e83005..1472385eb68eb 100644 +--- a/drivers/net/ethernet/intel/ice/ice_switch.c ++++ b/drivers/net/ethernet/intel/ice/ice_switch.c +@@ -1825,7 +1825,8 @@ ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id, + lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || + lkup_type == ICE_SW_LKUP_PROMISC || + lkup_type == ICE_SW_LKUP_PROMISC_VLAN || +- lkup_type == ICE_SW_LKUP_DFLT) { ++ lkup_type == ICE_SW_LKUP_DFLT || ++ lkup_type == ICE_SW_LKUP_LAST) { + sw_buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_REP); + } else if (lkup_type == ICE_SW_LKUP_VLAN) { + if (opc == ice_aqc_opc_alloc_res) +@@ -2759,7 +2760,8 @@ ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, + lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || + lkup_type == ICE_SW_LKUP_PROMISC || + lkup_type == ICE_SW_LKUP_PROMISC_VLAN || +- lkup_type == ICE_SW_LKUP_DFLT) ++ lkup_type == ICE_SW_LKUP_DFLT || ++ lkup_type == ICE_SW_LKUP_LAST) + rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR : + ICE_AQC_SW_RULES_T_VSI_LIST_SET; + else if (lkup_type == ICE_SW_LKUP_VLAN) +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +index 23adf53c2aa1c..cebc79a710ec2 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -4013,7 +4013,10 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, + } + } + +- skb = build_skb(data, frag_size); ++ if (frag_size) ++ skb = build_skb(data, frag_size); ++ else ++ skb = slab_build_skb(data); + if (!skb) { + netdev_warn(port->dev, "skb build failed\n"); + goto err_drop_frame; +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/Makefile b/drivers/net/ethernet/marvell/octeontx2/nic/Makefile +index 5664f768cb0cd..64a97a0a10ed6 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/Makefile ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/Makefile +@@ -9,10 +9,9 @@ obj-$(CONFIG_OCTEONTX2_VF) += rvu_nicvf.o otx2_ptp.o + rvu_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o \ + otx2_flows.o otx2_tc.o cn10k.o otx2_dmac_flt.o \ + otx2_devlink.o qos_sq.o qos.o +-rvu_nicvf-y := otx2_vf.o otx2_devlink.o ++rvu_nicvf-y := otx2_vf.o + + rvu_nicpf-$(CONFIG_DCB) += otx2_dcbnl.o +-rvu_nicvf-$(CONFIG_DCB) += otx2_dcbnl.o + rvu_nicpf-$(CONFIG_MACSEC) += cn10k_macsec.o + + ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c +index 28fb643d2917f..aa01110f04a33 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c +@@ -54,6 +54,7 @@ int otx2_pfc_txschq_config(struct otx2_nic *pfvf) + + return 0; + } ++EXPORT_SYMBOL(otx2_pfc_txschq_config); + + static int otx2_pfc_txschq_alloc_one(struct otx2_nic *pfvf, u8 prio) + { +@@ -122,6 +123,7 @@ int otx2_pfc_txschq_alloc(struct otx2_nic *pfvf) + + return 0; + } ++EXPORT_SYMBOL(otx2_pfc_txschq_alloc); + + static int otx2_pfc_txschq_stop_one(struct otx2_nic *pfvf, u8 prio) + { +@@ -260,6 +262,7 @@ int otx2_pfc_txschq_update(struct otx2_nic *pfvf) + + return 0; + } ++EXPORT_SYMBOL(otx2_pfc_txschq_update); + + int otx2_pfc_txschq_stop(struct otx2_nic *pfvf) + { +@@ -282,6 +285,7 @@ int otx2_pfc_txschq_stop(struct otx2_nic *pfvf) + + return 0; + } ++EXPORT_SYMBOL(otx2_pfc_txschq_stop); + + int otx2_config_priority_flow_ctrl(struct otx2_nic *pfvf) + { +@@ -321,6 +325,7 @@ int otx2_config_priority_flow_ctrl(struct otx2_nic *pfvf) + mutex_unlock(&pfvf->mbox.lock); + return err; + } ++EXPORT_SYMBOL(otx2_config_priority_flow_ctrl); + + void otx2_update_bpid_in_rqctx(struct otx2_nic *pfvf, int vlan_prio, int qidx, + bool pfc_enable) +@@ -385,6 +390,7 @@ void otx2_update_bpid_in_rqctx(struct otx2_nic *pfvf, int vlan_prio, int qidx, + "Updating BPIDs in CQ and Aura contexts of RQ%d failed with err %d\n", + qidx, err); + } ++EXPORT_SYMBOL(otx2_update_bpid_in_rqctx); + + static int otx2_dcbnl_ieee_getpfc(struct net_device *dev, struct ieee_pfc *pfc) + { +@@ -472,3 +478,4 @@ int otx2_dcbnl_set_ops(struct net_device *dev) + + return 0; + } ++EXPORT_SYMBOL(otx2_dcbnl_set_ops); +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c +index 4e1130496573e..05956bf03c05d 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c +@@ -112,6 +112,7 @@ int otx2_register_dl(struct otx2_nic *pfvf) + devlink_free(dl); + return err; + } ++EXPORT_SYMBOL(otx2_register_dl); + + void otx2_unregister_dl(struct otx2_nic *pfvf) + { +@@ -123,3 +124,4 @@ void otx2_unregister_dl(struct otx2_nic *pfvf) + ARRAY_SIZE(otx2_dl_params)); + devlink_free(dl); + } ++EXPORT_SYMBOL(otx2_unregister_dl); +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +index f828d32737af0..04a49b9b545f3 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +@@ -1171,8 +1171,11 @@ bool otx2_sq_append_skb(struct net_device *netdev, struct otx2_snd_queue *sq, + + if (skb_shinfo(skb)->gso_size && !is_hw_tso_supported(pfvf, skb)) { + /* Insert vlan tag before giving pkt to tso */ +- if (skb_vlan_tag_present(skb)) ++ if (skb_vlan_tag_present(skb)) { + skb = __vlan_hwaccel_push_inside(skb); ++ if (!skb) ++ return true; ++ } + otx2_sq_append_tso(pfvf, sq, skb, qidx); + return true; + } +diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c +index 8a6ae171e375b..def932035cba4 100644 +--- a/drivers/net/ethernet/microchip/lan743x_ethtool.c ++++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c +@@ -1148,8 +1148,12 @@ static void lan743x_ethtool_get_wol(struct net_device *netdev, + if (netdev->phydev) + phy_ethtool_get_wol(netdev->phydev, wol); + +- wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST | +- WAKE_MAGIC | WAKE_PHY | WAKE_ARP; ++ if (wol->supported != adapter->phy_wol_supported) ++ netif_warn(adapter, drv, adapter->netdev, ++ "PHY changed its supported WOL! old=%x, new=%x\n", ++ adapter->phy_wol_supported, wol->supported); ++ ++ wol->supported |= MAC_SUPPORTED_WAKES; + + if (adapter->is_pci11x1x) + wol->supported |= WAKE_MAGICSECURE; +@@ -1164,7 +1168,39 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev, + { + struct lan743x_adapter *adapter = netdev_priv(netdev); + ++ /* WAKE_MAGICSEGURE is a modifier of and only valid together with ++ * WAKE_MAGIC ++ */ ++ if ((wol->wolopts & WAKE_MAGICSECURE) && !(wol->wolopts & WAKE_MAGIC)) ++ return -EINVAL; ++ ++ if (netdev->phydev) { ++ struct ethtool_wolinfo phy_wol; ++ int ret; ++ ++ phy_wol.wolopts = wol->wolopts & adapter->phy_wol_supported; ++ ++ /* If WAKE_MAGICSECURE was requested, filter out WAKE_MAGIC ++ * for PHYs that do not support WAKE_MAGICSECURE ++ */ ++ if (wol->wolopts & WAKE_MAGICSECURE && ++ !(adapter->phy_wol_supported & WAKE_MAGICSECURE)) ++ phy_wol.wolopts &= ~WAKE_MAGIC; ++ ++ ret = phy_ethtool_set_wol(netdev->phydev, &phy_wol); ++ if (ret && (ret != -EOPNOTSUPP)) ++ return ret; ++ ++ if (ret == -EOPNOTSUPP) ++ adapter->phy_wolopts = 0; ++ else ++ adapter->phy_wolopts = phy_wol.wolopts; ++ } else { ++ adapter->phy_wolopts = 0; ++ } ++ + adapter->wolopts = 0; ++ wol->wolopts &= ~adapter->phy_wolopts; + if (wol->wolopts & WAKE_UCAST) + adapter->wolopts |= WAKE_UCAST; + if (wol->wolopts & WAKE_MCAST) +@@ -1185,10 +1221,10 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev, + memset(adapter->sopass, 0, sizeof(u8) * SOPASS_MAX); + } + ++ wol->wolopts = adapter->wolopts | adapter->phy_wolopts; + device_set_wakeup_enable(&adapter->pdev->dev, (bool)wol->wolopts); + +- return netdev->phydev ? phy_ethtool_set_wol(netdev->phydev, wol) +- : -ENETDOWN; ++ return 0; + } + #endif /* CONFIG_PM */ + +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index 75a988c0bd794..ecde3582e3dee 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -3111,6 +3111,17 @@ static int lan743x_netdev_open(struct net_device *netdev) + if (ret) + goto close_tx; + } ++ ++#ifdef CONFIG_PM ++ if (adapter->netdev->phydev) { ++ struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; ++ ++ phy_ethtool_get_wol(netdev->phydev, &wol); ++ adapter->phy_wol_supported = wol.supported; ++ adapter->phy_wolopts = wol.wolopts; ++ } ++#endif ++ + return 0; + + close_tx: +@@ -3568,7 +3579,7 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter) + + /* clear wake settings */ + pmtctl = lan743x_csr_read(adapter, PMT_CTL); +- pmtctl |= PMT_CTL_WUPS_MASK_; ++ pmtctl |= PMT_CTL_WUPS_MASK_ | PMT_CTL_RES_CLR_WKP_MASK_; + pmtctl &= ~(PMT_CTL_GPIO_WAKEUP_EN_ | PMT_CTL_EEE_WAKEUP_EN_ | + PMT_CTL_WOL_EN_ | PMT_CTL_MAC_D3_RX_CLK_OVR_ | + PMT_CTL_RX_FCT_RFE_D3_CLK_OVR_ | PMT_CTL_ETH_PHY_WAKE_EN_); +@@ -3580,10 +3591,9 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter) + + pmtctl |= PMT_CTL_ETH_PHY_D3_COLD_OVR_ | PMT_CTL_ETH_PHY_D3_OVR_; + +- if (adapter->wolopts & WAKE_PHY) { +- pmtctl |= PMT_CTL_ETH_PHY_EDPD_PLL_CTL_; ++ if (adapter->phy_wolopts) + pmtctl |= PMT_CTL_ETH_PHY_WAKE_EN_; +- } ++ + if (adapter->wolopts & WAKE_MAGIC) { + wucsr |= MAC_WUCSR_MPEN_; + macrx |= MAC_RX_RXEN_; +@@ -3679,7 +3689,7 @@ static int lan743x_pm_suspend(struct device *dev) + lan743x_csr_write(adapter, MAC_WUCSR2, 0); + lan743x_csr_write(adapter, MAC_WK_SRC, 0xFFFFFFFF); + +- if (adapter->wolopts) ++ if (adapter->wolopts || adapter->phy_wolopts) + lan743x_pm_set_wol(adapter); + + if (adapter->is_pci11x1x) { +@@ -3703,6 +3713,7 @@ static int lan743x_pm_resume(struct device *dev) + struct pci_dev *pdev = to_pci_dev(dev); + struct net_device *netdev = pci_get_drvdata(pdev); + struct lan743x_adapter *adapter = netdev_priv(netdev); ++ u32 data; + int ret; + + pci_set_power_state(pdev, PCI_D0); +@@ -3721,6 +3732,30 @@ static int lan743x_pm_resume(struct device *dev) + return ret; + } + ++ ret = lan743x_csr_read(adapter, MAC_WK_SRC); ++ netif_dbg(adapter, drv, adapter->netdev, ++ "Wakeup source : 0x%08X\n", ret); ++ ++ /* Clear the wol configuration and status bits. Note that ++ * the status bits are "Write One to Clear (W1C)" ++ */ ++ data = MAC_WUCSR_EEE_TX_WAKE_ | MAC_WUCSR_EEE_RX_WAKE_ | ++ MAC_WUCSR_RFE_WAKE_FR_ | MAC_WUCSR_PFDA_FR_ | MAC_WUCSR_WUFR_ | ++ MAC_WUCSR_MPR_ | MAC_WUCSR_BCAST_FR_; ++ lan743x_csr_write(adapter, MAC_WUCSR, data); ++ ++ data = MAC_WUCSR2_NS_RCD_ | MAC_WUCSR2_ARP_RCD_ | ++ MAC_WUCSR2_IPV6_TCPSYN_RCD_ | MAC_WUCSR2_IPV4_TCPSYN_RCD_; ++ lan743x_csr_write(adapter, MAC_WUCSR2, data); ++ ++ data = MAC_WK_SRC_ETH_PHY_WK_ | MAC_WK_SRC_IPV6_TCPSYN_RCD_WK_ | ++ MAC_WK_SRC_IPV4_TCPSYN_RCD_WK_ | MAC_WK_SRC_EEE_TX_WK_ | ++ MAC_WK_SRC_EEE_RX_WK_ | MAC_WK_SRC_RFE_FR_WK_ | ++ MAC_WK_SRC_PFDA_FR_WK_ | MAC_WK_SRC_MP_FR_WK_ | ++ MAC_WK_SRC_BCAST_FR_WK_ | MAC_WK_SRC_WU_FR_WK_ | ++ MAC_WK_SRC_WK_FR_SAVED_; ++ lan743x_csr_write(adapter, MAC_WK_SRC, data); ++ + /* open netdev when netdev is at running state while resume. + * For instance, it is true when system wakesup after pm-suspend + * However, it is false when system wakes up after suspend GUI menu +@@ -3729,9 +3764,6 @@ static int lan743x_pm_resume(struct device *dev) + lan743x_netdev_open(netdev); + + netif_device_attach(netdev); +- ret = lan743x_csr_read(adapter, MAC_WK_SRC); +- netif_info(adapter, drv, adapter->netdev, +- "Wakeup source : 0x%08X\n", ret); + + return 0; + } +diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h +index 645bc048e52ef..3b2585a384e2c 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.h ++++ b/drivers/net/ethernet/microchip/lan743x_main.h +@@ -61,6 +61,7 @@ + #define PMT_CTL_RX_FCT_RFE_D3_CLK_OVR_ BIT(18) + #define PMT_CTL_GPIO_WAKEUP_EN_ BIT(15) + #define PMT_CTL_EEE_WAKEUP_EN_ BIT(13) ++#define PMT_CTL_RES_CLR_WKP_MASK_ GENMASK(9, 8) + #define PMT_CTL_READY_ BIT(7) + #define PMT_CTL_ETH_PHY_RST_ BIT(4) + #define PMT_CTL_WOL_EN_ BIT(3) +@@ -227,12 +228,31 @@ + #define MAC_WUCSR (0x140) + #define MAC_MP_SO_EN_ BIT(21) + #define MAC_WUCSR_RFE_WAKE_EN_ BIT(14) ++#define MAC_WUCSR_EEE_TX_WAKE_ BIT(13) ++#define MAC_WUCSR_EEE_RX_WAKE_ BIT(11) ++#define MAC_WUCSR_RFE_WAKE_FR_ BIT(9) ++#define MAC_WUCSR_PFDA_FR_ BIT(7) ++#define MAC_WUCSR_WUFR_ BIT(6) ++#define MAC_WUCSR_MPR_ BIT(5) ++#define MAC_WUCSR_BCAST_FR_ BIT(4) + #define MAC_WUCSR_PFDA_EN_ BIT(3) + #define MAC_WUCSR_WAKE_EN_ BIT(2) + #define MAC_WUCSR_MPEN_ BIT(1) + #define MAC_WUCSR_BCST_EN_ BIT(0) + + #define MAC_WK_SRC (0x144) ++#define MAC_WK_SRC_ETH_PHY_WK_ BIT(17) ++#define MAC_WK_SRC_IPV6_TCPSYN_RCD_WK_ BIT(16) ++#define MAC_WK_SRC_IPV4_TCPSYN_RCD_WK_ BIT(15) ++#define MAC_WK_SRC_EEE_TX_WK_ BIT(14) ++#define MAC_WK_SRC_EEE_RX_WK_ BIT(13) ++#define MAC_WK_SRC_RFE_FR_WK_ BIT(12) ++#define MAC_WK_SRC_PFDA_FR_WK_ BIT(11) ++#define MAC_WK_SRC_MP_FR_WK_ BIT(10) ++#define MAC_WK_SRC_BCAST_FR_WK_ BIT(9) ++#define MAC_WK_SRC_WU_FR_WK_ BIT(8) ++#define MAC_WK_SRC_WK_FR_SAVED_ BIT(7) ++ + #define MAC_MP_SO_HI (0x148) + #define MAC_MP_SO_LO (0x14C) + +@@ -295,6 +315,10 @@ + #define RFE_INDX(index) (0x580 + (index << 2)) + + #define MAC_WUCSR2 (0x600) ++#define MAC_WUCSR2_NS_RCD_ BIT(7) ++#define MAC_WUCSR2_ARP_RCD_ BIT(6) ++#define MAC_WUCSR2_IPV6_TCPSYN_RCD_ BIT(5) ++#define MAC_WUCSR2_IPV4_TCPSYN_RCD_ BIT(4) + + #define SGMII_ACC (0x720) + #define SGMII_ACC_SGMII_BZY_ BIT(31) +@@ -1018,6 +1042,8 @@ enum lan743x_sgmii_lsd { + LINK_2500_SLAVE + }; + ++#define MAC_SUPPORTED_WAKES (WAKE_BCAST | WAKE_UCAST | WAKE_MCAST | \ ++ WAKE_MAGIC | WAKE_ARP) + struct lan743x_adapter { + struct net_device *netdev; + struct mii_bus *mdiobus; +@@ -1025,6 +1051,8 @@ struct lan743x_adapter { + #ifdef CONFIG_PM + u32 wolopts; + u8 sopass[SOPASS_MAX]; ++ u32 phy_wolopts; ++ u32 phy_wol_supported; + #endif + struct pci_dev *pdev; + struct lan743x_csr csr; +diff --git a/drivers/net/ethernet/qualcomm/qca_debug.c b/drivers/net/ethernet/qualcomm/qca_debug.c +index ff3b89e9028e9..ad06da0fdaa04 100644 +--- a/drivers/net/ethernet/qualcomm/qca_debug.c ++++ b/drivers/net/ethernet/qualcomm/qca_debug.c +@@ -98,10 +98,8 @@ qcaspi_info_show(struct seq_file *s, void *what) + + seq_printf(s, "IRQ : %d\n", + qca->spi_dev->irq); +- seq_printf(s, "INTR REQ : %u\n", +- qca->intr_req); +- seq_printf(s, "INTR SVC : %u\n", +- qca->intr_svc); ++ seq_printf(s, "INTR : %lx\n", ++ qca->intr); + + seq_printf(s, "SPI max speed : %lu\n", + (unsigned long)qca->spi_dev->max_speed_hz); +diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c +index 5799ecc88a875..8f7ce6b51a1c9 100644 +--- a/drivers/net/ethernet/qualcomm/qca_spi.c ++++ b/drivers/net/ethernet/qualcomm/qca_spi.c +@@ -35,6 +35,8 @@ + + #define MAX_DMA_BURST_LEN 5000 + ++#define SPI_INTR 0 ++ + /* Modules parameters */ + #define QCASPI_CLK_SPEED_MIN 1000000 + #define QCASPI_CLK_SPEED_MAX 16000000 +@@ -579,14 +581,14 @@ qcaspi_spi_thread(void *data) + continue; + } + +- if ((qca->intr_req == qca->intr_svc) && ++ if (!test_bit(SPI_INTR, &qca->intr) && + !qca->txr.skb[qca->txr.head]) + schedule(); + + set_current_state(TASK_RUNNING); + +- netdev_dbg(qca->net_dev, "have work to do. int: %d, tx_skb: %p\n", +- qca->intr_req - qca->intr_svc, ++ netdev_dbg(qca->net_dev, "have work to do. int: %lu, tx_skb: %p\n", ++ qca->intr, + qca->txr.skb[qca->txr.head]); + + qcaspi_qca7k_sync(qca, QCASPI_EVENT_UPDATE); +@@ -600,8 +602,7 @@ qcaspi_spi_thread(void *data) + msleep(QCASPI_QCA7K_REBOOT_TIME_MS); + } + +- if (qca->intr_svc != qca->intr_req) { +- qca->intr_svc = qca->intr_req; ++ if (test_and_clear_bit(SPI_INTR, &qca->intr)) { + start_spi_intr_handling(qca, &intr_cause); + + if (intr_cause & SPI_INT_CPU_ON) { +@@ -663,7 +664,7 @@ qcaspi_intr_handler(int irq, void *data) + { + struct qcaspi *qca = data; + +- qca->intr_req++; ++ set_bit(SPI_INTR, &qca->intr); + if (qca->spi_thread) + wake_up_process(qca->spi_thread); + +@@ -679,8 +680,7 @@ qcaspi_netdev_open(struct net_device *dev) + if (!qca) + return -EINVAL; + +- qca->intr_req = 1; +- qca->intr_svc = 0; ++ set_bit(SPI_INTR, &qca->intr); + qca->sync = QCASPI_SYNC_UNKNOWN; + qcafrm_fsm_init_spi(&qca->frm_handle); + +diff --git a/drivers/net/ethernet/qualcomm/qca_spi.h b/drivers/net/ethernet/qualcomm/qca_spi.h +index d59cb2352ceec..8f4808695e820 100644 +--- a/drivers/net/ethernet/qualcomm/qca_spi.h ++++ b/drivers/net/ethernet/qualcomm/qca_spi.h +@@ -81,8 +81,7 @@ struct qcaspi { + struct qcafrm_handle frm_handle; + struct sk_buff *rx_skb; + +- unsigned int intr_req; +- unsigned int intr_svc; ++ unsigned long intr; + u16 reset_count; + + #ifdef CONFIG_DEBUG_FS +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +index f05bd757dfe52..5ef52ef2698fb 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +@@ -218,6 +218,7 @@ static void timestamp_interrupt(struct stmmac_priv *priv) + { + u32 num_snapshot, ts_status, tsync_int; + struct ptp_clock_event event; ++ u32 acr_value, channel; + unsigned long flags; + u64 ptp_time; + int i; +@@ -243,12 +244,15 @@ static void timestamp_interrupt(struct stmmac_priv *priv) + num_snapshot = (ts_status & GMAC_TIMESTAMP_ATSNS_MASK) >> + GMAC_TIMESTAMP_ATSNS_SHIFT; + ++ acr_value = readl(priv->ptpaddr + PTP_ACR); ++ channel = ilog2(FIELD_GET(PTP_ACR_MASK, acr_value)); ++ + for (i = 0; i < num_snapshot; i++) { + read_lock_irqsave(&priv->ptp_lock, flags); + get_ptptime(priv->ptpaddr, &ptp_time); + read_unlock_irqrestore(&priv->ptp_lock, flags); + event.type = PTP_CLOCK_EXTTS; +- event.index = 0; ++ event.index = channel; + event.timestamp = ptp_time; + ptp_clock_event(priv->ptp_clock, &event); + } +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +index b1896379dbab5..7d240a2b54a85 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +@@ -358,24 +358,28 @@ static int tc_setup_cbs(struct stmmac_priv *priv, + + port_transmit_rate_kbps = qopt->idleslope - qopt->sendslope; + +- /* Port Transmit Rate and Speed Divider */ +- switch (div_s64(port_transmit_rate_kbps, 1000)) { +- case SPEED_10000: +- case SPEED_5000: +- ptr = 32; +- break; +- case SPEED_2500: +- case SPEED_1000: +- ptr = 8; +- break; +- case SPEED_100: +- ptr = 4; +- break; +- default: +- netdev_err(priv->dev, +- "Invalid portTransmitRate %lld (idleSlope - sendSlope)\n", +- port_transmit_rate_kbps); +- return -EINVAL; ++ if (qopt->enable) { ++ /* Port Transmit Rate and Speed Divider */ ++ switch (div_s64(port_transmit_rate_kbps, 1000)) { ++ case SPEED_10000: ++ case SPEED_5000: ++ ptr = 32; ++ break; ++ case SPEED_2500: ++ case SPEED_1000: ++ ptr = 8; ++ break; ++ case SPEED_100: ++ ptr = 4; ++ break; ++ default: ++ netdev_err(priv->dev, ++ "Invalid portTransmitRate %lld (idleSlope - sendSlope)\n", ++ port_transmit_rate_kbps); ++ return -EINVAL; ++ } ++ } else { ++ ptr = 0; + } + + mode_to_use = priv->plat->tx_queues_cfg[queue].mode_to_use; +diff --git a/drivers/net/phy/dp83tg720.c b/drivers/net/phy/dp83tg720.c +index 326c9770a6dcc..c706429b225a2 100644 +--- a/drivers/net/phy/dp83tg720.c ++++ b/drivers/net/phy/dp83tg720.c +@@ -17,6 +17,11 @@ + #define DP83TG720S_PHY_RESET 0x1f + #define DP83TG720S_HW_RESET BIT(15) + ++#define DP83TG720S_LPS_CFG3 0x18c ++/* Power modes are documented as bit fields but used as values */ ++/* Power Mode 0 is Normal mode */ ++#define DP83TG720S_LPS_CFG3_PWR_MODE_0 BIT(0) ++ + #define DP83TG720S_RGMII_DELAY_CTRL 0x602 + /* In RGMII mode, Enable or disable the internal delay for RXD */ + #define DP83TG720S_RGMII_RX_CLK_SEL BIT(1) +@@ -31,11 +36,20 @@ + + static int dp83tg720_config_aneg(struct phy_device *phydev) + { ++ int ret; ++ + /* Autoneg is not supported and this PHY supports only one speed. + * We need to care only about master/slave configuration if it was + * changed by user. + */ +- return genphy_c45_pma_baset1_setup_master_slave(phydev); ++ ret = genphy_c45_pma_baset1_setup_master_slave(phydev); ++ if (ret) ++ return ret; ++ ++ /* Re-read role configuration to make changes visible even if ++ * the link is in administrative down state. ++ */ ++ return genphy_c45_pma_baset1_read_master_slave(phydev); + } + + static int dp83tg720_read_status(struct phy_device *phydev) +@@ -64,6 +78,8 @@ static int dp83tg720_read_status(struct phy_device *phydev) + return ret; + + /* After HW reset we need to restore master/slave configuration. ++ * genphy_c45_pma_baset1_read_master_slave() call will be done ++ * by the dp83tg720_config_aneg() function. + */ + ret = dp83tg720_config_aneg(phydev); + if (ret) +@@ -154,10 +170,24 @@ static int dp83tg720_config_init(struct phy_device *phydev) + */ + usleep_range(1000, 2000); + +- if (phy_interface_is_rgmii(phydev)) +- return dp83tg720_config_rgmii_delay(phydev); ++ if (phy_interface_is_rgmii(phydev)) { ++ ret = dp83tg720_config_rgmii_delay(phydev); ++ if (ret) ++ return ret; ++ } ++ ++ /* In case the PHY is bootstrapped in managed mode, we need to ++ * wake it. ++ */ ++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_LPS_CFG3, ++ DP83TG720S_LPS_CFG3_PWR_MODE_0); ++ if (ret) ++ return ret; + +- return 0; ++ /* Make role configuration visible for ethtool on init and after ++ * rest. ++ */ ++ return genphy_c45_pma_baset1_read_master_slave(phydev); + } + + static struct phy_driver dp83tg720_driver[] = { +diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c +index b2d36a3a96f1e..e5f8ac4b4604b 100644 +--- a/drivers/net/phy/mxl-gpy.c ++++ b/drivers/net/phy/mxl-gpy.c +@@ -107,6 +107,7 @@ struct gpy_priv { + + u8 fw_major; + u8 fw_minor; ++ u32 wolopts; + + /* It takes 3 seconds to fully switch out of loopback mode before + * it can safely re-enter loopback mode. Record the time when +@@ -221,6 +222,15 @@ static int gpy_hwmon_register(struct phy_device *phydev) + } + #endif + ++static int gpy_ack_interrupt(struct phy_device *phydev) ++{ ++ int ret; ++ ++ /* Clear all pending interrupts */ ++ ret = phy_read(phydev, PHY_ISTAT); ++ return ret < 0 ? ret : 0; ++} ++ + static int gpy_mbox_read(struct phy_device *phydev, u32 addr) + { + struct gpy_priv *priv = phydev->priv; +@@ -262,16 +272,8 @@ static int gpy_mbox_read(struct phy_device *phydev, u32 addr) + + static int gpy_config_init(struct phy_device *phydev) + { +- int ret; +- +- /* Mask all interrupts */ +- ret = phy_write(phydev, PHY_IMASK, 0); +- if (ret) +- return ret; +- +- /* Clear all pending interrupts */ +- ret = phy_read(phydev, PHY_ISTAT); +- return ret < 0 ? ret : 0; ++ /* Nothing to configure. Configuration Requirement Placeholder */ ++ return 0; + } + + static int gpy21x_config_init(struct phy_device *phydev) +@@ -627,11 +629,23 @@ static int gpy_read_status(struct phy_device *phydev) + + static int gpy_config_intr(struct phy_device *phydev) + { ++ struct gpy_priv *priv = phydev->priv; + u16 mask = 0; ++ int ret; ++ ++ ret = gpy_ack_interrupt(phydev); ++ if (ret) ++ return ret; + + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) + mask = PHY_IMASK_MASK; + ++ if (priv->wolopts & WAKE_MAGIC) ++ mask |= PHY_IMASK_WOL; ++ ++ if (priv->wolopts & WAKE_PHY) ++ mask |= PHY_IMASK_LSTC; ++ + return phy_write(phydev, PHY_IMASK, mask); + } + +@@ -678,6 +692,7 @@ static int gpy_set_wol(struct phy_device *phydev, + struct ethtool_wolinfo *wol) + { + struct net_device *attach_dev = phydev->attached_dev; ++ struct gpy_priv *priv = phydev->priv; + int ret; + + if (wol->wolopts & WAKE_MAGIC) { +@@ -725,6 +740,8 @@ static int gpy_set_wol(struct phy_device *phydev, + ret = phy_read(phydev, PHY_ISTAT); + if (ret < 0) + return ret; ++ ++ priv->wolopts |= WAKE_MAGIC; + } else { + /* Disable magic packet matching */ + ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, +@@ -732,6 +749,13 @@ static int gpy_set_wol(struct phy_device *phydev, + WOL_EN); + if (ret < 0) + return ret; ++ ++ /* Disable the WOL interrupt */ ++ ret = phy_clear_bits(phydev, PHY_IMASK, PHY_IMASK_WOL); ++ if (ret < 0) ++ return ret; ++ ++ priv->wolopts &= ~WAKE_MAGIC; + } + + if (wol->wolopts & WAKE_PHY) { +@@ -748,9 +772,11 @@ static int gpy_set_wol(struct phy_device *phydev, + if (ret & (PHY_IMASK_MASK & ~PHY_IMASK_LSTC)) + phy_trigger_machine(phydev); + ++ priv->wolopts |= WAKE_PHY; + return 0; + } + ++ priv->wolopts &= ~WAKE_PHY; + /* Disable the link state change interrupt */ + return phy_clear_bits(phydev, PHY_IMASK, PHY_IMASK_LSTC); + } +@@ -758,18 +784,10 @@ static int gpy_set_wol(struct phy_device *phydev, + static void gpy_get_wol(struct phy_device *phydev, + struct ethtool_wolinfo *wol) + { +- int ret; ++ struct gpy_priv *priv = phydev->priv; + + wol->supported = WAKE_MAGIC | WAKE_PHY; +- wol->wolopts = 0; +- +- ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, VPSPEC2_WOL_CTL); +- if (ret & WOL_EN) +- wol->wolopts |= WAKE_MAGIC; +- +- ret = phy_read(phydev, PHY_IMASK); +- if (ret & PHY_IMASK_LSTC) +- wol->wolopts |= WAKE_PHY; ++ wol->wolopts = priv->wolopts; + } + + static int gpy_loopback(struct phy_device *phydev, bool enable) +diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c +index d999d9baadb26..52b71c7e78351 100644 +--- a/drivers/net/phy/sfp.c ++++ b/drivers/net/phy/sfp.c +@@ -385,18 +385,23 @@ static void sfp_fixup_rollball(struct sfp *sfp) + sfp->phy_t_retry = msecs_to_jiffies(1000); + } + +-static void sfp_fixup_fs_10gt(struct sfp *sfp) ++static void sfp_fixup_fs_2_5gt(struct sfp *sfp) + { +- sfp_fixup_10gbaset_30m(sfp); + sfp_fixup_rollball(sfp); + +- /* The RollBall fixup is not enough for FS modules, the AQR chip inside ++ /* The RollBall fixup is not enough for FS modules, the PHY chip inside + * them does not return 0xffff for PHY ID registers in all MMDs for the + * while initializing. They need a 4 second wait before accessing PHY. + */ + sfp->module_t_wait = msecs_to_jiffies(4000); + } + ++static void sfp_fixup_fs_10gt(struct sfp *sfp) ++{ ++ sfp_fixup_10gbaset_30m(sfp); ++ sfp_fixup_fs_2_5gt(sfp); ++} ++ + static void sfp_fixup_halny_gsfp(struct sfp *sfp) + { + /* Ignore the TX_FAULT and LOS signals on this module. +@@ -472,6 +477,10 @@ static const struct sfp_quirk sfp_quirks[] = { + // Rollball protocol to talk to the PHY. + SFP_QUIRK_F("FS", "SFP-10G-T", sfp_fixup_fs_10gt), + ++ // Fiberstore SFP-2.5G-T uses Rollball protocol to talk to the PHY and ++ // needs 4 sec wait before probing the PHY. ++ SFP_QUIRK_F("FS", "SFP-2.5G-T", sfp_fixup_fs_2_5gt), ++ + // Fiberstore GPON-ONU-34-20BI can operate at 2500base-X, but report 1.2GBd + // NRZ in their EEPROM + SFP_QUIRK("FS", "GPON-ONU-34-20BI", sfp_quirk_2500basex, +@@ -488,9 +497,6 @@ static const struct sfp_quirk sfp_quirks[] = { + SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex, + sfp_fixup_ignore_tx_fault), + +- // FS 2.5G Base-T +- SFP_QUIRK_M("FS", "SFP-2.5G-T", sfp_quirk_oem_2_5g), +- + // Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report + // 2500MBd NRZ in their EEPROM + SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex), +@@ -502,6 +508,9 @@ static const struct sfp_quirk sfp_quirks[] = { + SFP_QUIRK_F("Walsun", "HXSX-ATRC-1", sfp_fixup_fs_10gt), + SFP_QUIRK_F("Walsun", "HXSX-ATRI-1", sfp_fixup_fs_10gt), + ++ // OEM SFP-GE-T is a 1000Base-T module with broken TX_FAULT indicator ++ SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault), ++ + SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc), + SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g), + SFP_QUIRK_F("OEM", "RTSFP-10", sfp_fixup_rollball_cc), +diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c +index 56ede5fa02617..94d8b647f0f57 100644 +--- a/drivers/net/usb/ax88179_178a.c ++++ b/drivers/net/usb/ax88179_178a.c +@@ -174,7 +174,6 @@ struct ax88179_data { + u32 wol_supported; + u32 wolopts; + u8 disconnecting; +- u8 initialized; + }; + + struct ax88179_int_data { +@@ -1676,12 +1675,21 @@ static int ax88179_reset(struct usbnet *dev) + + static int ax88179_net_reset(struct usbnet *dev) + { +- struct ax88179_data *ax179_data = dev->driver_priv; ++ u16 tmp16; + +- if (ax179_data->initialized) ++ ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, GMII_PHY_PHYSR, ++ 2, &tmp16); ++ if (tmp16) { ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, ++ 2, 2, &tmp16); ++ if (!(tmp16 & AX_MEDIUM_RECEIVE_EN)) { ++ tmp16 |= AX_MEDIUM_RECEIVE_EN; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, ++ 2, 2, &tmp16); ++ } ++ } else { + ax88179_reset(dev); +- else +- ax179_data->initialized = 1; ++ } + + return 0; + } +diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c +index 97afd7335d868..01a3b2417a540 100644 +--- a/drivers/net/usb/rtl8150.c ++++ b/drivers/net/usb/rtl8150.c +@@ -778,7 +778,8 @@ static int rtl8150_get_link_ksettings(struct net_device *netdev, + struct ethtool_link_ksettings *ecmd) + { + rtl8150_t *dev = netdev_priv(netdev); +- short lpa, bmcr; ++ short lpa = 0; ++ short bmcr = 0; + u32 supported; + + supported = (SUPPORTED_10baseT_Half | +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 574b052a517d7..290bec2926463 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -1225,6 +1225,10 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev, + if (unlikely(hdr->hdr.gso_type)) + goto err_xdp; + ++ /* Partially checksummed packets must be dropped. */ ++ if (unlikely(hdr->hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM)) ++ goto err_xdp; ++ + buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + +@@ -1542,6 +1546,10 @@ static void *mergeable_xdp_get_buf(struct virtnet_info *vi, + if (unlikely(hdr->hdr.gso_type)) + return NULL; + ++ /* Partially checksummed packets must be dropped. */ ++ if (unlikely(hdr->hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM)) ++ return NULL; ++ + /* Now XDP core assumes frag size is PAGE_SIZE, but buffers + * with headroom may add hole in truesize, which + * make their length exceed PAGE_SIZE. So we disabled the +@@ -1808,6 +1816,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, + struct net_device *dev = vi->dev; + struct sk_buff *skb; + struct virtio_net_common_hdr *hdr; ++ u8 flags; + + if (unlikely(len < vi->hdr_len + ETH_HLEN)) { + pr_debug("%s: short packet %i\n", dev->name, len); +@@ -1816,6 +1825,15 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, + return; + } + ++ /* 1. Save the flags early, as the XDP program might overwrite them. ++ * These flags ensure packets marked as VIRTIO_NET_HDR_F_DATA_VALID ++ * stay valid after XDP processing. ++ * 2. XDP doesn't work with partially checksummed packets (refer to ++ * virtnet_xdp_set()), so packets marked as ++ * VIRTIO_NET_HDR_F_NEEDS_CSUM get dropped during XDP processing. ++ */ ++ flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags; ++ + if (vi->mergeable_rx_bufs) + skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit, + stats); +@@ -1831,7 +1849,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, + if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report) + virtio_skb_set_hash(&hdr->hash_v1_hdr, skb); + +- if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID) ++ if (flags & VIRTIO_NET_HDR_F_DATA_VALID) + skb->ip_summed = CHECKSUM_UNNECESSARY; + + if (virtio_net_hdr_to_skb(skb, &hdr->hdr, +@@ -4698,8 +4716,16 @@ static int virtnet_probe(struct virtio_device *vdev) + dev->features |= dev->hw_features & NETIF_F_ALL_TSO; + /* (!csum && gso) case will be fixed by register_netdev() */ + } +- if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM)) +- dev->features |= NETIF_F_RXCSUM; ++ ++ /* 1. With VIRTIO_NET_F_GUEST_CSUM negotiation, the driver doesn't ++ * need to calculate checksums for partially checksummed packets, ++ * as they're considered valid by the upper layer. ++ * 2. Without VIRTIO_NET_F_GUEST_CSUM negotiation, the driver only ++ * receives fully checksummed packets. The device may assist in ++ * validating these packets' checksums, so the driver won't have to. ++ */ ++ dev->features |= NETIF_F_RXCSUM; ++ + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || + virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)) + dev->features |= NETIF_F_GRO_HW; +diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h +index f02a308a9ffc5..34654f710d8a1 100644 +--- a/drivers/net/wireless/ath/ath.h ++++ b/drivers/net/wireless/ath/ath.h +@@ -171,8 +171,10 @@ struct ath_common { + unsigned int clockrate; + + spinlock_t cc_lock; +- struct ath_cycle_counters cc_ani; +- struct ath_cycle_counters cc_survey; ++ struct_group(cc, ++ struct ath_cycle_counters cc_ani; ++ struct ath_cycle_counters cc_survey; ++ ); + + struct ath_regulatory regulatory; + struct ath_regulatory reg_world_copy; +diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c +index 391b6fb2bd426..bff4598de4035 100644 +--- a/drivers/net/wireless/ath/ath12k/core.c ++++ b/drivers/net/wireless/ath/ath12k/core.c +@@ -1132,7 +1132,6 @@ static void ath12k_core_reset(struct work_struct *work) + ATH12K_RECOVER_START_TIMEOUT_HZ); + + ath12k_hif_power_down(ab); +- ath12k_qmi_free_resource(ab); + ath12k_hif_power_up(ab); + + ath12k_dbg(ab, ATH12K_DBG_BOOT, "reset started\n"); +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index 52a5fb8b03e9a..82ef4d4da681e 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -6286,14 +6286,24 @@ ath12k_mac_check_down_grade_phy_mode(struct ath12k *ar, + enum nl80211_band band, + enum nl80211_iftype type) + { +- struct ieee80211_sta_eht_cap *eht_cap; ++ struct ieee80211_sta_eht_cap *eht_cap = NULL; + enum wmi_phy_mode down_mode; ++ int n = ar->mac.sbands[band].n_iftype_data; ++ int i; ++ struct ieee80211_sband_iftype_data *data; + + if (mode < MODE_11BE_EHT20) + return mode; + +- eht_cap = &ar->mac.iftype[band][type].eht_cap; +- if (eht_cap->has_eht) ++ data = ar->mac.iftype[band]; ++ for (i = 0; i < n; i++) { ++ if (data[i].types_mask & BIT(type)) { ++ eht_cap = &data[i].eht_cap; ++ break; ++ } ++ } ++ ++ if (eht_cap && eht_cap->has_eht) + return mode; + + switch (mode) { +diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c +index 40b6abccbb508..e8eb996380eaf 100644 +--- a/drivers/net/wireless/ath/ath12k/qmi.c ++++ b/drivers/net/wireless/ath/ath12k/qmi.c +@@ -2325,8 +2325,9 @@ static void ath12k_qmi_free_target_mem_chunk(struct ath12k_base *ab) + for (i = 0; i < ab->qmi.mem_seg_count; i++) { + if (!ab->qmi.target_mem[i].v.addr) + continue; ++ + dma_free_coherent(ab->dev, +- ab->qmi.target_mem[i].size, ++ ab->qmi.target_mem[i].prev_size, + ab->qmi.target_mem[i].v.addr, + ab->qmi.target_mem[i].paddr); + ab->qmi.target_mem[i].v.addr = NULL; +@@ -2352,6 +2353,20 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab) + case M3_DUMP_REGION_TYPE: + case PAGEABLE_MEM_REGION_TYPE: + case CALDB_MEM_REGION_TYPE: ++ /* Firmware reloads in recovery/resume. ++ * In such cases, no need to allocate memory for FW again. ++ */ ++ if (chunk->v.addr) { ++ if (chunk->prev_type == chunk->type && ++ chunk->prev_size == chunk->size) ++ goto this_chunk_done; ++ ++ /* cannot reuse the existing chunk */ ++ dma_free_coherent(ab->dev, chunk->prev_size, ++ chunk->v.addr, chunk->paddr); ++ chunk->v.addr = NULL; ++ } ++ + chunk->v.addr = dma_alloc_coherent(ab->dev, + chunk->size, + &chunk->paddr, +@@ -2370,6 +2385,10 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab) + chunk->type, chunk->size); + return -ENOMEM; + } ++ ++ chunk->prev_type = chunk->type; ++ chunk->prev_size = chunk->size; ++this_chunk_done: + break; + default: + ath12k_warn(ab, "memory type %u not supported\n", +@@ -2666,6 +2685,19 @@ static int ath12k_qmi_load_bdf_qmi(struct ath12k_base *ab, + return ret; + } + ++static void ath12k_qmi_m3_free(struct ath12k_base *ab) ++{ ++ struct m3_mem_region *m3_mem = &ab->qmi.m3_mem; ++ ++ if (!m3_mem->vaddr) ++ return; ++ ++ dma_free_coherent(ab->dev, m3_mem->size, ++ m3_mem->vaddr, m3_mem->paddr); ++ m3_mem->vaddr = NULL; ++ m3_mem->size = 0; ++} ++ + static int ath12k_qmi_m3_load(struct ath12k_base *ab) + { + struct m3_mem_region *m3_mem = &ab->qmi.m3_mem; +@@ -2675,10 +2707,6 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab) + size_t m3_len; + int ret; + +- if (m3_mem->vaddr) +- /* m3 firmware buffer is already available in the DMA buffer */ +- return 0; +- + if (ab->fw.m3_data && ab->fw.m3_len > 0) { + /* firmware-N.bin had a m3 firmware file so use that */ + m3_data = ab->fw.m3_data; +@@ -2700,6 +2728,15 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab) + m3_len = fw->size; + } + ++ /* In recovery/resume cases, M3 buffer is not freed, try to reuse that */ ++ if (m3_mem->vaddr) { ++ if (m3_mem->size >= m3_len) ++ goto skip_m3_alloc; ++ ++ /* Old buffer is too small, free and reallocate */ ++ ath12k_qmi_m3_free(ab); ++ } ++ + m3_mem->vaddr = dma_alloc_coherent(ab->dev, + m3_len, &m3_mem->paddr, + GFP_KERNEL); +@@ -2710,6 +2747,7 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab) + goto out; + } + ++skip_m3_alloc: + memcpy(m3_mem->vaddr, m3_data, m3_len); + m3_mem->size = m3_len; + +@@ -2721,19 +2759,6 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab) + return ret; + } + +-static void ath12k_qmi_m3_free(struct ath12k_base *ab) +-{ +- struct m3_mem_region *m3_mem = &ab->qmi.m3_mem; +- +- if (!m3_mem->vaddr) +- return; +- +- dma_free_coherent(ab->dev, m3_mem->size, +- m3_mem->vaddr, m3_mem->paddr); +- m3_mem->vaddr = NULL; +- m3_mem->size = 0; +-} +- + static int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab) + { + struct m3_mem_region *m3_mem = &ab->qmi.m3_mem; +diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h +index 6ee33c9851c6b..f34263d4bee88 100644 +--- a/drivers/net/wireless/ath/ath12k/qmi.h ++++ b/drivers/net/wireless/ath/ath12k/qmi.h +@@ -96,6 +96,8 @@ struct ath12k_qmi_event_msg { + struct target_mem_chunk { + u32 size; + u32 type; ++ u32 prev_size; ++ u32 prev_type; + dma_addr_t paddr; + union { + void __iomem *ioaddr; +diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c +index a2943aaecb202..01173aac30456 100644 +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -135,8 +135,7 @@ void ath9k_ps_wakeup(struct ath_softc *sc) + if (power_mode != ATH9K_PM_AWAKE) { + spin_lock(&common->cc_lock); + ath_hw_cycle_counters_update(common); +- memset(&common->cc_survey, 0, sizeof(common->cc_survey)); +- memset(&common->cc_ani, 0, sizeof(common->cc_ani)); ++ memset(&common->cc, 0, sizeof(common->cc)); + spin_unlock(&common->cc_lock); + } + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +index 2403ac2fcdc3b..5f6b16d3fc8a3 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +@@ -4643,7 +4643,7 @@ static int iwl_mvm_roc_station(struct iwl_mvm *mvm, + + if (fw_ver == IWL_FW_CMD_VER_UNKNOWN) { + ret = iwl_mvm_send_aux_roc_cmd(mvm, channel, vif, duration); +- } else if (fw_ver == 3) { ++ } else if (fw_ver >= 3) { + ret = iwl_mvm_roc_add_cmd(mvm, channel, vif, duration, + ROC_ACTIVITY_HOTSPOT); + } else { +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +index 867e14f6b93a0..73e42ef429837 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +@@ -663,6 +663,7 @@ void mt7921_mac_reset_work(struct work_struct *work) + int i, ret; + + dev_dbg(dev->mt76.dev, "chip reset\n"); ++ set_bit(MT76_RESET, &dev->mphy.state); + dev->hw_full_reset = true; + ieee80211_stop_queues(hw); + +@@ -691,6 +692,7 @@ void mt7921_mac_reset_work(struct work_struct *work) + } + + dev->hw_full_reset = false; ++ clear_bit(MT76_RESET, &dev->mphy.state); + pm->suspended = false; + ieee80211_wake_queues(hw); + ieee80211_iterate_active_interfaces(hw, +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c +index c866144ff0613..031ba9aaa4e2f 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c +@@ -64,7 +64,6 @@ int mt7921e_mac_reset(struct mt792x_dev *dev) + mt76_wr(dev, dev->irq_map->host_irq_enable, 0); + mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0); + +- set_bit(MT76_RESET, &dev->mphy.state); + set_bit(MT76_MCU_RESET, &dev->mphy.state); + wake_up(&dev->mt76.mcu.wait); + skb_queue_purge(&dev->mt76.mcu.res_q); +@@ -115,7 +114,6 @@ int mt7921e_mac_reset(struct mt792x_dev *dev) + + err = __mt7921_start(&dev->phy); + out: +- clear_bit(MT76_RESET, &dev->mphy.state); + + local_bh_disable(); + napi_enable(&dev->mt76.tx_napi); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c +index 389eb0903807e..1f77cf71ca701 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c +@@ -98,7 +98,6 @@ int mt7921s_mac_reset(struct mt792x_dev *dev) + mt76_connac_free_pending_tx_skbs(&dev->pm, NULL); + mt76_txq_schedule_all(&dev->mphy); + mt76_worker_disable(&dev->mt76.tx_worker); +- set_bit(MT76_RESET, &dev->mphy.state); + set_bit(MT76_MCU_RESET, &dev->mphy.state); + wake_up(&dev->mt76.mcu.wait); + skb_queue_purge(&dev->mt76.mcu.res_q); +@@ -135,7 +134,6 @@ int mt7921s_mac_reset(struct mt792x_dev *dev) + + err = __mt7921_start(&dev->phy); + out: +- clear_bit(MT76_RESET, &dev->mphy.state); + + mt76_worker_enable(&dev->mt76.tx_worker); + +diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c +index 3e88798df0178..a4ed00eebc483 100644 +--- a/drivers/net/wireless/mediatek/mt76/sdio.c ++++ b/drivers/net/wireless/mediatek/mt76/sdio.c +@@ -499,7 +499,8 @@ static void mt76s_tx_status_data(struct mt76_worker *worker) + dev = container_of(sdio, struct mt76_dev, sdio); + + while (true) { +- if (test_bit(MT76_REMOVED, &dev->phy.state)) ++ if (test_bit(MT76_RESET, &dev->phy.state) || ++ test_bit(MT76_REMOVED, &dev->phy.state)) + break; + + if (!dev->drv->tx_status_data(dev, &update)) +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index d474b8d5df3dd..b8d419a5b9db0 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -4069,6 +4069,24 @@ void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg eve + } + } + ++void rtw89_check_quirks(struct rtw89_dev *rtwdev, const struct dmi_system_id *quirks) ++{ ++ const struct dmi_system_id *match; ++ enum rtw89_quirks quirk; ++ ++ if (!quirks) ++ return; ++ ++ for (match = dmi_first_match(quirks); match; match = dmi_first_match(match + 1)) { ++ quirk = (uintptr_t)match->driver_data; ++ if (quirk >= NUM_OF_RTW89_QUIRKS) ++ continue; ++ ++ set_bit(quirk, rtwdev->quirks); ++ } ++} ++EXPORT_SYMBOL(rtw89_check_quirks); ++ + int rtw89_core_start(struct rtw89_dev *rtwdev) + { + int ret; +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 2e854c9af7099..509d84a493348 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -7,6 +7,7 @@ + + #include <linux/average.h> + #include <linux/bitfield.h> ++#include <linux/dmi.h> + #include <linux/firmware.h> + #include <linux/iopoll.h> + #include <linux/workqueue.h> +@@ -3977,6 +3978,7 @@ union rtw89_bus_info { + + struct rtw89_driver_info { + const struct rtw89_chip_info *chip; ++ const struct dmi_system_id *quirks; + union rtw89_bus_info bus; + }; + +@@ -4324,6 +4326,12 @@ enum rtw89_flags { + NUM_OF_RTW89_FLAGS, + }; + ++enum rtw89_quirks { ++ RTW89_QUIRK_PCI_BER, ++ ++ NUM_OF_RTW89_QUIRKS, ++}; ++ + enum rtw89_pkt_drop_sel { + RTW89_PKT_DROP_SEL_MACID_BE_ONCE, + RTW89_PKT_DROP_SEL_MACID_BK_ONCE, +@@ -5084,6 +5092,7 @@ struct rtw89_dev { + DECLARE_BITMAP(mac_id_map, RTW89_MAX_MAC_ID_NUM); + DECLARE_BITMAP(flags, NUM_OF_RTW89_FLAGS); + DECLARE_BITMAP(pkt_offload, RTW89_MAX_PKT_OFLD_NUM); ++ DECLARE_BITMAP(quirks, NUM_OF_RTW89_QUIRKS); + + struct rtw89_phy_stat phystat; + struct rtw89_rfk_wait_info rfk_wait; +@@ -6129,6 +6138,7 @@ int rtw89_core_sta_remove(struct rtw89_dev *rtwdev, + void rtw89_core_set_tid_config(struct rtw89_dev *rtwdev, + struct ieee80211_sta *sta, + struct cfg80211_tid_config *tid_config); ++void rtw89_check_quirks(struct rtw89_dev *rtwdev, const struct dmi_system_id *quirks); + int rtw89_core_init(struct rtw89_dev *rtwdev); + void rtw89_core_deinit(struct rtw89_dev *rtwdev); + int rtw89_core_register(struct rtw89_dev *rtwdev); +diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c +index 0afe22e568f43..3b0d97da048dc 100644 +--- a/drivers/net/wireless/realtek/rtw89/pci.c ++++ b/drivers/net/wireless/realtek/rtw89/pci.c +@@ -2299,6 +2299,22 @@ static int rtw89_pci_deglitch_setting(struct rtw89_dev *rtwdev) + return 0; + } + ++static void rtw89_pci_ber(struct rtw89_dev *rtwdev) ++{ ++ u32 phy_offset; ++ ++ if (!test_bit(RTW89_QUIRK_PCI_BER, rtwdev->quirks)) ++ return; ++ ++ phy_offset = R_RAC_DIRECT_OFFSET_G1; ++ rtw89_write16(rtwdev, phy_offset + RAC_ANA1E * RAC_MULT, RAC_ANA1E_G1_VAL); ++ rtw89_write16(rtwdev, phy_offset + RAC_ANA2E * RAC_MULT, RAC_ANA2E_VAL); ++ ++ phy_offset = R_RAC_DIRECT_OFFSET_G2; ++ rtw89_write16(rtwdev, phy_offset + RAC_ANA1E * RAC_MULT, RAC_ANA1E_G2_VAL); ++ rtw89_write16(rtwdev, phy_offset + RAC_ANA2E * RAC_MULT, RAC_ANA2E_VAL); ++} ++ + static void rtw89_pci_rxdma_prefth(struct rtw89_dev *rtwdev) + { + if (rtwdev->chip->chip_id != RTL8852A) +@@ -2696,6 +2712,7 @@ static int rtw89_pci_ops_mac_pre_init_ax(struct rtw89_dev *rtwdev) + const struct rtw89_pci_info *info = rtwdev->pci_info; + int ret; + ++ rtw89_pci_ber(rtwdev); + rtw89_pci_rxdma_prefth(rtwdev); + rtw89_pci_l1off_pwroff(rtwdev); + rtw89_pci_deglitch_setting(rtwdev); +@@ -4172,6 +4189,8 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + rtwdev->hci.rpwm_addr = pci_info->rpwm_addr; + rtwdev->hci.cpwm_addr = pci_info->cpwm_addr; + ++ rtw89_check_quirks(rtwdev, info->quirks); ++ + SET_IEEE80211_DEV(rtwdev->hw, &pdev->dev); + + ret = rtw89_core_init(rtwdev); +diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h +index a63b6b7c9bfaf..87e7081664c1f 100644 +--- a/drivers/net/wireless/realtek/rtw89/pci.h ++++ b/drivers/net/wireless/realtek/rtw89/pci.h +@@ -26,11 +26,16 @@ + #define RAC_REG_FLD_0 0x1D + #define BAC_AUTOK_N_MASK GENMASK(3, 2) + #define PCIE_AUTOK_4 0x3 ++#define RAC_ANA1E 0x1E ++#define RAC_ANA1E_G1_VAL 0x66EA ++#define RAC_ANA1E_G2_VAL 0x6EEA + #define RAC_ANA1F 0x1F + #define RAC_ANA24 0x24 + #define B_AX_DEGLITCH GENMASK(11, 8) + #define RAC_ANA26 0x26 + #define B_AX_RXEN GENMASK(15, 14) ++#define RAC_ANA2E 0x2E ++#define RAC_ANA2E_VAL 0xFFFE + #define RAC_CTRL_PPR_V1 0x30 + #define B_AX_CLK_CALIB_EN BIT(12) + #define B_AX_CALIB_EN BIT(13) +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851be.c b/drivers/net/wireless/realtek/rtw89/rtw8851be.c +index ca1374a717272..ec3629d95fda1 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8851be.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8851be.c +@@ -63,6 +63,7 @@ static const struct rtw89_pci_info rtw8851b_pci_info = { + + static const struct rtw89_driver_info rtw89_8851be_info = { + .chip = &rtw8851b_chip_info, ++ .quirks = NULL, + .bus = { + .pci = &rtw8851b_pci_info, + }, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +index 7c6ffedb77e27..fdee5dd4ba148 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +@@ -61,6 +61,7 @@ static const struct rtw89_pci_info rtw8852a_pci_info = { + + static const struct rtw89_driver_info rtw89_8852ae_info = { + .chip = &rtw8852a_chip_info, ++ .quirks = NULL, + .bus = { + .pci = &rtw8852a_pci_info, + }, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852be.c b/drivers/net/wireless/realtek/rtw89/rtw8852be.c +index ed71364e6437b..5f941122655c4 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852be.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852be.c +@@ -63,6 +63,7 @@ static const struct rtw89_pci_info rtw8852b_pci_info = { + + static const struct rtw89_driver_info rtw89_8852be_info = { + .chip = &rtw8852b_chip_info, ++ .quirks = NULL, + .bus = { + .pci = &rtw8852b_pci_info, + }, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c +index 583ea673a4f54..e07c7f3ade41e 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c +@@ -68,8 +68,31 @@ static const struct rtw89_pci_info rtw8852c_pci_info = { + .recognize_intrs = rtw89_pci_recognize_intrs_v1, + }; + ++static const struct dmi_system_id rtw8852c_pci_quirks[] = { ++ { ++ .ident = "Dell Inc. Vostro 16 5640", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 16 5640"), ++ DMI_MATCH(DMI_PRODUCT_SKU, "0CA0"), ++ }, ++ .driver_data = (void *)RTW89_QUIRK_PCI_BER, ++ }, ++ { ++ .ident = "Dell Inc. Inspiron 16 5640", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 16 5640"), ++ DMI_MATCH(DMI_PRODUCT_SKU, "0C9F"), ++ }, ++ .driver_data = (void *)RTW89_QUIRK_PCI_BER, ++ }, ++ {}, ++}; ++ + static const struct rtw89_driver_info rtw89_8852ce_info = { + .chip = &rtw8852c_chip_info, ++ .quirks = rtw8852c_pci_quirks, + .bus = { + .pci = &rtw8852c_pci_info, + }, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922ae.c b/drivers/net/wireless/realtek/rtw89/rtw8922ae.c +index 4981b657bd7b0..ce8aaa9501e16 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8922ae.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8922ae.c +@@ -61,6 +61,7 @@ static const struct rtw89_pci_info rtw8922a_pci_info = { + + static const struct rtw89_driver_info rtw89_8922ae_info = { + .chip = &rtw8922a_chip_info, ++ .quirks = NULL, + .bus = { + .pci = &rtw8922a_pci_info, + }, +diff --git a/drivers/opp/core.c b/drivers/opp/core.c +index e233734b72205..cb4611fe1b5b2 100644 +--- a/drivers/opp/core.c ++++ b/drivers/opp/core.c +@@ -2394,7 +2394,8 @@ static void _opp_detach_genpd(struct opp_table *opp_table) + static int _opp_attach_genpd(struct opp_table *opp_table, struct device *dev, + const char * const *names, struct device ***virt_devs) + { +- struct device *virt_dev; ++ struct device *virt_dev, *gdev; ++ struct opp_table *genpd_table; + int index = 0, ret = -EINVAL; + const char * const *name = names; + +@@ -2427,6 +2428,34 @@ static int _opp_attach_genpd(struct opp_table *opp_table, struct device *dev, + goto err; + } + ++ /* ++ * The required_opp_tables parsing is not perfect, as the OPP ++ * core does the parsing solely based on the DT node pointers. ++ * The core sets the required_opp_tables entry to the first OPP ++ * table in the "opp_tables" list, that matches with the node ++ * pointer. ++ * ++ * If the target DT OPP table is used by multiple devices and ++ * they all create separate instances of 'struct opp_table' from ++ * it, then it is possible that the required_opp_tables entry ++ * may be set to the incorrect sibling device. ++ * ++ * Cross check it again and fix if required. ++ */ ++ gdev = dev_to_genpd_dev(virt_dev); ++ if (IS_ERR(gdev)) ++ return PTR_ERR(gdev); ++ ++ genpd_table = _find_opp_table(gdev); ++ if (!IS_ERR(genpd_table)) { ++ if (genpd_table != opp_table->required_opp_tables[index]) { ++ dev_pm_opp_put_opp_table(opp_table->required_opp_tables[index]); ++ opp_table->required_opp_tables[index] = genpd_table; ++ } else { ++ dev_pm_opp_put_opp_table(genpd_table); ++ } ++ } ++ + /* + * Add the virtual genpd device as a user of the OPP table, so + * we can call dev_pm_opp_set_opp() on it directly. +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 70b8c87055cb6..cbbf197df80f1 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -1277,6 +1277,11 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout) + for (;;) { + u32 id; + ++ if (pci_dev_is_disconnected(dev)) { ++ pci_dbg(dev, "disconnected; not waiting\n"); ++ return -ENOTTY; ++ } ++ + pci_read_config_dword(dev, PCI_COMMAND, &id); + if (!PCI_POSSIBLE_ERROR(id)) + break; +@@ -2962,6 +2967,18 @@ static const struct dmi_system_id bridge_d3_blacklist[] = { + DMI_MATCH(DMI_BOARD_VERSION, "Continental Z2"), + }, + }, ++ { ++ /* ++ * Changing power state of root port dGPU is connected fails ++ * https://gitlab.freedesktop.org/drm/amd/-/issues/3229 ++ */ ++ .ident = "Hewlett-Packard HP Pavilion 17 Notebook PC/1972", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_BOARD_NAME, "1972"), ++ DMI_MATCH(DMI_BOARD_VERSION, "95.33"), ++ }, ++ }, + #endif + { } + }; +diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +index acc2b5b9ea255..b8919443e46c9 100644 +--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c ++++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +@@ -187,6 +187,31 @@ static const unsigned int qmp_v6_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { + [QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V6_TX_TRANSCEIVER_BIAS_EN, + }; + ++static const unsigned int qmp_v6_n4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { ++ [QPHY_SW_RESET] = QPHY_V6_N4_PCS_SW_RESET, ++ [QPHY_START_CTRL] = QPHY_V6_N4_PCS_START_CONTROL, ++ [QPHY_PCS_STATUS] = QPHY_V6_N4_PCS_PCS_STATUS1, ++ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_N4_PCS_POWER_DOWN_CONTROL, ++ ++ /* In PCS_USB */ ++ [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V6_PCS_USB3_AUTONOMOUS_MODE_CTRL, ++ [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V6_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, ++ ++ [QPHY_COM_RESETSM_CNTRL] = QSERDES_V6_COM_RESETSM_CNTRL, ++ [QPHY_COM_C_READY_STATUS] = QSERDES_V6_COM_C_READY_STATUS, ++ [QPHY_COM_CMN_STATUS] = QSERDES_V6_COM_CMN_STATUS, ++ [QPHY_COM_BIAS_EN_CLKBUFLR_EN] = QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, ++ ++ [QPHY_DP_PHY_STATUS] = QSERDES_V6_DP_PHY_STATUS, ++ [QPHY_DP_PHY_VCO_DIV] = QSERDES_V6_DP_PHY_VCO_DIV, ++ ++ [QPHY_TX_TX_POL_INV] = QSERDES_V6_N4_TX_TX_POL_INV, ++ [QPHY_TX_TX_DRV_LVL] = QSERDES_V6_N4_TX_TX_DRV_LVL, ++ [QPHY_TX_TX_EMP_POST1_LVL] = QSERDES_V6_N4_TX_TX_EMP_POST1_LVL, ++ [QPHY_TX_HIGHZ_DRVR_EN] = QSERDES_V6_N4_TX_HIGHZ_DRVR_EN, ++ [QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V6_N4_TX_TRANSCEIVER_BIAS_EN, ++}; ++ + static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14), +@@ -997,6 +1022,31 @@ static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x0f), + }; + ++static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl[] = { ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SVS_MODE_CLK_SEL, 0x15), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x3b), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x02), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x0c), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_BUF_ENABLE, 0x06), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x30), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x07), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xc0), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x12), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN1_MODE0, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0a), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0, 0x14), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_CTRL, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 0x17), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x0f), ++}; ++ + static const struct qmp_phy_init_tbl qmp_v6_dp_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V6_TX_VMODE_CTRL1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V6_TX_PRE_STALL_LDO_BOOST_EN, 0x30), +@@ -1011,6 +1061,19 @@ static const struct qmp_phy_init_tbl qmp_v6_dp_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V6_TX_TX_BAND, 0x4), + }; + ++static const struct qmp_phy_init_tbl qmp_v6_n4_dp_tx_tbl[] = { ++ QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_VMODE_CTRL1, 0x40), ++ QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_PRE_STALL_LDO_BOOST_EN, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_INTERFACE_SELECT, 0xff), ++ QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_CLKBUF_ENABLE, 0x0f), ++ QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RESET_TSYNC_EN, 0x03), ++ QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_TRAN_DRVR_EMP_EN, 0x0f), ++ QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RES_CODE_LANE_OFFSET_TX, 0x11), ++ QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_RES_CODE_LANE_OFFSET_RX, 0x11), ++ QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_TX_BAND, 0x1), ++}; ++ + static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl_rbr[] = { + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34), +@@ -1059,6 +1122,74 @@ static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl_hbr3[] = { + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c), + }; + ++static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl_rbr[] = { ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x05), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x04), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x0b), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x37), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x04), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x71), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_ADJ_PER1, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x6b), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0x92), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01), ++}; ++ ++static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl_hbr[] = { ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x03), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x08), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x0b), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x07), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x71), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_ADJ_PER1, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x6b), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0x92), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01), ++}; ++ ++static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl_hbr2[] = { ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x01), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x46), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x08), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x05), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x0f), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0e), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x97), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x10), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_ADJ_PER1, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x6b), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0x18), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x02), ++}; ++ ++static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl_hbr3[] = { ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x08), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x0b), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x17), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x15), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x71), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_ADJ_PER1, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x6b), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x02), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0x92), ++ QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01), ++}; ++ + static const struct qmp_phy_init_tbl sc8280xp_usb43dp_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31), +@@ -1273,20 +1404,20 @@ static const struct qmp_phy_init_tbl x1e80100_usb43dp_rx_tbl[] = { + }; + + static const struct qmp_phy_init_tbl x1e80100_usb43dp_pcs_tbl[] = { +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_LOCK_DETECT_CONFIG1, 0xc4), +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_LOCK_DETECT_CONFIG2, 0x89), +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_LOCK_DETECT_CONFIG3, 0x20), +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_LOCK_DETECT_CONFIG6, 0x13), +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_REFGEN_REQ_CONFIG1, 0x21), +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_RX_SIGDET_LVL, 0x55), +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_CDR_RESET_TIME, 0x0a), +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_ALIGN_DETECT_CONFIG1, 0xd4), +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_ALIGN_DETECT_CONFIG2, 0x30), +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_PCS_TX_RX_CONFIG, 0x0c), +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_EQ_CONFIG1, 0x4b), +- QMP_PHY_INIT_CFG(QPHY_V6_PCS_EQ_CONFIG5, 0x10), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG1, 0xc4), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG2, 0x89), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG3, 0x20), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG6, 0x13), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_REFGEN_REQ_CONFIG1, 0x21), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_RX_SIGDET_LVL, 0x55), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_RX_CONFIG, 0x0a), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_ALIGN_DETECT_CONFIG1, 0xd4), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_ALIGN_DETECT_CONFIG2, 0x30), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_PCS_TX_RX_CONFIG, 0x0c), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_EQ_CONFIG1, 0x4b), ++ QMP_PHY_INIT_CFG(QPHY_V6_N4_PCS_EQ_CONFIG5, 0x10), + }; + + static const struct qmp_phy_init_tbl x1e80100_usb43dp_pcs_usb_tbl[] = { +@@ -1794,22 +1925,22 @@ static const struct qmp_phy_cfg x1e80100_usb3dpphy_cfg = { + .pcs_usb_tbl = x1e80100_usb43dp_pcs_usb_tbl, + .pcs_usb_tbl_num = ARRAY_SIZE(x1e80100_usb43dp_pcs_usb_tbl), + +- .dp_serdes_tbl = qmp_v6_dp_serdes_tbl, +- .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl), +- .dp_tx_tbl = qmp_v6_dp_tx_tbl, +- .dp_tx_tbl_num = ARRAY_SIZE(qmp_v6_dp_tx_tbl), ++ .dp_serdes_tbl = qmp_v6_n4_dp_serdes_tbl, ++ .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v6_n4_dp_serdes_tbl), ++ .dp_tx_tbl = qmp_v6_n4_dp_tx_tbl, ++ .dp_tx_tbl_num = ARRAY_SIZE(qmp_v6_n4_dp_tx_tbl), + +- .serdes_tbl_rbr = qmp_v6_dp_serdes_tbl_rbr, +- .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_rbr), +- .serdes_tbl_hbr = qmp_v6_dp_serdes_tbl_hbr, +- .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr), +- .serdes_tbl_hbr2 = qmp_v6_dp_serdes_tbl_hbr2, +- .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr2), +- .serdes_tbl_hbr3 = qmp_v6_dp_serdes_tbl_hbr3, +- .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr3), ++ .serdes_tbl_rbr = qmp_v6_n4_dp_serdes_tbl_rbr, ++ .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v6_n4_dp_serdes_tbl_rbr), ++ .serdes_tbl_hbr = qmp_v6_n4_dp_serdes_tbl_hbr, ++ .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v6_n4_dp_serdes_tbl_hbr), ++ .serdes_tbl_hbr2 = qmp_v6_n4_dp_serdes_tbl_hbr2, ++ .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v6_n4_dp_serdes_tbl_hbr2), ++ .serdes_tbl_hbr3 = qmp_v6_n4_dp_serdes_tbl_hbr3, ++ .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v6_n4_dp_serdes_tbl_hbr3), + +- .swing_hbr_rbr = &qmp_dp_v5_voltage_swing_hbr_rbr, +- .pre_emphasis_hbr_rbr = &qmp_dp_v5_pre_emphasis_hbr_rbr, ++ .swing_hbr_rbr = &qmp_dp_v6_voltage_swing_hbr_rbr, ++ .pre_emphasis_hbr_rbr = &qmp_dp_v6_pre_emphasis_hbr_rbr, + .swing_hbr3_hbr2 = &qmp_dp_v5_voltage_swing_hbr3_hbr2, + .pre_emphasis_hbr3_hbr2 = &qmp_dp_v5_pre_emphasis_hbr3_hbr2, + +@@ -1822,7 +1953,7 @@ static const struct qmp_phy_cfg x1e80100_usb3dpphy_cfg = { + .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), +- .regs = qmp_v45_usb3phy_regs_layout, ++ .regs = qmp_v6_n4_usb3phy_regs_layout, + }; + + static const struct qmp_phy_cfg sm6350_usb3dpphy_cfg = { +diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6-n4.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6-n4.h +new file mode 100644 +index 0000000000000..b3024714dab4e +--- /dev/null ++++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v6-n4.h +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (c) 2023, Linaro Limited ++ */ ++ ++#ifndef QCOM_PHY_QMP_PCS_V6_N4_H_ ++#define QCOM_PHY_QMP_PCS_V6_N4_H_ ++ ++/* Only for QMP V6 N4 PHY - USB/PCIe PCS registers */ ++#define QPHY_V6_N4_PCS_SW_RESET 0x000 ++#define QPHY_V6_N4_PCS_PCS_STATUS1 0x014 ++#define QPHY_V6_N4_PCS_POWER_DOWN_CONTROL 0x040 ++#define QPHY_V6_N4_PCS_START_CONTROL 0x044 ++#define QPHY_V6_N4_PCS_POWER_STATE_CONFIG1 0x090 ++#define QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG1 0x0c4 ++#define QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG2 0x0c8 ++#define QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG3 0x0cc ++#define QPHY_V6_N4_PCS_LOCK_DETECT_CONFIG6 0x0d8 ++#define QPHY_V6_N4_PCS_REFGEN_REQ_CONFIG1 0x0dc ++#define QPHY_V6_N4_PCS_RX_SIGDET_LVL 0x188 ++#define QPHY_V6_N4_PCS_RCVR_DTCT_DLY_P1U2_L 0x190 ++#define QPHY_V6_N4_PCS_RCVR_DTCT_DLY_P1U2_H 0x194 ++#define QPHY_V6_N4_PCS_RATE_SLEW_CNTRL1 0x198 ++#define QPHY_V6_N4_PCS_RX_CONFIG 0x1b0 ++#define QPHY_V6_N4_PCS_ALIGN_DETECT_CONFIG1 0x1c0 ++#define QPHY_V6_N4_PCS_ALIGN_DETECT_CONFIG2 0x1c4 ++#define QPHY_V6_N4_PCS_PCS_TX_RX_CONFIG 0x1d0 ++#define QPHY_V6_N4_PCS_EQ_CONFIG1 0x1dc ++#define QPHY_V6_N4_PCS_EQ_CONFIG2 0x1e0 ++#define QPHY_V6_N4_PCS_EQ_CONFIG5 0x1ec ++ ++#endif +diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_n4.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_n4.h +index a814ad11af071..d37cc0d4fd365 100644 +--- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_n4.h ++++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v6_n4.h +@@ -6,11 +6,24 @@ + #ifndef QCOM_PHY_QMP_QSERDES_TXRX_V6_N4_H_ + #define QCOM_PHY_QMP_QSERDES_TXRX_V6_N4_H_ + ++#define QSERDES_V6_N4_TX_CLKBUF_ENABLE 0x08 ++#define QSERDES_V6_N4_TX_TX_EMP_POST1_LVL 0x0c ++#define QSERDES_V6_N4_TX_TX_DRV_LVL 0x14 ++#define QSERDES_V6_N4_TX_RESET_TSYNC_EN 0x1c ++#define QSERDES_V6_N4_TX_PRE_STALL_LDO_BOOST_EN 0x20 + #define QSERDES_V6_N4_TX_RES_CODE_LANE_OFFSET_TX 0x30 + #define QSERDES_V6_N4_TX_RES_CODE_LANE_OFFSET_RX 0x34 ++#define QSERDES_V6_N4_TX_TRANSCEIVER_BIAS_EN 0x48 ++#define QSERDES_V6_N4_TX_HIGHZ_DRVR_EN 0x4c ++#define QSERDES_V6_N4_TX_TX_POL_INV 0x50 ++#define QSERDES_V6_N4_TX_PARRATE_REC_DETECT_IDLE_EN 0x54 + #define QSERDES_V6_N4_TX_LANE_MODE_1 0x78 + #define QSERDES_V6_N4_TX_LANE_MODE_2 0x7c + #define QSERDES_V6_N4_TX_LANE_MODE_3 0x80 ++#define QSERDES_V6_N4_TX_TRAN_DRVR_EMP_EN 0xac ++#define QSERDES_V6_N4_TX_TX_BAND 0xd8 ++#define QSERDES_V6_N4_TX_INTERFACE_SELECT 0xe4 ++#define QSERDES_V6_N4_TX_VMODE_CTRL1 0xb0 + + #define QSERDES_V6_N4_RX_UCDR_FO_GAIN_RATE2 0x8 + #define QSERDES_V6_N4_RX_UCDR_SO_GAIN_RATE2 0x18 +diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h +index d10b8f653c4b2..d0f41e4aaa855 100644 +--- a/drivers/phy/qualcomm/phy-qcom-qmp.h ++++ b/drivers/phy/qualcomm/phy-qcom-qmp.h +@@ -46,6 +46,8 @@ + + #include "phy-qcom-qmp-pcs-v6.h" + ++#include "phy-qcom-qmp-pcs-v6-n4.h" ++ + #include "phy-qcom-qmp-pcs-v6_20.h" + + #include "phy-qcom-qmp-pcs-v7.h" +diff --git a/drivers/platform/chrome/cros_usbpd_logger.c b/drivers/platform/chrome/cros_usbpd_logger.c +index f618757f8b321..930c2f47269f6 100644 +--- a/drivers/platform/chrome/cros_usbpd_logger.c ++++ b/drivers/platform/chrome/cros_usbpd_logger.c +@@ -7,6 +7,7 @@ + + #include <linux/ktime.h> + #include <linux/math64.h> ++#include <linux/mod_devicetable.h> + #include <linux/module.h> + #include <linux/platform_data/cros_ec_commands.h> + #include <linux/platform_data/cros_ec_proto.h> +@@ -249,6 +250,12 @@ static int __maybe_unused cros_usbpd_logger_suspend(struct device *dev) + static SIMPLE_DEV_PM_OPS(cros_usbpd_logger_pm_ops, cros_usbpd_logger_suspend, + cros_usbpd_logger_resume); + ++static const struct platform_device_id cros_usbpd_logger_id[] = { ++ { DRV_NAME, 0 }, ++ {} ++}; ++MODULE_DEVICE_TABLE(platform, cros_usbpd_logger_id); ++ + static struct platform_driver cros_usbpd_logger_driver = { + .driver = { + .name = DRV_NAME, +@@ -256,10 +263,10 @@ static struct platform_driver cros_usbpd_logger_driver = { + }, + .probe = cros_usbpd_logger_probe, + .remove_new = cros_usbpd_logger_remove, ++ .id_table = cros_usbpd_logger_id, + }; + + module_platform_driver(cros_usbpd_logger_driver); + + MODULE_LICENSE("GPL v2"); + MODULE_DESCRIPTION("Logging driver for ChromeOS EC USBPD Charger."); +-MODULE_ALIAS("platform:" DRV_NAME); +diff --git a/drivers/platform/chrome/cros_usbpd_notify.c b/drivers/platform/chrome/cros_usbpd_notify.c +index aacad022f21df..c83f81d86483c 100644 +--- a/drivers/platform/chrome/cros_usbpd_notify.c ++++ b/drivers/platform/chrome/cros_usbpd_notify.c +@@ -6,6 +6,7 @@ + */ + + #include <linux/acpi.h> ++#include <linux/mod_devicetable.h> + #include <linux/module.h> + #include <linux/platform_data/cros_ec_proto.h> + #include <linux/platform_data/cros_usbpd_notify.h> +@@ -218,12 +219,19 @@ static void cros_usbpd_notify_remove_plat(struct platform_device *pdev) + &pdnotify->nb); + } + ++static const struct platform_device_id cros_usbpd_notify_id[] = { ++ { DRV_NAME, 0 }, ++ {} ++}; ++MODULE_DEVICE_TABLE(platform, cros_usbpd_notify_id); ++ + static struct platform_driver cros_usbpd_notify_plat_driver = { + .driver = { + .name = DRV_NAME, + }, + .probe = cros_usbpd_notify_probe_plat, + .remove_new = cros_usbpd_notify_remove_plat, ++ .id_table = cros_usbpd_notify_id, + }; + + static int __init cros_usbpd_notify_init(void) +@@ -258,4 +266,3 @@ module_exit(cros_usbpd_notify_exit); + MODULE_LICENSE("GPL"); + MODULE_DESCRIPTION("ChromeOS power delivery notifier device"); + MODULE_AUTHOR("Jon Flatley <jflat@chromium.org>"); +-MODULE_ALIAS("platform:" DRV_NAME); +diff --git a/drivers/platform/x86/p2sb.c b/drivers/platform/x86/p2sb.c +index 3d66e1d4eb1f5..1ac30034f3e59 100644 +--- a/drivers/platform/x86/p2sb.c ++++ b/drivers/platform/x86/p2sb.c +@@ -56,12 +56,9 @@ static int p2sb_get_devfn(unsigned int *devfn) + return 0; + } + +-static bool p2sb_valid_resource(struct resource *res) ++static bool p2sb_valid_resource(const struct resource *res) + { +- if (res->flags) +- return true; +- +- return false; ++ return res->flags & ~IORESOURCE_UNSET; + } + + /* Copy resource from the first BAR of the device in question */ +@@ -220,16 +217,20 @@ EXPORT_SYMBOL_GPL(p2sb_bar); + + static int __init p2sb_fs_init(void) + { +- p2sb_cache_resources(); +- return 0; ++ return p2sb_cache_resources(); + } + + /* +- * pci_rescan_remove_lock to avoid access to unhidden P2SB devices can +- * not be locked in sysfs pci bus rescan path because of deadlock. To +- * avoid the deadlock, access to P2SB devices with the lock at an early +- * step in kernel initialization and cache required resources. This +- * should happen after subsys_initcall which initializes PCI subsystem +- * and before device_initcall which requires P2SB resources. ++ * pci_rescan_remove_lock() can not be locked in sysfs PCI bus rescan path ++ * because of deadlock. To avoid the deadlock, access P2SB devices with the lock ++ * at an early step in kernel initialization and cache required resources. ++ * ++ * We want to run as early as possible. If the P2SB was assigned a bad BAR, ++ * we'll need to wait on pcibios_assign_resources() to fix it. So, our list of ++ * initcall dependencies looks something like this: ++ * ++ * ... ++ * subsys_initcall (pci_subsys_init) ++ * fs_initcall (pcibios_assign_resources) + */ +-fs_initcall(p2sb_fs_init); ++fs_initcall_sync(p2sb_fs_init); +diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c +index 77244c9aa60d2..16e941449b144 100644 +--- a/drivers/platform/x86/toshiba_acpi.c ++++ b/drivers/platform/x86/toshiba_acpi.c +@@ -57,6 +57,11 @@ module_param(turn_on_panel_on_resume, int, 0644); + MODULE_PARM_DESC(turn_on_panel_on_resume, + "Call HCI_PANEL_POWER_ON on resume (-1 = auto, 0 = no, 1 = yes"); + ++static int hci_hotkey_quickstart = -1; ++module_param(hci_hotkey_quickstart, int, 0644); ++MODULE_PARM_DESC(hci_hotkey_quickstart, ++ "Call HCI_HOTKEY_EVENT with value 0x5 for quickstart button support (-1 = auto, 0 = no, 1 = yes"); ++ + #define TOSHIBA_WMI_EVENT_GUID "59142400-C6A3-40FA-BADB-8A2652834100" + + /* Scan code for Fn key on TOS1900 models */ +@@ -136,6 +141,7 @@ MODULE_PARM_DESC(turn_on_panel_on_resume, + #define HCI_ACCEL_MASK 0x7fff + #define HCI_ACCEL_DIRECTION_MASK 0x8000 + #define HCI_HOTKEY_DISABLE 0x0b ++#define HCI_HOTKEY_ENABLE_QUICKSTART 0x05 + #define HCI_HOTKEY_ENABLE 0x09 + #define HCI_HOTKEY_SPECIAL_FUNCTIONS 0x10 + #define HCI_LCD_BRIGHTNESS_BITS 3 +@@ -2731,10 +2737,15 @@ static int toshiba_acpi_enable_hotkeys(struct toshiba_acpi_dev *dev) + return -ENODEV; + + /* ++ * Enable quickstart buttons if supported. ++ * + * Enable the "Special Functions" mode only if they are + * supported and if they are activated. + */ +- if (dev->kbd_function_keys_supported && dev->special_functions) ++ if (hci_hotkey_quickstart) ++ result = hci_write(dev, HCI_HOTKEY_EVENT, ++ HCI_HOTKEY_ENABLE_QUICKSTART); ++ else if (dev->kbd_function_keys_supported && dev->special_functions) + result = hci_write(dev, HCI_HOTKEY_EVENT, + HCI_HOTKEY_SPECIAL_FUNCTIONS); + else +@@ -3258,7 +3269,14 @@ static const char *find_hci_method(acpi_handle handle) + * works. toshiba_acpi_resume() uses HCI_PANEL_POWER_ON to avoid changing + * the configured brightness level. + */ +-static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = { ++#define QUIRK_TURN_ON_PANEL_ON_RESUME BIT(0) ++/* ++ * Some Toshibas use "quickstart" keys. On these, HCI_HOTKEY_EVENT must use ++ * the value HCI_HOTKEY_ENABLE_QUICKSTART. ++ */ ++#define QUIRK_HCI_HOTKEY_QUICKSTART BIT(1) ++ ++static const struct dmi_system_id toshiba_dmi_quirks[] = { + { + /* Toshiba Portégé R700 */ + /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */ +@@ -3266,6 +3284,7 @@ static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R700"), + }, ++ .driver_data = (void *)QUIRK_TURN_ON_PANEL_ON_RESUME, + }, + { + /* Toshiba Satellite/Portégé R830 */ +@@ -3275,6 +3294,7 @@ static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "R830"), + }, ++ .driver_data = (void *)QUIRK_TURN_ON_PANEL_ON_RESUME, + }, + { + /* Toshiba Satellite/Portégé Z830 */ +@@ -3282,6 +3302,7 @@ static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Z830"), + }, ++ .driver_data = (void *)(QUIRK_TURN_ON_PANEL_ON_RESUME | QUIRK_HCI_HOTKEY_QUICKSTART), + }, + }; + +@@ -3290,6 +3311,8 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) + struct toshiba_acpi_dev *dev; + const char *hci_method; + u32 dummy; ++ const struct dmi_system_id *dmi_id; ++ long quirks = 0; + int ret = 0; + + if (toshiba_acpi) +@@ -3442,8 +3465,15 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) + } + #endif + ++ dmi_id = dmi_first_match(toshiba_dmi_quirks); ++ if (dmi_id) ++ quirks = (long)dmi_id->driver_data; ++ + if (turn_on_panel_on_resume == -1) +- turn_on_panel_on_resume = dmi_check_system(turn_on_panel_on_resume_dmi_ids); ++ turn_on_panel_on_resume = !!(quirks & QUIRK_TURN_ON_PANEL_ON_RESUME); ++ ++ if (hci_hotkey_quickstart == -1) ++ hci_hotkey_quickstart = !!(quirks & QUIRK_HCI_HOTKEY_QUICKSTART); + + toshiba_wwan_available(dev); + if (dev->wwan_supported) +diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c +index a3415f1c0b5f8..6559bb4ea7305 100644 +--- a/drivers/platform/x86/x86-android-tablets/core.c ++++ b/drivers/platform/x86/x86-android-tablets/core.c +@@ -278,25 +278,25 @@ static void x86_android_tablet_remove(struct platform_device *pdev) + { + int i; + +- for (i = 0; i < serdev_count; i++) { ++ for (i = serdev_count - 1; i >= 0; i--) { + if (serdevs[i]) + serdev_device_remove(serdevs[i]); + } + + kfree(serdevs); + +- for (i = 0; i < pdev_count; i++) ++ for (i = pdev_count - 1; i >= 0; i--) + platform_device_unregister(pdevs[i]); + + kfree(pdevs); + kfree(buttons); + +- for (i = 0; i < spi_dev_count; i++) ++ for (i = spi_dev_count - 1; i >= 0; i--) + spi_unregister_device(spi_devs[i]); + + kfree(spi_devs); + +- for (i = 0; i < i2c_client_count; i++) ++ for (i = i2c_client_count - 1; i >= 0; i--) + i2c_unregister_device(i2c_clients[i]); + + kfree(i2c_clients); +diff --git a/drivers/platform/x86/x86-android-tablets/dmi.c b/drivers/platform/x86/x86-android-tablets/dmi.c +index 5d6c12494f082..141a2d25e83be 100644 +--- a/drivers/platform/x86/x86-android-tablets/dmi.c ++++ b/drivers/platform/x86/x86-android-tablets/dmi.c +@@ -104,6 +104,24 @@ const struct dmi_system_id x86_android_tablet_ids[] __initconst = { + }, + .driver_data = (void *)&lenovo_yogabook_x91_info, + }, ++ { ++ /* ++ * Lenovo Yoga Tablet 2 Pro 1380F/L (13") This has more or less ++ * the same BIOS as the 830F/L or 1050F/L (8" and 10") below, ++ * but unlike the 8" / 10" models which share the same mainboard ++ * this model has a different mainboard. ++ * This match for the 13" model MUST come before the 8" + 10" ++ * match since that one will also match the 13" model! ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"), ++ DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"), ++ /* Full match so as to NOT match the 830/1050 BIOS */ ++ DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21.X64.0005.R00.1504101516"), ++ }, ++ .driver_data = (void *)&lenovo_yoga_tab2_1380_info, ++ }, + { + /* + * Lenovo Yoga Tablet 2 830F/L or 1050F/L (The 8" and 10" +diff --git a/drivers/platform/x86/x86-android-tablets/lenovo.c b/drivers/platform/x86/x86-android-tablets/lenovo.c +index c297391955adb..16fa04d604a09 100644 +--- a/drivers/platform/x86/x86-android-tablets/lenovo.c ++++ b/drivers/platform/x86/x86-android-tablets/lenovo.c +@@ -19,6 +19,7 @@ + #include <linux/pinctrl/machine.h> + #include <linux/platform_data/lp855x.h> + #include <linux/platform_device.h> ++#include <linux/power/bq24190_charger.h> + #include <linux/reboot.h> + #include <linux/rmi.h> + #include <linux/spi/spi.h> +@@ -565,6 +566,221 @@ static void lenovo_yoga_tab2_830_1050_exit(void) + } + } + ++/* ++ * Lenovo Yoga Tablet 2 Pro 1380F/L ++ * ++ * The Lenovo Yoga Tablet 2 Pro 1380F/L mostly has the same design as the 830F/L ++ * and the 1050F/L so this re-uses some of the handling for that from above. ++ */ ++static const char * const lc824206xa_chg_det_psy[] = { "lc824206xa-charger-detect" }; ++ ++static const struct property_entry lenovo_yoga_tab2_1380_bq24190_props[] = { ++ PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lc824206xa_chg_det_psy), ++ PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node), ++ PROPERTY_ENTRY_BOOL("omit-battery-class"), ++ PROPERTY_ENTRY_BOOL("disable-reset"), ++ { } ++}; ++ ++static const struct software_node lenovo_yoga_tab2_1380_bq24190_node = { ++ .properties = lenovo_yoga_tab2_1380_bq24190_props, ++}; ++ ++/* For enabling the bq24190 5V boost based on id-pin */ ++static struct regulator_consumer_supply lc824206xa_consumer = { ++ .supply = "vbus", ++ .dev_name = "i2c-lc824206xa", ++}; ++ ++static const struct regulator_init_data lenovo_yoga_tab2_1380_bq24190_vbus_init_data = { ++ .constraints = { ++ .name = "bq24190_vbus", ++ .valid_ops_mask = REGULATOR_CHANGE_STATUS, ++ }, ++ .consumer_supplies = &lc824206xa_consumer, ++ .num_consumer_supplies = 1, ++}; ++ ++struct bq24190_platform_data lenovo_yoga_tab2_1380_bq24190_pdata = { ++ .regulator_init_data = &lenovo_yoga_tab2_1380_bq24190_vbus_init_data, ++}; ++ ++static const struct property_entry lenovo_yoga_tab2_1380_lc824206xa_props[] = { ++ PROPERTY_ENTRY_BOOL("onnn,enable-miclr-for-dcp"), ++ { } ++}; ++ ++static const struct software_node lenovo_yoga_tab2_1380_lc824206xa_node = { ++ .properties = lenovo_yoga_tab2_1380_lc824206xa_props, ++}; ++ ++static const char * const lenovo_yoga_tab2_1380_lms303d_mount_matrix[] = { ++ "0", "-1", "0", ++ "-1", "0", "0", ++ "0", "0", "1" ++}; ++ ++static const struct property_entry lenovo_yoga_tab2_1380_lms303d_props[] = { ++ PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", lenovo_yoga_tab2_1380_lms303d_mount_matrix), ++ { } ++}; ++ ++static const struct software_node lenovo_yoga_tab2_1380_lms303d_node = { ++ .properties = lenovo_yoga_tab2_1380_lms303d_props, ++}; ++ ++static const struct x86_i2c_client_info lenovo_yoga_tab2_1380_i2c_clients[] __initconst = { ++ { ++ /* BQ27541 fuel-gauge */ ++ .board_info = { ++ .type = "bq27541", ++ .addr = 0x55, ++ .dev_name = "bq27541", ++ .swnode = &fg_bq24190_supply_node, ++ }, ++ .adapter_path = "\\_SB_.I2C1", ++ }, { ++ /* bq24292i battery charger */ ++ .board_info = { ++ .type = "bq24190", ++ .addr = 0x6b, ++ .dev_name = "bq24292i", ++ .swnode = &lenovo_yoga_tab2_1380_bq24190_node, ++ .platform_data = &lenovo_yoga_tab2_1380_bq24190_pdata, ++ }, ++ .adapter_path = "\\_SB_.I2C1", ++ .irq_data = { ++ .type = X86_ACPI_IRQ_TYPE_GPIOINT, ++ .chip = "INT33FC:02", ++ .index = 2, ++ .trigger = ACPI_EDGE_SENSITIVE, ++ .polarity = ACPI_ACTIVE_HIGH, ++ .con_id = "bq24292i_irq", ++ }, ++ }, { ++ /* LP8557 Backlight controller */ ++ .board_info = { ++ .type = "lp8557", ++ .addr = 0x2c, ++ .dev_name = "lp8557", ++ .platform_data = &lenovo_lp8557_pwm_and_reg_pdata, ++ }, ++ .adapter_path = "\\_SB_.I2C3", ++ }, { ++ /* LC824206XA Micro USB Switch */ ++ .board_info = { ++ .type = "lc824206xa", ++ .addr = 0x48, ++ .dev_name = "lc824206xa", ++ .swnode = &lenovo_yoga_tab2_1380_lc824206xa_node, ++ }, ++ .adapter_path = "\\_SB_.I2C3", ++ .irq_data = { ++ .type = X86_ACPI_IRQ_TYPE_GPIOINT, ++ .chip = "INT33FC:02", ++ .index = 1, ++ .trigger = ACPI_LEVEL_SENSITIVE, ++ .polarity = ACPI_ACTIVE_LOW, ++ .con_id = "lc824206xa_irq", ++ }, ++ }, { ++ /* AL3320A ambient light sensor */ ++ .board_info = { ++ .type = "al3320a", ++ .addr = 0x1c, ++ .dev_name = "al3320a", ++ }, ++ .adapter_path = "\\_SB_.I2C5", ++ }, { ++ /* LSM303DA accelerometer + magnetometer */ ++ .board_info = { ++ .type = "lsm303d", ++ .addr = 0x1d, ++ .dev_name = "lsm303d", ++ .swnode = &lenovo_yoga_tab2_1380_lms303d_node, ++ }, ++ .adapter_path = "\\_SB_.I2C5", ++ }, { ++ /* Synaptics RMI touchscreen */ ++ .board_info = { ++ .type = "rmi4_i2c", ++ .addr = 0x38, ++ .dev_name = "rmi4_i2c", ++ .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata, ++ }, ++ .adapter_path = "\\_SB_.I2C6", ++ .irq_data = { ++ .type = X86_ACPI_IRQ_TYPE_APIC, ++ .index = 0x45, ++ .trigger = ACPI_EDGE_SENSITIVE, ++ .polarity = ACPI_ACTIVE_HIGH, ++ }, ++ } ++}; ++ ++static const struct platform_device_info lenovo_yoga_tab2_1380_pdevs[] __initconst = { ++ { ++ /* For the Tablet 2 Pro 1380's custom fast charging driver */ ++ .name = "lenovo-yoga-tab2-pro-1380-fastcharger", ++ .id = PLATFORM_DEVID_NONE, ++ }, ++}; ++ ++const char * const lenovo_yoga_tab2_1380_modules[] __initconst = { ++ "bq24190_charger", /* For the Vbus regulator for lc824206xa */ ++ NULL ++}; ++ ++static int __init lenovo_yoga_tab2_1380_init(void) ++{ ++ int ret; ++ ++ /* To verify that the DMI matching works vs the 830 / 1050 models */ ++ pr_info("detected Lenovo Yoga Tablet 2 Pro 1380F/L\n"); ++ ++ ret = lenovo_yoga_tab2_830_1050_init_codec(); ++ if (ret) ++ return ret; ++ ++ /* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */ ++ lenovo_yoga_tab2_830_1050_sys_off_handler = ++ register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1, ++ lenovo_yoga_tab2_830_1050_power_off, NULL); ++ if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler)) ++ return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler); ++ ++ return 0; ++} ++ ++static struct gpiod_lookup_table lenovo_yoga_tab2_1380_fc_gpios = { ++ .dev_id = "serial0-0", ++ .table = { ++ GPIO_LOOKUP("INT33FC:00", 57, "uart3_txd", GPIO_ACTIVE_HIGH), ++ GPIO_LOOKUP("INT33FC:00", 61, "uart3_rxd", GPIO_ACTIVE_HIGH), ++ { } ++ }, ++}; ++ ++static struct gpiod_lookup_table * const lenovo_yoga_tab2_1380_gpios[] = { ++ &lenovo_yoga_tab2_830_1050_codec_gpios, ++ &lenovo_yoga_tab2_1380_fc_gpios, ++ NULL ++}; ++ ++const struct x86_dev_info lenovo_yoga_tab2_1380_info __initconst = { ++ .i2c_client_info = lenovo_yoga_tab2_1380_i2c_clients, ++ .i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_i2c_clients), ++ .pdev_info = lenovo_yoga_tab2_1380_pdevs, ++ .pdev_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_pdevs), ++ .gpio_button = &lenovo_yoga_tab2_830_1050_lid, ++ .gpio_button_count = 1, ++ .gpiod_lookup_tables = lenovo_yoga_tab2_1380_gpios, ++ .bat_swnode = &generic_lipo_hv_4v35_battery_node, ++ .modules = lenovo_yoga_tab2_1380_modules, ++ .init = lenovo_yoga_tab2_1380_init, ++ .exit = lenovo_yoga_tab2_830_1050_exit, ++}; ++ + /* Lenovo Yoga Tab 3 Pro YT3-X90F */ + + /* +diff --git a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h +index 468993edfeee2..821dc094b0254 100644 +--- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h ++++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h +@@ -112,6 +112,7 @@ extern const struct x86_dev_info czc_p10t; + extern const struct x86_dev_info lenovo_yogabook_x90_info; + extern const struct x86_dev_info lenovo_yogabook_x91_info; + extern const struct x86_dev_info lenovo_yoga_tab2_830_1050_info; ++extern const struct x86_dev_info lenovo_yoga_tab2_1380_info; + extern const struct x86_dev_info lenovo_yt3_info; + extern const struct x86_dev_info medion_lifetab_s10346_info; + extern const struct x86_dev_info nextbook_ares8_info; +diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c +index 4215ffd9b11c5..c40eda92a85a7 100644 +--- a/drivers/pmdomain/core.c ++++ b/drivers/pmdomain/core.c +@@ -184,6 +184,16 @@ static struct generic_pm_domain *dev_to_genpd(struct device *dev) + return pd_to_genpd(dev->pm_domain); + } + ++struct device *dev_to_genpd_dev(struct device *dev) ++{ ++ struct generic_pm_domain *genpd = dev_to_genpd(dev); ++ ++ if (IS_ERR(genpd)) ++ return ERR_CAST(genpd); ++ ++ return &genpd->dev; ++} ++ + static int genpd_stop_dev(const struct generic_pm_domain *genpd, + struct device *dev) + { +diff --git a/drivers/power/supply/cros_usbpd-charger.c b/drivers/power/supply/cros_usbpd-charger.c +index b6c96376776a9..8008e31c0c098 100644 +--- a/drivers/power/supply/cros_usbpd-charger.c ++++ b/drivers/power/supply/cros_usbpd-charger.c +@@ -5,6 +5,7 @@ + * Copyright (c) 2014 - 2018 Google, Inc + */ + ++#include <linux/mod_devicetable.h> + #include <linux/module.h> + #include <linux/platform_data/cros_ec_commands.h> + #include <linux/platform_data/cros_ec_proto.h> +@@ -711,16 +712,22 @@ static int cros_usbpd_charger_resume(struct device *dev) + static SIMPLE_DEV_PM_OPS(cros_usbpd_charger_pm_ops, NULL, + cros_usbpd_charger_resume); + ++static const struct platform_device_id cros_usbpd_charger_id[] = { ++ { DRV_NAME, 0 }, ++ {} ++}; ++MODULE_DEVICE_TABLE(platform, cros_usbpd_charger_id); ++ + static struct platform_driver cros_usbpd_charger_driver = { + .driver = { + .name = DRV_NAME, + .pm = &cros_usbpd_charger_pm_ops, + }, +- .probe = cros_usbpd_charger_probe ++ .probe = cros_usbpd_charger_probe, ++ .id_table = cros_usbpd_charger_id, + }; + + module_platform_driver(cros_usbpd_charger_driver); + + MODULE_LICENSE("GPL"); + MODULE_DESCRIPTION("ChromeOS EC USBPD charger"); +-MODULE_ALIAS("platform:" DRV_NAME); +diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c +index a15460aaa03b3..6b1b8f57cd951 100644 +--- a/drivers/ptp/ptp_sysfs.c ++++ b/drivers/ptp/ptp_sysfs.c +@@ -296,8 +296,7 @@ static ssize_t max_vclocks_store(struct device *dev, + if (max < ptp->n_vclocks) + goto out; + +- size = sizeof(int) * max; +- vclock_index = kzalloc(size, GFP_KERNEL); ++ vclock_index = kcalloc(max, sizeof(int), GFP_KERNEL); + if (!vclock_index) { + err = -ENOMEM; + goto out; +diff --git a/drivers/regulator/bd71815-regulator.c b/drivers/regulator/bd71815-regulator.c +index 26192d55a6858..79fbb45297f6b 100644 +--- a/drivers/regulator/bd71815-regulator.c ++++ b/drivers/regulator/bd71815-regulator.c +@@ -256,7 +256,7 @@ static int buck12_set_hw_dvs_levels(struct device_node *np, + * 10: 2.50mV/usec 10mV 4uS + * 11: 1.25mV/usec 10mV 8uS + */ +-static const unsigned int bd7181x_ramp_table[] = { 1250, 2500, 5000, 10000 }; ++static const unsigned int bd7181x_ramp_table[] = { 10000, 5000, 2500, 1250 }; + + static int bd7181x_led_set_current_limit(struct regulator_dev *rdev, + int min_uA, int max_uA) +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 2c33653ffdea3..51ff3f9eafd0e 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -3347,6 +3347,7 @@ struct regmap *regulator_get_regmap(struct regulator *regulator) + + return map ? map : ERR_PTR(-EOPNOTSUPP); + } ++EXPORT_SYMBOL_GPL(regulator_get_regmap); + + /** + * regulator_get_hardware_vsel_register - get the HW voltage selector register +diff --git a/drivers/scsi/qedi/qedi_debugfs.c b/drivers/scsi/qedi/qedi_debugfs.c +index 8deb2001dc2ff..37eed6a278164 100644 +--- a/drivers/scsi/qedi/qedi_debugfs.c ++++ b/drivers/scsi/qedi/qedi_debugfs.c +@@ -120,15 +120,11 @@ static ssize_t + qedi_dbg_do_not_recover_cmd_read(struct file *filp, char __user *buffer, + size_t count, loff_t *ppos) + { +- size_t cnt = 0; +- +- if (*ppos) +- return 0; ++ char buf[64]; ++ int len; + +- cnt = sprintf(buffer, "do_not_recover=%d\n", qedi_do_not_recover); +- cnt = min_t(int, count, cnt - *ppos); +- *ppos += cnt; +- return cnt; ++ len = sprintf(buf, "do_not_recover=%d\n", qedi_do_not_recover); ++ return simple_read_from_buffer(buffer, count, ppos, buf, len); + } + + static int +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 4f7b9b5b9c5b4..a4638ea92571d 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -63,6 +63,7 @@ + #include <scsi/scsi_cmnd.h> + #include <scsi/scsi_dbg.h> + #include <scsi/scsi_device.h> ++#include <scsi/scsi_devinfo.h> + #include <scsi/scsi_driver.h> + #include <scsi/scsi_eh.h> + #include <scsi/scsi_host.h> +@@ -3125,6 +3126,9 @@ static void sd_read_io_hints(struct scsi_disk *sdkp, unsigned char *buffer) + struct scsi_mode_data data; + int res; + ++ if (sdp->sdev_bflags & BLIST_SKIP_IO_HINTS) ++ return; ++ + res = scsi_mode_sense(sdp, /*dbd=*/0x8, /*modepage=*/0x0a, + /*subpage=*/0x05, buffer, SD_BUF_SIZE, SD_TIMEOUT, + sdkp->max_retries, &data, &sshdr); +diff --git a/drivers/spi/spi-cs42l43.c b/drivers/spi/spi-cs42l43.c +index aabef9fc84bdf..0d9c948e119af 100644 +--- a/drivers/spi/spi-cs42l43.c ++++ b/drivers/spi/spi-cs42l43.c +@@ -21,7 +21,7 @@ + #include <linux/units.h> + + #define CS42L43_FIFO_SIZE 16 +-#define CS42L43_SPI_ROOT_HZ (40 * HZ_PER_MHZ) ++#define CS42L43_SPI_ROOT_HZ 49152000 + #define CS42L43_SPI_MAX_LENGTH 65532 + + enum cs42l43_spi_cmd { +diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c +index c3e5cee18bea7..09b6c1b45f1a1 100644 +--- a/drivers/spi/spi-imx.c ++++ b/drivers/spi/spi-imx.c +@@ -660,18 +660,8 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx, + ctrl |= (spi_imx->target_burst * 8 - 1) + << MX51_ECSPI_CTRL_BL_OFFSET; + else { +- if (spi_imx->usedma) { +- ctrl |= (spi_imx->bits_per_word - 1) +- << MX51_ECSPI_CTRL_BL_OFFSET; +- } else { +- if (spi_imx->count >= MX51_ECSPI_CTRL_MAX_BURST) +- ctrl |= (MX51_ECSPI_CTRL_MAX_BURST * BITS_PER_BYTE - 1) +- << MX51_ECSPI_CTRL_BL_OFFSET; +- else +- ctrl |= (spi_imx->count / DIV_ROUND_UP(spi_imx->bits_per_word, +- BITS_PER_BYTE) * spi_imx->bits_per_word - 1) +- << MX51_ECSPI_CTRL_BL_OFFSET; +- } ++ ctrl |= (spi_imx->bits_per_word - 1) ++ << MX51_ECSPI_CTRL_BL_OFFSET; + } + + /* set clock speed */ +diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c +index f1e922fd362ab..955c920c4b639 100644 +--- a/drivers/spi/spi-stm32-qspi.c ++++ b/drivers/spi/spi-stm32-qspi.c +@@ -349,7 +349,7 @@ static int stm32_qspi_wait_poll_status(struct stm32_qspi *qspi) + + static int stm32_qspi_get_mode(u8 buswidth) + { +- if (buswidth == 4) ++ if (buswidth >= 4) + return CCR_BUSWIDTH_4; + + return buswidth; +@@ -653,9 +653,7 @@ static int stm32_qspi_setup(struct spi_device *spi) + return -EINVAL; + + mode = spi->mode & (SPI_TX_OCTAL | SPI_RX_OCTAL); +- if ((mode == SPI_TX_OCTAL || mode == SPI_RX_OCTAL) || +- ((mode == (SPI_TX_OCTAL | SPI_RX_OCTAL)) && +- gpiod_count(qspi->dev, "cs") == -ENOENT)) { ++ if (mode && gpiod_count(qspi->dev, "cs") == -ENOENT) { + dev_err(qspi->dev, "spi-rx-bus-width\\/spi-tx-bus-width\\/cs-gpios\n"); + dev_err(qspi->dev, "configuration not supported\n"); + +@@ -676,10 +674,10 @@ static int stm32_qspi_setup(struct spi_device *spi) + qspi->cr_reg = CR_APMS | 3 << CR_FTHRES_SHIFT | CR_SSHIFT | CR_EN; + + /* +- * Dual flash mode is only enable in case SPI_TX_OCTAL and SPI_TX_OCTAL +- * are both set in spi->mode and "cs-gpios" properties is found in DT ++ * Dual flash mode is only enable in case SPI_TX_OCTAL or SPI_RX_OCTAL ++ * is set in spi->mode and "cs-gpios" properties is found in DT + */ +- if (mode == (SPI_TX_OCTAL | SPI_RX_OCTAL)) { ++ if (mode) { + qspi->cr_reg |= CR_DFM; + dev_dbg(qspi->dev, "Dual flash mode enable"); + } +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index 2cea7aeb10f95..c349d6012625a 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -685,10 +685,12 @@ static int __spi_add_device(struct spi_device *spi) + * Make sure that multiple logical CS doesn't map to the same physical CS. + * For example, spi->chip_select[0] != spi->chip_select[1] and so on. + */ +- for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) { +- status = spi_dev_check_cs(dev, spi, idx, spi, idx + 1); +- if (status) +- return status; ++ if (!spi_controller_is_target(ctlr)) { ++ for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) { ++ status = spi_dev_check_cs(dev, spi, idx, spi, idx + 1); ++ if (status) ++ return status; ++ } + } + + /* Set the bus ID string */ +diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c +index 9f30e0edadfe2..bdb6595ffd2d5 100644 +--- a/drivers/ssb/main.c ++++ b/drivers/ssb/main.c +@@ -341,11 +341,13 @@ static int ssb_bus_match(struct device *dev, struct device_driver *drv) + + static int ssb_device_uevent(const struct device *dev, struct kobj_uevent_env *env) + { +- const struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); ++ const struct ssb_device *ssb_dev; + + if (!dev) + return -ENODEV; + ++ ssb_dev = dev_to_ssb_dev(dev); ++ + return add_uevent_var(env, + "MODALIAS=ssb:v%04Xid%04Xrev%02X", + ssb_dev->id.vendor, ssb_dev->id.coreid, +diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c +index 14e34eabc4191..4a1bfebb1b8e5 100644 +--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c ++++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c +@@ -150,7 +150,7 @@ static irqreturn_t proc_thermal_irq_handler(int irq, void *devid) + { + struct proc_thermal_pci *pci_info = devid; + struct proc_thermal_device *proc_priv; +- int ret = IRQ_HANDLED; ++ int ret = IRQ_NONE; + u32 status; + + proc_priv = pci_info->proc_priv; +@@ -175,6 +175,7 @@ static irqreturn_t proc_thermal_irq_handler(int irq, void *devid) + /* Disable enable interrupt flag */ + proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0); + pkg_thermal_schedule_work(&pci_info->work); ++ ret = IRQ_HANDLED; + } + + pci_write_config_byte(pci_info->pdev, 0xdc, 0x01); +diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c +index 4e5c213a89225..6b9422bd8795d 100644 +--- a/drivers/thermal/mediatek/lvts_thermal.c ++++ b/drivers/thermal/mediatek/lvts_thermal.c +@@ -740,7 +740,11 @@ static int lvts_golden_temp_init(struct device *dev, u32 *value, int temp_offset + + gt = (*value) >> 24; + +- if (gt && gt < LVTS_GOLDEN_TEMP_MAX) ++ /* A zero value for gt means that device has invalid efuse data */ ++ if (!gt) ++ return -ENODATA; ++ ++ if (gt < LVTS_GOLDEN_TEMP_MAX) + golden_temp = gt; + + golden_temp_offset = golden_temp * 500 + temp_offset; +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index 258482036f1e9..28888ac43c0a1 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -1633,6 +1633,12 @@ static int thermal_pm_notify(struct notifier_block *nb, + + static struct notifier_block thermal_pm_nb = { + .notifier_call = thermal_pm_notify, ++ /* ++ * Run at the lowest priority to avoid interference between the thermal ++ * zone resume work items spawned by thermal_pm_notify() and the other ++ * PM notifiers. ++ */ ++ .priority = INT_MIN, + }; + + static int __init thermal_init(void) +diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c +index 94d680e4b5353..a58890fd53e2c 100644 +--- a/drivers/tty/serial/8250/8250_dw.c ++++ b/drivers/tty/serial/8250/8250_dw.c +@@ -57,6 +57,33 @@ + #define DW_UART_QUIRK_APMC0D08 BIT(4) + #define DW_UART_QUIRK_CPR_VALUE BIT(5) + ++struct dw8250_platform_data { ++ u8 usr_reg; ++ u32 cpr_value; ++ unsigned int quirks; ++}; ++ ++struct dw8250_data { ++ struct dw8250_port_data data; ++ const struct dw8250_platform_data *pdata; ++ ++ int msr_mask_on; ++ int msr_mask_off; ++ struct clk *clk; ++ struct clk *pclk; ++ struct notifier_block clk_notifier; ++ struct work_struct clk_work; ++ struct reset_control *rst; ++ ++ unsigned int skip_autocfg:1; ++ unsigned int uart_16550_compatible:1; ++}; ++ ++static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data) ++{ ++ return container_of(data, struct dw8250_data, data); ++} ++ + static inline struct dw8250_data *clk_to_dw8250_data(struct notifier_block *nb) + { + return container_of(nb, struct dw8250_data, clk_notifier); +diff --git a/drivers/tty/serial/8250/8250_dwlib.h b/drivers/tty/serial/8250/8250_dwlib.h +index 794a9014cdac1..7dd2a8e7b7808 100644 +--- a/drivers/tty/serial/8250/8250_dwlib.h ++++ b/drivers/tty/serial/8250/8250_dwlib.h +@@ -2,15 +2,10 @@ + /* Synopsys DesignWare 8250 library header file. */ + + #include <linux/io.h> +-#include <linux/notifier.h> + #include <linux/types.h> +-#include <linux/workqueue.h> + + #include "8250.h" + +-struct clk; +-struct reset_control; +- + struct dw8250_port_data { + /* Port properties */ + int line; +@@ -26,36 +21,9 @@ struct dw8250_port_data { + bool hw_rs485_support; + }; + +-struct dw8250_platform_data { +- u8 usr_reg; +- u32 cpr_value; +- unsigned int quirks; +-}; +- +-struct dw8250_data { +- struct dw8250_port_data data; +- const struct dw8250_platform_data *pdata; +- +- int msr_mask_on; +- int msr_mask_off; +- struct clk *clk; +- struct clk *pclk; +- struct notifier_block clk_notifier; +- struct work_struct clk_work; +- struct reset_control *rst; +- +- unsigned int skip_autocfg:1; +- unsigned int uart_16550_compatible:1; +-}; +- + void dw8250_do_set_termios(struct uart_port *p, struct ktermios *termios, const struct ktermios *old); + void dw8250_setup_port(struct uart_port *p); + +-static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data) +-{ +- return container_of(data, struct dw8250_data, data); +-} +- + static inline u32 dw8250_readl_ext(struct uart_port *p, int offset) + { + if (p->iotype == UPIO_MEM32BE) +diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c +index 0440df7de1ed7..4d1e07343d0bb 100644 +--- a/drivers/tty/serial/8250/8250_exar.c ++++ b/drivers/tty/serial/8250/8250_exar.c +@@ -46,8 +46,50 @@ + #define PCI_DEVICE_ID_COMMTECH_4228PCIE 0x0021 + #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 + ++#define PCI_VENDOR_ID_CONNECT_TECH 0x12c4 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_SP_OPTO 0x0340 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_SP_OPTO_A 0x0341 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_SP_OPTO_B 0x0342 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XPRS 0x0350 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_A 0x0351 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_B 0x0352 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS 0x0353 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_16_XPRS_A 0x0354 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_16_XPRS_B 0x0355 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XPRS_OPTO 0x0360 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_OPTO_A 0x0361 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XPRS_OPTO_B 0x0362 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_SP 0x0370 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_SP_232 0x0371 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_SP_485 0x0372 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4_SP 0x0373 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_6_2_SP 0x0374 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_6_SP 0x0375 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_SP_232_NS 0x0376 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XP_OPTO_LEFT 0x0380 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_XP_OPTO_RIGHT 0x0381 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_XP_OPTO 0x0382 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4_XPRS_OPTO 0x0392 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS_LP 0x03A0 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS_LP_232 0x03A1 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS_LP_485 0x03A2 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_XPRS_LP_232_NS 0x03A3 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XEG001 0x0602 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_BASE 0x1000 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_2 0x1002 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_4 0x1004 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_8 0x1008 ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_12 0x100C ++#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCIE_XR35X_16 0x1010 ++#define PCI_DEVICE_ID_CONNECT_TECH_PCI_XR79X_12_XIG00X 0x110c ++#define PCI_DEVICE_ID_CONNECT_TECH_PCI_XR79X_12_XIG01X 0x110d ++#define PCI_DEVICE_ID_CONNECT_TECH_PCI_XR79X_16 0x1110 ++ + #define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358 + #define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358 ++#define PCI_DEVICE_ID_EXAR_XR17V252 0x0252 ++#define PCI_DEVICE_ID_EXAR_XR17V254 0x0254 ++#define PCI_DEVICE_ID_EXAR_XR17V258 0x0258 + + #define PCI_SUBDEVICE_ID_USR_2980 0x0128 + #define PCI_SUBDEVICE_ID_USR_2981 0x0129 +diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c +index e148132506161..09c1678ddfd49 100644 +--- a/drivers/tty/serial/imx.c ++++ b/drivers/tty/serial/imx.c +@@ -26,6 +26,7 @@ + #include <linux/slab.h> + #include <linux/of.h> + #include <linux/io.h> ++#include <linux/iopoll.h> + #include <linux/dma-mapping.h> + + #include <asm/irq.h> +@@ -2010,7 +2011,7 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) + struct imx_port *sport = imx_uart_ports[co->index]; + struct imx_port_ucrs old_ucr; + unsigned long flags; +- unsigned int ucr1; ++ unsigned int ucr1, usr2; + int locked = 1; + + if (sport->port.sysrq) +@@ -2041,8 +2042,8 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) + * Finally, wait for transmitter to become empty + * and restore UCR1/2/3 + */ +- while (!(imx_uart_readl(sport, USR2) & USR2_TXDC)); +- ++ read_poll_timeout_atomic(imx_uart_readl, usr2, usr2 & USR2_TXDC, ++ 0, USEC_PER_SEC, false, sport, USR2); + imx_uart_ucrs_restore(sport, &old_ucr); + + if (locked) +diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c +index 3f68e213df1f7..d80e9d4c974b4 100644 +--- a/drivers/tty/tty_ldisc.c ++++ b/drivers/tty/tty_ldisc.c +@@ -545,6 +545,12 @@ int tty_set_ldisc(struct tty_struct *tty, int disc) + goto out; + } + ++ if (tty->ops->ldisc_ok) { ++ retval = tty->ops->ldisc_ok(tty, disc); ++ if (retval) ++ goto out; ++ } ++ + old_ldisc = tty->ldisc; + + /* Shutdown the old discipline. */ +diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c +index 9b5b98dfc8b40..cd87e3d1291ed 100644 +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -3576,6 +3576,15 @@ static void con_cleanup(struct tty_struct *tty) + tty_port_put(&vc->port); + } + ++/* ++ * We can't deal with anything but the N_TTY ldisc, ++ * because we can sleep in our write() routine. ++ */ ++static int con_ldisc_ok(struct tty_struct *tty, int ldisc) ++{ ++ return ldisc == N_TTY ? 0 : -EINVAL; ++} ++ + static int default_color = 7; /* white */ + static int default_italic_color = 2; // green (ASCII) + static int default_underline_color = 3; // cyan (ASCII) +@@ -3695,6 +3704,7 @@ static const struct tty_operations con_ops = { + .resize = vt_resize, + .shutdown = con_shutdown, + .cleanup = con_cleanup, ++ .ldisc_ok = con_ldisc_ok, + }; + + static struct cdev vc0_cdev; +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index ce1abd5d725ad..f7d04f7c0017d 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -8972,6 +8972,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params) + (hba->quirks & UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH)) { + /* Reset the device and controller before doing reinit */ + ufshcd_device_reset(hba); ++ ufs_put_device_desc(hba); + ufshcd_hba_stop(hba); + ufshcd_vops_reinit_notify(hba); + ret = ufshcd_hba_enable(hba); +diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c +index 497deed38c0c1..9ef821ca2fc71 100644 +--- a/drivers/usb/dwc3/dwc3-pci.c ++++ b/drivers/usb/dwc3/dwc3-pci.c +@@ -8,6 +8,7 @@ + * Sebastian Andrzej Siewior <bigeasy@linutronix.de> + */ + ++#include <linux/dmi.h> + #include <linux/kernel.h> + #include <linux/module.h> + #include <linux/slab.h> +@@ -220,6 +221,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc, + + if (pdev->device == PCI_DEVICE_ID_INTEL_BYT) { + struct gpio_desc *gpio; ++ const char *bios_ver; + int ret; + + /* On BYT the FW does not always enable the refclock */ +@@ -277,8 +279,12 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc, + * detection. These can be identified by them _not_ + * using the standard ACPI battery and ac drivers. + */ ++ bios_ver = dmi_get_system_info(DMI_BIOS_VERSION); + if (acpi_dev_present("INT33FD", "1", 2) && +- acpi_quirk_skip_acpi_ac_and_battery()) { ++ acpi_quirk_skip_acpi_ac_and_battery() && ++ /* Lenovo Yoga Tablet 2 Pro 1380 uses LC824206XA instead */ ++ !(bios_ver && ++ strstarts(bios_ver, "BLADE_21.X64.0005.R00.1504101516"))) { + dev_info(&pdev->dev, "Using TUSB1211 phy for charger detection\n"); + swnode = &dwc3_pci_intel_phy_charger_detect_swnode; + } +diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c +index 3c8a9dd585c09..2db01e03bfbf0 100644 +--- a/drivers/usb/gadget/function/f_hid.c ++++ b/drivers/usb/gadget/function/f_hid.c +@@ -1029,9 +1029,9 @@ static inline int hidg_get_minor(void) + { + int ret; + +- ret = ida_simple_get(&hidg_ida, 0, 0, GFP_KERNEL); ++ ret = ida_alloc(&hidg_ida, GFP_KERNEL); + if (ret >= HIDG_MINORS) { +- ida_simple_remove(&hidg_ida, ret); ++ ida_free(&hidg_ida, ret); + ret = -ENODEV; + } + +@@ -1176,7 +1176,7 @@ static const struct config_item_type hid_func_type = { + + static inline void hidg_put_minor(int minor) + { +- ida_simple_remove(&hidg_ida, minor); ++ ida_free(&hidg_ida, minor); + } + + static void hidg_free_inst(struct usb_function_instance *f) +diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c +index 076dd4c1be96c..ba7d180cc9e6d 100644 +--- a/drivers/usb/gadget/function/f_printer.c ++++ b/drivers/usb/gadget/function/f_printer.c +@@ -1312,9 +1312,9 @@ static inline int gprinter_get_minor(void) + { + int ret; + +- ret = ida_simple_get(&printer_ida, 0, 0, GFP_KERNEL); ++ ret = ida_alloc(&printer_ida, GFP_KERNEL); + if (ret >= PRINTER_MINORS) { +- ida_simple_remove(&printer_ida, ret); ++ ida_free(&printer_ida, ret); + ret = -ENODEV; + } + +@@ -1323,7 +1323,7 @@ static inline int gprinter_get_minor(void) + + static inline void gprinter_put_minor(int minor) + { +- ida_simple_remove(&printer_ida, minor); ++ ida_free(&printer_ida, minor); + } + + static int gprinter_setup(int); +diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c +index 29bf8664bf582..12c5d9cf450c1 100644 +--- a/drivers/usb/gadget/function/rndis.c ++++ b/drivers/usb/gadget/function/rndis.c +@@ -869,12 +869,12 @@ EXPORT_SYMBOL_GPL(rndis_msg_parser); + + static inline int rndis_get_nr(void) + { +- return ida_simple_get(&rndis_ida, 0, 1000, GFP_KERNEL); ++ return ida_alloc_max(&rndis_ida, 999, GFP_KERNEL); + } + + static inline void rndis_put_nr(int nr) + { +- ida_simple_remove(&rndis_ida, nr); ++ ida_free(&rndis_ida, nr); + } + + struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v) +diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c +index a4377df612f51..6fac696ea8463 100644 +--- a/drivers/usb/gadget/function/uvc_configfs.c ++++ b/drivers/usb/gadget/function/uvc_configfs.c +@@ -13,6 +13,7 @@ + #include "uvc_configfs.h" + + #include <linux/sort.h> ++#include <linux/usb/uvc.h> + #include <linux/usb/video.h> + + /* ----------------------------------------------------------------------------- +@@ -2260,6 +2261,8 @@ static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item, + struct f_uvc_opts *opts; + struct config_item *opts_item; + struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; ++ const struct uvc_format_desc *format; ++ u8 tmpguidFormat[sizeof(ch->desc.guidFormat)]; + int ret; + + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ +@@ -2273,7 +2276,16 @@ static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item, + goto end; + } + +- memcpy(ch->desc.guidFormat, page, ++ memcpy(tmpguidFormat, page, ++ min(sizeof(tmpguidFormat), len)); ++ ++ format = uvc_format_by_guid(tmpguidFormat); ++ if (!format) { ++ ret = -EINVAL; ++ goto end; ++ } ++ ++ memcpy(ch->desc.guidFormat, tmpguidFormat, + min(sizeof(ch->desc.guidFormat), len)); + ret = sizeof(ch->desc.guidFormat); + +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index b271ec916926b..febf64723434c 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -271,17 +271,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + "QUIRK: Fresco Logic revision %u " + "has broken MSI implementation", + pdev->revision); +- xhci->quirks |= XHCI_TRUST_TX_LENGTH; + } + + if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && + pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1009) + xhci->quirks |= XHCI_BROKEN_STREAMS; + +- if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && +- pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1100) +- xhci->quirks |= XHCI_TRUST_TX_LENGTH; +- + if (pdev->vendor == PCI_VENDOR_ID_NEC) + xhci->quirks |= XHCI_NEC_HOST; + +@@ -308,11 +303,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + xhci->quirks |= XHCI_RESET_ON_RESUME; + } + +- if (pdev->vendor == PCI_VENDOR_ID_AMD) { +- xhci->quirks |= XHCI_TRUST_TX_LENGTH; +- if (pdev->device == 0x43f7) +- xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; +- } ++ if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x43f7) ++ xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; + + if ((pdev->vendor == PCI_VENDOR_ID_AMD) && + ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) || +@@ -400,7 +392,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + if (pdev->vendor == PCI_VENDOR_ID_ETRON && + pdev->device == PCI_DEVICE_ID_EJ168) { + xhci->quirks |= XHCI_RESET_ON_RESUME; +- xhci->quirks |= XHCI_TRUST_TX_LENGTH; + xhci->quirks |= XHCI_BROKEN_STREAMS; + } + if (pdev->vendor == PCI_VENDOR_ID_ETRON && +@@ -411,7 +402,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + + if (pdev->vendor == PCI_VENDOR_ID_RENESAS && + pdev->device == 0x0014) { +- xhci->quirks |= XHCI_TRUST_TX_LENGTH; + xhci->quirks |= XHCI_ZERO_64B_REGS; + } + if (pdev->vendor == PCI_VENDOR_ID_RENESAS && +@@ -441,7 +431,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + } + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && + pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) { +- xhci->quirks |= XHCI_TRUST_TX_LENGTH; + xhci->quirks |= XHCI_NO_64BIT_SUPPORT; + } + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && +diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c +index ab9c5969e4624..8b357647728c2 100644 +--- a/drivers/usb/host/xhci-rcar.c ++++ b/drivers/usb/host/xhci-rcar.c +@@ -214,8 +214,7 @@ static int xhci_rcar_resume_quirk(struct usb_hcd *hcd) + */ + #define SET_XHCI_PLAT_PRIV_FOR_RCAR(firmware) \ + .firmware_name = firmware, \ +- .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_TRUST_TX_LENGTH | \ +- XHCI_SLOW_SUSPEND, \ ++ .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_SLOW_SUSPEND, \ + .init_quirk = xhci_rcar_init_quirk, \ + .plat_start = xhci_rcar_start, \ + .resume_quirk = xhci_rcar_resume_quirk, +@@ -229,8 +228,7 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = { + }; + + static const struct xhci_plat_priv xhci_plat_renesas_rzv2m = { +- .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_TRUST_TX_LENGTH | +- XHCI_SLOW_SUSPEND, ++ .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_SLOW_SUSPEND, + .init_quirk = xhci_rzv2m_init_quirk, + .plat_start = xhci_rzv2m_start, + }; +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 850846c206ed4..48d745e9f9730 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -2431,8 +2431,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, + break; + if (remaining) { + frame->status = short_framestatus; +- if (xhci->quirks & XHCI_TRUST_TX_LENGTH) +- sum_trbs_for_length = true; ++ sum_trbs_for_length = true; + break; + } + frame->status = 0; +@@ -2681,15 +2680,11 @@ static int handle_tx_event(struct xhci_hcd *xhci, + * transfer type + */ + case COMP_SUCCESS: +- if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) +- break; +- if (xhci->quirks & XHCI_TRUST_TX_LENGTH || +- ep_ring->last_td_was_short) ++ if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { + trb_comp_code = COMP_SHORT_PACKET; +- else +- xhci_warn_ratelimited(xhci, +- "WARN Successful completion on short TX for slot %u ep %u: needs XHCI_TRUST_TX_LENGTH quirk?\n", +- slot_id, ep_index); ++ xhci_dbg(xhci, "Successful completion on short TX for slot %u ep %u with last td short %d\n", ++ slot_id, ep_index, ep_ring->last_td_was_short); ++ } + break; + case COMP_SHORT_PACKET: + break; +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 069a187540a0c..1683d779e4bc0 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1590,7 +1590,7 @@ struct xhci_hcd { + #define XHCI_RESET_ON_RESUME BIT_ULL(7) + #define XHCI_SW_BW_CHECKING BIT_ULL(8) + #define XHCI_AMD_0x96_HOST BIT_ULL(9) +-#define XHCI_TRUST_TX_LENGTH BIT_ULL(10) ++#define XHCI_TRUST_TX_LENGTH BIT_ULL(10) /* Deprecated */ + #define XHCI_LPM_SUPPORT BIT_ULL(11) + #define XHCI_INTEL_HOST BIT_ULL(12) + #define XHCI_SPURIOUS_REBOOT BIT_ULL(13) +@@ -1730,8 +1730,6 @@ static inline bool xhci_has_one_roothub(struct xhci_hcd *xhci) + dev_err(xhci_to_hcd(xhci)->self.controller , fmt , ## args) + #define xhci_warn(xhci, fmt, args...) \ + dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args) +-#define xhci_warn_ratelimited(xhci, fmt, args...) \ +- dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args) + #define xhci_info(xhci, fmt, args...) \ + dev_info(xhci_to_hcd(xhci)->self.controller , fmt , ## args) + +diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c +index b00d92db5dfd1..eb5a8e0d9e2d6 100644 +--- a/drivers/usb/misc/uss720.c ++++ b/drivers/usb/misc/uss720.c +@@ -677,7 +677,7 @@ static int uss720_probe(struct usb_interface *intf, + struct parport_uss720_private *priv; + struct parport *pp; + unsigned char reg; +- int i; ++ int ret; + + dev_dbg(&intf->dev, "probe: vendor id 0x%x, device id 0x%x\n", + le16_to_cpu(usbdev->descriptor.idVendor), +@@ -688,8 +688,8 @@ static int uss720_probe(struct usb_interface *intf, + usb_put_dev(usbdev); + return -ENODEV; + } +- i = usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 2); +- dev_dbg(&intf->dev, "set interface result %d\n", i); ++ ret = usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 2); ++ dev_dbg(&intf->dev, "set interface result %d\n", ret); + + interface = intf->cur_altsetting; + +@@ -725,12 +725,18 @@ static int uss720_probe(struct usb_interface *intf, + set_1284_register(pp, 7, 0x00, GFP_KERNEL); + set_1284_register(pp, 6, 0x30, GFP_KERNEL); /* PS/2 mode */ + set_1284_register(pp, 2, 0x0c, GFP_KERNEL); +- /* debugging */ +- get_1284_register(pp, 0, ®, GFP_KERNEL); ++ ++ /* The Belkin F5U002 Rev 2 P80453-B USB parallel port adapter shares the ++ * device ID 050d:0002 with some other device that works with this ++ * driver, but it itself does not. Detect and handle the bad cable ++ * here. */ ++ ret = get_1284_register(pp, 0, ®, GFP_KERNEL); + dev_dbg(&intf->dev, "reg: %7ph\n", priv->reg); ++ if (ret < 0) ++ return ret; + +- i = usb_find_last_int_in_endpoint(interface, &epd); +- if (!i) { ++ ret = usb_find_last_int_in_endpoint(interface, &epd); ++ if (!ret) { + dev_dbg(&intf->dev, "epaddr %d interval %d\n", + epd->bEndpointAddress, epd->bInterval); + } +diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c +index 12cf9940e5b67..7d87e2a521ed9 100644 +--- a/drivers/usb/storage/scsiglue.c ++++ b/drivers/usb/storage/scsiglue.c +@@ -86,6 +86,12 @@ static int slave_alloc (struct scsi_device *sdev) + if (us->protocol == USB_PR_BULK && us->max_lun > 0) + sdev->sdev_bflags |= BLIST_FORCELUN; + ++ /* ++ * Some USB storage devices reset if the IO advice hints grouping mode ++ * page is queried. Hence skip that mode page. ++ */ ++ sdev->sdev_bflags |= BLIST_SKIP_IO_HINTS; ++ + return 0; + } + +diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c +index 08953f0d4532a..1ed2bdda0cd40 100644 +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -21,6 +21,7 @@ + #include <scsi/scsi.h> + #include <scsi/scsi_eh.h> + #include <scsi/scsi_dbg.h> ++#include <scsi/scsi_devinfo.h> + #include <scsi/scsi_cmnd.h> + #include <scsi/scsi_device.h> + #include <scsi/scsi_host.h> +@@ -820,6 +821,12 @@ static int uas_slave_alloc(struct scsi_device *sdev) + struct uas_dev_info *devinfo = + (struct uas_dev_info *)sdev->host->hostdata; + ++ /* ++ * Some USB storage devices reset if the IO advice hints grouping mode ++ * page is queried. Hence skip that mode page. ++ */ ++ sdev->sdev_bflags |= BLIST_SKIP_IO_HINTS; ++ + sdev->hostdata = devinfo; + + /* +diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c +index d3958c061a972..501eddb294e43 100644 +--- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c ++++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c +@@ -41,7 +41,7 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev) + struct device_node *np = dev->of_node; + const struct pmic_typec_resources *res; + struct regmap *regmap; +- struct device *bridge_dev; ++ struct auxiliary_device *bridge_dev; + u32 base; + int ret; + +@@ -92,7 +92,7 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev) + if (!tcpm->tcpc.fwnode) + return -EINVAL; + +- bridge_dev = drm_dp_hpd_bridge_register(tcpm->dev, to_of_node(tcpm->tcpc.fwnode)); ++ bridge_dev = devm_drm_dp_hpd_bridge_alloc(tcpm->dev, to_of_node(tcpm->tcpc.fwnode)); + if (IS_ERR(bridge_dev)) + return PTR_ERR(bridge_dev); + +@@ -110,8 +110,14 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev) + if (ret) + goto port_stop; + ++ ret = devm_drm_dp_hpd_bridge_add(tcpm->dev, bridge_dev); ++ if (ret) ++ goto pdphy_stop; ++ + return 0; + ++pdphy_stop: ++ tcpm->pdphy_stop(tcpm); + port_stop: + tcpm->port_stop(tcpm); + port_unregister: +diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c +index ce08eb33e5bec..1d0e2d87e9b31 100644 +--- a/drivers/usb/typec/ucsi/ucsi_glink.c ++++ b/drivers/usb/typec/ucsi/ucsi_glink.c +@@ -176,7 +176,8 @@ static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset, + left = wait_for_completion_timeout(&ucsi->sync_ack, 5 * HZ); + if (!left) { + dev_err(ucsi->dev, "timeout waiting for UCSI sync write response\n"); +- ret = -ETIMEDOUT; ++ /* return 0 here and let core UCSI code handle the CCI_BUSY */ ++ ret = 0; + } else if (ucsi->sync_val) { + dev_err(ucsi->dev, "sync write returned: %d\n", ucsi->sync_val); + } +@@ -243,10 +244,7 @@ static void pmic_glink_ucsi_notify(struct work_struct *work) + ucsi_connector_change(ucsi->ucsi, con_num); + } + +- if (ucsi->sync_pending && cci & UCSI_CCI_BUSY) { +- ucsi->sync_val = -EBUSY; +- complete(&ucsi->sync_ack); +- } else if (ucsi->sync_pending && ++ if (ucsi->sync_pending && + (cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE))) { + complete(&ucsi->sync_ack); + } +@@ -311,12 +309,14 @@ static void pmic_glink_ucsi_destroy(void *data) + mutex_unlock(&ucsi->lock); + } + ++static unsigned long quirk_sc8180x = UCSI_NO_PARTNER_PDOS; ++ + static const struct of_device_id pmic_glink_ucsi_of_quirks[] = { +- { .compatible = "qcom,qcm6490-pmic-glink", .data = (void *)UCSI_NO_PARTNER_PDOS, }, +- { .compatible = "qcom,sc8180x-pmic-glink", .data = (void *)UCSI_NO_PARTNER_PDOS, }, +- { .compatible = "qcom,sc8280xp-pmic-glink", .data = (void *)UCSI_NO_PARTNER_PDOS, }, +- { .compatible = "qcom,sm8350-pmic-glink", .data = (void *)UCSI_NO_PARTNER_PDOS, }, +- { .compatible = "qcom,sm8550-pmic-glink", .data = (void *)UCSI_NO_PARTNER_PDOS, }, ++ { .compatible = "qcom,qcm6490-pmic-glink", .data = &quirk_sc8180x, }, ++ { .compatible = "qcom,sc8180x-pmic-glink", .data = &quirk_sc8180x, }, ++ { .compatible = "qcom,sc8280xp-pmic-glink", .data = &quirk_sc8180x, }, ++ { .compatible = "qcom,sm8350-pmic-glink", .data = &quirk_sc8180x, }, ++ { .compatible = "qcom,sm8550-pmic-glink", .data = &quirk_sc8180x, }, + {} + }; + +@@ -354,7 +354,7 @@ static int pmic_glink_ucsi_probe(struct auxiliary_device *adev, + + match = of_match_device(pmic_glink_ucsi_of_quirks, dev->parent); + if (match) +- ucsi->ucsi->quirks = (unsigned long)match->data; ++ ucsi->ucsi->quirks = *(unsigned long *)match->data; + + ucsi_set_drvdata(ucsi->ucsi, ucsi); + +diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c +index d94d61b92c1ac..d8c95cc16be81 100644 +--- a/drivers/vfio/pci/vfio_pci_core.c ++++ b/drivers/vfio/pci/vfio_pci_core.c +@@ -778,25 +778,26 @@ static int vfio_pci_count_devs(struct pci_dev *pdev, void *data) + } + + struct vfio_pci_fill_info { +- struct vfio_pci_dependent_device __user *devices; +- struct vfio_pci_dependent_device __user *devices_end; + struct vfio_device *vdev; ++ struct vfio_pci_dependent_device *devices; ++ int nr_devices; + u32 count; + u32 flags; + }; + + static int vfio_pci_fill_devs(struct pci_dev *pdev, void *data) + { +- struct vfio_pci_dependent_device info = { +- .segment = pci_domain_nr(pdev->bus), +- .bus = pdev->bus->number, +- .devfn = pdev->devfn, +- }; ++ struct vfio_pci_dependent_device *info; + struct vfio_pci_fill_info *fill = data; + +- fill->count++; +- if (fill->devices >= fill->devices_end) +- return 0; ++ /* The topology changed since we counted devices */ ++ if (fill->count >= fill->nr_devices) ++ return -EAGAIN; ++ ++ info = &fill->devices[fill->count++]; ++ info->segment = pci_domain_nr(pdev->bus); ++ info->bus = pdev->bus->number; ++ info->devfn = pdev->devfn; + + if (fill->flags & VFIO_PCI_HOT_RESET_FLAG_DEV_ID) { + struct iommufd_ctx *iommufd = vfio_iommufd_device_ictx(fill->vdev); +@@ -809,19 +810,19 @@ static int vfio_pci_fill_devs(struct pci_dev *pdev, void *data) + */ + vdev = vfio_find_device_in_devset(dev_set, &pdev->dev); + if (!vdev) { +- info.devid = VFIO_PCI_DEVID_NOT_OWNED; ++ info->devid = VFIO_PCI_DEVID_NOT_OWNED; + } else { + int id = vfio_iommufd_get_dev_id(vdev, iommufd); + + if (id > 0) +- info.devid = id; ++ info->devid = id; + else if (id == -ENOENT) +- info.devid = VFIO_PCI_DEVID_OWNED; ++ info->devid = VFIO_PCI_DEVID_OWNED; + else +- info.devid = VFIO_PCI_DEVID_NOT_OWNED; ++ info->devid = VFIO_PCI_DEVID_NOT_OWNED; + } + /* If devid is VFIO_PCI_DEVID_NOT_OWNED, clear owned flag. */ +- if (info.devid == VFIO_PCI_DEVID_NOT_OWNED) ++ if (info->devid == VFIO_PCI_DEVID_NOT_OWNED) + fill->flags &= ~VFIO_PCI_HOT_RESET_FLAG_DEV_ID_OWNED; + } else { + struct iommu_group *iommu_group; +@@ -830,13 +831,10 @@ static int vfio_pci_fill_devs(struct pci_dev *pdev, void *data) + if (!iommu_group) + return -EPERM; /* Cannot reset non-isolated devices */ + +- info.group_id = iommu_group_id(iommu_group); ++ info->group_id = iommu_group_id(iommu_group); + iommu_group_put(iommu_group); + } + +- if (copy_to_user(fill->devices, &info, sizeof(info))) +- return -EFAULT; +- fill->devices++; + return 0; + } + +@@ -1258,10 +1256,11 @@ static int vfio_pci_ioctl_get_pci_hot_reset_info( + { + unsigned long minsz = + offsetofend(struct vfio_pci_hot_reset_info, count); ++ struct vfio_pci_dependent_device *devices = NULL; + struct vfio_pci_hot_reset_info hdr; + struct vfio_pci_fill_info fill = {}; + bool slot = false; +- int ret = 0; ++ int ret, count; + + if (copy_from_user(&hdr, arg, minsz)) + return -EFAULT; +@@ -1277,9 +1276,23 @@ static int vfio_pci_ioctl_get_pci_hot_reset_info( + else if (pci_probe_reset_bus(vdev->pdev->bus)) + return -ENODEV; + +- fill.devices = arg->devices; +- fill.devices_end = arg->devices + +- (hdr.argsz - sizeof(hdr)) / sizeof(arg->devices[0]); ++ ret = vfio_pci_for_each_slot_or_bus(vdev->pdev, vfio_pci_count_devs, ++ &count, slot); ++ if (ret) ++ return ret; ++ ++ if (count > (hdr.argsz - sizeof(hdr)) / sizeof(*devices)) { ++ hdr.count = count; ++ ret = -ENOSPC; ++ goto header; ++ } ++ ++ devices = kcalloc(count, sizeof(*devices), GFP_KERNEL); ++ if (!devices) ++ return -ENOMEM; ++ ++ fill.devices = devices; ++ fill.nr_devices = count; + fill.vdev = &vdev->vdev; + + if (vfio_device_cdev_opened(&vdev->vdev)) +@@ -1291,16 +1304,23 @@ static int vfio_pci_ioctl_get_pci_hot_reset_info( + &fill, slot); + mutex_unlock(&vdev->vdev.dev_set->lock); + if (ret) +- return ret; ++ goto out; ++ ++ if (copy_to_user(arg->devices, devices, ++ sizeof(*devices) * fill.count)) { ++ ret = -EFAULT; ++ goto out; ++ } + + hdr.count = fill.count; + hdr.flags = fill.flags; +- if (copy_to_user(arg, &hdr, minsz)) +- return -EFAULT; + +- if (fill.count > fill.devices - arg->devices) +- return -ENOSPC; +- return 0; ++header: ++ if (copy_to_user(arg, &hdr, minsz)) ++ ret = -EFAULT; ++out: ++ kfree(devices); ++ return ret; + } + + static int +diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c +index 477f350a8bd09..e3a57196b0ee0 100644 +--- a/fs/btrfs/bio.c ++++ b/fs/btrfs/bio.c +@@ -741,7 +741,9 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num) + ret = btrfs_bio_csum(bbio); + if (ret) + goto fail_put_bio; +- } else if (use_append) { ++ } else if (use_append || ++ (btrfs_is_zoned(fs_info) && inode && ++ inode->flags & BTRFS_INODE_NODATASUM)) { + ret = btrfs_alloc_dummy_sum(bbio); + if (ret) + goto fail_put_bio; +diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c +index 1e09aeea69c22..1a66be33bb048 100644 +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -1785,6 +1785,7 @@ void btrfs_reclaim_bgs_work(struct work_struct *work) + container_of(work, struct btrfs_fs_info, reclaim_bgs_work); + struct btrfs_block_group *bg; + struct btrfs_space_info *space_info; ++ LIST_HEAD(retry_list); + + if (!test_bit(BTRFS_FS_OPEN, &fs_info->flags)) + return; +@@ -1921,8 +1922,11 @@ void btrfs_reclaim_bgs_work(struct work_struct *work) + } + + next: +- if (ret) +- btrfs_mark_bg_to_reclaim(bg); ++ if (ret) { ++ /* Refcount held by the reclaim_bgs list after splice. */ ++ btrfs_get_block_group(bg); ++ list_add_tail(&bg->bg_list, &retry_list); ++ } + btrfs_put_block_group(bg); + + mutex_unlock(&fs_info->reclaim_bgs_lock); +@@ -1942,6 +1946,9 @@ void btrfs_reclaim_bgs_work(struct work_struct *work) + spin_unlock(&fs_info->unused_bgs_lock); + mutex_unlock(&fs_info->reclaim_bgs_lock); + end: ++ spin_lock(&fs_info->unused_bgs_lock); ++ list_splice_tail(&retry_list, &fs_info->reclaim_bgs); ++ spin_unlock(&fs_info->unused_bgs_lock); + btrfs_exclop_finish(fs_info); + sb_end_write(fs_info->sb); + } +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 714f83632e3f9..66b5a68b0254e 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -831,6 +831,8 @@ static int mb_avg_fragment_size_order(struct super_block *sb, ext4_grpblk_t len) + return 0; + if (order == MB_NUM_ORDERS(sb)) + order--; ++ if (WARN_ON_ONCE(order > MB_NUM_ORDERS(sb))) ++ order = MB_NUM_ORDERS(sb) - 1; + return order; + } + +@@ -1008,6 +1010,8 @@ static void ext4_mb_choose_next_group_best_avail(struct ext4_allocation_context + * goal length. + */ + order = fls(ac->ac_g_ex.fe_len) - 1; ++ if (WARN_ON_ONCE(order - 1 > MB_NUM_ORDERS(ac->ac_sb))) ++ order = MB_NUM_ORDERS(ac->ac_sb); + min_order = order - sbi->s_mb_best_avail_max_trim_order; + if (min_order < 0) + min_order = 0; +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 044135796f2b6..4b368f4dbc45a 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -5551,19 +5551,15 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) + if (err) + goto failed_mount6; + +- err = ext4_register_sysfs(sb); +- if (err) +- goto failed_mount7; +- + err = ext4_init_orphan_info(sb); + if (err) +- goto failed_mount8; ++ goto failed_mount7; + #ifdef CONFIG_QUOTA + /* Enable quota usage during mount. */ + if (ext4_has_feature_quota(sb) && !sb_rdonly(sb)) { + err = ext4_enable_quotas(sb); + if (err) +- goto failed_mount9; ++ goto failed_mount8; + } + #endif /* CONFIG_QUOTA */ + +@@ -5589,7 +5585,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) + ext4_msg(sb, KERN_INFO, "recovery complete"); + err = ext4_mark_recovery_complete(sb, es); + if (err) +- goto failed_mount10; ++ goto failed_mount9; + } + + if (test_opt(sb, DISCARD) && !bdev_max_discard_sectors(sb->s_bdev)) +@@ -5606,15 +5602,17 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) + atomic_set(&sbi->s_warning_count, 0); + atomic_set(&sbi->s_msg_count, 0); + ++ /* Register sysfs after all initializations are complete. */ ++ err = ext4_register_sysfs(sb); ++ if (err) ++ goto failed_mount9; ++ + return 0; + +-failed_mount10: ++failed_mount9: + ext4_quotas_off(sb, EXT4_MAXQUOTAS); +-failed_mount9: __maybe_unused ++failed_mount8: __maybe_unused + ext4_release_orphan_info(sb); +-failed_mount8: +- ext4_unregister_sysfs(sb); +- kobject_put(&sbi->s_kobj); + failed_mount7: + ext4_unregister_li_request(sb); + failed_mount6: +diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c +index 6d332dff79ddc..63cbda3700ea9 100644 +--- a/fs/ext4/sysfs.c ++++ b/fs/ext4/sysfs.c +@@ -29,6 +29,7 @@ typedef enum { + attr_trigger_test_error, + attr_first_error_time, + attr_last_error_time, ++ attr_clusters_in_group, + attr_feature, + attr_pointer_ui, + attr_pointer_ul, +@@ -104,7 +105,7 @@ static ssize_t reserved_clusters_store(struct ext4_sb_info *sbi, + int ret; + + ret = kstrtoull(skip_spaces(buf), 0, &val); +- if (ret || val >= clusters) ++ if (ret || val >= clusters || (s64)val < 0) + return -EINVAL; + + atomic64_set(&sbi->s_resv_clusters, val); +@@ -207,13 +208,14 @@ EXT4_ATTR_FUNC(sra_exceeded_retry_limit, 0444); + + EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, inode_readahead, + ext4_sb_info, s_inode_readahead_blks); ++EXT4_ATTR_OFFSET(mb_group_prealloc, 0644, clusters_in_group, ++ ext4_sb_info, s_mb_group_prealloc); + EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal); + EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats); + EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan); + EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan); + EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs); + EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request); +-EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc); + EXT4_RW_ATTR_SBI_UI(mb_max_linear_groups, s_mb_max_linear_groups); + EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb); + EXT4_ATTR(trigger_fs_error, 0200, trigger_test_error); +@@ -392,6 +394,7 @@ static ssize_t ext4_attr_show(struct kobject *kobj, + (unsigned long long) + percpu_counter_sum(&sbi->s_sra_exceeded_retry_limit)); + case attr_inode_readahead: ++ case attr_clusters_in_group: + case attr_pointer_ui: + if (!ptr) + return 0; +@@ -451,7 +454,8 @@ static ssize_t ext4_attr_store(struct kobject *kobj, + s_kobj); + struct ext4_attr *a = container_of(attr, struct ext4_attr, attr); + void *ptr = calc_ptr(a, sbi); +- unsigned long t; ++ unsigned int t; ++ unsigned long lt; + int ret; + + switch (a->attr_id) { +@@ -460,7 +464,7 @@ static ssize_t ext4_attr_store(struct kobject *kobj, + case attr_pointer_ui: + if (!ptr) + return 0; +- ret = kstrtoul(skip_spaces(buf), 0, &t); ++ ret = kstrtouint(skip_spaces(buf), 0, &t); + if (ret) + return ret; + if (a->attr_ptr == ptr_ext4_super_block_offset) +@@ -468,13 +472,21 @@ static ssize_t ext4_attr_store(struct kobject *kobj, + else + *((unsigned int *) ptr) = t; + return len; ++ case attr_clusters_in_group: ++ ret = kstrtouint(skip_spaces(buf), 0, &t); ++ if (ret) ++ return ret; ++ if (t > sbi->s_clusters_per_group) ++ return -EINVAL; ++ *((unsigned int *) ptr) = t; ++ return len; + case attr_pointer_ul: + if (!ptr) + return 0; +- ret = kstrtoul(skip_spaces(buf), 0, &t); ++ ret = kstrtoul(skip_spaces(buf), 0, <); + if (ret) + return ret; +- *((unsigned long *) ptr) = t; ++ *((unsigned long *) ptr) = lt; + return len; + case attr_inode_readahead: + return inode_readahead_blks_store(sbi, buf, len); +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index 9fdd134220736..78f06f86c3835 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1619,6 +1619,7 @@ static struct inode *ext4_xattr_inode_lookup_create(handle_t *handle, + static int ext4_xattr_set_entry(struct ext4_xattr_info *i, + struct ext4_xattr_search *s, + handle_t *handle, struct inode *inode, ++ struct inode *new_ea_inode, + bool is_block) + { + struct ext4_xattr_entry *last, *next; +@@ -1626,7 +1627,6 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, + size_t min_offs = s->end - s->base, name_len = strlen(i->name); + int in_inode = i->in_inode; + struct inode *old_ea_inode = NULL; +- struct inode *new_ea_inode = NULL; + size_t old_size, new_size; + int ret; + +@@ -1711,38 +1711,11 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, + old_ea_inode = NULL; + goto out; + } +- } +- if (i->value && in_inode) { +- WARN_ON_ONCE(!i->value_len); +- +- new_ea_inode = ext4_xattr_inode_lookup_create(handle, inode, +- i->value, i->value_len); +- if (IS_ERR(new_ea_inode)) { +- ret = PTR_ERR(new_ea_inode); +- new_ea_inode = NULL; +- goto out; +- } +- } + +- if (old_ea_inode) { + /* We are ready to release ref count on the old_ea_inode. */ + ret = ext4_xattr_inode_dec_ref(handle, old_ea_inode); +- if (ret) { +- /* Release newly required ref count on new_ea_inode. */ +- if (new_ea_inode) { +- int err; +- +- err = ext4_xattr_inode_dec_ref(handle, +- new_ea_inode); +- if (err) +- ext4_warning_inode(new_ea_inode, +- "dec ref new_ea_inode err=%d", +- err); +- ext4_xattr_inode_free_quota(inode, new_ea_inode, +- i->value_len); +- } ++ if (ret) + goto out; +- } + + ext4_xattr_inode_free_quota(inode, old_ea_inode, + le32_to_cpu(here->e_value_size)); +@@ -1866,7 +1839,6 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, + ret = 0; + out: + iput(old_ea_inode); +- iput(new_ea_inode); + return ret; + } + +@@ -1929,9 +1901,21 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, + size_t old_ea_inode_quota = 0; + unsigned int ea_ino; + +- + #define header(x) ((struct ext4_xattr_header *)(x)) + ++ /* If we need EA inode, prepare it before locking the buffer */ ++ if (i->value && i->in_inode) { ++ WARN_ON_ONCE(!i->value_len); ++ ++ ea_inode = ext4_xattr_inode_lookup_create(handle, inode, ++ i->value, i->value_len); ++ if (IS_ERR(ea_inode)) { ++ error = PTR_ERR(ea_inode); ++ ea_inode = NULL; ++ goto cleanup; ++ } ++ } ++ + if (s->base) { + int offset = (char *)s->here - bs->bh->b_data; + +@@ -1940,6 +1924,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, + EXT4_JTR_NONE); + if (error) + goto cleanup; ++ + lock_buffer(bs->bh); + + if (header(s->base)->h_refcount == cpu_to_le32(1)) { +@@ -1966,7 +1951,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, + } + ea_bdebug(bs->bh, "modifying in-place"); + error = ext4_xattr_set_entry(i, s, handle, inode, +- true /* is_block */); ++ ea_inode, true /* is_block */); + ext4_xattr_block_csum_set(inode, bs->bh); + unlock_buffer(bs->bh); + if (error == -EFSCORRUPTED) +@@ -2034,29 +2019,13 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, + s->end = s->base + sb->s_blocksize; + } + +- error = ext4_xattr_set_entry(i, s, handle, inode, true /* is_block */); ++ error = ext4_xattr_set_entry(i, s, handle, inode, ea_inode, ++ true /* is_block */); + if (error == -EFSCORRUPTED) + goto bad_block; + if (error) + goto cleanup; + +- if (i->value && s->here->e_value_inum) { +- /* +- * A ref count on ea_inode has been taken as part of the call to +- * ext4_xattr_set_entry() above. We would like to drop this +- * extra ref but we have to wait until the xattr block is +- * initialized and has its own ref count on the ea_inode. +- */ +- ea_ino = le32_to_cpu(s->here->e_value_inum); +- error = ext4_xattr_inode_iget(inode, ea_ino, +- le32_to_cpu(s->here->e_hash), +- &ea_inode); +- if (error) { +- ea_inode = NULL; +- goto cleanup; +- } +- } +- + inserted: + if (!IS_LAST_ENTRY(s->first)) { + new_bh = ext4_xattr_block_cache_find(inode, header(s->base), +@@ -2198,17 +2167,16 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, + + cleanup: + if (ea_inode) { +- int error2; +- +- error2 = ext4_xattr_inode_dec_ref(handle, ea_inode); +- if (error2) +- ext4_warning_inode(ea_inode, "dec ref error=%d", +- error2); ++ if (error) { ++ int error2; + +- /* If there was an error, revert the quota charge. */ +- if (error) ++ error2 = ext4_xattr_inode_dec_ref(handle, ea_inode); ++ if (error2) ++ ext4_warning_inode(ea_inode, "dec ref error=%d", ++ error2); + ext4_xattr_inode_free_quota(inode, ea_inode, + i_size_read(ea_inode)); ++ } + iput(ea_inode); + } + if (ce) +@@ -2266,14 +2234,38 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode, + { + struct ext4_xattr_ibody_header *header; + struct ext4_xattr_search *s = &is->s; ++ struct inode *ea_inode = NULL; + int error; + + if (!EXT4_INODE_HAS_XATTR_SPACE(inode)) + return -ENOSPC; + +- error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */); +- if (error) ++ /* If we need EA inode, prepare it before locking the buffer */ ++ if (i->value && i->in_inode) { ++ WARN_ON_ONCE(!i->value_len); ++ ++ ea_inode = ext4_xattr_inode_lookup_create(handle, inode, ++ i->value, i->value_len); ++ if (IS_ERR(ea_inode)) ++ return PTR_ERR(ea_inode); ++ } ++ error = ext4_xattr_set_entry(i, s, handle, inode, ea_inode, ++ false /* is_block */); ++ if (error) { ++ if (ea_inode) { ++ int error2; ++ ++ error2 = ext4_xattr_inode_dec_ref(handle, ea_inode); ++ if (error2) ++ ext4_warning_inode(ea_inode, "dec ref error=%d", ++ error2); ++ ++ ext4_xattr_inode_free_quota(inode, ea_inode, ++ i_size_read(ea_inode)); ++ iput(ea_inode); ++ } + return error; ++ } + header = IHDR(inode, ext4_raw_inode(&is->iloc)); + if (!IS_LAST_ENTRY(s->first)) { + header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC); +@@ -2282,6 +2274,7 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode, + header->h_magic = cpu_to_le32(0); + ext4_clear_inode_state(inode, EXT4_STATE_XATTR); + } ++ iput(ea_inode); + return 0; + } + +diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c +index 7df5ad84cb5ea..15c9a9f5750bc 100644 +--- a/fs/f2fs/node.c ++++ b/fs/f2fs/node.c +@@ -1187,7 +1187,17 @@ int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from) + default: + BUG(); + } +- if (err < 0 && err != -ENOENT) ++ if (err == -ENOENT) { ++ set_sbi_flag(F2FS_P_SB(page), SBI_NEED_FSCK); ++ f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR); ++ f2fs_err_ratelimited(sbi, ++ "truncate node fail, ino:%lu, nid:%u, " ++ "offset[0]:%d, offset[1]:%d, nofs:%d", ++ inode->i_ino, dn.nid, offset[0], ++ offset[1], nofs); ++ err = 0; ++ } ++ if (err < 0) + goto fail; + if (offset[1] == 0 && + ri->i_nid[offset[0] - NODE_DIR1_BLOCK]) { +diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c +index a4bc26dfdb1af..2f75a7dfc311d 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -2132,8 +2132,6 @@ static void default_options(struct f2fs_sb_info *sbi, bool remount) + F2FS_OPTION(sbi).memory_mode = MEMORY_MODE_NORMAL; + F2FS_OPTION(sbi).errors = MOUNT_ERRORS_CONTINUE; + +- sbi->sb->s_flags &= ~SB_INLINECRYPT; +- + set_opt(sbi, INLINE_XATTR); + set_opt(sbi, INLINE_DATA); + set_opt(sbi, INLINE_DENTRY); +@@ -4131,9 +4129,15 @@ void f2fs_handle_critical_error(struct f2fs_sb_info *sbi, unsigned char reason, + if (shutdown) + set_sbi_flag(sbi, SBI_IS_SHUTDOWN); + +- /* continue filesystem operators if errors=continue */ +- if (continue_fs || f2fs_readonly(sb)) ++ /* ++ * Continue filesystem operators if errors=continue. Should not set ++ * RO by shutdown, since RO bypasses thaw_super which can hang the ++ * system. ++ */ ++ if (continue_fs || f2fs_readonly(sb) || shutdown) { ++ f2fs_warn(sbi, "Stopped filesystem due to reason: %d", reason); + return; ++ } + + f2fs_warn(sbi, "Remounting filesystem read-only"); + /* +diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c +index e4f17c53ddfcf..d31853032a931 100644 +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -2069,6 +2069,7 @@ static long wb_writeback(struct bdi_writeback *wb, + struct inode *inode; + long progress; + struct blk_plug plug; ++ bool queued = false; + + blk_start_plug(&plug); + for (;;) { +@@ -2111,8 +2112,10 @@ static long wb_writeback(struct bdi_writeback *wb, + dirtied_before = jiffies; + + trace_writeback_start(wb, work); +- if (list_empty(&wb->b_io)) ++ if (list_empty(&wb->b_io)) { + queue_io(wb, work, dirtied_before); ++ queued = true; ++ } + if (work->sb) + progress = writeback_sb_inodes(work->sb, wb, work); + else +@@ -2127,7 +2130,7 @@ static long wb_writeback(struct bdi_writeback *wb, + * mean the overall work is done. So we keep looping as long + * as made some progress on cleaning pages or inodes. + */ +- if (progress) { ++ if (progress || !queued) { + spin_unlock(&wb->list_lock); + continue; + } +diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c +index 604fea3a26ff0..86807086b2dfd 100644 +--- a/fs/ocfs2/journal.c ++++ b/fs/ocfs2/journal.c +@@ -479,12 +479,6 @@ int ocfs2_allocate_extend_trans(handle_t *handle, int thresh) + return status; + } + +- +-struct ocfs2_triggers { +- struct jbd2_buffer_trigger_type ot_triggers; +- int ot_offset; +-}; +- + static inline struct ocfs2_triggers *to_ocfs2_trigger(struct jbd2_buffer_trigger_type *triggers) + { + return container_of(triggers, struct ocfs2_triggers, ot_triggers); +@@ -548,85 +542,76 @@ static void ocfs2_db_frozen_trigger(struct jbd2_buffer_trigger_type *triggers, + static void ocfs2_abort_trigger(struct jbd2_buffer_trigger_type *triggers, + struct buffer_head *bh) + { ++ struct ocfs2_triggers *ot = to_ocfs2_trigger(triggers); ++ + mlog(ML_ERROR, + "ocfs2_abort_trigger called by JBD2. bh = 0x%lx, " + "bh->b_blocknr = %llu\n", + (unsigned long)bh, + (unsigned long long)bh->b_blocknr); + +- ocfs2_error(bh->b_assoc_map->host->i_sb, ++ ocfs2_error(ot->sb, + "JBD2 has aborted our journal, ocfs2 cannot continue\n"); + } + +-static struct ocfs2_triggers di_triggers = { +- .ot_triggers = { +- .t_frozen = ocfs2_frozen_trigger, +- .t_abort = ocfs2_abort_trigger, +- }, +- .ot_offset = offsetof(struct ocfs2_dinode, i_check), +-}; +- +-static struct ocfs2_triggers eb_triggers = { +- .ot_triggers = { +- .t_frozen = ocfs2_frozen_trigger, +- .t_abort = ocfs2_abort_trigger, +- }, +- .ot_offset = offsetof(struct ocfs2_extent_block, h_check), +-}; +- +-static struct ocfs2_triggers rb_triggers = { +- .ot_triggers = { +- .t_frozen = ocfs2_frozen_trigger, +- .t_abort = ocfs2_abort_trigger, +- }, +- .ot_offset = offsetof(struct ocfs2_refcount_block, rf_check), +-}; +- +-static struct ocfs2_triggers gd_triggers = { +- .ot_triggers = { +- .t_frozen = ocfs2_frozen_trigger, +- .t_abort = ocfs2_abort_trigger, +- }, +- .ot_offset = offsetof(struct ocfs2_group_desc, bg_check), +-}; +- +-static struct ocfs2_triggers db_triggers = { +- .ot_triggers = { +- .t_frozen = ocfs2_db_frozen_trigger, +- .t_abort = ocfs2_abort_trigger, +- }, +-}; ++static void ocfs2_setup_csum_triggers(struct super_block *sb, ++ enum ocfs2_journal_trigger_type type, ++ struct ocfs2_triggers *ot) ++{ ++ BUG_ON(type >= OCFS2_JOURNAL_TRIGGER_COUNT); + +-static struct ocfs2_triggers xb_triggers = { +- .ot_triggers = { +- .t_frozen = ocfs2_frozen_trigger, +- .t_abort = ocfs2_abort_trigger, +- }, +- .ot_offset = offsetof(struct ocfs2_xattr_block, xb_check), +-}; ++ switch (type) { ++ case OCFS2_JTR_DI: ++ ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; ++ ot->ot_offset = offsetof(struct ocfs2_dinode, i_check); ++ break; ++ case OCFS2_JTR_EB: ++ ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; ++ ot->ot_offset = offsetof(struct ocfs2_extent_block, h_check); ++ break; ++ case OCFS2_JTR_RB: ++ ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; ++ ot->ot_offset = offsetof(struct ocfs2_refcount_block, rf_check); ++ break; ++ case OCFS2_JTR_GD: ++ ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; ++ ot->ot_offset = offsetof(struct ocfs2_group_desc, bg_check); ++ break; ++ case OCFS2_JTR_DB: ++ ot->ot_triggers.t_frozen = ocfs2_db_frozen_trigger; ++ break; ++ case OCFS2_JTR_XB: ++ ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; ++ ot->ot_offset = offsetof(struct ocfs2_xattr_block, xb_check); ++ break; ++ case OCFS2_JTR_DQ: ++ ot->ot_triggers.t_frozen = ocfs2_dq_frozen_trigger; ++ break; ++ case OCFS2_JTR_DR: ++ ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; ++ ot->ot_offset = offsetof(struct ocfs2_dx_root_block, dr_check); ++ break; ++ case OCFS2_JTR_DL: ++ ot->ot_triggers.t_frozen = ocfs2_frozen_trigger; ++ ot->ot_offset = offsetof(struct ocfs2_dx_leaf, dl_check); ++ break; ++ case OCFS2_JTR_NONE: ++ /* To make compiler happy... */ ++ return; ++ } + +-static struct ocfs2_triggers dq_triggers = { +- .ot_triggers = { +- .t_frozen = ocfs2_dq_frozen_trigger, +- .t_abort = ocfs2_abort_trigger, +- }, +-}; ++ ot->ot_triggers.t_abort = ocfs2_abort_trigger; ++ ot->sb = sb; ++} + +-static struct ocfs2_triggers dr_triggers = { +- .ot_triggers = { +- .t_frozen = ocfs2_frozen_trigger, +- .t_abort = ocfs2_abort_trigger, +- }, +- .ot_offset = offsetof(struct ocfs2_dx_root_block, dr_check), +-}; ++void ocfs2_initialize_journal_triggers(struct super_block *sb, ++ struct ocfs2_triggers triggers[]) ++{ ++ enum ocfs2_journal_trigger_type type; + +-static struct ocfs2_triggers dl_triggers = { +- .ot_triggers = { +- .t_frozen = ocfs2_frozen_trigger, +- .t_abort = ocfs2_abort_trigger, +- }, +- .ot_offset = offsetof(struct ocfs2_dx_leaf, dl_check), +-}; ++ for (type = OCFS2_JTR_DI; type < OCFS2_JOURNAL_TRIGGER_COUNT; type++) ++ ocfs2_setup_csum_triggers(sb, type, &triggers[type]); ++} + + static int __ocfs2_journal_access(handle_t *handle, + struct ocfs2_caching_info *ci, +@@ -708,56 +693,91 @@ static int __ocfs2_journal_access(handle_t *handle, + int ocfs2_journal_access_di(handle_t *handle, struct ocfs2_caching_info *ci, + struct buffer_head *bh, int type) + { +- return __ocfs2_journal_access(handle, ci, bh, &di_triggers, type); ++ struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); ++ ++ return __ocfs2_journal_access(handle, ci, bh, ++ &osb->s_journal_triggers[OCFS2_JTR_DI], ++ type); + } + + int ocfs2_journal_access_eb(handle_t *handle, struct ocfs2_caching_info *ci, + struct buffer_head *bh, int type) + { +- return __ocfs2_journal_access(handle, ci, bh, &eb_triggers, type); ++ struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); ++ ++ return __ocfs2_journal_access(handle, ci, bh, ++ &osb->s_journal_triggers[OCFS2_JTR_EB], ++ type); + } + + int ocfs2_journal_access_rb(handle_t *handle, struct ocfs2_caching_info *ci, + struct buffer_head *bh, int type) + { +- return __ocfs2_journal_access(handle, ci, bh, &rb_triggers, ++ struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); ++ ++ return __ocfs2_journal_access(handle, ci, bh, ++ &osb->s_journal_triggers[OCFS2_JTR_RB], + type); + } + + int ocfs2_journal_access_gd(handle_t *handle, struct ocfs2_caching_info *ci, + struct buffer_head *bh, int type) + { +- return __ocfs2_journal_access(handle, ci, bh, &gd_triggers, type); ++ struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); ++ ++ return __ocfs2_journal_access(handle, ci, bh, ++ &osb->s_journal_triggers[OCFS2_JTR_GD], ++ type); + } + + int ocfs2_journal_access_db(handle_t *handle, struct ocfs2_caching_info *ci, + struct buffer_head *bh, int type) + { +- return __ocfs2_journal_access(handle, ci, bh, &db_triggers, type); ++ struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); ++ ++ return __ocfs2_journal_access(handle, ci, bh, ++ &osb->s_journal_triggers[OCFS2_JTR_DB], ++ type); + } + + int ocfs2_journal_access_xb(handle_t *handle, struct ocfs2_caching_info *ci, + struct buffer_head *bh, int type) + { +- return __ocfs2_journal_access(handle, ci, bh, &xb_triggers, type); ++ struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); ++ ++ return __ocfs2_journal_access(handle, ci, bh, ++ &osb->s_journal_triggers[OCFS2_JTR_XB], ++ type); + } + + int ocfs2_journal_access_dq(handle_t *handle, struct ocfs2_caching_info *ci, + struct buffer_head *bh, int type) + { +- return __ocfs2_journal_access(handle, ci, bh, &dq_triggers, type); ++ struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); ++ ++ return __ocfs2_journal_access(handle, ci, bh, ++ &osb->s_journal_triggers[OCFS2_JTR_DQ], ++ type); + } + + int ocfs2_journal_access_dr(handle_t *handle, struct ocfs2_caching_info *ci, + struct buffer_head *bh, int type) + { +- return __ocfs2_journal_access(handle, ci, bh, &dr_triggers, type); ++ struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); ++ ++ return __ocfs2_journal_access(handle, ci, bh, ++ &osb->s_journal_triggers[OCFS2_JTR_DR], ++ type); + } + + int ocfs2_journal_access_dl(handle_t *handle, struct ocfs2_caching_info *ci, + struct buffer_head *bh, int type) + { +- return __ocfs2_journal_access(handle, ci, bh, &dl_triggers, type); ++ struct ocfs2_super *osb = OCFS2_SB(ocfs2_metadata_cache_get_super(ci)); ++ ++ return __ocfs2_journal_access(handle, ci, bh, ++ &osb->s_journal_triggers[OCFS2_JTR_DL], ++ type); + } + + int ocfs2_journal_access(handle_t *handle, struct ocfs2_caching_info *ci, +@@ -778,13 +798,15 @@ void ocfs2_journal_dirty(handle_t *handle, struct buffer_head *bh) + if (!is_handle_aborted(handle)) { + journal_t *journal = handle->h_transaction->t_journal; + +- mlog(ML_ERROR, "jbd2_journal_dirty_metadata failed. " +- "Aborting transaction and journal.\n"); ++ mlog(ML_ERROR, "jbd2_journal_dirty_metadata failed: " ++ "handle type %u started at line %u, credits %u/%u " ++ "errcode %d. Aborting transaction and journal.\n", ++ handle->h_type, handle->h_line_no, ++ handle->h_requested_credits, ++ jbd2_handle_buffer_credits(handle), status); + handle->h_err = status; + jbd2_journal_abort_handle(handle); + jbd2_journal_abort(journal, status); +- ocfs2_abort(bh->b_assoc_map->host->i_sb, +- "Journal already aborted.\n"); + } + } + } +diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h +index a503c553bab21..8fe826143d7bf 100644 +--- a/fs/ocfs2/ocfs2.h ++++ b/fs/ocfs2/ocfs2.h +@@ -284,6 +284,30 @@ enum ocfs2_mount_options + #define OCFS2_OSB_ERROR_FS 0x0004 + #define OCFS2_DEFAULT_ATIME_QUANTUM 60 + ++struct ocfs2_triggers { ++ struct jbd2_buffer_trigger_type ot_triggers; ++ int ot_offset; ++ struct super_block *sb; ++}; ++ ++enum ocfs2_journal_trigger_type { ++ OCFS2_JTR_DI, ++ OCFS2_JTR_EB, ++ OCFS2_JTR_RB, ++ OCFS2_JTR_GD, ++ OCFS2_JTR_DB, ++ OCFS2_JTR_XB, ++ OCFS2_JTR_DQ, ++ OCFS2_JTR_DR, ++ OCFS2_JTR_DL, ++ OCFS2_JTR_NONE /* This must be the last entry */ ++}; ++ ++#define OCFS2_JOURNAL_TRIGGER_COUNT OCFS2_JTR_NONE ++ ++void ocfs2_initialize_journal_triggers(struct super_block *sb, ++ struct ocfs2_triggers triggers[]); ++ + struct ocfs2_journal; + struct ocfs2_slot_info; + struct ocfs2_recovery_map; +@@ -351,6 +375,9 @@ struct ocfs2_super + struct ocfs2_journal *journal; + unsigned long osb_commit_interval; + ++ /* Journal triggers for checksum */ ++ struct ocfs2_triggers s_journal_triggers[OCFS2_JOURNAL_TRIGGER_COUNT]; ++ + struct delayed_work la_enable_wq; + + /* +diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c +index 8aabaed2c1cb9..afee70125ae3b 100644 +--- a/fs/ocfs2/super.c ++++ b/fs/ocfs2/super.c +@@ -1075,9 +1075,11 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) + debugfs_create_file("fs_state", S_IFREG|S_IRUSR, osb->osb_debug_root, + osb, &ocfs2_osb_debug_fops); + +- if (ocfs2_meta_ecc(osb)) ++ if (ocfs2_meta_ecc(osb)) { ++ ocfs2_initialize_journal_triggers(sb, osb->s_journal_triggers); + ocfs2_blockcheck_stats_debugfs_install( &osb->osb_ecc_stats, + osb->osb_debug_root); ++ } + + status = ocfs2_mount_volume(sb); + if (status < 0) +diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c +index 063409069f56d..5868cb2229552 100644 +--- a/fs/overlayfs/export.c ++++ b/fs/overlayfs/export.c +@@ -181,6 +181,10 @@ static int ovl_check_encode_origin(struct dentry *dentry) + struct ovl_fs *ofs = OVL_FS(dentry->d_sb); + bool decodable = ofs->config.nfs_export; + ++ /* No upper layer? */ ++ if (!ovl_upper_mnt(ofs)) ++ return 1; ++ + /* Lower file handle for non-upper non-decodable */ + if (!ovl_dentry_upper(dentry) && !decodable) + return 1; +@@ -209,7 +213,7 @@ static int ovl_check_encode_origin(struct dentry *dentry) + * ovl_connect_layer() will try to make origin's layer "connected" by + * copying up a "connectable" ancestor. + */ +- if (d_is_dir(dentry) && ovl_upper_mnt(ofs) && decodable) ++ if (d_is_dir(dentry) && decodable) + return ovl_connect_layer(dentry); + + /* Lower file handle for indexed and non-upper dir/non-dir */ +diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c +index 4fb21affe4e11..d8ede68260007 100644 +--- a/fs/smb/client/cifsfs.c ++++ b/fs/smb/client/cifsfs.c +@@ -134,7 +134,7 @@ module_param(enable_oplocks, bool, 0644); + MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks. Default: y/Y/1"); + + module_param(enable_gcm_256, bool, 0644); +-MODULE_PARM_DESC(enable_gcm_256, "Enable requesting strongest (256 bit) GCM encryption. Default: n/N/0"); ++MODULE_PARM_DESC(enable_gcm_256, "Enable requesting strongest (256 bit) GCM encryption. Default: y/Y/0"); + + module_param(require_gcm_256, bool, 0644); + MODULE_PARM_DESC(require_gcm_256, "Require strongest (256 bit) GCM encryption. Default: n/N/0"); +diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c +index 758163af39c26..78ecc633606fb 100644 +--- a/fs/udf/udftime.c ++++ b/fs/udf/udftime.c +@@ -46,13 +46,18 @@ udf_disk_stamp_to_time(struct timespec64 *dest, struct timestamp src) + dest->tv_sec = mktime64(year, src.month, src.day, src.hour, src.minute, + src.second); + dest->tv_sec -= offset * 60; +- dest->tv_nsec = 1000 * (src.centiseconds * 10000 + +- src.hundredsOfMicroseconds * 100 + src.microseconds); ++ + /* + * Sanitize nanosecond field since reportedly some filesystems are + * recorded with bogus sub-second values. + */ +- dest->tv_nsec %= NSEC_PER_SEC; ++ if (src.centiseconds < 100 && src.hundredsOfMicroseconds < 100 && ++ src.microseconds < 100) { ++ dest->tv_nsec = 1000 * (src.centiseconds * 10000 + ++ src.hundredsOfMicroseconds * 100 + src.microseconds); ++ } else { ++ dest->tv_nsec = 0; ++ } + } + + void +diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h +index 3d90716f95229..f5fbc15e56980 100644 +--- a/include/acpi/acpixf.h ++++ b/include/acpi/acpixf.h +@@ -662,6 +662,10 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status + acpi_execute_reg_methods(acpi_handle device, + acpi_adr_space_type + space_id)) ++ACPI_EXTERNAL_RETURN_STATUS(acpi_status ++ acpi_execute_orphan_reg_method(acpi_handle device, ++ acpi_adr_space_type ++ space_id)) + ACPI_EXTERNAL_RETURN_STATUS(acpi_status + acpi_remove_address_space_handler(acpi_handle + device, +diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h +index 7cb1b75eee381..e742db470a711 100644 +--- a/include/linux/bpf_verifier.h ++++ b/include/linux/bpf_verifier.h +@@ -737,6 +737,8 @@ struct bpf_verifier_env { + /* Same as scratched_regs but for stack slots */ + u64 scratched_stack_slots; + u64 prev_log_pos, prev_insn_print_pos; ++ /* buffer used to temporary hold constants as scalar registers */ ++ struct bpf_reg_state fake_reg[2]; + /* buffer used to generate temporary string representations, + * e.g., in reg_type_str() to generate reg_type string + */ +diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h +index 0ce6ff0d9c9aa..de4cf0ee96f79 100644 +--- a/include/linux/cpuset.h ++++ b/include/linux/cpuset.h +@@ -70,7 +70,6 @@ extern int cpuset_init(void); + extern void cpuset_init_smp(void); + extern void cpuset_force_rebuild(void); + extern void cpuset_update_active_cpus(void); +-extern void cpuset_wait_for_hotplug(void); + extern void inc_dl_tasks_cs(struct task_struct *task); + extern void dec_dl_tasks_cs(struct task_struct *task); + extern void cpuset_lock(void); +@@ -185,8 +184,6 @@ static inline void cpuset_update_active_cpus(void) + partition_sched_domains(1, NULL, NULL); + } + +-static inline void cpuset_wait_for_hotplug(void) { } +- + static inline void inc_dl_tasks_cs(struct task_struct *task) { } + static inline void dec_dl_tasks_cs(struct task_struct *task) { } + static inline void cpuset_lock(void) { } +diff --git a/include/linux/kcov.h b/include/linux/kcov.h +index 1068a7318d897..75a2fb8b16c32 100644 +--- a/include/linux/kcov.h ++++ b/include/linux/kcov.h +@@ -21,6 +21,8 @@ enum kcov_mode { + KCOV_MODE_TRACE_PC = 2, + /* Collecting comparison operands mode. */ + KCOV_MODE_TRACE_CMP = 3, ++ /* The process owns a KCOV remote reference. */ ++ KCOV_MODE_REMOTE = 4, + }; + + #define KCOV_IN_CTXSW (1 << 30) +diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h +index 0ff44d6633e33..5fcbc254d1864 100644 +--- a/include/linux/kprobes.h ++++ b/include/linux/kprobes.h +@@ -378,11 +378,15 @@ static inline void wait_for_kprobe_optimizer(void) { } + extern void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, + struct ftrace_ops *ops, struct ftrace_regs *fregs); + extern int arch_prepare_kprobe_ftrace(struct kprobe *p); ++/* Set when ftrace has been killed: kprobes on ftrace must be disabled for safety */ ++extern bool kprobe_ftrace_disabled __read_mostly; ++extern void kprobe_ftrace_kill(void); + #else + static inline int arch_prepare_kprobe_ftrace(struct kprobe *p) + { + return -EINVAL; + } ++static inline void kprobe_ftrace_kill(void) {} + #endif /* CONFIG_KPROBES_ON_FTRACE */ + + /* Get the kprobe at this addr (if any) - called with preemption disabled */ +@@ -495,6 +499,9 @@ static inline void kprobe_flush_task(struct task_struct *tk) + static inline void kprobe_free_init_mem(void) + { + } ++static inline void kprobe_ftrace_kill(void) ++{ ++} + static inline int disable_kprobe(struct kprobe *kp) + { + return -EOPNOTSUPP; +diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h +index 334e00efbde45..7e539f6f8c674 100644 +--- a/include/linux/lsm_hook_defs.h ++++ b/include/linux/lsm_hook_defs.h +@@ -412,7 +412,7 @@ LSM_HOOK(void, LSM_RET_VOID, key_post_create_or_update, struct key *keyring, + + #ifdef CONFIG_AUDIT + LSM_HOOK(int, 0, audit_rule_init, u32 field, u32 op, char *rulestr, +- void **lsmrule) ++ void **lsmrule, gfp_t gfp) + LSM_HOOK(int, 0, audit_rule_known, struct audit_krule *krule) + LSM_HOOK(int, 0, audit_rule_match, u32 secid, u32 field, u32 op, void *lsmrule) + LSM_HOOK(void, LSM_RET_VOID, audit_rule_free, void *lsmrule) +diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h +index 7a9a07ea451bc..4338b1b4ac444 100644 +--- a/include/linux/mod_devicetable.h ++++ b/include/linux/mod_devicetable.h +@@ -690,6 +690,8 @@ struct x86_cpu_id { + __u16 model; + __u16 steppings; + __u16 feature; /* bit index */ ++ /* Solely for kernel-internal use: DO NOT EXPORT to userspace! */ ++ __u16 flags; + kernel_ulong_t driver_data; + }; + +diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h +index 5283b6193e7dc..d31e59e2e411a 100644 +--- a/include/linux/pagemap.h ++++ b/include/linux/pagemap.h +@@ -379,6 +379,10 @@ static inline void mapping_set_large_folios(struct address_space *mapping) + */ + static inline bool mapping_large_folio_support(struct address_space *mapping) + { ++ /* AS_LARGE_FOLIO_SUPPORT is only reasonable for pagecache folios */ ++ VM_WARN_ONCE((unsigned long)mapping & PAGE_MAPPING_ANON, ++ "Anonymous mapping always supports large folio"); ++ + return IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && + test_bit(AS_LARGE_FOLIO_SUPPORT, &mapping->flags); + } +diff --git a/include/linux/pci.h b/include/linux/pci.h +index 16493426a04ff..6f9c5ed5eb3ba 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -2519,7 +2519,12 @@ static inline struct pci_dev *pcie_find_root_port(struct pci_dev *dev) + + static inline bool pci_dev_is_disconnected(const struct pci_dev *dev) + { +- return dev->error_state == pci_channel_io_perm_failure; ++ /* ++ * error_state is set in pci_dev_set_io_state() using xchg/cmpxchg() ++ * and read w/o common lock. READ_ONCE() ensures compiler cannot cache ++ * the value (e.g. inside the loop in pci_dev_wait()). ++ */ ++ return READ_ONCE(dev->error_state) == pci_channel_io_perm_failure; + } + + void pci_request_acs(void); +diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h +index 772d3280d35fa..f24546a3d3db3 100644 +--- a/include/linux/pm_domain.h ++++ b/include/linux/pm_domain.h +@@ -260,6 +260,7 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, + int pm_genpd_init(struct generic_pm_domain *genpd, + struct dev_power_governor *gov, bool is_off); + int pm_genpd_remove(struct generic_pm_domain *genpd); ++struct device *dev_to_genpd_dev(struct device *dev); + int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state); + int dev_pm_genpd_add_notifier(struct device *dev, struct notifier_block *nb); + int dev_pm_genpd_remove_notifier(struct device *dev); +@@ -307,6 +308,11 @@ static inline int pm_genpd_remove(struct generic_pm_domain *genpd) + return -EOPNOTSUPP; + } + ++static inline struct device *dev_to_genpd_dev(struct device *dev) ++{ ++ return ERR_PTR(-EOPNOTSUPP); ++} ++ + static inline int dev_pm_genpd_set_performance_state(struct device *dev, + unsigned int state) + { +diff --git a/include/linux/security.h b/include/linux/security.h +index 41a8f667bdfa0..5122e3ad83b19 100644 +--- a/include/linux/security.h ++++ b/include/linux/security.h +@@ -2048,7 +2048,8 @@ static inline void security_key_post_create_or_update(struct key *keyring, + + #ifdef CONFIG_AUDIT + #ifdef CONFIG_SECURITY +-int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule); ++int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule, ++ gfp_t gfp); + int security_audit_rule_known(struct audit_krule *krule); + int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule); + void security_audit_rule_free(void *lsmrule); +@@ -2056,7 +2057,7 @@ void security_audit_rule_free(void *lsmrule); + #else + + static inline int security_audit_rule_init(u32 field, u32 op, char *rulestr, +- void **lsmrule) ++ void **lsmrule, gfp_t gfp) + { + return 0; + } +diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h +index 7372124fbf90b..dd4b31ce6d5d4 100644 +--- a/include/linux/tty_driver.h ++++ b/include/linux/tty_driver.h +@@ -154,6 +154,13 @@ struct serial_struct; + * + * Optional. Called under the @tty->termios_rwsem. May sleep. + * ++ * @ldisc_ok: ``int ()(struct tty_struct *tty, int ldisc)`` ++ * ++ * This routine allows the @tty driver to decide if it can deal ++ * with a particular @ldisc. ++ * ++ * Optional. Called under the @tty->ldisc_sem and @tty->termios_rwsem. ++ * + * @set_ldisc: ``void ()(struct tty_struct *tty)`` + * + * This routine allows the @tty driver to be notified when the device's +@@ -372,6 +379,7 @@ struct tty_operations { + void (*hangup)(struct tty_struct *tty); + int (*break_ctl)(struct tty_struct *tty, int state); + void (*flush_buffer)(struct tty_struct *tty); ++ int (*ldisc_ok)(struct tty_struct *tty, int ldisc); + void (*set_ldisc)(struct tty_struct *tty); + void (*wait_until_sent)(struct tty_struct *tty, int timeout); + void (*send_xchar)(struct tty_struct *tty, u8 ch); +diff --git a/include/net/netns/netfilter.h b/include/net/netns/netfilter.h +index 02bbdc577f8e2..a6a0bf4a247e5 100644 +--- a/include/net/netns/netfilter.h ++++ b/include/net/netns/netfilter.h +@@ -15,6 +15,9 @@ struct netns_nf { + const struct nf_logger __rcu *nf_loggers[NFPROTO_NUMPROTO]; + #ifdef CONFIG_SYSCTL + struct ctl_table_header *nf_log_dir_header; ++#ifdef CONFIG_LWTUNNEL ++ struct ctl_table_header *nf_lwtnl_dir_header; ++#endif + #endif + struct nf_hook_entries __rcu *hooks_ipv4[NF_INET_NUMHOOKS]; + struct nf_hook_entries __rcu *hooks_ipv6[NF_INET_NUMHOOKS]; +diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h +index 41ca14e81d55f..0014b9ee5e381 100644 +--- a/include/net/sch_generic.h ++++ b/include/net/sch_generic.h +@@ -128,6 +128,7 @@ struct Qdisc { + + struct rcu_head rcu; + netdevice_tracker dev_tracker; ++ struct lock_class_key root_lock_key; + /* private data */ + long privdata[] ____cacheline_aligned; + }; +diff --git a/include/scsi/scsi_devinfo.h b/include/scsi/scsi_devinfo.h +index 6b548dc2c4965..1d79a3b536cee 100644 +--- a/include/scsi/scsi_devinfo.h ++++ b/include/scsi/scsi_devinfo.h +@@ -69,8 +69,10 @@ + #define BLIST_RETRY_ITF ((__force blist_flags_t)(1ULL << 32)) + /* Always retry ABORTED_COMMAND with ASC 0xc1 */ + #define BLIST_RETRY_ASC_C1 ((__force blist_flags_t)(1ULL << 33)) ++/* Do not query the IO Advice Hints Grouping mode page */ ++#define BLIST_SKIP_IO_HINTS ((__force blist_flags_t)(1ULL << 34)) + +-#define __BLIST_LAST_USED BLIST_RETRY_ASC_C1 ++#define __BLIST_LAST_USED BLIST_SKIP_IO_HINTS + + #define __BLIST_HIGH_UNUSED (~(__BLIST_LAST_USED | \ + (__force blist_flags_t) \ +diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c +index 87f9aa7cf9255..956e2c715eb48 100644 +--- a/io_uring/rsrc.c ++++ b/io_uring/rsrc.c +@@ -1105,7 +1105,6 @@ int io_import_fixed(int ddir, struct iov_iter *iter, + * branch doesn't expect non PAGE_SIZE'd chunks. + */ + iter->bvec = bvec; +- iter->nr_segs = bvec->bv_len; + iter->count -= offset; + iter->iov_offset = offset; + } else { +diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c +index 158ab09c605ba..b3722e5275e77 100644 +--- a/io_uring/sqpoll.c ++++ b/io_uring/sqpoll.c +@@ -293,6 +293,14 @@ static int io_sq_thread(void *data) + sqd->sq_cpu = raw_smp_processor_id(); + } + ++ /* ++ * Force audit context to get setup, in case we do prep side async ++ * operations that would trigger an audit call before any issue side ++ * audit has been done. ++ */ ++ audit_uring_entry(IORING_OP_NOP); ++ audit_uring_exit(true, 0); ++ + mutex_lock(&sqd->lock); + while (1) { + bool cap_entries, sqt_spin = false; +diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c +index be8c680121e46..d6ef4f4f9cba5 100644 +--- a/kernel/auditfilter.c ++++ b/kernel/auditfilter.c +@@ -529,7 +529,8 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + entry->rule.buflen += f_val; + f->lsm_str = str; + err = security_audit_rule_init(f->type, f->op, str, +- (void **)&f->lsm_rule); ++ (void **)&f->lsm_rule, ++ GFP_KERNEL); + /* Keep currently invalid fields around in case they + * become valid after a policy reload. */ + if (err == -EINVAL) { +@@ -799,7 +800,7 @@ static inline int audit_dupe_lsm_field(struct audit_field *df, + + /* our own (refreshed) copy of lsm_rule */ + ret = security_audit_rule_init(df->type, df->op, df->lsm_str, +- (void **)&df->lsm_rule); ++ (void **)&df->lsm_rule, GFP_KERNEL); + /* Keep currently invalid fields around in case they + * become valid after a policy reload. */ + if (ret == -EINVAL) { +diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c +index 050fe1ebf0f7d..d0febf07051ed 100644 +--- a/kernel/bpf/lpm_trie.c ++++ b/kernel/bpf/lpm_trie.c +@@ -308,6 +308,7 @@ static long trie_update_elem(struct bpf_map *map, + { + struct lpm_trie *trie = container_of(map, struct lpm_trie, map); + struct lpm_trie_node *node, *im_node = NULL, *new_node = NULL; ++ struct lpm_trie_node *free_node = NULL; + struct lpm_trie_node __rcu **slot; + struct bpf_lpm_trie_key_u8 *key = _key; + unsigned long irq_flags; +@@ -382,7 +383,7 @@ static long trie_update_elem(struct bpf_map *map, + trie->n_entries--; + + rcu_assign_pointer(*slot, new_node); +- kfree_rcu(node, rcu); ++ free_node = node; + + goto out; + } +@@ -429,6 +430,7 @@ static long trie_update_elem(struct bpf_map *map, + } + + spin_unlock_irqrestore(&trie->lock, irq_flags); ++ kfree_rcu(free_node, rcu); + + return ret; + } +@@ -437,6 +439,7 @@ static long trie_update_elem(struct bpf_map *map, + static long trie_delete_elem(struct bpf_map *map, void *_key) + { + struct lpm_trie *trie = container_of(map, struct lpm_trie, map); ++ struct lpm_trie_node *free_node = NULL, *free_parent = NULL; + struct bpf_lpm_trie_key_u8 *key = _key; + struct lpm_trie_node __rcu **trim, **trim2; + struct lpm_trie_node *node, *parent; +@@ -506,8 +509,8 @@ static long trie_delete_elem(struct bpf_map *map, void *_key) + else + rcu_assign_pointer( + *trim2, rcu_access_pointer(parent->child[0])); +- kfree_rcu(parent, rcu); +- kfree_rcu(node, rcu); ++ free_parent = parent; ++ free_node = node; + goto out; + } + +@@ -521,10 +524,12 @@ static long trie_delete_elem(struct bpf_map *map, void *_key) + rcu_assign_pointer(*trim, rcu_access_pointer(node->child[1])); + else + RCU_INIT_POINTER(*trim, NULL); +- kfree_rcu(node, rcu); ++ free_node = node; + + out: + spin_unlock_irqrestore(&trie->lock, irq_flags); ++ kfree_rcu(free_parent, rcu); ++ kfree_rcu(free_node, rcu); + + return ret; + } +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 8a29309db4245..0ef18ae40bc5a 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -14973,7 +14973,6 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, + struct bpf_reg_state *regs = this_branch->frame[this_branch->curframe]->regs; + struct bpf_reg_state *dst_reg, *other_branch_regs, *src_reg = NULL; + struct bpf_reg_state *eq_branch_regs; +- struct bpf_reg_state fake_reg = {}; + u8 opcode = BPF_OP(insn->code); + bool is_jmp32; + int pred = -1; +@@ -15039,7 +15038,8 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, + verbose(env, "BPF_JMP/JMP32 uses reserved fields\n"); + return -EINVAL; + } +- src_reg = &fake_reg; ++ src_reg = &env->fake_reg[0]; ++ memset(src_reg, 0, sizeof(*src_reg)); + src_reg->type = SCALAR_VALUE; + __mark_reg_known(src_reg, insn->imm); + } +@@ -15099,10 +15099,16 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, + &other_branch_regs[insn->src_reg], + dst_reg, src_reg, opcode, is_jmp32); + } else /* BPF_SRC(insn->code) == BPF_K */ { ++ /* reg_set_min_max() can mangle the fake_reg. Make a copy ++ * so that these are two different memory locations. The ++ * src_reg is not used beyond here in context of K. ++ */ ++ memcpy(&env->fake_reg[1], &env->fake_reg[0], ++ sizeof(env->fake_reg[0])); + err = reg_set_min_max(env, + &other_branch_regs[insn->dst_reg], +- src_reg /* fake one */, +- dst_reg, src_reg /* same fake one */, ++ &env->fake_reg[0], ++ dst_reg, &env->fake_reg[1], + opcode, is_jmp32); + } + if (err) +diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c +index da24187c4e025..73ef0dabc3f22 100644 +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -201,6 +201,14 @@ struct cpuset { + struct list_head remote_sibling; + }; + ++/* ++ * Legacy hierarchy call to cgroup_transfer_tasks() is handled asynchrously ++ */ ++struct cpuset_remove_tasks_struct { ++ struct work_struct work; ++ struct cpuset *cs; ++}; ++ + /* + * Exclusive CPUs distributed out to sub-partitions of top_cpuset + */ +@@ -449,12 +457,6 @@ static DEFINE_SPINLOCK(callback_lock); + + static struct workqueue_struct *cpuset_migrate_mm_wq; + +-/* +- * CPU / memory hotplug is handled asynchronously. +- */ +-static void cpuset_hotplug_workfn(struct work_struct *work); +-static DECLARE_WORK(cpuset_hotplug_work, cpuset_hotplug_workfn); +- + static DECLARE_WAIT_QUEUE_HEAD(cpuset_attach_wq); + + static inline void check_insane_mems_config(nodemask_t *nodes) +@@ -540,22 +542,10 @@ static void guarantee_online_cpus(struct task_struct *tsk, + rcu_read_lock(); + cs = task_cs(tsk); + +- while (!cpumask_intersects(cs->effective_cpus, pmask)) { ++ while (!cpumask_intersects(cs->effective_cpus, pmask)) + cs = parent_cs(cs); +- if (unlikely(!cs)) { +- /* +- * The top cpuset doesn't have any online cpu as a +- * consequence of a race between cpuset_hotplug_work +- * and cpu hotplug notifier. But we know the top +- * cpuset's effective_cpus is on its way to be +- * identical to cpu_online_mask. +- */ +- goto out_unlock; +- } +- } +- cpumask_and(pmask, pmask, cs->effective_cpus); + +-out_unlock: ++ cpumask_and(pmask, pmask, cs->effective_cpus); + rcu_read_unlock(); + } + +@@ -1217,7 +1207,7 @@ static void rebuild_sched_domains_locked(void) + /* + * If we have raced with CPU hotplug, return early to avoid + * passing doms with offlined cpu to partition_sched_domains(). +- * Anyways, cpuset_hotplug_workfn() will rebuild sched domains. ++ * Anyways, cpuset_handle_hotplug() will rebuild sched domains. + * + * With no CPUs in any subpartitions, top_cpuset's effective CPUs + * should be the same as the active CPUs, so checking only top_cpuset +@@ -1260,12 +1250,17 @@ static void rebuild_sched_domains_locked(void) + } + #endif /* CONFIG_SMP */ + +-void rebuild_sched_domains(void) ++static void rebuild_sched_domains_cpuslocked(void) + { +- cpus_read_lock(); + mutex_lock(&cpuset_mutex); + rebuild_sched_domains_locked(); + mutex_unlock(&cpuset_mutex); ++} ++ ++void rebuild_sched_domains(void) ++{ ++ cpus_read_lock(); ++ rebuild_sched_domains_cpuslocked(); + cpus_read_unlock(); + } + +@@ -2079,14 +2074,11 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd, + + /* + * For partcmd_update without newmask, it is being called from +- * cpuset_hotplug_workfn() where cpus_read_lock() wasn't taken. +- * Update the load balance flag and scheduling domain if +- * cpus_read_trylock() is successful. ++ * cpuset_handle_hotplug(). Update the load balance flag and ++ * scheduling domain accordingly. + */ +- if ((cmd == partcmd_update) && !newmask && cpus_read_trylock()) { ++ if ((cmd == partcmd_update) && !newmask) + update_partition_sd_lb(cs, old_prs); +- cpus_read_unlock(); +- } + + notify_partition_change(cs, old_prs); + return 0; +@@ -3599,8 +3591,8 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of, + * proceeding, so that we don't end up keep removing tasks added + * after execution capability is restored. + * +- * cpuset_hotplug_work calls back into cgroup core via +- * cgroup_transfer_tasks() and waiting for it from a cgroupfs ++ * cpuset_handle_hotplug may call back into cgroup core asynchronously ++ * via cgroup_transfer_tasks() and waiting for it from a cgroupfs + * operation like this one can lead to a deadlock through kernfs + * active_ref protection. Let's break the protection. Losing the + * protection is okay as we check whether @cs is online after +@@ -3609,7 +3601,6 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of, + */ + css_get(&cs->css); + kernfs_break_active_protection(of->kn); +- flush_work(&cpuset_hotplug_work); + + cpus_read_lock(); + mutex_lock(&cpuset_mutex); +@@ -4354,6 +4345,16 @@ static void remove_tasks_in_empty_cpuset(struct cpuset *cs) + } + } + ++static void cpuset_migrate_tasks_workfn(struct work_struct *work) ++{ ++ struct cpuset_remove_tasks_struct *s; ++ ++ s = container_of(work, struct cpuset_remove_tasks_struct, work); ++ remove_tasks_in_empty_cpuset(s->cs); ++ css_put(&s->cs->css); ++ kfree(s); ++} ++ + static void + hotplug_update_tasks_legacy(struct cpuset *cs, + struct cpumask *new_cpus, nodemask_t *new_mems, +@@ -4383,12 +4384,21 @@ hotplug_update_tasks_legacy(struct cpuset *cs, + /* + * Move tasks to the nearest ancestor with execution resources, + * This is full cgroup operation which will also call back into +- * cpuset. Should be done outside any lock. ++ * cpuset. Execute it asynchronously using workqueue. + */ +- if (is_empty) { +- mutex_unlock(&cpuset_mutex); +- remove_tasks_in_empty_cpuset(cs); +- mutex_lock(&cpuset_mutex); ++ if (is_empty && cs->css.cgroup->nr_populated_csets && ++ css_tryget_online(&cs->css)) { ++ struct cpuset_remove_tasks_struct *s; ++ ++ s = kzalloc(sizeof(*s), GFP_KERNEL); ++ if (WARN_ON_ONCE(!s)) { ++ css_put(&cs->css); ++ return; ++ } ++ ++ s->cs = cs; ++ INIT_WORK(&s->work, cpuset_migrate_tasks_workfn); ++ schedule_work(&s->work); + } + } + +@@ -4421,30 +4431,6 @@ void cpuset_force_rebuild(void) + force_rebuild = true; + } + +-/* +- * Attempt to acquire a cpus_read_lock while a hotplug operation may be in +- * progress. +- * Return: true if successful, false otherwise +- * +- * To avoid circular lock dependency between cpuset_mutex and cpus_read_lock, +- * cpus_read_trylock() is used here to acquire the lock. +- */ +-static bool cpuset_hotplug_cpus_read_trylock(void) +-{ +- int retries = 0; +- +- while (!cpus_read_trylock()) { +- /* +- * CPU hotplug still in progress. Retry 5 times +- * with a 10ms wait before bailing out. +- */ +- if (++retries > 5) +- return false; +- msleep(10); +- } +- return true; +-} +- + /** + * cpuset_hotplug_update_tasks - update tasks in a cpuset for hotunplug + * @cs: cpuset in interest +@@ -4493,13 +4479,11 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp) + compute_partition_effective_cpumask(cs, &new_cpus); + + if (remote && cpumask_empty(&new_cpus) && +- partition_is_populated(cs, NULL) && +- cpuset_hotplug_cpus_read_trylock()) { ++ partition_is_populated(cs, NULL)) { + remote_partition_disable(cs, tmp); + compute_effective_cpumask(&new_cpus, cs, parent); + remote = false; + cpuset_force_rebuild(); +- cpus_read_unlock(); + } + + /* +@@ -4519,18 +4503,8 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp) + else if (is_partition_valid(parent) && is_partition_invalid(cs)) + partcmd = partcmd_update; + +- /* +- * cpus_read_lock needs to be held before calling +- * update_parent_effective_cpumask(). To avoid circular lock +- * dependency between cpuset_mutex and cpus_read_lock, +- * cpus_read_trylock() is used here to acquire the lock. +- */ + if (partcmd >= 0) { +- if (!cpuset_hotplug_cpus_read_trylock()) +- goto update_tasks; +- + update_parent_effective_cpumask(cs, partcmd, NULL, tmp); +- cpus_read_unlock(); + if ((partcmd == partcmd_invalidate) || is_partition_valid(cs)) { + compute_partition_effective_cpumask(cs, &new_cpus); + cpuset_force_rebuild(); +@@ -4558,8 +4532,7 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp) + } + + /** +- * cpuset_hotplug_workfn - handle CPU/memory hotunplug for a cpuset +- * @work: unused ++ * cpuset_handle_hotplug - handle CPU/memory hot{,un}plug for a cpuset + * + * This function is called after either CPU or memory configuration has + * changed and updates cpuset accordingly. The top_cpuset is always +@@ -4573,8 +4546,10 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp) + * + * Note that CPU offlining during suspend is ignored. We don't modify + * cpusets across suspend/resume cycles at all. ++ * ++ * CPU / memory hotplug is handled synchronously. + */ +-static void cpuset_hotplug_workfn(struct work_struct *work) ++static void cpuset_handle_hotplug(void) + { + static cpumask_t new_cpus; + static nodemask_t new_mems; +@@ -4585,6 +4560,7 @@ static void cpuset_hotplug_workfn(struct work_struct *work) + if (on_dfl && !alloc_cpumasks(NULL, &tmp)) + ptmp = &tmp; + ++ lockdep_assert_cpus_held(); + mutex_lock(&cpuset_mutex); + + /* fetch the available cpus/mems and find out which changed how */ +@@ -4666,7 +4642,7 @@ static void cpuset_hotplug_workfn(struct work_struct *work) + /* rebuild sched domains if cpus_allowed has changed */ + if (cpus_updated || force_rebuild) { + force_rebuild = false; +- rebuild_sched_domains(); ++ rebuild_sched_domains_cpuslocked(); + } + + free_cpumasks(NULL, ptmp); +@@ -4679,12 +4655,7 @@ void cpuset_update_active_cpus(void) + * inside cgroup synchronization. Bounce actual hotplug processing + * to a work item to avoid reverse locking order. + */ +- schedule_work(&cpuset_hotplug_work); +-} +- +-void cpuset_wait_for_hotplug(void) +-{ +- flush_work(&cpuset_hotplug_work); ++ cpuset_handle_hotplug(); + } + + /* +@@ -4695,7 +4666,7 @@ void cpuset_wait_for_hotplug(void) + static int cpuset_track_online_nodes(struct notifier_block *self, + unsigned long action, void *arg) + { +- schedule_work(&cpuset_hotplug_work); ++ cpuset_handle_hotplug(); + return NOTIFY_OK; + } + +diff --git a/kernel/cpu.c b/kernel/cpu.c +index 63447eb85dab6..563877d6c28b6 100644 +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -1208,52 +1208,6 @@ void __init cpuhp_threads_init(void) + kthread_unpark(this_cpu_read(cpuhp_state.thread)); + } + +-/* +- * +- * Serialize hotplug trainwrecks outside of the cpu_hotplug_lock +- * protected region. +- * +- * The operation is still serialized against concurrent CPU hotplug via +- * cpu_add_remove_lock, i.e. CPU map protection. But it is _not_ +- * serialized against other hotplug related activity like adding or +- * removing of state callbacks and state instances, which invoke either the +- * startup or the teardown callback of the affected state. +- * +- * This is required for subsystems which are unfixable vs. CPU hotplug and +- * evade lock inversion problems by scheduling work which has to be +- * completed _before_ cpu_up()/_cpu_down() returns. +- * +- * Don't even think about adding anything to this for any new code or even +- * drivers. It's only purpose is to keep existing lock order trainwrecks +- * working. +- * +- * For cpu_down() there might be valid reasons to finish cleanups which are +- * not required to be done under cpu_hotplug_lock, but that's a different +- * story and would be not invoked via this. +- */ +-static void cpu_up_down_serialize_trainwrecks(bool tasks_frozen) +-{ +- /* +- * cpusets delegate hotplug operations to a worker to "solve" the +- * lock order problems. Wait for the worker, but only if tasks are +- * _not_ frozen (suspend, hibernate) as that would wait forever. +- * +- * The wait is required because otherwise the hotplug operation +- * returns with inconsistent state, which could even be observed in +- * user space when a new CPU is brought up. The CPU plug uevent +- * would be delivered and user space reacting on it would fail to +- * move tasks to the newly plugged CPU up to the point where the +- * work has finished because up to that point the newly plugged CPU +- * is not assignable in cpusets/cgroups. On unplug that's not +- * necessarily a visible issue, but it is still inconsistent state, +- * which is the real problem which needs to be "fixed". This can't +- * prevent the transient state between scheduling the work and +- * returning from waiting for it. +- */ +- if (!tasks_frozen) +- cpuset_wait_for_hotplug(); +-} +- + #ifdef CONFIG_HOTPLUG_CPU + #ifndef arch_clear_mm_cpumask_cpu + #define arch_clear_mm_cpumask_cpu(cpu, mm) cpumask_clear_cpu(cpu, mm_cpumask(mm)) +@@ -1494,7 +1448,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, + */ + lockup_detector_cleanup(); + arch_smt_update(); +- cpu_up_down_serialize_trainwrecks(tasks_frozen); + return ret; + } + +@@ -1728,7 +1681,6 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target) + out: + cpus_write_unlock(); + arch_smt_update(); +- cpu_up_down_serialize_trainwrecks(tasks_frozen); + return ret; + } + +diff --git a/kernel/gcov/gcc_4_7.c b/kernel/gcov/gcc_4_7.c +index 74a4ef1da9ad7..fd75b4a484d76 100644 +--- a/kernel/gcov/gcc_4_7.c ++++ b/kernel/gcov/gcc_4_7.c +@@ -18,7 +18,9 @@ + #include <linux/mm.h> + #include "gcov.h" + +-#if (__GNUC__ >= 10) ++#if (__GNUC__ >= 14) ++#define GCOV_COUNTERS 9 ++#elif (__GNUC__ >= 10) + #define GCOV_COUNTERS 8 + #elif (__GNUC__ >= 7) + #define GCOV_COUNTERS 9 +diff --git a/kernel/kcov.c b/kernel/kcov.c +index f9ac2e9e460fc..9f4affae4fad4 100644 +--- a/kernel/kcov.c ++++ b/kernel/kcov.c +@@ -631,6 +631,7 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd, + return -EINVAL; + kcov->mode = mode; + t->kcov = kcov; ++ t->kcov_mode = KCOV_MODE_REMOTE; + kcov->t = t; + kcov->remote = true; + kcov->remote_size = remote_arg->area_size; +diff --git a/kernel/kprobes.c b/kernel/kprobes.c +index 65adc815fc6e6..4f917bdad1e11 100644 +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -1068,6 +1068,7 @@ static struct ftrace_ops kprobe_ipmodify_ops __read_mostly = { + + static int kprobe_ipmodify_enabled; + static int kprobe_ftrace_enabled; ++bool kprobe_ftrace_disabled; + + static int __arm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops, + int *cnt) +@@ -1136,6 +1137,11 @@ static int disarm_kprobe_ftrace(struct kprobe *p) + ipmodify ? &kprobe_ipmodify_ops : &kprobe_ftrace_ops, + ipmodify ? &kprobe_ipmodify_enabled : &kprobe_ftrace_enabled); + } ++ ++void kprobe_ftrace_kill(void) ++{ ++ kprobe_ftrace_disabled = true; ++} + #else /* !CONFIG_KPROBES_ON_FTRACE */ + static inline int arm_kprobe_ftrace(struct kprobe *p) + { +diff --git a/kernel/padata.c b/kernel/padata.c +index e3f639ff16707..53f4bc9127127 100644 +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -106,7 +106,7 @@ static int __init padata_work_alloc_mt(int nworks, void *data, + { + int i; + +- spin_lock(&padata_works_lock); ++ spin_lock_bh(&padata_works_lock); + /* Start at 1 because the current task participates in the job. */ + for (i = 1; i < nworks; ++i) { + struct padata_work *pw = padata_work_alloc(); +@@ -116,7 +116,7 @@ static int __init padata_work_alloc_mt(int nworks, void *data, + padata_work_init(pw, padata_mt_helper, data, 0); + list_add(&pw->pw_list, head); + } +- spin_unlock(&padata_works_lock); ++ spin_unlock_bh(&padata_works_lock); + + return i; + } +@@ -134,12 +134,12 @@ static void __init padata_works_free(struct list_head *works) + if (list_empty(works)) + return; + +- spin_lock(&padata_works_lock); ++ spin_lock_bh(&padata_works_lock); + list_for_each_entry_safe(cur, next, works, pw_list) { + list_del(&cur->pw_list); + padata_work_free(cur); + } +- spin_unlock(&padata_works_lock); ++ spin_unlock_bh(&padata_works_lock); + } + + static void padata_parallel_worker(struct work_struct *parallel_work) +diff --git a/kernel/power/process.c b/kernel/power/process.c +index cae81a87cc91e..66ac067d9ae64 100644 +--- a/kernel/power/process.c ++++ b/kernel/power/process.c +@@ -194,8 +194,6 @@ void thaw_processes(void) + __usermodehelper_set_disable_depth(UMH_FREEZING); + thaw_workqueues(); + +- cpuset_wait_for_hotplug(); +- + read_lock(&tasklist_lock); + for_each_process_thread(g, p) { + /* No other threads should have PF_SUSPEND_TASK set */ +diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c +index 45d6b4c3d199c..cf2e907534a8d 100644 +--- a/kernel/rcu/rcutorture.c ++++ b/kernel/rcu/rcutorture.c +@@ -1997,7 +1997,8 @@ static bool rcu_torture_one_read(struct torture_random_state *trsp, long myid) + preempt_disable(); + pipe_count = READ_ONCE(p->rtort_pipe_count); + if (pipe_count > RCU_TORTURE_PIPE_LEN) { +- /* Should not happen, but... */ ++ // Should not happen in a correct RCU implementation, ++ // happens quite often for torture_type=busted. + pipe_count = RCU_TORTURE_PIPE_LEN; + } + completed = cur_ops->get_gp_seq(); +@@ -2486,8 +2487,8 @@ static int rcu_torture_stall(void *args) + preempt_disable(); + pr_alert("%s start on CPU %d.\n", + __func__, raw_smp_processor_id()); +- while (ULONG_CMP_LT((unsigned long)ktime_get_seconds(), +- stop_at)) ++ while (ULONG_CMP_LT((unsigned long)ktime_get_seconds(), stop_at) && ++ !kthread_should_stop()) + if (stall_cpu_block) { + #ifdef CONFIG_PREEMPTION + preempt_schedule(); +@@ -3040,11 +3041,12 @@ static void rcu_torture_barrier_cbf(struct rcu_head *rcu) + } + + /* IPI handler to get callback posted on desired CPU, if online. */ +-static void rcu_torture_barrier1cb(void *rcu_void) ++static int rcu_torture_barrier1cb(void *rcu_void) + { + struct rcu_head *rhp = rcu_void; + + cur_ops->call(rhp, rcu_torture_barrier_cbf); ++ return 0; + } + + /* kthread function to register callbacks used to test RCU barriers. */ +@@ -3070,11 +3072,9 @@ static int rcu_torture_barrier_cbs(void *arg) + * The above smp_load_acquire() ensures barrier_phase load + * is ordered before the following ->call(). + */ +- if (smp_call_function_single(myid, rcu_torture_barrier1cb, +- &rcu, 1)) { +- // IPI failed, so use direct call from current CPU. ++ if (smp_call_on_cpu(myid, rcu_torture_barrier1cb, &rcu, 1)) + cur_ops->call(&rcu, rcu_torture_barrier_cbf); +- } ++ + if (atomic_dec_and_test(&barrier_cbs_count)) + wake_up(&barrier_wq); + } while (!torture_must_stop()); +diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c +index e5b260aa0e02c..4d50d53ac719f 100644 +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -20,6 +20,16 @@ + #include "tick-internal.h" + #include "timekeeping_internal.h" + ++static noinline u64 cycles_to_nsec_safe(struct clocksource *cs, u64 start, u64 end) ++{ ++ u64 delta = clocksource_delta(end, start, cs->mask); ++ ++ if (likely(delta < cs->max_cycles)) ++ return clocksource_cyc2ns(delta, cs->mult, cs->shift); ++ ++ return mul_u64_u32_shr(delta, cs->mult, cs->shift); ++} ++ + /** + * clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks + * @mult: pointer to mult variable +@@ -222,8 +232,8 @@ enum wd_read_status { + static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow) + { + unsigned int nretries, max_retries; +- u64 wd_end, wd_end2, wd_delta; + int64_t wd_delay, wd_seq_delay; ++ u64 wd_end, wd_end2; + + max_retries = clocksource_get_max_watchdog_retry(); + for (nretries = 0; nretries <= max_retries; nretries++) { +@@ -234,9 +244,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, + wd_end2 = watchdog->read(watchdog); + local_irq_enable(); + +- wd_delta = clocksource_delta(wd_end, *wdnow, watchdog->mask); +- wd_delay = clocksource_cyc2ns(wd_delta, watchdog->mult, +- watchdog->shift); ++ wd_delay = cycles_to_nsec_safe(watchdog, *wdnow, wd_end); + if (wd_delay <= WATCHDOG_MAX_SKEW) { + if (nretries > 1 || nretries >= max_retries) { + pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n", +@@ -254,8 +262,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, + * report system busy, reinit the watchdog and skip the current + * watchdog test. + */ +- wd_delta = clocksource_delta(wd_end2, wd_end, watchdog->mask); +- wd_seq_delay = clocksource_cyc2ns(wd_delta, watchdog->mult, watchdog->shift); ++ wd_seq_delay = cycles_to_nsec_safe(watchdog, wd_end, wd_end2); + if (wd_seq_delay > WATCHDOG_MAX_SKEW/2) + goto skip_test; + } +@@ -366,8 +373,7 @@ void clocksource_verify_percpu(struct clocksource *cs) + delta = (csnow_end - csnow_mid) & cs->mask; + if (delta < 0) + cpumask_set_cpu(cpu, &cpus_ahead); +- delta = clocksource_delta(csnow_end, csnow_begin, cs->mask); +- cs_nsec = clocksource_cyc2ns(delta, cs->mult, cs->shift); ++ cs_nsec = cycles_to_nsec_safe(cs, csnow_begin, csnow_end); + if (cs_nsec > cs_nsec_max) + cs_nsec_max = cs_nsec; + if (cs_nsec < cs_nsec_min) +@@ -398,8 +404,8 @@ static inline void clocksource_reset_watchdog(void) + + static void clocksource_watchdog(struct timer_list *unused) + { +- u64 csnow, wdnow, cslast, wdlast, delta; + int64_t wd_nsec, cs_nsec, interval; ++ u64 csnow, wdnow, cslast, wdlast; + int next_cpu, reset_pending; + struct clocksource *cs; + enum wd_read_status read_ret; +@@ -456,12 +462,8 @@ static void clocksource_watchdog(struct timer_list *unused) + continue; + } + +- delta = clocksource_delta(wdnow, cs->wd_last, watchdog->mask); +- wd_nsec = clocksource_cyc2ns(delta, watchdog->mult, +- watchdog->shift); +- +- delta = clocksource_delta(csnow, cs->cs_last, cs->mask); +- cs_nsec = clocksource_cyc2ns(delta, cs->mult, cs->shift); ++ wd_nsec = cycles_to_nsec_safe(watchdog, cs->wd_last, wdnow); ++ cs_nsec = cycles_to_nsec_safe(cs, cs->cs_last, csnow); + wdlast = cs->wd_last; /* save these in case we print them */ + cslast = cs->cs_last; + cs->cs_last = csnow; +@@ -832,7 +834,7 @@ void clocksource_start_suspend_timing(struct clocksource *cs, u64 start_cycles) + */ + u64 clocksource_stop_suspend_timing(struct clocksource *cs, u64 cycle_now) + { +- u64 now, delta, nsec = 0; ++ u64 now, nsec = 0; + + if (!suspend_clocksource) + return 0; +@@ -847,12 +849,8 @@ u64 clocksource_stop_suspend_timing(struct clocksource *cs, u64 cycle_now) + else + now = suspend_clocksource->read(suspend_clocksource); + +- if (now > suspend_start) { +- delta = clocksource_delta(now, suspend_start, +- suspend_clocksource->mask); +- nsec = mul_u64_u32_shr(delta, suspend_clocksource->mult, +- suspend_clocksource->shift); +- } ++ if (now > suspend_start) ++ nsec = cycles_to_nsec_safe(suspend_clocksource, suspend_start, now); + + /* + * Disable the suspend timer to save power if current clocksource is +diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig +index 47345bf1d4a9f..34804c7152ddf 100644 +--- a/kernel/trace/Kconfig ++++ b/kernel/trace/Kconfig +@@ -1123,7 +1123,7 @@ config PREEMPTIRQ_DELAY_TEST + + config SYNTH_EVENT_GEN_TEST + tristate "Test module for in-kernel synthetic event generation" +- depends on SYNTH_EVENTS ++ depends on SYNTH_EVENTS && m + help + This option creates a test module to check the base + functionality of in-kernel synthetic event definition and +@@ -1136,7 +1136,7 @@ config SYNTH_EVENT_GEN_TEST + + config KPROBE_EVENT_GEN_TEST + tristate "Test module for in-kernel kprobe event generation" +- depends on KPROBE_EVENTS ++ depends on KPROBE_EVENTS && m + help + This option creates a test module to check the base + functionality of in-kernel kprobe event definition. +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 1e12df9bb531b..2e11236722366 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -7902,6 +7902,7 @@ void ftrace_kill(void) + ftrace_disabled = 1; + ftrace_enabled = 0; + ftrace_trace_function = ftrace_stub; ++ kprobe_ftrace_kill(); + } + + /** +diff --git a/kernel/trace/preemptirq_delay_test.c b/kernel/trace/preemptirq_delay_test.c +index 8c4ffd0761624..cb0871fbdb07f 100644 +--- a/kernel/trace/preemptirq_delay_test.c ++++ b/kernel/trace/preemptirq_delay_test.c +@@ -215,4 +215,5 @@ static void __exit preemptirq_delay_exit(void) + + module_init(preemptirq_delay_init) + module_exit(preemptirq_delay_exit) ++MODULE_DESCRIPTION("Preempt / IRQ disable delay thread to test latency tracers"); + MODULE_LICENSE("GPL v2"); +diff --git a/lib/ubsan.h b/lib/ubsan.h +index 0abbbac8700d1..0982578fbd98f 100644 +--- a/lib/ubsan.h ++++ b/lib/ubsan.h +@@ -124,19 +124,32 @@ typedef s64 s_max; + typedef u64 u_max; + #endif + +-void __ubsan_handle_add_overflow(void *data, void *lhs, void *rhs); +-void __ubsan_handle_sub_overflow(void *data, void *lhs, void *rhs); +-void __ubsan_handle_mul_overflow(void *data, void *lhs, void *rhs); +-void __ubsan_handle_negate_overflow(void *_data, void *old_val); +-void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs); +-void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr); +-void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr); +-void __ubsan_handle_out_of_bounds(void *_data, void *index); +-void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs); +-void __ubsan_handle_builtin_unreachable(void *_data); +-void __ubsan_handle_load_invalid_value(void *_data, void *val); +-void __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr, +- unsigned long align, +- unsigned long offset); ++/* ++ * When generating Runtime Calls, Clang doesn't respect the -mregparm=3 ++ * option used on i386: https://github.com/llvm/llvm-project/issues/89670 ++ * Fix this for earlier Clang versions by forcing the calling convention ++ * to use non-register arguments. ++ */ ++#if defined(CONFIG_X86_32) && \ ++ defined(CONFIG_CC_IS_CLANG) && CONFIG_CLANG_VERSION < 190000 ++# define ubsan_linkage asmlinkage ++#else ++# define ubsan_linkage ++#endif ++ ++void ubsan_linkage __ubsan_handle_add_overflow(void *data, void *lhs, void *rhs); ++void ubsan_linkage __ubsan_handle_sub_overflow(void *data, void *lhs, void *rhs); ++void ubsan_linkage __ubsan_handle_mul_overflow(void *data, void *lhs, void *rhs); ++void ubsan_linkage __ubsan_handle_negate_overflow(void *_data, void *old_val); ++void ubsan_linkage __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs); ++void ubsan_linkage __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr); ++void ubsan_linkage __ubsan_handle_type_mismatch_v1(void *_data, void *ptr); ++void ubsan_linkage __ubsan_handle_out_of_bounds(void *_data, void *index); ++void ubsan_linkage __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs); ++void ubsan_linkage __ubsan_handle_builtin_unreachable(void *_data); ++void ubsan_linkage __ubsan_handle_load_invalid_value(void *_data, void *val); ++void ubsan_linkage __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr, ++ unsigned long align, ++ unsigned long offset); + + #endif +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index dd1fc105f70bd..769e8a125f0c9 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -3058,30 +3058,36 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list, + if (new_order >= folio_order(folio)) + return -EINVAL; + +- /* Cannot split anonymous THP to order-1 */ +- if (new_order == 1 && folio_test_anon(folio)) { +- VM_WARN_ONCE(1, "Cannot split to order-1 folio"); +- return -EINVAL; +- } +- +- if (new_order) { +- /* Only swapping a whole PMD-mapped folio is supported */ +- if (folio_test_swapcache(folio)) ++ if (folio_test_anon(folio)) { ++ /* order-1 is not supported for anonymous THP. */ ++ if (new_order == 1) { ++ VM_WARN_ONCE(1, "Cannot split to order-1 folio"); + return -EINVAL; ++ } ++ } else if (new_order) { + /* Split shmem folio to non-zero order not supported */ + if (shmem_mapping(folio->mapping)) { + VM_WARN_ONCE(1, + "Cannot split shmem folio to non-0 order"); + return -EINVAL; + } +- /* No split if the file system does not support large folio */ +- if (!mapping_large_folio_support(folio->mapping)) { ++ /* ++ * No split if the file system does not support large folio. ++ * Note that we might still have THPs in such mappings due to ++ * CONFIG_READ_ONLY_THP_FOR_FS. But in that case, the mapping ++ * does not actually support large folios properly. ++ */ ++ if (IS_ENABLED(CONFIG_READ_ONLY_THP_FOR_FS) && ++ !mapping_large_folio_support(folio->mapping)) { + VM_WARN_ONCE(1, + "Cannot split file folio to non-0 order"); + return -EINVAL; + } + } + ++ /* Only swapping a whole PMD-mapped folio is supported */ ++ if (folio_test_swapcache(folio) && new_order) ++ return -EINVAL; + + is_hzp = is_huge_zero_page(&folio->page); + if (is_hzp) { +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index fabce2b50c695..612558f306f4a 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -7531,8 +7531,7 @@ void __mem_cgroup_uncharge_folios(struct folio_batch *folios) + * @new: Replacement folio. + * + * Charge @new as a replacement folio for @old. @old will +- * be uncharged upon free. This is only used by the page cache +- * (in replace_page_cache_folio()). ++ * be uncharged upon free. + * + * Both folios must be locked, @new->mapping must be set up. + */ +diff --git a/mm/page_table_check.c b/mm/page_table_check.c +index af69c3c8f7c2d..6363f93a47c69 100644 +--- a/mm/page_table_check.c ++++ b/mm/page_table_check.c +@@ -71,6 +71,9 @@ static void page_table_check_clear(unsigned long pfn, unsigned long pgcnt) + page = pfn_to_page(pfn); + page_ext = page_ext_get(page); + ++ if (!page_ext) ++ return; ++ + BUG_ON(PageSlab(page)); + anon = PageAnon(page); + +@@ -108,6 +111,9 @@ static void page_table_check_set(unsigned long pfn, unsigned long pgcnt, + page = pfn_to_page(pfn); + page_ext = page_ext_get(page); + ++ if (!page_ext) ++ return; ++ + BUG_ON(PageSlab(page)); + anon = PageAnon(page); + +@@ -138,7 +144,10 @@ void __page_table_check_zero(struct page *page, unsigned int order) + BUG_ON(PageSlab(page)); + + page_ext = page_ext_get(page); +- BUG_ON(!page_ext); ++ ++ if (!page_ext) ++ return; ++ + for (i = 0; i < (1ul << order); i++) { + struct page_table_check *ptc = get_page_table_check(page_ext); + +diff --git a/mm/shmem.c b/mm/shmem.c +index 1f84a41aeb850..b66e99e2c70f3 100644 +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -1786,7 +1786,7 @@ static int shmem_replace_folio(struct folio **foliop, gfp_t gfp, + xa_lock_irq(&swap_mapping->i_pages); + error = shmem_replace_entry(swap_mapping, swap_index, old, new); + if (!error) { +- mem_cgroup_migrate(old, new); ++ mem_cgroup_replace_folio(old, new); + __lruvec_stat_mod_folio(new, NR_FILE_PAGES, 1); + __lruvec_stat_mod_folio(new, NR_SHMEM, 1); + __lruvec_stat_mod_folio(old, NR_FILE_PAGES, -1); +diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c +index 71c143d4b6d05..ac74f6ead62d5 100644 +--- a/net/batman-adv/originator.c ++++ b/net/batman-adv/originator.c +@@ -1266,6 +1266,8 @@ void batadv_purge_orig_ref(struct batadv_priv *bat_priv) + /* for all origins... */ + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; ++ if (hlist_empty(head)) ++ continue; + list_lock = &hash->list_locks[i]; + + spin_lock_bh(list_lock); +diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c +index b0f221d658be8..430ed18f8584c 100644 +--- a/net/core/drop_monitor.c ++++ b/net/core/drop_monitor.c +@@ -74,7 +74,7 @@ struct net_dm_hw_entries { + }; + + struct per_cpu_dm_data { +- spinlock_t lock; /* Protects 'skb', 'hw_entries' and ++ raw_spinlock_t lock; /* Protects 'skb', 'hw_entries' and + * 'send_timer' + */ + union { +@@ -168,9 +168,9 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data) + err: + mod_timer(&data->send_timer, jiffies + HZ / 10); + out: +- spin_lock_irqsave(&data->lock, flags); ++ raw_spin_lock_irqsave(&data->lock, flags); + swap(data->skb, skb); +- spin_unlock_irqrestore(&data->lock, flags); ++ raw_spin_unlock_irqrestore(&data->lock, flags); + + if (skb) { + struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data; +@@ -225,7 +225,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location) + + local_irq_save(flags); + data = this_cpu_ptr(&dm_cpu_data); +- spin_lock(&data->lock); ++ raw_spin_lock(&data->lock); + dskb = data->skb; + + if (!dskb) +@@ -259,7 +259,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location) + } + + out: +- spin_unlock_irqrestore(&data->lock, flags); ++ raw_spin_unlock_irqrestore(&data->lock, flags); + } + + static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb, +@@ -314,9 +314,9 @@ net_dm_hw_reset_per_cpu_data(struct per_cpu_dm_data *hw_data) + mod_timer(&hw_data->send_timer, jiffies + HZ / 10); + } + +- spin_lock_irqsave(&hw_data->lock, flags); ++ raw_spin_lock_irqsave(&hw_data->lock, flags); + swap(hw_data->hw_entries, hw_entries); +- spin_unlock_irqrestore(&hw_data->lock, flags); ++ raw_spin_unlock_irqrestore(&hw_data->lock, flags); + + return hw_entries; + } +@@ -448,7 +448,7 @@ net_dm_hw_trap_summary_probe(void *ignore, const struct devlink *devlink, + return; + + hw_data = this_cpu_ptr(&dm_hw_cpu_data); +- spin_lock_irqsave(&hw_data->lock, flags); ++ raw_spin_lock_irqsave(&hw_data->lock, flags); + hw_entries = hw_data->hw_entries; + + if (!hw_entries) +@@ -477,7 +477,7 @@ net_dm_hw_trap_summary_probe(void *ignore, const struct devlink *devlink, + } + + out: +- spin_unlock_irqrestore(&hw_data->lock, flags); ++ raw_spin_unlock_irqrestore(&hw_data->lock, flags); + } + + static const struct net_dm_alert_ops net_dm_alert_summary_ops = { +@@ -1673,7 +1673,7 @@ static struct notifier_block dropmon_net_notifier = { + + static void __net_dm_cpu_data_init(struct per_cpu_dm_data *data) + { +- spin_lock_init(&data->lock); ++ raw_spin_lock_init(&data->lock); + skb_queue_head_init(&data->drop_queue); + u64_stats_init(&data->stats.syncp); + } +diff --git a/net/core/filter.c b/net/core/filter.c +index a5856a8b4498b..ce255e0a2fbd9 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -1662,6 +1662,11 @@ static DEFINE_PER_CPU(struct bpf_scratchpad, bpf_sp); + static inline int __bpf_try_make_writable(struct sk_buff *skb, + unsigned int write_len) + { ++#ifdef CONFIG_DEBUG_NET ++ /* Avoid a splat in pskb_may_pull_reason() */ ++ if (write_len > INT_MAX) ++ return -EINVAL; ++#endif + return skb_ensure_writable(skb, write_len); + } + +diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c +index 9d690d32da33a..b1dc84c4fda11 100644 +--- a/net/core/net_namespace.c ++++ b/net/core/net_namespace.c +@@ -693,11 +693,16 @@ EXPORT_SYMBOL_GPL(__put_net); + * get_net_ns - increment the refcount of the network namespace + * @ns: common namespace (net) + * +- * Returns the net's common namespace. ++ * Returns the net's common namespace or ERR_PTR() if ref is zero. + */ + struct ns_common *get_net_ns(struct ns_common *ns) + { +- return &get_net(container_of(ns, struct net, ns))->ns; ++ struct net *net; ++ ++ net = maybe_get_net(container_of(ns, struct net, ns)); ++ if (net) ++ return &net->ns; ++ return ERR_PTR(-EINVAL); + } + EXPORT_SYMBOL_GPL(get_net_ns); + +diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c +index 7004b3399c2b0..8c2d5a0bc208e 100644 +--- a/net/core/netdev-genl.c ++++ b/net/core/netdev-genl.c +@@ -59,22 +59,22 @@ XDP_METADATA_KFUNC_xxx + nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_RX_METADATA_FEATURES, + xdp_rx_meta, NETDEV_A_DEV_PAD) || + nla_put_u64_64bit(rsp, NETDEV_A_DEV_XSK_FEATURES, +- xsk_features, NETDEV_A_DEV_PAD)) { +- genlmsg_cancel(rsp, hdr); +- return -EINVAL; +- } ++ xsk_features, NETDEV_A_DEV_PAD)) ++ goto err_cancel_msg; + + if (netdev->xdp_features & NETDEV_XDP_ACT_XSK_ZEROCOPY) { + if (nla_put_u32(rsp, NETDEV_A_DEV_XDP_ZC_MAX_SEGS, +- netdev->xdp_zc_max_segs)) { +- genlmsg_cancel(rsp, hdr); +- return -EINVAL; +- } ++ netdev->xdp_zc_max_segs)) ++ goto err_cancel_msg; + } + + genlmsg_end(rsp, hdr); + + return 0; ++ ++err_cancel_msg: ++ genlmsg_cancel(rsp, hdr); ++ return -EMSGSIZE; + } + + static void +diff --git a/net/core/netpoll.c b/net/core/netpoll.c +index 543007f159f99..55bcacf67df3b 100644 +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -316,7 +316,7 @@ static int netpoll_owner_active(struct net_device *dev) + struct napi_struct *napi; + + list_for_each_entry_rcu(napi, &dev->napi_list, dev_list) { +- if (napi->poll_owner == smp_processor_id()) ++ if (READ_ONCE(napi->poll_owner) == smp_processor_id()) + return 1; + } + return 0; +diff --git a/net/core/sock.c b/net/core/sock.c +index 0963689a59506..09eccc9c5020a 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -3743,6 +3743,9 @@ void sk_common_release(struct sock *sk) + + sk->sk_prot->unhash(sk); + ++ if (sk->sk_socket) ++ sk->sk_socket->sk = NULL; ++ + /* + * In this point socket cannot receive new packets, but it is possible + * that some packets are in flight because some CPU runs receiver and +diff --git a/net/devlink/core.c b/net/devlink/core.c +index 7f0b093208d75..f49cd83f1955f 100644 +--- a/net/devlink/core.c ++++ b/net/devlink/core.c +@@ -314,7 +314,7 @@ static void devlink_release(struct work_struct *work) + mutex_destroy(&devlink->lock); + lockdep_unregister_key(&devlink->lock_key); + put_device(devlink->dev); +- kfree(devlink); ++ kvfree(devlink); + } + + void devlink_put(struct devlink *devlink) +@@ -420,7 +420,7 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops, + if (!devlink_reload_actions_valid(ops)) + return NULL; + +- devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL); ++ devlink = kvzalloc(struct_size(devlink, priv, priv_size), GFP_KERNEL); + if (!devlink) + return NULL; + +@@ -455,7 +455,7 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops, + return devlink; + + err_xa_alloc: +- kfree(devlink); ++ kvfree(devlink); + return NULL; + } + EXPORT_SYMBOL_GPL(devlink_alloc_ns); +diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c +index 8b17d83e5fde4..1eb98440c01ea 100644 +--- a/net/ipv4/cipso_ipv4.c ++++ b/net/ipv4/cipso_ipv4.c +@@ -2012,12 +2012,16 @@ static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr) + * from there we can determine the new total option length */ + iter = 0; + optlen_new = 0; +- while (iter < opt->opt.optlen) +- if (opt->opt.__data[iter] != IPOPT_NOP) { ++ while (iter < opt->opt.optlen) { ++ if (opt->opt.__data[iter] == IPOPT_END) { ++ break; ++ } else if (opt->opt.__data[iter] == IPOPT_NOP) { ++ iter++; ++ } else { + iter += opt->opt.__data[iter + 1]; + optlen_new = iter; +- } else +- iter++; ++ } ++ } + hdr_delta = opt->opt.optlen; + opt->opt.optlen = (optlen_new + 3) & ~3; + hdr_delta -= opt->opt.optlen; +diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c +index 37c42b63ff993..09c0fa6756b7d 100644 +--- a/net/ipv4/tcp_ao.c ++++ b/net/ipv4/tcp_ao.c +@@ -1968,8 +1968,10 @@ static int tcp_ao_info_cmd(struct sock *sk, unsigned short int family, + first = true; + } + +- if (cmd.ao_required && tcp_ao_required_verify(sk)) +- return -EKEYREJECTED; ++ if (cmd.ao_required && tcp_ao_required_verify(sk)) { ++ err = -EKEYREJECTED; ++ goto out; ++ } + + /* For sockets in TCP_CLOSED it's possible set keys that aren't + * matching the future peer (address/port/VRF/etc), +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index a140d9f7a0a36..1054a440332d3 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -6289,6 +6289,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, + skb_rbtree_walk_from(data) + tcp_mark_skb_lost(sk, data); + tcp_xmit_retransmit_queue(sk); ++ tp->retrans_stamp = 0; + NET_INC_STATS(sock_net(sk), + LINUX_MIB_TCPFASTOPENACTIVEFAIL); + return true; +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 8f8c8fcfd1c21..d7a5ca012a8fc 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -638,6 +638,8 @@ static void rt6_probe(struct fib6_nh *fib6_nh) + rcu_read_lock(); + last_probe = READ_ONCE(fib6_nh->last_probe); + idev = __in6_dev_get(dev); ++ if (!idev) ++ goto out; + neigh = __ipv6_neigh_lookup_noref(dev, nh_gw); + if (neigh) { + if (READ_ONCE(neigh->nud_state) & NUD_VALID) +@@ -3603,7 +3605,7 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh, + if (!dev) + goto out; + +- if (idev->cnf.disable_ipv6) { ++ if (!idev || idev->cnf.disable_ipv6) { + NL_SET_ERR_MSG(extack, "IPv6 is disabled on nexthop device"); + err = -EACCES; + goto out; +diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c +index 24e2b4b494cb0..c434940131b1d 100644 +--- a/net/ipv6/seg6_local.c ++++ b/net/ipv6/seg6_local.c +@@ -941,8 +941,8 @@ static int input_action_end_dx6(struct sk_buff *skb, + + if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled)) + return NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, +- dev_net(skb->dev), NULL, skb, NULL, +- skb_dst(skb)->dev, input_action_end_dx6_finish); ++ dev_net(skb->dev), NULL, skb, skb->dev, ++ NULL, input_action_end_dx6_finish); + + return input_action_end_dx6_finish(dev_net(skb->dev), NULL, skb); + drop: +@@ -991,8 +991,8 @@ static int input_action_end_dx4(struct sk_buff *skb, + + if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled)) + return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, +- dev_net(skb->dev), NULL, skb, NULL, +- skb_dst(skb)->dev, input_action_end_dx4_finish); ++ dev_net(skb->dev), NULL, skb, skb->dev, ++ NULL, input_action_end_dx4_finish); + + return input_action_end_dx4_finish(dev_net(skb->dev), NULL, skb); + drop: +diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c +index ce48173c60e56..4332d4b82b1dc 100644 +--- a/net/ipv6/xfrm6_policy.c ++++ b/net/ipv6/xfrm6_policy.c +@@ -56,12 +56,18 @@ static int xfrm6_get_saddr(struct net *net, int oif, + { + struct dst_entry *dst; + struct net_device *dev; ++ struct inet6_dev *idev; + + dst = xfrm6_dst_lookup(net, 0, oif, NULL, daddr, mark); + if (IS_ERR(dst)) + return -EHOSTUNREACH; + +- dev = ip6_dst_idev(dst)->dev; ++ idev = ip6_dst_idev(dst); ++ if (!idev) { ++ dst_release(dst); ++ return -EHOSTUNREACH; ++ } ++ dev = idev->dev; + ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6); + dst_release(dst); + return 0; +diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c +index dce37ba8ebe37..254d745832cbf 100644 +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -311,6 +311,18 @@ int drv_assign_vif_chanctx(struct ieee80211_local *local, + might_sleep(); + lockdep_assert_wiphy(local->hw.wiphy); + ++ /* ++ * We should perhaps push emulate chanctx down and only ++ * make it call ->config() when the chanctx is actually ++ * assigned here (and unassigned below), but that's yet ++ * another change to all drivers to add assign/unassign ++ * emulation callbacks. Maybe later. ++ */ ++ if (sdata->vif.type == NL80211_IFTYPE_MONITOR && ++ local->emulate_chanctx && ++ !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) ++ return 0; ++ + if (!check_sdata_in_driver(sdata)) + return -EIO; + +@@ -338,6 +350,11 @@ void drv_unassign_vif_chanctx(struct ieee80211_local *local, + might_sleep(); + lockdep_assert_wiphy(local->hw.wiphy); + ++ if (sdata->vif.type == NL80211_IFTYPE_MONITOR && ++ local->emulate_chanctx && ++ !ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) ++ return; ++ + if (!check_sdata_in_driver(sdata)) + return; + +diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c +index ef6b0fc82d022..7c8a421f0901d 100644 +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -686,6 +686,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do + ieee80211_del_virtual_monitor(local); + + ieee80211_recalc_idle(local); ++ ieee80211_recalc_offload(local); + + if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)) + break; +@@ -1121,9 +1122,6 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) + struct ieee80211_sub_if_data *sdata; + int ret; + +- if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) +- return 0; +- + ASSERT_RTNL(); + lockdep_assert_wiphy(local->hw.wiphy); + +@@ -1145,11 +1143,13 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) + + ieee80211_set_default_queues(sdata); + +- ret = drv_add_interface(local, sdata); +- if (WARN_ON(ret)) { +- /* ok .. stupid driver, it asked for this! */ +- kfree(sdata); +- return ret; ++ if (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) { ++ ret = drv_add_interface(local, sdata); ++ if (WARN_ON(ret)) { ++ /* ok .. stupid driver, it asked for this! */ ++ kfree(sdata); ++ return ret; ++ } + } + + set_bit(SDATA_STATE_RUNNING, &sdata->state); +@@ -1187,9 +1187,6 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local) + { + struct ieee80211_sub_if_data *sdata; + +- if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) +- return; +- + ASSERT_RTNL(); + lockdep_assert_wiphy(local->hw.wiphy); + +@@ -1209,7 +1206,8 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local) + + ieee80211_link_release_channel(&sdata->deflink); + +- drv_remove_interface(local, sdata); ++ if (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) ++ drv_remove_interface(local, sdata); + + kfree(sdata); + } +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index a237cbcf7b491..0da5f6082d159 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1841,7 +1841,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) + + /* add interfaces */ + sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata); +- if (sdata) { ++ if (sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) { + /* in HW restart it exists already */ + WARN_ON(local->resuming); + res = drv_add_interface(local, sdata); +diff --git a/net/netfilter/core.c b/net/netfilter/core.c +index 3126911f50425..b00fc285b3349 100644 +--- a/net/netfilter/core.c ++++ b/net/netfilter/core.c +@@ -815,12 +815,21 @@ int __init netfilter_init(void) + if (ret < 0) + goto err; + ++#ifdef CONFIG_LWTUNNEL ++ ret = netfilter_lwtunnel_init(); ++ if (ret < 0) ++ goto err_lwtunnel_pernet; ++#endif + ret = netfilter_log_init(); + if (ret < 0) +- goto err_pernet; ++ goto err_log_pernet; + + return 0; +-err_pernet: ++err_log_pernet: ++#ifdef CONFIG_LWTUNNEL ++ netfilter_lwtunnel_fini(); ++err_lwtunnel_pernet: ++#endif + unregister_pernet_subsys(&netfilter_net_ops); + err: + return ret; +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index c7ae4d9bf3d24..61431690cbd5f 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -53,12 +53,13 @@ MODULE_DESCRIPTION("core IP set support"); + MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET); + + /* When the nfnl mutex or ip_set_ref_lock is held: */ +-#define ip_set_dereference(p) \ +- rcu_dereference_protected(p, \ ++#define ip_set_dereference(inst) \ ++ rcu_dereference_protected((inst)->ip_set_list, \ + lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET) || \ +- lockdep_is_held(&ip_set_ref_lock)) ++ lockdep_is_held(&ip_set_ref_lock) || \ ++ (inst)->is_deleted) + #define ip_set(inst, id) \ +- ip_set_dereference((inst)->ip_set_list)[id] ++ ip_set_dereference(inst)[id] + #define ip_set_ref_netlink(inst,id) \ + rcu_dereference_raw((inst)->ip_set_list)[id] + #define ip_set_dereference_nfnl(p) \ +@@ -1133,7 +1134,7 @@ static int ip_set_create(struct sk_buff *skb, const struct nfnl_info *info, + if (!list) + goto cleanup; + /* nfnl mutex is held, both lists are valid */ +- tmp = ip_set_dereference(inst->ip_set_list); ++ tmp = ip_set_dereference(inst); + memcpy(list, tmp, sizeof(struct ip_set *) * inst->ip_set_max); + rcu_assign_pointer(inst->ip_set_list, list); + /* Make sure all current packets have passed through */ +diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c +index 0ee98ce5b8165..559665467b04d 100644 +--- a/net/netfilter/nf_conntrack_standalone.c ++++ b/net/netfilter/nf_conntrack_standalone.c +@@ -22,9 +22,6 @@ + #include <net/netfilter/nf_conntrack_acct.h> + #include <net/netfilter/nf_conntrack_zones.h> + #include <net/netfilter/nf_conntrack_timestamp.h> +-#ifdef CONFIG_LWTUNNEL +-#include <net/netfilter/nf_hooks_lwtunnel.h> +-#endif + #include <linux/rculist_nulls.h> + + static bool enable_hooks __read_mostly; +@@ -612,9 +609,6 @@ enum nf_ct_sysctl_index { + NF_SYSCTL_CT_PROTO_TIMEOUT_GRE, + NF_SYSCTL_CT_PROTO_TIMEOUT_GRE_STREAM, + #endif +-#ifdef CONFIG_LWTUNNEL +- NF_SYSCTL_CT_LWTUNNEL, +-#endif + + __NF_SYSCTL_CT_LAST_SYSCTL, + }; +@@ -947,15 +941,6 @@ static struct ctl_table nf_ct_sysctl_table[] = { + .mode = 0644, + .proc_handler = proc_dointvec_jiffies, + }, +-#endif +-#ifdef CONFIG_LWTUNNEL +- [NF_SYSCTL_CT_LWTUNNEL] = { +- .procname = "nf_hooks_lwtunnel", +- .data = NULL, +- .maxlen = sizeof(int), +- .mode = 0644, +- .proc_handler = nf_hooks_lwtunnel_sysctl_handler, +- }, + #endif + {} + }; +diff --git a/net/netfilter/nf_hooks_lwtunnel.c b/net/netfilter/nf_hooks_lwtunnel.c +index 00e89ffd78f69..7cdb59bb4459f 100644 +--- a/net/netfilter/nf_hooks_lwtunnel.c ++++ b/net/netfilter/nf_hooks_lwtunnel.c +@@ -3,6 +3,9 @@ + #include <linux/sysctl.h> + #include <net/lwtunnel.h> + #include <net/netfilter/nf_hooks_lwtunnel.h> ++#include <linux/netfilter.h> ++ ++#include "nf_internals.h" + + static inline int nf_hooks_lwtunnel_get(void) + { +@@ -50,4 +53,68 @@ int nf_hooks_lwtunnel_sysctl_handler(struct ctl_table *table, int write, + return ret; + } + EXPORT_SYMBOL_GPL(nf_hooks_lwtunnel_sysctl_handler); ++ ++static struct ctl_table nf_lwtunnel_sysctl_table[] = { ++ { ++ .procname = "nf_hooks_lwtunnel", ++ .data = NULL, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = nf_hooks_lwtunnel_sysctl_handler, ++ }, ++}; ++ ++static int __net_init nf_lwtunnel_net_init(struct net *net) ++{ ++ struct ctl_table_header *hdr; ++ struct ctl_table *table; ++ ++ table = nf_lwtunnel_sysctl_table; ++ if (!net_eq(net, &init_net)) { ++ table = kmemdup(nf_lwtunnel_sysctl_table, ++ sizeof(nf_lwtunnel_sysctl_table), ++ GFP_KERNEL); ++ if (!table) ++ goto err_alloc; ++ } ++ ++ hdr = register_net_sysctl_sz(net, "net/netfilter", table, ++ ARRAY_SIZE(nf_lwtunnel_sysctl_table)); ++ if (!hdr) ++ goto err_reg; ++ ++ net->nf.nf_lwtnl_dir_header = hdr; ++ ++ return 0; ++err_reg: ++ if (!net_eq(net, &init_net)) ++ kfree(table); ++err_alloc: ++ return -ENOMEM; ++} ++ ++static void __net_exit nf_lwtunnel_net_exit(struct net *net) ++{ ++ const struct ctl_table *table; ++ ++ table = net->nf.nf_lwtnl_dir_header->ctl_table_arg; ++ unregister_net_sysctl_table(net->nf.nf_lwtnl_dir_header); ++ if (!net_eq(net, &init_net)) ++ kfree(table); ++} ++ ++static struct pernet_operations nf_lwtunnel_net_ops = { ++ .init = nf_lwtunnel_net_init, ++ .exit = nf_lwtunnel_net_exit, ++}; ++ ++int __init netfilter_lwtunnel_init(void) ++{ ++ return register_pernet_subsys(&nf_lwtunnel_net_ops); ++} ++ ++void netfilter_lwtunnel_fini(void) ++{ ++ unregister_pernet_subsys(&nf_lwtunnel_net_ops); ++} + #endif /* CONFIG_SYSCTL */ +diff --git a/net/netfilter/nf_internals.h b/net/netfilter/nf_internals.h +index 832ae64179f0f..25403023060b6 100644 +--- a/net/netfilter/nf_internals.h ++++ b/net/netfilter/nf_internals.h +@@ -29,6 +29,12 @@ void nf_queue_nf_hook_drop(struct net *net); + /* nf_log.c */ + int __init netfilter_log_init(void); + ++#ifdef CONFIG_LWTUNNEL ++/* nf_hooks_lwtunnel.c */ ++int __init netfilter_lwtunnel_init(void); ++void netfilter_lwtunnel_fini(void); ++#endif ++ + /* core.c */ + void nf_hook_entries_delete_raw(struct nf_hook_entries __rcu **pp, + const struct nf_hook_ops *reg); +diff --git a/net/netrom/nr_timer.c b/net/netrom/nr_timer.c +index 4e7c968cde2dc..5e3ca068f04e0 100644 +--- a/net/netrom/nr_timer.c ++++ b/net/netrom/nr_timer.c +@@ -121,7 +121,8 @@ static void nr_heartbeat_expiry(struct timer_list *t) + is accepted() it isn't 'dead' so doesn't get removed. */ + if (sock_flag(sk, SOCK_DESTROY) || + (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) { +- sock_hold(sk); ++ if (sk->sk_state == TCP_LISTEN) ++ sock_hold(sk); + bh_unlock_sock(sk); + nr_destroy_socket(sk); + goto out; +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 150451ddd7553..ea3ebc160e25c 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3799,28 +3799,30 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval, + case PACKET_TX_RING: + { + union tpacket_req_u req_u; +- int len; + ++ ret = -EINVAL; + lock_sock(sk); + switch (po->tp_version) { + case TPACKET_V1: + case TPACKET_V2: +- len = sizeof(req_u.req); ++ if (optlen < sizeof(req_u.req)) ++ break; ++ ret = copy_from_sockptr(&req_u.req, optval, ++ sizeof(req_u.req)) ? ++ -EINVAL : 0; + break; + case TPACKET_V3: + default: +- len = sizeof(req_u.req3); ++ if (optlen < sizeof(req_u.req3)) ++ break; ++ ret = copy_from_sockptr(&req_u.req3, optval, ++ sizeof(req_u.req3)) ? ++ -EINVAL : 0; + break; + } +- if (optlen < len) { +- ret = -EINVAL; +- } else { +- if (copy_from_sockptr(&req_u.req, optval, len)) +- ret = -EFAULT; +- else +- ret = packet_set_ring(sk, &req_u, 0, +- optname == PACKET_TX_RING); +- } ++ if (!ret) ++ ret = packet_set_ring(sk, &req_u, 0, ++ optname == PACKET_TX_RING); + release_sock(sk); + return ret; + } +diff --git a/net/sched/act_api.c b/net/sched/act_api.c +index 9ee622fb1160f..2520708b06a12 100644 +--- a/net/sched/act_api.c ++++ b/net/sched/act_api.c +@@ -830,7 +830,6 @@ int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index, + u32 max; + + if (*index) { +-again: + rcu_read_lock(); + p = idr_find(&idrinfo->action_idr, *index); + +@@ -839,7 +838,7 @@ int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index, + * index but did not assign the pointer yet. + */ + rcu_read_unlock(); +- goto again; ++ return -EAGAIN; + } + + if (!p) { +diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c +index baac083fd8f10..2a96d9c1db65b 100644 +--- a/net/sched/act_ct.c ++++ b/net/sched/act_ct.c +@@ -41,21 +41,26 @@ static struct workqueue_struct *act_ct_wq; + static struct rhashtable zones_ht; + static DEFINE_MUTEX(zones_mutex); + ++struct zones_ht_key { ++ struct net *net; ++ u16 zone; ++}; ++ + struct tcf_ct_flow_table { + struct rhash_head node; /* In zones tables */ + + struct rcu_work rwork; + struct nf_flowtable nf_ft; + refcount_t ref; +- u16 zone; ++ struct zones_ht_key key; + + bool dying; + }; + + static const struct rhashtable_params zones_params = { + .head_offset = offsetof(struct tcf_ct_flow_table, node), +- .key_offset = offsetof(struct tcf_ct_flow_table, zone), +- .key_len = sizeof_field(struct tcf_ct_flow_table, zone), ++ .key_offset = offsetof(struct tcf_ct_flow_table, key), ++ .key_len = sizeof_field(struct tcf_ct_flow_table, key), + .automatic_shrinking = true, + }; + +@@ -316,11 +321,12 @@ static struct nf_flowtable_type flowtable_ct = { + + static int tcf_ct_flow_table_get(struct net *net, struct tcf_ct_params *params) + { ++ struct zones_ht_key key = { .net = net, .zone = params->zone }; + struct tcf_ct_flow_table *ct_ft; + int err = -ENOMEM; + + mutex_lock(&zones_mutex); +- ct_ft = rhashtable_lookup_fast(&zones_ht, ¶ms->zone, zones_params); ++ ct_ft = rhashtable_lookup_fast(&zones_ht, &key, zones_params); + if (ct_ft && refcount_inc_not_zero(&ct_ft->ref)) + goto out_unlock; + +@@ -329,7 +335,7 @@ static int tcf_ct_flow_table_get(struct net *net, struct tcf_ct_params *params) + goto err_alloc; + refcount_set(&ct_ft->ref, 1); + +- ct_ft->zone = params->zone; ++ ct_ft->key = key; + err = rhashtable_insert_fast(&zones_ht, &ct_ft->node, zones_params); + if (err) + goto err_insert; +diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c +index 60239378d43fb..6292d6d73b720 100644 +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -1389,6 +1389,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev, + ops->destroy(sch); + qdisc_put_stab(rtnl_dereference(sch->stab)); + err_out3: ++ lockdep_unregister_key(&sch->root_lock_key); + netdev_put(dev, &sch->dev_tracker); + qdisc_free(sch); + err_out2: +diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c +index 10b1491d55809..fb32984d7a168 100644 +--- a/net/sched/sch_generic.c ++++ b/net/sched/sch_generic.c +@@ -946,7 +946,9 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, + __skb_queue_head_init(&sch->gso_skb); + __skb_queue_head_init(&sch->skb_bad_txq); + gnet_stats_basic_sync_init(&sch->bstats); ++ lockdep_register_key(&sch->root_lock_key); + spin_lock_init(&sch->q.lock); ++ lockdep_set_class(&sch->q.lock, &sch->root_lock_key); + + if (ops->static_flags & TCQ_F_CPUSTATS) { + sch->cpu_bstats = +@@ -981,6 +983,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, + + return sch; + errout1: ++ lockdep_unregister_key(&sch->root_lock_key); + kfree(sch); + errout: + return ERR_PTR(err); +@@ -1069,6 +1072,7 @@ static void __qdisc_destroy(struct Qdisc *qdisc) + if (ops->destroy) + ops->destroy(qdisc); + ++ lockdep_unregister_key(&qdisc->root_lock_key); + module_put(ops->owner); + netdev_put(dev, &qdisc->dev_tracker); + +diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c +index 93e6fb56f3b58..ff3de37874e4b 100644 +--- a/net/sched/sch_htb.c ++++ b/net/sched/sch_htb.c +@@ -1039,13 +1039,6 @@ static void htb_work_func(struct work_struct *work) + rcu_read_unlock(); + } + +-static void htb_set_lockdep_class_child(struct Qdisc *q) +-{ +- static struct lock_class_key child_key; +- +- lockdep_set_class(qdisc_lock(q), &child_key); +-} +- + static int htb_offload(struct net_device *dev, struct tc_htb_qopt_offload *opt) + { + return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_HTB, opt); +@@ -1132,7 +1125,6 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt, + return -ENOMEM; + } + +- htb_set_lockdep_class_child(qdisc); + q->direct_qdiscs[ntx] = qdisc; + qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; + } +@@ -1468,7 +1460,6 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, + } + + if (q->offload) { +- htb_set_lockdep_class_child(new); + /* One ref for cl->leaf.q, the other for dev_queue->qdisc. */ + qdisc_refcount_inc(new); + old_q = htb_graft_helper(dev_queue, new); +@@ -1733,11 +1724,8 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg, + new_q = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops, + cl->parent->common.classid, + NULL); +- if (q->offload) { +- if (new_q) +- htb_set_lockdep_class_child(new_q); ++ if (q->offload) + htb_parent_to_leaf_offload(sch, dev_queue, new_q); +- } + } + + sch_tree_lock(sch); +@@ -1947,13 +1935,9 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, + new_q = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops, + classid, NULL); + if (q->offload) { +- if (new_q) { +- htb_set_lockdep_class_child(new_q); +- /* One ref for cl->leaf.q, the other for +- * dev_queue->qdisc. +- */ ++ /* One ref for cl->leaf.q, the other for dev_queue->qdisc. */ ++ if (new_q) + qdisc_refcount_inc(new_q); +- } + old_q = htb_graft_helper(dev_queue, new_q); + /* No qdisc_put needed. */ + WARN_ON(!(old_q->flags & TCQ_F_BUILTIN)); +diff --git a/net/tipc/node.c b/net/tipc/node.c +index c1e890a824347..500320e5ca479 100644 +--- a/net/tipc/node.c ++++ b/net/tipc/node.c +@@ -2105,6 +2105,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) + } else { + n = tipc_node_find_by_id(net, ehdr->id); + } ++ skb_dst_force(skb); + tipc_crypto_rcv(net, (n) ? n->crypto_rx : NULL, &skb, b); + if (!skb) + return; +diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c +index 45beb1c5f747a..6b5181c668b5b 100644 +--- a/security/apparmor/audit.c ++++ b/security/apparmor/audit.c +@@ -217,7 +217,7 @@ void aa_audit_rule_free(void *vrule) + } + } + +-int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) ++int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, gfp_t gfp) + { + struct aa_audit_rule *rule; + +@@ -230,14 +230,14 @@ int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) + return -EINVAL; + } + +- rule = kzalloc(sizeof(struct aa_audit_rule), GFP_KERNEL); ++ rule = kzalloc(sizeof(struct aa_audit_rule), gfp); + + if (!rule) + return -ENOMEM; + + /* Currently rules are treated as coming from the root ns */ + rule->label = aa_label_parse(&root_ns->unconfined->label, rulestr, +- GFP_KERNEL, true, false); ++ gfp, true, false); + if (IS_ERR(rule->label)) { + int err = PTR_ERR(rule->label); + aa_audit_rule_free(rule); +diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h +index acbb03b9bd25c..0c8cc86b417b5 100644 +--- a/security/apparmor/include/audit.h ++++ b/security/apparmor/include/audit.h +@@ -200,7 +200,7 @@ static inline int complain_error(int error) + } + + void aa_audit_rule_free(void *vrule); +-int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule); ++int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, gfp_t gfp); + int aa_audit_rule_known(struct audit_krule *rule); + int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule); + +diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h +index 11d7c03322070..0a4f274f77810 100644 +--- a/security/integrity/ima/ima.h ++++ b/security/integrity/ima/ima.h +@@ -540,7 +540,7 @@ static inline void ima_free_modsig(struct modsig *modsig) + #else + + static inline int ima_filter_rule_init(u32 field, u32 op, char *rulestr, +- void **lsmrule) ++ void **lsmrule, gfp_t gfp) + { + return -EINVAL; + } +diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c +index c0556907c2e67..09da8e6392395 100644 +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -401,7 +401,8 @@ static void ima_free_rule(struct ima_rule_entry *entry) + kfree(entry); + } + +-static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) ++static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry, ++ gfp_t gfp) + { + struct ima_rule_entry *nentry; + int i; +@@ -410,7 +411,7 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) + * Immutable elements are copied over as pointers and data; only + * lsm rules can change + */ +- nentry = kmemdup(entry, sizeof(*nentry), GFP_KERNEL); ++ nentry = kmemdup(entry, sizeof(*nentry), gfp); + if (!nentry) + return NULL; + +@@ -425,7 +426,8 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) + + ima_filter_rule_init(nentry->lsm[i].type, Audit_equal, + nentry->lsm[i].args_p, +- &nentry->lsm[i].rule); ++ &nentry->lsm[i].rule, ++ gfp); + if (!nentry->lsm[i].rule) + pr_warn("rule for LSM \'%s\' is undefined\n", + nentry->lsm[i].args_p); +@@ -438,7 +440,7 @@ static int ima_lsm_update_rule(struct ima_rule_entry *entry) + int i; + struct ima_rule_entry *nentry; + +- nentry = ima_lsm_copy_rule(entry); ++ nentry = ima_lsm_copy_rule(entry, GFP_KERNEL); + if (!nentry) + return -ENOMEM; + +@@ -664,7 +666,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, + } + + if (rc == -ESTALE && !rule_reinitialized) { +- lsm_rule = ima_lsm_copy_rule(rule); ++ lsm_rule = ima_lsm_copy_rule(rule, GFP_ATOMIC); + if (lsm_rule) { + rule_reinitialized = true; + goto retry; +@@ -1140,7 +1142,8 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, + entry->lsm[lsm_rule].type = audit_type; + result = ima_filter_rule_init(entry->lsm[lsm_rule].type, Audit_equal, + entry->lsm[lsm_rule].args_p, +- &entry->lsm[lsm_rule].rule); ++ &entry->lsm[lsm_rule].rule, ++ GFP_KERNEL); + if (!entry->lsm[lsm_rule].rule) { + pr_warn("rule for LSM \'%s\' is undefined\n", + entry->lsm[lsm_rule].args_p); +diff --git a/security/security.c b/security/security.c +index 0a9a0ac3f2662..4fd3c839353ec 100644 +--- a/security/security.c ++++ b/security/security.c +@@ -5331,15 +5331,17 @@ void security_key_post_create_or_update(struct key *keyring, struct key *key, + * @op: rule operator + * @rulestr: rule context + * @lsmrule: receive buffer for audit rule struct ++ * @gfp: GFP flag used for kmalloc + * + * Allocate and initialize an LSM audit rule structure. + * + * Return: Return 0 if @lsmrule has been successfully set, -EINVAL in case of + * an invalid rule. + */ +-int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) ++int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule, ++ gfp_t gfp) + { +- return call_int_hook(audit_rule_init, field, op, rulestr, lsmrule); ++ return call_int_hook(audit_rule_init, field, op, rulestr, lsmrule, gfp); + } + + /** +diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h +index 52aca71210b47..29c7d4c86f6d5 100644 +--- a/security/selinux/include/audit.h ++++ b/security/selinux/include/audit.h +@@ -21,12 +21,14 @@ + * @op: the operator the rule uses + * @rulestr: the text "target" of the rule + * @rule: pointer to the new rule structure returned via this ++ * @gfp: GFP flag used for kmalloc + * + * Returns 0 if successful, -errno if not. On success, the rule structure + * will be allocated internally. The caller must free this structure with + * selinux_audit_rule_free() after use. + */ +-int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule); ++int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule, ++ gfp_t gfp); + + /** + * selinux_audit_rule_free - free an selinux audit rule structure. +diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c +index e88b1b6c4adbb..ded250e525e9c 100644 +--- a/security/selinux/ss/services.c ++++ b/security/selinux/ss/services.c +@@ -3508,7 +3508,8 @@ void selinux_audit_rule_free(void *vrule) + } + } + +-int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) ++int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, ++ gfp_t gfp) + { + struct selinux_state *state = &selinux_state; + struct selinux_policy *policy; +@@ -3549,7 +3550,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) + return -EINVAL; + } + +- tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL); ++ tmprule = kzalloc(sizeof(struct selinux_audit_rule), gfp); + if (!tmprule) + return -ENOMEM; + context_init(&tmprule->au_ctxt); +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 146667937811b..c6df5c00c7bab 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -4692,11 +4692,13 @@ static int smack_post_notification(const struct cred *w_cred, + * @op: required testing operator (=, !=, >, <, ...) + * @rulestr: smack label to be audited + * @vrule: pointer to save our own audit rule representation ++ * @gfp: type of the memory for the allocation + * + * Prepare to audit cases where (@field @op @rulestr) is true. + * The label to be audited is created if necessay. + */ +-static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) ++static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, ++ gfp_t gfp) + { + struct smack_known *skp; + char **rule = (char **)vrule; +diff --git a/sound/core/seq/seq_ump_convert.c b/sound/core/seq/seq_ump_convert.c +index 171fb75267afa..d81f776a4c3dd 100644 +--- a/sound/core/seq/seq_ump_convert.c ++++ b/sound/core/seq/seq_ump_convert.c +@@ -1075,6 +1075,8 @@ static const struct seq_ev_to_ump seq_ev_ump_encoders[] = { + system_ev_to_ump_midi1, system_ev_to_ump_midi2 }, + { SNDRV_SEQ_EVENT_SENSING, UMP_SYSTEM_STATUS_ACTIVE_SENSING, + system_ev_to_ump_midi1, system_ev_to_ump_midi2 }, ++ { SNDRV_SEQ_EVENT_RESET, UMP_SYSTEM_STATUS_RESET, ++ system_ev_to_ump_midi1, system_ev_to_ump_midi2 }, + }; + + static const struct seq_ev_to_ump *find_ump_encoder(int type) +diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c +index d1f6cdcf1866e..e7c2ef6c6b4cb 100644 +--- a/sound/hda/intel-dsp-config.c ++++ b/sound/hda/intel-dsp-config.c +@@ -16,7 +16,7 @@ + static int dsp_driver; + + module_param(dsp_driver, int, 0444); +-MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)"); ++MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF, 4=AVS)"); + + #define FLAG_SST BIT(0) + #define FLAG_SOF BIT(1) +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index d3fa6e136744d..ec688c60c153b 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -1362,7 +1362,7 @@ static void cs35l41_hda_unbind(struct device *dev, struct device *master, void * + if (comps[cs35l41->index].dev == dev) { + memset(&comps[cs35l41->index], 0, sizeof(*comps)); + sleep_flags = lock_system_sleep(); +- device_link_remove(&comps->codec->core.dev, cs35l41->dev); ++ device_link_remove(&cs35l41->codec->core.dev, cs35l41->dev); + unlock_system_sleep(sleep_flags); + } + } +@@ -1857,6 +1857,8 @@ void cs35l41_hda_remove(struct device *dev) + { + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + ++ component_del(cs35l41->dev, &cs35l41_hda_comp_ops); ++ + pm_runtime_get_sync(cs35l41->dev); + pm_runtime_dont_use_autosuspend(cs35l41->dev); + pm_runtime_disable(cs35l41->dev); +@@ -1864,8 +1866,6 @@ void cs35l41_hda_remove(struct device *dev) + if (cs35l41->halo_initialized) + cs35l41_remove_dsp(cs35l41); + +- component_del(cs35l41->dev, &cs35l41_hda_comp_ops); +- + acpi_dev_put(cs35l41->dacpi); + + pm_runtime_put_noidle(cs35l41->dev); +diff --git a/sound/pci/hda/cs35l56_hda.c b/sound/pci/hda/cs35l56_hda.c +index 11b0570ff56d4..6b77c38a0e155 100644 +--- a/sound/pci/hda/cs35l56_hda.c ++++ b/sound/pci/hda/cs35l56_hda.c +@@ -1072,12 +1072,12 @@ void cs35l56_hda_remove(struct device *dev) + { + struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev); + ++ component_del(cs35l56->base.dev, &cs35l56_hda_comp_ops); ++ + pm_runtime_dont_use_autosuspend(cs35l56->base.dev); + pm_runtime_get_sync(cs35l56->base.dev); + pm_runtime_disable(cs35l56->base.dev); + +- component_del(cs35l56->base.dev, &cs35l56_hda_comp_ops); +- + cs_dsp_remove(&cs35l56->cs_dsp); + + kfree(cs35l56->system_name); +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 1a1ca7caaff07..3e6de1d86022f 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10147,6 +10147,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8b92, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8b96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8b97, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), ++ SND_PCI_QUIRK(0x103c, 0x8bb3, "HP Slim OMEN", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x103c, 0x8bb4, "HP Slim OMEN", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8bdd, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8bde, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8bdf, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2), +@@ -10167,6 +10169,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8c47, "HP EliteBook 840 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8c48, "HP EliteBook 860 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8c49, "HP Elite x360 830 2-in-1 G11", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8c4d, "HP Omen", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x103c, 0x8c4e, "HP Omen", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8c4f, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8c50, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8c51, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2), +@@ -10179,6 +10183,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8c70, "HP EliteBook 835 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8c71, "HP EliteBook 845 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8c72, "HP EliteBook 865 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), ++ SND_PCI_QUIRK(0x103c, 0x8c7b, "HP ProBook 445 G11", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), ++ SND_PCI_QUIRK(0x103c, 0x8c7c, "HP ProBook 445 G11", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), ++ SND_PCI_QUIRK(0x103c, 0x8c7d, "HP ProBook 465 G11", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), ++ SND_PCI_QUIRK(0x103c, 0x8c7e, "HP ProBook 465 G11", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8c89, "HP ProBook 460 G11", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8c8a, "HP EliteBook 630", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8c8c, "HP EliteBook 660", ALC236_FIXUP_HP_GPIO_LED), +@@ -10486,7 +10494,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940 / Yoga Duet 7", ALC298_FIXUP_LENOVO_C940_DUET7), + SND_PCI_QUIRK(0x17aa, 0x3819, "Lenovo 13s Gen2 ITL", ALC287_FIXUP_13S_GEN2_SPEAKERS), +- SND_PCI_QUIRK(0x17aa, 0x3820, "Yoga Duet 7 13ITL6", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), ++ SND_PCI_QUIRK(0x17aa, 0x3820, "IdeaPad 330-17IKB 81DM", ALC269_FIXUP_ASPIRE_HEADSET_MIC), + SND_PCI_QUIRK(0x17aa, 0x3824, "Legion Y9000X 2020", ALC285_FIXUP_LEGION_Y9000X_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF), + SND_PCI_QUIRK(0x17aa, 0x3834, "Lenovo IdeaPad Slim 9i 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), +@@ -10497,6 +10505,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x3852, "Lenovo Yoga 7 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6), ++ SND_PCI_QUIRK(0x17aa, 0x3865, "Lenovo 13X", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x17aa, 0x3866, "Lenovo 13X", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), + SND_PCI_QUIRK(0x17aa, 0x386f, "Legion Pro 7/7i", ALC287_FIXUP_LENOVO_LEGION_7), + SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C), +@@ -10508,6 +10518,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x3882, "Lenovo Yoga Pro 7 14APH8", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), + SND_PCI_QUIRK(0x17aa, 0x3884, "Y780 YG DUAL", ALC287_FIXUP_TAS2781_I2C), + SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C), ++ SND_PCI_QUIRK(0x17aa, 0x3891, "Lenovo Yoga Pro 7 14AHP9", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), + SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C), + SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C), + SND_PCI_QUIRK(0x17aa, 0x38a9, "Thinkbook 16P", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD), +@@ -10562,6 +10573,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ + SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802), + SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X), ++ SND_PCI_QUIRK(0x1c6c, 0x122a, "Positivo N14AP7", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x1c6c, 0x1251, "Positivo N14KP6-TG", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1d05, 0x1132, "TongFang PHxTxX1", ALC256_FIXUP_SET_COEF_DEFAULTS), + SND_PCI_QUIRK(0x1d05, 0x1096, "TongFang GMxMRxx", ALC269_FIXUP_NO_SHUTUP), +@@ -10586,7 +10598,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10), + SND_PCI_QUIRK(0x8086, 0x3038, "Intel NUC 13", ALC295_FIXUP_CHROME_BOOK), + SND_PCI_QUIRK(0xf111, 0x0001, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), +- SND_PCI_QUIRK(0xf111, 0x0005, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0xf111, 0x0006, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), + + #if 0 +diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c +index 75f7674c66ee7..fdee6592c502d 100644 +--- a/sound/pci/hda/tas2781_hda_i2c.c ++++ b/sound/pci/hda/tas2781_hda_i2c.c +@@ -777,11 +777,11 @@ static void tas2781_hda_remove(struct device *dev) + { + struct tas2781_hda *tas_hda = dev_get_drvdata(dev); + ++ component_del(tas_hda->dev, &tas2781_hda_comp_ops); ++ + pm_runtime_get_sync(tas_hda->dev); + pm_runtime_disable(tas_hda->dev); + +- component_del(tas_hda->dev, &tas2781_hda_comp_ops); +- + pm_runtime_put_noidle(tas_hda->dev); + + tasdevice_remove(tas_hda->priv); +diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c +index a90b43162a54b..5d0125ef140c3 100644 +--- a/sound/soc/intel/boards/sof_sdw.c ++++ b/sound/soc/intel/boards/sof_sdw.c +@@ -429,6 +429,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { + RT711_JD2 | + SOF_SDW_FOUR_SPK), + }, ++ { ++ .callback = sof_sdw_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C0F") ++ }, ++ .driver_data = (void *)(SOF_SDW_TGL_HDMI | ++ RT711_JD2), ++ }, + { + .callback = sof_sdw_quirk_cb, + .matches = { +@@ -495,6 +504,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { + SOF_BT_OFFLOAD_SSP(1) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, ++ { ++ .callback = sof_sdw_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "HP"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "OMEN Transcend Gaming Laptop"), ++ }, ++ .driver_data = (void *)(RT711_JD2), ++ }, ++ + /* LunarLake devices */ + { + .callback = sof_sdw_quirk_cb, +diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h +index ccc13e9913760..cd8420e8c3ad8 100644 +--- a/tools/arch/arm64/include/asm/sysreg.h ++++ b/tools/arch/arm64/include/asm/sysreg.h +@@ -701,18 +701,18 @@ + * Permission Indirection Extension (PIE) permission encodings. + * Encodings with the _O suffix, have overlays applied (Permission Overlay Extension). + */ +-#define PIE_NONE_O 0x0 +-#define PIE_R_O 0x1 +-#define PIE_X_O 0x2 +-#define PIE_RX_O 0x3 +-#define PIE_RW_O 0x5 +-#define PIE_RWnX_O 0x6 +-#define PIE_RWX_O 0x7 +-#define PIE_R 0x8 +-#define PIE_GCS 0x9 +-#define PIE_RX 0xa +-#define PIE_RW 0xc +-#define PIE_RWX 0xe ++#define PIE_NONE_O UL(0x0) ++#define PIE_R_O UL(0x1) ++#define PIE_X_O UL(0x2) ++#define PIE_RX_O UL(0x3) ++#define PIE_RW_O UL(0x5) ++#define PIE_RWnX_O UL(0x6) ++#define PIE_RWX_O UL(0x7) ++#define PIE_R UL(0x8) ++#define PIE_GCS UL(0x9) ++#define PIE_RX UL(0xa) ++#define PIE_RW UL(0xc) ++#define PIE_RWX UL(0xe) + + #define PIRx_ELx_PERM(idx, perm) ((perm) << ((idx) * 4)) + +diff --git a/tools/testing/selftests/arm64/tags/tags_test.c b/tools/testing/selftests/arm64/tags/tags_test.c +index 5701163460ef7..955f87c1170d7 100644 +--- a/tools/testing/selftests/arm64/tags/tags_test.c ++++ b/tools/testing/selftests/arm64/tags/tags_test.c +@@ -6,6 +6,7 @@ + #include <stdint.h> + #include <sys/prctl.h> + #include <sys/utsname.h> ++#include "../../kselftest.h" + + #define SHIFT_TAG(tag) ((uint64_t)(tag) << 56) + #define SET_TAG(ptr, tag) (((uint64_t)(ptr) & ~SHIFT_TAG(0xff)) | \ +@@ -21,6 +22,9 @@ int main(void) + if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0) + tbi_enabled = 1; + ptr = (struct utsname *)malloc(sizeof(*ptr)); ++ if (!ptr) ++ ksft_exit_fail_msg("Failed to allocate utsname buffer\n"); ++ + if (tbi_enabled) + tag = 0x42; + ptr = (struct utsname *)SET_TAG(ptr, tag); +diff --git a/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c b/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c +index a8b53b8736f01..f66ceccd7029c 100644 +--- a/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c ++++ b/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c +@@ -25,7 +25,7 @@ static void test_lookup_update(void) + int map1_fd, map2_fd, map3_fd, map4_fd, map5_fd, map1_id, map2_id; + int outer_arr_fd, outer_hash_fd, outer_arr_dyn_fd; + struct test_btf_map_in_map *skel; +- int err, key = 0, val, i, fd; ++ int err, key = 0, val, i; + + skel = test_btf_map_in_map__open_and_load(); + if (CHECK(!skel, "skel_open", "failed to open&load skeleton\n")) +@@ -102,30 +102,6 @@ static void test_lookup_update(void) + CHECK(map1_id == 0, "map1_id", "failed to get ID 1\n"); + CHECK(map2_id == 0, "map2_id", "failed to get ID 2\n"); + +- test_btf_map_in_map__destroy(skel); +- skel = NULL; +- +- /* we need to either wait for or force synchronize_rcu(), before +- * checking for "still exists" condition, otherwise map could still be +- * resolvable by ID, causing false positives. +- * +- * Older kernels (5.8 and earlier) freed map only after two +- * synchronize_rcu()s, so trigger two, to be entirely sure. +- */ +- CHECK(kern_sync_rcu(), "sync_rcu", "failed\n"); +- CHECK(kern_sync_rcu(), "sync_rcu", "failed\n"); +- +- fd = bpf_map_get_fd_by_id(map1_id); +- if (CHECK(fd >= 0, "map1_leak", "inner_map1 leaked!\n")) { +- close(fd); +- goto cleanup; +- } +- fd = bpf_map_get_fd_by_id(map2_id); +- if (CHECK(fd >= 0, "map2_leak", "inner_map2 leaked!\n")) { +- close(fd); +- goto cleanup; +- } +- + cleanup: + test_btf_map_in_map__destroy(skel); + } +diff --git a/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c b/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c +index baff5ffe94051..a9fc30ed4d732 100644 +--- a/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c ++++ b/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c +@@ -8,6 +8,13 @@ + #include "xdp_metadata.h" + #include "bpf_kfuncs.h" + ++/* The compiler may be able to detect the access to uninitialized ++ memory in the routines performing out of bound memory accesses and ++ emit warnings about it. This is the case of GCC. */ ++#if !defined(__clang__) ++#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" ++#endif ++ + int arr[1]; + int unkn_idx; + const volatile bool call_dead_subprog = false; +diff --git a/tools/testing/selftests/bpf/test_tc_tunnel.sh b/tools/testing/selftests/bpf/test_tc_tunnel.sh +index 910044f08908a..7989ec6084545 100755 +--- a/tools/testing/selftests/bpf/test_tc_tunnel.sh ++++ b/tools/testing/selftests/bpf/test_tc_tunnel.sh +@@ -72,7 +72,6 @@ cleanup() { + server_listen() { + ip netns exec "${ns2}" nc "${netcat_opt}" -l "${port}" > "${outfile}" & + server_pid=$! +- sleep 0.2 + } + + client_connect() { +@@ -93,6 +92,16 @@ verify_data() { + fi + } + ++wait_for_port() { ++ for i in $(seq 20); do ++ if ip netns exec "${ns2}" ss ${2:--4}OHntl | grep -q "$1"; then ++ return 0 ++ fi ++ sleep 0.1 ++ done ++ return 1 ++} ++ + set -e + + # no arguments: automated test, run all +@@ -193,6 +202,7 @@ setup + # basic communication works + echo "test basic connectivity" + server_listen ++wait_for_port ${port} ${netcat_opt} + client_connect + verify_data + +@@ -204,6 +214,7 @@ ip netns exec "${ns1}" tc filter add dev veth1 egress \ + section "encap_${tuntype}_${mac}" + echo "test bpf encap without decap (expect failure)" + server_listen ++wait_for_port ${port} ${netcat_opt} + ! client_connect + + if [[ "$tuntype" =~ "udp" ]]; then +diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c +index c79e65581dc37..161db24e3c409 100644 +--- a/tools/testing/selftests/net/cmsg_sender.c ++++ b/tools/testing/selftests/net/cmsg_sender.c +@@ -333,16 +333,17 @@ static const char *cs_ts_info2str(unsigned int info) + return "unknown"; + } + +-static void ++static unsigned long + cs_read_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz) + { + struct sock_extended_err *see; + struct scm_timestamping *ts; ++ unsigned long ts_seen = 0; + struct cmsghdr *cmsg; + int i, err; + + if (!opt.ts.ena) +- return; ++ return 0; + msg->msg_control = cbuf; + msg->msg_controllen = cbuf_sz; + +@@ -396,8 +397,11 @@ cs_read_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz) + printf(" %5s ts%d %lluus\n", + cs_ts_info2str(see->ee_info), + i, rel_time); ++ ts_seen |= 1 << see->ee_info; + } + } ++ ++ return ts_seen; + } + + static void ca_set_sockopts(int fd) +@@ -509,10 +513,16 @@ int main(int argc, char *argv[]) + err = ERN_SUCCESS; + + if (opt.ts.ena) { +- /* Make sure all timestamps have time to loop back */ +- usleep(opt.txtime.delay); ++ unsigned long seen; ++ int i; + +- cs_read_cmsg(fd, &msg, cbuf, sizeof(cbuf)); ++ /* Make sure all timestamps have time to loop back */ ++ for (i = 0; i < 40; i++) { ++ seen = cs_read_cmsg(fd, &msg, cbuf, sizeof(cbuf)); ++ if (seen & (1 << SCM_TSTAMP_SND)) ++ break; ++ usleep(opt.txtime.delay / 20); ++ } + } + + err_out: +diff --git a/tools/testing/selftests/net/mptcp/userspace_pm.sh b/tools/testing/selftests/net/mptcp/userspace_pm.sh +index 9e2981f2d7f5c..9cb05978269d1 100755 +--- a/tools/testing/selftests/net/mptcp/userspace_pm.sh ++++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh +@@ -160,10 +160,12 @@ make_connection() + local is_v6=$1 + local app_port=$app4_port + local connect_addr="10.0.1.1" ++ local client_addr="10.0.1.2" + local listen_addr="0.0.0.0" + if [ "$is_v6" = "v6" ] + then + connect_addr="dead:beef:1::1" ++ client_addr="dead:beef:1::2" + listen_addr="::" + app_port=$app6_port + else +@@ -206,6 +208,7 @@ make_connection() + [ "$server_serverside" = 1 ] + then + test_pass ++ print_title "Connection info: ${client_addr}:${client_port} -> ${connect_addr}:${app_port}" + else + test_fail "Expected tokens (c:${client_token} - s:${server_token}) and server (c:${client_serverside} - s:${server_serverside})" + mptcp_lib_result_print_all_tap +@@ -297,7 +300,7 @@ test_announce() + ip netns exec "$ns2"\ + ./pm_nl_ctl ann 10.0.2.2 token "$client4_token" id $client_addr_id dev\ + ns2eth1 +- print_test "ADD_ADDR id:${client_addr_id} 10.0.2.2 (ns2) => ns1, reuse port" ++ print_test "ADD_ADDR id:client 10.0.2.2 (ns2) => ns1, reuse port" + sleep 0.5 + verify_announce_event $server_evts $ANNOUNCED $server4_token "10.0.2.2" $client_addr_id \ + "$client4_port" +@@ -306,7 +309,7 @@ test_announce() + :>"$server_evts" + ip netns exec "$ns2" ./pm_nl_ctl ann\ + dead:beef:2::2 token "$client6_token" id $client_addr_id dev ns2eth1 +- print_test "ADD_ADDR6 id:${client_addr_id} dead:beef:2::2 (ns2) => ns1, reuse port" ++ print_test "ADD_ADDR6 id:client dead:beef:2::2 (ns2) => ns1, reuse port" + sleep 0.5 + verify_announce_event "$server_evts" "$ANNOUNCED" "$server6_token" "dead:beef:2::2"\ + "$client_addr_id" "$client6_port" "v6" +@@ -316,7 +319,7 @@ test_announce() + client_addr_id=$((client_addr_id+1)) + ip netns exec "$ns2" ./pm_nl_ctl ann 10.0.2.2 token "$client4_token" id\ + $client_addr_id dev ns2eth1 port $new4_port +- print_test "ADD_ADDR id:${client_addr_id} 10.0.2.2 (ns2) => ns1, new port" ++ print_test "ADD_ADDR id:client+1 10.0.2.2 (ns2) => ns1, new port" + sleep 0.5 + verify_announce_event "$server_evts" "$ANNOUNCED" "$server4_token" "10.0.2.2"\ + "$client_addr_id" "$new4_port" +@@ -327,7 +330,7 @@ test_announce() + # ADD_ADDR from the server to client machine reusing the subflow port + ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server4_token" id\ + $server_addr_id dev ns1eth2 +- print_test "ADD_ADDR id:${server_addr_id} 10.0.2.1 (ns1) => ns2, reuse port" ++ print_test "ADD_ADDR id:server 10.0.2.1 (ns1) => ns2, reuse port" + sleep 0.5 + verify_announce_event "$client_evts" "$ANNOUNCED" "$client4_token" "10.0.2.1"\ + "$server_addr_id" "$app4_port" +@@ -336,7 +339,7 @@ test_announce() + :>"$client_evts" + ip netns exec "$ns1" ./pm_nl_ctl ann dead:beef:2::1 token "$server6_token" id\ + $server_addr_id dev ns1eth2 +- print_test "ADD_ADDR6 id:${server_addr_id} dead:beef:2::1 (ns1) => ns2, reuse port" ++ print_test "ADD_ADDR6 id:server dead:beef:2::1 (ns1) => ns2, reuse port" + sleep 0.5 + verify_announce_event "$client_evts" "$ANNOUNCED" "$client6_token" "dead:beef:2::1"\ + "$server_addr_id" "$app6_port" "v6" +@@ -346,7 +349,7 @@ test_announce() + server_addr_id=$((server_addr_id+1)) + ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server4_token" id\ + $server_addr_id dev ns1eth2 port $new4_port +- print_test "ADD_ADDR id:${server_addr_id} 10.0.2.1 (ns1) => ns2, new port" ++ print_test "ADD_ADDR id:server+1 10.0.2.1 (ns1) => ns2, new port" + sleep 0.5 + verify_announce_event "$client_evts" "$ANNOUNCED" "$client4_token" "10.0.2.1"\ + "$server_addr_id" "$new4_port" +@@ -380,7 +383,7 @@ test_remove() + local invalid_token=$(( client4_token - 1 )) + ip netns exec "$ns2" ./pm_nl_ctl rem token $invalid_token id\ + $client_addr_id > /dev/null 2>&1 +- print_test "RM_ADDR id:${client_addr_id} ns2 => ns1, invalid token" ++ print_test "RM_ADDR id:client ns2 => ns1, invalid token" + local type + type=$(mptcp_lib_evts_get_info type "$server_evts") + if [ "$type" = "" ] +@@ -394,7 +397,7 @@ test_remove() + local invalid_id=$(( client_addr_id + 1 )) + ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ + $invalid_id > /dev/null 2>&1 +- print_test "RM_ADDR id:${invalid_id} ns2 => ns1, invalid id" ++ print_test "RM_ADDR id:client+1 ns2 => ns1, invalid id" + type=$(mptcp_lib_evts_get_info type "$server_evts") + if [ "$type" = "" ] + then +@@ -407,7 +410,7 @@ test_remove() + :>"$server_evts" + ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ + $client_addr_id +- print_test "RM_ADDR id:${client_addr_id} ns2 => ns1" ++ print_test "RM_ADDR id:client ns2 => ns1" + sleep 0.5 + verify_remove_event "$server_evts" "$REMOVED" "$server4_token" "$client_addr_id" + +@@ -416,7 +419,7 @@ test_remove() + client_addr_id=$(( client_addr_id - 1 )) + ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id\ + $client_addr_id +- print_test "RM_ADDR id:${client_addr_id} ns2 => ns1" ++ print_test "RM_ADDR id:client-1 ns2 => ns1" + sleep 0.5 + verify_remove_event "$server_evts" "$REMOVED" "$server4_token" "$client_addr_id" + +@@ -424,7 +427,7 @@ test_remove() + :>"$server_evts" + ip netns exec "$ns2" ./pm_nl_ctl rem token "$client6_token" id\ + $client_addr_id +- print_test "RM_ADDR6 id:${client_addr_id} ns2 => ns1" ++ print_test "RM_ADDR6 id:client-1 ns2 => ns1" + sleep 0.5 + verify_remove_event "$server_evts" "$REMOVED" "$server6_token" "$client_addr_id" + +@@ -434,7 +437,7 @@ test_remove() + # RM_ADDR from the server to client machine + ip netns exec "$ns1" ./pm_nl_ctl rem token "$server4_token" id\ + $server_addr_id +- print_test "RM_ADDR id:${server_addr_id} ns1 => ns2" ++ print_test "RM_ADDR id:server ns1 => ns2" + sleep 0.5 + verify_remove_event "$client_evts" "$REMOVED" "$client4_token" "$server_addr_id" + +@@ -443,7 +446,7 @@ test_remove() + server_addr_id=$(( server_addr_id - 1 )) + ip netns exec "$ns1" ./pm_nl_ctl rem token "$server4_token" id\ + $server_addr_id +- print_test "RM_ADDR id:${server_addr_id} ns1 => ns2" ++ print_test "RM_ADDR id:server-1 ns1 => ns2" + sleep 0.5 + verify_remove_event "$client_evts" "$REMOVED" "$client4_token" "$server_addr_id" + +@@ -451,7 +454,7 @@ test_remove() + :>"$client_evts" + ip netns exec "$ns1" ./pm_nl_ctl rem token "$server6_token" id\ + $server_addr_id +- print_test "RM_ADDR6 id:${server_addr_id} ns1 => ns2" ++ print_test "RM_ADDR6 id:server-1 ns1 => ns2" + sleep 0.5 + verify_remove_event "$client_evts" "$REMOVED" "$client6_token" "$server_addr_id" + } +@@ -479,8 +482,14 @@ verify_subflow_events() + local locid + local remid + local info ++ local e_dport_txt + +- info="${e_saddr} (${e_from}) => ${e_daddr}:${e_dport} (${e_to})" ++ # only display the fixed ports ++ if [ "${e_dport}" -ge "${app4_port}" ] && [ "${e_dport}" -le "${app6_port}" ]; then ++ e_dport_txt=":${e_dport}" ++ fi ++ ++ info="${e_saddr} (${e_from}) => ${e_daddr}${e_dport_txt} (${e_to})" + + if [ "$e_type" = "$SUB_ESTABLISHED" ] + then +@@ -766,7 +775,7 @@ test_subflows_v4_v6_mix() + :>"$client_evts" + ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server6_token" id\ + $server_addr_id dev ns1eth2 +- print_test "ADD_ADDR4 id:${server_addr_id} 10.0.2.1 (ns1) => ns2, reuse port" ++ print_test "ADD_ADDR4 id:server 10.0.2.1 (ns1) => ns2, reuse port" + sleep 0.5 + verify_announce_event "$client_evts" "$ANNOUNCED" "$client6_token" "10.0.2.1"\ + "$server_addr_id" "$app6_port" +@@ -861,7 +870,7 @@ test_listener() + local listener_pid=$! + + sleep 0.5 +- print_test "CREATE_LISTENER 10.0.2.2:$client4_port" ++ print_test "CREATE_LISTENER 10.0.2.2 (client port)" + verify_listener_events $client_evts $LISTENER_CREATED $AF_INET 10.0.2.2 $client4_port + + # ADD_ADDR from client to server machine reusing the subflow port +@@ -878,13 +887,14 @@ test_listener() + mptcp_lib_kill_wait $listener_pid + + sleep 0.5 +- print_test "CLOSE_LISTENER 10.0.2.2:$client4_port" ++ print_test "CLOSE_LISTENER 10.0.2.2 (client port)" + verify_listener_events $client_evts $LISTENER_CLOSED $AF_INET 10.0.2.2 $client4_port + } + + print_title "Make connections" + make_connection + make_connection "v6" ++print_title "Will be using address IDs ${client_addr_id} (client) and ${server_addr_id} (server)" + + test_announce + test_remove +diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh b/tools/testing/selftests/net/openvswitch/openvswitch.sh +index 5cae535438491..15bca07087179 100755 +--- a/tools/testing/selftests/net/openvswitch/openvswitch.sh ++++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh +@@ -1,4 +1,4 @@ +-#!/bin/sh ++#!/bin/bash + # SPDX-License-Identifier: GPL-2.0 + # + # OVS kernel module self tests +diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c +index 0f4e0cf4f158b..747fe251e445b 100644 +--- a/virt/kvm/guest_memfd.c ++++ b/virt/kvm/guest_memfd.c +@@ -510,8 +510,10 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, + } + + if (folio_test_hwpoison(folio)) { ++ folio_unlock(folio); ++ folio_put(folio); + r = -EHWPOISON; +- goto out_unlock; ++ goto out_fput; + } + + page = folio_file_page(folio, index); +@@ -522,7 +524,6 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, + + r = 0; + +-out_unlock: + folio_unlock(folio); + out_fput: + fput(file); +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index ff0a20565f908..d9ce063c76f92 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -4066,12 +4066,13 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield_to_kernel_mode) + { + struct kvm *kvm = me->kvm; + struct kvm_vcpu *vcpu; +- int last_boosted_vcpu = me->kvm->last_boosted_vcpu; ++ int last_boosted_vcpu; + unsigned long i; + int yielded = 0; + int try = 3; + int pass; + ++ last_boosted_vcpu = READ_ONCE(kvm->last_boosted_vcpu); + kvm_vcpu_set_in_spin_loop(me, true); + /* + * We boost the priority of a VCPU that is runnable but not +@@ -4109,7 +4110,7 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield_to_kernel_mode) + + yielded = kvm_vcpu_yield_to(vcpu); + if (yielded > 0) { +- kvm->last_boosted_vcpu = i; ++ WRITE_ONCE(kvm->last_boosted_vcpu, i); + break; + } else if (yielded < 0) { + try--; |